X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fld65%2Fexports.c;h=6518bcaf917ab2a0d67a651fc6f3921544af73fa;hb=ead7de2b4299f8bb20264b03bbd70ca162d873bf;hp=7141067a36cd9c185128236a9325162dd4d4cf29;hpb=2767f66146ff0af2d26933a2f9cae6282c4bd6b6;p=cc65 diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 7141067a3..6518bcaf9 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -2,7 +2,7 @@ /* */ /* exports.c */ /* */ -/* Exports handing for the ld65 linker */ +/* Exports handling for the ld65 linker */ /* */ /* */ /* */ @@ -37,13 +37,18 @@ #include #include -#include "../common/symdefs.h" -#include "../common/hashstr.h" -#include "../common/xmalloc.h" +/* common */ +#include "check.h" +#include "coll.h" +#include "hashstr.h" +#include "symdefs.h" +#include "xmalloc.h" -#include "global.h" +/* ld65 */ +#include "condes.h" #include "error.h" #include "fileio.h" +#include "global.h" #include "objdata.h" #include "expr.h" #include "exports.h" @@ -51,30 +56,30 @@ /*****************************************************************************/ -/* 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 */ /*****************************************************************************/ @@ -165,14 +170,15 @@ Import* ReadImport (FILE* F, ObjData* Obj) /* 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); @@ -192,22 +198,24 @@ Import* ReadImport (FILE* F, ObjData* Obj) 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; @@ -223,6 +231,11 @@ void InsertExport (Export* 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; @@ -238,7 +251,7 @@ void InsertExport (Export* E) 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; @@ -247,12 +260,12 @@ void InsertExport (Export* E) if (Last) { Last->Next = E; } else { - HashTab [HashVal] = E; + HashTab [HashVal] = E; } ImpOpen -= E->ImpCount; /* Decrease open imports now */ xfree (L); /* We must run through the import list and change the - * export pointer now. + * export pointer now. */ Imp = E->ImpList; while (Imp) { @@ -261,7 +274,7 @@ void InsertExport (Export* E) } } else { /* Duplicate entry, ignore it */ - Warning ("Duplicate external identifier: `%s'", L->Name); + Warning ("Duplicate external identifier: `%s'", L->Name); } return; } @@ -282,20 +295,43 @@ Export* ReadExport (FILE* F, ObjData* O) /* 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); @@ -314,7 +350,7 @@ Export* CreateConstExport (const char* Name, long Value) /* 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); @@ -332,7 +368,7 @@ Export* CreateMemExport (const char* Name, Memory* Mem, unsigned long Offs) /* 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); @@ -346,7 +382,25 @@ Export* CreateMemExport (const char* Name, Memory* Mem, unsigned long Offs) -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. */ @@ -372,8 +426,14 @@ int IsUnresolved (const char* Name) /* 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; } @@ -405,26 +465,26 @@ long GetExportVal (const Export* E) -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); } } @@ -441,7 +501,7 @@ static void CheckSymTypes (void) /* 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); @@ -468,7 +528,7 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data) "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; } @@ -542,19 +602,21 @@ void PrintExportMap (FILE* F) /* 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"); } } } @@ -567,44 +629,38 @@ void PrintImportMap (FILE* F) /* 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; } } } @@ -620,7 +676,7 @@ void PrintExportLabels (FILE* F) /* 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); } } @@ -655,7 +711,7 @@ 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)", - E->Name, E->Obj->Files [E->Pos.Name], E->Pos.Line); + E->Name, GetSourceFileName (E->Obj, E->Pos.Name), E->Pos.Line); }