/*****************************************************************************/
/* */
-/* exports.c */
+/* exports.c */
/* */
-/* Exports handling for the ld65 linker */
+/* Exports handling for the ld65 linker */
/* */
/* */
/* */
-/* (C) 1998-2011, Ullrich von Bassewitz */
+/* (C) 1998-2013, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* common */
#include "addrsize.h"
#include "check.h"
-#include "hashstr.h"
+#include "hashfunc.h"
+#include "lidefs.h"
#include "symdefs.h"
#include "xmalloc.h"
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
/* Hash table */
#define HASHTAB_MASK 0x0FFFU
-#define HASHTAB_SIZE (HASHTAB_MASK + 1)
-static Export* HashTab[HASHTAB_SIZE];
+#define HASHTAB_SIZE (HASHTAB_MASK + 1)
+static Export* HashTab[HASHTAB_SIZE];
/* Import management variables */
-static unsigned ImpCount = 0; /* Import count */
-static unsigned ImpOpen = 0; /* Count of open imports */
+static unsigned ImpCount = 0; /* Import count */
+static unsigned ImpOpen = 0; /* Count of open imports */
/* Export management variables */
-static unsigned ExpCount = 0; /* Export count */
-static Export** ExpPool = 0; /* Exports array */
+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_INLIST 0x0001U /* Export is in exports list */
-#define EXP_USERMARK 0x0002U /* User setable flag */
+#define EXP_USERMARK 0x0002U /* User setable flag */
/*****************************************************************************/
-/* Import handling */
+/* Import handling */
/*****************************************************************************/
-static Export* NewExport (unsigned char Type, unsigned char AddrSize,
+static Export* NewExport (unsigned Type, unsigned char AddrSize,
unsigned Name, ObjData* Obj);
/* Create a new export and initialize it */
Import* I = xmalloc (sizeof (Import));
/* Initialize the fields */
- I->Next = 0;
- I->Obj = Obj;
- I->LineInfos = EmptyCollection;
+ I->Next = 0;
+ I->Obj = Obj;
+ I->DefLines = EmptyCollection;
+ I->RefLines = EmptyCollection;
I->Exp = 0;
I->Name = INVALID_STRING_ID;
I->Flags = 0;
/* Safety */
PRECONDITION ((I->Flags & IMP_INLIST) == 0);
- /* Free the line info collection */
- DoneCollection (&I->LineInfos);
+ /* Free the line info collections */
+ DoneCollection (&I->DefLines);
+ DoneCollection (&I->RefLines);
/* Free the struct */
xfree (I);
I->Name = MakeGlobalStringId (Obj, ReadVar (F));
/* Read the line infos */
- ReadLineInfoList (F, Obj, &I->LineInfos);
+ ReadLineInfoList (F, Obj, &I->DefLines);
+ ReadLineInfoList (F, Obj, &I->RefLines);
/* Check the address size */
if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) {
*/
if (ObjHasFiles (I->Obj)) {
const LineInfo* LI = GetImportPos (I);
- Error ("Invalid import size in for `%s', imported from %s(%lu): 0x%02X",
+ Error ("Invalid import size in for `%s', imported from %s(%u): 0x%02X",
GetString (I->Name),
GetSourceName (LI),
GetSourceLine (LI),
/* Check the address size */
if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) {
- /* Beware: This function may be called in cases where the object file
- * is not read completely into memory. In this case, the file list is
- * invalid. Be sure not to access it in this case.
+ /* We have no object file information and no line info for a new
+ * import
*/
- if (ObjHasFiles (I->Obj)) {
- const LineInfo* LI = GetImportPos (I);
- Error ("Invalid import size in for `%s', imported from %s(%lu): 0x%02X",
- GetString (I->Name),
- GetSourceName (LI),
- GetSourceLine (LI),
- I->AddrSize);
- } else {
- Error ("Invalid import size in for `%s', imported from %s: 0x%02X",
- GetString (I->Name),
- GetObjFileName (I->Obj),
- I->AddrSize);
- }
+ Error ("Invalid import size 0x%02X for symbol `%s'",
+ I->AddrSize,
+ GetString (I->Name));
}
/* Return the new import */
/* Create a hash value for the given name */
unsigned Hash = (Name & HASHTAB_MASK);
- /* Search through the list in that slot and print matching duplicates */
+ /* Search through the list in that slot for a symbol with that name */
if (HashTab[Hash] == 0) {
- /* The slot is empty, we need to insert a dummy export */
- E = HashTab[Hash] = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
- ++ExpCount;
+ /* The slot is empty, we need to insert a dummy export */
+ E = HashTab[Hash] = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
+ ++ExpCount;
} else {
- E = HashTab [Hash];
- while (1) {
- if (E->Name == Name) {
- /* We have an entry, L points to it */
- break;
- }
- if (E->Next == 0) {
- /* End of list an entry not found, insert a dummy */
- E->Next = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
- E = E->Next; /* Point to dummy */
- ++ExpCount; /* One export more */
- break;
- } else {
- E = E->Next;
- }
- }
+ E = HashTab [Hash];
+ while (1) {
+ if (E->Name == Name) {
+ /* We have an entry, L points to it */
+ break;
+ }
+ if (E->Next == 0) {
+ /* End of list an entry not found, insert a dummy */
+ E->Next = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
+ E = E->Next; /* Point to dummy */
+ ++ExpCount; /* One export more */
+ break;
+ } else {
+ E = E->Next;
+ }
+ }
}
/* Ok, E now points to a valid exports entry for the given import. Insert
I->Next = E->ImpList;
E->ImpList = I;
E->ImpCount++;
- ++ImpCount; /* Total import count */
+ ++ImpCount; /* Total import count */
if (E->Expr == 0) {
- /* This is a dummy export */
- ++ImpOpen;
+ /* This is a dummy export */
+ ++ImpOpen;
}
/* Mark the import so we know it's in the list */
-const LineInfo* GetImportPos (const Import* I)
+const LineInfo* GetImportPos (const Import* Imp)
/* Return the basic line info of an import */
{
- /* Source file position is always in slot zero */
- return CollConstAt (&I->LineInfos, 0);
+ /* Search in DefLines, then in RefLines */
+ const LineInfo* LI = GetAsmLineInfo (&Imp->DefLines);
+ if (LI == 0) {
+ LI = GetAsmLineInfo (&Imp->RefLines);
+ }
+ return LI;
}
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
-static Export* NewExport (unsigned char Type, unsigned char AddrSize,
+static Export* NewExport (unsigned Type, unsigned char AddrSize,
unsigned Name, ObjData* Obj)
/* Create a new export and initialize it */
{
+ unsigned I;
+
/* Allocate memory */
Export* E = xmalloc (sizeof (Export));
/* Initialize the fields */
E->Name = Name;
E->Next = 0;
- E->Flags = 0;
+ E->Flags = 0;
E->Obj = Obj;
E->ImpCount = 0;
E->ImpList = 0;
- E->Expr = 0;
- E->LineInfos = EmptyCollection;
- E->Type = Type;
+ E->Expr = 0;
+ E->Size = 0;
+ E->DefLines = EmptyCollection;
+ E->RefLines = EmptyCollection;
+ E->DbgSymId = ~0U;
+ E->Type = Type | SYM_EXPORT;
E->AddrSize = AddrSize;
- memset (E->ConDes, 0, sizeof (E->ConDes));
+ for (I = 0; I < sizeof (E->ConDes) / sizeof (E->ConDes[0]); ++I) {
+ E->ConDes[I] = CD_PRIO_NONE;
+ }
/* Return the new entry */
return E;
PRECONDITION ((E->Flags & EXP_INLIST) == 0);
/* Free the line infos */
- DoneCollection (&E->LineInfos);
+ DoneCollection (&E->DefLines);
+ DoneCollection (&E->RefLines);
/* Free the export expression */
FreeExpr (E->Expr);
Export* ReadExport (FILE* F, ObjData* O)
/* Read an export from a file */
{
- unsigned ConDesCount;
- Export* E;
+ unsigned ConDesCount;
+ unsigned I;
+ Export* E;
/* Read the type */
- unsigned char Type = ReadVar (F);
+ unsigned Type = ReadVar (F);
/* Read the address size */
unsigned char AddrSize = Read8 (F);
ConDesCount = SYM_GET_CONDES_COUNT (Type);
if (ConDesCount > 0) {
- unsigned char ConDes[CD_TYPE_COUNT];
- unsigned I;
-
- /* Read the data into temp storage */
- ReadData (F, ConDes, ConDesCount);
-
- /* Re-order the data. In the file, each decl is encoded into a byte
- * which contains the type and the priority. In memory, we will use
- * an array of types which contain the priority. This array was
- * cleared by the constructor (NewExport), so we must only set the
- * fields that contain values.
- */
- for (I = 0; I < ConDesCount; ++I) {
- unsigned ConDesType = CD_GET_TYPE (ConDes[I]);
- unsigned ConDesPrio = CD_GET_PRIO (ConDes[I]);
- E->ConDes[ConDesType] = ConDesPrio;
- }
+ unsigned char ConDes[CD_TYPE_COUNT];
+
+ /* Read the data into temp storage */
+ ReadData (F, ConDes, ConDesCount);
+
+ /* Re-order the data. In the file, each decl is encoded into a byte
+ * which contains the type and the priority. In memory, we will use
+ * an array of types which contain the priority.
+ */
+ for (I = 0; I < ConDesCount; ++I) {
+ E->ConDes[CD_GET_TYPE (ConDes[I])] = CD_GET_PRIO (ConDes[I]);
+ }
}
/* Read the name */
/* Read the value */
if (SYM_IS_EXPR (Type)) {
- E->Expr = ReadExpr (F, O);
+ E->Expr = ReadExpr (F, O);
} else {
- E->Expr = LiteralExpr (Read32 (F), O);
+ E->Expr = LiteralExpr (Read32 (F), O);
+ }
+
+ /* Read the size */
+ if (SYM_HAS_SIZE (Type)) {
+ E->Size = ReadVar (F);
}
- /* Last is the file position where the definition was done */
- ReadLineInfoList (F, O, &E->LineInfos);
+ /* Last are the locations */
+ ReadLineInfoList (F, O, &E->DefLines);
+ ReadLineInfoList (F, O, &E->RefLines);
+
+ /* If this symbol is exported as a condes, and the condes type declares a
+ * forced import, add this import to the object module.
+ */
+ for (I = 0; I < CD_TYPE_COUNT; ++I) {
+ const ConDesImport* CDI;
+
+ if (E->ConDes[I] != CD_PRIO_NONE && (CDI = ConDesGetImport (I)) != 0) {
+ unsigned J;
+
+ /* Generate a new import, and add it to the module's import list. */
+ Import* Imp = GenImport (CDI->Name, CDI->AddrSize);
+
+ Imp->Obj = O;
+ CollAppend (&O->Imports, Imp);
+
+ /* Add line info for the export that is actually the condes that
+ * forces the import. Then, add line info for the config. file.
+ * The export's info is added first because the import pretends
+ * that it came from the object module instead of the config. file.
+ */
+ for (J = 0; J < CollCount (&E->DefLines); ++J) {
+ CollAppend (&Imp->RefLines, DupLineInfo (CollAt (&E->DefLines, J)));
+ }
+ CollAppend (&Imp->RefLines, GenLineInfo (&CDI->Pos));
+ }
+ }
/* Return the new export */
return E;
/* Insert the export into any condes tables if needed */
if (SYM_IS_CONDES (E->Type)) {
- ConDesAddExport (E);
+ ConDesAddExport (E);
}
/* Create a hash value for the given name */
/* Search through the list in that slot */
if (HashTab[Hash] == 0) {
- /* The slot is empty */
- HashTab[Hash] = E;
- ++ExpCount;
+ /* The slot is empty */
+ HashTab[Hash] = E;
+ ++ExpCount;
} else {
- Last = 0;
- L = HashTab[Hash];
- do {
- if (L->Name == E->Name) {
- /* This may be an unresolved external */
- if (L->Expr == 0) {
+ Last = 0;
+ L = HashTab[Hash];
+ do {
+ if (L->Name == E->Name) {
+ /* This may be an unresolved external */
+ if (L->Expr == 0) {
- /* This *is* an unresolved external. Use the actual export
+ /* 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 {
- HashTab[Hash] = E;
- }
- ImpOpen -= E->ImpCount; /* Decrease open imports now */
- 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'",
+ E->Next = L->Next;
+ E->ImpCount = L->ImpCount;
+ E->ImpList = L->ImpList;
+ 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
+ * export pointer now.
+ */
+ 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;
- }
- Last = L;
- L = L->Next;
+ }
+ return;
+ }
+ Last = L;
+ L = L->Next;
- } while (L);
+ } while (L);
- /* Insert export at end of queue */
- Last->Next = E;
- ++ExpCount;
+ /* Insert export at end of queue */
+ Last->Next = E;
+ ++ExpCount;
}
}
const LineInfo* GetExportPos (const Export* E)
/* Return the basic line info of an export */
{
- /* Source file position is always in slot zero */
- return CollConstAt (&E->LineInfos, 0);
+ /* Search in DefLines, then in RefLines */
+ const LineInfo* LI = GetAsmLineInfo (&E->DefLines);
+ if (LI == 0) {
+ LI = GetAsmLineInfo (&E->RefLines);
+ }
+ return LI;
}
/* Create an export for a literal date */
{
/* Create a new export */
- Export* E = NewExport (SYM_CONST | SYM_EQUATE, ADDR_SIZE_ABS, Name, 0);
+ Export* E = NewExport (SYM_CONST|SYM_EQUATE, ADDR_SIZE_ABS, Name, 0);
/* Assign the value */
E->Expr = LiteralExpr (Value, 0);
/* Create an export for an expression */
{
/* Create a new export */
- Export* E = NewExport (SYM_EXPR | SYM_EQUATE, AddrSize, Name, 0);
+ Export* E = NewExport (SYM_EXPR|SYM_EQUATE, AddrSize, Name, 0);
/* Assign the value expression */
E->Expr = Expr;
Export* L = HashTab[Name & HASHTAB_MASK];
while (L) {
/* Search through the list in that slot */
- if (L->Name == Name) {
- /* Entry found */
- return L;
- }
- L = L->Next;
+ if (L->Name == Name) {
+ /* Entry found */
+ return L;
+ }
+ L = L->Next;
}
/* Not found */
/* Return true if the expression associated with this export is const */
{
if (E->Expr == 0) {
- /* External symbols cannot be const */
- return 0;
+ /* External symbols cannot be const */
+ return 0;
} else {
return IsConstExpr (E->Expr);
}
/* Get the value of this export */
{
if (E->Expr == 0) {
- /* OOPS */
- Internal ("`%s' is an undefined external", GetString (E->Name));
+ /* OOPS */
+ Internal ("`%s' is an undefined external", GetString (E->Name));
}
return GetExprVal (E->Expr);
}
/* External with matching imports */
Import* I = E->ImpList;
while (I) {
- if (E->AddrSize != I->AddrSize) {
- /* Export and import address sizes do not match */
+ if (E->AddrSize != I->AddrSize) {
+ /* Export and import address sizes do not match */
StrBuf ExportLoc = STATIC_STRBUF_INITIALIZER;
StrBuf ImportLoc = STATIC_STRBUF_INITIALIZER;
- const char* ExpAddrSize = AddrSizeToStr (E->AddrSize);
- const char* ImpAddrSize = AddrSizeToStr (I->AddrSize);
+ const char* ExpAddrSize = AddrSizeToStr ((unsigned char) E->AddrSize);
+ const char* ImpAddrSize = AddrSizeToStr ((unsigned char) I->AddrSize);
const LineInfo* ExportLI = GetExportPos (E);
const LineInfo* ImportLI = GetImportPos (I);
*/
if (E->Obj) {
/* The export comes from an object file */
- SB_Printf (&ExportLoc, "%s, %s(%lu)",
+ SB_Printf (&ExportLoc, "%s, %s(%u)",
GetString (E->Obj->Name),
GetSourceName (ExportLI),
GetSourceLine (ExportLI));
} else {
- SB_Printf (&ExportLoc, "%s(%lu)",
+ SB_Printf (&ExportLoc, "%s(%u)",
GetSourceName (ExportLI),
GetSourceLine (ExportLI));
}
if (I->Obj) {
/* The import comes from an object file */
- SB_Printf (&ImportLoc, "%s, %s(%lu)",
+ SB_Printf (&ImportLoc, "%s, %s(%u)",
GetString (I->Obj->Name),
GetSourceName (ImportLI),
GetSourceLine (ImportLI));
- } else {
- SB_Printf (&ImportLoc, "%s(%lu)",
+ } else if (ImportLI) {
+ /* The import is linker generated and we have line
+ * information
+ */
+ SB_Printf (&ImportLoc, "%s(%u)",
GetSourceName (ImportLI),
GetSourceLine (ImportLI));
+ } else {
+ /* The import is linker generated and we don't have line
+ * information
+ */
+ SB_Printf (&ImportLoc, "%s", GetObjFileName (I->Obj));
}
/* Output the diagnostic */
/* Free the temporary strings */
SB_Done (&ExportLoc);
SB_Done (&ImportLoc);
- }
- I = I->Next;
+ }
+ I = I->Next;
}
}
/* Print all open imports */
for (I = 0; I < ExpCount; ++I) {
- const Export* E = ExpPool [I];
- if (E->Expr != 0 && E->ImpCount > 0) {
- /* External with matching imports */
- CheckSymType (E);
- }
+ const Export* E = ExpPool [I];
+ if (E->Expr != 0 && E->ImpCount > 0) {
+ /* External with matching imports */
+ CheckSymType (E);
+ }
}
}
/* Print all open imports */
for (I = 0; I < ExpCount; ++I) {
- Export* E = ExpPool [I];
- if (E->Expr == 0 && E->ImpCount > 0 && F (E->Name, Data) == 0) {
- /* Unresolved external */
- Import* Imp = E->ImpList;
- fprintf (stderr,
- "Unresolved external `%s' referenced in:\n",
- GetString (E->Name));
- while (Imp) {
- const LineInfo* LI = GetImportPos (Imp);
- fprintf (stderr,
- " %s(%lu)\n",
+ Export* E = ExpPool [I];
+ if (E->Expr == 0 && E->ImpCount > 0 && F (E->Name, Data) == 0) {
+ /* Unresolved external */
+ Import* Imp = E->ImpList;
+ fprintf (stderr,
+ "Unresolved external `%s' referenced in:\n",
+ GetString (E->Name));
+ while (Imp) {
+ unsigned J;
+ for (J = 0; J < CollCount (&Imp->RefLines); ++J) {
+ const LineInfo* LI = CollConstAt (&Imp->RefLines, J);
+ fprintf (stderr,
+ " %s(%u)\n",
GetSourceName (LI),
GetSourceLine (LI));
- Imp = Imp->Next;
- }
- }
+ }
+ Imp = Imp->Next;
+ }
+ }
}
}
/* Allocate memory */
if (ExpPool) {
- xfree (ExpPool);
+ xfree (ExpPool);
}
ExpPool = xmalloc (ExpCount * sizeof (Export*));
/* Walk through the list and insert the exports */
for (I = 0, J = 0; I < sizeof (HashTab) / sizeof (HashTab [0]); ++I) {
- Export* E = HashTab[I];
- while (E) {
- CHECK (J < ExpCount);
- ExpPool[J++] = E;
- E = E->Next;
- }
+ Export* E = HashTab[I];
+ while (E) {
+ CHECK (J < ExpCount);
+ ExpPool[J++] = E;
+ E = E->Next;
+ }
}
/* Sort them by name */
{
/* Check for unresolved externals */
if (ImpOpen != 0) {
- /* Print all open imports */
- PrintUnresolved (F, Data);
+ /* Print all open imports */
+ PrintUnresolved (F, Data);
}
}
case ADDR_SIZE_LONG: return 'L';
default:
Internal ("Invalid address size: %u", AddrSize);
- /* NOTREACHED */
- return '-';
+ /* NOTREACHED */
+ return '-';
}
}
/* Print all exports */
Count = 0;
for (I = 0; I < ExpCount; ++I) {
- const Export* E = ExpPool [I];
-
- /* Print unreferenced symbols only if explictly requested */
- if (VerboseMap || E->ImpCount > 0 || SYM_IS_CONDES (E->Type)) {
- fprintf (F,
- "%-25s %06lX %c%c%c%c ",
- GetString (E->Name),
- GetExportVal (E),
- E->ImpCount? 'R' : ' ',
- SYM_IS_LABEL (E->Type)? 'L' : 'E',
- GetAddrSizeCode (E->AddrSize),
- SYM_IS_CONDES (E->Type)? 'I' : ' ');
- if (++Count == 2) {
- Count = 0;
- fprintf (F, "\n");
- }
- }
+ const Export* E = ExpPool [I];
+
+ /* Print unreferenced symbols only if explictly requested */
+ if (VerboseMap || E->ImpCount > 0 || SYM_IS_CONDES (E->Type)) {
+ fprintf (F,
+ "%-25s %06lX %c%c%c%c ",
+ GetString (E->Name),
+ GetExportVal (E),
+ E->ImpCount? 'R' : ' ',
+ SYM_IS_LABEL (E->Type)? 'L' : 'E',
+ GetAddrSizeCode ((unsigned char) E->AddrSize),
+ SYM_IS_CONDES (E->Type)? 'I' : ' ');
+ if (++Count == 2) {
+ Count = 0;
+ fprintf (F, "\n");
+ }
+ }
}
fprintf (F, "\n");
}
/* Loop over all exports */
for (I = 0; I < ExpCount; ++I) {
- /* Get the export */
- const Export* Exp = ExpPool [I];
-
- /* Print the symbol only if there are imports, or if a verbose map
- * file is requested.
- */
- if (VerboseMap || Exp->ImpCount > 0) {
-
- /* Print the export */
- fprintf (F,
- "%s (%s):\n",
- GetString (Exp->Name),
- GetObjFileName (Exp->Obj));
+ /* Get the export */
+ const Export* Exp = ExpPool [I];
- /* Print all imports for this symbol */
- Imp = Exp->ImpList;
- while (Imp) {
-
- /* Print the import */
+ /* Print the symbol only if there are imports, or if a verbose map
+ * file is requested.
+ */
+ if (VerboseMap || Exp->ImpCount > 0) {
+
+ /* Print the export */
+ fprintf (F,
+ "%s (%s):\n",
+ GetString (Exp->Name),
+ GetObjFileName (Exp->Obj));
+
+ /* Print all imports for this symbol */
+ Imp = Exp->ImpList;
+ while (Imp) {
+
+ /* Print the import. Beware: The import might be linker
+ * generated, in which case there is no object file and
+ * sometimes no line information.
+ */
const LineInfo* LI = GetImportPos (Imp);
- fprintf (F,
- " %-25s %s(%lu)\n",
- GetObjFileName (Imp->Obj),
- GetSourceName (LI),
- GetSourceLine (LI));
-
- /* Next import */
- Imp = Imp->Next;
- }
- }
+ if (LI) {
+ fprintf (F,
+ " %-25s %s(%u)\n",
+ GetObjFileName (Imp->Obj),
+ GetSourceName (LI),
+ GetSourceLine (LI));
+ } else {
+ fprintf (F,
+ " %-25s\n",
+ GetObjFileName (Imp->Obj));
+ }
+
+ /* Next import */
+ Imp = Imp->Next;
+ }
+ }
}
fprintf (F, "\n");
}
/* Print all exports */
for (I = 0; I < ExpCount; ++I) {
- const Export* E = ExpPool [I];
- fprintf (F, "al %06lX .%s\n", GetExportVal (E), GetString (E->Name));
+ const Export* E = ExpPool [I];
+ fprintf (F, "al %06lX .%s\n", GetExportVal (E), GetString (E->Name));
}
}
/* Print an error about a circular reference using to define the given export */
{
const LineInfo* LI = GetExportPos (E);
- Error ("Circular reference for symbol `%s', %s(%lu)",
- GetString (E->Name),
+ Error ("Circular reference for symbol `%s', %s(%u)",
+ GetString (E->Name),
GetSourceName (LI),
GetSourceLine (LI));
}
-
-
-
-