1 /* -----------------------------------------------------------------------------
2 * $Id: Linker.c,v 1.31 2001/02/14 13:56:50 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) \
108 SymX(tryPutMVarzh_fast) \
114 SymX(killThreadzh_fast) \
115 SymX(waitReadzh_fast) \
116 SymX(waitWritezh_fast) \
117 SymX(suspendThread) \
119 SymX(stackOverflow) \
120 SymX(int2Integerzh_fast) \
121 SymX(word2Integerzh_fast) \
122 SymX(mkForeignObjzh_fast) \
123 SymX(__encodeDouble) \
124 SymX(decodeDoublezh_fast) \
125 SymX(decodeFloatzh_fast) \
126 SymX(gcdIntegerzh_fast) \
127 SymX(newArrayzh_fast) \
128 SymX(unsafeThawArrayzh_fast) \
129 SymX(newByteArrayzh_fast) \
130 SymX(newMutVarzh_fast) \
131 SymX(quotRemIntegerzh_fast) \
132 SymX(quotIntegerzh_fast) \
133 SymX(remIntegerzh_fast) \
134 SymX(divExactIntegerzh_fast) \
135 SymX(divModIntegerzh_fast) \
136 SymX(timesIntegerzh_fast) \
137 SymX(minusIntegerzh_fast) \
138 SymX(plusIntegerzh_fast) \
139 SymX(andIntegerzh_fast) \
140 SymX(orIntegerzh_fast) \
141 SymX(xorIntegerzh_fast) \
142 SymX(complementIntegerzh_fast) \
143 SymX(mkWeakzh_fast) \
144 SymX(makeStableNamezh_fast) \
145 SymX(finalizzeWeakzh_fast) \
146 SymX(blockAsyncExceptionszh_fast) \
147 SymX(unblockAsyncExceptionszh_fast) \
149 SymX(isDoubleInfinite) \
150 SymX(isDoubleDenormalized) \
151 SymX(isDoubleNegativeZero) \
152 SymX(__encodeFloat) \
154 SymX(isFloatInfinite) \
155 SymX(isFloatDenormalized) \
156 SymX(isFloatNegativeZero) \
157 SymX(__int_encodeFloat) \
158 SymX(__int_encodeDouble) \
159 SymX(__gmpz_cmp_si) \
160 SymX(__gmpz_cmp_ui) \
165 SymX(resetNonBlockingFd) \
167 SymX(stable_ptr_table) \
168 SymX(shutdownHaskellAndExit) \
169 Sym(stg_enterStackTop) \
170 Sym(stg_yield_to_interpreter) \
174 Sym(__init_PrelGHC) \
175 SymX(freeHaskellFunctionPtr) \
178 SymX(NoRunnableThreadsHook) \
179 SymX(StackOverflowHook) \
180 SymX(OutOfHeapHook) \
181 SymX(MallocFailHook) \
182 SymX(PatErrorHdrHook) \
185 SymX(PostTraceHook) \
186 SymX(stg_sig_install) \
188 SymX(createAdjustor) \
190 SymX(rts_mkStablePtr) \
193 SymX(rts_checkSchedStatus) \
196 #ifndef SUPPORT_LONG_LONGS
197 #define RTS_LONG_LONG_SYMS /* nothing */
199 #define RTS_LONG_LONG_SYMS \
212 SymX(stg_remWord64) \
213 SymX(stg_quotWord64) \
215 SymX(stg_quotInt64) \
216 SymX(stg_negateInt64) \
217 SymX(stg_plusInt64) \
218 SymX(stg_minusInt64) \
219 SymX(stg_timesInt64) \
225 SymX(stg_shiftRL64) \
226 SymX(stg_iShiftL64) \
227 SymX(stg_iShiftRL64) \
228 SymX(stg_iShiftRA64) \
229 SymX(stg_intToInt64) \
230 SymX(stg_int64ToInt) \
231 SymX(stg_int64ToWord64) \
232 SymX(stg_wordToWord64) \
233 SymX(stg_word64ToWord) \
234 SymX(stg_word64ToInt64) \
235 SymX(int64ToIntegerzh_fast) \
236 SymX(word64ToIntegerzh_fast)
237 #endif /* SUPPORT_LONG_LONGS */
239 /* entirely bogus claims about types of these symbols */
240 #define Sym(vvv) extern void (vvv);
241 #define SymX(vvv) /**/
246 #ifdef LEADING_UNDERSCORE
247 #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
249 #define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
252 #define Sym(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
254 #define SymX(vvv) Sym(vvv)
256 static SymbolVal rtsSyms[] = {
259 { 0, 0 } /* sentinel */
262 /* -----------------------------------------------------------------------------
263 * initialize the object linker
265 static void *dl_prog_handle;
272 symhash = allocStrHashTable();
274 /* populate the symbol table with stuff from the RTS */
275 for (sym = rtsSyms; sym->lbl != NULL; sym++) {
276 insertStrHashTable(symhash, sym->lbl, sym);
279 dl_prog_handle = dlopen(NULL, RTLD_LAZY);
282 /* -----------------------------------------------------------------------------
283 * Add a DLL from which symbols may be found. In the ELF case, just
284 * do RTLD_GLOBAL-style add, so no further messing around needs to
285 * happen in order that symbols in the loaded .so are findable --
286 * lookupSymbol() will subsequently see them by dlsym on the program's
287 * dl-handle. Returns 0 if fail, 1 if success.
290 addDLL ( char* dll_name )
292 # if defined(OBJFORMAT_ELF)
297 buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
298 sprintf(buf, "lib%s.so", dll_name);
299 hdl = dlopen(buf, RTLD_NOW | RTLD_GLOBAL );
302 /* dlopen failed; return a ptr to the error msg. */
304 if (errmsg == NULL) errmsg = "addDLL: unknown error";
309 ASSERT(0); /*NOTREACHED*/
310 # elif defined(OBJFORMAT_PEi386)
311 barf("addDLL: not implemented on PEi386 yet");
314 barf("addDLL: not implemented on this platform");
318 /* -----------------------------------------------------------------------------
319 * lookup a symbol in the hash table
322 lookupSymbol( char *lbl )
325 ASSERT(symhash != NULL);
326 val = lookupStrHashTable(symhash, lbl);
329 return dlsym(dl_prog_handle, lbl);
337 lookupLocalSymbol( ObjectCode* oc, char *lbl )
340 val = lookupStrHashTable(oc->lochash, lbl);
350 /* -----------------------------------------------------------------------------
351 * Load an obj (populate the global symbol table, but don't resolve yet)
353 * Returns: 1 if ok, 0 on error.
356 loadObj( char *path )
364 /* assert that we haven't already loaded this object */
367 for (o = objects; o; o = o->next)
368 ASSERT(strcmp(o->fileName, path));
372 oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
374 # if defined(OBJFORMAT_ELF)
375 oc->formatName = "ELF";
376 # elif defined(OBJFORMAT_PEi386)
377 oc->formatName = "PEi386";
380 barf("loadObj: not implemented on this platform");
384 if (r == -1) { return 0; }
386 /* sigh, strdup() isn't a POSIX function, so do it the long way */
387 oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
388 strcpy(oc->fileName, path);
390 oc->fileSize = st.st_size;
391 oc->image = stgMallocBytes( st.st_size, "loadObj(image)" );
394 oc->lochash = allocStrHashTable();
396 /* chain it onto the list of objects */
400 /* load the image into memory */
401 f = fopen(path, "rb");
403 barf("loadObj: can't read `%s'", path);
405 n = fread ( oc->image, 1, oc->fileSize, f );
406 if (n != oc->fileSize) {
408 barf("loadObj: error whilst reading `%s'", path);
411 /* verify the in-memory image */
412 # if defined(OBJFORMAT_ELF)
413 r = ocVerifyImage_ELF ( oc );
414 # elif defined(OBJFORMAT_PEi386)
415 r = ocVerifyImage_PEi386 ( oc );
417 barf("loadObj: no verify method");
419 if (!r) { return r; }
421 /* build the symbol list for this image */
422 # if defined(OBJFORMAT_ELF)
423 r = ocGetNames_ELF ( oc );
424 # elif defined(OBJFORMAT_PEi386)
425 r = ocGetNames_PEi386 ( oc );
427 barf("loadObj: no getNames method");
429 if (!r) { return r; }
431 /* loaded, but not resolved yet */
432 oc->status = OBJECT_LOADED;
437 /* -----------------------------------------------------------------------------
438 * resolve all the currently unlinked objects in memory
440 * Returns: 1 if ok, 0 on error.
448 for (oc = objects; oc; oc = oc->next) {
449 if (oc->status != OBJECT_RESOLVED) {
450 # if defined(OBJFORMAT_ELF)
451 r = ocResolve_ELF ( oc );
452 # elif defined(OBJFORMAT_PEi386)
453 r = ocResolve_PEi386 ( oc );
455 barf("link: not implemented on this platform");
457 if (!r) { return r; }
458 oc->status = OBJECT_RESOLVED;
464 /* -----------------------------------------------------------------------------
465 * delete an object from the pool
468 unloadObj( char *path )
470 ObjectCode *oc, *prev;
472 ASSERT(symhash != NULL);
473 ASSERT(objects != NULL);
476 for (oc = objects; oc; prev = oc, oc = oc->next) {
477 if (!strcmp(oc->fileName,path)) {
479 /* Remove all the mappings for the symbols within this
484 for (s = oc->symbols; s < oc->symbols + oc->n_symbols; s++) {
485 if (s->lbl != NULL) {
486 removeStrHashTable(symhash, s->lbl, NULL);
494 prev->next = oc->next;
497 /* We're going to leave this in place, in case there are
498 any pointers from the heap into it: */
499 /* free(oc->image); */
503 /* The local hash table should have been freed at the end
504 of the ocResolve_ call on it. */
505 ASSERT(oc->lochash == NULL);
511 belch("unloadObj: can't find `%s' to unload", path);
515 /* --------------------------------------------------------------------------
516 * PEi386 specifics (Win32 targets)
517 * ------------------------------------------------------------------------*/
519 /* The information for this linker comes from
520 Microsoft Portable Executable
521 and Common Object File Format Specification
522 revision 5.1 January 1998
523 which SimonM says comes from the MS Developer Network CDs.
527 #if defined(OBJFORMAT_PEi386)
531 typedef unsigned char UChar;
532 typedef unsigned short UInt16;
533 typedef unsigned int UInt32;
540 UInt16 NumberOfSections;
541 UInt32 TimeDateStamp;
542 UInt32 PointerToSymbolTable;
543 UInt32 NumberOfSymbols;
544 UInt16 SizeOfOptionalHeader;
545 UInt16 Characteristics;
549 #define sizeof_COFF_header 20
556 UInt32 VirtualAddress;
557 UInt32 SizeOfRawData;
558 UInt32 PointerToRawData;
559 UInt32 PointerToRelocations;
560 UInt32 PointerToLinenumbers;
561 UInt16 NumberOfRelocations;
562 UInt16 NumberOfLineNumbers;
563 UInt32 Characteristics;
567 #define sizeof_COFF_section 40
574 UInt16 SectionNumber;
577 UChar NumberOfAuxSymbols;
581 #define sizeof_COFF_symbol 18
586 UInt32 VirtualAddress;
587 UInt32 SymbolTableIndex;
592 #define sizeof_COFF_reloc 10
595 /* From PE spec doc, section 3.3.2 */
596 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001
597 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
598 #define IMAGE_FILE_DLL 0x2000
599 #define IMAGE_FILE_SYSTEM 0x1000
600 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
601 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
602 #define IMAGE_FILE_32BIT_MACHINE 0x0100
604 /* From PE spec doc, section 5.4.2 and 5.4.4 */
605 #define IMAGE_SYM_CLASS_EXTERNAL 2
606 #define IMAGE_SYM_CLASS_STATIC 3
607 #define IMAGE_SYM_UNDEFINED 0
609 /* From PE spec doc, section 4.1 */
610 #define IMAGE_SCN_CNT_CODE 0x00000020
611 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
613 /* From PE spec doc, section 5.2.1 */
614 #define IMAGE_REL_I386_DIR32 0x0006
615 #define IMAGE_REL_I386_REL32 0x0014
618 /* We use myindex to calculate array addresses, rather than
619 simply doing the normal subscript thing. That's because
620 some of the above structs have sizes which are not
621 a whole number of words. GCC rounds their sizes up to a
622 whole number of words, which means that the address calcs
623 arising from using normal C indexing or pointer arithmetic
624 are just plain wrong. Sigh.
627 myindex ( int scale, int index, void* base )
630 ((UChar*)base) + scale * index;
635 printName ( UChar* name, UChar* strtab )
637 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
638 UInt32 strtab_offset = * (UInt32*)(name+4);
639 fprintf ( stderr, "%s", strtab + strtab_offset );
642 for (i = 0; i < 8; i++) {
643 if (name[i] == 0) break;
644 fprintf ( stderr, "%c", name[i] );
651 copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
653 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
654 UInt32 strtab_offset = * (UInt32*)(name+4);
655 strncpy ( dst, strtab+strtab_offset, dstSize );
661 if (name[i] == 0) break;
671 cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
674 /* If the string is longer than 8 bytes, look in the
675 string table for it -- this will be correctly zero terminated.
677 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
678 UInt32 strtab_offset = * (UInt32*)(name+4);
679 return ((UChar*)strtab) + strtab_offset;
681 /* Otherwise, if shorter than 8 bytes, return the original,
682 which by defn is correctly terminated.
684 if (name[7]==0) return name;
685 /* The annoying case: 8 bytes. Copy into a temporary
686 (which is never freed ...)
690 strncpy(newstr,name,8);
697 /* Just compares the short names (first 8 chars) */
698 static COFF_section *
699 findPEi386SectionCalled ( ObjectCode* oc, char* name )
703 = (COFF_header*)(oc->image);
706 ((UChar*)(oc->image))
707 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
709 for (i = 0; i < hdr->NumberOfSections; i++) {
712 COFF_section* section_i
714 myindex ( sizeof_COFF_section, i, sectab );
715 n1 = (UChar*) &(section_i->Name);
717 if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] &&
718 n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] &&
719 n1[6]==n2[6] && n1[7]==n2[7])
728 zapTrailingAtSign ( UChar* sym )
731 if (sym[0] == 0) return;
733 while (sym[i] != 0) i++;
736 while (j > 0 && isdigit(sym[j])) j--;
737 if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
742 ocVerifyImage_PEi386 ( ObjectCode* oc )
746 COFF_section* sectab;
750 hdr = (COFF_header*)(oc->image);
751 sectab = (COFF_section*) (
752 ((UChar*)(oc->image))
753 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
755 symtab = (COFF_symbol*) (
756 ((UChar*)(oc->image))
757 + hdr->PointerToSymbolTable
759 strtab = ((UChar*)(oc->image))
760 + hdr->PointerToSymbolTable
761 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
763 if (hdr->Machine != 0x14c) {
764 oc->errMsg("Not x86 PEi386");
767 if (hdr->SizeOfOptionalHeader != 0) {
768 oc->errMsg("PEi386 with nonempty optional header");
771 if ( /* (hdr->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) || */
772 (hdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ||
773 (hdr->Characteristics & IMAGE_FILE_DLL) ||
774 (hdr->Characteristics & IMAGE_FILE_SYSTEM) ) {
775 oc->errMsg("Not a PEi386 object file");
778 if ( (hdr->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI) ||
779 !(hdr->Characteristics & IMAGE_FILE_32BIT_MACHINE) ) {
780 oc->errMsg("Invalid PEi386 word size or endiannness");
784 if (!verb) return TRUE;
785 /* No further verification after this point; only debug printing. */
788 "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
790 "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
792 "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
794 fprintf ( stderr, "\n" );
796 "Machine: 0x%x\n", (UInt32)(hdr->Machine) );
798 "# sections: %d\n", (UInt32)(hdr->NumberOfSections) );
800 "time/date: 0x%x\n", (UInt32)(hdr->TimeDateStamp) );
802 "symtab offset: %d\n", (UInt32)(hdr->PointerToSymbolTable) );
804 "# symbols: %d\n", (UInt32)(hdr->NumberOfSymbols) );
806 "sz of opt hdr: %d\n", (UInt32)(hdr->SizeOfOptionalHeader) );
808 "characteristics: 0x%x\n", (UInt32)(hdr->Characteristics) );
810 fprintf ( stderr, "\n" );
811 fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
812 fprintf ( stderr, "---START of string table---\n");
813 for (i = 4; i < *(UInt32*)strtab; i++) {
815 fprintf ( stderr, "\n"); else
816 fprintf( stderr, "%c", strtab[i] );
818 fprintf ( stderr, "--- END of string table---\n");
820 fprintf ( stderr, "\n" );
821 for (i = 0; i < hdr->NumberOfSections; i++) {
823 COFF_section* sectab_i
825 myindex ( sizeof_COFF_section, i, sectab );
832 printName ( sectab_i->Name, strtab );
841 sectab_i->VirtualSize,
842 sectab_i->VirtualAddress,
843 sectab_i->SizeOfRawData,
844 sectab_i->PointerToRawData,
845 sectab_i->NumberOfRelocations,
846 sectab_i->PointerToRelocations
848 reltab = (COFF_reloc*) (
849 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
851 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
853 COFF_reloc* rel = (COFF_reloc*)
854 myindex ( sizeof_COFF_reloc, j, reltab );
856 " type 0x%-4x vaddr 0x%-8x name `",
858 rel->VirtualAddress );
860 myindex ( sizeof_COFF_symbol, rel->SymbolTableIndex, symtab );
861 printName ( sym->Name, strtab );
862 fprintf ( stderr, "'\n" );
864 fprintf ( stderr, "\n" );
868 fprintf ( stderr, "\n" );
871 COFF_symbol* symtab_i;
872 if (i >= hdr->NumberOfSymbols) break;
873 symtab_i = (COFF_symbol*)
874 myindex ( sizeof_COFF_symbol, i, symtab );
880 printName ( symtab_i->Name, strtab );
889 (Int32)(symtab_i->SectionNumber) - 1,
890 (UInt32)symtab_i->Type,
891 (UInt32)symtab_i->StorageClass,
892 (UInt32)symtab_i->NumberOfAuxSymbols
894 i += symtab_i->NumberOfAuxSymbols;
898 fprintf ( stderr, "\n" );
905 ocGetNames_PEi386 ( ObjectCode* oc )
908 COFF_section* sectab;
916 hdr = (COFF_header*)(oc->image);
917 sectab = (COFF_section*) (
918 ((UChar*)(oc->image))
919 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
921 symtab = (COFF_symbol*) (
922 ((UChar*)(oc->image))
923 + hdr->PointerToSymbolTable
925 strtab = ((UChar*)(oc->image))
926 + hdr->PointerToSymbolTable
927 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
929 /* Copy exported symbols into the ObjectCode. */
932 COFF_symbol* symtab_i;
933 if (i >= hdr->NumberOfSymbols) break;
934 symtab_i = (COFF_symbol*)
935 myindex ( sizeof_COFF_symbol, i, symtab );
937 if (symtab_i->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
938 symtab_i->SectionNumber != IMAGE_SYM_UNDEFINED) {
940 /* This symbol is global and defined, viz, exported */
941 COFF_section* sectabent;
943 sname = cstring_from_COFF_symbol_name (
944 symtab_i->Name, strtab
947 oc->errMsg("Out of memory when copying PEi386 symbol");
951 /* for IMAGE_SYMCLASS_EXTERNAL
952 && !IMAGE_SYM_UNDEFINED,
953 the address of the symbol is:
954 address of relevant section + offset in section
956 sectabent = (COFF_section*)
957 myindex ( sizeof_COFF_section,
958 symtab_i->SectionNumber-1,
960 addr = ((UChar*)(oc->image))
961 + (sectabent->PointerToRawData
963 /* fprintf ( stderr, "addSymbol %p `%s'\n", addr,sname); */
964 if (!addSymbol(oc,sname,addr)) return FALSE;
966 i += symtab_i->NumberOfAuxSymbols;
970 oc->sections = stgMallocBytes( NumberOfSections * sizeof(Section),
971 "ocGetNamesPEi386" );
973 /* Copy section information into the ObjectCode. */
974 for (i = 0; i < hdr->NumberOfSections; i++) {
980 COFF_section* sectab_i
982 myindex ( sizeof_COFF_section, i, sectab );
983 /* fprintf ( stderr, "section name = %s\n", sectab_i->Name ); */
986 /* I'm sure this is the Right Way to do it. However, the
987 alternative of testing the sectab_i->Name field seems to
990 if (sectab_i->Characteristics & IMAGE_SCN_CNT_CODE ||
991 sectab_i->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
992 kind = SECTIONKIND_CODE_OR_RODATA;
995 if (0==strcmp(".text",sectab_i->Name))
996 kind = SECTIONKIND_CODE_OR_RODATA;
997 if (0==strcmp(".data",sectab_i->Name) ||
998 0==strcmp(".bss",sectab_i->Name))
999 kind = SECTIONKIND_RWDATA;
1001 start = ((UChar*)(oc->image))
1002 + sectab_i->PointerToRawData;
1004 + sectab_i->SizeOfRawData - 1;
1006 if (kind != SECTIONKIND_OTHER) {
1007 addSection ( oc, start, end, kind );
1009 fprintf ( stderr, "unknown section name = `%s'\n",
1011 oc->errMsg("Unknown PEi386 section name");
1021 ocResolve_PEi386 ( ObjectCode* oc, int verb )
1024 COFF_section* sectab;
1025 COFF_symbol* symtab;
1033 char symbol[1000]; // ToDo
1035 hdr = (COFF_header*)(oc->image);
1036 sectab = (COFF_section*) (
1037 ((UChar*)(oc->image))
1038 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1040 symtab = (COFF_symbol*) (
1041 ((UChar*)(oc->image))
1042 + hdr->PointerToSymbolTable
1044 strtab = ((UChar*)(oc->image))
1045 + hdr->PointerToSymbolTable
1046 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1048 for (i = 0; i < hdr->NumberOfSections; i++) {
1049 COFF_section* sectab_i
1051 myindex ( sizeof_COFF_section, i, sectab );
1054 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
1056 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1058 COFF_reloc* reltab_j
1060 myindex ( sizeof_COFF_reloc, j, reltab );
1062 /* the location to patch */
1064 ((UChar*)(oc->image))
1065 + (sectab_i->PointerToRawData
1066 + reltab_j->VirtualAddress)
1068 /* the existing contents of pP */
1070 /* the symbol to connect to */
1071 sym = (COFF_symbol*)
1072 myindex ( sizeof_COFF_symbol,
1073 reltab_j->SymbolTableIndex, symtab );
1076 "reloc sec %2d num %3d: type 0x%-4x "
1077 "vaddr 0x%-8x name `",
1079 (UInt32)reltab_j->Type,
1080 reltab_j->VirtualAddress );
1081 printName ( sym->Name, strtab );
1082 fprintf ( stderr, "'\n" );
1085 if (sym->StorageClass == IMAGE_SYM_CLASS_STATIC) {
1086 COFF_section* section_sym
1087 = findPEi386SectionCalled ( oc, sym->Name );
1089 fprintf ( stderr, "bad section = `%s'\n", sym->Name );
1090 oc->errMsg("Can't find abovementioned PEi386 section");
1093 S = ((UInt32)(oc->image))
1094 + (section_sym->PointerToRawData
1097 copyName ( sym->Name, strtab, symbol, 1000 );
1098 zapTrailingAtSign ( symbol );
1099 S = (UInt32) ocLookupSym ( oc, symbol );
1101 S = (UInt32)(oc->clientLookup ( symbol ));
1103 belch("%s: unresolvable reference to `%s'", oc->fileName, symbol);
1108 switch (reltab_j->Type) {
1109 case IMAGE_REL_I386_DIR32:
1112 case IMAGE_REL_I386_REL32:
1113 /* Tricky. We have to insert a displacement at
1114 pP which, when added to the PC for the _next_
1115 insn, gives the address of the target (S).
1116 Problem is to know the address of the next insn
1117 when we only know pP. We assume that this
1118 literal field is always the last in the insn,
1119 so that the address of the next insn is pP+4
1120 -- hence the constant 4.
1121 Also I don't know if A should be added, but so
1122 far it has always been zero.
1125 *pP = S - ((UInt32)pP) - 4;
1129 "unhandled PEi386 relocation type %d\n",
1131 oc->errMsg("unhandled PEi386 relocation type");
1141 #endif /* defined(OBJFORMAT_PEi386) */
1144 /* --------------------------------------------------------------------------
1146 * ------------------------------------------------------------------------*/
1148 #if defined(OBJFORMAT_ELF)
1153 #if defined(sparc_TARGET_ARCH)
1154 # define ELF_TARGET_SPARC /* Used inside <elf.h> */
1160 findElfSection ( void* objImage, Elf32_Word sh_type )
1163 char* ehdrC = (char*)objImage;
1164 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1165 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1167 for (i = 0; i < ehdr->e_shnum; i++) {
1168 if (shdr[i].sh_type == sh_type &&
1169 i != ehdr->e_shstrndx) {
1170 ptr = ehdrC + shdr[i].sh_offset;
1179 ocVerifyImage_ELF ( ObjectCode* oc )
1183 int i, j, nent, nstrtab, nsymtabs;
1187 char* ehdrC = (char*)(oc->image);
1188 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1190 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1191 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1192 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1193 ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1194 belch("ocVerifyImage_ELF: not an ELF header");
1197 IF_DEBUG(linker,belch( "Is an ELF header" ));
1199 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1200 belch("ocVerifyImage_ELF: not 32 bit ELF" );
1204 IF_DEBUG(linker,belch( "Is 32 bit ELF" ));
1206 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1207 IF_DEBUG(linker,belch( "Is little-endian" ));
1209 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1210 IF_DEBUG(linker,belch( "Is big-endian" ));
1212 belch("ocVerifyImage_ELF: unknown endiannness");
1216 if (ehdr->e_type != ET_REL) {
1217 belch("ocVerifyImage_ELF: not a relocatable object (.o) file");
1220 IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
1222 IF_DEBUG(linker,belch( "Architecture is " ));
1223 switch (ehdr->e_machine) {
1224 case EM_386: IF_DEBUG(linker,belch( "x86" )); break;
1225 case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
1226 default: IF_DEBUG(linker,belch( "unknown" ));
1227 belch("ocVerifyImage_ELF: unknown architecture");
1231 IF_DEBUG(linker,belch(
1232 "\nSection header table: start %d, n_entries %d, ent_size %d",
1233 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize ));
1235 ASSERT (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1237 shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1239 if (ehdr->e_shstrndx == SHN_UNDEF) {
1240 belch("ocVerifyImage_ELF: no section header string table");
1243 IF_DEBUG(linker,belch( "Section header string table is section %d",
1245 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1248 for (i = 0; i < ehdr->e_shnum; i++) {
1249 IF_DEBUG(linker,fprintf(stderr, "%2d: ", i ));
1250 IF_DEBUG(linker,fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type ));
1251 IF_DEBUG(linker,fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size ));
1252 IF_DEBUG(linker,fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset ));
1253 IF_DEBUG(linker,fprintf(stderr, " (%p .. %p) ",
1254 ehdrC + shdr[i].sh_offset,
1255 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
1257 if (shdr[i].sh_type == SHT_REL) {
1258 IF_DEBUG(linker,fprintf(stderr, "Rel " ));
1259 } else if (shdr[i].sh_type == SHT_RELA) {
1260 IF_DEBUG(linker,fprintf(stderr, "RelA " ));
1262 IF_DEBUG(linker,fprintf(stderr," "));
1265 IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
1269 IF_DEBUG(linker,belch( "\nString tables" ));
1272 for (i = 0; i < ehdr->e_shnum; i++) {
1273 if (shdr[i].sh_type == SHT_STRTAB &&
1274 i != ehdr->e_shstrndx) {
1275 IF_DEBUG(linker,belch(" section %d is a normal string table", i ));
1276 strtab = ehdrC + shdr[i].sh_offset;
1281 belch("ocVerifyImage_ELF: no string tables, or too many");
1286 IF_DEBUG(linker,belch( "\nSymbol tables" ));
1287 for (i = 0; i < ehdr->e_shnum; i++) {
1288 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1289 IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
1291 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1292 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1293 IF_DEBUG(linker,belch( " number of entries is apparently %d (%d rem)",
1295 shdr[i].sh_size % sizeof(Elf32_Sym)
1297 if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1298 belch("ocVerifyImage_ELF: non-integral number of symbol table entries");
1301 for (j = 0; j < nent; j++) {
1302 IF_DEBUG(linker,fprintf(stderr, " %2d ", j ));
1303 IF_DEBUG(linker,fprintf(stderr, " sec=%-5d size=%-3d val=%5p ",
1304 (int)stab[j].st_shndx,
1305 (int)stab[j].st_size,
1306 (char*)stab[j].st_value ));
1308 IF_DEBUG(linker,fprintf(stderr, "type=" ));
1309 switch (ELF32_ST_TYPE(stab[j].st_info)) {
1310 case STT_NOTYPE: IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
1311 case STT_OBJECT: IF_DEBUG(linker,fprintf(stderr, "object " )); break;
1312 case STT_FUNC : IF_DEBUG(linker,fprintf(stderr, "func " )); break;
1313 case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
1314 case STT_FILE: IF_DEBUG(linker,fprintf(stderr, "file " )); break;
1315 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1317 IF_DEBUG(linker,fprintf(stderr, " " ));
1319 IF_DEBUG(linker,fprintf(stderr, "bind=" ));
1320 switch (ELF32_ST_BIND(stab[j].st_info)) {
1321 case STB_LOCAL : IF_DEBUG(linker,fprintf(stderr, "local " )); break;
1322 case STB_GLOBAL: IF_DEBUG(linker,fprintf(stderr, "global" )); break;
1323 case STB_WEAK : IF_DEBUG(linker,fprintf(stderr, "weak " )); break;
1324 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1326 IF_DEBUG(linker,fprintf(stderr, " " ));
1328 IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
1332 if (nsymtabs == 0) {
1333 belch("ocVerifyImage_ELF: didn't find any symbol tables");
1342 ocGetNames_ELF ( ObjectCode* oc )
1347 char* ehdrC = (char*)(oc->image);
1348 Elf32_Ehdr* ehdr = (Elf32_Ehdr*)ehdrC;
1349 char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
1350 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1351 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1353 ASSERT(symhash != NULL);
1356 belch("ocGetNames_ELF: no strtab");
1361 oc->sections = stgMallocBytes( ehdr->e_shnum * sizeof(Section),
1363 oc->n_sections = ehdr->e_shnum;
1365 for (i = 0; i < ehdr->e_shnum; i++) {
1367 /* make a section entry for relevant sections */
1368 SectionKind kind = SECTIONKIND_OTHER;
1369 if (!strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1370 !strcmp(".data1",sh_strtab+shdr[i].sh_name))
1371 kind = SECTIONKIND_RWDATA;
1372 if (!strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1373 !strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1374 !strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1375 kind = SECTIONKIND_CODE_OR_RODATA;
1377 /* fill in the section info */
1378 oc->sections[i].start = ehdrC + shdr[i].sh_offset;
1379 oc->sections[i].end = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
1380 oc->sections[i].kind = kind;
1382 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1384 /* copy stuff into this module's object symbol table */
1385 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1386 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1387 oc->symbols = malloc(nent * sizeof(SymbolVal));
1388 oc->n_symbols = nent;
1389 for (j = 0; j < nent; j++) {
1390 if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
1391 || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
1393 /* and not an undefined symbol */
1394 && stab[j].st_shndx != SHN_UNDEF
1395 /* and not in a "special section" */
1396 && stab[j].st_shndx < SHN_LORESERVE
1398 /* and it's a not a section or string table or anything silly */
1399 ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1400 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
1401 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE
1404 char* nm = strtab + stab[j].st_name;
1406 + shdr[ stab[j].st_shndx ].sh_offset
1410 oc->symbols[j].lbl = nm;
1411 oc->symbols[j].addr = ad;
1412 if (ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL) {
1413 IF_DEBUG(linker,belch( "addOTabName(LOCL): %10p %s %s",
1414 ad, oc->fileName, nm ));
1415 insertStrHashTable(oc->lochash, nm, &(oc->symbols[j]));
1417 IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p %s %s",
1418 ad, oc->fileName, nm ));
1419 insertStrHashTable(symhash, nm, &(oc->symbols[j]));
1423 IF_DEBUG(linker,belch( "skipping `%s'",
1424 strtab + stab[j].st_name ));
1427 "skipping bind = %d, type = %d, shndx = %d `%s'\n",
1428 (int)ELF32_ST_BIND(stab[j].st_info),
1429 (int)ELF32_ST_TYPE(stab[j].st_info),
1430 (int)stab[j].st_shndx,
1431 strtab + stab[j].st_name
1434 oc->symbols[j].lbl = NULL;
1435 oc->symbols[j].addr = NULL;
1444 /* Do ELF relocations which lack an explicit addend. All x86-linux
1445 relocations appear to be of this form. */
1446 static int do_Elf32_Rel_relocations ( ObjectCode* oc, char* ehdrC,
1447 Elf32_Shdr* shdr, int shnum,
1448 Elf32_Sym* stab, char* strtab )
1453 Elf32_Rel* rtab = (Elf32_Rel*) (ehdrC + shdr[shnum].sh_offset);
1454 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rel);
1455 int target_shndx = shdr[shnum].sh_info;
1456 int symtab_shndx = shdr[shnum].sh_link;
1457 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1458 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1459 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1460 target_shndx, symtab_shndx ));
1461 for (j = 0; j < nent; j++) {
1462 Elf32_Addr offset = rtab[j].r_offset;
1463 Elf32_Word info = rtab[j].r_info;
1465 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1466 Elf32_Word* pP = (Elf32_Word*)P;
1470 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)",
1471 j, (void*)offset, (void*)info ));
1473 IF_DEBUG(linker,belch( " ZERO" ));
1476 /* First see if it is a nameless local symbol. */
1477 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1478 symbol = "(noname)";
1480 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1481 + stab[ELF32_R_SYM(info)].st_value);
1483 /* No? Should be in a symbol table then; first try the
1485 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1486 (void*)S = lookupLocalSymbol( oc, symbol );
1487 if ((void*)S == NULL)
1488 (void*)S = lookupSymbol( symbol );
1491 barf("do_Elf32_Rel_relocations: %s: unknown symbol `%s'",
1492 oc->fileName, symbol);
1494 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1496 IF_DEBUG(linker,belch( "Reloc: P = %p S = %p A = %p",
1497 (void*)P, (void*)S, (void*)A ));
1498 switch (ELF32_R_TYPE(info)) {
1499 #ifdef i386_TARGET_ARCH
1500 case R_386_32: *pP = S + A; break;
1501 case R_386_PC32: *pP = S + A - P; break;
1504 barf("do_Elf32_Rel_relocations: unhandled ELF relocation(Rel) type %d\n", ELF32_R_TYPE(info));
1513 /* Do ELF relocations for which explicit addends are supplied.
1514 sparc-solaris relocations appear to be of this form. */
1515 static int do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
1516 Elf32_Shdr* shdr, int shnum,
1517 Elf32_Sym* stab, char* strtab )
1522 Elf32_Rela* rtab = (Elf32_Rela*) (ehdrC + shdr[shnum].sh_offset);
1523 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rela);
1524 int target_shndx = shdr[shnum].sh_info;
1525 int symtab_shndx = shdr[shnum].sh_link;
1526 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1527 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1528 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1529 target_shndx, symtab_shndx ));
1530 for (j = 0; j < nent; j++) {
1531 Elf32_Addr offset = rtab[j].r_offset;
1532 Elf32_Word info = rtab[j].r_info;
1533 Elf32_Sword addend = rtab[j].r_addend;
1535 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1536 Elf32_Addr A = addend;
1538 # if defined(sparc_TARGET_ARCH)
1539 /* This #ifdef only serves to avoid unused-var warnings. */
1540 Elf32_Word* pP = (Elf32_Word*)P;
1544 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ",
1545 j, (void*)offset, (void*)info,
1548 IF_DEBUG(linker,belch( " ZERO" ));
1551 /* First see if it is a nameless local symbol. */
1552 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1553 symbol = "(noname)";
1555 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1556 + stab[ELF32_R_SYM(info)].st_value);
1558 /* No? Should be in a symbol table then; first try the
1560 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1561 (void*)S = lookupLocalSymbol( oc, symbol );
1562 if ((void*)S == NULL)
1563 (void*)S = lookupSymbol( symbol );
1566 barf("ocResolve_ELF: %s: unknown symbol `%s'",
1567 oc->fileName, symbol);
1570 fprintf ( stderr, "S %p A %p S+A %p S+A-P %p\n",S,A,S+A,S+A-P);
1573 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1575 IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n",
1576 (void*)P, (void*)S, (void*)A ));
1577 switch (ELF32_R_TYPE(info)) {
1578 # if defined(sparc_TARGET_ARCH)
1579 case R_SPARC_WDISP30:
1580 w1 = *pP & 0xC0000000;
1581 w2 = (Elf32_Word)((S + A - P) >> 2);
1582 ASSERT((w2 & 0xC0000000) == 0);
1587 w1 = *pP & 0xFFC00000;
1588 w2 = (Elf32_Word)((S + A) >> 10);
1589 ASSERT((w2 & 0xFFC00000) == 0);
1595 w2 = (Elf32_Word)((S + A) & 0x3FF);
1596 ASSERT((w2 & ~0x3FF) == 0);
1601 w2 = (Elf32_Word)(S + A);
1606 fprintf(stderr, "unhandled ELF relocation(RelA) type %d\n",
1607 ELF32_R_TYPE(info));
1608 barf("do_Elf32_Rela_relocations: unhandled ELF relocation type");
1618 ocResolve_ELF ( ObjectCode* oc )
1622 Elf32_Sym* stab = NULL;
1623 char* ehdrC = (char*)(oc->image);
1624 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1625 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1627 /* first find "the" symbol table */
1628 stab = (Elf32_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
1630 /* also go find the string table */
1631 strtab = findElfSection ( ehdrC, SHT_STRTAB );
1633 if (stab == NULL || strtab == NULL) {
1634 belch("ocResolve_ELF: can't find string or symbol table");
1638 /* Process the relocation sections. */
1639 for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
1640 if (shdr[shnum].sh_type == SHT_REL ) {
1641 ok = do_Elf32_Rel_relocations ( oc, ehdrC, shdr,
1642 shnum, stab, strtab );
1646 if (shdr[shnum].sh_type == SHT_RELA) {
1647 ok = do_Elf32_Rela_relocations ( oc, ehdrC, shdr,
1648 shnum, stab, strtab );
1653 /* Free the local symbol table; we won't need it again. */
1654 freeHashTable(oc->lochash, NULL);