-static void AssignBaseIds (void)
+static void AssignIds (void)
/* Assign the base ids for debug info output. Within each module, many of the
* items are addressed by ids which are actually the indices of the items in
* the collections. To make them unique, we must assign a unique base to each
* range.
*/
{
- unsigned I;
-
/* Walk over all modules */
- unsigned FileBaseId = 0;
+ unsigned I;
unsigned SymBaseId = 0;
unsigned ScopeBaseId = 0;
for (I = 0; I < CollCount (&ObjDataList); ++I) {
/* Get this module */
ObjData* O = CollAt (&ObjDataList, I);
- /* Assign ids */
- O->FileBaseId = FileBaseId;
+ /* Assign the module id */
+ O->Id = I;
+
+ /* Assign base ids */
O->SymBaseId = SymBaseId;
O->ScopeBaseId = ScopeBaseId;
/* Bump the base ids */
- FileBaseId += CollCount (&O->Files);
SymBaseId += CollCount (&O->DbgSyms);
ScopeBaseId += CollCount (&O->Scopes);
- }
+ }
+
+ /* Assign the ids to the file infos */
+ AssignFileInfoIds ();
}
void CreateDbgFile (void)
/* Create a debug info file */
{
- unsigned I;
-
/* Open the debug info file */
FILE* F = fopen (DbgFileName, "w");
if (F == 0) {
/* Output version information */
fprintf (F, "version\tmajor=1,minor=2\n");
- /* Assign the base ids to the modules */
- AssignBaseIds ();
+ /* Assign the ids to the items */
+ AssignIds ();
/* Output libraries */
PrintDbgLibraries (F);
/* 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);
- }
+ PrintDbgModules (F);
/* Output the segment info */
PrintDbgSegments (F);
-static FileInfo* NewFileInfo (void)
+static FileInfo* NewFileInfo (unsigned Name, unsigned long MTime, unsigned long Size)
/* Allocate and initialize a new FileInfo struct and return it */
{
- /* We will assign file info ids in increasing order of creation */
- static unsigned Id = 0;
-
/* Allocate memory */
FileInfo* FI = xmalloc (sizeof (FileInfo));
/* Initialize stuff */
- FI->Id = Id++;
- FI->Dumped = 0;
+ FI->Id = ~0U;
+ FI->Name = Name;
+ FI->MTime = MTime;
+ FI->Size = Size;
+ FI->Modules = EmptyCollection;
/* Return the new struct */
return FI;
+static void FreeFileInfo (FileInfo* FI)
+/* Free a file info structure */
+{
+ /* Free the collection */
+ DoneCollection (&FI->Modules);
+
+ /* Free memory for the structure */
+ xfree (FI);
+}
+
+
+
FileInfo* ReadFileInfo (FILE* F, ObjData* O)
/* Read a file info from a file and return it */
{
/* Check size and modification time stamp */
if (FI->Size == Size && FI->MTime == MTime) {
- /* Return this one */
+ /* Remember that the modules uses this file info, then return it */
+ CollAppend (&FI->Modules, O);
return FI;
}
}
/* Not found. Allocate a new FileInfo structure */
- FI = NewFileInfo ();
+ FI = NewFileInfo (Name, MTime, Size);
- /* Set the fields */
- FI->Name = Name;
- FI->MTime = MTime;
- FI->Size = Size;
+ /* Remember that this module uses the file info */
+ CollAppend (&FI->Modules, O);
/* Insert the file info in our global list. Index points to the insert
* position.
+void AssignFileInfoIds (void)
+/* Remove unused file infos and assign the ids to the remaining ones */
+{
+ unsigned I, J;
+
+ /* Print all file infos */
+ for (I = 0, J = 0; I < CollCount (&FileInfos); ++I) {
+
+ /* Get the next file info */
+ FileInfo* FI = CollAtUnchecked (&FileInfos, I);
+
+ /* If it's unused, free it, otherwise assign the id and keep it */
+ if (CollCount (&FI->Modules) == 0) {
+ FreeFileInfo (FI);
+ } else {
+ FI->Id = J;
+ CollReplace (&FileInfos, FI, J++);
+ }
+ }
+
+ /* The new count is now in J */
+ FileInfos.Count = J;
+}
+
+
+
void PrintDbgFileInfo (FILE* F)
/* Output the file info to a debug info file */
{
unsigned I, J;
- /* Print file infos from all modules we have linked into the output file */
- for (I = 0; I < CollCount (&ObjDataList); ++I) {
+ /* Print all file infos */
+ for (I = 0; I < CollCount (&FileInfos); ++I) {
+
+ /* Get the file info */
+ const FileInfo* FI = CollAtUnchecked (&FileInfos, I);
- /* Get the object file */
- ObjData* O = CollAtUnchecked (&ObjDataList, I);
+ /* Base info */
+ fprintf (F,
+ "file\tid=%u,name=\"%s\",size=%lu,mtime=0x%08lX,mod=",
+ FI->Id, GetString (FI->Name), FI->Size, FI->MTime);
- /* Output the files section */
- for (J = 0; J < CollCount (&O->Files); ++J) {
- FileInfo* FI = CollAt (&O->Files, J);
- if (!FI->Dumped) {
- fprintf (F,
- "file\tid=%u,name=\"%s\",size=%lu,mtime=0x%08lX\n",
- FI->Id, GetString (FI->Name), FI->Size, FI->MTime);
- FI->Dumped = 1;
+ /* Modules that use the file */
+ for (J = 0; J < CollCount (&FI->Modules); ++J) {
+
+ /* Get the module */
+ const ObjData* O = CollConstAt (&FI->Modules, J);
+
+ /* Output its id */
+ if (J > 0) {
+ fprintf (F, "+%u", O->Id);
+ } else {
+ fprintf (F, "%u", O->Id);
}
}
+
+ /* Terminate the output line */
+ fputc ('\n', F);
}
}
typedef struct FileInfo FileInfo;
struct FileInfo {
+ unsigned Id; /* Id of file for debug info */
unsigned Name; /* File name index */
unsigned long MTime; /* Time of last modification */
unsigned long Size; /* Size of the file */
- unsigned Id; /* Id of file for debug info */
- unsigned Dumped; /* Flag: Dumped to debug info file */
+ Collection Modules; /* Modules that use this file */
};
FileInfo* ReadFileInfo (FILE* F, ObjData* O);
/* Read a file info from a file and return it */
+void AssignFileInfoIds (void);
+/* Assign the ids to the file infos */
+
void PrintDbgFileInfo (FILE* F);
/* Output the file info to a debug info file */
/* Print it */
fprintf (F,
- "line\tfile=%u,line=%lu,segment=%u,range=0x%lX-0x%lX",
+ "line\tfile=%u,line=%lu,seg=%u,range=0x%lX-0x%lX",
LI->File->Id, GetSourceLine (LI), S->Seg->Id,
S->Offs, S->Offs + S->Size - 1);
#include "error.h"
#include "exports.h"
#include "fileinfo.h"
+#include "library.h"
#include "objdata.h"
#include "spool.h"
O->MTime = 0;
O->Start = 0;
O->Flags = 0;
- O->FileBaseId = 0;
O->SymBaseId = 0;
O->ScopeBaseId = 0;
O->Files = EmptyCollection;
{
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) {
+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);
+ }
+
+}
+
+
+
typedef struct ObjData ObjData;
struct ObjData {
ObjData* Next; /* Linked list of all objects */
+ unsigned Id; /* Id of this module */
unsigned Name; /* Module name */
struct Library* Lib; /* Library where module comes from */
unsigned long MTime; /* Time of last modification */
unsigned long Start; /* Start offset of data in library */
unsigned Flags;
- unsigned FileBaseId; /* Debug info base id for files */
unsigned SymBaseId; /* Debug info base id for symbols */
unsigned ScopeBaseId; /* Debug info base if for scopes */
struct Scope* GetObjScope (ObjData* Obj, unsigned Id);
/* Get a scope from an object file checking for a valid index */
+void PrintDbgModules (FILE* F);
+/* Output the modules to a debug info file */
+
/* End of objdata.h */