/* */
/* exports.c */
/* */
-/* Exports handing for the ld65 linker */
+/* Exports handling for the ld65 linker */
/* */
/* */
/* */
#include <stdlib.h>
#include <string.h>
-#include "../common/symdefs.h"
-#include "../common/hashstr.h"
+/* common */
+#include "check.h"
+#include "coll.h"
+#include "hashstr.h"
+#include "symdefs.h"
+#include "xmalloc.h"
-#include "global.h"
-#include "mem.h"
+/* ld65 */
+#include "condes.h"
#include "error.h"
#include "fileio.h"
+#include "global.h"
#include "objdata.h"
#include "expr.h"
#include "exports.h"
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
/* Hash table */
-#define HASHTAB_SIZE 4081
-static Export* HashTab [HASHTAB_SIZE];
+#define HASHTAB_SIZE 4081
+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 Export */
-#define EXP_USERMARK 0x0001
+#define EXP_USERMARK 0x0001
/*****************************************************************************/
-/* Import handling */
+/* Import handling */
/*****************************************************************************/
/* Create a new import and initialize it */
{
/* Allocate memory */
- Import* I = Xmalloc (sizeof (Import));
+ Import* I = xmalloc (sizeof (Import));
/* Initialize the fields */
I->Next = 0;
}
/* Now free the name since it's no longer needed */
- Xfree (Name);
+ xfree (Name);
}
/* Read the import type and check it */
unsigned char Type = Read8 (F);
if (Type != IMP_ZP && Type != IMP_ABS) {
- Error ("Unknown import type in module `%s': %02X", Obj->Name, Type);
+ Error ("Unknown import type in module `%s': %02X",
+ GetObjFileName (Obj), Type);
}
/* Create a new import */
I = NewImport (Type, Obj);
/* Read the name */
- I->V.Name = ReadMallocedStr (F);
+ I->V.Name = ReadStr (F);
/* Read the file position */
ReadFilePos (F, &I->Pos);
static Export* NewExport (unsigned char Type, const char* Name, ObjData* Obj)
/* Create a new export and initialize it */
{
- /* Get the length of the symbol name */
- unsigned Len = strlen (Name);
-
/* Allocate memory */
- Export* E = Xmalloc (sizeof (Export) + Len);
+ Export* E = xmalloc (sizeof (Export));
/* Initialize the fields */
E->Next = 0;
- E->Flags = 0;
+ E->Flags = 0;
E->Obj = Obj;
E->ImpCount = 0;
E->ImpList = 0;
E->Expr = 0;
E->Type = Type;
- memcpy (E->Name, Name, Len);
- E->Name [Len] = '\0';
+ memset (E->ConDes, 0, sizeof (E->ConDes));
+ if (Name) {
+ E->Name = xstrdup (Name);
+ } else {
+ /* Name will get added later */
+ E->Name = 0;
+ }
/* Return the new entry */
return E;
Import* Imp;
unsigned HashVal;
+ /* Insert the export into any condes tables if needed */
+ if (IS_EXP_CONDES (E->Type)) {
+ ConDesAddExport (E);
+ }
+
/* Create a hash value for the given name */
HashVal = HashStr (E->Name) % HASHTAB_SIZE;
do {
if (strcmp (L->Name, E->Name) == 0) {
/* This may be an unresolved external */
- if (L->Expr == 0) {
+ if (L->Expr == 0) {
/* This *is* an unresolved external */
E->Next = L->Next;
if (Last) {
Last->Next = E;
} else {
- HashTab [HashVal] = E;
+ HashTab [HashVal] = E;
}
ImpOpen -= E->ImpCount; /* Decrease open imports now */
- Xfree (L);
+ xfree (L);
/* We must run through the import list and change the
- * export pointer now.
+ * export pointer now.
*/
Imp = E->ImpList;
while (Imp) {
}
} else {
/* Duplicate entry, ignore it */
- Warning ("Duplicate external identifier: `%s'", L->Name);
+ Warning ("Duplicate external identifier: `%s'", L->Name);
}
return;
}
/* Read an export from a file */
{
unsigned char Type;
- char Name [256];
+ unsigned ConDesCount;
Export* E;
/* Read the type */
Type = Read8 (F);
- /* Read the name */
- ReadStr (F, Name);
+ /* Create a new export without a name */
+ E = NewExport (Type, 0, O);
- /* Create a new export */
- E = NewExport (Type, Name, O);
+ /* Read the constructor/destructor decls if we have any */
+ ConDesCount = GET_EXP_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;
+ }
+ }
+
+ /* Read the name */
+ E->Name = ReadStr (F);
/* Read the value */
- if (Type & EXP_EXPR) {
+ if (IS_EXP_EXPR (Type)) {
E->Expr = ReadExpr (F, O);
} else {
E->Expr = LiteralExpr (Read32 (F), O);
/* Create an export for a literal date */
{
/* Create a new export */
- Export* E = NewExport (EXP_ABS, Name, 0);
+ Export* E = NewExport (EXP_ABS | EXP_CONST | EXP_EQUATE, Name, 0);
/* Assign the value */
E->Expr = LiteralExpr (Value, 0);
/* Create an relative export for a memory area offset */
{
/* Create a new export */
- Export* E = NewExport (EXP_ABS, Name, 0);
+ Export* E = NewExport (EXP_ABS | EXP_EXPR | EXP_LABEL, Name, 0);
/* Assign the value */
E->Expr = MemExpr (Mem, Offs, 0);
-static Export* FindExport (const char* Name)
+Export* CreateSegExport (const char* Name, Section* Sec, unsigned long Offs)
+/* Create a relative export to a segment (section) */
+{
+ /* Create a new export */
+ Export* E = NewExport (EXP_ABS | EXP_EXPR | EXP_LABEL, Name, 0);
+
+ /* Assign the value */
+ E->Expr = SegExpr (Sec, Offs, 0);
+
+ /* Insert the export */
+ InsertExport (E);
+
+ /* Return the new export */
+ return E;
+}
+
+
+
+Export* FindExport (const char* Name)
/* Check for an identifier in the list. Return 0 if not found, otherwise
* return a pointer to the export.
*/
/* Check if this symbol is an unresolved export */
{
/* Find the export */
- Export* E = FindExport (Name);
+ return IsUnresolvedExport (FindExport (Name));
+}
+
+
+int IsUnresolvedExport (const Export* E)
+/* Return true if the given export is unresolved */
+{
/* Check if it's unresolved */
return E != 0 && E->Expr == 0;
}
-static void CheckSymType (Export* E)
+static void CheckSymType (const Export* E)
/* Check the types for one export */
{
/* External with matching imports */
Import* Imp = E->ImpList;
- int ZP = (E->Type & EXP_ZP) != 0;
+ int ZP = IS_EXP_ZP (E->Type);
while (Imp) {
- if (ZP != ((Imp->Type & IMP_ZP) != 0)) {
+ if (ZP != IS_IMP_ZP (Imp->Type)) {
/* Export is ZP, import is abs or the other way round */
if (E->Obj) {
- /* User defined export */
- Warning ("Type mismatch for `%s', export in "
+ /* User defined export */
+ Warning ("Type mismatch for `%s', export in "
"%s(%lu), import in %s(%lu)",
- E->Name, E->Obj->Files [Imp->Pos.Name],
- E->Pos.Line, Imp->Obj->Files [Imp->Pos.Name],
+ E->Name, GetSourceFileName (E->Obj, Imp->Pos.Name),
+ 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)",
- E->Name, Imp->Obj->Files [Imp->Pos.Name],
+ E->Name, GetSourceFileName (Imp->Obj, Imp->Pos.Name),
Imp->Pos.Line);
}
}
/* Print all open imports */
for (I = 0; I < ExpCount; ++I) {
- Export* E = ExpPool [I];
+ const Export* E = ExpPool [I];
if (E->Expr != 0 && E->ImpCount > 0) {
/* External with matching imports */
CheckSymType (E);
"Unresolved external `%s' referenced in:\n",
E->Name);
while (Imp) {
- const char* Name = Imp->Obj->Files [Imp->Pos.Name];
+ const char* Name = GetSourceFileName (Imp->Obj, Imp->Pos.Name);
fprintf (stderr, " %s(%lu)\n", Name, Imp->Pos.Line);
Imp = Imp->Next;
}
/* Allocate memory */
if (ExpPool) {
- Xfree (ExpPool);
+ xfree (ExpPool);
}
- ExpPool = Xmalloc (ExpCount * sizeof (Export*));
+ 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) {
/* Print all exports */
Count = 0;
for (I = 0; I < ExpCount; ++I) {
- Export* E = ExpPool [I];
+ const Export* E = ExpPool [I];
/* Print unreferenced symbols only if explictly requested */
- if (VerboseMap || E->ImpCount > 0) {
+ if (VerboseMap || E->ImpCount > 0 || IS_EXP_CONDES (E->Type)) {
fprintf (F,
- "%-25s %06lX %c%c ",
- E->Name,
- GetExportVal (E),
- E->ImpCount? 'R' : ' ',
- (E->Type & EXP_ZP)? 'Z' : ' ');
+ "%-25s %06lX %c%c%c%c ",
+ E->Name,
+ GetExportVal (E),
+ E->ImpCount? 'R' : ' ',
+ IS_EXP_LABEL (E->Type)? 'L' : 'E',
+ IS_EXP_ZP (E->Type)? 'Z' : ' ',
+ IS_EXP_CONDES (E->Type)? 'I' : ' ');
if (++Count == 2) {
- Count = 0;
- fprintf (F, "\n");
+ Count = 0;
+ fprintf (F, "\n");
}
}
}
/* Print an import map to the given file */
{
unsigned I;
- Import* Imp;
+ const Import* Imp;
/* Loop over all exports */
for (I = 0; I < ExpCount; ++I) {
/* Get the export */
- Export* Exp = ExpPool [I];
+ 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) {
- /* Get the name of the object file that exports the symbol.
- * Beware: There may be no object file if the symbol is a linker
- * generated symbol.
- */
- const char* ObjName = (Exp->Obj != 0)? Exp->Obj->Name : "linker generated";
-
/* Print the export */
fprintf (F,
- "%s (%s):\n",
- Exp->Name,
- ObjName);
+ "%s (%s):\n",
+ Exp->Name,
+ GetObjFileName (Exp->Obj));
/* Print all imports for this symbol */
Imp = Exp->ImpList;
while (Imp) {
- /* Print the import */
- fprintf (F,
- " %-25s %s(%lu)\n",
- Imp->Obj->Name,
- Imp->Obj->Files [Imp->Pos.Name],
- Imp->Pos.Line);
+ /* Print the import */
+ fprintf (F,
+ " %-25s %s(%lu)\n",
+ GetObjFileName (Imp->Obj),
+ GetSourceFileName (Imp->Obj, Imp->Pos.Name),
+ Imp->Pos.Line);
- /* Next import */
- Imp = Imp->Next;
+ /* Next import */
+ Imp = Imp->Next;
}
}
}
/* Print all exports */
for (I = 0; I < ExpCount; ++I) {
- Export* E = ExpPool [I];
+ const Export* E = ExpPool [I];
fprintf (F, "al %06lX .%s\n", GetExportVal (E), E->Name);
}
}
/* Print an error about a circular reference using to define the given export */
{
Error ("Circular reference for symbol `%s', %s(%lu)",
- E->Name, E->Obj->Files [E->Pos.Name], E->Pos.Line);
+ E->Name, GetSourceFileName (E->Obj, E->Pos.Name), E->Pos.Line);
}