1 /* -----------------------------------------------------------------------------
2 * $Id: Linker.c,v 1.28 2001/02/13 18:01:22 simonmar Exp $
4 * (c) The GHC Team, 2000
8 * ---------------------------------------------------------------------------*/
15 #include "LinkerInternals.h"
17 #include "StoragePriv.h"
19 #ifdef HAVE_SYS_TYPES_H
20 #include <sys/types.h>
23 #ifdef HAVE_SYS_STAT_H
31 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS) || defined(freebsd_TARGET_OS)
33 #elif defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS)
34 #define OBJFORMAT_PEi386
37 /* Hash table mapping symbol names to Symbol */
38 /*Str*/HashTable *symhash;
40 #if defined(OBJFORMAT_ELF)
41 static int ocVerifyImage_ELF ( ObjectCode* oc );
42 static int ocGetNames_ELF ( ObjectCode* oc );
43 static int ocResolve_ELF ( ObjectCode* oc );
44 #elif defined(OBJFORMAT_PEi386)
45 static int ocVerifyImage_PEi386 ( ObjectCode* oc );
46 static int ocGetNames_PEi386 ( ObjectCode* oc );
47 static int ocResolve_PEi386 ( ObjectCode* oc );
50 /* -----------------------------------------------------------------------------
51 * Built-in symbols from the RTS
68 SymX(stg_update_PAP) \
69 SymX(stg_ap_2_upd_info) \
70 SymX(stg_ap_3_upd_info) \
71 SymX(stg_ap_4_upd_info) \
72 SymX(stg_ap_5_upd_info) \
73 SymX(stg_ap_6_upd_info) \
74 SymX(stg_ap_7_upd_info) \
75 SymX(stg_ap_8_upd_info) \
76 SymX(stg_sel_0_upd_info) \
77 SymX(stg_sel_1_upd_info) \
78 SymX(stg_sel_2_upd_info) \
79 SymX(stg_sel_3_upd_info) \
80 SymX(stg_sel_4_upd_info) \
81 SymX(stg_sel_5_upd_info) \
82 SymX(stg_sel_6_upd_info) \
83 SymX(stg_sel_7_upd_info) \
84 SymX(stg_sel_8_upd_info) \
85 SymX(stg_sel_9_upd_info) \
86 SymX(stg_sel_10_upd_info) \
87 SymX(stg_sel_11_upd_info) \
88 SymX(stg_sel_12_upd_info) \
89 SymX(stg_sel_13_upd_info) \
90 SymX(stg_sel_14_upd_info) \
91 SymX(stg_sel_15_upd_info) \
92 SymX(stg_upd_frame_info) \
93 SymX(stg_seq_frame_info) \
94 SymX(stg_CAF_BLACKHOLE_info) \
95 SymX(stg_IND_STATIC_info) \
96 SymX(stg_EMPTY_MVAR_info) \
97 SymX(stg_MUT_ARR_PTRS_FROZEN_info) \
99 SymX(stg_CHARLIKE_closure) \
100 SymX(stg_INTLIKE_closure) \
102 SymX(newBCOzh_fast) \
103 SymX(mkApUpd0zh_fast) \
104 SymX(putMVarzh_fast) \
105 SymX(newMVarzh_fast) \
106 SymX(takeMVarzh_fast) \
107 SymX(tryTakeMVarzh_fast) \
113 SymX(killThreadzh_fast) \
114 SymX(waitReadzh_fast) \
115 SymX(waitWritezh_fast) \
116 SymX(suspendThread) \
118 SymX(stackOverflow) \
119 SymX(int2Integerzh_fast) \
120 SymX(word2Integerzh_fast) \
121 SymX(mkForeignObjzh_fast) \
122 SymX(__encodeDouble) \
123 SymX(decodeDoublezh_fast) \
124 SymX(decodeFloatzh_fast) \
125 SymX(gcdIntegerzh_fast) \
126 SymX(newArrayzh_fast) \
127 SymX(unsafeThawArrayzh_fast) \
128 SymX(newByteArrayzh_fast) \
129 SymX(newMutVarzh_fast) \
130 SymX(quotRemIntegerzh_fast) \
131 SymX(quotIntegerzh_fast) \
132 SymX(remIntegerzh_fast) \
133 SymX(divExactIntegerzh_fast) \
134 SymX(divModIntegerzh_fast) \
135 SymX(timesIntegerzh_fast) \
136 SymX(minusIntegerzh_fast) \
137 SymX(plusIntegerzh_fast) \
138 SymX(andIntegerzh_fast) \
139 SymX(orIntegerzh_fast) \
140 SymX(xorIntegerzh_fast) \
141 SymX(complementIntegerzh_fast) \
142 SymX(mkWeakzh_fast) \
143 SymX(makeStableNamezh_fast) \
144 SymX(finalizzeWeakzh_fast) \
145 SymX(blockAsyncExceptionszh_fast) \
146 SymX(unblockAsyncExceptionszh_fast) \
148 SymX(isDoubleInfinite) \
149 SymX(isDoubleDenormalized) \
150 SymX(isDoubleNegativeZero) \
151 SymX(__encodeFloat) \
153 SymX(isFloatInfinite) \
154 SymX(isFloatDenormalized) \
155 SymX(isFloatNegativeZero) \
156 SymX(__int_encodeFloat) \
157 SymX(__int_encodeDouble) \
158 SymX(__gmpz_cmp_si) \
159 SymX(__gmpz_cmp_ui) \
164 SymX(resetNonBlockingFd) \
166 SymX(stable_ptr_table) \
167 SymX(shutdownHaskellAndExit) \
168 Sym(stg_enterStackTop) \
169 Sym(stg_yield_to_interpreter) \
173 Sym(__init_PrelGHC) \
174 SymX(freeHaskellFunctionPtr) \
177 SymX(NoRunnableThreadsHook) \
178 SymX(StackOverflowHook) \
179 SymX(OutOfHeapHook) \
180 SymX(MallocFailHook) \
181 SymX(PatErrorHdrHook) \
184 SymX(PostTraceHook) \
185 SymX(stg_sig_install) \
187 SymX(createAdjustor) \
189 SymX(rts_mkStablePtr) \
192 SymX(rts_checkSchedStatus) \
195 #ifndef SUPPORT_LONG_LONGS
196 #define RTS_LONG_LONG_SYMS /* nothing */
198 #define RTS_LONG_LONG_SYMS \
211 SymX(stg_remWord64) \
212 SymX(stg_quotWord64) \
214 SymX(stg_quotInt64) \
215 SymX(stg_negateInt64) \
216 SymX(stg_plusInt64) \
217 SymX(stg_minusInt64) \
218 SymX(stg_timesInt64) \
224 SymX(stg_shiftRL64) \
225 SymX(stg_iShiftL64) \
226 SymX(stg_iShiftRL64) \
227 SymX(stg_iShiftRA64) \
228 SymX(stg_intToInt64) \
229 SymX(stg_int64ToInt) \
230 SymX(stg_int64ToWord64) \
231 SymX(stg_wordToWord64) \
232 SymX(stg_word64ToWord) \
233 SymX(stg_word64ToInt64) \
234 SymX(int64ToIntegerzh_fast) \
235 SymX(word64ToIntegerzh_fast)
236 #endif /* SUPPORT_LONG_LONGS */
238 /* entirely bogus claims about types of these symbols */
239 #define Sym(vvv) extern void (vvv);
240 #define SymX(vvv) /**/
245 #ifdef LEADING_UNDERSCORE
246 #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
248 #define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
251 #define Sym(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
253 #define SymX(vvv) Sym(vvv)
255 static SymbolVal rtsSyms[] = {
258 { 0, 0 } /* sentinel */
261 /* -----------------------------------------------------------------------------
262 * initialize the object linker
264 static void *dl_prog_handle;
271 symhash = allocStrHashTable();
273 /* populate the symbol table with stuff from the RTS */
274 for (sym = rtsSyms; sym->lbl != NULL; sym++) {
275 insertStrHashTable(symhash, sym->lbl, sym);
278 dl_prog_handle = dlopen(NULL, RTLD_LAZY);
281 /* -----------------------------------------------------------------------------
282 * Add a DLL from which symbols may be found. In the ELF case, just
283 * do RTLD_GLOBAL-style add, so no further messing around needs to
284 * happen in order that symbols in the loaded .so are findable --
285 * lookupSymbol() will subsequently see them by dlsym on the program's
286 * dl-handle. Returns 0 if fail, 1 if success.
289 addDLL ( char* dll_name )
291 # if defined(OBJFORMAT_ELF)
295 buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
296 sprintf(buf, "lib%s.so", dll_name);
297 hdl = dlopen(buf, RTLD_NOW | RTLD_GLOBAL);
299 return (hdl == NULL) ? 0 : 1;
300 # elif defined(OBJFORMAT_PEi386)
301 barf("addDLL: not implemented on PEi386 yet");
304 barf("addDLL: not implemented on this platform");
308 /* -----------------------------------------------------------------------------
309 * lookup a symbol in the hash table
312 lookupSymbol( char *lbl )
315 ASSERT(symhash != NULL);
316 val = lookupStrHashTable(symhash, lbl);
319 return dlsym(dl_prog_handle, lbl);
327 lookupLocalSymbol( ObjectCode* oc, char *lbl )
330 val = lookupStrHashTable(oc->lochash, lbl);
340 /* -----------------------------------------------------------------------------
341 * Load an obj (populate the global symbol table, but don't resolve yet)
343 * Returns: 1 if ok, 0 on error.
346 loadObj( char *path )
354 /* assert that we haven't already loaded this object */
357 for (o = objects; o; o = o->next)
358 ASSERT(strcmp(o->fileName, path));
362 oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
364 # if defined(OBJFORMAT_ELF)
365 oc->formatName = "ELF";
366 # elif defined(OBJFORMAT_PEi386)
367 oc->formatName = "PEi386";
370 barf("loadObj: not implemented on this platform");
374 if (r == -1) { return 0; }
376 /* sigh, strdup() isn't a POSIX function, so do it the long way */
377 oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
378 strcpy(oc->fileName, path);
380 oc->fileSize = st.st_size;
381 oc->image = stgMallocBytes( st.st_size, "loadObj(image)" );
384 oc->lochash = allocStrHashTable();
386 /* chain it onto the list of objects */
390 /* load the image into memory */
391 f = fopen(path, "rb");
393 barf("loadObj: can't read `%s'", path);
395 n = fread ( oc->image, 1, oc->fileSize, f );
396 if (n != oc->fileSize) {
398 barf("loadObj: error whilst reading `%s'", path);
401 /* verify the in-memory image */
402 # if defined(OBJFORMAT_ELF)
403 r = ocVerifyImage_ELF ( oc );
404 # elif defined(OBJFORMAT_PEi386)
405 r = ocVerifyImage_PEi386 ( oc );
407 barf("loadObj: no verify method");
409 if (!r) { return r; }
411 /* build the symbol list for this image */
412 # if defined(OBJFORMAT_ELF)
413 r = ocGetNames_ELF ( oc );
414 # elif defined(OBJFORMAT_PEi386)
415 r = ocGetNames_PEi386 ( oc );
417 barf("loadObj: no getNames method");
419 if (!r) { return r; }
421 /* loaded, but not resolved yet */
422 oc->status = OBJECT_LOADED;
427 /* -----------------------------------------------------------------------------
428 * resolve all the currently unlinked objects in memory
430 * Returns: 1 if ok, 0 on error.
438 for (oc = objects; oc; oc = oc->next) {
439 if (oc->status != OBJECT_RESOLVED) {
440 # if defined(OBJFORMAT_ELF)
441 r = ocResolve_ELF ( oc );
442 # elif defined(OBJFORMAT_PEi386)
443 r = ocResolve_PEi386 ( oc );
445 barf("link: not implemented on this platform");
447 if (!r) { return r; }
448 oc->status = OBJECT_RESOLVED;
454 /* -----------------------------------------------------------------------------
455 * delete an object from the pool
458 unloadObj( char *path )
460 ObjectCode *oc, *prev;
462 ASSERT(symhash != NULL);
463 ASSERT(objects != NULL);
466 for (oc = objects; oc; prev = oc, oc = oc->next) {
467 if (!strcmp(oc->fileName,path)) {
469 /* Remove all the mappings for the symbols within this
474 for (s = oc->symbols; s < oc->symbols + oc->n_symbols; s++) {
475 if (s->lbl != NULL) {
476 removeStrHashTable(symhash, s->lbl, NULL);
484 prev->next = oc->next;
487 /* We're going to leave this in place, in case there are
488 any pointers from the heap into it: */
489 /* free(oc->image); */
493 /* The local hash table should have been freed at the end
494 of the ocResolve_ call on it. */
495 ASSERT(oc->lochash == NULL);
501 belch("unloadObj: can't find `%s' to unload", path);
505 /* --------------------------------------------------------------------------
506 * PEi386 specifics (Win32 targets)
507 * ------------------------------------------------------------------------*/
509 /* The information for this linker comes from
510 Microsoft Portable Executable
511 and Common Object File Format Specification
512 revision 5.1 January 1998
513 which SimonM says comes from the MS Developer Network CDs.
517 #if defined(OBJFORMAT_PEi386)
521 typedef unsigned char UChar;
522 typedef unsigned short UInt16;
523 typedef unsigned int UInt32;
530 UInt16 NumberOfSections;
531 UInt32 TimeDateStamp;
532 UInt32 PointerToSymbolTable;
533 UInt32 NumberOfSymbols;
534 UInt16 SizeOfOptionalHeader;
535 UInt16 Characteristics;
539 #define sizeof_COFF_header 20
546 UInt32 VirtualAddress;
547 UInt32 SizeOfRawData;
548 UInt32 PointerToRawData;
549 UInt32 PointerToRelocations;
550 UInt32 PointerToLinenumbers;
551 UInt16 NumberOfRelocations;
552 UInt16 NumberOfLineNumbers;
553 UInt32 Characteristics;
557 #define sizeof_COFF_section 40
564 UInt16 SectionNumber;
567 UChar NumberOfAuxSymbols;
571 #define sizeof_COFF_symbol 18
576 UInt32 VirtualAddress;
577 UInt32 SymbolTableIndex;
582 #define sizeof_COFF_reloc 10
585 /* From PE spec doc, section 3.3.2 */
586 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001
587 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
588 #define IMAGE_FILE_DLL 0x2000
589 #define IMAGE_FILE_SYSTEM 0x1000
590 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
591 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
592 #define IMAGE_FILE_32BIT_MACHINE 0x0100
594 /* From PE spec doc, section 5.4.2 and 5.4.4 */
595 #define IMAGE_SYM_CLASS_EXTERNAL 2
596 #define IMAGE_SYM_CLASS_STATIC 3
597 #define IMAGE_SYM_UNDEFINED 0
599 /* From PE spec doc, section 4.1 */
600 #define IMAGE_SCN_CNT_CODE 0x00000020
601 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
603 /* From PE spec doc, section 5.2.1 */
604 #define IMAGE_REL_I386_DIR32 0x0006
605 #define IMAGE_REL_I386_REL32 0x0014
608 /* We use myindex to calculate array addresses, rather than
609 simply doing the normal subscript thing. That's because
610 some of the above structs have sizes which are not
611 a whole number of words. GCC rounds their sizes up to a
612 whole number of words, which means that the address calcs
613 arising from using normal C indexing or pointer arithmetic
614 are just plain wrong. Sigh.
617 myindex ( int scale, int index, void* base )
620 ((UChar*)base) + scale * index;
625 printName ( UChar* name, UChar* strtab )
627 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
628 UInt32 strtab_offset = * (UInt32*)(name+4);
629 fprintf ( stderr, "%s", strtab + strtab_offset );
632 for (i = 0; i < 8; i++) {
633 if (name[i] == 0) break;
634 fprintf ( stderr, "%c", name[i] );
641 copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
643 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
644 UInt32 strtab_offset = * (UInt32*)(name+4);
645 strncpy ( dst, strtab+strtab_offset, dstSize );
651 if (name[i] == 0) break;
661 cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
664 /* If the string is longer than 8 bytes, look in the
665 string table for it -- this will be correctly zero terminated.
667 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
668 UInt32 strtab_offset = * (UInt32*)(name+4);
669 return ((UChar*)strtab) + strtab_offset;
671 /* Otherwise, if shorter than 8 bytes, return the original,
672 which by defn is correctly terminated.
674 if (name[7]==0) return name;
675 /* The annoying case: 8 bytes. Copy into a temporary
676 (which is never freed ...)
680 strncpy(newstr,name,8);
687 /* Just compares the short names (first 8 chars) */
688 static COFF_section *
689 findPEi386SectionCalled ( ObjectCode* oc, char* name )
693 = (COFF_header*)(oc->image);
696 ((UChar*)(oc->image))
697 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
699 for (i = 0; i < hdr->NumberOfSections; i++) {
702 COFF_section* section_i
704 myindex ( sizeof_COFF_section, i, sectab );
705 n1 = (UChar*) &(section_i->Name);
707 if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] &&
708 n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] &&
709 n1[6]==n2[6] && n1[7]==n2[7])
718 zapTrailingAtSign ( UChar* sym )
721 if (sym[0] == 0) return;
723 while (sym[i] != 0) i++;
726 while (j > 0 && isdigit(sym[j])) j--;
727 if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
732 ocVerifyImage_PEi386 ( ObjectCode* oc )
736 COFF_section* sectab;
740 hdr = (COFF_header*)(oc->image);
741 sectab = (COFF_section*) (
742 ((UChar*)(oc->image))
743 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
745 symtab = (COFF_symbol*) (
746 ((UChar*)(oc->image))
747 + hdr->PointerToSymbolTable
749 strtab = ((UChar*)(oc->image))
750 + hdr->PointerToSymbolTable
751 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
753 if (hdr->Machine != 0x14c) {
754 oc->errMsg("Not x86 PEi386");
757 if (hdr->SizeOfOptionalHeader != 0) {
758 oc->errMsg("PEi386 with nonempty optional header");
761 if ( /* (hdr->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) || */
762 (hdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ||
763 (hdr->Characteristics & IMAGE_FILE_DLL) ||
764 (hdr->Characteristics & IMAGE_FILE_SYSTEM) ) {
765 oc->errMsg("Not a PEi386 object file");
768 if ( (hdr->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI) ||
769 !(hdr->Characteristics & IMAGE_FILE_32BIT_MACHINE) ) {
770 oc->errMsg("Invalid PEi386 word size or endiannness");
774 if (!verb) return TRUE;
775 /* No further verification after this point; only debug printing. */
778 "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
780 "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
782 "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
784 fprintf ( stderr, "\n" );
786 "Machine: 0x%x\n", (UInt32)(hdr->Machine) );
788 "# sections: %d\n", (UInt32)(hdr->NumberOfSections) );
790 "time/date: 0x%x\n", (UInt32)(hdr->TimeDateStamp) );
792 "symtab offset: %d\n", (UInt32)(hdr->PointerToSymbolTable) );
794 "# symbols: %d\n", (UInt32)(hdr->NumberOfSymbols) );
796 "sz of opt hdr: %d\n", (UInt32)(hdr->SizeOfOptionalHeader) );
798 "characteristics: 0x%x\n", (UInt32)(hdr->Characteristics) );
800 fprintf ( stderr, "\n" );
801 fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
802 fprintf ( stderr, "---START of string table---\n");
803 for (i = 4; i < *(UInt32*)strtab; i++) {
805 fprintf ( stderr, "\n"); else
806 fprintf( stderr, "%c", strtab[i] );
808 fprintf ( stderr, "--- END of string table---\n");
810 fprintf ( stderr, "\n" );
811 for (i = 0; i < hdr->NumberOfSections; i++) {
813 COFF_section* sectab_i
815 myindex ( sizeof_COFF_section, i, sectab );
822 printName ( sectab_i->Name, strtab );
831 sectab_i->VirtualSize,
832 sectab_i->VirtualAddress,
833 sectab_i->SizeOfRawData,
834 sectab_i->PointerToRawData,
835 sectab_i->NumberOfRelocations,
836 sectab_i->PointerToRelocations
838 reltab = (COFF_reloc*) (
839 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
841 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
843 COFF_reloc* rel = (COFF_reloc*)
844 myindex ( sizeof_COFF_reloc, j, reltab );
846 " type 0x%-4x vaddr 0x%-8x name `",
848 rel->VirtualAddress );
850 myindex ( sizeof_COFF_symbol, rel->SymbolTableIndex, symtab );
851 printName ( sym->Name, strtab );
852 fprintf ( stderr, "'\n" );
854 fprintf ( stderr, "\n" );
858 fprintf ( stderr, "\n" );
861 COFF_symbol* symtab_i;
862 if (i >= hdr->NumberOfSymbols) break;
863 symtab_i = (COFF_symbol*)
864 myindex ( sizeof_COFF_symbol, i, symtab );
870 printName ( symtab_i->Name, strtab );
879 (Int32)(symtab_i->SectionNumber) - 1,
880 (UInt32)symtab_i->Type,
881 (UInt32)symtab_i->StorageClass,
882 (UInt32)symtab_i->NumberOfAuxSymbols
884 i += symtab_i->NumberOfAuxSymbols;
888 fprintf ( stderr, "\n" );
895 ocGetNames_PEi386 ( ObjectCode* oc )
898 COFF_section* sectab;
906 hdr = (COFF_header*)(oc->image);
907 sectab = (COFF_section*) (
908 ((UChar*)(oc->image))
909 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
911 symtab = (COFF_symbol*) (
912 ((UChar*)(oc->image))
913 + hdr->PointerToSymbolTable
915 strtab = ((UChar*)(oc->image))
916 + hdr->PointerToSymbolTable
917 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
919 /* Copy exported symbols into the ObjectCode. */
922 COFF_symbol* symtab_i;
923 if (i >= hdr->NumberOfSymbols) break;
924 symtab_i = (COFF_symbol*)
925 myindex ( sizeof_COFF_symbol, i, symtab );
927 if (symtab_i->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
928 symtab_i->SectionNumber != IMAGE_SYM_UNDEFINED) {
930 /* This symbol is global and defined, viz, exported */
931 COFF_section* sectabent;
933 sname = cstring_from_COFF_symbol_name (
934 symtab_i->Name, strtab
937 oc->errMsg("Out of memory when copying PEi386 symbol");
941 /* for IMAGE_SYMCLASS_EXTERNAL
942 && !IMAGE_SYM_UNDEFINED,
943 the address of the symbol is:
944 address of relevant section + offset in section
946 sectabent = (COFF_section*)
947 myindex ( sizeof_COFF_section,
948 symtab_i->SectionNumber-1,
950 addr = ((UChar*)(oc->image))
951 + (sectabent->PointerToRawData
953 /* fprintf ( stderr, "addSymbol %p `%s'\n", addr,sname); */
954 if (!addSymbol(oc,sname,addr)) return FALSE;
956 i += symtab_i->NumberOfAuxSymbols;
960 oc->sections = stgMallocBytes( NumberOfSections * sizeof(Section),
961 "ocGetNamesPEi386" );
963 /* Copy section information into the ObjectCode. */
964 for (i = 0; i < hdr->NumberOfSections; i++) {
970 COFF_section* sectab_i
972 myindex ( sizeof_COFF_section, i, sectab );
973 /* fprintf ( stderr, "section name = %s\n", sectab_i->Name ); */
976 /* I'm sure this is the Right Way to do it. However, the
977 alternative of testing the sectab_i->Name field seems to
980 if (sectab_i->Characteristics & IMAGE_SCN_CNT_CODE ||
981 sectab_i->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
982 kind = SECTIONKIND_CODE_OR_RODATA;
985 if (0==strcmp(".text",sectab_i->Name))
986 kind = SECTIONKIND_CODE_OR_RODATA;
987 if (0==strcmp(".data",sectab_i->Name) ||
988 0==strcmp(".bss",sectab_i->Name))
989 kind = SECTIONKIND_RWDATA;
991 start = ((UChar*)(oc->image))
992 + sectab_i->PointerToRawData;
994 + sectab_i->SizeOfRawData - 1;
996 if (kind != SECTIONKIND_OTHER) {
997 addSection ( oc, start, end, kind );
999 fprintf ( stderr, "unknown section name = `%s'\n",
1001 oc->errMsg("Unknown PEi386 section name");
1011 ocResolve_PEi386 ( ObjectCode* oc, int verb )
1014 COFF_section* sectab;
1015 COFF_symbol* symtab;
1023 char symbol[1000]; // ToDo
1025 hdr = (COFF_header*)(oc->image);
1026 sectab = (COFF_section*) (
1027 ((UChar*)(oc->image))
1028 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1030 symtab = (COFF_symbol*) (
1031 ((UChar*)(oc->image))
1032 + hdr->PointerToSymbolTable
1034 strtab = ((UChar*)(oc->image))
1035 + hdr->PointerToSymbolTable
1036 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1038 for (i = 0; i < hdr->NumberOfSections; i++) {
1039 COFF_section* sectab_i
1041 myindex ( sizeof_COFF_section, i, sectab );
1044 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
1046 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1048 COFF_reloc* reltab_j
1050 myindex ( sizeof_COFF_reloc, j, reltab );
1052 /* the location to patch */
1054 ((UChar*)(oc->image))
1055 + (sectab_i->PointerToRawData
1056 + reltab_j->VirtualAddress)
1058 /* the existing contents of pP */
1060 /* the symbol to connect to */
1061 sym = (COFF_symbol*)
1062 myindex ( sizeof_COFF_symbol,
1063 reltab_j->SymbolTableIndex, symtab );
1066 "reloc sec %2d num %3d: type 0x%-4x "
1067 "vaddr 0x%-8x name `",
1069 (UInt32)reltab_j->Type,
1070 reltab_j->VirtualAddress );
1071 printName ( sym->Name, strtab );
1072 fprintf ( stderr, "'\n" );
1075 if (sym->StorageClass == IMAGE_SYM_CLASS_STATIC) {
1076 COFF_section* section_sym
1077 = findPEi386SectionCalled ( oc, sym->Name );
1079 fprintf ( stderr, "bad section = `%s'\n", sym->Name );
1080 oc->errMsg("Can't find abovementioned PEi386 section");
1083 S = ((UInt32)(oc->image))
1084 + (section_sym->PointerToRawData
1087 copyName ( sym->Name, strtab, symbol, 1000 );
1088 zapTrailingAtSign ( symbol );
1089 S = (UInt32) ocLookupSym ( oc, symbol );
1091 S = (UInt32)(oc->clientLookup ( symbol ));
1093 belch("%s: unresolvable reference to `%s'", oc->fileName, symbol);
1098 switch (reltab_j->Type) {
1099 case IMAGE_REL_I386_DIR32:
1102 case IMAGE_REL_I386_REL32:
1103 /* Tricky. We have to insert a displacement at
1104 pP which, when added to the PC for the _next_
1105 insn, gives the address of the target (S).
1106 Problem is to know the address of the next insn
1107 when we only know pP. We assume that this
1108 literal field is always the last in the insn,
1109 so that the address of the next insn is pP+4
1110 -- hence the constant 4.
1111 Also I don't know if A should be added, but so
1112 far it has always been zero.
1115 *pP = S - ((UInt32)pP) - 4;
1119 "unhandled PEi386 relocation type %d\n",
1121 oc->errMsg("unhandled PEi386 relocation type");
1131 #endif /* defined(OBJFORMAT_PEi386) */
1134 /* --------------------------------------------------------------------------
1136 * ------------------------------------------------------------------------*/
1138 #if defined(OBJFORMAT_ELF)
1143 #if defined(sparc_TARGET_ARCH)
1144 # define ELF_TARGET_SPARC /* Used inside <elf.h> */
1150 findElfSection ( void* objImage, Elf32_Word sh_type )
1153 char* ehdrC = (char*)objImage;
1154 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1155 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1157 for (i = 0; i < ehdr->e_shnum; i++) {
1158 if (shdr[i].sh_type == sh_type &&
1159 i != ehdr->e_shstrndx) {
1160 ptr = ehdrC + shdr[i].sh_offset;
1169 ocVerifyImage_ELF ( ObjectCode* oc )
1173 int i, j, nent, nstrtab, nsymtabs;
1177 char* ehdrC = (char*)(oc->image);
1178 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1180 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1181 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1182 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1183 ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1184 belch("ocVerifyImage_ELF: not an ELF header");
1187 IF_DEBUG(linker,belch( "Is an ELF header" ));
1189 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1190 belch("ocVerifyImage_ELF: not 32 bit ELF" );
1194 IF_DEBUG(linker,belch( "Is 32 bit ELF" ));
1196 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1197 IF_DEBUG(linker,belch( "Is little-endian" ));
1199 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1200 IF_DEBUG(linker,belch( "Is big-endian" ));
1202 belch("ocVerifyImage_ELF: unknown endiannness");
1206 if (ehdr->e_type != ET_REL) {
1207 belch("ocVerifyImage_ELF: not a relocatable object (.o) file");
1210 IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
1212 IF_DEBUG(linker,belch( "Architecture is " ));
1213 switch (ehdr->e_machine) {
1214 case EM_386: IF_DEBUG(linker,belch( "x86" )); break;
1215 case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
1216 default: IF_DEBUG(linker,belch( "unknown" ));
1217 belch("ocVerifyImage_ELF: unknown architecture");
1221 IF_DEBUG(linker,belch(
1222 "\nSection header table: start %d, n_entries %d, ent_size %d",
1223 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize ));
1225 ASSERT (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1227 shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1229 if (ehdr->e_shstrndx == SHN_UNDEF) {
1230 belch("ocVerifyImage_ELF: no section header string table");
1233 IF_DEBUG(linker,belch( "Section header string table is section %d",
1235 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1238 for (i = 0; i < ehdr->e_shnum; i++) {
1239 IF_DEBUG(linker,fprintf(stderr, "%2d: ", i ));
1240 IF_DEBUG(linker,fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type ));
1241 IF_DEBUG(linker,fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size ));
1242 IF_DEBUG(linker,fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset ));
1243 IF_DEBUG(linker,fprintf(stderr, " (%p .. %p) ",
1244 ehdrC + shdr[i].sh_offset,
1245 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
1247 if (shdr[i].sh_type == SHT_REL) {
1248 IF_DEBUG(linker,fprintf(stderr, "Rel " ));
1249 } else if (shdr[i].sh_type == SHT_RELA) {
1250 IF_DEBUG(linker,fprintf(stderr, "RelA " ));
1252 IF_DEBUG(linker,fprintf(stderr," "));
1255 IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
1259 IF_DEBUG(linker,belch( "\nString tables" ));
1262 for (i = 0; i < ehdr->e_shnum; i++) {
1263 if (shdr[i].sh_type == SHT_STRTAB &&
1264 i != ehdr->e_shstrndx) {
1265 IF_DEBUG(linker,belch(" section %d is a normal string table", i ));
1266 strtab = ehdrC + shdr[i].sh_offset;
1271 belch("ocVerifyImage_ELF: no string tables, or too many");
1276 IF_DEBUG(linker,belch( "\nSymbol tables" ));
1277 for (i = 0; i < ehdr->e_shnum; i++) {
1278 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1279 IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
1281 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1282 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1283 IF_DEBUG(linker,belch( " number of entries is apparently %d (%d rem)",
1285 shdr[i].sh_size % sizeof(Elf32_Sym)
1287 if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1288 belch("ocVerifyImage_ELF: non-integral number of symbol table entries");
1291 for (j = 0; j < nent; j++) {
1292 IF_DEBUG(linker,fprintf(stderr, " %2d ", j ));
1293 IF_DEBUG(linker,fprintf(stderr, " sec=%-5d size=%-3d val=%5p ",
1294 (int)stab[j].st_shndx,
1295 (int)stab[j].st_size,
1296 (char*)stab[j].st_value ));
1298 IF_DEBUG(linker,fprintf(stderr, "type=" ));
1299 switch (ELF32_ST_TYPE(stab[j].st_info)) {
1300 case STT_NOTYPE: IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
1301 case STT_OBJECT: IF_DEBUG(linker,fprintf(stderr, "object " )); break;
1302 case STT_FUNC : IF_DEBUG(linker,fprintf(stderr, "func " )); break;
1303 case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
1304 case STT_FILE: IF_DEBUG(linker,fprintf(stderr, "file " )); break;
1305 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1307 IF_DEBUG(linker,fprintf(stderr, " " ));
1309 IF_DEBUG(linker,fprintf(stderr, "bind=" ));
1310 switch (ELF32_ST_BIND(stab[j].st_info)) {
1311 case STB_LOCAL : IF_DEBUG(linker,fprintf(stderr, "local " )); break;
1312 case STB_GLOBAL: IF_DEBUG(linker,fprintf(stderr, "global" )); break;
1313 case STB_WEAK : IF_DEBUG(linker,fprintf(stderr, "weak " )); break;
1314 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1316 IF_DEBUG(linker,fprintf(stderr, " " ));
1318 IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
1322 if (nsymtabs == 0) {
1323 belch("ocVerifyImage_ELF: didn't find any symbol tables");
1332 ocGetNames_ELF ( ObjectCode* oc )
1337 char* ehdrC = (char*)(oc->image);
1338 Elf32_Ehdr* ehdr = (Elf32_Ehdr*)ehdrC;
1339 char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
1340 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1341 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1343 ASSERT(symhash != NULL);
1346 belch("ocGetNames_ELF: no strtab");
1351 oc->sections = stgMallocBytes( ehdr->e_shnum * sizeof(Section),
1353 oc->n_sections = ehdr->e_shnum;
1355 for (i = 0; i < ehdr->e_shnum; i++) {
1357 /* make a section entry for relevant sections */
1358 SectionKind kind = SECTIONKIND_OTHER;
1359 if (!strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1360 !strcmp(".data1",sh_strtab+shdr[i].sh_name))
1361 kind = SECTIONKIND_RWDATA;
1362 if (!strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1363 !strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1364 !strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1365 kind = SECTIONKIND_CODE_OR_RODATA;
1367 /* fill in the section info */
1368 oc->sections[i].start = ehdrC + shdr[i].sh_offset;
1369 oc->sections[i].end = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
1370 oc->sections[i].kind = kind;
1372 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1374 /* copy stuff into this module's object symbol table */
1375 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1376 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1377 oc->symbols = malloc(nent * sizeof(SymbolVal));
1378 oc->n_symbols = nent;
1379 for (j = 0; j < nent; j++) {
1380 if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
1381 || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
1383 /* and not an undefined symbol */
1384 && stab[j].st_shndx != SHN_UNDEF
1385 /* and not in a "special section" */
1386 && stab[j].st_shndx < SHN_LORESERVE
1388 /* and it's a not a section or string table or anything silly */
1389 ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1390 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
1391 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE
1394 char* nm = strtab + stab[j].st_name;
1396 + shdr[ stab[j].st_shndx ].sh_offset
1400 oc->symbols[j].lbl = nm;
1401 oc->symbols[j].addr = ad;
1402 if (ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL) {
1403 IF_DEBUG(linker,belch( "addOTabName(LOCL): %10p %s %s",
1404 ad, oc->fileName, nm ));
1405 insertStrHashTable(oc->lochash, nm, &(oc->symbols[j]));
1407 IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p %s %s",
1408 ad, oc->fileName, nm ));
1409 insertStrHashTable(symhash, nm, &(oc->symbols[j]));
1413 IF_DEBUG(linker,belch( "skipping `%s'",
1414 strtab + stab[j].st_name ));
1417 "skipping bind = %d, type = %d, shndx = %d `%s'\n",
1418 (int)ELF32_ST_BIND(stab[j].st_info),
1419 (int)ELF32_ST_TYPE(stab[j].st_info),
1420 (int)stab[j].st_shndx,
1421 strtab + stab[j].st_name
1424 oc->symbols[j].lbl = NULL;
1425 oc->symbols[j].addr = NULL;
1434 /* Do ELF relocations which lack an explicit addend. All x86-linux
1435 relocations appear to be of this form. */
1436 static int do_Elf32_Rel_relocations ( ObjectCode* oc, char* ehdrC,
1437 Elf32_Shdr* shdr, int shnum,
1438 Elf32_Sym* stab, char* strtab )
1443 Elf32_Rel* rtab = (Elf32_Rel*) (ehdrC + shdr[shnum].sh_offset);
1444 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rel);
1445 int target_shndx = shdr[shnum].sh_info;
1446 int symtab_shndx = shdr[shnum].sh_link;
1447 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1448 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1449 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1450 target_shndx, symtab_shndx ));
1451 for (j = 0; j < nent; j++) {
1452 Elf32_Addr offset = rtab[j].r_offset;
1453 Elf32_Word info = rtab[j].r_info;
1455 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1456 Elf32_Word* pP = (Elf32_Word*)P;
1460 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)",
1461 j, (void*)offset, (void*)info ));
1463 IF_DEBUG(linker,belch( " ZERO" ));
1466 /* First see if it is a nameless local symbol. */
1467 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1468 symbol = "(noname)";
1470 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1471 + stab[ELF32_R_SYM(info)].st_value);
1473 /* No? Should be in a symbol table then; first try the
1475 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1476 (void*)S = lookupLocalSymbol( oc, symbol );
1477 if ((void*)S == NULL)
1478 (void*)S = lookupSymbol( symbol );
1481 barf("do_Elf32_Rel_relocations: %s: unknown symbol `%s'",
1482 oc->fileName, symbol);
1484 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1486 IF_DEBUG(linker,belch( "Reloc: P = %p S = %p A = %p",
1487 (void*)P, (void*)S, (void*)A ));
1488 switch (ELF32_R_TYPE(info)) {
1489 #ifdef i386_TARGET_ARCH
1490 case R_386_32: *pP = S + A; break;
1491 case R_386_PC32: *pP = S + A - P; break;
1494 barf("do_Elf32_Rel_relocations: unhandled ELF relocation(Rel) type %d\n", ELF32_R_TYPE(info));
1503 /* Do ELF relocations for which explicit addends are supplied.
1504 sparc-solaris relocations appear to be of this form. */
1505 static int do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
1506 Elf32_Shdr* shdr, int shnum,
1507 Elf32_Sym* stab, char* strtab )
1512 Elf32_Rela* rtab = (Elf32_Rela*) (ehdrC + shdr[shnum].sh_offset);
1513 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rela);
1514 int target_shndx = shdr[shnum].sh_info;
1515 int symtab_shndx = shdr[shnum].sh_link;
1516 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1517 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1518 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1519 target_shndx, symtab_shndx ));
1520 for (j = 0; j < nent; j++) {
1521 Elf32_Addr offset = rtab[j].r_offset;
1522 Elf32_Word info = rtab[j].r_info;
1523 Elf32_Sword addend = rtab[j].r_addend;
1525 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1526 Elf32_Addr A = addend;
1528 # if defined(sparc_TARGET_ARCH)
1529 /* This #ifdef only serves to avoid unused-var warnings. */
1530 Elf32_Word* pP = (Elf32_Word*)P;
1534 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ",
1535 j, (void*)offset, (void*)info,
1538 IF_DEBUG(linker,belch( " ZERO" ));
1541 /* First see if it is a nameless local symbol. */
1542 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1543 symbol = "(noname)";
1545 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1546 + stab[ELF32_R_SYM(info)].st_value);
1548 /* No? Should be in a symbol table then; first try the
1550 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1551 (void*)S = lookupLocalSymbol( oc, symbol );
1552 if ((void*)S == NULL)
1553 (void*)S = lookupSymbol( symbol );
1556 barf("ocResolve_ELF: %s: unknown symbol `%s'",
1557 oc->fileName, symbol);
1560 fprintf ( stderr, "S %p A %p S+A %p S+A-P %p\n",S,A,S+A,S+A-P);
1563 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1565 IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n",
1566 (void*)P, (void*)S, (void*)A ));
1567 switch (ELF32_R_TYPE(info)) {
1568 # if defined(sparc_TARGET_ARCH)
1569 case R_SPARC_WDISP30:
1570 w1 = *pP & 0xC0000000;
1571 w2 = (Elf32_Word)((S + A - P) >> 2);
1572 ASSERT((w2 & 0xC0000000) == 0);
1577 w1 = *pP & 0xFFC00000;
1578 w2 = (Elf32_Word)((S + A) >> 10);
1579 ASSERT((w2 & 0xFFC00000) == 0);
1585 w2 = (Elf32_Word)((S + A) & 0x3FF);
1586 ASSERT((w2 & ~0x3FF) == 0);
1591 w2 = (Elf32_Word)(S + A);
1596 fprintf(stderr, "unhandled ELF relocation(RelA) type %d\n",
1597 ELF32_R_TYPE(info));
1598 barf("do_Elf32_Rela_relocations: unhandled ELF relocation type");
1608 ocResolve_ELF ( ObjectCode* oc )
1612 Elf32_Sym* stab = NULL;
1613 char* ehdrC = (char*)(oc->image);
1614 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1615 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1617 /* first find "the" symbol table */
1618 stab = (Elf32_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
1620 /* also go find the string table */
1621 strtab = findElfSection ( ehdrC, SHT_STRTAB );
1623 if (stab == NULL || strtab == NULL) {
1624 belch("ocResolve_ELF: can't find string or symbol table");
1628 /* Process the relocation sections. */
1629 for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
1630 if (shdr[shnum].sh_type == SHT_REL ) {
1631 ok = do_Elf32_Rel_relocations ( oc, ehdrC, shdr,
1632 shnum, stab, strtab );
1636 if (shdr[shnum].sh_type == SHT_RELA) {
1637 ok = do_Elf32_Rela_relocations ( oc, ehdrC, shdr,
1638 shnum, stab, strtab );
1643 /* Free the local symbol table; we won't need it again. */
1644 freeHashTable(oc->lochash, NULL);