Changed multi-line C comments into another style.
The left side doesn't look unbalanced.
This commit is contained in:
@@ -106,8 +106,8 @@ static unsigned BinWriteExpr (ExprNode* E, int Signed, unsigned Size,
|
||||
unsigned long Offs attribute ((unused)),
|
||||
void* Data)
|
||||
/* Called from SegWrite for an expression. Evaluate the expression, check the
|
||||
* range and write the expression value to the file.
|
||||
*/
|
||||
** range and write the expression value to the file.
|
||||
*/
|
||||
{
|
||||
/* There's a predefined function to handle constant expressions */
|
||||
return SegWriteConstExpr (((BinDesc*)Data)->F, E, Signed, Size);
|
||||
@@ -170,23 +170,23 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M)
|
||||
PrintNumVal ("FileOffs", (unsigned long) ftell (D->F));
|
||||
|
||||
/* Check if the alignment for the segment from the linker config is
|
||||
* a multiple for that of the segment.
|
||||
*/
|
||||
** a multiple for that of the segment.
|
||||
*/
|
||||
if ((S->RunAlignment % S->Seg->Alignment) != 0) {
|
||||
/* Segment requires another alignment than configured
|
||||
* in the linker.
|
||||
*/
|
||||
** in the linker.
|
||||
*/
|
||||
Warning ("Segment `%s' is not aligned properly. Resulting "
|
||||
"executable may not be functional.",
|
||||
GetString (S->Name));
|
||||
}
|
||||
|
||||
/* If this is the run memory area, we must apply run alignment. If
|
||||
* this is not the run memory area but the load memory area (which
|
||||
* means that both are different), we must apply load alignment.
|
||||
* Beware: DoWrite may be true even if this is the run memory area,
|
||||
* because it may be also the load memory area.
|
||||
*/
|
||||
** this is not the run memory area but the load memory area (which
|
||||
** means that both are different), we must apply load alignment.
|
||||
** Beware: DoWrite may be true even if this is the run memory area,
|
||||
** because it may be also the load memory area.
|
||||
*/
|
||||
if (S->Run == M) {
|
||||
|
||||
/* Handle ALIGN and OFFSET/START */
|
||||
@@ -227,8 +227,8 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M)
|
||||
}
|
||||
|
||||
/* Now write the segment to disk if it is not a BSS type segment and
|
||||
* if the memory area is the load area.
|
||||
*/
|
||||
** if the memory area is the load area.
|
||||
*/
|
||||
if (DoWrite) {
|
||||
unsigned long P = ftell (D->F);
|
||||
SegWrite (D->Filename, D->F, S->Seg, BinWriteExpr, D);
|
||||
@@ -263,9 +263,9 @@ static int BinUnresolved (unsigned Name attribute ((unused)), void* D)
|
||||
/* Called if an unresolved symbol is encountered */
|
||||
{
|
||||
/* Unresolved symbols are an error in binary format. Bump the counter
|
||||
* and return zero telling the caller that the symbol is indeed
|
||||
* unresolved.
|
||||
*/
|
||||
** and return zero telling the caller that the symbol is indeed
|
||||
** unresolved.
|
||||
*/
|
||||
((BinDesc*) D)->Undef++;
|
||||
return 0;
|
||||
}
|
||||
@@ -281,8 +281,8 @@ void BinWriteTarget (BinDesc* D, struct File* F)
|
||||
D->Filename = GetString (F->Name);
|
||||
|
||||
/* Check for unresolved symbols. The function BinUnresolved is called
|
||||
* if we get an unresolved symbol.
|
||||
*/
|
||||
** if we get an unresolved symbol.
|
||||
*/
|
||||
D->Undef = 0; /* Reset the counter */
|
||||
CheckUnresolvedImports (BinUnresolved, D);
|
||||
if (D->Undef > 0) {
|
||||
|
||||
@@ -230,8 +230,8 @@ long CfgConstExpr (void)
|
||||
|
||||
long CfgCheckedConstExpr (long Min, long Max)
|
||||
/* Read an expression, make sure it's an int and in range, then return its
|
||||
* value.
|
||||
*/
|
||||
** value.
|
||||
*/
|
||||
{
|
||||
/* Get the value */
|
||||
long Val = CfgConstExpr ();
|
||||
|
||||
@@ -57,8 +57,8 @@ long CfgConstExpr (void);
|
||||
|
||||
long CfgCheckedConstExpr (long Min, long Max);
|
||||
/* Read an expression, make sure it's an int and in range, then return its
|
||||
* value.
|
||||
*/
|
||||
** value.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -137,9 +137,9 @@ static int ConDesCompare (void* Data, const void* E1, const void* E2)
|
||||
int Cmp;
|
||||
|
||||
/* Data is actually a pointer to a ConDesDesc from the table, E1 and
|
||||
* E2 are exports from the collection. Get the condes type and cast
|
||||
* the void pointers to object pointers.
|
||||
*/
|
||||
** E2 are exports from the collection. Get the condes type and cast
|
||||
** the void pointers to object pointers.
|
||||
*/
|
||||
ConDesDesc* CD = ((ConDesDesc*) Data);
|
||||
int Type = CD - ConDes;
|
||||
const Export* Exp1 = (const Export*) E1;
|
||||
@@ -178,16 +178,16 @@ static void ConDesCreateOne (ConDesDesc* CD)
|
||||
unsigned I;
|
||||
|
||||
/* Check if this table has a segment and table label defined. If not,
|
||||
* creation was not requested in the config file - ignore it.
|
||||
*/
|
||||
** creation was not requested in the config file - ignore it.
|
||||
*/
|
||||
if (CD->SegName == INVALID_STRING_ID || CD->Label == INVALID_STRING_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if there is an import for the table label. If not, there is no
|
||||
* reference to the table and we would just waste memory creating the
|
||||
* table.
|
||||
*/
|
||||
** reference to the table and we would just waste memory creating the
|
||||
** table.
|
||||
*/
|
||||
if (!IsUnresolved (CD->Label)) {
|
||||
return;
|
||||
}
|
||||
@@ -202,10 +202,10 @@ static void ConDesCreateOne (ConDesDesc* CD)
|
||||
Sec = NewSection (Seg, 1, ADDR_SIZE_ABS);
|
||||
|
||||
/* Walk over the exports and create a fragment for each one. We will use
|
||||
* the exported expression without copying it, since it's cheap and there
|
||||
* is currently no place where it gets changed (hope this will not hunt
|
||||
* me later...).
|
||||
*/
|
||||
** the exported expression without copying it, since it's cheap and there
|
||||
** is currently no place where it gets changed (hope this will not hunt
|
||||
** me later...).
|
||||
*/
|
||||
Count = CollCount (&CD->ExpList);
|
||||
for (I = 0; I < Count; ++I) {
|
||||
|
||||
@@ -220,13 +220,13 @@ static void ConDesCreateOne (ConDesDesc* CD)
|
||||
}
|
||||
|
||||
/* Define the table start as an export, offset into section is zero
|
||||
* (the section only contains the table).
|
||||
*/
|
||||
** (the section only contains the table).
|
||||
*/
|
||||
CreateSectionExport (CD->Label, Sec, 0);
|
||||
|
||||
/* If we have a CountSym name given AND if it is referenced, define it
|
||||
* with the number of elements in the table.
|
||||
*/
|
||||
** with the number of elements in the table.
|
||||
*/
|
||||
if (CD->CountSym) {
|
||||
CreateConstExport (CD->CountSym, Count);
|
||||
}
|
||||
@@ -273,8 +273,8 @@ void ConDesSetSegName (unsigned Type, unsigned SegName)
|
||||
|
||||
const ConDesImport* ConDesGetImport (unsigned Type)
|
||||
/* Get the forced import for the given ConDes type. Returns NULL if there is
|
||||
* no forced import for this type.
|
||||
*/
|
||||
** no forced import for this type.
|
||||
*/
|
||||
{
|
||||
const ConDesImport* Import;
|
||||
|
||||
|
||||
@@ -89,8 +89,8 @@ void ConDesSetSegName (unsigned Type, unsigned SegName);
|
||||
|
||||
const ConDesImport* ConDesGetImport (unsigned Type);
|
||||
/* Get the forced import for the given ConDes type. Returns NULL if there is
|
||||
* no forced import for this type.
|
||||
*/
|
||||
** no forced import for this type.
|
||||
*/
|
||||
|
||||
void ConDesSetImport (unsigned Type, const ConDesImport* Import);
|
||||
/* Set the forced import for the given ConDes type */
|
||||
|
||||
@@ -131,9 +131,9 @@ typedef enum {
|
||||
} CfgSymType;
|
||||
|
||||
/* Symbol structure. It is used for o65 imports and exports, but also for
|
||||
* symbols from the SYMBOLS sections (symbols defined in the config file or
|
||||
* forced imports).
|
||||
*/
|
||||
** symbols from the SYMBOLS sections (symbols defined in the config file or
|
||||
** forced imports).
|
||||
*/
|
||||
typedef struct CfgSymbol CfgSymbol;
|
||||
struct CfgSymbol {
|
||||
CfgSymType Type; /* Type of symbol */
|
||||
@@ -268,9 +268,9 @@ static void MemoryInsert (MemoryArea* M, SegDesc* S)
|
||||
|
||||
static CfgSymbol* NewCfgSymbol (CfgSymType Type, unsigned Name)
|
||||
/* Create a new CfgSymbol structure with the given type and name. The
|
||||
* current config file position is recorded in the returned struct. The
|
||||
* created struct is inserted into the CfgSymbols collection and returned.
|
||||
*/
|
||||
** current config file position is recorded in the returned struct. The
|
||||
** created struct is inserted into the CfgSymbols collection and returned.
|
||||
*/
|
||||
{
|
||||
/* Allocate memory */
|
||||
CfgSymbol* Sym = xmalloc (sizeof (CfgSymbol));
|
||||
@@ -385,8 +385,8 @@ static void FreeSegDesc (SegDesc* S)
|
||||
|
||||
static void FlagAttr (unsigned* Flags, unsigned Mask, const char* Name)
|
||||
/* Check if the item is already defined. Print an error if so. If not, set
|
||||
* the marker that we have a definition now.
|
||||
*/
|
||||
** the marker that we have a definition now.
|
||||
*/
|
||||
{
|
||||
if (*Flags & Mask) {
|
||||
CfgError (&CfgErrorPos, "%s is already defined", Name);
|
||||
@@ -522,8 +522,8 @@ static void ParseMemory (void)
|
||||
AttrCheck (M->Attr, MA_SIZE, "SIZE");
|
||||
|
||||
/* If we don't have a file name for output given, use the default
|
||||
* file name.
|
||||
*/
|
||||
** file name.
|
||||
*/
|
||||
if ((M->Attr & MA_FILE) == 0) {
|
||||
FileInsert (GetFile (GetStringId (OutputName)), M);
|
||||
OutputNameUsed = 1;
|
||||
@@ -781,8 +781,8 @@ static void ParseSegments (void)
|
||||
}
|
||||
|
||||
/* An attribute of ALIGN_LOAD doesn't make sense if there are no
|
||||
* separate run and load memory areas.
|
||||
*/
|
||||
** separate run and load memory areas.
|
||||
*/
|
||||
if ((S->Flags & SF_ALIGN_LOAD) != 0 && (S->Load == S->Run)) {
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"ALIGN_LOAD attribute specified, but no separate "
|
||||
@@ -792,8 +792,8 @@ static void ParseSegments (void)
|
||||
}
|
||||
|
||||
/* If the segment is marked as BSS style, it may not have separate
|
||||
* load and run memory areas, because it's is never written to disk.
|
||||
*/
|
||||
** load and run memory areas, because it's is never written to disk.
|
||||
*/
|
||||
if ((S->Flags & SF_BSS) != 0 && (S->Load != S->Run)) {
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"Segment with type `bss' has both LOAD and RUN "
|
||||
@@ -930,8 +930,8 @@ static void ParseO65 (void)
|
||||
/* Cannot use this attribute twice */
|
||||
FlagAttr (&AttrFlags, atOS, "OS");
|
||||
/* Get the operating system. It may be specified as name or
|
||||
* as a number in the range 1..255.
|
||||
*/
|
||||
** as a number in the range 1..255.
|
||||
*/
|
||||
if (CfgTok == CFGTOK_INTCON) {
|
||||
CfgRangeCheck (O65OS_MIN, O65OS_MAX);
|
||||
OS = (unsigned) CfgIVal;
|
||||
@@ -1266,8 +1266,8 @@ static void ParseStartAddress (void)
|
||||
AttrCheck (AttrFlags, atDefault, "DEFAULT");
|
||||
|
||||
/* If no start address was given on the command line, use the one given
|
||||
* here
|
||||
*/
|
||||
** here
|
||||
*/
|
||||
if (!HaveStartAddr) {
|
||||
StartAddr = DefStartAddr;
|
||||
}
|
||||
@@ -1559,8 +1559,8 @@ void CfgRead (void)
|
||||
O65FmtDesc = NewO65Desc ();
|
||||
|
||||
/* If we have a config name given, open the file, otherwise we will read
|
||||
* from a buffer.
|
||||
*/
|
||||
** from a buffer.
|
||||
*/
|
||||
CfgOpenInput ();
|
||||
|
||||
/* Parse the file */
|
||||
@@ -1591,14 +1591,14 @@ static void ProcessSegments (void)
|
||||
SegDesc* S = CollAtUnchecked (&SegDescList, I);
|
||||
|
||||
/* Search for the actual segment in the input files. The function may
|
||||
* return NULL (no such segment), this is checked later.
|
||||
*/
|
||||
** return NULL (no such segment), this is checked later.
|
||||
*/
|
||||
S->Seg = SegFind (S->Name);
|
||||
|
||||
/* If the segment is marked as BSS style, and if the segment exists
|
||||
* in any of the object file, check that there's no initialized data
|
||||
* in the segment.
|
||||
*/
|
||||
** in any of the object file, check that there's no initialized data
|
||||
** in the segment.
|
||||
*/
|
||||
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment `%s' with type `bss' contains initialized data",
|
||||
@@ -1606,10 +1606,10 @@ static void ProcessSegments (void)
|
||||
}
|
||||
|
||||
/* If this segment does exist in any of the object files, insert the
|
||||
* segment into the load/run memory areas. Otherwise print a warning
|
||||
* and discard it, because the segment pointer in the descriptor is
|
||||
* invalid.
|
||||
*/
|
||||
** segment into the load/run memory areas. Otherwise print a warning
|
||||
** and discard it, because the segment pointer in the descriptor is
|
||||
** invalid.
|
||||
*/
|
||||
if (S->Seg != 0) {
|
||||
|
||||
/* Insert the segment into the memory area list */
|
||||
@@ -1669,9 +1669,9 @@ static void ProcessSymbols (void)
|
||||
}
|
||||
|
||||
/* Check if we have this symbol defined already. The entry
|
||||
* routine will check this also, but we get a more verbose
|
||||
* error message when checking it here.
|
||||
*/
|
||||
** routine will check this also, but we get a more verbose
|
||||
** error message when checking it here.
|
||||
*/
|
||||
if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
GetSourcePos (Sym->LI),
|
||||
@@ -1695,9 +1695,9 @@ static void ProcessSymbols (void)
|
||||
}
|
||||
|
||||
/* Check if we have this symbol defined already. The entry
|
||||
* routine will check this also, but we get a more verbose
|
||||
* error message when checking it here.
|
||||
*/
|
||||
** routine will check this also, but we get a more verbose
|
||||
** error message when checking it here.
|
||||
*/
|
||||
if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
GetSourcePos (Sym->LI),
|
||||
@@ -1770,28 +1770,28 @@ static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr)
|
||||
|
||||
unsigned CfgProcess (void)
|
||||
/* Process the config file after reading in object files and libraries. This
|
||||
* includes postprocessing of the config file data but also assigning segments
|
||||
* and defining segment/memory area related symbols. The function will return
|
||||
* the number of memory area overflows (so zero means anything went ok).
|
||||
* In case of overflows, a short mapfile can be generated later, to ease the
|
||||
* task of rearranging segments for the user.
|
||||
*/
|
||||
** includes postprocessing of the config file data but also assigning segments
|
||||
** and defining segment/memory area related symbols. The function will return
|
||||
** the number of memory area overflows (so zero means anything went ok).
|
||||
** In case of overflows, a short mapfile can be generated later, to ease the
|
||||
** task of rearranging segments for the user.
|
||||
*/
|
||||
{
|
||||
unsigned Overflows = 0;
|
||||
unsigned I;
|
||||
|
||||
/* Postprocess symbols. We must do that first, since weak symbols are
|
||||
* defined here, which may be needed later.
|
||||
*/
|
||||
** defined here, which may be needed later.
|
||||
*/
|
||||
ProcessSymbols ();
|
||||
|
||||
/* Postprocess segments */
|
||||
ProcessSegments ();
|
||||
|
||||
/* Walk through each of the memory sections. Add up the sizes and check
|
||||
* for an overflow of the section. Assign the start addresses of the
|
||||
* segments while doing this.
|
||||
*/
|
||||
** for an overflow of the section. Assign the start addresses of the
|
||||
** segments while doing this.
|
||||
*/
|
||||
for (I = 0; I < CollCount (&MemoryAreas); ++I) {
|
||||
|
||||
unsigned J;
|
||||
@@ -1807,8 +1807,8 @@ unsigned CfgProcess (void)
|
||||
M->Relocatable = RelocatableBinFmt (M->F->Format);
|
||||
|
||||
/* Resolve the start address expression, remember the start address
|
||||
* and mark the memory area as placed.
|
||||
*/
|
||||
** and mark the memory area as placed.
|
||||
*/
|
||||
if (!IsConstExpr (M->StartExpr)) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Start address of memory area `%s' is not constant",
|
||||
@@ -1818,9 +1818,9 @@ unsigned CfgProcess (void)
|
||||
M->Flags |= MF_PLACED;
|
||||
|
||||
/* If requested, define the symbol for the start of the memory area.
|
||||
* Doing it here means that the expression for the size of the area
|
||||
* may reference this symbol.
|
||||
*/
|
||||
** Doing it here means that the expression for the size of the area
|
||||
** may reference this symbol.
|
||||
*/
|
||||
if (M->Flags & MF_DEFINE) {
|
||||
Export* E;
|
||||
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||
@@ -1851,21 +1851,21 @@ unsigned CfgProcess (void)
|
||||
unsigned long StartAddr = Addr;
|
||||
|
||||
/* Some actions depend on wether this is the load or run memory
|
||||
* area.
|
||||
*/
|
||||
** area.
|
||||
*/
|
||||
if (S->Run == M) {
|
||||
|
||||
/* This is the run (and maybe load) memory area. Handle
|
||||
* alignment and explict start address and offset.
|
||||
*/
|
||||
** alignment and explict start address and offset.
|
||||
*/
|
||||
if (S->Flags & SF_ALIGN) {
|
||||
/* Align the address */
|
||||
unsigned long NewAddr = AlignAddr (Addr, S->RunAlignment);
|
||||
|
||||
/* If the first segment placed in the memory area needs
|
||||
* fill bytes for the alignment, emit a warning, since
|
||||
* this is somewhat suspicious.
|
||||
*/
|
||||
** fill bytes for the alignment, emit a warning, since
|
||||
** this is somewhat suspicious.
|
||||
*/
|
||||
if (M->FillLevel == 0 && NewAddr > Addr) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"First segment in memory area `%s' does "
|
||||
@@ -1901,22 +1901,22 @@ unsigned CfgProcess (void)
|
||||
}
|
||||
|
||||
/* Set the start address of this segment, set the readonly flag
|
||||
* in the segment and and remember if the segment is in a
|
||||
* relocatable file or not.
|
||||
*/
|
||||
** in the segment and and remember if the segment is in a
|
||||
** relocatable file or not.
|
||||
*/
|
||||
S->Seg->PC = Addr;
|
||||
S->Seg->ReadOnly = (S->Flags & SF_RO) != 0;
|
||||
|
||||
/* Remember the run memory for this segment, which is also a
|
||||
* flag that the segment has been placed.
|
||||
*/
|
||||
** flag that the segment has been placed.
|
||||
*/
|
||||
S->Seg->MemArea = M;
|
||||
|
||||
} else if (S->Load == M) {
|
||||
|
||||
/* This is the load memory area, *and* run and load are
|
||||
* different (because of the "else" above). Handle alignment.
|
||||
*/
|
||||
** different (because of the "else" above). Handle alignment.
|
||||
*/
|
||||
if (S->Flags & SF_ALIGN_LOAD) {
|
||||
/* Align the address */
|
||||
Addr = AlignAddr (Addr, S->LoadAlignment);
|
||||
@@ -1925,15 +1925,15 @@ unsigned CfgProcess (void)
|
||||
}
|
||||
|
||||
/* If this is the load memory area and the segment doesn't have a
|
||||
* fill value defined, use the one from the memory area.
|
||||
*/
|
||||
** fill value defined, use the one from the memory area.
|
||||
*/
|
||||
if (S->Load == M && (S->Flags & SF_FILLVAL) == 0) {
|
||||
S->Seg->FillVal = M->FillVal;
|
||||
}
|
||||
|
||||
/* Increment the fill level of the memory area and check for an
|
||||
* overflow.
|
||||
*/
|
||||
** overflow.
|
||||
*/
|
||||
M->FillLevel = Addr + S->Seg->Size - M->Start;
|
||||
if (M->FillLevel > M->Size && (M->Flags & MF_OVERFLOW) == 0) {
|
||||
++Overflows;
|
||||
@@ -1945,8 +1945,8 @@ unsigned CfgProcess (void)
|
||||
}
|
||||
|
||||
/* If requested, define symbols for the start and size of the
|
||||
* segment.
|
||||
*/
|
||||
** segment.
|
||||
*/
|
||||
if (S->Flags & SF_DEFINE) {
|
||||
if (S->Run == M && (S->Flags & SF_RUN_DEF) == 0) {
|
||||
CreateRunDefines (S, Addr);
|
||||
@@ -1960,8 +1960,8 @@ unsigned CfgProcess (void)
|
||||
Addr += S->Seg->Size;
|
||||
|
||||
/* If this segment will go out to the file, or its place
|
||||
* in the file will be filled, then increase the file size.
|
||||
*/
|
||||
** in the file will be filled, then increase the file size.
|
||||
*/
|
||||
if (S->Load == M &&
|
||||
((S->Flags & SF_BSS) == 0 || (M->Flags & MF_FILL) != 0)) {
|
||||
M->F->Size += Addr - StartAddr;
|
||||
@@ -1970,8 +1970,8 @@ unsigned CfgProcess (void)
|
||||
}
|
||||
|
||||
/* If requested, define symbols for start, size and offset of the
|
||||
* memory area
|
||||
*/
|
||||
** memory area
|
||||
*/
|
||||
if (M->Flags & MF_DEFINE) {
|
||||
Export* E;
|
||||
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||
@@ -1987,8 +1987,8 @@ unsigned CfgProcess (void)
|
||||
CollAppend (&E->DefLines, M->LI);
|
||||
|
||||
/* Define the file offset of the memory area. This isn't of much
|
||||
* use for relocatable output files.
|
||||
*/
|
||||
** use for relocatable output files.
|
||||
*/
|
||||
if (!M->Relocatable) {
|
||||
SB_Printf (&Buf, "__%s_FILEOFFS__", GetString (M->Name));
|
||||
E = CreateConstExport (GetStrBufId (&Buf), M->FileOffs);
|
||||
@@ -2000,8 +2000,8 @@ unsigned CfgProcess (void)
|
||||
}
|
||||
|
||||
/* If we didn't have an overflow and are requested to fill the memory
|
||||
* area, acount for that in the file size.
|
||||
*/
|
||||
** area, acount for that in the file size.
|
||||
*/
|
||||
if ((M->Flags & MF_OVERFLOW) == 0 && (M->Flags & MF_FILL) != 0) {
|
||||
M->F->Size += (M->Size - M->FillLevel);
|
||||
}
|
||||
@@ -2054,8 +2054,8 @@ void CfgWriteTarget (void)
|
||||
} else {
|
||||
|
||||
/* No output file. Walk through the list and mark all segments
|
||||
* loading into these memory areas in this file as dumped.
|
||||
*/
|
||||
** loading into these memory areas in this file as dumped.
|
||||
*/
|
||||
unsigned J;
|
||||
for (J = 0; J < CollCount (&F->MemoryAreas); ++J) {
|
||||
|
||||
|
||||
@@ -110,12 +110,12 @@ void CfgRead (void);
|
||||
|
||||
unsigned CfgProcess (void);
|
||||
/* Process the config file after reading in object files and libraries. This
|
||||
* includes postprocessing of the config file data but also assigning segments
|
||||
* and defining segment/memory area related symbols. The function will return
|
||||
* the number of memory area overflows (so zero means anything went ok).
|
||||
* In case of overflows, a short mapfile can be generated later, to ease the
|
||||
* task of rearranging segments for the user.
|
||||
*/
|
||||
** includes postprocessing of the config file data but also assigning segments
|
||||
** and defining segment/memory area related symbols. The function will return
|
||||
** the number of memory area overflows (so zero means anything went ok).
|
||||
** In case of overflows, a short mapfile can be generated later, to ease the
|
||||
** task of rearranging segments for the user.
|
||||
*/
|
||||
|
||||
void CfgWriteTarget (void);
|
||||
/* Write the target file(s) */
|
||||
|
||||
@@ -60,10 +60,10 @@
|
||||
|
||||
static void AssignIds (void)
|
||||
/* Assign the base ids for debug info output. Within each module, many of the
|
||||
* items are addressed by ids which are actually the indices of the items in
|
||||
* the collections. To make them unique, we must assign a unique base to each
|
||||
* range.
|
||||
*/
|
||||
** items are addressed by ids which are actually the indices of the items in
|
||||
** the collections. To make them unique, we must assign a unique base to each
|
||||
** range.
|
||||
*/
|
||||
{
|
||||
/* Walk over all modules */
|
||||
unsigned I;
|
||||
@@ -114,8 +114,8 @@ void CreateDbgFile (void)
|
||||
fprintf (F, "version\tmajor=2,minor=0\n");
|
||||
|
||||
/* Output a line with the item numbers so the debug info module is able
|
||||
* to preallocate the required memory.
|
||||
*/
|
||||
** to preallocate the required memory.
|
||||
*/
|
||||
fprintf (
|
||||
F,
|
||||
"info\tcsym=%u,file=%u,lib=%u,line=%u,mod=%u,scope=%u,seg=%u,span=%u,sym=%u,type=%u\n",
|
||||
|
||||
@@ -91,8 +91,8 @@ struct HLLDbgSym {
|
||||
};
|
||||
|
||||
/* We will collect all debug symbols in the following array and remove
|
||||
* duplicates before outputing them into a label file.
|
||||
*/
|
||||
** duplicates before outputing them into a label file.
|
||||
*/
|
||||
static DbgSym* DbgSymPool[256];
|
||||
|
||||
|
||||
@@ -141,8 +141,8 @@ static HLLDbgSym* NewHLLDbgSym (void)
|
||||
|
||||
static DbgSym* GetDbgSym (DbgSym* D, long Val)
|
||||
/* Check if we find the same debug symbol in the table. If we find it, return
|
||||
* a pointer to the other occurrence, if we didn't find it, return NULL.
|
||||
*/
|
||||
** a pointer to the other occurrence, if we didn't find it, return NULL.
|
||||
*/
|
||||
{
|
||||
/* Create the hash. We hash over the symbol value */
|
||||
unsigned Hash = ((Val >> 24) & 0xFF) ^
|
||||
@@ -219,8 +219,8 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O, unsigned Id)
|
||||
}
|
||||
|
||||
/* If its an exports, there's also the export id, but we don't remember
|
||||
* it but use it to let the export point back to us.
|
||||
*/
|
||||
** it but use it to let the export point back to us.
|
||||
*/
|
||||
if (SYM_IS_EXPORT (D->Type)) {
|
||||
/* Get the export from the export id, then set the our id */
|
||||
GetObjExport (O, ReadVar (F))->DbgSymId = Id;
|
||||
@@ -377,8 +377,8 @@ void PrintDbgSyms (FILE* F)
|
||||
}
|
||||
|
||||
/* For cheap local symbols, add the owner symbol, for others,
|
||||
* add the owner scope.
|
||||
*/
|
||||
** add the owner scope.
|
||||
*/
|
||||
if (SYM_IS_STD (S->Type)) {
|
||||
fprintf (F, ",scope=%u", O->ScopeBaseId + S->OwnerId);
|
||||
} else {
|
||||
@@ -390,9 +390,9 @@ void PrintDbgSyms (FILE* F)
|
||||
PrintLineInfo (F, &S->RefLines, ",ref=%u");
|
||||
|
||||
/* If this is an import, output the id of the matching export.
|
||||
* If this is not an import, output its value and - if we have
|
||||
* it - the segment.
|
||||
*/
|
||||
** If this is not an import, output its value and - if we have
|
||||
** it - the segment.
|
||||
*/
|
||||
if (SYM_IS_IMPORT (S->Type)) {
|
||||
|
||||
/* Get the import */
|
||||
@@ -405,9 +405,9 @@ void PrintDbgSyms (FILE* F)
|
||||
fputs (",type=imp", F);
|
||||
|
||||
/* If this is not a linker generated symbol, and the module
|
||||
* that contains the export has debug info, output the debug
|
||||
* symbol id for the export
|
||||
*/
|
||||
** that contains the export has debug info, output the debug
|
||||
** symbol id for the export
|
||||
*/
|
||||
if (Exp->Obj && OBJ_HAS_DBGINFO (Exp->Obj->Header.Flags)) {
|
||||
fprintf (F, ",exp=%u", Exp->Obj->SymBaseId + Exp->DbgSymId);
|
||||
}
|
||||
@@ -423,8 +423,8 @@ void PrintDbgSyms (FILE* F)
|
||||
fprintf (F, ",val=0x%lX", Val);
|
||||
|
||||
/* Check for a segmented expression and add the segment id to
|
||||
* the debug info if we have one.
|
||||
*/
|
||||
** the debug info if we have one.
|
||||
*/
|
||||
GetSegExprVal (S->Expr, &D);
|
||||
if (!D.TooComplex && D.Seg != 0) {
|
||||
fprintf (F, ",seg=%u", D.Seg->Id);
|
||||
@@ -526,9 +526,9 @@ void PrintDbgSymLabels (FILE* F)
|
||||
Val = GetDbgSymVal (D);
|
||||
|
||||
/* Lookup this symbol in the table. If it is found in the table, it was
|
||||
* already written to the file, so don't emit it twice. If it is not in
|
||||
* the table, insert and output it.
|
||||
*/
|
||||
** already written to the file, so don't emit it twice. If it is not in
|
||||
** the table, insert and output it.
|
||||
*/
|
||||
if (GetDbgSym (D, Val) == 0) {
|
||||
|
||||
/* Emit the VICE label line */
|
||||
|
||||
@@ -123,9 +123,9 @@ static Import* NewImport (unsigned char AddrSize, ObjData* Obj)
|
||||
|
||||
void FreeImport (Import* I)
|
||||
/* Free an import. NOTE: This won't remove the import from the exports table,
|
||||
* so it may only be called for unused imports (imports from modules that
|
||||
* aren't referenced).
|
||||
*/
|
||||
** so it may only be called for unused imports (imports from modules that
|
||||
** aren't referenced).
|
||||
*/
|
||||
{
|
||||
/* Safety */
|
||||
PRECONDITION ((I->Flags & IMP_INLIST) == 0);
|
||||
@@ -161,9 +161,9 @@ Import* ReadImport (FILE* F, ObjData* Obj)
|
||||
/* 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.
|
||||
*/
|
||||
** is not read completely into memory. In this case, the file list is
|
||||
** invalid. Be sure not to access it in this case.
|
||||
*/
|
||||
if (ObjHasFiles (I->Obj)) {
|
||||
const LineInfo* LI = GetImportPos (I);
|
||||
Error ("Invalid import size in for `%s', imported from %s(%u): 0x%02X",
|
||||
@@ -197,8 +197,8 @@ Import* GenImport (unsigned Name, unsigned char AddrSize)
|
||||
/* Check the address size */
|
||||
if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) {
|
||||
/* We have no object file information and no line info for a new
|
||||
* import
|
||||
*/
|
||||
** import
|
||||
*/
|
||||
Error ("Invalid import size 0x%02X for symbol `%s'",
|
||||
I->AddrSize,
|
||||
GetString (I->Name));
|
||||
@@ -246,8 +246,8 @@ Import* InsertImport (Import* I)
|
||||
}
|
||||
|
||||
/* Ok, E now points to a valid exports entry for the given import. Insert
|
||||
* the import into the imports list and update the counters.
|
||||
*/
|
||||
** the import into the imports list and update the counters.
|
||||
*/
|
||||
I->Exp = E;
|
||||
I->Next = E->ImpList;
|
||||
E->ImpList = I;
|
||||
@@ -321,9 +321,9 @@ static Export* NewExport (unsigned Type, unsigned char AddrSize,
|
||||
|
||||
void FreeExport (Export* E)
|
||||
/* Free an export. NOTE: This won't remove the export from the exports table,
|
||||
* so it may only be called for unused exports (exports from modules that
|
||||
* aren't referenced).
|
||||
*/
|
||||
** so it may only be called for unused exports (exports from modules that
|
||||
** aren't referenced).
|
||||
*/
|
||||
{
|
||||
/* Safety */
|
||||
PRECONDITION ((E->Flags & EXP_INLIST) == 0);
|
||||
@@ -367,9 +367,9 @@ Export* ReadExport (FILE* F, ObjData* O)
|
||||
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.
|
||||
*/
|
||||
** 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]);
|
||||
}
|
||||
@@ -395,8 +395,8 @@ Export* ReadExport (FILE* F, ObjData* O)
|
||||
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.
|
||||
*/
|
||||
** forced import, add this import to the object module.
|
||||
*/
|
||||
for (I = 0; I < CD_TYPE_COUNT; ++I) {
|
||||
const ConDesImport* CDI;
|
||||
|
||||
@@ -410,10 +410,10 @@ Export* ReadExport (FILE* F, ObjData* 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.
|
||||
*/
|
||||
** 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)));
|
||||
}
|
||||
@@ -461,8 +461,8 @@ void InsertExport (Export* E)
|
||||
if (L->Expr == 0) {
|
||||
|
||||
/* This *is* an unresolved external. Use the actual export
|
||||
* in E instead of the dummy one in L.
|
||||
*/
|
||||
** in E instead of the dummy one in L.
|
||||
*/
|
||||
E->Next = L->Next;
|
||||
E->ImpCount = L->ImpCount;
|
||||
E->ImpList = L->ImpList;
|
||||
@@ -474,8 +474,8 @@ void InsertExport (Export* 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) {
|
||||
Imp->Exp = E;
|
||||
@@ -606,8 +606,8 @@ Export* CreateSectionExport (unsigned Name, Section* Sec, unsigned long Offs)
|
||||
|
||||
Export* FindExport (unsigned 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 */
|
||||
Export* L = HashTab[Name & HASHTAB_MASK];
|
||||
@@ -685,9 +685,9 @@ static void CheckSymType (const Export* E)
|
||||
const LineInfo* ImportLI = GetImportPos (I);
|
||||
|
||||
/* Generate strings that describe the location of the im- and
|
||||
* exports. This depends on the place from where they come:
|
||||
* Object file or linker config.
|
||||
*/
|
||||
** exports. This depends on the place from where they come:
|
||||
** Object file or linker config.
|
||||
*/
|
||||
if (E->Obj) {
|
||||
/* The export comes from an object file */
|
||||
SB_Printf (&ExportLoc, "%s, %s(%u)",
|
||||
@@ -707,15 +707,15 @@ static void CheckSymType (const Export* E)
|
||||
GetSourceLine (ImportLI));
|
||||
} else if (ImportLI) {
|
||||
/* The import is linker generated and we have line
|
||||
* information
|
||||
*/
|
||||
** information
|
||||
*/
|
||||
SB_Printf (&ImportLoc, "%s(%u)",
|
||||
GetSourceName (ImportLI),
|
||||
GetSourceLine (ImportLI));
|
||||
} else {
|
||||
/* The import is linker generated and we don't have line
|
||||
* information
|
||||
*/
|
||||
** information
|
||||
*/
|
||||
SB_Printf (&ImportLoc, "%s", GetObjFileName (I->Obj));
|
||||
}
|
||||
|
||||
@@ -758,8 +758,8 @@ static void CheckSymTypes (void)
|
||||
|
||||
static void PrintUnresolved (ExpCheckFunc F, void* Data)
|
||||
/* Print a list of unresolved symbols. On unresolved symbols, F is
|
||||
* called (see the comments on ExpCheckFunc in the data section).
|
||||
*/
|
||||
** called (see the comments on ExpCheckFunc in the data section).
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
@@ -827,8 +827,8 @@ static void CreateExportPool (void)
|
||||
|
||||
void CheckExports (void)
|
||||
/* Setup the list of all exports and check for export/import symbol type
|
||||
* mismatches.
|
||||
*/
|
||||
** mismatches.
|
||||
*/
|
||||
{
|
||||
/* Create an export pool */
|
||||
CreateExportPool ();
|
||||
@@ -841,8 +841,8 @@ void CheckExports (void)
|
||||
|
||||
void CheckUnresolvedImports (ExpCheckFunc F, void* Data)
|
||||
/* Check if there are any unresolved imports. On unresolved imports, F is
|
||||
* called (see the comments on ExpCheckFunc in the data section).
|
||||
*/
|
||||
** called (see the comments on ExpCheckFunc in the data section).
|
||||
*/
|
||||
{
|
||||
/* Check for unresolved externals */
|
||||
if (ImpOpen != 0) {
|
||||
@@ -970,8 +970,8 @@ void PrintImportMap (FILE* F)
|
||||
const Export* Exp = ExpPool [I];
|
||||
|
||||
/* Print the symbol only if there are imports, or if a verbose map
|
||||
* file is requested.
|
||||
*/
|
||||
** file is requested.
|
||||
*/
|
||||
if (VerboseMap || Exp->ImpCount > 0) {
|
||||
|
||||
/* Print the export */
|
||||
@@ -985,9 +985,9 @@ void PrintImportMap (FILE* F)
|
||||
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.
|
||||
*/
|
||||
** generated, in which case there is no object file and
|
||||
** sometimes no line information.
|
||||
*/
|
||||
const LineInfo* LI = GetImportPos (Imp);
|
||||
if (LI) {
|
||||
fprintf (F,
|
||||
|
||||
@@ -96,11 +96,11 @@ struct Export {
|
||||
|
||||
|
||||
/* Prototype of a function that is called if an undefined symbol is found. It
|
||||
* may check if the symbol is an external symbol (for binary formats that
|
||||
* support externals) and will return zero if the symbol could not be
|
||||
* resolved, or a value != zero if the symbol could be resolved. The
|
||||
* CheckExports routine will print out the missing symbol in the first case.
|
||||
*/
|
||||
** may check if the symbol is an external symbol (for binary formats that
|
||||
** support externals) and will return zero if the symbol could not be
|
||||
** resolved, or a value != zero if the symbol could be resolved. The
|
||||
** CheckExports routine will print out the missing symbol in the first case.
|
||||
*/
|
||||
typedef int (*ExpCheckFunc) (unsigned Name, void* Data);
|
||||
|
||||
|
||||
@@ -113,9 +113,9 @@ typedef int (*ExpCheckFunc) (unsigned Name, void* Data);
|
||||
|
||||
void FreeImport (Import* I);
|
||||
/* Free an import. NOTE: This won't remove the import from the exports table,
|
||||
* so it may only be called for unused imports (imports from modules that
|
||||
* aren't referenced).
|
||||
*/
|
||||
** so it may only be called for unused imports (imports from modules that
|
||||
** aren't referenced).
|
||||
*/
|
||||
|
||||
Import* ReadImport (FILE* F, ObjData* Obj);
|
||||
/* Read an import from a file and insert it into the table */
|
||||
@@ -131,9 +131,9 @@ const LineInfo* GetImportPos (const Import* I);
|
||||
|
||||
void FreeExport (Export* E);
|
||||
/* Free an export. NOTE: This won't remove the export from the exports table,
|
||||
* so it may only be called for unused exports (exports from modules that
|
||||
* aren't referenced).
|
||||
*/
|
||||
** so it may only be called for unused exports (exports from modules that
|
||||
** aren't referenced).
|
||||
*/
|
||||
|
||||
Export* ReadExport (FILE* F, ObjData* Obj);
|
||||
/* Read an export from a file */
|
||||
@@ -161,8 +161,8 @@ Export* CreateSectionExport (unsigned Name, Section* S, unsigned long Offs);
|
||||
|
||||
Export* FindExport (unsigned 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.
|
||||
*/
|
||||
|
||||
int IsUnresolved (unsigned Name);
|
||||
/* Check if this symbol is an unresolved export */
|
||||
@@ -178,13 +178,13 @@ long GetExportVal (const Export* E);
|
||||
|
||||
void CheckExports (void);
|
||||
/* Setup the list of all exports and check for export/import symbol type
|
||||
* mismatches.
|
||||
*/
|
||||
** mismatches.
|
||||
*/
|
||||
|
||||
void CheckUnresolvedImports (ExpCheckFunc F, void* Data);
|
||||
/* Check if there are any unresolved imports. On unresolved imports, F is
|
||||
* called (see the comments on ExpCheckFunc in the data section).
|
||||
*/
|
||||
** called (see the comments on ExpCheckFunc in the data section).
|
||||
*/
|
||||
|
||||
void PrintExportMapByName (FILE* F);
|
||||
/* Print an export map to the given file (sorted by symbol name) */
|
||||
|
||||
@@ -93,8 +93,8 @@ void FreeExpr (ExprNode* Root)
|
||||
|
||||
int IsConstExpr (ExprNode* Root)
|
||||
/* Return true if the given expression is a constant expression, that is, one
|
||||
* with no references to external symbols.
|
||||
*/
|
||||
** with no references to external symbols.
|
||||
*/
|
||||
{
|
||||
int Const;
|
||||
Export* E;
|
||||
@@ -111,9 +111,9 @@ int IsConstExpr (ExprNode* Root)
|
||||
/* Get the referenced export */
|
||||
E = GetExprExport (Root);
|
||||
/* If this export has a mark set, we've already encountered it.
|
||||
* This means that the export is used to define it's own value,
|
||||
* which in turn means, that we have a circular reference.
|
||||
*/
|
||||
** This means that the export is used to define it's own value,
|
||||
** which in turn means, that we have a circular reference.
|
||||
*/
|
||||
if (ExportHasMark (E)) {
|
||||
CircularRefError (E);
|
||||
Const = 0;
|
||||
@@ -126,8 +126,8 @@ int IsConstExpr (ExprNode* Root)
|
||||
|
||||
case EXPR_SECTION:
|
||||
/* A section expression is const if the segment it is in is
|
||||
* not relocatable and already placed.
|
||||
*/
|
||||
** not relocatable and already placed.
|
||||
*/
|
||||
S = GetExprSection (Root);
|
||||
M = S->Seg->MemArea;
|
||||
return M != 0 && (M->Flags & MF_PLACED) != 0 && !M->Relocatable;
|
||||
@@ -160,9 +160,9 @@ int IsConstExpr (ExprNode* Root)
|
||||
GetSegExprVal (Root->Left, &D);
|
||||
|
||||
/* The expression is const if the expression contains exactly
|
||||
* one segment that is assigned to a memory area which has a
|
||||
* bank attribute that is constant.
|
||||
*/
|
||||
** one segment that is assigned to a memory area which has a
|
||||
** bank attribute that is constant.
|
||||
*/
|
||||
return (D.TooComplex == 0 &&
|
||||
D.Seg != 0 &&
|
||||
D.Seg->MemArea != 0 &&
|
||||
@@ -224,9 +224,9 @@ Import* GetExprImport (ExprNode* Expr)
|
||||
PRECONDITION (Expr->Op == EXPR_SYMBOL);
|
||||
|
||||
/* If we have an object file, get the import from it, otherwise
|
||||
* (internally generated expressions), get the import from the
|
||||
* import pointer.
|
||||
*/
|
||||
** (internally generated expressions), get the import from the
|
||||
** import pointer.
|
||||
*/
|
||||
if (Expr->Obj) {
|
||||
/* Return the Import */
|
||||
return GetObjImport (Expr->Obj, Expr->V.ImpNum);
|
||||
@@ -256,9 +256,9 @@ Section* GetExprSection (ExprNode* Expr)
|
||||
PRECONDITION (Expr->Op == EXPR_SECTION);
|
||||
|
||||
/* If we have an object file, get the section from it, otherwise
|
||||
* (internally generated expressions), get the section from the
|
||||
* section pointer.
|
||||
*/
|
||||
** (internally generated expressions), get the section from the
|
||||
** section pointer.
|
||||
*/
|
||||
if (Expr->Obj) {
|
||||
/* Return the export */
|
||||
return CollAt (&Expr->Obj->Sections, Expr->V.SecNum);
|
||||
@@ -288,9 +288,9 @@ long GetExprVal (ExprNode* Expr)
|
||||
/* Get the referenced export */
|
||||
E = GetExprExport (Expr);
|
||||
/* If this export has a mark set, we've already encountered it.
|
||||
* This means that the export is used to define it's own value,
|
||||
* which in turn means, that we have a circular reference.
|
||||
*/
|
||||
** This means that the export is used to define it's own value,
|
||||
** which in turn means, that we have a circular reference.
|
||||
*/
|
||||
if (ExportHasMark (E)) {
|
||||
CircularRefError (E);
|
||||
Val = 0;
|
||||
@@ -453,10 +453,10 @@ long GetExprVal (ExprNode* Expr)
|
||||
|
||||
static void GetSegExprValInternal (ExprNode* Expr, SegExprDesc* D, int Sign)
|
||||
/* Check if the given expression consists of a segment reference and only
|
||||
* constant values, additions and subtractions. If anything else is found,
|
||||
* set D->TooComplex to true.
|
||||
* Internal, recursive routine.
|
||||
*/
|
||||
** constant values, additions and subtractions. If anything else is found,
|
||||
** set D->TooComplex to true.
|
||||
** Internal, recursive routine.
|
||||
*/
|
||||
{
|
||||
Export* E;
|
||||
|
||||
@@ -470,9 +470,9 @@ static void GetSegExprValInternal (ExprNode* Expr, SegExprDesc* D, int Sign)
|
||||
/* Get the referenced export */
|
||||
E = GetExprExport (Expr);
|
||||
/* If this export has a mark set, we've already encountered it.
|
||||
* This means that the export is used to define it's own value,
|
||||
* which in turn means, that we have a circular reference.
|
||||
*/
|
||||
** This means that the export is used to define it's own value,
|
||||
** which in turn means, that we have a circular reference.
|
||||
*/
|
||||
if (ExportHasMark (E)) {
|
||||
CircularRefError (E);
|
||||
} else {
|
||||
@@ -530,9 +530,9 @@ static void GetSegExprValInternal (ExprNode* Expr, SegExprDesc* D, int Sign)
|
||||
|
||||
void GetSegExprVal (ExprNode* Expr, SegExprDesc* D)
|
||||
/* Check if the given expression consists of a segment reference and only
|
||||
* constant values, additions and subtractions. If anything else is found,
|
||||
* set D->TooComplex to true. The function will initialize D.
|
||||
*/
|
||||
** constant values, additions and subtractions. If anything else is found,
|
||||
** set D->TooComplex to true. The function will initialize D.
|
||||
*/
|
||||
{
|
||||
/* Initialize the given structure */
|
||||
D->Val = 0;
|
||||
|
||||
@@ -78,8 +78,8 @@ void FreeExpr (ExprNode* Root);
|
||||
|
||||
int IsConstExpr (ExprNode* Root);
|
||||
/* Return true if the given expression is a constant expression, that is, one
|
||||
* with no references to external symbols.
|
||||
*/
|
||||
** with no references to external symbols.
|
||||
*/
|
||||
|
||||
Import* GetExprImport (ExprNode* Expr);
|
||||
/* Get the import data structure for a symbol expression node */
|
||||
@@ -95,9 +95,9 @@ long GetExprVal (ExprNode* Expr);
|
||||
|
||||
void GetSegExprVal (ExprNode* Expr, SegExprDesc* D);
|
||||
/* Check if the given expression consists of a segment reference and only
|
||||
* constant values, additions and subtractions. If anything else is found,
|
||||
* set D->TooComplex to true. The function will initialize D.
|
||||
*/
|
||||
** constant values, additions and subtractions. If anything else is found,
|
||||
** set D->TooComplex to true. The function will initialize D.
|
||||
*/
|
||||
|
||||
ExprNode* LiteralExpr (long Val, ObjData* O);
|
||||
/* Return an expression tree that encodes the given literal value */
|
||||
|
||||
@@ -124,8 +124,8 @@ ExtSym* NewExtSym (ExtSymTab* Tab, unsigned Name)
|
||||
|
||||
static void FreeExtSym (ExtSym* E)
|
||||
/* Free an external symbol structure. Will not unlink the entry, so internal
|
||||
* use only.
|
||||
*/
|
||||
** use only.
|
||||
*/
|
||||
{
|
||||
xfree (E);
|
||||
}
|
||||
@@ -172,8 +172,8 @@ void FreeExtSymTab (ExtSymTab* Tab)
|
||||
|
||||
ExtSym* GetExtSym (const ExtSymTab* Tab, unsigned Name)
|
||||
/* Return the entry for the external symbol with the given name. Return NULL
|
||||
* if there is no such symbol.
|
||||
*/
|
||||
** if there is no such symbol.
|
||||
*/
|
||||
{
|
||||
/* Hash the name */
|
||||
unsigned Hash = (Name & HASHTAB_MASK);
|
||||
@@ -204,8 +204,8 @@ unsigned ExtSymCount (const ExtSymTab* Tab)
|
||||
|
||||
const ExtSym* ExtSymList (const ExtSymTab* Tab)
|
||||
/* Return the start of the symbol list sorted by symbol number. Call
|
||||
* ExtSymNext for the next symbol.
|
||||
*/
|
||||
** ExtSymNext for the next symbol.
|
||||
*/
|
||||
{
|
||||
return Tab->Root;
|
||||
}
|
||||
|
||||
@@ -69,16 +69,16 @@ void FreeExtSymTab (ExtSymTab* Tab);
|
||||
|
||||
ExtSym* GetExtSym (const ExtSymTab* Tab, unsigned Name);
|
||||
/* Return the entry for the external symbol with the given name. Return NULL
|
||||
* if there is no such symbol.
|
||||
*/
|
||||
** if there is no such symbol.
|
||||
*/
|
||||
|
||||
unsigned ExtSymCount (const ExtSymTab* Tab);
|
||||
/* Return the number of symbols in the table */
|
||||
|
||||
const ExtSym* ExtSymList (const ExtSymTab* Tab);
|
||||
/* Return the start of the symbol list sorted by symbol number. Call
|
||||
* ExtSymNext for the next symbol.
|
||||
*/
|
||||
** ExtSymNext for the next symbol.
|
||||
*/
|
||||
|
||||
unsigned ExtSymNum (const ExtSym* E);
|
||||
/* Return the number of an external symbol */
|
||||
|
||||
@@ -64,10 +64,10 @@ static Collection FileInfos = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
static int FindFileInfo (unsigned Name, unsigned* Index)
|
||||
/* Find the FileInfo for a given file name. The function returns true if the
|
||||
* name was found. In this case, Index contains the index of the first item
|
||||
* that matches. If the item wasn't found, the function returns false and
|
||||
* Index contains the insert position for FileName.
|
||||
*/
|
||||
** name was found. In this case, Index contains the index of the first item
|
||||
** that matches. If the item wasn't found, the function returns false and
|
||||
** Index contains the insert position for FileName.
|
||||
*/
|
||||
{
|
||||
/* Do a binary search */
|
||||
int Lo = 0;
|
||||
@@ -87,8 +87,8 @@ static int FindFileInfo (unsigned Name, unsigned* Index)
|
||||
} else {
|
||||
Hi = Cur - 1;
|
||||
/* Since we may have duplicates, repeat the search until we've
|
||||
* the first item that has a match.
|
||||
*/
|
||||
** the first item that has a match.
|
||||
*/
|
||||
if (CurItem->Name == Name) {
|
||||
Found = 1;
|
||||
}
|
||||
@@ -148,10 +148,10 @@ FileInfo* ReadFileInfo (FILE* F, ObjData* O)
|
||||
if (FindFileInfo (Name, &Index)) {
|
||||
|
||||
/* We have at least one such entry. Try all of them and, if size and
|
||||
* modification time matches, return the first match. When the loop
|
||||
* is terminated without finding an entry, Index points one behind
|
||||
* the last entry with the name, which is the perfect insert position.
|
||||
*/
|
||||
** modification time matches, return the first match. When the loop
|
||||
** is terminated without finding an entry, Index points one behind
|
||||
** the last entry with the name, which is the perfect insert position.
|
||||
*/
|
||||
FI = CollAt (&FileInfos, Index);
|
||||
while (1) {
|
||||
|
||||
@@ -183,8 +183,8 @@ FileInfo* ReadFileInfo (FILE* F, ObjData* O)
|
||||
CollAppend (&FI->Modules, O);
|
||||
|
||||
/* Insert the file info in our global list. Index points to the insert
|
||||
* position.
|
||||
*/
|
||||
** position.
|
||||
*/
|
||||
CollInsert (&FileInfos, FI, Index);
|
||||
|
||||
/* Return the new struct */
|
||||
|
||||
@@ -147,10 +147,10 @@ void WriteVar (FILE* F, unsigned long V)
|
||||
/* Write a variable sized value to the file in special encoding */
|
||||
{
|
||||
/* We will write the value to the file in 7 bit chunks. If the 8th bit
|
||||
* is clear, we're done, if it is set, another chunk follows. This will
|
||||
* allow us to encode smaller values with less bytes, at the expense of
|
||||
* needing 5 bytes if a 32 bit value is written to file.
|
||||
*/
|
||||
** is clear, we're done, if it is set, another chunk follows. This will
|
||||
** allow us to encode smaller values with less bytes, at the expense of
|
||||
** needing 5 bytes if a 32 bit value is written to file.
|
||||
*/
|
||||
do {
|
||||
unsigned char C = (V & 0x7F);
|
||||
V >>= 7;
|
||||
@@ -258,8 +258,8 @@ unsigned long ReadVar (FILE* F)
|
||||
/* Read a variable size value from the file */
|
||||
{
|
||||
/* The value was written to the file in 7 bit chunks LSB first. If there
|
||||
* are more bytes, bit 8 is set, otherwise it is clear.
|
||||
*/
|
||||
** are more bytes, bit 8 is set, otherwise it is clear.
|
||||
*/
|
||||
unsigned char C;
|
||||
unsigned long V = 0;
|
||||
unsigned Shift = 0;
|
||||
@@ -280,8 +280,8 @@ unsigned long ReadVar (FILE* F)
|
||||
|
||||
unsigned ReadStr (FILE* F)
|
||||
/* Read a string from the file, place it into the global string pool, and
|
||||
* return its string id.
|
||||
*/
|
||||
** return its string id.
|
||||
*/
|
||||
{
|
||||
unsigned Id;
|
||||
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||
/* R<EFBFBD>merstrasse 52 */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
@@ -104,8 +104,8 @@ unsigned long ReadVar (FILE* F);
|
||||
|
||||
unsigned ReadStr (FILE* F);
|
||||
/* Read a string from the file, place it into the global string pool, and
|
||||
* return its string id.
|
||||
*/
|
||||
** return its string id.
|
||||
*/
|
||||
|
||||
FilePos* ReadFilePos (FILE* F, FilePos* Pos);
|
||||
/* Read a file position from the file */
|
||||
|
||||
@@ -57,8 +57,8 @@ Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S)
|
||||
Fragment* F;
|
||||
|
||||
/* Calculate the size of the memory block. LitBuf is only needed if the
|
||||
* fragment contains literal data.
|
||||
*/
|
||||
** fragment contains literal data.
|
||||
*/
|
||||
unsigned FragSize = sizeof (Fragment) - 1;
|
||||
if (Type == FRAG_LITERAL) {
|
||||
FragSize += Size;
|
||||
|
||||
@@ -232,8 +232,8 @@ static ObjData* ReadIndexEntry (Library* L)
|
||||
|
||||
static void ReadBasicData (Library* L, ObjData* O)
|
||||
/* Read basic data for an object file that is necessary to resolve external
|
||||
* references.
|
||||
*/
|
||||
** references.
|
||||
*/
|
||||
{
|
||||
/* Seek to the start of the object file and read the header */
|
||||
LibSeek (L, O->Start);
|
||||
@@ -275,8 +275,8 @@ static void LibReadIndex (Library* L)
|
||||
}
|
||||
|
||||
/* Walk over the index and read basic data for all object files in the
|
||||
* library.
|
||||
*/
|
||||
** library.
|
||||
*/
|
||||
for (I = 0; I < CollCount (&L->Modules); ++I) {
|
||||
ReadBasicData (L, CollAtUnchecked (&L->Modules, I));
|
||||
}
|
||||
@@ -292,8 +292,8 @@ static void LibReadIndex (Library* L)
|
||||
|
||||
static void LibCheckExports (ObjData* O)
|
||||
/* Check if the exports from this file can satisfy any import requests. If so,
|
||||
* insert the imports and exports from this file and mark the file as added.
|
||||
*/
|
||||
** insert the imports and exports from this file and mark the file as added.
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
@@ -336,8 +336,8 @@ static void LibResolve (void)
|
||||
unsigned Additions;
|
||||
|
||||
/* Walk repeatedly over all open libraries until there's nothing more
|
||||
* to add.
|
||||
*/
|
||||
** to add.
|
||||
*/
|
||||
do {
|
||||
|
||||
Additions = 0;
|
||||
@@ -349,9 +349,9 @@ static void LibResolve (void)
|
||||
Library* L = CollAt (&OpenLibs, I);
|
||||
|
||||
/* Walk through all modules in this library and check for each
|
||||
* module if there are unresolved externals in existing modules
|
||||
* that may be resolved by adding the module.
|
||||
*/
|
||||
** module if there are unresolved externals in existing modules
|
||||
** that may be resolved by adding the module.
|
||||
*/
|
||||
for (J = 0; J < CollCount (&L->Modules); ++J) {
|
||||
|
||||
/* Get the next module */
|
||||
@@ -371,17 +371,17 @@ static void LibResolve (void)
|
||||
} while (Additions > 0);
|
||||
|
||||
/* We do know now which modules must be added, so we can load the data
|
||||
* for these modues into memory. Since we're walking over all modules
|
||||
* anyway, we will also remove data for unneeded modules.
|
||||
*/
|
||||
** for these modues into memory. Since we're walking over all modules
|
||||
** anyway, we will also remove data for unneeded modules.
|
||||
*/
|
||||
for (I = 0; I < CollCount (&OpenLibs); ++I) {
|
||||
|
||||
/* Get the next library */
|
||||
Library* L = CollAt (&OpenLibs, I);
|
||||
|
||||
/* Walk over all modules in this library and add the files list and
|
||||
* sections for all referenced modules.
|
||||
*/
|
||||
** sections for all referenced modules.
|
||||
*/
|
||||
J = 0;
|
||||
while (J < CollCount (&L->Modules)) {
|
||||
|
||||
@@ -398,22 +398,22 @@ static void LibResolve (void)
|
||||
ObjReadAssertions (L->F, O->Start + O->Header.AssertOffs, O);
|
||||
|
||||
/* Seek to the start of the segment list and read the segments.
|
||||
* This must be late, since the data here may reference other
|
||||
* stuff.
|
||||
*/
|
||||
** This must be late, since the data here may reference other
|
||||
** stuff.
|
||||
*/
|
||||
ObjReadSections (L->F, O->Start + O->Header.SegOffs, O);
|
||||
|
||||
/* Read the scope table from the object file. Scopes reference
|
||||
* segments, so we must read them after the sections.
|
||||
*/
|
||||
** segments, so we must read them after the sections.
|
||||
*/
|
||||
ObjReadScopes (L->F, O->Start + O->Header.ScopeOffs, O);
|
||||
|
||||
/* Read the spans */
|
||||
ObjReadSpans (L->F, O->Start + O->Header.SpanOffs, O);
|
||||
|
||||
/* All references to strings are now resolved, so we can delete
|
||||
* the module string pool.
|
||||
*/
|
||||
** the module string pool.
|
||||
*/
|
||||
FreeObjStrings (O);
|
||||
|
||||
/* Insert the object into the list of all used object files */
|
||||
@@ -432,8 +432,8 @@ static void LibResolve (void)
|
||||
}
|
||||
|
||||
/* If we have referenced modules in this library, assign it an id
|
||||
* (which is the index in the library collection) and keep it.
|
||||
*/
|
||||
** (which is the index in the library collection) and keep it.
|
||||
*/
|
||||
if (CollCount (&L->Modules) > 0) {
|
||||
CloseLibrary (L);
|
||||
L->Id = CollCount (&LibraryList);
|
||||
@@ -453,16 +453,16 @@ static void LibResolve (void)
|
||||
|
||||
void LibAdd (FILE* F, const char* Name)
|
||||
/* Add files from the library to the list if there are references that could
|
||||
* be satisfied.
|
||||
*/
|
||||
** be satisfied.
|
||||
*/
|
||||
{
|
||||
/* Add the library to the list of open libraries */
|
||||
LibOpen (F, Name);
|
||||
|
||||
/* If there is no library group open, just resolve all open symbols and
|
||||
* close the library. Otherwise we will do nothing because resolving will
|
||||
* be done when the group is closed.
|
||||
*/
|
||||
** close the library. Otherwise we will do nothing because resolving will
|
||||
** be done when the group is closed.
|
||||
*/
|
||||
if (!Grouping) {
|
||||
LibResolve ();
|
||||
}
|
||||
@@ -472,9 +472,9 @@ void LibAdd (FILE* F, const char* Name)
|
||||
|
||||
void LibStartGroup (void)
|
||||
/* Start a library group. Objects within a library group may reference each
|
||||
* other, and libraries are searched repeatedly until all references are
|
||||
* satisfied.
|
||||
*/
|
||||
** other, and libraries are searched repeatedly until all references are
|
||||
** satisfied.
|
||||
*/
|
||||
{
|
||||
/* We cannot already have a group open */
|
||||
if (Grouping) {
|
||||
@@ -489,9 +489,9 @@ void LibStartGroup (void)
|
||||
|
||||
void LibEndGroup (void)
|
||||
/* End a library group and resolve all open references. Objects within a
|
||||
* library group may reference each other, and libraries are searched
|
||||
* repeatedly until all references are satisfied.
|
||||
*/
|
||||
** library group may reference each other, and libraries are searched
|
||||
** repeatedly until all references are satisfied.
|
||||
*/
|
||||
{
|
||||
/* We must have a library group open */
|
||||
if (!Grouping) {
|
||||
|
||||
@@ -57,20 +57,20 @@ struct Library;
|
||||
|
||||
void LibAdd (FILE* F, const char* Name);
|
||||
/* Add files from the library to the list if there are references that could
|
||||
* be satisfied.
|
||||
*/
|
||||
** be satisfied.
|
||||
*/
|
||||
|
||||
void LibStartGroup (void);
|
||||
/* Start a library group. Objects within a library group may reference each
|
||||
* other, and libraries are searched repeatedly until all references are
|
||||
* satisfied.
|
||||
*/
|
||||
** other, and libraries are searched repeatedly until all references are
|
||||
** satisfied.
|
||||
*/
|
||||
|
||||
void LibEndGroup (void);
|
||||
/* End a library group and resolve all open references. Objects within a
|
||||
* library group may reference each other, and libraries are searched
|
||||
* repeatedly until all references are satisfied.
|
||||
*/
|
||||
** library group may reference each other, and libraries are searched
|
||||
** repeatedly until all references are satisfied.
|
||||
*/
|
||||
|
||||
void LibCheckGroup (void);
|
||||
/* Check if there are open library groups */
|
||||
|
||||
@@ -143,8 +143,8 @@ LineInfo* ReadLineInfo (FILE* F, ObjData* O)
|
||||
|
||||
void ReadLineInfoList (FILE* F, ObjData* O, Collection* LineInfos)
|
||||
/* Read a list of line infos stored as a list of indices in the object file,
|
||||
* make real line infos from them and place them into the passed collection.
|
||||
*/
|
||||
** make real line infos from them and place them into the passed collection.
|
||||
*/
|
||||
{
|
||||
/* Read the number of line info indices that follow */
|
||||
unsigned LineInfoCount = ReadVar (F);
|
||||
@@ -159,8 +159,8 @@ void ReadLineInfoList (FILE* F, ObjData* O, Collection* LineInfos)
|
||||
unsigned LineInfoIndex = ReadVar (F);
|
||||
|
||||
/* The line info index was written by the assembler and must
|
||||
* therefore be part of the line infos read from the object file.
|
||||
*/
|
||||
** therefore be part of the line infos read from the object file.
|
||||
*/
|
||||
if (LineInfoIndex >= CollCount (&O->LineInfos)) {
|
||||
Internal ("Invalid line info index %u in module `%s' - max is %u",
|
||||
LineInfoIndex,
|
||||
@@ -177,8 +177,8 @@ void ReadLineInfoList (FILE* F, ObjData* O, Collection* LineInfos)
|
||||
|
||||
const LineInfo* GetAsmLineInfo (const Collection* LineInfos)
|
||||
/* Find a line info of type LI_TYPE_ASM and count zero in the given collection
|
||||
* and return it. Return NULL if no such line info was found.
|
||||
*/
|
||||
** and return it. Return NULL if no such line info was found.
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
|
||||
@@ -68,9 +68,9 @@ struct Segment;
|
||||
|
||||
|
||||
/* Structure holding line information. The Pos.Name field is always the
|
||||
* global string id of the file name. If the line info was read from the
|
||||
* object file, the File pointer is valid, otherwise it is NULL.
|
||||
*/
|
||||
** global string id of the file name. If the line info was read from the
|
||||
** object file, the File pointer is valid, otherwise it is NULL.
|
||||
*/
|
||||
typedef struct LineInfo LineInfo;
|
||||
struct LineInfo {
|
||||
unsigned Id; /* Line info id */
|
||||
@@ -102,13 +102,13 @@ LineInfo* DupLineInfo (const LineInfo* LI);
|
||||
|
||||
void ReadLineInfoList (FILE* F, struct ObjData* O, Collection* LineInfos);
|
||||
/* Read a list of line infos stored as a list of indices in the object file,
|
||||
* make real line infos from them and place them into the passed collection.
|
||||
*/
|
||||
** make real line infos from them and place them into the passed collection.
|
||||
*/
|
||||
|
||||
const LineInfo* GetAsmLineInfo (const Collection* LineInfos);
|
||||
/* Find a line info of type LI_TYPE_ASM and count zero in the given collection
|
||||
* and return it. Return NULL if no such line info was found.
|
||||
*/
|
||||
** and return it. Return NULL if no such line info was found.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE const FilePos* GetSourcePos (const LineInfo* LI)
|
||||
|
||||
@@ -152,8 +152,8 @@ static void Usage (void)
|
||||
|
||||
static unsigned long CvtNumber (const char* Arg, const char* Number)
|
||||
/* Convert a number from a string. Allow '$' and '0x' prefixes for hex
|
||||
* numbers.
|
||||
*/
|
||||
** numbers.
|
||||
*/
|
||||
{
|
||||
unsigned long Val;
|
||||
int Converted;
|
||||
@@ -227,11 +227,11 @@ static void LinkFile (const char* Name, FILETYPE Type)
|
||||
Magic = Read32 (F);
|
||||
|
||||
/* Check the magic for known file types. The handling is somewhat weird
|
||||
* since we may have given a file with a ".lib" extension, which was
|
||||
* searched and found in a directory for library files, but we now find
|
||||
* out (by looking at the magic) that it's indeed an object file. We just
|
||||
* ignore the problem and hope no one will notice...
|
||||
*/
|
||||
** since we may have given a file with a ".lib" extension, which was
|
||||
** searched and found in a directory for library files, but we now find
|
||||
** out (by looking at the magic) that it's indeed an object file. We just
|
||||
** ignore the problem and hope no one will notice...
|
||||
*/
|
||||
switch (Magic) {
|
||||
|
||||
case OBJ_MAGIC:
|
||||
@@ -365,8 +365,8 @@ static void OptForceImport (const char* Opt attribute ((unused)), const char* Ar
|
||||
if (ColPos == 0) {
|
||||
|
||||
/* Use default address size (which for now is always absolute
|
||||
* addressing)
|
||||
*/
|
||||
** addressing)
|
||||
*/
|
||||
InsertImport (GenImport (GetStringId (Arg), ADDR_SIZE_ABS));
|
||||
|
||||
} else {
|
||||
@@ -800,9 +800,9 @@ int main (int argc, char* argv [])
|
||||
ConDesCreate ();
|
||||
|
||||
/* Process data from the config file. Assign start addresses for the
|
||||
* segments, define linker symbols. The function will return the number
|
||||
* of memory area overflows (zero on success).
|
||||
*/
|
||||
** segments, define linker symbols. The function will return the number
|
||||
** of memory area overflows (zero on success).
|
||||
*/
|
||||
MemoryAreaOverflows = CfgProcess ();
|
||||
|
||||
/* Check module assertions */
|
||||
@@ -812,9 +812,9 @@ int main (int argc, char* argv [])
|
||||
CheckExports ();
|
||||
|
||||
/* If we had a memory area overflow before, we cannot generate the output
|
||||
* file. However, we will generate a short map file if requested, since
|
||||
* this will help the user to rearrange segments and fix the overflow.
|
||||
*/
|
||||
** file. However, we will generate a short map file if requested, since
|
||||
** this will help the user to rearrange segments and fix the overflow.
|
||||
*/
|
||||
if (MemoryAreaOverflows) {
|
||||
if (MapFileName) {
|
||||
CreateMapFile (SHORT_MAPFILE);
|
||||
|
||||
@@ -59,8 +59,8 @@
|
||||
|
||||
void CreateMapFile (int ShortMap)
|
||||
/* Create a map file. If ShortMap is true, only the segment lists are
|
||||
* generated, not the import/export lists.
|
||||
*/
|
||||
** generated, not the import/export lists.
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
@@ -90,8 +90,8 @@ void CreateMapFile (int ShortMap)
|
||||
for (J = 0; J < CollCount (&O->Sections); ++J) {
|
||||
const Section* S = CollConstAt (&O->Sections, J);
|
||||
/* Don't include zero sized sections if not explicitly
|
||||
* requested
|
||||
*/
|
||||
** requested
|
||||
*/
|
||||
if (VerboseMap || S->Size > 0) {
|
||||
fprintf (F,
|
||||
" %-17s Offs=%06lX Size=%06lX "
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2005 Ullrich von Bassewitz */
|
||||
/* R<EFBFBD>merstrasse 52 */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
@@ -60,8 +60,8 @@ enum {
|
||||
|
||||
void CreateMapFile (int ShortMap);
|
||||
/* Create a map file. If ShortMap is true, only the segment lists are
|
||||
* generated, not the import/export lists.
|
||||
*/
|
||||
** generated, not the import/export lists.
|
||||
*/
|
||||
|
||||
void CreateLabelFile (void);
|
||||
/* Create a label file */
|
||||
|
||||
104
src/ld65/o65.c
104
src/ld65/o65.c
@@ -94,8 +94,8 @@
|
||||
#define MF_ALIGN_MASK 0x0003 /* Mask to extract alignment */
|
||||
|
||||
/* The four o65 segment types. Note: These values are identical to the values
|
||||
* needed for the segmentID in the o65 spec.
|
||||
*/
|
||||
** needed for the segmentID in the o65 spec.
|
||||
*/
|
||||
#define O65SEG_UNDEF 0x00
|
||||
#define O65SEG_ABS 0x01
|
||||
#define O65SEG_TEXT 0x02
|
||||
@@ -222,11 +222,11 @@ static unsigned O65SegType (const SegDesc* S)
|
||||
/* Map our own segment types into something o65 compatible */
|
||||
{
|
||||
/* Check the segment type. Readonly segments are assign to the o65
|
||||
* text segment, writeable segments that contain data are assigned
|
||||
* to data, bss and zp segments are handled respectively.
|
||||
* Beware: Zeropage segments have the SF_BSS flag set, so be sure
|
||||
* to check SF_ZP first.
|
||||
*/
|
||||
** text segment, writeable segments that contain data are assigned
|
||||
** to data, bss and zp segments are handled respectively.
|
||||
** Beware: Zeropage segments have the SF_BSS flag set, so be sure
|
||||
** to check SF_ZP first.
|
||||
*/
|
||||
if (S->Flags & SF_RO) {
|
||||
return O65SEG_TEXT;
|
||||
} else if (S->Flags & SF_ZP) {
|
||||
@@ -242,8 +242,8 @@ static unsigned O65SegType (const SegDesc* S)
|
||||
|
||||
static void CvtMemoryToSegment (ExprDesc* ED)
|
||||
/* Convert a memory area into a segment by searching the list of run segments
|
||||
* in this memory area and assigning the nearest one.
|
||||
*/
|
||||
** in this memory area and assigning the nearest one.
|
||||
*/
|
||||
{
|
||||
/* Get the memory area from the expression */
|
||||
MemoryArea* M = ED->MemRef;
|
||||
@@ -291,8 +291,8 @@ static void CvtMemoryToSegment (ExprDesc* ED)
|
||||
|
||||
static const SegDesc* FindSeg (SegDesc** const List, unsigned Count, const Segment* S)
|
||||
/* Search for a segment in the given list of segment descriptors and return
|
||||
* the descriptor for a segment if we found it, and NULL if not.
|
||||
*/
|
||||
** the descriptor for a segment if we found it, and NULL if not.
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
@@ -341,9 +341,9 @@ static const SegDesc* O65FindSeg (const O65Desc* D, const Segment* S)
|
||||
|
||||
static void O65ParseExpr (ExprNode* Expr, ExprDesc* D, int Sign)
|
||||
/* Extract and evaluate all constant factors in an subtree that has only
|
||||
* additions and subtractions. If anything other than additions and
|
||||
* subtractions are found, D->TooComplex is set to true.
|
||||
*/
|
||||
** additions and subtractions. If anything other than additions and
|
||||
** subtractions are found, D->TooComplex is set to true.
|
||||
*/
|
||||
{
|
||||
Export* E;
|
||||
|
||||
@@ -357,9 +357,9 @@ static void O65ParseExpr (ExprNode* Expr, ExprDesc* D, int Sign)
|
||||
/* Get the referenced Export */
|
||||
E = GetExprExport (Expr);
|
||||
/* If this export has a mark set, we've already encountered it.
|
||||
* This means that the export is used to define it's own value,
|
||||
* which in turn means, that we have a circular reference.
|
||||
*/
|
||||
** This means that the export is used to define it's own value,
|
||||
** which in turn means, that we have a circular reference.
|
||||
*/
|
||||
if (ExportHasMark (E)) {
|
||||
CircularRefError (E);
|
||||
} else if (E->Expr == 0) {
|
||||
@@ -412,8 +412,8 @@ static void O65ParseExpr (ExprNode* Expr, ExprDesc* D, int Sign)
|
||||
/* Remember the memory area reference */
|
||||
D->MemRef = Expr->V.Mem;
|
||||
/* Add the start address of the memory area to the constant
|
||||
* value
|
||||
*/
|
||||
** value
|
||||
*/
|
||||
D->Val += (Sign * D->MemRef->Start);
|
||||
}
|
||||
break;
|
||||
@@ -593,9 +593,9 @@ static void O65WriteHeader (O65Desc* D)
|
||||
static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
|
||||
unsigned long Offs, void* Data)
|
||||
/* Called from SegWrite for an expression. Evaluate the expression, check the
|
||||
* range and write the expression value to the file, update the relocation
|
||||
* table.
|
||||
*/
|
||||
** range and write the expression value to the file, update the relocation
|
||||
** table.
|
||||
*/
|
||||
{
|
||||
long Diff;
|
||||
unsigned RefCount;
|
||||
@@ -614,9 +614,9 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
|
||||
}
|
||||
|
||||
/* We have a relocatable expression that needs a relocation table entry.
|
||||
* Calculate the number of bytes between this entry and the last one, and
|
||||
* setup all necessary intermediate bytes in the relocation table.
|
||||
*/
|
||||
** Calculate the number of bytes between this entry and the last one, and
|
||||
** setup all necessary intermediate bytes in the relocation table.
|
||||
*/
|
||||
Offs += D->SegSize; /* Calulate full offset */
|
||||
Diff = ((long) Offs) - D->LastOffs;
|
||||
while (Diff > 0xFE) {
|
||||
@@ -649,9 +649,9 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
|
||||
}
|
||||
|
||||
/* If we have a memory area reference, we need to convert it into a
|
||||
* segment reference. If we cannot do that, we cannot handle the
|
||||
* expression.
|
||||
*/
|
||||
** segment reference. If we cannot do that, we cannot handle the
|
||||
** expression.
|
||||
*/
|
||||
if (ED.MemRef) {
|
||||
CvtMemoryToSegment (&ED);
|
||||
if (ED.SegRef == 0) {
|
||||
@@ -682,8 +682,8 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
|
||||
WriteVal (D->F, BinVal, Size);
|
||||
|
||||
/* Determine the actual type of relocation entry needed from the
|
||||
* information gathered about the expression.
|
||||
*/
|
||||
** information gathered about the expression.
|
||||
*/
|
||||
if (E->Op == EXPR_BYTE0) {
|
||||
RelocType = O65RELOC_LOW;
|
||||
} else if (E->Op == EXPR_BYTE1) {
|
||||
@@ -730,8 +730,8 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
|
||||
Seg = O65FindSeg (D, ED.SegRef);
|
||||
if (Seg == 0) {
|
||||
/* For some reason, we didn't find this segment in the list of
|
||||
* segments written to the o65 file.
|
||||
*/
|
||||
** segments written to the o65 file.
|
||||
*/
|
||||
return SEG_EXPR_INVALID;
|
||||
}
|
||||
RelocType |= O65SegType (Seg);
|
||||
@@ -844,8 +844,8 @@ static void O65WriteDataSeg (O65Desc* D)
|
||||
|
||||
static void O65WriteBssSeg (O65Desc* D)
|
||||
/* "Write" the bss segments to the o65 output file. This will only update
|
||||
* the relevant header fields.
|
||||
*/
|
||||
** the relevant header fields.
|
||||
*/
|
||||
{
|
||||
/* Initialize variables */
|
||||
D->CurReloc = 0;
|
||||
@@ -861,8 +861,8 @@ static void O65WriteBssSeg (O65Desc* D)
|
||||
|
||||
static void O65WriteZPSeg (O65Desc* D)
|
||||
/* "Write" the zeropage segments to the o65 output file. This will only update
|
||||
* the relevant header fields.
|
||||
*/
|
||||
** the relevant header fields.
|
||||
*/
|
||||
{
|
||||
/* Initialize variables */
|
||||
D->CurReloc = 0;
|
||||
@@ -935,9 +935,9 @@ static void O65WriteExports (O65Desc* D)
|
||||
const char* Name = GetString (NameIdx);
|
||||
|
||||
/* Get the export for this symbol. We've checked before that this
|
||||
* export does really exist, so if it is unresolved, or if we don't
|
||||
* find it, there is an error in the linker code.
|
||||
*/
|
||||
** export does really exist, so if it is unresolved, or if we don't
|
||||
** find it, there is an error in the linker code.
|
||||
*/
|
||||
Export* E = FindExport (NameIdx);
|
||||
if (E == 0 || IsUnresolvedExport (E)) {
|
||||
Internal ("Unresolved export `%s' found in O65WriteExports", Name);
|
||||
@@ -950,8 +950,8 @@ static void O65WriteExports (O65Desc* D)
|
||||
O65ParseExpr (Expr, InitExprDesc (&ED, D), 1);
|
||||
|
||||
/* We cannot handle expressions with imported symbols, or expressions
|
||||
* with more than one segment reference here
|
||||
*/
|
||||
** with more than one segment reference here
|
||||
*/
|
||||
if (ED.ExtRef != 0 || (ED.SegRef != 0 && ED.SecRef != 0)) {
|
||||
ED.TooComplex = 1;
|
||||
}
|
||||
@@ -975,8 +975,8 @@ static void O65WriteExports (O65Desc* D)
|
||||
Seg = O65FindSeg (D, ED.SegRef);
|
||||
if (Seg == 0) {
|
||||
/* For some reason, we didn't find this segment in the list of
|
||||
* segments written to the o65 file.
|
||||
*/
|
||||
** segments written to the o65 file.
|
||||
*/
|
||||
Error ("Segment for symbol `%s' is undefined", Name);
|
||||
}
|
||||
SegmentID = O65SegType (Seg);
|
||||
@@ -1203,8 +1203,8 @@ void O65SetExport (O65Desc* D, unsigned Ident)
|
||||
/* Set an exported identifier */
|
||||
{
|
||||
/* Get the export for this symbol and check if it does exist and is
|
||||
* a resolved symbol.
|
||||
*/
|
||||
** a resolved symbol.
|
||||
*/
|
||||
Export* E = FindExport (Ident);
|
||||
if (E == 0 || IsUnresolvedExport (E)) {
|
||||
Error ("Unresolved export: `%s'", GetString (Ident));
|
||||
@@ -1328,9 +1328,9 @@ static void O65UpdateHeader (O65Desc* D)
|
||||
/* Update mode word, currently only the "simple" bit */
|
||||
{
|
||||
/* If we have byte wise relocation and an alignment of 1, and text
|
||||
* and data are adjacent, we can set the "simple addressing" bit
|
||||
* in the header.
|
||||
*/
|
||||
** and data are adjacent, we can set the "simple addressing" bit
|
||||
** in the header.
|
||||
*/
|
||||
if ((D->Header.Mode & MF_RELOC_MASK) == MF_RELOC_BYTE &&
|
||||
(D->Header.Mode & MF_ALIGN_MASK) == MF_ALIGN_1 &&
|
||||
D->Header.TextBase + D->Header.TextSize == D->Header.DataBase &&
|
||||
@@ -1352,8 +1352,8 @@ void O65WriteTarget (O65Desc* D, File* F)
|
||||
D->Filename = GetString (F->Name);
|
||||
|
||||
/* Check for unresolved symbols. The function O65Unresolved is called
|
||||
* if we get an unresolved symbol.
|
||||
*/
|
||||
** if we get an unresolved symbol.
|
||||
*/
|
||||
D->Undef = 0; /* Reset the counter */
|
||||
CheckUnresolvedImports (O65Unresolved, D);
|
||||
if (D->Undef > 0) {
|
||||
@@ -1377,8 +1377,8 @@ void O65WriteTarget (O65Desc* D, File* F)
|
||||
Print (stdout, 1, "Opened `%s'...\n", D->Filename);
|
||||
|
||||
/* Define some more options: A timestamp, the linker version and the
|
||||
* filename
|
||||
*/
|
||||
** filename
|
||||
*/
|
||||
T = time (0);
|
||||
strcpy (OptBuf, ctime (&T));
|
||||
OptLen = strlen (OptBuf);
|
||||
|
||||
@@ -104,9 +104,9 @@ ObjData* NewObjData (void)
|
||||
|
||||
void FreeObjData (ObjData* O)
|
||||
/* Free an ObjData object. NOTE: This function works only for unused object
|
||||
* data, that is, ObjData objects that aren't used because they aren't
|
||||
* referenced.
|
||||
*/
|
||||
** data, that is, ObjData objects that aren't used because they aren't
|
||||
** referenced.
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
@@ -145,8 +145,8 @@ void FreeObjData (ObjData* O)
|
||||
|
||||
void FreeObjStrings (ObjData* O)
|
||||
/* Free the module string data. Used once the object file is loaded completely
|
||||
* when all strings are converted to global strings.
|
||||
*/
|
||||
** when all strings are converted to global strings.
|
||||
*/
|
||||
{
|
||||
xfree (O->Strings);
|
||||
O->Strings = 0;
|
||||
@@ -164,8 +164,8 @@ void InsertObjData (ObjData* O)
|
||||
|
||||
void InsertObjGlobals (ObjData* O)
|
||||
/* Insert imports and exports from the object file into the global import and
|
||||
* export lists.
|
||||
*/
|
||||
** export lists.
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
@@ -194,8 +194,8 @@ unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
|
||||
|
||||
const char* GetObjFileName (const ObjData* O)
|
||||
/* Get the name of the object file. Return "[linker generated]" if the object
|
||||
* file is NULL.
|
||||
*/
|
||||
** file is NULL.
|
||||
*/
|
||||
{
|
||||
return O? GetString (O->Name) : "[linker generated]";
|
||||
}
|
||||
|
||||
@@ -111,30 +111,30 @@ ObjData* NewObjData (void);
|
||||
|
||||
void FreeObjData (ObjData* O);
|
||||
/* Free an ObjData object. NOTE: This function works only for unused object
|
||||
* data, that is, ObjData objects that aren't used because they aren't
|
||||
* referenced.
|
||||
*/
|
||||
** data, that is, ObjData objects that aren't used because they aren't
|
||||
** referenced.
|
||||
*/
|
||||
|
||||
void FreeObjStrings (ObjData* O);
|
||||
/* Free the module string data. Used once the object file is loaded completely
|
||||
* when all strings are converted to global strings.
|
||||
*/
|
||||
** when all strings are converted to global strings.
|
||||
*/
|
||||
|
||||
void InsertObjData (ObjData* O);
|
||||
/* Insert the ObjData object into the collection of used ObjData objects. */
|
||||
|
||||
void InsertObjGlobals (ObjData* O);
|
||||
/* Insert imports and exports from the object file into the global import and
|
||||
* export lists.
|
||||
*/
|
||||
** export lists.
|
||||
*/
|
||||
|
||||
unsigned MakeGlobalStringId (const ObjData* O, unsigned Index);
|
||||
/* Convert a local string id into a global one and return it. */
|
||||
|
||||
const char* GetObjFileName (const ObjData* O);
|
||||
/* Get the name of the object file. Return "[linker generated]" if the object
|
||||
* file is NULL.
|
||||
*/
|
||||
** file is NULL.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ObjHasFiles (const ObjData* O)
|
||||
|
||||
@@ -342,14 +342,14 @@ void ObjAdd (FILE* Obj, const char* Name)
|
||||
ObjReadAssertions (Obj, O->Header.AssertOffs, O);
|
||||
|
||||
/* Read the segment list from the object file. This must be late, since
|
||||
* the expressions stored in the code may reference segments or imported
|
||||
* symbols.
|
||||
*/
|
||||
** the expressions stored in the code may reference segments or imported
|
||||
** symbols.
|
||||
*/
|
||||
ObjReadSections (Obj, O->Header.SegOffs, O);
|
||||
|
||||
/* Read the scope table from the object file. Scopes reference segments, so
|
||||
* we must read them after the sections.
|
||||
*/
|
||||
** we must read them after the sections.
|
||||
*/
|
||||
ObjReadScopes (Obj, O->Header.ScopeOffs, O);
|
||||
|
||||
/* Read the spans from the object file */
|
||||
@@ -368,7 +368,7 @@ void ObjAdd (FILE* Obj, const char* Name)
|
||||
InsertObjData (O);
|
||||
|
||||
/* All references to strings are now resolved, so we can delete the module
|
||||
* string pool.
|
||||
*/
|
||||
** string pool.
|
||||
*/
|
||||
FreeObjStrings (O);
|
||||
}
|
||||
|
||||
@@ -166,12 +166,12 @@ extern StrBuf CfgSVal;
|
||||
extern unsigned long CfgIVal;
|
||||
|
||||
/* Error location. PLEASE NOTE: I'm abusing the FilePos structure to some
|
||||
* degree. It is used mostly to hold a file position, where the Name member
|
||||
* is an index into the source file table of an object file. As used in config
|
||||
* file processing, the Name member is a string pool index instead. This is
|
||||
* distinguished by the object file pointer being NULL or not in the structs
|
||||
* where this is relevant.
|
||||
*/
|
||||
** degree. It is used mostly to hold a file position, where the Name member
|
||||
** is an index into the source file table of an object file. As used in config
|
||||
** file processing, the Name member is a string pool index instead. This is
|
||||
** distinguished by the object file pointer being NULL or not in the structs
|
||||
** where this is relevant.
|
||||
*/
|
||||
extern FilePos CfgErrorPos;
|
||||
|
||||
|
||||
|
||||
@@ -124,16 +124,16 @@ static Segment* NewSegment (unsigned Name, unsigned char AddrSize)
|
||||
|
||||
Segment* GetSegment (unsigned Name, unsigned char AddrSize, const char* ObjName)
|
||||
/* Search for a segment and return an existing one. If the segment does not
|
||||
* exist, create a new one and return that. ObjName is only used for the error
|
||||
* message and may be NULL if the segment is linker generated.
|
||||
*/
|
||||
** exist, create a new one and return that. ObjName is only used for the error
|
||||
** message and may be NULL if the segment is linker generated.
|
||||
*/
|
||||
{
|
||||
/* Try to locate the segment in the table */
|
||||
Segment* S = SegFind (Name);
|
||||
|
||||
/* If we don't have that segment already, allocate it using the type of
|
||||
* the first section.
|
||||
*/
|
||||
** the first section.
|
||||
*/
|
||||
if (S == 0) {
|
||||
/* Create a new segment */
|
||||
S = NewSegment (Name, AddrSize);
|
||||
@@ -308,8 +308,8 @@ Segment* SegFind (unsigned Name)
|
||||
|
||||
int IsBSSType (Segment* S)
|
||||
/* Check if the given segment is a BSS style segment, that is, it does not
|
||||
* contain non-zero data.
|
||||
*/
|
||||
** contain non-zero data.
|
||||
*/
|
||||
{
|
||||
/* Loop over all sections */
|
||||
unsigned I;
|
||||
@@ -405,8 +405,8 @@ void SegDump (void)
|
||||
|
||||
unsigned SegWriteConstExpr (FILE* F, ExprNode* E, int Signed, unsigned Size)
|
||||
/* Write a supposedly constant expression to the target file. Do a range
|
||||
* check and return one of the SEG_EXPR_xxx codes.
|
||||
*/
|
||||
** check and return one of the SEG_EXPR_xxx codes.
|
||||
*/
|
||||
{
|
||||
static const unsigned long U_Hi[4] = {
|
||||
0x000000FFUL, 0x0000FFFFUL, 0x00FFFFFFUL, 0xFFFFFFFFUL
|
||||
@@ -449,8 +449,8 @@ unsigned SegWriteConstExpr (FILE* F, ExprNode* E, int Signed, unsigned Size)
|
||||
|
||||
void SegWrite (const char* TgtName, FILE* Tgt, Segment* S, SegWriteFunc F, void* Data)
|
||||
/* Write the data from the given segment to a file. For expressions, F is
|
||||
* called (see description of SegWriteFunc above).
|
||||
*/
|
||||
** called (see description of SegWriteFunc above).
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
int Sign;
|
||||
@@ -472,9 +472,9 @@ void SegWrite (const char* TgtName, FILE* Tgt, Segment* S, SegWriteFunc F, void*
|
||||
Print (stdout, 2, " Section from \"%s\"\n", GetObjFileName (Sec->Obj));
|
||||
|
||||
/* If we have fill bytes, write them now. Beware: If this is the
|
||||
* first section, the fill value is not considered part of the segment
|
||||
* and therefore taken from the memory area.
|
||||
*/
|
||||
** first section, the fill value is not considered part of the segment
|
||||
** and therefore taken from the memory area.
|
||||
*/
|
||||
FillVal = (I == 0)? S->MemArea->FillVal : S->FillVal;
|
||||
Print (stdout, 2, " Filling 0x%lx bytes with 0x%02x\n",
|
||||
Sec->Fill, FillVal);
|
||||
@@ -646,8 +646,8 @@ void PrintDbgSegments (FILE* F)
|
||||
|
||||
void CheckSegments (void)
|
||||
/* Walk through the segment list and check if there are segments that were
|
||||
* not written to the output file. Output an error if this is the case.
|
||||
*/
|
||||
** not written to the output file. Output an error if this is the case.
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
for (I = 0; I < CollCount (&SegmentList); ++I) {
|
||||
|
||||
@@ -95,8 +95,8 @@ struct Section {
|
||||
|
||||
|
||||
/* Prototype for a function that is used to write expressions to the target
|
||||
* file (used in SegWrite). It returns one of the following values:
|
||||
*/
|
||||
** file (used in SegWrite). It returns one of the following values:
|
||||
*/
|
||||
#define SEG_EXPR_OK 0U /* Ok */
|
||||
#define SEG_EXPR_RANGE_ERROR 1U /* Range error */
|
||||
#define SEG_EXPR_TOO_COMPLEX 2U /* Expression too complex */
|
||||
@@ -118,9 +118,9 @@ typedef unsigned (*SegWriteFunc) (ExprNode* E, /* The expression to write
|
||||
|
||||
Segment* GetSegment (unsigned Name, unsigned char AddrSize, const char* ObjName);
|
||||
/* Search for a segment and return an existing one. If the segment does not
|
||||
* exist, create a new one and return that. ObjName is only used for the error
|
||||
* message and may be NULL if the segment is linker generated.
|
||||
*/
|
||||
** exist, create a new one and return that. ObjName is only used for the error
|
||||
** message and may be NULL if the segment is linker generated.
|
||||
*/
|
||||
|
||||
Section* NewSection (Segment* Seg, unsigned long Alignment, unsigned char AddrSize);
|
||||
/* Create a new section for the given segment */
|
||||
@@ -133,21 +133,21 @@ Segment* SegFind (unsigned Name);
|
||||
|
||||
int IsBSSType (Segment* S);
|
||||
/* Check if the given segment is a BSS style segment, that is, it does not
|
||||
* contain non-zero data.
|
||||
*/
|
||||
** contain non-zero data.
|
||||
*/
|
||||
|
||||
void SegDump (void);
|
||||
/* Dump the segments and it's contents */
|
||||
|
||||
unsigned SegWriteConstExpr (FILE* F, ExprNode* E, int Signed, unsigned Size);
|
||||
/* Write a supposedly constant expression to the target file. Do a range
|
||||
* check and return one of the SEG_EXPR_xxx codes.
|
||||
*/
|
||||
** check and return one of the SEG_EXPR_xxx codes.
|
||||
*/
|
||||
|
||||
void SegWrite (const char* TgtName, FILE* Tgt, Segment* S, SegWriteFunc F, void* Data);
|
||||
/* Write the data from the given segment to a file. For expressions, F is
|
||||
* called (see description of SegWriteFunc above).
|
||||
*/
|
||||
** called (see description of SegWriteFunc above).
|
||||
*/
|
||||
|
||||
unsigned SegmentCount (void);
|
||||
/* Return the total number of segments */
|
||||
@@ -160,8 +160,8 @@ void PrintDbgSegments (FILE* F);
|
||||
|
||||
void CheckSegments (void);
|
||||
/* Walk through the segment list and check if there are segments that were
|
||||
* not written to the output file. Output an error if this is the case.
|
||||
*/
|
||||
** not written to the output file. Output an error if this is the case.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -111,9 +111,9 @@ Span* ReadSpan (FILE* F, ObjData* O, unsigned Id)
|
||||
|
||||
unsigned* ReadSpanList (FILE* F)
|
||||
/* Read a list of span ids from a file. The list is returned as an array of
|
||||
* unsigneds, the first being the number of spans (never zero) followed by
|
||||
* the span ids. If the number of spans is zero, NULL is returned.
|
||||
*/
|
||||
** unsigneds, the first being the number of spans (never zero) followed by
|
||||
** the span ids. If the number of spans is zero, NULL is returned.
|
||||
*/
|
||||
{
|
||||
unsigned* Spans;
|
||||
|
||||
@@ -187,9 +187,9 @@ unsigned SpanCount (void)
|
||||
|
||||
void PrintDbgSpanList (FILE* F, const ObjData* O, const unsigned* List)
|
||||
/* Output a string ",span=x[+y...]" for the given list. If the list is empty
|
||||
* or NULL, output nothing. This is a helper function for other modules to
|
||||
* print a list of spans read by ReadSpanList to the debug info file.
|
||||
*/
|
||||
** or NULL, output nothing. This is a helper function for other modules to
|
||||
** print a list of spans read by ReadSpanList to the debug info file.
|
||||
*/
|
||||
{
|
||||
if (List && *List) {
|
||||
unsigned I;
|
||||
|
||||
@@ -78,9 +78,9 @@ Span* ReadSpan (FILE* F, struct ObjData* O, unsigned Id);
|
||||
|
||||
unsigned* ReadSpanList (FILE* F);
|
||||
/* Read a list of span ids from a file. The list is returned as an array of
|
||||
* unsigneds, the first being the number of spans (never zero) followed by
|
||||
* the span ids. If the number of spans is zero, NULL is returned.
|
||||
*/
|
||||
** unsigneds, the first being the number of spans (never zero) followed by
|
||||
** the span ids. If the number of spans is zero, NULL is returned.
|
||||
*/
|
||||
|
||||
unsigned* DupSpanList (const unsigned* S);
|
||||
/* Duplicate a span list */
|
||||
@@ -93,9 +93,9 @@ unsigned SpanCount (void);
|
||||
|
||||
void PrintDbgSpanList (FILE* F, const struct ObjData* O, const unsigned* List);
|
||||
/* Output a string ",span=x[+y...]" for the given list. If the list is empty
|
||||
* or NULL, output nothing. This is a helper function for other modules to
|
||||
* print a list of spans read by ReadSpanList to the debug info file.
|
||||
*/
|
||||
** or NULL, output nothing. This is a helper function for other modules to
|
||||
** print a list of spans read by ReadSpanList to the debug info file.
|
||||
*/
|
||||
|
||||
void PrintDbgSpans (FILE* F);
|
||||
/* Output the spans to a debug info file */
|
||||
|
||||
@@ -61,7 +61,7 @@ void InitStrPool (void)
|
||||
StrPool = NewStringPool (1103);
|
||||
|
||||
/* We insert a first string here, which will have id zero. This means
|
||||
* that we can treat index zero later as invalid.
|
||||
*/
|
||||
** that we can treat index zero later as invalid.
|
||||
*/
|
||||
SP_AddStr (StrPool, "<invalid message #0>");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user