1 /* -----------------------------------------------------------------------------
2 * $Id: Linker.c,v 1.29 2001/02/14 11:02:36 sewardj 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)
296 buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
297 sprintf(buf, "lib%s.so", dll_name);
298 hdl = dlopen(buf, RTLD_NOW | RTLD_GLOBAL );
301 /* dlopen failed; return a ptr to the error msg. */
303 if (errmsg == NULL) errmsg = "addDLL: unknown error";
308 ASSERT(0); /*NOTREACHED*/
309 # elif defined(OBJFORMAT_PEi386)
310 barf("addDLL: not implemented on PEi386 yet");
313 barf("addDLL: not implemented on this platform");
317 /* -----------------------------------------------------------------------------
318 * lookup a symbol in the hash table
321 lookupSymbol( char *lbl )
324 ASSERT(symhash != NULL);
325 val = lookupStrHashTable(symhash, lbl);
328 return dlsym(dl_prog_handle, lbl);
336 lookupLocalSymbol( ObjectCode* oc, char *lbl )
339 val = lookupStrHashTable(oc->lochash, lbl);
349 /* -----------------------------------------------------------------------------
350 * Load an obj (populate the global symbol table, but don't resolve yet)
352 * Returns: 1 if ok, 0 on error.
355 loadObj( char *path )
363 /* assert that we haven't already loaded this object */
366 for (o = objects; o; o = o->next)
367 ASSERT(strcmp(o->fileName, path));
371 oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
373 # if defined(OBJFORMAT_ELF)
374 oc->formatName = "ELF";
375 # elif defined(OBJFORMAT_PEi386)
376 oc->formatName = "PEi386";
379 barf("loadObj: not implemented on this platform");
383 if (r == -1) { return 0; }
385 /* sigh, strdup() isn't a POSIX function, so do it the long way */
386 oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
387 strcpy(oc->fileName, path);
389 oc->fileSize = st.st_size;
390 oc->image = stgMallocBytes( st.st_size, "loadObj(image)" );
393 oc->lochash = allocStrHashTable();
395 /* chain it onto the list of objects */
399 /* load the image into memory */
400 f = fopen(path, "rb");
402 barf("loadObj: can't read `%s'", path);
404 n = fread ( oc->image, 1, oc->fileSize, f );
405 if (n != oc->fileSize) {
407 barf("loadObj: error whilst reading `%s'", path);
410 /* verify the in-memory image */
411 # if defined(OBJFORMAT_ELF)
412 r = ocVerifyImage_ELF ( oc );
413 # elif defined(OBJFORMAT_PEi386)
414 r = ocVerifyImage_PEi386 ( oc );
416 barf("loadObj: no verify method");
418 if (!r) { return r; }
420 /* build the symbol list for this image */
421 # if defined(OBJFORMAT_ELF)
422 r = ocGetNames_ELF ( oc );
423 # elif defined(OBJFORMAT_PEi386)
424 r = ocGetNames_PEi386 ( oc );
426 barf("loadObj: no getNames method");
428 if (!r) { return r; }
430 /* loaded, but not resolved yet */
431 oc->status = OBJECT_LOADED;
436 /* -----------------------------------------------------------------------------
437 * resolve all the currently unlinked objects in memory
439 * Returns: 1 if ok, 0 on error.
447 for (oc = objects; oc; oc = oc->next) {
448 if (oc->status != OBJECT_RESOLVED) {
449 # if defined(OBJFORMAT_ELF)
450 r = ocResolve_ELF ( oc );
451 # elif defined(OBJFORMAT_PEi386)
452 r = ocResolve_PEi386 ( oc );
454 barf("link: not implemented on this platform");
456 if (!r) { return r; }
457 oc->status = OBJECT_RESOLVED;
463 /* -----------------------------------------------------------------------------
464 * delete an object from the pool
467 unloadObj( char *path )
469 ObjectCode *oc, *prev;
471 ASSERT(symhash != NULL);
472 ASSERT(objects != NULL);
475 for (oc = objects; oc; prev = oc, oc = oc->next) {
476 if (!strcmp(oc->fileName,path)) {
478 /* Remove all the mappings for the symbols within this
483 for (s = oc->symbols; s < oc->symbols + oc->n_symbols; s++) {
484 if (s->lbl != NULL) {
485 removeStrHashTable(symhash, s->lbl, NULL);
493 prev->next = oc->next;
496 /* We're going to leave this in place, in case there are
497 any pointers from the heap into it: */
498 /* free(oc->image); */
502 /* The local hash table should have been freed at the end
503 of the ocResolve_ call on it. */
504 ASSERT(oc->lochash == NULL);
510 belch("unloadObj: can't find `%s' to unload", path);
514 /* --------------------------------------------------------------------------
515 * PEi386 specifics (Win32 targets)
516 * ------------------------------------------------------------------------*/
518 /* The information for this linker comes from
519 Microsoft Portable Executable
520 and Common Object File Format Specification
521 revision 5.1 January 1998
522 which SimonM says comes from the MS Developer Network CDs.
526 #if defined(OBJFORMAT_PEi386)
530 typedef unsigned char UChar;
531 typedef unsigned short UInt16;
532 typedef unsigned int UInt32;
539 UInt16 NumberOfSections;
540 UInt32 TimeDateStamp;
541 UInt32 PointerToSymbolTable;
542 UInt32 NumberOfSymbols;
543 UInt16 SizeOfOptionalHeader;
544 UInt16 Characteristics;
548 #define sizeof_COFF_header 20
555 UInt32 VirtualAddress;
556 UInt32 SizeOfRawData;
557 UInt32 PointerToRawData;
558 UInt32 PointerToRelocations;
559 UInt32 PointerToLinenumbers;
560 UInt16 NumberOfRelocations;
561 UInt16 NumberOfLineNumbers;
562 UInt32 Characteristics;
566 #define sizeof_COFF_section 40
573 UInt16 SectionNumber;
576 UChar NumberOfAuxSymbols;
580 #define sizeof_COFF_symbol 18
585 UInt32 VirtualAddress;
586 UInt32 SymbolTableIndex;
591 #define sizeof_COFF_reloc 10
594 /* From PE spec doc, section 3.3.2 */
595 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001
596 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
597 #define IMAGE_FILE_DLL 0x2000
598 #define IMAGE_FILE_SYSTEM 0x1000
599 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
600 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
601 #define IMAGE_FILE_32BIT_MACHINE 0x0100
603 /* From PE spec doc, section 5.4.2 and 5.4.4 */
604 #define IMAGE_SYM_CLASS_EXTERNAL 2
605 #define IMAGE_SYM_CLASS_STATIC 3
606 #define IMAGE_SYM_UNDEFINED 0
608 /* From PE spec doc, section 4.1 */
609 #define IMAGE_SCN_CNT_CODE 0x00000020
610 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
612 /* From PE spec doc, section 5.2.1 */
613 #define IMAGE_REL_I386_DIR32 0x0006
614 #define IMAGE_REL_I386_REL32 0x0014
617 /* We use myindex to calculate array addresses, rather than
618 simply doing the normal subscript thing. That's because
619 some of the above structs have sizes which are not
620 a whole number of words. GCC rounds their sizes up to a
621 whole number of words, which means that the address calcs
622 arising from using normal C indexing or pointer arithmetic
623 are just plain wrong. Sigh.
626 myindex ( int scale, int index, void* base )
629 ((UChar*)base) + scale * index;
634 printName ( UChar* name, UChar* strtab )
636 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
637 UInt32 strtab_offset = * (UInt32*)(name+4);
638 fprintf ( stderr, "%s", strtab + strtab_offset );
641 for (i = 0; i < 8; i++) {
642 if (name[i] == 0) break;
643 fprintf ( stderr, "%c", name[i] );
650 copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
652 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
653 UInt32 strtab_offset = * (UInt32*)(name+4);
654 strncpy ( dst, strtab+strtab_offset, dstSize );
660 if (name[i] == 0) break;
670 cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
673 /* If the string is longer than 8 bytes, look in the
674 string table for it -- this will be correctly zero terminated.
676 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
677 UInt32 strtab_offset = * (UInt32*)(name+4);
678 return ((UChar*)strtab) + strtab_offset;
680 /* Otherwise, if shorter than 8 bytes, return the original,
681 which by defn is correctly terminated.
683 if (name[7]==0) return name;
684 /* The annoying case: 8 bytes. Copy into a temporary
685 (which is never freed ...)
689 strncpy(newstr,name,8);
696 /* Just compares the short names (first 8 chars) */
697 static COFF_section *
698 findPEi386SectionCalled ( ObjectCode* oc, char* name )
702 = (COFF_header*)(oc->image);
705 ((UChar*)(oc->image))
706 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
708 for (i = 0; i < hdr->NumberOfSections; i++) {
711 COFF_section* section_i
713 myindex ( sizeof_COFF_section, i, sectab );
714 n1 = (UChar*) &(section_i->Name);
716 if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] &&
717 n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] &&
718 n1[6]==n2[6] && n1[7]==n2[7])
727 zapTrailingAtSign ( UChar* sym )
730 if (sym[0] == 0) return;
732 while (sym[i] != 0) i++;
735 while (j > 0 && isdigit(sym[j])) j--;
736 if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
741 ocVerifyImage_PEi386 ( ObjectCode* oc )
745 COFF_section* sectab;
749 hdr = (COFF_header*)(oc->image);
750 sectab = (COFF_section*) (
751 ((UChar*)(oc->image))
752 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
754 symtab = (COFF_symbol*) (
755 ((UChar*)(oc->image))
756 + hdr->PointerToSymbolTable
758 strtab = ((UChar*)(oc->image))
759 + hdr->PointerToSymbolTable
760 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
762 if (hdr->Machine != 0x14c) {
763 oc->errMsg("Not x86 PEi386");
766 if (hdr->SizeOfOptionalHeader != 0) {
767 oc->errMsg("PEi386 with nonempty optional header");
770 if ( /* (hdr->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) || */
771 (hdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ||
772 (hdr->Characteristics & IMAGE_FILE_DLL) ||
773 (hdr->Characteristics & IMAGE_FILE_SYSTEM) ) {
774 oc->errMsg("Not a PEi386 object file");
777 if ( (hdr->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI) ||
778 !(hdr->Characteristics & IMAGE_FILE_32BIT_MACHINE) ) {
779 oc->errMsg("Invalid PEi386 word size or endiannness");
783 if (!verb) return TRUE;
784 /* No further verification after this point; only debug printing. */
787 "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
789 "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
791 "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
793 fprintf ( stderr, "\n" );
795 "Machine: 0x%x\n", (UInt32)(hdr->Machine) );
797 "# sections: %d\n", (UInt32)(hdr->NumberOfSections) );
799 "time/date: 0x%x\n", (UInt32)(hdr->TimeDateStamp) );
801 "symtab offset: %d\n", (UInt32)(hdr->PointerToSymbolTable) );
803 "# symbols: %d\n", (UInt32)(hdr->NumberOfSymbols) );
805 "sz of opt hdr: %d\n", (UInt32)(hdr->SizeOfOptionalHeader) );
807 "characteristics: 0x%x\n", (UInt32)(hdr->Characteristics) );
809 fprintf ( stderr, "\n" );
810 fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
811 fprintf ( stderr, "---START of string table---\n");
812 for (i = 4; i < *(UInt32*)strtab; i++) {
814 fprintf ( stderr, "\n"); else
815 fprintf( stderr, "%c", strtab[i] );
817 fprintf ( stderr, "--- END of string table---\n");
819 fprintf ( stderr, "\n" );
820 for (i = 0; i < hdr->NumberOfSections; i++) {
822 COFF_section* sectab_i
824 myindex ( sizeof_COFF_section, i, sectab );
831 printName ( sectab_i->Name, strtab );
840 sectab_i->VirtualSize,
841 sectab_i->VirtualAddress,
842 sectab_i->SizeOfRawData,
843 sectab_i->PointerToRawData,
844 sectab_i->NumberOfRelocations,
845 sectab_i->PointerToRelocations
847 reltab = (COFF_reloc*) (
848 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
850 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
852 COFF_reloc* rel = (COFF_reloc*)
853 myindex ( sizeof_COFF_reloc, j, reltab );
855 " type 0x%-4x vaddr 0x%-8x name `",
857 rel->VirtualAddress );
859 myindex ( sizeof_COFF_symbol, rel->SymbolTableIndex, symtab );
860 printName ( sym->Name, strtab );
861 fprintf ( stderr, "'\n" );
863 fprintf ( stderr, "\n" );
867 fprintf ( stderr, "\n" );
870 COFF_symbol* symtab_i;
871 if (i >= hdr->NumberOfSymbols) break;
872 symtab_i = (COFF_symbol*)
873 myindex ( sizeof_COFF_symbol, i, symtab );
879 printName ( symtab_i->Name, strtab );
888 (Int32)(symtab_i->SectionNumber) - 1,
889 (UInt32)symtab_i->Type,
890 (UInt32)symtab_i->StorageClass,
891 (UInt32)symtab_i->NumberOfAuxSymbols
893 i += symtab_i->NumberOfAuxSymbols;
897 fprintf ( stderr, "\n" );
904 ocGetNames_PEi386 ( ObjectCode* oc )
907 COFF_section* sectab;
915 hdr = (COFF_header*)(oc->image);
916 sectab = (COFF_section*) (
917 ((UChar*)(oc->image))
918 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
920 symtab = (COFF_symbol*) (
921 ((UChar*)(oc->image))
922 + hdr->PointerToSymbolTable
924 strtab = ((UChar*)(oc->image))
925 + hdr->PointerToSymbolTable
926 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
928 /* Copy exported symbols into the ObjectCode. */
931 COFF_symbol* symtab_i;
932 if (i >= hdr->NumberOfSymbols) break;
933 symtab_i = (COFF_symbol*)
934 myindex ( sizeof_COFF_symbol, i, symtab );
936 if (symtab_i->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
937 symtab_i->SectionNumber != IMAGE_SYM_UNDEFINED) {
939 /* This symbol is global and defined, viz, exported */
940 COFF_section* sectabent;
942 sname = cstring_from_COFF_symbol_name (
943 symtab_i->Name, strtab
946 oc->errMsg("Out of memory when copying PEi386 symbol");
950 /* for IMAGE_SYMCLASS_EXTERNAL
951 && !IMAGE_SYM_UNDEFINED,
952 the address of the symbol is:
953 address of relevant section + offset in section
955 sectabent = (COFF_section*)
956 myindex ( sizeof_COFF_section,
957 symtab_i->SectionNumber-1,
959 addr = ((UChar*)(oc->image))
960 + (sectabent->PointerToRawData
962 /* fprintf ( stderr, "addSymbol %p `%s'\n", addr,sname); */
963 if (!addSymbol(oc,sname,addr)) return FALSE;
965 i += symtab_i->NumberOfAuxSymbols;
969 oc->sections = stgMallocBytes( NumberOfSections * sizeof(Section),
970 "ocGetNamesPEi386" );
972 /* Copy section information into the ObjectCode. */
973 for (i = 0; i < hdr->NumberOfSections; i++) {
979 COFF_section* sectab_i
981 myindex ( sizeof_COFF_section, i, sectab );
982 /* fprintf ( stderr, "section name = %s\n", sectab_i->Name ); */
985 /* I'm sure this is the Right Way to do it. However, the
986 alternative of testing the sectab_i->Name field seems to
989 if (sectab_i->Characteristics & IMAGE_SCN_CNT_CODE ||
990 sectab_i->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
991 kind = SECTIONKIND_CODE_OR_RODATA;
994 if (0==strcmp(".text",sectab_i->Name))
995 kind = SECTIONKIND_CODE_OR_RODATA;
996 if (0==strcmp(".data",sectab_i->Name) ||
997 0==strcmp(".bss",sectab_i->Name))
998 kind = SECTIONKIND_RWDATA;
1000 start = ((UChar*)(oc->image))
1001 + sectab_i->PointerToRawData;
1003 + sectab_i->SizeOfRawData - 1;
1005 if (kind != SECTIONKIND_OTHER) {
1006 addSection ( oc, start, end, kind );
1008 fprintf ( stderr, "unknown section name = `%s'\n",
1010 oc->errMsg("Unknown PEi386 section name");
1020 ocResolve_PEi386 ( ObjectCode* oc, int verb )
1023 COFF_section* sectab;
1024 COFF_symbol* symtab;
1032 char symbol[1000]; // ToDo
1034 hdr = (COFF_header*)(oc->image);
1035 sectab = (COFF_section*) (
1036 ((UChar*)(oc->image))
1037 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1039 symtab = (COFF_symbol*) (
1040 ((UChar*)(oc->image))
1041 + hdr->PointerToSymbolTable
1043 strtab = ((UChar*)(oc->image))
1044 + hdr->PointerToSymbolTable
1045 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1047 for (i = 0; i < hdr->NumberOfSections; i++) {
1048 COFF_section* sectab_i
1050 myindex ( sizeof_COFF_section, i, sectab );
1053 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
1055 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1057 COFF_reloc* reltab_j
1059 myindex ( sizeof_COFF_reloc, j, reltab );
1061 /* the location to patch */
1063 ((UChar*)(oc->image))
1064 + (sectab_i->PointerToRawData
1065 + reltab_j->VirtualAddress)
1067 /* the existing contents of pP */
1069 /* the symbol to connect to */
1070 sym = (COFF_symbol*)
1071 myindex ( sizeof_COFF_symbol,
1072 reltab_j->SymbolTableIndex, symtab );
1075 "reloc sec %2d num %3d: type 0x%-4x "
1076 "vaddr 0x%-8x name `",
1078 (UInt32)reltab_j->Type,
1079 reltab_j->VirtualAddress );
1080 printName ( sym->Name, strtab );
1081 fprintf ( stderr, "'\n" );
1084 if (sym->StorageClass == IMAGE_SYM_CLASS_STATIC) {
1085 COFF_section* section_sym
1086 = findPEi386SectionCalled ( oc, sym->Name );
1088 fprintf ( stderr, "bad section = `%s'\n", sym->Name );
1089 oc->errMsg("Can't find abovementioned PEi386 section");
1092 S = ((UInt32)(oc->image))
1093 + (section_sym->PointerToRawData
1096 copyName ( sym->Name, strtab, symbol, 1000 );
1097 zapTrailingAtSign ( symbol );
1098 S = (UInt32) ocLookupSym ( oc, symbol );
1100 S = (UInt32)(oc->clientLookup ( symbol ));
1102 belch("%s: unresolvable reference to `%s'", oc->fileName, symbol);
1107 switch (reltab_j->Type) {
1108 case IMAGE_REL_I386_DIR32:
1111 case IMAGE_REL_I386_REL32:
1112 /* Tricky. We have to insert a displacement at
1113 pP which, when added to the PC for the _next_
1114 insn, gives the address of the target (S).
1115 Problem is to know the address of the next insn
1116 when we only know pP. We assume that this
1117 literal field is always the last in the insn,
1118 so that the address of the next insn is pP+4
1119 -- hence the constant 4.
1120 Also I don't know if A should be added, but so
1121 far it has always been zero.
1124 *pP = S - ((UInt32)pP) - 4;
1128 "unhandled PEi386 relocation type %d\n",
1130 oc->errMsg("unhandled PEi386 relocation type");
1140 #endif /* defined(OBJFORMAT_PEi386) */
1143 /* --------------------------------------------------------------------------
1145 * ------------------------------------------------------------------------*/
1147 #if defined(OBJFORMAT_ELF)
1152 #if defined(sparc_TARGET_ARCH)
1153 # define ELF_TARGET_SPARC /* Used inside <elf.h> */
1159 findElfSection ( void* objImage, Elf32_Word sh_type )
1162 char* ehdrC = (char*)objImage;
1163 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1164 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1166 for (i = 0; i < ehdr->e_shnum; i++) {
1167 if (shdr[i].sh_type == sh_type &&
1168 i != ehdr->e_shstrndx) {
1169 ptr = ehdrC + shdr[i].sh_offset;
1178 ocVerifyImage_ELF ( ObjectCode* oc )
1182 int i, j, nent, nstrtab, nsymtabs;
1186 char* ehdrC = (char*)(oc->image);
1187 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1189 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1190 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1191 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1192 ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1193 belch("ocVerifyImage_ELF: not an ELF header");
1196 IF_DEBUG(linker,belch( "Is an ELF header" ));
1198 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1199 belch("ocVerifyImage_ELF: not 32 bit ELF" );
1203 IF_DEBUG(linker,belch( "Is 32 bit ELF" ));
1205 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1206 IF_DEBUG(linker,belch( "Is little-endian" ));
1208 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1209 IF_DEBUG(linker,belch( "Is big-endian" ));
1211 belch("ocVerifyImage_ELF: unknown endiannness");
1215 if (ehdr->e_type != ET_REL) {
1216 belch("ocVerifyImage_ELF: not a relocatable object (.o) file");
1219 IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
1221 IF_DEBUG(linker,belch( "Architecture is " ));
1222 switch (ehdr->e_machine) {
1223 case EM_386: IF_DEBUG(linker,belch( "x86" )); break;
1224 case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
1225 default: IF_DEBUG(linker,belch( "unknown" ));
1226 belch("ocVerifyImage_ELF: unknown architecture");
1230 IF_DEBUG(linker,belch(
1231 "\nSection header table: start %d, n_entries %d, ent_size %d",
1232 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize ));
1234 ASSERT (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1236 shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1238 if (ehdr->e_shstrndx == SHN_UNDEF) {
1239 belch("ocVerifyImage_ELF: no section header string table");
1242 IF_DEBUG(linker,belch( "Section header string table is section %d",
1244 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1247 for (i = 0; i < ehdr->e_shnum; i++) {
1248 IF_DEBUG(linker,fprintf(stderr, "%2d: ", i ));
1249 IF_DEBUG(linker,fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type ));
1250 IF_DEBUG(linker,fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size ));
1251 IF_DEBUG(linker,fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset ));
1252 IF_DEBUG(linker,fprintf(stderr, " (%p .. %p) ",
1253 ehdrC + shdr[i].sh_offset,
1254 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
1256 if (shdr[i].sh_type == SHT_REL) {
1257 IF_DEBUG(linker,fprintf(stderr, "Rel " ));
1258 } else if (shdr[i].sh_type == SHT_RELA) {
1259 IF_DEBUG(linker,fprintf(stderr, "RelA " ));
1261 IF_DEBUG(linker,fprintf(stderr," "));
1264 IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
1268 IF_DEBUG(linker,belch( "\nString tables" ));
1271 for (i = 0; i < ehdr->e_shnum; i++) {
1272 if (shdr[i].sh_type == SHT_STRTAB &&
1273 i != ehdr->e_shstrndx) {
1274 IF_DEBUG(linker,belch(" section %d is a normal string table", i ));
1275 strtab = ehdrC + shdr[i].sh_offset;
1280 belch("ocVerifyImage_ELF: no string tables, or too many");
1285 IF_DEBUG(linker,belch( "\nSymbol tables" ));
1286 for (i = 0; i < ehdr->e_shnum; i++) {
1287 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1288 IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
1290 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1291 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1292 IF_DEBUG(linker,belch( " number of entries is apparently %d (%d rem)",
1294 shdr[i].sh_size % sizeof(Elf32_Sym)
1296 if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1297 belch("ocVerifyImage_ELF: non-integral number of symbol table entries");
1300 for (j = 0; j < nent; j++) {
1301 IF_DEBUG(linker,fprintf(stderr, " %2d ", j ));
1302 IF_DEBUG(linker,fprintf(stderr, " sec=%-5d size=%-3d val=%5p ",
1303 (int)stab[j].st_shndx,
1304 (int)stab[j].st_size,
1305 (char*)stab[j].st_value ));
1307 IF_DEBUG(linker,fprintf(stderr, "type=" ));
1308 switch (ELF32_ST_TYPE(stab[j].st_info)) {
1309 case STT_NOTYPE: IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
1310 case STT_OBJECT: IF_DEBUG(linker,fprintf(stderr, "object " )); break;
1311 case STT_FUNC : IF_DEBUG(linker,fprintf(stderr, "func " )); break;
1312 case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
1313 case STT_FILE: IF_DEBUG(linker,fprintf(stderr, "file " )); break;
1314 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1316 IF_DEBUG(linker,fprintf(stderr, " " ));
1318 IF_DEBUG(linker,fprintf(stderr, "bind=" ));
1319 switch (ELF32_ST_BIND(stab[j].st_info)) {
1320 case STB_LOCAL : IF_DEBUG(linker,fprintf(stderr, "local " )); break;
1321 case STB_GLOBAL: IF_DEBUG(linker,fprintf(stderr, "global" )); break;
1322 case STB_WEAK : IF_DEBUG(linker,fprintf(stderr, "weak " )); break;
1323 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1325 IF_DEBUG(linker,fprintf(stderr, " " ));
1327 IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
1331 if (nsymtabs == 0) {
1332 belch("ocVerifyImage_ELF: didn't find any symbol tables");
1341 ocGetNames_ELF ( ObjectCode* oc )
1346 char* ehdrC = (char*)(oc->image);
1347 Elf32_Ehdr* ehdr = (Elf32_Ehdr*)ehdrC;
1348 char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
1349 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1350 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1352 ASSERT(symhash != NULL);
1355 belch("ocGetNames_ELF: no strtab");
1360 oc->sections = stgMallocBytes( ehdr->e_shnum * sizeof(Section),
1362 oc->n_sections = ehdr->e_shnum;
1364 for (i = 0; i < ehdr->e_shnum; i++) {
1366 /* make a section entry for relevant sections */
1367 SectionKind kind = SECTIONKIND_OTHER;
1368 if (!strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1369 !strcmp(".data1",sh_strtab+shdr[i].sh_name))
1370 kind = SECTIONKIND_RWDATA;
1371 if (!strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1372 !strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1373 !strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1374 kind = SECTIONKIND_CODE_OR_RODATA;
1376 /* fill in the section info */
1377 oc->sections[i].start = ehdrC + shdr[i].sh_offset;
1378 oc->sections[i].end = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
1379 oc->sections[i].kind = kind;
1381 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1383 /* copy stuff into this module's object symbol table */
1384 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1385 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1386 oc->symbols = malloc(nent * sizeof(SymbolVal));
1387 oc->n_symbols = nent;
1388 for (j = 0; j < nent; j++) {
1389 if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
1390 || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
1392 /* and not an undefined symbol */
1393 && stab[j].st_shndx != SHN_UNDEF
1394 /* and not in a "special section" */
1395 && stab[j].st_shndx < SHN_LORESERVE
1397 /* and it's a not a section or string table or anything silly */
1398 ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1399 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
1400 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE
1403 char* nm = strtab + stab[j].st_name;
1405 + shdr[ stab[j].st_shndx ].sh_offset
1409 oc->symbols[j].lbl = nm;
1410 oc->symbols[j].addr = ad;
1411 if (ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL) {
1412 IF_DEBUG(linker,belch( "addOTabName(LOCL): %10p %s %s",
1413 ad, oc->fileName, nm ));
1414 insertStrHashTable(oc->lochash, nm, &(oc->symbols[j]));
1416 IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p %s %s",
1417 ad, oc->fileName, nm ));
1418 insertStrHashTable(symhash, nm, &(oc->symbols[j]));
1422 IF_DEBUG(linker,belch( "skipping `%s'",
1423 strtab + stab[j].st_name ));
1426 "skipping bind = %d, type = %d, shndx = %d `%s'\n",
1427 (int)ELF32_ST_BIND(stab[j].st_info),
1428 (int)ELF32_ST_TYPE(stab[j].st_info),
1429 (int)stab[j].st_shndx,
1430 strtab + stab[j].st_name
1433 oc->symbols[j].lbl = NULL;
1434 oc->symbols[j].addr = NULL;
1443 /* Do ELF relocations which lack an explicit addend. All x86-linux
1444 relocations appear to be of this form. */
1445 static int do_Elf32_Rel_relocations ( ObjectCode* oc, char* ehdrC,
1446 Elf32_Shdr* shdr, int shnum,
1447 Elf32_Sym* stab, char* strtab )
1452 Elf32_Rel* rtab = (Elf32_Rel*) (ehdrC + shdr[shnum].sh_offset);
1453 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rel);
1454 int target_shndx = shdr[shnum].sh_info;
1455 int symtab_shndx = shdr[shnum].sh_link;
1456 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1457 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1458 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1459 target_shndx, symtab_shndx ));
1460 for (j = 0; j < nent; j++) {
1461 Elf32_Addr offset = rtab[j].r_offset;
1462 Elf32_Word info = rtab[j].r_info;
1464 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1465 Elf32_Word* pP = (Elf32_Word*)P;
1469 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)",
1470 j, (void*)offset, (void*)info ));
1472 IF_DEBUG(linker,belch( " ZERO" ));
1475 /* First see if it is a nameless local symbol. */
1476 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1477 symbol = "(noname)";
1479 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1480 + stab[ELF32_R_SYM(info)].st_value);
1482 /* No? Should be in a symbol table then; first try the
1484 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1485 (void*)S = lookupLocalSymbol( oc, symbol );
1486 if ((void*)S == NULL)
1487 (void*)S = lookupSymbol( symbol );
1490 barf("do_Elf32_Rel_relocations: %s: unknown symbol `%s'",
1491 oc->fileName, symbol);
1493 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1495 IF_DEBUG(linker,belch( "Reloc: P = %p S = %p A = %p",
1496 (void*)P, (void*)S, (void*)A ));
1497 switch (ELF32_R_TYPE(info)) {
1498 #ifdef i386_TARGET_ARCH
1499 case R_386_32: *pP = S + A; break;
1500 case R_386_PC32: *pP = S + A - P; break;
1503 barf("do_Elf32_Rel_relocations: unhandled ELF relocation(Rel) type %d\n", ELF32_R_TYPE(info));
1512 /* Do ELF relocations for which explicit addends are supplied.
1513 sparc-solaris relocations appear to be of this form. */
1514 static int do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
1515 Elf32_Shdr* shdr, int shnum,
1516 Elf32_Sym* stab, char* strtab )
1521 Elf32_Rela* rtab = (Elf32_Rela*) (ehdrC + shdr[shnum].sh_offset);
1522 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rela);
1523 int target_shndx = shdr[shnum].sh_info;
1524 int symtab_shndx = shdr[shnum].sh_link;
1525 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1526 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1527 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1528 target_shndx, symtab_shndx ));
1529 for (j = 0; j < nent; j++) {
1530 Elf32_Addr offset = rtab[j].r_offset;
1531 Elf32_Word info = rtab[j].r_info;
1532 Elf32_Sword addend = rtab[j].r_addend;
1534 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1535 Elf32_Addr A = addend;
1537 # if defined(sparc_TARGET_ARCH)
1538 /* This #ifdef only serves to avoid unused-var warnings. */
1539 Elf32_Word* pP = (Elf32_Word*)P;
1543 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ",
1544 j, (void*)offset, (void*)info,
1547 IF_DEBUG(linker,belch( " ZERO" ));
1550 /* First see if it is a nameless local symbol. */
1551 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1552 symbol = "(noname)";
1554 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1555 + stab[ELF32_R_SYM(info)].st_value);
1557 /* No? Should be in a symbol table then; first try the
1559 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1560 (void*)S = lookupLocalSymbol( oc, symbol );
1561 if ((void*)S == NULL)
1562 (void*)S = lookupSymbol( symbol );
1565 barf("ocResolve_ELF: %s: unknown symbol `%s'",
1566 oc->fileName, symbol);
1569 fprintf ( stderr, "S %p A %p S+A %p S+A-P %p\n",S,A,S+A,S+A-P);
1572 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1574 IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n",
1575 (void*)P, (void*)S, (void*)A ));
1576 switch (ELF32_R_TYPE(info)) {
1577 # if defined(sparc_TARGET_ARCH)
1578 case R_SPARC_WDISP30:
1579 w1 = *pP & 0xC0000000;
1580 w2 = (Elf32_Word)((S + A - P) >> 2);
1581 ASSERT((w2 & 0xC0000000) == 0);
1586 w1 = *pP & 0xFFC00000;
1587 w2 = (Elf32_Word)((S + A) >> 10);
1588 ASSERT((w2 & 0xFFC00000) == 0);
1594 w2 = (Elf32_Word)((S + A) & 0x3FF);
1595 ASSERT((w2 & ~0x3FF) == 0);
1600 w2 = (Elf32_Word)(S + A);
1605 fprintf(stderr, "unhandled ELF relocation(RelA) type %d\n",
1606 ELF32_R_TYPE(info));
1607 barf("do_Elf32_Rela_relocations: unhandled ELF relocation type");
1617 ocResolve_ELF ( ObjectCode* oc )
1621 Elf32_Sym* stab = NULL;
1622 char* ehdrC = (char*)(oc->image);
1623 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1624 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1626 /* first find "the" symbol table */
1627 stab = (Elf32_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
1629 /* also go find the string table */
1630 strtab = findElfSection ( ehdrC, SHT_STRTAB );
1632 if (stab == NULL || strtab == NULL) {
1633 belch("ocResolve_ELF: can't find string or symbol table");
1637 /* Process the relocation sections. */
1638 for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
1639 if (shdr[shnum].sh_type == SHT_REL ) {
1640 ok = do_Elf32_Rel_relocations ( oc, ehdrC, shdr,
1641 shnum, stab, strtab );
1645 if (shdr[shnum].sh_type == SHT_RELA) {
1646 ok = do_Elf32_Rela_relocations ( oc, ehdrC, shdr,
1647 shnum, stab, strtab );
1652 /* Free the local symbol table; we won't need it again. */
1653 freeHashTable(oc->lochash, NULL);