More stringpool use / memory savings
git-svn-id: svn://svn.cc65.org/cc65/trunk@2199 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -75,8 +75,12 @@ static unsigned ImpOpen = 0; /* Count of open imports */
|
|||||||
static unsigned ExpCount = 0; /* Export count */
|
static unsigned ExpCount = 0; /* Export count */
|
||||||
static Export** ExpPool = 0; /* Exports array */
|
static Export** ExpPool = 0; /* Exports array */
|
||||||
|
|
||||||
|
/* Defines for the flags in Import */
|
||||||
|
#define IMP_INLIST 0x0001U /* Import is in exports list */
|
||||||
|
|
||||||
/* Defines for the flags in Export */
|
/* Defines for the flags in Export */
|
||||||
#define EXP_USERMARK 0x0001
|
#define EXP_INLIST 0x0001U /* Export is in exports list */
|
||||||
|
#define EXP_USERMARK 0x0002U /* User setable flag */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -102,6 +106,7 @@ static Import* NewImport (unsigned char Type, ObjData* Obj)
|
|||||||
I->Obj = Obj;
|
I->Obj = Obj;
|
||||||
I->Exp = 0;
|
I->Exp = 0;
|
||||||
I->Name = INVALID_STRING_ID;
|
I->Name = INVALID_STRING_ID;
|
||||||
|
I->Flags = 0;
|
||||||
I->Type = Type;
|
I->Type = Type;
|
||||||
|
|
||||||
/* Return the new structure */
|
/* Return the new structure */
|
||||||
@@ -157,6 +162,24 @@ void InsertImport (Import* I)
|
|||||||
/* This is a dummy export */
|
/* This is a dummy export */
|
||||||
++ImpOpen;
|
++ImpOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark the import so we know it's in the list */
|
||||||
|
I->Flags |= IMP_INLIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FreeImport (Import* I)
|
||||||
|
/* Free an import. NOTE: This won't remove the import from the exports table,
|
||||||
|
* so it may only be called for unused imports (imports from modules that
|
||||||
|
* aren't referenced).
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* Safety */
|
||||||
|
PRECONDITION ((I->Flags & IMP_INLIST) == 0);
|
||||||
|
|
||||||
|
/* Free the struct */
|
||||||
|
xfree (I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -217,6 +240,24 @@ static Export* NewExport (unsigned char Type, unsigned Name, ObjData* Obj)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FreeExport (Export* E)
|
||||||
|
/* Free an export. NOTE: This won't remove the export from the exports table,
|
||||||
|
* so it may only be called for unused exports (exports from modules that
|
||||||
|
* aren't referenced).
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* Safety */
|
||||||
|
PRECONDITION ((E->Flags & EXP_INLIST) == 0);
|
||||||
|
|
||||||
|
/* Free the export expression */
|
||||||
|
FreeExpr (E->Expr);
|
||||||
|
|
||||||
|
/* Free the struct */
|
||||||
|
xfree (E);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void InsertExport (Export* E)
|
void InsertExport (Export* E)
|
||||||
/* Insert an exported identifier and check if it's already in the list */
|
/* Insert an exported identifier and check if it's already in the list */
|
||||||
{
|
{
|
||||||
@@ -225,6 +266,9 @@ void InsertExport (Export* E)
|
|||||||
Import* Imp;
|
Import* Imp;
|
||||||
unsigned Hash;
|
unsigned Hash;
|
||||||
|
|
||||||
|
/* Mark the export as inserted */
|
||||||
|
E->Flags |= EXP_INLIST;
|
||||||
|
|
||||||
/* Insert the export into any condes tables if needed */
|
/* Insert the export into any condes tables if needed */
|
||||||
if (IS_EXP_CONDES (E->Type)) {
|
if (IS_EXP_CONDES (E->Type)) {
|
||||||
ConDesAddExport (E);
|
ConDesAddExport (E);
|
||||||
@@ -243,35 +287,37 @@ void InsertExport (Export* E)
|
|||||||
Last = 0;
|
Last = 0;
|
||||||
L = HashTab[Hash];
|
L = HashTab[Hash];
|
||||||
do {
|
do {
|
||||||
if (L->Name == E->Name) {
|
if (L->Name == E->Name) {
|
||||||
/* This may be an unresolved external */
|
/* This may be an unresolved external */
|
||||||
if (L->Expr == 0) {
|
if (L->Expr == 0) {
|
||||||
|
|
||||||
/* This *is* an unresolved external */
|
/* This *is* an unresolved external. Use the actual export
|
||||||
|
* in E instead of the dummy one in L.
|
||||||
|
*/
|
||||||
E->Next = L->Next;
|
E->Next = L->Next;
|
||||||
E->ImpCount = L->ImpCount;
|
E->ImpCount = L->ImpCount;
|
||||||
E->ImpList = L->ImpList;
|
E->ImpList = L->ImpList;
|
||||||
if (Last) {
|
if (Last) {
|
||||||
Last->Next = E;
|
Last->Next = E;
|
||||||
} else {
|
} else {
|
||||||
HashTab[Hash] = E;
|
HashTab[Hash] = E;
|
||||||
}
|
}
|
||||||
ImpOpen -= E->ImpCount; /* Decrease open imports now */
|
ImpOpen -= E->ImpCount; /* Decrease open imports now */
|
||||||
xfree (L);
|
xfree (L);
|
||||||
/* We must run through the import list and change the
|
/* We must run through the import list and change the
|
||||||
* export pointer now.
|
* export pointer now.
|
||||||
*/
|
*/
|
||||||
Imp = E->ImpList;
|
Imp = E->ImpList;
|
||||||
while (Imp) {
|
while (Imp) {
|
||||||
Imp->Exp = E;
|
Imp->Exp = E;
|
||||||
Imp = Imp->Next;
|
Imp = Imp->Next;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Duplicate entry, ignore it */
|
/* Duplicate entry, ignore it */
|
||||||
Warning ("Duplicate external identifier: `%s'",
|
Warning ("Duplicate external identifier: `%s'",
|
||||||
GetString (L->Name));
|
GetString (L->Name));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Last = L;
|
Last = L;
|
||||||
L = L->Next;
|
L = L->Next;
|
||||||
@@ -491,15 +537,15 @@ static void CheckSymType (const Export* E)
|
|||||||
/* User defined export */
|
/* User defined export */
|
||||||
Warning ("Type mismatch for `%s', export in "
|
Warning ("Type mismatch for `%s', export in "
|
||||||
"%s(%lu), import in %s(%lu)",
|
"%s(%lu), import in %s(%lu)",
|
||||||
GetString (E->Name),
|
GetString (E->Name),
|
||||||
GetSourceFileName (E->Obj, Imp->Pos.Name),
|
GetSourceFileName (E->Obj, Imp->Pos.Name),
|
||||||
E->Pos.Line,
|
E->Pos.Line,
|
||||||
GetSourceFileName (Imp->Obj, Imp->Pos.Name),
|
GetSourceFileName (Imp->Obj, Imp->Pos.Name),
|
||||||
Imp->Pos.Line);
|
Imp->Pos.Line);
|
||||||
} else {
|
} else {
|
||||||
/* Export created by the linker */
|
/* Export created by the linker */
|
||||||
Warning ("Type mismatch for `%s', imported from %s(%lu)",
|
Warning ("Type mismatch for `%s', imported from %s(%lu)",
|
||||||
GetString (E->Name),
|
GetString (E->Name),
|
||||||
GetSourceFileName (Imp->Obj, Imp->Pos.Name),
|
GetSourceFileName (Imp->Obj, Imp->Pos.Name),
|
||||||
Imp->Pos.Line);
|
Imp->Pos.Line);
|
||||||
}
|
}
|
||||||
@@ -557,7 +603,7 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
|
|||||||
static int CmpExpName (const void* K1, const void* K2)
|
static int CmpExpName (const void* K1, const void* K2)
|
||||||
/* Compare function for qsort */
|
/* Compare function for qsort */
|
||||||
{
|
{
|
||||||
return strcmp (GetString ((*(Export**)K1)->Name),
|
return strcmp (GetString ((*(Export**)K1)->Name),
|
||||||
GetString ((*(Export**)K2)->Name));
|
GetString ((*(Export**)K2)->Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,11 +774,11 @@ void CircularRefError (const Export* E)
|
|||||||
/* Print an error about a circular reference using to define the given export */
|
/* Print an error about a circular reference using to define the given export */
|
||||||
{
|
{
|
||||||
Error ("Circular reference for symbol `%s', %s(%lu)",
|
Error ("Circular reference for symbol `%s', %s(%lu)",
|
||||||
GetString (E->Name),
|
GetString (E->Name),
|
||||||
GetSourceFileName (E->Obj, E->Pos.Name),
|
GetSourceFileName (E->Obj, E->Pos.Name),
|
||||||
E->Pos.Line);
|
E->Pos.Line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ struct Import {
|
|||||||
FilePos Pos; /* File position of reference */
|
FilePos Pos; /* File position of reference */
|
||||||
struct Export* Exp; /* Matching export for this import */
|
struct Export* Exp; /* Matching export for this import */
|
||||||
unsigned Name; /* Name if not in table */
|
unsigned Name; /* Name if not in table */
|
||||||
|
unsigned char Flags; /* Generic flags */
|
||||||
unsigned char Type; /* Type of import */
|
unsigned char Type; /* Type of import */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -103,12 +104,24 @@ typedef int (*ExpCheckFunc) (unsigned Name, void* Data);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FreeImport (Import* I);
|
||||||
|
/* Free an import. NOTE: This won't remove the import from the exports table,
|
||||||
|
* so it may only be called for unused imports (imports from modules that
|
||||||
|
* aren't referenced).
|
||||||
|
*/
|
||||||
|
|
||||||
Import* ReadImport (FILE* F, ObjData* Obj);
|
Import* ReadImport (FILE* F, ObjData* Obj);
|
||||||
/* Read an import from a file and insert it into the table */
|
/* Read an import from a file and insert it into the table */
|
||||||
|
|
||||||
void InsertImport (Import* I);
|
void InsertImport (Import* I);
|
||||||
/* Insert an import into the table */
|
/* Insert an import into the table */
|
||||||
|
|
||||||
|
void FreeExport (Export* E);
|
||||||
|
/* Free an export. NOTE: This won't remove the export from the exports table,
|
||||||
|
* so it may only be called for unused exports (exports from modules that
|
||||||
|
* aren't referenced).
|
||||||
|
*/
|
||||||
|
|
||||||
Export* ReadExport (FILE* F, ObjData* Obj);
|
Export* ReadExport (FILE* F, ObjData* Obj);
|
||||||
/* Read an export from a file */
|
/* Read an export from a file */
|
||||||
|
|
||||||
|
|||||||
@@ -49,9 +49,10 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "exports.h"
|
#include "exports.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
|
#include "library.h"
|
||||||
#include "objdata.h"
|
#include "objdata.h"
|
||||||
#include "objfile.h"
|
#include "objfile.h"
|
||||||
#include "library.h"
|
#include "spool.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -63,19 +64,18 @@
|
|||||||
|
|
||||||
/* Library data */
|
/* Library data */
|
||||||
static FILE* Lib = 0;
|
static FILE* Lib = 0;
|
||||||
static char* LibName = 0;
|
|
||||||
static unsigned ModuleCount = 0;
|
static unsigned ModuleCount = 0;
|
||||||
static ObjData** Index = 0;
|
static ObjData** Index = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Reading file data structures */
|
/* Reading file data structures */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void LibReadObjHeader (ObjData* O)
|
static void LibReadObjHeader (ObjData* O, const char* LibName)
|
||||||
/* Read the header of the object file checking the signature */
|
/* Read the header of the object file checking the signature */
|
||||||
{
|
{
|
||||||
O->Header.Magic = Read32 (Lib);
|
O->Header.Magic = Read32 (Lib);
|
||||||
@@ -117,10 +117,14 @@ static ObjData* ReadIndexEntry (void)
|
|||||||
/* Create a new entry and insert it into the list */
|
/* Create a new entry and insert it into the list */
|
||||||
ObjData* O = NewObjData ();
|
ObjData* O = NewObjData ();
|
||||||
|
|
||||||
/* Module name/flags/MTime/Start/Size */
|
/* Module name */
|
||||||
O->Name = ReadStr (Lib);
|
char* Name = ReadStr (Lib);
|
||||||
|
O->Name = GetStringId (Name);
|
||||||
|
xfree (Name);
|
||||||
|
|
||||||
|
/* Module flags/MTime/Start/Size */
|
||||||
O->Flags = Read16 (Lib);
|
O->Flags = Read16 (Lib);
|
||||||
Read32 (Lib); /* Skip MTime */
|
O->MTime = Read32 (Lib);
|
||||||
O->Start = Read32 (Lib);
|
O->Start = Read32 (Lib);
|
||||||
Read32 (Lib); /* Skip Size */
|
Read32 (Lib); /* Skip Size */
|
||||||
|
|
||||||
@@ -208,13 +212,14 @@ void LibAdd (FILE* F, const char* Name)
|
|||||||
* be satisfied.
|
* be satisfied.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int Add;
|
unsigned LibName;
|
||||||
|
int HaveAdditions;
|
||||||
unsigned I;
|
unsigned I;
|
||||||
LibHeader Header;
|
LibHeader Header;
|
||||||
|
|
||||||
/* Store the parameters, so they're visible for other routines */
|
/* Store the parameters, so they're visible for other routines */
|
||||||
Lib = F;
|
Lib = F;
|
||||||
LibName = xstrdup (Name);
|
LibName = GetStringId (Name);
|
||||||
|
|
||||||
/* Read the remaining header fields (magic is already read) */
|
/* Read the remaining header fields (magic is already read) */
|
||||||
Header.Magic = LIB_MAGIC;
|
Header.Magic = LIB_MAGIC;
|
||||||
@@ -235,27 +240,31 @@ void LibAdd (FILE* F, const char* Name)
|
|||||||
* were added.
|
* were added.
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
Add = 0;
|
HaveAdditions = 0;
|
||||||
for (I = 0; I < ModuleCount; ++I) {
|
for (I = 0; I < ModuleCount; ++I) {
|
||||||
ObjData* O = Index [I];
|
ObjData* O = Index [I];
|
||||||
if ((O->Flags & OBJ_REF) == 0) {
|
if ((O->Flags & OBJ_REF) == 0) {
|
||||||
LibCheckExports (O);
|
LibCheckExports (O);
|
||||||
if (O->Flags & OBJ_REF) {
|
if (O->Flags & OBJ_REF) {
|
||||||
/* The routine added the file */
|
/* The routine added the file */
|
||||||
Add = 1;
|
HaveAdditions = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (Add);
|
} while (HaveAdditions);
|
||||||
|
|
||||||
/* Add the files list and sections for all requested modules */
|
/* Add the files list and sections for all requested modules */
|
||||||
for (I = 0; I < ModuleCount; ++I) {
|
for (I = 0; I < ModuleCount; ++I) {
|
||||||
|
|
||||||
|
/* Get the object data */
|
||||||
ObjData* O = Index [I];
|
ObjData* O = Index [I];
|
||||||
|
|
||||||
|
/* Is this object file referenced? */
|
||||||
if (O->Flags & OBJ_REF) {
|
if (O->Flags & OBJ_REF) {
|
||||||
|
|
||||||
/* Seek to the start of the object file and read the header */
|
/* Seek to the start of the object file and read the header */
|
||||||
fseek (Lib, O->Start, SEEK_SET);
|
fseek (Lib, O->Start, SEEK_SET);
|
||||||
LibReadObjHeader (O);
|
LibReadObjHeader (O, Name);
|
||||||
|
|
||||||
/* Seek to the start of the files list and read the files list */
|
/* Seek to the start of the files list and read the files list */
|
||||||
fseek (Lib, O->Start + O->Header.FileOffs, SEEK_SET);
|
fseek (Lib, O->Start + O->Header.FileOffs, SEEK_SET);
|
||||||
@@ -276,24 +285,29 @@ void LibAdd (FILE* F, const char* Name)
|
|||||||
fseek (Lib, O->Start + O->Header.SegOffs, SEEK_SET);
|
fseek (Lib, O->Start + O->Header.SegOffs, SEEK_SET);
|
||||||
ObjReadSections (Lib, O);
|
ObjReadSections (Lib, O);
|
||||||
|
|
||||||
/* We have the data now */
|
/* Add a pointer to the library name */
|
||||||
O->Flags |= OBJ_HAVEDATA;
|
O->LibName = LibName;
|
||||||
}
|
|
||||||
|
|
||||||
/* All references to strings are now resolved, so we can delete
|
/* All references to strings are now resolved, so we can delete
|
||||||
* the module string pool.
|
* the module string pool.
|
||||||
*/
|
*/
|
||||||
FreeObjStrings (O);
|
FreeObjStrings (O);
|
||||||
|
|
||||||
/* Add a pointer to the library name */
|
/* Insert the object into the list of all used object files */
|
||||||
O->LibName = LibName;
|
InsertObjData (O);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* Unreferenced object file, remove it */
|
||||||
|
FreeObjData (O);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Done. Close the file, release allocated memory */
|
/* Done. Close the file, release allocated memory */
|
||||||
fclose (F);
|
fclose (F);
|
||||||
xfree (Index);
|
xfree (Index);
|
||||||
Lib = 0;
|
Lib = 0;
|
||||||
LibName = 0;
|
|
||||||
ModuleCount = 0;
|
ModuleCount = 0;
|
||||||
Index = 0;
|
Index = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,6 @@
|
|||||||
void CreateMapFile (void)
|
void CreateMapFile (void)
|
||||||
/* Create a map file */
|
/* Create a map file */
|
||||||
{
|
{
|
||||||
ObjData* O;
|
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
/* Open the map file */
|
/* Open the map file */
|
||||||
@@ -72,28 +71,30 @@ void CreateMapFile (void)
|
|||||||
/* Write a modules list */
|
/* Write a modules list */
|
||||||
fprintf (F, "Modules list:\n"
|
fprintf (F, "Modules list:\n"
|
||||||
"-------------\n");
|
"-------------\n");
|
||||||
O = ObjRoot;
|
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
||||||
while (O) {
|
|
||||||
if (O->Flags & OBJ_HAVEDATA) {
|
unsigned J;
|
||||||
/* We've linked this module */
|
|
||||||
if (O->LibName) {
|
/* Get the object file */
|
||||||
/* The file is from a library */
|
const ObjData* O = CollConstAt (&ObjDataList, I);
|
||||||
fprintf (F, "%s(%s):\n", O->LibName, GetObjFileName (O));
|
|
||||||
} else {
|
/* Output the data */
|
||||||
fprintf (F, "%s:\n", GetObjFileName (O));
|
if (O->LibName != INVALID_STRING_ID) {
|
||||||
}
|
/* The file is from a library */
|
||||||
for (I = 0; I < O->SectionCount; ++I) {
|
fprintf (F, "%s(%s):\n", GetString (O->LibName), GetObjFileName (O));
|
||||||
const Section* S = O->Sections [I];
|
} else {
|
||||||
/* Don't include zero sized sections if not explicitly
|
fprintf (F, "%s:\n", GetObjFileName (O));
|
||||||
* requested
|
}
|
||||||
*/
|
for (J = 0; J < O->SectionCount; ++J) {
|
||||||
if (VerboseMap || S->Size > 0) {
|
const Section* S = O->Sections [J];
|
||||||
fprintf (F, " %-15s Offs = %06lX Size = %06lX\n",
|
/* Don't include zero sized sections if not explicitly
|
||||||
GetString (S->Seg->Name), S->Offs, S->Size);
|
* requested
|
||||||
}
|
*/
|
||||||
}
|
if (VerboseMap || S->Size > 0) {
|
||||||
}
|
fprintf (F, " %-15s Offs = %06lX Size = %06lX\n",
|
||||||
O = O->Next;
|
GetString (S->Seg->Name), S->Offs, S->Size);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the segment list */
|
/* Write the segment list */
|
||||||
@@ -125,7 +126,7 @@ void CreateMapFile (void)
|
|||||||
void CreateLabelFile (void)
|
void CreateLabelFile (void)
|
||||||
/* Create a label file */
|
/* Create a label file */
|
||||||
{
|
{
|
||||||
ObjData* O;
|
unsigned I;
|
||||||
|
|
||||||
/* Open the label file */
|
/* Open the label file */
|
||||||
FILE* F = fopen (LabelFileName, "w");
|
FILE* F = fopen (LabelFileName, "w");
|
||||||
@@ -136,15 +137,14 @@ void CreateLabelFile (void)
|
|||||||
/* Print the labels for the export symbols */
|
/* Print the labels for the export symbols */
|
||||||
PrintExportLabels (F);
|
PrintExportLabels (F);
|
||||||
|
|
||||||
/* Print debug symbols from all modules we have linked into the output file */
|
/* Create labels from all modules we have linked into the output file */
|
||||||
O = ObjRoot;
|
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
||||||
while (O) {
|
|
||||||
if (O->Flags & OBJ_HAVEDATA) {
|
|
||||||
/* We've linked this module */
|
|
||||||
PrintDbgSymLabels (O, F);
|
|
||||||
|
|
||||||
}
|
/* Get the object file */
|
||||||
O = O->Next;
|
ObjData* O = CollAtUnchecked (&ObjDataList, I);
|
||||||
|
|
||||||
|
/* Output the labels */
|
||||||
|
PrintDbgSymLabels (O, F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we should mark write protected areas as such, do it */
|
/* If we should mark write protected areas as such, do it */
|
||||||
@@ -174,7 +174,7 @@ void CreateLabelFile (void)
|
|||||||
void CreateDbgFile (void)
|
void CreateDbgFile (void)
|
||||||
/* Create a debug info file */
|
/* Create a debug info file */
|
||||||
{
|
{
|
||||||
ObjData* O;
|
unsigned I;
|
||||||
|
|
||||||
/* Open the debug info file */
|
/* Open the debug info file */
|
||||||
FILE* F = fopen (DbgFileName, "w");
|
FILE* F = fopen (DbgFileName, "w");
|
||||||
@@ -183,14 +183,13 @@ void CreateDbgFile (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Print line infos from all modules we have linked into the output file */
|
/* Print line infos from all modules we have linked into the output file */
|
||||||
O = ObjRoot;
|
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
||||||
while (O) {
|
|
||||||
if (O->Flags & OBJ_HAVEDATA) {
|
|
||||||
/* We've linked this module */
|
|
||||||
PrintDbgInfo (O, F);
|
|
||||||
|
|
||||||
}
|
/* Get the object file */
|
||||||
O = O->Next;
|
ObjData* O = CollAtUnchecked (&ObjDataList, I);
|
||||||
|
|
||||||
|
/* Output debug info */
|
||||||
|
PrintDbgInfo (O, F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close the file */
|
/* Close the file */
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
/* ld65 */
|
/* ld65 */
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "exports.h"
|
||||||
#include "fileinfo.h"
|
#include "fileinfo.h"
|
||||||
#include "objdata.h"
|
#include "objdata.h"
|
||||||
#include "spool.h"
|
#include "spool.h"
|
||||||
@@ -53,11 +54,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Object data list management */
|
/* Collection containing used ObjData objects */
|
||||||
unsigned ObjCount = 0; /* Count of object files in the list */
|
Collection ObjDataList = STATIC_COLLECTION_INITIALIZER;
|
||||||
ObjData* ObjRoot = 0; /* List of object files */
|
|
||||||
ObjData* ObjLast = 0; /* Last entry in list */
|
|
||||||
ObjData** ObjPool = 0; /* Object files as array */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -75,8 +73,9 @@ ObjData* NewObjData (void)
|
|||||||
|
|
||||||
/* Initialize the data */
|
/* Initialize the data */
|
||||||
O->Next = 0;
|
O->Next = 0;
|
||||||
O->Name = 0;
|
O->Name = INVALID_STRING_ID;
|
||||||
O->LibName = 0;
|
O->LibName = INVALID_STRING_ID;
|
||||||
|
O->MTime = 0;
|
||||||
O->Flags = 0;
|
O->Flags = 0;
|
||||||
O->Start = 0;
|
O->Start = 0;
|
||||||
O->ExportCount = 0;
|
O->ExportCount = 0;
|
||||||
@@ -90,24 +89,33 @@ ObjData* NewObjData (void)
|
|||||||
O->StringCount = 0;
|
O->StringCount = 0;
|
||||||
O->Strings = 0;
|
O->Strings = 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;
|
|
||||||
|
|
||||||
/* Return the new entry */
|
/* Return the new entry */
|
||||||
return O;
|
return O;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FreeObjData (ObjData* O)
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* Unused ObjData do only have the string pool, Exports and Imports. */
|
||||||
|
while (O->ExportCount) {
|
||||||
|
FreeExport (O->Exports[--O->ExportCount]);
|
||||||
|
}
|
||||||
|
xfree (O->Exports);
|
||||||
|
while (O->ImportCount) {
|
||||||
|
FreeImport (O->Imports[--O->ImportCount]);
|
||||||
|
}
|
||||||
|
xfree (O->Imports);
|
||||||
|
FreeObjStrings (O);
|
||||||
|
xfree (O);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FreeObjStrings (ObjData* O)
|
void FreeObjStrings (ObjData* O)
|
||||||
/* Free the module string data. Used once the object file is loaded completely
|
/* Free the module string data. Used once the object file is loaded completely
|
||||||
* when all strings are converted to global strings.
|
* when all strings are converted to global strings.
|
||||||
@@ -122,6 +130,14 @@ void FreeObjStrings (ObjData* O)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void InsertObjData (ObjData* O)
|
||||||
|
/* Insert the ObjData object into the collection of used ObjData objects. */
|
||||||
|
{
|
||||||
|
CollAppend (&ObjDataList, O);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetObjString (const ObjData* O, unsigned Index)
|
const char* GetObjString (const ObjData* O, unsigned Index)
|
||||||
/* Get a string from the object file string table. Abort if the string index
|
/* Get a string from the object file string table. Abort if the string index
|
||||||
* is invalid.
|
* is invalid.
|
||||||
@@ -153,7 +169,7 @@ const char* GetObjFileName (const ObjData* O)
|
|||||||
* file is NULL.
|
* file is NULL.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
return O? O->Name : "[linker generated]";
|
return O? GetString (O->Name) : "[linker generated]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "coll.h"
|
||||||
#include "objdefs.h"
|
#include "objdefs.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -51,16 +52,14 @@
|
|||||||
|
|
||||||
/* Values for the Flags field */
|
/* Values for the Flags field */
|
||||||
#define OBJ_REF 0x0001 /* We have a reference to this file */
|
#define OBJ_REF 0x0001 /* We have a reference to this file */
|
||||||
#define OBJ_HAVEDATA 0x0002 /* We have this object file already */
|
|
||||||
#define OBJ_MARKED 0x0004 /* Generic marker bit */
|
|
||||||
|
|
||||||
|
|
||||||
/* Internal structure holding object file data */
|
/* Internal structure holding object file data */
|
||||||
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 */
|
||||||
char* Name; /* Module name */
|
unsigned Name; /* Module name */
|
||||||
char* LibName; /* Name of library */
|
unsigned LibName; /* Name of library */
|
||||||
|
unsigned long MTime; /* Time of last modification */
|
||||||
ObjHeader Header; /* Header of file */
|
ObjHeader Header; /* Header of file */
|
||||||
unsigned long Start; /* Start offset of data in library */
|
unsigned long Start; /* Start offset of data in library */
|
||||||
unsigned Flags;
|
unsigned Flags;
|
||||||
@@ -82,15 +81,13 @@ struct ObjData {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Object data list management */
|
/* Collection containing used ObjData objects */
|
||||||
extern unsigned ObjCount; /* Count of files in the list */
|
extern Collection ObjDataList;
|
||||||
extern ObjData* ObjRoot; /* List of object files */
|
|
||||||
extern ObjData* ObjLast; /* Last entry in list */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@@ -98,11 +95,20 @@ extern ObjData* ObjLast; /* Last entry in list */
|
|||||||
ObjData* NewObjData (void);
|
ObjData* NewObjData (void);
|
||||||
/* Allocate a new structure on the heap, insert it into the list, return it */
|
/* Allocate a new structure on the heap, insert it into the list, return it */
|
||||||
|
|
||||||
|
void FreeObjData (ObjData* O);
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
void FreeObjStrings (ObjData* O);
|
void FreeObjStrings (ObjData* O);
|
||||||
/* Free the module string data. Used once the object file is loaded completely
|
/* Free the module string data. Used once the object file is loaded completely
|
||||||
* when all strings are converted to global strings.
|
* when all strings are converted to global strings.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void InsertObjData (ObjData* O);
|
||||||
|
/* Insert the ObjData object into the collection of used ObjData objects. */
|
||||||
|
|
||||||
const char* GetObjString (const ObjData* O, unsigned Index);
|
const char* GetObjString (const ObjData* O, unsigned Index);
|
||||||
/* Get a string from the object file string table. Abort if the string index
|
/* Get a string from the object file string table. Abort if the string index
|
||||||
* is invalid.
|
* is invalid.
|
||||||
|
|||||||
@@ -51,8 +51,9 @@
|
|||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "lineinfo.h"
|
#include "lineinfo.h"
|
||||||
#include "objdata.h"
|
#include "objdata.h"
|
||||||
#include "segments.h"
|
|
||||||
#include "objfile.h"
|
#include "objfile.h"
|
||||||
|
#include "segments.h"
|
||||||
|
#include "spool.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -62,15 +63,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char* GetModule (const char* Name)
|
static unsigned GetModule (const char* Name)
|
||||||
/* Get a module name from the file name */
|
/* Get a module name index from the file name */
|
||||||
{
|
{
|
||||||
/* Make a module name from the file name */
|
/* Make a module name from the file name */
|
||||||
const char* Module = FindName (Name);
|
const char* Module = FindName (Name);
|
||||||
if (*Module == 0) {
|
if (*Module == 0) {
|
||||||
Error ("Cannot make module name from `%s'", Name);
|
Error ("Cannot make module name from `%s'", Name);
|
||||||
}
|
}
|
||||||
return Module;
|
return GetStringId (Module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -216,8 +217,7 @@ void ObjAdd (FILE* Obj, const char* Name)
|
|||||||
ObjReadHeader (Obj, &O->Header, Name);
|
ObjReadHeader (Obj, &O->Header, Name);
|
||||||
|
|
||||||
/* Initialize the object module data structure */
|
/* Initialize the object module data structure */
|
||||||
O->Name = xstrdup (GetModule (Name));
|
O->Name = GetModule (Name);
|
||||||
O->Flags = OBJ_HAVEDATA;
|
|
||||||
|
|
||||||
/* Read the string pool from the object file */
|
/* Read the string pool from the object file */
|
||||||
fseek (Obj, O->Header.StrPoolOffs, SEEK_SET);
|
fseek (Obj, O->Header.StrPoolOffs, SEEK_SET);
|
||||||
@@ -251,7 +251,7 @@ void ObjAdd (FILE* Obj, const char* Name)
|
|||||||
ObjReadSections (Obj, O);
|
ObjReadSections (Obj, O);
|
||||||
|
|
||||||
/* Mark this object file as needed */
|
/* Mark this object file as needed */
|
||||||
O->Flags |= OBJ_REF | OBJ_HAVEDATA;
|
O->Flags |= OBJ_REF;
|
||||||
|
|
||||||
/* Done, close the file (we read it only, so no error check) */
|
/* Done, close the file (we read it only, so no error check) */
|
||||||
fclose (Obj);
|
fclose (Obj);
|
||||||
@@ -260,6 +260,9 @@ void ObjAdd (FILE* Obj, const char* Name)
|
|||||||
* string pool.
|
* string pool.
|
||||||
*/
|
*/
|
||||||
FreeObjStrings (O);
|
FreeObjStrings (O);
|
||||||
|
|
||||||
|
/* Insert the object into the list of all used object files */
|
||||||
|
InsertObjData (O);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user