-static Segment* NewSegment (const char* Name, unsigned char Type)
+static Segment* SegFindInternal (const char* Name, unsigned HashVal)
+/* Try to find the segment with the given name, return a pointer to the
+ * segment structure, or 0 if not found.
+ */
+{
+ Segment* S = HashTab [HashVal];
+ while (S) {
+ if (strcmp (Name, S->Name) == 0) {
+ /* Found */
+ break;
+ }
+ S = S->Next;
+ }
+ /* Not found */
+ return S;
+}
+
+
+
+static Segment* NewSegment (const char* Name, unsigned HashVal, unsigned char Type)
/* Create a new segment and initialize it */
{
/* Get the length of the symbol name */
SegRoot = S;
++SegCount;
+ /* Insert the segment into the segment hash list */
+ S->Next = HashTab [HashVal];
+ HashTab [HashVal] = S;
+
/* Return the new entry */
return S;
}
-static Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type)
+Segment* GetSegment (const char* Name, unsigned char Type, 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.
+ */
+{
+ /* Create a hash over the name and try to locate the segment in the table */
+ unsigned HashVal = HashStr (Name) % HASHTAB_SIZE;
+ Segment* S = SegFindInternal (Name, HashVal);
+
+ /* If we don't have that segment already, allocate it using the type of
+ * the first section.
+ */
+ if (S == 0) {
+ /* Create a new segment */
+ S = NewSegment (Name, HashVal, Type);
+ } else {
+ /* Check if the existing segment has the requested type */
+ if (S->Type != Type) {
+ /* Allow an empty object name */
+ if (ObjName == 0) {
+ ObjName = "[linker generated]";
+ }
+ Error ("Module `%s': Type mismatch for segment `%s'", ObjName, Name);
+ }
+ }
+
+ /* Return the segment */
+ return S;
+}
+
+
+
+Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type)
/* Create a new section for the given segment */
{
unsigned long V;
S->Seg = Seg;
S->FragRoot = 0;
S->FragLast = 0;
- S->Size = 0;
+ S->Size = 0;
S->Align = Align;
S->Type = Type;
-static Segment* SegFindInternal (const char* Name, unsigned HashVal)
-/* Try to find the segment with the given name, return a pointer to the
- * segment structure, or 0 if not found.
- */
-{
- Segment* S = HashTab [HashVal];
- while (S) {
- if (strcmp (Name, S->Name) == 0) {
- /* Found */
- break;
- }
- S = S->Next;
- }
- /* Not found */
- return S;
-}
-
-
-
Section* ReadSection (FILE* F, ObjData* O)
/* Read a section from a file */
{
- unsigned HashVal;
char* Name;
unsigned long Size;
unsigned char Align;
/* Print some data */
if (Verbose > 1) {
printf ("Module `%s': Found segment `%s', size = %lu, align = %u, type = %u\n",
- O->Name, Name, Size, Align, Type);
+ GetObjFileName (O), Name, Size, Align, Type);
}
- /* Create a hash over the name and try to locate the segment in the table */
- HashVal = HashStr (Name) % HASHTAB_SIZE;
- S = SegFindInternal (Name, HashVal);
-
- /* If we don't have that segment already, allocate it using the type of
- * the first section.
- */
- if (S == 0) {
- /* Create a new segment and insert it */
- S = NewSegment (Name, Type);
- S->Next = HashTab [HashVal];
- HashTab [HashVal] = S;
- }
+ /* Get the segment for this section */
+ S = GetSegment (Name, Type, GetObjFileName (O));
/* We have the segment and don't need the name any longer */
xfree (Name);
/* Allocate the section we will return later */
Sec = NewSection (S, Align, Type);
- /* Check if the section has the same type as the segment */
- if (Sec->Type != S->Type) {
- /* OOPS */
- Error ("Module `%s': Type mismatch for segment `%s'", O->Name, S->Name);
- }
-
/* Set up the minimum segment alignment */
if (Sec->Align > S->Align) {
/* Section needs larger alignment, use this one */
default:
Error ("Unknown fragment type in module `%s', segment `%s': %02X",
- O->Name, S->Name, Type);
+ GetObjFileName (O), S->Name, Type);
/* NOTREACHED */
return 0;
}
Size -= Frag->Size;
}
- /* Increment the segment size by the section size */
- S->Size += Sec->Size;
-
/* Return the section */
return Sec;
}
case SEG_EXPR_RANGE_ERROR:
Error ("Range error in module `%s', line %lu",
- Frag->Obj->Files [Frag->Pos.Name], Frag->Pos.Line);
+ GetSourceFileName (Frag->Obj, Frag->Pos.Name),
+ Frag->Pos.Line);
break;
case SEG_EXPR_TOO_COMPLEX:
Error ("Expression too complex in module `%s', line %lu",
- Frag->Obj->Files [Frag->Pos.Name], Frag->Pos.Line);
+ GetSourceFileName (Frag->Obj, Frag->Pos.Name),
+ Frag->Pos.Line);
break;
default: