mirror of
https://github.com/cc65/cc65.git
synced 2025-01-12 17:30:50 +00:00
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:
parent
cea9aff3ef
commit
eb5637b6e4
@ -75,8 +75,12 @@ static unsigned ImpOpen = 0; /* Count of open imports */
|
||||
static unsigned ExpCount = 0; /* Export count */
|
||||
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 */
|
||||
#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->Exp = 0;
|
||||
I->Name = INVALID_STRING_ID;
|
||||
I->Flags = 0;
|
||||
I->Type = Type;
|
||||
|
||||
/* Return the new structure */
|
||||
@ -157,6 +162,24 @@ void InsertImport (Import* I)
|
||||
/* This is a dummy export */
|
||||
++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)
|
||||
/* Insert an exported identifier and check if it's already in the list */
|
||||
{
|
||||
@ -225,6 +266,9 @@ void InsertExport (Export* E)
|
||||
Import* Imp;
|
||||
unsigned Hash;
|
||||
|
||||
/* Mark the export as inserted */
|
||||
E->Flags |= EXP_INLIST;
|
||||
|
||||
/* Insert the export into any condes tables if needed */
|
||||
if (IS_EXP_CONDES (E->Type)) {
|
||||
ConDesAddExport (E);
|
||||
@ -243,35 +287,37 @@ void InsertExport (Export* E)
|
||||
Last = 0;
|
||||
L = HashTab[Hash];
|
||||
do {
|
||||
if (L->Name == E->Name) {
|
||||
if (L->Name == E->Name) {
|
||||
/* This may be an unresolved external */
|
||||
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->ImpCount = L->ImpCount;
|
||||
E->ImpList = L->ImpList;
|
||||
if (Last) {
|
||||
Last->Next = E;
|
||||
} else {
|
||||
if (Last) {
|
||||
Last->Next = E;
|
||||
} else {
|
||||
HashTab[Hash] = E;
|
||||
}
|
||||
}
|
||||
ImpOpen -= E->ImpCount; /* Decrease open imports now */
|
||||
xfree (L);
|
||||
/* We must run through the import list and change the
|
||||
xfree (L);
|
||||
/* We must run through the import list and change the
|
||||
* export pointer now.
|
||||
*/
|
||||
Imp = E->ImpList;
|
||||
while (Imp) {
|
||||
Imp->Exp = E;
|
||||
Imp = Imp->Next;
|
||||
}
|
||||
} else {
|
||||
/* Duplicate entry, ignore it */
|
||||
Warning ("Duplicate external identifier: `%s'",
|
||||
*/
|
||||
Imp = E->ImpList;
|
||||
while (Imp) {
|
||||
Imp->Exp = E;
|
||||
Imp = Imp->Next;
|
||||
}
|
||||
} else {
|
||||
/* Duplicate entry, ignore it */
|
||||
Warning ("Duplicate external identifier: `%s'",
|
||||
GetString (L->Name));
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
Last = L;
|
||||
L = L->Next;
|
||||
@ -491,15 +537,15 @@ static void CheckSymType (const Export* E)
|
||||
/* User defined export */
|
||||
Warning ("Type mismatch for `%s', export in "
|
||||
"%s(%lu), import in %s(%lu)",
|
||||
GetString (E->Name),
|
||||
GetString (E->Name),
|
||||
GetSourceFileName (E->Obj, Imp->Pos.Name),
|
||||
E->Pos.Line,
|
||||
E->Pos.Line,
|
||||
GetSourceFileName (Imp->Obj, Imp->Pos.Name),
|
||||
Imp->Pos.Line);
|
||||
} else {
|
||||
/* Export created by the linker */
|
||||
Warning ("Type mismatch for `%s', imported from %s(%lu)",
|
||||
GetString (E->Name),
|
||||
GetString (E->Name),
|
||||
GetSourceFileName (Imp->Obj, Imp->Pos.Name),
|
||||
Imp->Pos.Line);
|
||||
}
|
||||
@ -557,7 +603,7 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
|
||||
static int CmpExpName (const void* K1, const void* K2)
|
||||
/* Compare function for qsort */
|
||||
{
|
||||
return strcmp (GetString ((*(Export**)K1)->Name),
|
||||
return strcmp (GetString ((*(Export**)K1)->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 */
|
||||
{
|
||||
Error ("Circular reference for symbol `%s', %s(%lu)",
|
||||
GetString (E->Name),
|
||||
GetString (E->Name),
|
||||
GetSourceFileName (E->Obj, E->Pos.Name),
|
||||
E->Pos.Line);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -65,6 +65,7 @@ struct Import {
|
||||
FilePos Pos; /* File position of reference */
|
||||
struct Export* Exp; /* Matching export for this import */
|
||||
unsigned Name; /* Name if not in table */
|
||||
unsigned char Flags; /* Generic flags */
|
||||
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);
|
||||
/* Read an import from a file and insert it into the table */
|
||||
|
||||
void InsertImport (Import* I);
|
||||
/* 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);
|
||||
/* Read an export from a file */
|
||||
|
||||
|
@ -49,9 +49,10 @@
|
||||
#include "error.h"
|
||||
#include "exports.h"
|
||||
#include "fileio.h"
|
||||
#include "library.h"
|
||||
#include "objdata.h"
|
||||
#include "objfile.h"
|
||||
#include "library.h"
|
||||
#include "spool.h"
|
||||
|
||||
|
||||
|
||||
@ -63,19 +64,18 @@
|
||||
|
||||
/* Library data */
|
||||
static FILE* Lib = 0;
|
||||
static char* LibName = 0;
|
||||
static unsigned ModuleCount = 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 */
|
||||
{
|
||||
O->Header.Magic = Read32 (Lib);
|
||||
@ -117,10 +117,14 @@ static ObjData* ReadIndexEntry (void)
|
||||
/* Create a new entry and insert it into the list */
|
||||
ObjData* O = NewObjData ();
|
||||
|
||||
/* Module name/flags/MTime/Start/Size */
|
||||
O->Name = ReadStr (Lib);
|
||||
/* Module name */
|
||||
char* Name = ReadStr (Lib);
|
||||
O->Name = GetStringId (Name);
|
||||
xfree (Name);
|
||||
|
||||
/* Module flags/MTime/Start/Size */
|
||||
O->Flags = Read16 (Lib);
|
||||
Read32 (Lib); /* Skip MTime */
|
||||
O->MTime = Read32 (Lib);
|
||||
O->Start = Read32 (Lib);
|
||||
Read32 (Lib); /* Skip Size */
|
||||
|
||||
@ -208,13 +212,14 @@ void LibAdd (FILE* F, const char* Name)
|
||||
* be satisfied.
|
||||
*/
|
||||
{
|
||||
int Add;
|
||||
unsigned LibName;
|
||||
int HaveAdditions;
|
||||
unsigned I;
|
||||
LibHeader Header;
|
||||
|
||||
/* Store the parameters, so they're visible for other routines */
|
||||
Lib = F;
|
||||
LibName = xstrdup (Name);
|
||||
LibName = GetStringId (Name);
|
||||
|
||||
/* Read the remaining header fields (magic is already read) */
|
||||
Header.Magic = LIB_MAGIC;
|
||||
@ -235,27 +240,31 @@ void LibAdd (FILE* F, const char* Name)
|
||||
* were added.
|
||||
*/
|
||||
do {
|
||||
Add = 0;
|
||||
for (I = 0; I < ModuleCount; ++I) {
|
||||
ObjData* O = Index [I];
|
||||
if ((O->Flags & OBJ_REF) == 0) {
|
||||
LibCheckExports (O);
|
||||
if (O->Flags & OBJ_REF) {
|
||||
/* The routine added the file */
|
||||
Add = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (Add);
|
||||
HaveAdditions = 0;
|
||||
for (I = 0; I < ModuleCount; ++I) {
|
||||
ObjData* O = Index [I];
|
||||
if ((O->Flags & OBJ_REF) == 0) {
|
||||
LibCheckExports (O);
|
||||
if (O->Flags & OBJ_REF) {
|
||||
/* The routine added the file */
|
||||
HaveAdditions = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (HaveAdditions);
|
||||
|
||||
/* Add the files list and sections for all requested modules */
|
||||
for (I = 0; I < ModuleCount; ++I) {
|
||||
|
||||
/* Get the object data */
|
||||
ObjData* O = Index [I];
|
||||
|
||||
/* Is this object file referenced? */
|
||||
if (O->Flags & OBJ_REF) {
|
||||
|
||||
/* Seek to the start of the object file and read the header */
|
||||
fseek (Lib, O->Start, SEEK_SET);
|
||||
LibReadObjHeader (O);
|
||||
LibReadObjHeader (O, Name);
|
||||
|
||||
/* Seek to the start of the files list and read the files list */
|
||||
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);
|
||||
ObjReadSections (Lib, O);
|
||||
|
||||
/* We have the data now */
|
||||
O->Flags |= OBJ_HAVEDATA;
|
||||
}
|
||||
/* Add a pointer to the library name */
|
||||
O->LibName = LibName;
|
||||
|
||||
/* All references to strings are now resolved, so we can delete
|
||||
* the module string pool.
|
||||
*/
|
||||
FreeObjStrings (O);
|
||||
/* All references to strings are now resolved, so we can delete
|
||||
* the module string pool.
|
||||
*/
|
||||
FreeObjStrings (O);
|
||||
|
||||
/* Add a pointer to the library name */
|
||||
O->LibName = LibName;
|
||||
/* Insert the object into the list of all used object files */
|
||||
InsertObjData (O);
|
||||
|
||||
} else {
|
||||
|
||||
/* Unreferenced object file, remove it */
|
||||
FreeObjData (O);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Done. Close the file, release allocated memory */
|
||||
fclose (F);
|
||||
xfree (Index);
|
||||
Lib = 0;
|
||||
LibName = 0;
|
||||
ModuleCount = 0;
|
||||
Index = 0;
|
||||
}
|
||||
|
@ -60,7 +60,6 @@
|
||||
void CreateMapFile (void)
|
||||
/* Create a map file */
|
||||
{
|
||||
ObjData* O;
|
||||
unsigned I;
|
||||
|
||||
/* Open the map file */
|
||||
@ -72,28 +71,30 @@ void CreateMapFile (void)
|
||||
/* Write a modules list */
|
||||
fprintf (F, "Modules list:\n"
|
||||
"-------------\n");
|
||||
O = ObjRoot;
|
||||
while (O) {
|
||||
if (O->Flags & OBJ_HAVEDATA) {
|
||||
/* We've linked this module */
|
||||
if (O->LibName) {
|
||||
/* The file is from a library */
|
||||
fprintf (F, "%s(%s):\n", O->LibName, GetObjFileName (O));
|
||||
} else {
|
||||
fprintf (F, "%s:\n", GetObjFileName (O));
|
||||
}
|
||||
for (I = 0; I < O->SectionCount; ++I) {
|
||||
const Section* S = O->Sections [I];
|
||||
/* Don't include zero sized sections if not explicitly
|
||||
* requested
|
||||
*/
|
||||
if (VerboseMap || S->Size > 0) {
|
||||
fprintf (F, " %-15s Offs = %06lX Size = %06lX\n",
|
||||
GetString (S->Seg->Name), S->Offs, S->Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
O = O->Next;
|
||||
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
||||
|
||||
unsigned J;
|
||||
|
||||
/* Get the object file */
|
||||
const ObjData* O = CollConstAt (&ObjDataList, I);
|
||||
|
||||
/* Output the data */
|
||||
if (O->LibName != INVALID_STRING_ID) {
|
||||
/* The file is from a library */
|
||||
fprintf (F, "%s(%s):\n", GetString (O->LibName), GetObjFileName (O));
|
||||
} else {
|
||||
fprintf (F, "%s:\n", GetObjFileName (O));
|
||||
}
|
||||
for (J = 0; J < O->SectionCount; ++J) {
|
||||
const Section* S = O->Sections [J];
|
||||
/* Don't include zero sized sections if not explicitly
|
||||
* requested
|
||||
*/
|
||||
if (VerboseMap || S->Size > 0) {
|
||||
fprintf (F, " %-15s Offs = %06lX Size = %06lX\n",
|
||||
GetString (S->Seg->Name), S->Offs, S->Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the segment list */
|
||||
@ -125,7 +126,7 @@ void CreateMapFile (void)
|
||||
void CreateLabelFile (void)
|
||||
/* Create a label file */
|
||||
{
|
||||
ObjData* O;
|
||||
unsigned I;
|
||||
|
||||
/* Open the label file */
|
||||
FILE* F = fopen (LabelFileName, "w");
|
||||
@ -136,15 +137,14 @@ void CreateLabelFile (void)
|
||||
/* Print the labels for the export symbols */
|
||||
PrintExportLabels (F);
|
||||
|
||||
/* Print debug symbols from all modules we have linked into the output file */
|
||||
O = ObjRoot;
|
||||
while (O) {
|
||||
if (O->Flags & OBJ_HAVEDATA) {
|
||||
/* We've linked this module */
|
||||
PrintDbgSymLabels (O, F);
|
||||
/* Create labels from all modules we have linked into the output file */
|
||||
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
||||
|
||||
}
|
||||
O = O->Next;
|
||||
/* Get the object file */
|
||||
ObjData* O = CollAtUnchecked (&ObjDataList, I);
|
||||
|
||||
/* Output the labels */
|
||||
PrintDbgSymLabels (O, F);
|
||||
}
|
||||
|
||||
/* If we should mark write protected areas as such, do it */
|
||||
@ -174,7 +174,7 @@ void CreateLabelFile (void)
|
||||
void CreateDbgFile (void)
|
||||
/* Create a debug info file */
|
||||
{
|
||||
ObjData* O;
|
||||
unsigned I;
|
||||
|
||||
/* Open the debug info file */
|
||||
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 */
|
||||
O = ObjRoot;
|
||||
while (O) {
|
||||
if (O->Flags & OBJ_HAVEDATA) {
|
||||
/* We've linked this module */
|
||||
PrintDbgInfo (O, F);
|
||||
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
||||
|
||||
}
|
||||
O = O->Next;
|
||||
/* Get the object file */
|
||||
ObjData* O = CollAtUnchecked (&ObjDataList, I);
|
||||
|
||||
/* Output debug info */
|
||||
PrintDbgInfo (O, F);
|
||||
}
|
||||
|
||||
/* Close the file */
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
/* ld65 */
|
||||
#include "error.h"
|
||||
#include "exports.h"
|
||||
#include "fileinfo.h"
|
||||
#include "objdata.h"
|
||||
#include "spool.h"
|
||||
@ -53,11 +54,8 @@
|
||||
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
|
||||
|
||||
@ -75,8 +73,9 @@ ObjData* NewObjData (void)
|
||||
|
||||
/* Initialize the data */
|
||||
O->Next = 0;
|
||||
O->Name = 0;
|
||||
O->LibName = 0;
|
||||
O->Name = INVALID_STRING_ID;
|
||||
O->LibName = INVALID_STRING_ID;
|
||||
O->MTime = 0;
|
||||
O->Flags = 0;
|
||||
O->Start = 0;
|
||||
O->ExportCount = 0;
|
||||
@ -90,24 +89,33 @@ ObjData* NewObjData (void)
|
||||
O->StringCount = 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 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)
|
||||
/* Free the module string data. Used once the object file is loaded completely
|
||||
* 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)
|
||||
/* Get a string from the object file string table. Abort if the string index
|
||||
* is invalid.
|
||||
@ -153,7 +169,7 @@ const char* GetObjFileName (const ObjData* O)
|
||||
* file is NULL.
|
||||
*/
|
||||
{
|
||||
return O? O->Name : "[linker generated]";
|
||||
return O? GetString (O->Name) : "[linker generated]";
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
|
||||
/* common */
|
||||
#include "coll.h"
|
||||
#include "objdefs.h"
|
||||
|
||||
|
||||
@ -51,16 +52,14 @@
|
||||
|
||||
/* Values for the Flags field */
|
||||
#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 */
|
||||
typedef struct ObjData ObjData;
|
||||
struct ObjData {
|
||||
ObjData* Next; /* Linked list of all objects */
|
||||
char* Name; /* Module name */
|
||||
char* LibName; /* Name of library */
|
||||
ObjData* Next; /* Linked list of all objects */
|
||||
unsigned Name; /* Module name */
|
||||
unsigned LibName; /* Name of library */
|
||||
unsigned long MTime; /* Time of last modification */
|
||||
ObjHeader Header; /* Header of file */
|
||||
unsigned long Start; /* Start offset of data in library */
|
||||
unsigned Flags;
|
||||
@ -82,15 +81,13 @@ struct ObjData {
|
||||
|
||||
|
||||
|
||||
/* Object data list management */
|
||||
extern unsigned ObjCount; /* Count of files in the list */
|
||||
extern ObjData* ObjRoot; /* List of object files */
|
||||
extern ObjData* ObjLast; /* Last entry in list */
|
||||
/* Collection containing used ObjData objects */
|
||||
extern Collection ObjDataList;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@ -98,11 +95,20 @@ extern ObjData* ObjLast; /* Last entry in list */
|
||||
ObjData* NewObjData (void);
|
||||
/* 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);
|
||||
/* Free the module string data. Used once the object file is loaded completely
|
||||
* 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);
|
||||
/* Get a string from the object file string table. Abort if the string index
|
||||
* is invalid.
|
||||
|
@ -51,8 +51,9 @@
|
||||
#include "fileio.h"
|
||||
#include "lineinfo.h"
|
||||
#include "objdata.h"
|
||||
#include "segments.h"
|
||||
#include "objfile.h"
|
||||
#include "segments.h"
|
||||
#include "spool.h"
|
||||
|
||||
|
||||
|
||||
@ -62,15 +63,15 @@
|
||||
|
||||
|
||||
|
||||
static const char* GetModule (const char* Name)
|
||||
/* Get a module name from the file name */
|
||||
static unsigned GetModule (const char* Name)
|
||||
/* Get a module name index from the file name */
|
||||
{
|
||||
/* Make a module name from the file name */
|
||||
const char* Module = FindName (Name);
|
||||
if (*Module == 0) {
|
||||
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);
|
||||
|
||||
/* Initialize the object module data structure */
|
||||
O->Name = xstrdup (GetModule (Name));
|
||||
O->Flags = OBJ_HAVEDATA;
|
||||
O->Name = GetModule (Name);
|
||||
|
||||
/* Read the string pool from the object file */
|
||||
fseek (Obj, O->Header.StrPoolOffs, SEEK_SET);
|
||||
@ -251,7 +251,7 @@ void ObjAdd (FILE* Obj, const char* Name)
|
||||
ObjReadSections (Obj, O);
|
||||
|
||||
/* 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) */
|
||||
fclose (Obj);
|
||||
@ -260,6 +260,9 @@ void ObjAdd (FILE* Obj, const char* Name)
|
||||
* string pool.
|
||||
*/
|
||||
FreeObjStrings (O);
|
||||
|
||||
/* Insert the object into the list of all used object files */
|
||||
InsertObjData (O);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user