S->Right = 0;
S->Locals = 0;
S->Sym.Tab = 0;
- S->LineInfos = EmptyCollection;
- GetFullLineInfo (&S->LineInfos);
+ S->DefLines = EmptyCollection;
+ S->RefLines = EmptyCollection;
for (I = 0; I < sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0]); ++I) {
S->GuessedUse[I] = 0;
}
-void SymRef (SymEntry* S)
-/* Mark the given symbol as referenced */
-{
- /* Mark the symbol as referenced */
- S->Flags |= SF_REFERENCED;
-}
-
-
-
void SymTransferExprRefs (SymEntry* From, SymEntry* To)
/* Transfer all expression references from one symbol to another. */
{
*/
if (S->Flags & SF_GLOBAL) {
S->Flags = (S->Flags & ~SF_GLOBAL) | SF_EXPORT;
+ ReleaseFullLineInfo (&S->DefLines);
}
/* Mark the symbol as defined and use the given address size */
S->Flags |= (SF_DEFINED | Flags);
S->AddrSize = AddrSize;
+ /* Remember the line info of the symbol definition */
+ GetFullLineInfo (&S->DefLines);
+
/* If the symbol is exported, check the address sizes */
if (S->Flags & SF_EXPORT) {
if (S->ExportSize == ADDR_SIZE_DEFAULT) {
S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */
- LIWarning (&S->LineInfos, 1, "Symbol `%m%p' is %s but exported %s",
- GetSymName (S), AddrSizeToStr (S->AddrSize),
- AddrSizeToStr (S->ExportSize));
+ Warning (1, "Symbol `%m%p' is %s but exported %s",
+ GetSymName (S), AddrSizeToStr (S->AddrSize),
+ AddrSizeToStr (S->ExportSize));
}
}
+void SymRef (SymEntry* S)
+/* Mark the given symbol as referenced */
+{
+ /* Mark the symbol as referenced */
+ S->Flags |= SF_REFERENCED;
+
+ /* Remember the current location */
+ CollAppend (&S->RefLines, GetAsmLineInfo ());
+}
+
+
+
void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
/* Mark the given symbol as an imported symbol */
{
/* Set the symbol data */
S->Flags |= (SF_IMPORT | Flags);
S->AddrSize = AddrSize;
+
+ /* Mark the position of the import as the position of the definition.
+ * Please note: In case of multiple .global or .import statements, the line
+ * infos add up.
+ */
+ GetFullLineInfo (&S->DefLines);
}
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
}
S->Flags &= ~SF_GLOBAL;
+
+ /* .GLOBAL remembers line infos in case an .IMPORT follows. We have
+ * to remove these here.
+ */
+ ReleaseFullLineInfo (&S->DefLines);
}
/* If the symbol was already marked as an export, but wasn't defined
}
S->ExportSize = AddrSize;
S->Flags |= (SF_GLOBAL | Flags);
+
+ /* Remember the current location as location of definition in case
+ * an .IMPORT follows later.
+ */
+ GetFullLineInfo (&S->DefLines);
}
}
/* Set the symbol data */
S->Flags |= (SF_EXPORT | SF_REFERENCED);
+
+ /* In case we have no line info for the definition, record it now */
+ if (CollCount (&S->DefLines) == 0) {
+ GetFullLineInfo (&S->DefLines);
+ }
}
if (S->Flags & SF_EXPORT) {
if (Sym->Flags & SF_IMPORT) {
/* The symbol is already marked as import */
- LIError (&S->LineInfos,
+ LIError (&S->RefLines,
"Symbol `%s' is already an import",
GetString (Sym->Name));
}
/* The symbol is already marked as an export. */
if (Sym->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */
- LIWarning (&S->LineInfos, 1,
+ LIWarning (&S->DefLines, 1,
"Symbol `%m%p' is %s but exported %s",
GetSymName (Sym),
AddrSizeToStr (Sym->AddrSize),
}
if (Sym->AddrSize > Sym->ExportSize) {
/* We're exporting a symbol smaller than it actually is */
- LIWarning (&S->LineInfos, 1,
+ LIWarning (&S->DefLines, 1,
"Symbol `%m%p' is %s but exported %s",
GetSymName (Sym),
AddrSizeToStr (Sym->AddrSize),
}
}
}
- Sym->Flags |= (S->Flags & SF_REFERENCED);
+ if (S->Flags & SF_REFERENCED) {
+ unsigned I;
+ Sym->Flags |= SF_REFERENCED;
+ for (I = 0; I < CollCount (&S->RefLines); ++I) {
+ CollAppend (&Sym->RefLines, CollAtUnchecked (&S->RefLines, I));
+ }
+ CollDeleteAll (&S->RefLines);
+ }
/* Transfer all expression references */
SymTransferExprRefs (S, Sym);
/* The symbol is definitely undefined */
if (S->Flags & SF_EXPORT) {
/* We will not auto-import an export */
- LIError (&S->LineInfos,
+ LIError (&S->RefLines,
"Exported symbol `%m%p' was never defined",
GetSymName (S));
} else {
S->Flags |= SF_IMPORT;
/* Use the address size for code */
S->AddrSize = CodeAddrSize;
+ /* Mark point of import */
+ GetFullLineInfo (&S->DefLines);
} else {
/* Error */
- LIError (&S->LineInfos,
+ LIError (&S->RefLines,
"Symbol `%m%p' is undefined",
GetSymName (S));
}
/* Handle undefined symbols */
if ((S->Flags & SF_UNDEFMASK) == SF_UNDEFVAL) {
/* This is an undefined symbol. Handle it. */
+ printf ("Undefined: %s\n", SB_GetConstBuf (GetSymName (S)));
SymCheckUndefined (S);
}
(S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
/* Check for defined symbols that were never referenced */
- if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
- const StrBuf* Name = GetStrBuf (S->Name);
- if (SB_At (Name, 0) != '.') { /* Ignore internals */
- LIWarning (&S->LineInfos, 2,
- "Symbol `%m%p' is defined but never used",
- GetSymName (S));
- }
- }
+ if (IsSizeOfSymbol (S)) {
+ /* Remove line infos, we don't need them any longer */
+ ReleaseFullLineInfo (&S->DefLines);
+ ReleaseFullLineInfo (&S->RefLines);
+ } else if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
+ LIWarning (&S->DefLines, 2,
+ "Symbol `%m%p' is defined but never used",
+ GetSymName (S));
+ }
/* Assign an index to all imports */
if (S->Flags & SF_IMPORT) {
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
/* Imported symbol is not referenced */
- LIWarning (&S->LineInfos, 2,
+ LIWarning (&S->DefLines, 2,
"Symbol `%m%p' is imported but never used",
GetSymName (S));
} else {
S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */
- LIWarning (&S->LineInfos, 1,
+ LIWarning (&S->DefLines, 1,
"Symbol `%m%p' is %s but exported %s",
GetSymName (S),
AddrSizeToStr (S->AddrSize),
ObjWrite8 (S->AddrSize);
ObjWriteVar (S->Name);
- WriteLineInfo (&S->LineInfos);
+ WriteLineInfo (&S->DefLines);
+ WriteLineInfo (&S->RefLines);
}
S = S->List;
}
}
/* Write the line infos */
- WriteLineInfo (&S->LineInfos);
+ WriteLineInfo (&S->DefLines);
+ WriteLineInfo (&S->RefLines);
}
S = S->List;
}
}
/* Write the line infos */
- WriteLineInfo (&S->LineInfos);
+ WriteLineInfo (&S->DefLines);
+ WriteLineInfo (&S->RefLines);
}
S = S->List;
}