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);
114 void ObjReadFiles (FILE* F, unsigned long Pos, ObjData* O)
115 /* Read the files list from a file at the given position */
120 /* Seek to the correct position */
124 FileCount = ReadVar (F);
125 CollGrow (&O->Files, FileCount);
126 for (I = 0; I < FileCount; ++I) {
127 CollAppend (&O->Files, ReadFileInfo (F, O));
133 void ObjReadSections (FILE* F, unsigned long Pos, ObjData* O)
134 /* Read the section data from a file at the given position */
137 unsigned SectionCount;
139 /* Seek to the correct position */
143 SectionCount = ReadVar (F);
144 CollGrow (&O->Sections, SectionCount);
145 for (I = 0; I < SectionCount; ++I) {
146 CollAppend (&O->Sections, ReadSection (F, O));
152 void ObjReadImports (FILE* F, unsigned long Pos, ObjData* O)
153 /* Read the imports from a file at the given position */
156 unsigned ImportCount;
158 /* Seek to the correct position */
162 ImportCount = ReadVar (F);
163 CollGrow (&O->Imports, ImportCount);
164 for (I = 0; I < ImportCount; ++I) {
165 CollAppend (&O->Imports, ReadImport (F, O));
171 void ObjReadExports (FILE* F, unsigned long Pos, ObjData* O)
172 /* Read the exports from a file at the given position */
175 unsigned ExportCount;
177 /* Seek to the correct position */
181 ExportCount = ReadVar (F);
182 CollGrow (&O->Exports, ExportCount);
183 for (I = 0; I < ExportCount; ++I) {
184 CollAppend (&O->Exports, ReadExport (F, O));
190 void ObjReadDbgSyms (FILE* F, unsigned long Pos, ObjData* O)
191 /* Read the debug symbols from a file at the given position */
194 unsigned DbgSymCount;
196 /* Seek to the correct position */
200 DbgSymCount = ReadVar (F);
201 CollGrow (&O->DbgSyms, DbgSymCount);
202 for (I = 0; I < DbgSymCount; ++I) {
203 CollAppend (&O->DbgSyms, ReadDbgSym (F, O));
209 void ObjReadLineInfos (FILE* F, unsigned long Pos, ObjData* O)
210 /* Read the line infos from a file at the given position */
213 unsigned LineInfoCount;
215 /* Seek to the correct position */
219 LineInfoCount = ReadVar (F);
220 CollGrow (&O->LineInfos, LineInfoCount);
221 for (I = 0; I < LineInfoCount; ++I) {
222 CollAppend (&O->LineInfos, ReadLineInfo (F, O));
228 void ObjReadStrPool (FILE* F, unsigned long Pos, ObjData* O)
229 /* Read the string pool from a file at the given position */
233 /* Seek to the correct position */
237 O->StringCount = ReadVar (F);
238 O->Strings = xmalloc (O->StringCount * sizeof (O->Strings[0]));
239 for (I = 0; I < O->StringCount; ++I) {
240 O->Strings[I] = ReadStr (F);
246 void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O)
247 /* Read the assertions from a file at the given offset */
250 unsigned AssertionCount;
252 /* Seek to the correct position */
256 AssertionCount = ReadVar (F);
257 CollGrow (&O->Assertions, AssertionCount);
258 for (I = 0; I < AssertionCount; ++I) {
259 CollAppend (&O->Assertions, ReadAssertion (F, O));
265 void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O)
266 /* Read the scope table from a file at the given offset */
271 /* Seek to the correct position */
275 ScopeCount = ReadVar (F);
276 CollGrow (&O->Scopes, ScopeCount);
277 for (I = 0; I < ScopeCount; ++I) {
278 CollAppend (&O->Scopes, ReadScope (F, O, I));
284 void ObjAdd (FILE* Obj, const char* Name)
285 /* Add an object file to the module list */
287 /* Create a new structure for the object file data */
288 ObjData* O = NewObjData ();
290 /* The magic was already read and checked, so set it in the header */
291 O->Header.Magic = OBJ_MAGIC;
293 /* Read and check the header */
294 ObjReadHeader (Obj, &O->Header, Name);
296 /* Initialize the object module data structure */
297 O->Name = GetModule (Name);
299 /* Read the string pool from the object file */
300 ObjReadStrPool (Obj, O->Header.StrPoolOffs, O);
302 /* Read the files list from the object file */
303 ObjReadFiles (Obj, O->Header.FileOffs, O);
305 /* Read the line infos from the object file */
306 ObjReadLineInfos (Obj, O->Header.LineInfoOffs, O);
308 /* Read the imports list from the object file */
309 ObjReadImports (Obj, O->Header.ImportOffs, O);
311 /* Read the object file exports and insert them into the exports list */
312 ObjReadExports (Obj, O->Header.ExportOffs, O);
314 /* Read the object debug symbols from the object file */
315 ObjReadDbgSyms (Obj, O->Header.DbgSymOffs, O);
317 /* Read the assertions from the object file */
318 ObjReadAssertions (Obj, O->Header.AssertOffs, O);
320 /* Read the scope table from the object file */
321 ObjReadScopes (Obj, O->Header.ScopeOffs, O);
323 /* Read the segment list from the object file. This must be last, since
324 * the expressions stored in the code may reference segments or imported
327 ObjReadSections (Obj, O->Header.SegOffs, O);
329 /* Mark this object file as needed */
332 /* Done, close the file (we read it only, so no error check) */
335 /* Insert the imports and exports to the global lists */
336 InsertObjGlobals (O);
338 /* Insert the object into the list of all used object files */
341 /* All references to strings are now resolved, so we can delete the module