1 /*****************************************************************************/
5 /* Object file handling for the ld65 linker */
9 /* (C) 1998-2011, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
39 #include <sys/types.h> /* EMX needs this */
62 /*****************************************************************************/
64 /*****************************************************************************/
68 static unsigned GetModule (const char* Name)
69 /* Get a module name index from the file name */
71 /* Make a module name from the file name */
72 const char* Module = FindName (Name);
74 Error ("Cannot make module name from `%s'", Name);
76 return GetStringId (Module);
81 static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
82 /* Read the header of the object file checking the signature */
84 H->Version = Read16 (Obj);
85 if (H->Version != OBJ_VERSION) {
86 Error ("Object file `%s' has wrong version, expected %08X, got %08X",
87 Name, OBJ_VERSION, H->Version);
89 H->Flags = Read16 (Obj);
90 H->OptionOffs = Read32 (Obj);
91 H->OptionSize = Read32 (Obj);
92 H->FileOffs = Read32 (Obj);
93 H->FileSize = Read32 (Obj);
94 H->SegOffs = Read32 (Obj);
95 H->SegSize = Read32 (Obj);
96 H->ImportOffs = Read32 (Obj);
97 H->ImportSize = Read32 (Obj);
98 H->ExportOffs = Read32 (Obj);
99 H->ExportSize = Read32 (Obj);
100 H->DbgSymOffs = Read32 (Obj);
101 H->DbgSymSize = Read32 (Obj);
102 H->LineInfoOffs = Read32 (Obj);
103 H->LineInfoSize = Read32 (Obj);
104 H->StrPoolOffs = Read32 (Obj);
105 H->StrPoolSize = Read32 (Obj);
106 H->AssertOffs = Read32 (Obj);
107 H->AssertSize = Read32 (Obj);
108 H->ScopeOffs = Read32 (Obj);
109 H->ScopeSize = Read32 (Obj);
110 H->SpanOffs = Read32 (Obj);
111 H->SpanSize = Read32 (Obj);
116 void ObjReadFiles (FILE* F, unsigned long Pos, ObjData* O)
117 /* Read the files list from a file at the given position */
122 /* Seek to the correct position */
126 FileCount = ReadVar (F);
127 CollGrow (&O->Files, FileCount);
128 for (I = 0; I < FileCount; ++I) {
129 CollAppend (&O->Files, ReadFileInfo (F, O));
135 void ObjReadSections (FILE* F, unsigned long Pos, ObjData* O)
136 /* Read the section data from a file at the given position */
139 unsigned SectionCount;
141 /* Seek to the correct position */
145 SectionCount = ReadVar (F);
146 CollGrow (&O->Sections, SectionCount);
147 for (I = 0; I < SectionCount; ++I) {
148 CollAppend (&O->Sections, ReadSection (F, O));
154 void ObjReadImports (FILE* F, unsigned long Pos, ObjData* O)
155 /* Read the imports from a file at the given position */
158 unsigned ImportCount;
160 /* Seek to the correct position */
164 ImportCount = ReadVar (F);
165 CollGrow (&O->Imports, ImportCount);
166 for (I = 0; I < ImportCount; ++I) {
167 CollAppend (&O->Imports, ReadImport (F, O));
173 void ObjReadExports (FILE* F, unsigned long Pos, ObjData* O)
174 /* Read the exports from a file at the given position */
177 unsigned ExportCount;
179 /* Seek to the correct position */
183 ExportCount = ReadVar (F);
184 CollGrow (&O->Exports, ExportCount);
185 for (I = 0; I < ExportCount; ++I) {
186 CollAppend (&O->Exports, ReadExport (F, O));
192 void ObjReadDbgSyms (FILE* F, unsigned long Pos, ObjData* O)
193 /* Read the debug symbols from a file at the given position */
196 unsigned DbgSymCount;
198 /* Seek to the correct position */
201 /* Read the asm debug symbols */
202 DbgSymCount = ReadVar (F);
203 CollGrow (&O->DbgSyms, DbgSymCount);
204 for (I = 0; I < DbgSymCount; ++I) {
205 CollAppend (&O->DbgSyms, ReadDbgSym (F, O, I));
208 /* Read the hll debug symbols */
209 DbgSymCount = ReadVar (F);
210 CollGrow (&O->HLLDbgSyms, DbgSymCount);
211 for (I = 0; I < DbgSymCount; ++I) {
212 CollAppend (&O->HLLDbgSyms, ReadHLLDbgSym (F, O, I));
218 void ObjReadLineInfos (FILE* F, unsigned long Pos, ObjData* O)
219 /* Read the line infos from a file at the given position */
222 unsigned LineInfoCount;
224 /* Seek to the correct position */
228 LineInfoCount = ReadVar (F);
229 CollGrow (&O->LineInfos, LineInfoCount);
230 for (I = 0; I < LineInfoCount; ++I) {
231 CollAppend (&O->LineInfos, ReadLineInfo (F, O));
237 void ObjReadStrPool (FILE* F, unsigned long Pos, ObjData* O)
238 /* Read the string pool from a file at the given position */
242 /* Seek to the correct position */
246 O->StringCount = ReadVar (F);
247 O->Strings = xmalloc (O->StringCount * sizeof (O->Strings[0]));
248 for (I = 0; I < O->StringCount; ++I) {
249 O->Strings[I] = ReadStr (F);
255 void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O)
256 /* Read the assertions from a file at the given offset */
259 unsigned AssertionCount;
261 /* Seek to the correct position */
265 AssertionCount = ReadVar (F);
266 CollGrow (&O->Assertions, AssertionCount);
267 for (I = 0; I < AssertionCount; ++I) {
268 CollAppend (&O->Assertions, ReadAssertion (F, O));
274 void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O)
275 /* Read the scope table from a file at the given offset */
280 /* Seek to the correct position */
284 ScopeCount = ReadVar (F);
285 CollGrow (&O->Scopes, ScopeCount);
286 for (I = 0; I < ScopeCount; ++I) {
287 CollAppend (&O->Scopes, ReadScope (F, O, I));
293 void ObjReadSpans (FILE* F, unsigned long Pos, ObjData* O)
294 /* Read the span table from a file at the given offset */
299 /* Seek to the correct position */
303 SpanCount = ReadVar (F);
304 CollGrow (&O->Spans, SpanCount);
305 for (I = 0; I < SpanCount; ++I) {
306 CollAppend (&O->Spans, ReadSpan (F, O, I));
312 void ObjAdd (FILE* Obj, const char* Name)
313 /* Add an object file to the module list */
315 /* Create a new structure for the object file data */
316 ObjData* O = NewObjData ();
318 /* The magic was already read and checked, so set it in the header */
319 O->Header.Magic = OBJ_MAGIC;
321 /* Read and check the header */
322 ObjReadHeader (Obj, &O->Header, Name);
324 /* Initialize the object module data structure */
325 O->Name = GetModule (Name);
327 /* Read the string pool from the object file */
328 ObjReadStrPool (Obj, O->Header.StrPoolOffs, O);
330 /* Read the files list from the object file */
331 ObjReadFiles (Obj, O->Header.FileOffs, O);
333 /* Read the line infos from the object file */
334 ObjReadLineInfos (Obj, O->Header.LineInfoOffs, O);
336 /* Read the imports list from the object file */
337 ObjReadImports (Obj, O->Header.ImportOffs, O);
339 /* Read the object file exports and insert them into the exports list */
340 ObjReadExports (Obj, O->Header.ExportOffs, O);
342 /* Read the object debug symbols from the object file */
343 ObjReadDbgSyms (Obj, O->Header.DbgSymOffs, O);
345 /* Read the assertions from the object file */
346 ObjReadAssertions (Obj, O->Header.AssertOffs, O);
348 /* Read the segment list from the object file. This must be late, since
349 * the expressions stored in the code may reference segments or imported
352 ObjReadSections (Obj, O->Header.SegOffs, O);
354 /* Read the scope table from the object file. Scopes reference segments, so
355 * we must read them after the sections.
357 ObjReadScopes (Obj, O->Header.ScopeOffs, O);
359 /* Read the spans from the object file */
360 ObjReadSpans (Obj, O->Header.SpanOffs, O);
362 /* Mark this object file as needed */
365 /* Done, close the file (we read it only, so no error check) */
368 /* Insert the imports and exports to the global lists */
369 InsertObjGlobals (O);
371 /* Insert the object into the list of all used object files */
374 /* All references to strings are now resolved, so we can delete the module