X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fld65%2Fobjdata.c;h=2a7a0ac1d9a9f1161c6fe246da4e2294193c68fc;hb=35e1184901ca38bdb2e56d154ed3b71f6096eacc;hp=ce88775dc74b30a4b8ae33066e1da22882a9d964;hpb=4ea94a9302b8946f452fe14667fa1deaba52bbe7;p=cc65 diff --git a/src/ld65/objdata.c b/src/ld65/objdata.c index ce88775dc..2a7a0ac1d 100644 --- a/src/ld65/objdata.c +++ b/src/ld65/objdata.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -41,26 +41,27 @@ /* ld65 */ #include "error.h" +#include "exports.h" +#include "fileinfo.h" +#include "library.h" #include "objdata.h" +#include "spool.h" /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ -/* Object data list management */ -unsigned ObjCount = 0; /* Count of object files in the list */ -ObjData* ObjRoot = 0; /* List of object files */ -ObjData* ObjLast = 0; /* Last entry in list */ -ObjData** ObjPool = 0; /* Object files as array */ +/* Collection containing used ObjData objects */ +Collection ObjDataList = STATIC_COLLECTION_INITIALIZER; /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -73,28 +74,27 @@ ObjData* NewObjData (void) /* Initialize the data */ O->Next = 0; - O->Name = 0; - O->LibName = 0; - O->Flags = 0; + O->Name = INVALID_STRING_ID; + O->Lib = 0; + O->MTime = 0; O->Start = 0; - O->ExportCount = 0; - O->Exports = 0; - O->ImportCount = 0; - O->Imports = 0; - O->DbgSymCount = 0; - O->DbgSyms = 0; - - /* Link it into the list */ - if (ObjLast) { - ObjLast->Next = O; - ObjLast = O; - } else { - /* First entry */ - ObjRoot = ObjLast = O; - } - - /* One object file more now */ - ++ObjCount; + O->Flags = 0; + O->HLLSymBaseId = 0; + O->SymBaseId = 0; + O->ScopeBaseId = 0; + O->SpanBaseId = 0; + O->Files = EmptyCollection; + O->Sections = EmptyCollection; + O->Exports = EmptyCollection; + O->Imports = EmptyCollection; + O->DbgSyms = EmptyCollection; + O->HLLDbgSyms = EmptyCollection; + O->LineInfos = EmptyCollection; + O->StringCount = 0; + O->Strings = 0; + O->Assertions = EmptyCollection; + O->Scopes = EmptyCollection; + O->Spans = EmptyCollection; /* Return the new entry */ return O; @@ -103,47 +103,211 @@ ObjData* NewObjData (void) void FreeObjData (ObjData* O) -/* Free a complete struct */ +/* Free an ObjData object. NOTE: This function works only for unused object + * data, that is, ObjData objects that aren't used because they aren't + * referenced. + */ { - xfree (O->Name); - xfree (O->Imports); - xfree (O->Exports); - xfree (O->DbgSyms); + unsigned I; + + for (I = 0; I < CollCount (&O->Files); ++I) { + CollDeleteItem (&((FileInfo*) CollAtUnchecked (&O->Files, I))->Modules, O); + } + DoneCollection (&O->Files); + DoneCollection (&O->Sections); + for (I = 0; I < CollCount (&O->Exports); ++I) { + FreeExport (CollAtUnchecked (&O->Exports, I)); + } + DoneCollection (&O->Exports); + for (I = 0; I < CollCount (&O->Imports); ++I) { + FreeImport (CollAtUnchecked (&O->Imports, I)); + } + DoneCollection (&O->Imports); + DoneCollection (&O->DbgSyms); + DoneCollection (&O->HLLDbgSyms); + + for (I = 0; I < CollCount (&O->LineInfos); ++I) { + FreeLineInfo (CollAtUnchecked (&O->LineInfos, I)); + } + DoneCollection (&O->LineInfos); + xfree (O->Strings); + DoneCollection (&O->Assertions); + DoneCollection (&O->Scopes); + for (I = 0; I < CollCount (&O->Spans); ++I) { + FreeSpan (CollAtUnchecked (&O->Spans, I)); + } + DoneCollection (&O->Spans); + xfree (O); } +void FreeObjStrings (ObjData* O) +/* Free the module string data. Used once the object file is loaded completely + * when all strings are converted to global strings. + */ +{ + xfree (O->Strings); + O->Strings = 0; +} + + + +void InsertObjData (ObjData* O) +/* Insert the ObjData object into the collection of used ObjData objects. */ +{ + CollAppend (&ObjDataList, O); +} + + + +void InsertObjGlobals (ObjData* O) +/* Insert imports and exports from the object file into the global import and + * export lists. + */ +{ + unsigned I; + + /* Insert exports and imports */ + for (I = 0; I < CollCount (&O->Exports); ++I) { + InsertExport (CollAt (&O->Exports, I)); + } + for (I = 0; I < CollCount (&O->Imports); ++I) { + InsertImport (CollAt (&O->Imports, I)); + } +} + + + +unsigned MakeGlobalStringId (const ObjData* O, unsigned Index) +/* Convert a local string id into a global one and return it. */ +{ + if (Index >= O->StringCount) { + Error ("Invalid string index (%u) in module `%s'", + Index, GetObjFileName (O)); + } + return O->Strings[Index]; +} + + + const char* GetObjFileName (const ObjData* O) /* Get the name of the object file. Return "[linker generated]" if the object * file is NULL. */ { - return O? O->Name : "[linker generated]"; + return O? GetString (O->Name) : "[linker generated]"; } -const char* GetSourceFileName (const ObjData* O, unsigned Index) -/* Get the name of the source file with the given index. If O is NULL, return - * "[linker generated]" as the file name. - */ +const struct StrBuf* GetObjString (const ObjData* Obj, unsigned Id) +/* Get a string from an object file checking for an invalid index */ { - /* Check if we have an object file */ - if (O == 0) { + return GetStrBuf (MakeGlobalStringId (Obj, Id)); +} - /* No object file */ - return "[linker generated]"; - } else { - /* Check the parameter */ - PRECONDITION (Index < O->FileCount); +struct Section* GetObjSection (const ObjData* O, unsigned Id) +/* Get a section from an object file checking for a valid index */ +{ + if (Id >= CollCount (&O->Sections)) { + Error ("Invalid section index (%u) in module `%s'", + Id, GetObjFileName (O)); + } + return CollAtUnchecked (&O->Sections, Id); +} + + + +struct Import* GetObjImport (const ObjData* O, unsigned Id) +/* Get an import from an object file checking for a valid index */ +{ + if (Id >= CollCount (&O->Imports)) { + Error ("Invalid import index (%u) in module `%s'", + Id, GetObjFileName (O)); + } + return CollAtUnchecked (&O->Imports, Id); +} + + + +struct Export* GetObjExport (const ObjData* O, unsigned Id) +/* Get an export from an object file checking for a valid index */ +{ + if (Id >= CollCount (&O->Exports)) { + Error ("Invalid export index (%u) in module `%s'", + Id, GetObjFileName (O)); + } + return CollAtUnchecked (&O->Exports, Id); +} + + + +struct DbgSym* GetObjDbgSym (const ObjData* O, unsigned Id) +/* Get a debug symbol from an object file checking for a valid index */ +{ + if (Id >= CollCount (&O->DbgSyms)) { + Error ("Invalid debug symbol index (%u) in module `%s'", + Id, GetObjFileName (O)); + } + return CollAtUnchecked (&O->DbgSyms, Id); +} + - /* Return the name */ - return O->Files[Index]; - } +struct Scope* GetObjScope (const ObjData* O, unsigned Id) +/* Get a scope from an object file checking for a valid index */ +{ + if (Id >= CollCount (&O->Scopes)) { + Error ("Invalid scope index (%u) in module `%s'", + Id, GetObjFileName (O)); + } + return CollAtUnchecked (&O->Scopes, Id); +} + + + +unsigned ObjDataCount (void) +/* Return the total number of modules */ +{ + return CollCount (&ObjDataList); +} + + + +void PrintDbgModules (FILE* F) +/* Output the modules to a debug info file */ +{ + unsigned I; + + /* Output modules */ + for (I = 0; I < CollCount (&ObjDataList); ++I) { + + /* Get this object file */ + const ObjData* O = CollConstAt (&ObjDataList, I); + + /* The main source file is the one at index zero */ + const FileInfo* Source = CollConstAt (&O->Files, 0); + + /* Output the module line */ + fprintf (F, + "mod\tid=%u,name=\"%s\",file=%u", + I, + GetObjFileName (O), + Source->Id); + + /* Add library if any */ + if (O->Lib != 0) { + fprintf (F, ",lib=%u", GetLibId (O->Lib)); + } + + /* Terminate the output line */ + fputc ('\n', F); + } + }