mirror of
https://github.com/cc65/cc65.git
synced 2025-08-08 06:25:17 +00:00
Debug info: Make file info ids continous. Output modules that use a file.
git-svn-id: svn://svn.cc65.org/cc65/trunk@5128 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -56,17 +56,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void AssignBaseIds (void)
|
static void AssignIds (void)
|
||||||
/* Assign the base ids for debug info output. Within each module, many of the
|
/* 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
|
* 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
|
* the collections. To make them unique, we must assign a unique base to each
|
||||||
* range.
|
* range.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned I;
|
|
||||||
|
|
||||||
/* Walk over all modules */
|
/* Walk over all modules */
|
||||||
unsigned FileBaseId = 0;
|
unsigned I;
|
||||||
unsigned SymBaseId = 0;
|
unsigned SymBaseId = 0;
|
||||||
unsigned ScopeBaseId = 0;
|
unsigned ScopeBaseId = 0;
|
||||||
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
||||||
@@ -74,16 +72,20 @@ static void AssignBaseIds (void)
|
|||||||
/* Get this module */
|
/* Get this module */
|
||||||
ObjData* O = CollAt (&ObjDataList, I);
|
ObjData* O = CollAt (&ObjDataList, I);
|
||||||
|
|
||||||
/* Assign ids */
|
/* Assign the module id */
|
||||||
O->FileBaseId = FileBaseId;
|
O->Id = I;
|
||||||
|
|
||||||
|
/* Assign base ids */
|
||||||
O->SymBaseId = SymBaseId;
|
O->SymBaseId = SymBaseId;
|
||||||
O->ScopeBaseId = ScopeBaseId;
|
O->ScopeBaseId = ScopeBaseId;
|
||||||
|
|
||||||
/* Bump the base ids */
|
/* Bump the base ids */
|
||||||
FileBaseId += CollCount (&O->Files);
|
|
||||||
SymBaseId += CollCount (&O->DbgSyms);
|
SymBaseId += CollCount (&O->DbgSyms);
|
||||||
ScopeBaseId += CollCount (&O->Scopes);
|
ScopeBaseId += CollCount (&O->Scopes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assign the ids to the file infos */
|
||||||
|
AssignFileInfoIds ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -91,8 +93,6 @@ static void AssignBaseIds (void)
|
|||||||
void CreateDbgFile (void)
|
void CreateDbgFile (void)
|
||||||
/* Create a debug info file */
|
/* Create a debug info file */
|
||||||
{
|
{
|
||||||
unsigned I;
|
|
||||||
|
|
||||||
/* Open the debug info file */
|
/* Open the debug info file */
|
||||||
FILE* F = fopen (DbgFileName, "w");
|
FILE* F = fopen (DbgFileName, "w");
|
||||||
if (F == 0) {
|
if (F == 0) {
|
||||||
@@ -102,36 +102,14 @@ void CreateDbgFile (void)
|
|||||||
/* Output version information */
|
/* Output version information */
|
||||||
fprintf (F, "version\tmajor=1,minor=2\n");
|
fprintf (F, "version\tmajor=1,minor=2\n");
|
||||||
|
|
||||||
/* Assign the base ids to the modules */
|
/* Assign the ids to the items */
|
||||||
AssignBaseIds ();
|
AssignIds ();
|
||||||
|
|
||||||
/* Output libraries */
|
/* Output libraries */
|
||||||
PrintDbgLibraries (F);
|
PrintDbgLibraries (F);
|
||||||
|
|
||||||
/* Output modules */
|
/* Output modules */
|
||||||
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
PrintDbgModules (F);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output the segment info */
|
/* Output the segment info */
|
||||||
PrintDbgSegments (F);
|
PrintDbgSegments (F);
|
||||||
|
@@ -102,18 +102,18 @@ static int FindFileInfo (unsigned Name, unsigned* Index)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
/* 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 */
|
/* Allocate memory */
|
||||||
FileInfo* FI = xmalloc (sizeof (FileInfo));
|
FileInfo* FI = xmalloc (sizeof (FileInfo));
|
||||||
|
|
||||||
/* Initialize stuff */
|
/* Initialize stuff */
|
||||||
FI->Id = Id++;
|
FI->Id = ~0U;
|
||||||
FI->Dumped = 0;
|
FI->Name = Name;
|
||||||
|
FI->MTime = MTime;
|
||||||
|
FI->Size = Size;
|
||||||
|
FI->Modules = EmptyCollection;
|
||||||
|
|
||||||
/* Return the new struct */
|
/* Return the new struct */
|
||||||
return FI;
|
return FI;
|
||||||
@@ -121,6 +121,18 @@ static FileInfo* NewFileInfo (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
FileInfo* ReadFileInfo (FILE* F, ObjData* O)
|
||||||
/* Read a file info from a file and return it */
|
/* Read a file info from a file and return it */
|
||||||
{
|
{
|
||||||
@@ -145,7 +157,8 @@ FileInfo* ReadFileInfo (FILE* F, ObjData* O)
|
|||||||
|
|
||||||
/* Check size and modification time stamp */
|
/* Check size and modification time stamp */
|
||||||
if (FI->Size == Size && FI->MTime == MTime) {
|
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;
|
return FI;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,12 +177,10 @@ FileInfo* ReadFileInfo (FILE* F, ObjData* O)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Not found. Allocate a new FileInfo structure */
|
/* Not found. Allocate a new FileInfo structure */
|
||||||
FI = NewFileInfo ();
|
FI = NewFileInfo (Name, MTime, Size);
|
||||||
|
|
||||||
/* Set the fields */
|
/* Remember that this module uses the file info */
|
||||||
FI->Name = Name;
|
CollAppend (&FI->Modules, O);
|
||||||
FI->MTime = MTime;
|
|
||||||
FI->Size = Size;
|
|
||||||
|
|
||||||
/* Insert the file info in our global list. Index points to the insert
|
/* Insert the file info in our global list. Index points to the insert
|
||||||
* position.
|
* position.
|
||||||
@@ -182,27 +193,64 @@ FileInfo* ReadFileInfo (FILE* F, ObjData* O)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
void PrintDbgFileInfo (FILE* F)
|
||||||
/* Output the file info to a debug info file */
|
/* Output the file info to a debug info file */
|
||||||
{
|
{
|
||||||
unsigned I, J;
|
unsigned I, J;
|
||||||
|
|
||||||
/* Print file infos from all modules we have linked into the output file */
|
/* Print all file infos */
|
||||||
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
for (I = 0; I < CollCount (&FileInfos); ++I) {
|
||||||
|
|
||||||
/* Get the object file */
|
/* Get the file info */
|
||||||
ObjData* O = CollAtUnchecked (&ObjDataList, I);
|
const FileInfo* FI = CollAtUnchecked (&FileInfos, I);
|
||||||
|
|
||||||
/* Output the files section */
|
/* Base info */
|
||||||
for (J = 0; J < CollCount (&O->Files); ++J) {
|
fprintf (F,
|
||||||
FileInfo* FI = CollAt (&O->Files, J);
|
"file\tid=%u,name=\"%s\",size=%lu,mtime=0x%08lX,mod=",
|
||||||
if (!FI->Dumped) {
|
FI->Id, GetString (FI->Name), FI->Size, FI->MTime);
|
||||||
fprintf (F,
|
|
||||||
"file\tid=%u,name=\"%s\",size=%lu,mtime=0x%08lX\n",
|
/* Modules that use the file */
|
||||||
FI->Id, GetString (FI->Name), FI->Size, FI->MTime);
|
for (J = 0; J < CollCount (&FI->Modules); ++J) {
|
||||||
FI->Dumped = 1;
|
|
||||||
|
/* 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -57,11 +57,11 @@
|
|||||||
|
|
||||||
typedef struct FileInfo FileInfo;
|
typedef struct FileInfo FileInfo;
|
||||||
struct FileInfo {
|
struct FileInfo {
|
||||||
|
unsigned Id; /* Id of file for debug info */
|
||||||
unsigned Name; /* File name index */
|
unsigned Name; /* File name index */
|
||||||
unsigned long MTime; /* Time of last modification */
|
unsigned long MTime; /* Time of last modification */
|
||||||
unsigned long Size; /* Size of the file */
|
unsigned long Size; /* Size of the file */
|
||||||
unsigned Id; /* Id of file for debug info */
|
Collection Modules; /* Modules that use this file */
|
||||||
unsigned Dumped; /* Flag: Dumped to debug info file */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -75,6 +75,9 @@ struct FileInfo {
|
|||||||
FileInfo* ReadFileInfo (FILE* F, ObjData* O);
|
FileInfo* ReadFileInfo (FILE* F, ObjData* O);
|
||||||
/* Read a file info from a file and return it */
|
/* Read a file info from a file and return it */
|
||||||
|
|
||||||
|
void AssignFileInfoIds (void);
|
||||||
|
/* Assign the ids to the file infos */
|
||||||
|
|
||||||
void PrintDbgFileInfo (FILE* F);
|
void PrintDbgFileInfo (FILE* F);
|
||||||
/* Output the file info to a debug info file */
|
/* Output the file info to a debug info file */
|
||||||
|
|
||||||
|
@@ -236,7 +236,7 @@ void PrintDbgLineInfo (FILE* F)
|
|||||||
|
|
||||||
/* Print it */
|
/* Print it */
|
||||||
fprintf (F,
|
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,
|
LI->File->Id, GetSourceLine (LI), S->Seg->Id,
|
||||||
S->Offs, S->Offs + S->Size - 1);
|
S->Offs, S->Offs + S->Size - 1);
|
||||||
|
|
||||||
|
@@ -43,6 +43,7 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "exports.h"
|
#include "exports.h"
|
||||||
#include "fileinfo.h"
|
#include "fileinfo.h"
|
||||||
|
#include "library.h"
|
||||||
#include "objdata.h"
|
#include "objdata.h"
|
||||||
#include "spool.h"
|
#include "spool.h"
|
||||||
|
|
||||||
@@ -78,7 +79,6 @@ ObjData* NewObjData (void)
|
|||||||
O->MTime = 0;
|
O->MTime = 0;
|
||||||
O->Start = 0;
|
O->Start = 0;
|
||||||
O->Flags = 0;
|
O->Flags = 0;
|
||||||
O->FileBaseId = 0;
|
|
||||||
O->SymBaseId = 0;
|
O->SymBaseId = 0;
|
||||||
O->ScopeBaseId = 0;
|
O->ScopeBaseId = 0;
|
||||||
O->Files = EmptyCollection;
|
O->Files = EmptyCollection;
|
||||||
@@ -106,6 +106,9 @@ void FreeObjData (ObjData* O)
|
|||||||
{
|
{
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
|
for (I = 0; I < CollCount (&O->Files); ++I) {
|
||||||
|
CollDeleteItem (&((FileInfo*) CollAtUnchecked (&O->Files, I))->Modules, O);
|
||||||
|
}
|
||||||
DoneCollection (&O->Files);
|
DoneCollection (&O->Files);
|
||||||
DoneCollection (&O->Sections);
|
DoneCollection (&O->Sections);
|
||||||
for (I = 0; I < CollCount (&O->Exports); ++I) {
|
for (I = 0; I < CollCount (&O->Exports); ++I) {
|
||||||
@@ -213,3 +216,37 @@ struct Scope* GetObjScope (ObjData* O, unsigned Id)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -63,6 +63,7 @@ struct Section;
|
|||||||
typedef struct ObjData ObjData;
|
typedef struct ObjData ObjData;
|
||||||
struct ObjData {
|
struct ObjData {
|
||||||
ObjData* Next; /* Linked list of all objects */
|
ObjData* Next; /* Linked list of all objects */
|
||||||
|
unsigned Id; /* Id of this module */
|
||||||
unsigned Name; /* Module name */
|
unsigned Name; /* Module name */
|
||||||
struct Library* Lib; /* Library where module comes from */
|
struct Library* Lib; /* Library where module comes from */
|
||||||
unsigned long MTime; /* Time of last modification */
|
unsigned long MTime; /* Time of last modification */
|
||||||
@@ -70,7 +71,6 @@ struct ObjData {
|
|||||||
unsigned long Start; /* Start offset of data in library */
|
unsigned long Start; /* Start offset of data in library */
|
||||||
unsigned Flags;
|
unsigned Flags;
|
||||||
|
|
||||||
unsigned FileBaseId; /* Debug info base id for files */
|
|
||||||
unsigned SymBaseId; /* Debug info base id for symbols */
|
unsigned SymBaseId; /* Debug info base id for symbols */
|
||||||
unsigned ScopeBaseId; /* Debug info base if for scopes */
|
unsigned ScopeBaseId; /* Debug info base if for scopes */
|
||||||
|
|
||||||
@@ -145,6 +145,9 @@ struct Section* GetObjSection (ObjData* Obj, unsigned Id);
|
|||||||
struct Scope* GetObjScope (ObjData* Obj, unsigned Id);
|
struct Scope* GetObjScope (ObjData* Obj, unsigned Id);
|
||||||
/* Get a scope from an object file checking for a valid index */
|
/* 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 */
|
/* End of objdata.h */
|
||||||
|
Reference in New Issue
Block a user