/* */
/* exports.c */
/* */
-/* Exports handing for the ld65 linker */
+/* Exports handling for the ld65 linker */
/* */
/* */
/* */
#include "xmalloc.h"
/* ld65 */
-#include "global.h"
+#include "condes.h"
#include "error.h"
#include "fileio.h"
+#include "global.h"
#include "objdata.h"
#include "expr.h"
#include "exports.h"
/* Defines for the flags in Export */
#define EXP_USERMARK 0x0001
-/* List of all exports that are also initializers */
-static Collection Initializers = STATIC_COLLECTION_INITIALIZER;
-
/*****************************************************************************/
-/* Import handling */
+/* Import handling */
/*****************************************************************************/
/* 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 */
/* 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;
+ memset (E->ConDes, 0, sizeof (E->ConDes));
if (Name) {
E->Name = xstrdup (Name);
} else {
- /* Name will get added later */
- E->Name = 0;
+ /* Name will get added later */
+ E->Name = 0;
}
/* Return the new entry */
Import* Imp;
unsigned HashVal;
- /* If this is an initializer, insert it into the initializer list */
- if (IS_EXP_INIT (E->Type)) {
- CollAppend (&Initializers, E);
+ /* 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 */
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) {
}
} 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;
+ unsigned ConDesCount;
Export* E;
/* Read the type */
/* Create a new export without a name */
E = NewExport (Type, 0, 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);
/* 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);
+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;
+}
+
+
+
static Export* FindExport (const char* Name)
/* Check for an identifier in the list. Return 0 if not found, otherwise
- * return a pointer to the export.
+ * return a pointer to the export.
*/
{
/* Get a pointer to the list with the symbols hash value */
/* 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);
}
}
"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;
}
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%c ",
+ "%-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_INIT (E->Type)? 'I' : ' ');
+ IS_EXP_CONDES (E->Type)? 'I' : ' ');
if (++Count == 2) {
Count = 0;
fprintf (F, "\n");
*/
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);
+ GetObjFileName (Exp->Obj));
/* Print all imports for this symbol */
Imp = Exp->ImpList;
/* Print the import */
fprintf (F,
" %-25s %s(%lu)\n",
- Imp->Obj->Name,
- Imp->Obj->Files [Imp->Pos.Name],
+ GetObjFileName (Imp->Obj),
+ GetSourceFileName (Imp->Obj, Imp->Pos.Name),
Imp->Pos.Line);
/* Next import */
/* 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);
}