1 /* -----------------------------------------------------------------------------
2 * $Id: Linker.c,v 1.32 2001/02/28 10:03:42 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)
32 # define OBJFORMAT_ELF
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
54 typedef struct _RtsSymbolVal {
74 SymX(stg_update_PAP) \
75 SymX(stg_ap_2_upd_info) \
76 SymX(stg_ap_3_upd_info) \
77 SymX(stg_ap_4_upd_info) \
78 SymX(stg_ap_5_upd_info) \
79 SymX(stg_ap_6_upd_info) \
80 SymX(stg_ap_7_upd_info) \
81 SymX(stg_ap_8_upd_info) \
82 SymX(stg_sel_0_upd_info) \
83 SymX(stg_sel_1_upd_info) \
84 SymX(stg_sel_2_upd_info) \
85 SymX(stg_sel_3_upd_info) \
86 SymX(stg_sel_4_upd_info) \
87 SymX(stg_sel_5_upd_info) \
88 SymX(stg_sel_6_upd_info) \
89 SymX(stg_sel_7_upd_info) \
90 SymX(stg_sel_8_upd_info) \
91 SymX(stg_sel_9_upd_info) \
92 SymX(stg_sel_10_upd_info) \
93 SymX(stg_sel_11_upd_info) \
94 SymX(stg_sel_12_upd_info) \
95 SymX(stg_sel_13_upd_info) \
96 SymX(stg_sel_14_upd_info) \
97 SymX(stg_sel_15_upd_info) \
98 SymX(stg_upd_frame_info) \
99 SymX(stg_seq_frame_info) \
100 SymX(stg_CAF_BLACKHOLE_info) \
101 SymX(stg_IND_STATIC_info) \
102 SymX(stg_EMPTY_MVAR_info) \
103 SymX(stg_MUT_ARR_PTRS_FROZEN_info) \
104 SymX(stg_WEAK_info) \
105 SymX(stg_CHARLIKE_closure) \
106 SymX(stg_INTLIKE_closure) \
108 SymX(newBCOzh_fast) \
109 SymX(mkApUpd0zh_fast) \
110 SymX(putMVarzh_fast) \
111 SymX(newMVarzh_fast) \
112 SymX(takeMVarzh_fast) \
113 SymX(tryTakeMVarzh_fast) \
114 SymX(tryPutMVarzh_fast) \
120 SymX(killThreadzh_fast) \
121 SymX(waitReadzh_fast) \
122 SymX(waitWritezh_fast) \
123 SymX(suspendThread) \
125 SymX(stackOverflow) \
126 SymX(int2Integerzh_fast) \
127 SymX(word2Integerzh_fast) \
128 SymX(mkForeignObjzh_fast) \
129 SymX(__encodeDouble) \
130 SymX(decodeDoublezh_fast) \
131 SymX(decodeFloatzh_fast) \
132 SymX(gcdIntegerzh_fast) \
133 SymX(newArrayzh_fast) \
134 SymX(unsafeThawArrayzh_fast) \
135 SymX(newByteArrayzh_fast) \
136 SymX(newMutVarzh_fast) \
137 SymX(quotRemIntegerzh_fast) \
138 SymX(quotIntegerzh_fast) \
139 SymX(remIntegerzh_fast) \
140 SymX(divExactIntegerzh_fast) \
141 SymX(divModIntegerzh_fast) \
142 SymX(timesIntegerzh_fast) \
143 SymX(minusIntegerzh_fast) \
144 SymX(plusIntegerzh_fast) \
145 SymX(andIntegerzh_fast) \
146 SymX(orIntegerzh_fast) \
147 SymX(xorIntegerzh_fast) \
148 SymX(complementIntegerzh_fast) \
149 SymX(mkWeakzh_fast) \
150 SymX(makeStableNamezh_fast) \
151 SymX(finalizzeWeakzh_fast) \
152 SymX(blockAsyncExceptionszh_fast) \
153 SymX(unblockAsyncExceptionszh_fast) \
155 SymX(isDoubleInfinite) \
156 SymX(isDoubleDenormalized) \
157 SymX(isDoubleNegativeZero) \
158 SymX(__encodeFloat) \
160 SymX(isFloatInfinite) \
161 SymX(isFloatDenormalized) \
162 SymX(isFloatNegativeZero) \
163 SymX(__int_encodeFloat) \
164 SymX(__int_encodeDouble) \
165 SymX(__gmpz_cmp_si) \
166 SymX(__gmpz_cmp_ui) \
171 SymX(resetNonBlockingFd) \
173 SymX(stable_ptr_table) \
174 SymX(shutdownHaskellAndExit) \
175 Sym(stg_enterStackTop) \
176 Sym(stg_yield_to_interpreter) \
180 Sym(__init_PrelGHC) \
181 SymX(freeHaskellFunctionPtr) \
184 SymX(NoRunnableThreadsHook) \
185 SymX(StackOverflowHook) \
186 SymX(OutOfHeapHook) \
187 SymX(MallocFailHook) \
188 SymX(PatErrorHdrHook) \
191 SymX(PostTraceHook) \
192 SymX(stg_sig_install) \
194 SymX(createAdjustor) \
196 SymX(rts_mkStablePtr) \
199 SymX(rts_checkSchedStatus) \
202 #ifndef SUPPORT_LONG_LONGS
203 #define RTS_LONG_LONG_SYMS /* nothing */
205 #define RTS_LONG_LONG_SYMS \
218 SymX(stg_remWord64) \
219 SymX(stg_quotWord64) \
221 SymX(stg_quotInt64) \
222 SymX(stg_negateInt64) \
223 SymX(stg_plusInt64) \
224 SymX(stg_minusInt64) \
225 SymX(stg_timesInt64) \
231 SymX(stg_shiftRL64) \
232 SymX(stg_iShiftL64) \
233 SymX(stg_iShiftRL64) \
234 SymX(stg_iShiftRA64) \
235 SymX(stg_intToInt64) \
236 SymX(stg_int64ToInt) \
237 SymX(stg_int64ToWord64) \
238 SymX(stg_wordToWord64) \
239 SymX(stg_word64ToWord) \
240 SymX(stg_word64ToInt64) \
241 SymX(int64ToIntegerzh_fast) \
242 SymX(word64ToIntegerzh_fast)
243 #endif /* SUPPORT_LONG_LONGS */
245 /* entirely bogus claims about types of these symbols */
246 #define Sym(vvv) extern void (vvv);
247 #define SymX(vvv) /**/
252 #ifdef LEADING_UNDERSCORE
253 #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
255 #define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
258 #define Sym(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
260 #define SymX(vvv) Sym(vvv)
262 static RtsSymbolVal rtsSyms[] = {
265 { 0, 0 } /* sentinel */
268 /* -----------------------------------------------------------------------------
269 * initialize the object linker
271 #if defined(OBJFORMAT_ELF)
272 static void *dl_prog_handle;
280 symhash = allocStrHashTable();
282 /* populate the symbol table with stuff from the RTS */
283 for (sym = rtsSyms; sym->lbl != NULL; sym++) {
284 insertStrHashTable(symhash, sym->lbl, sym->addr);
286 # if defined(OBJFORMAT_ELF)
287 dl_prog_handle = dlopen(NULL, RTLD_LAZY);
291 /* -----------------------------------------------------------------------------
292 * Add a DLL from which symbols may be found. In the ELF case, just
293 * do RTLD_GLOBAL-style add, so no further messing around needs to
294 * happen in order that symbols in the loaded .so are findable --
295 * lookupSymbol() will subsequently see them by dlsym on the program's
296 * dl-handle. Returns 0 if fail, 1 if success.
299 addDLL ( char* dll_name )
301 # if defined(OBJFORMAT_ELF)
306 buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
307 sprintf(buf, "lib%s.so", dll_name);
308 hdl = dlopen(buf, RTLD_NOW | RTLD_GLOBAL );
311 /* dlopen failed; return a ptr to the error msg. */
313 if (errmsg == NULL) errmsg = "addDLL: unknown error";
318 ASSERT(0); /*NOTREACHED*/
319 # elif defined(OBJFORMAT_PEi386)
320 barf("addDLL: not implemented on PEi386 yet");
323 barf("addDLL: not implemented on this platform");
327 /* -----------------------------------------------------------------------------
328 * lookup a symbol in the hash table
331 lookupSymbol( char *lbl )
334 ASSERT(symhash != NULL);
335 val = lookupStrHashTable(symhash, lbl);
338 # if defined(OBJFORMAT_ELF)
339 return dlsym(dl_prog_handle, lbl);
340 # elif defined(OBJFORMAT_PEi386)
351 lookupLocalSymbol( ObjectCode* oc, char *lbl )
354 val = lookupStrHashTable(oc->lochash, lbl);
364 /* -----------------------------------------------------------------------------
365 * Load an obj (populate the global symbol table, but don't resolve yet)
367 * Returns: 1 if ok, 0 on error.
370 loadObj( char *path )
378 /* assert that we haven't already loaded this object */
381 for (o = objects; o; o = o->next)
382 ASSERT(strcmp(o->fileName, path));
386 oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
388 # if defined(OBJFORMAT_ELF)
389 oc->formatName = "ELF";
390 # elif defined(OBJFORMAT_PEi386)
391 oc->formatName = "PEi386";
394 barf("loadObj: not implemented on this platform");
398 if (r == -1) { return 0; }
400 /* sigh, strdup() isn't a POSIX function, so do it the long way */
401 oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
402 strcpy(oc->fileName, path);
404 oc->fileSize = st.st_size;
405 oc->image = stgMallocBytes( st.st_size, "loadObj(image)" );
408 oc->lochash = allocStrHashTable();
410 /* chain it onto the list of objects */
414 /* load the image into memory */
415 f = fopen(path, "rb");
417 barf("loadObj: can't read `%s'", path);
419 n = fread ( oc->image, 1, oc->fileSize, f );
420 if (n != oc->fileSize) {
422 barf("loadObj: error whilst reading `%s'", path);
425 /* verify the in-memory image */
426 # if defined(OBJFORMAT_ELF)
427 r = ocVerifyImage_ELF ( oc );
428 # elif defined(OBJFORMAT_PEi386)
429 r = ocVerifyImage_PEi386 ( oc );
431 barf("loadObj: no verify method");
433 if (!r) { return r; }
435 /* build the symbol list for this image */
436 # if defined(OBJFORMAT_ELF)
437 r = ocGetNames_ELF ( oc );
438 # elif defined(OBJFORMAT_PEi386)
439 r = ocGetNames_PEi386 ( oc );
441 barf("loadObj: no getNames method");
443 if (!r) { return r; }
445 /* loaded, but not resolved yet */
446 oc->status = OBJECT_LOADED;
451 /* -----------------------------------------------------------------------------
452 * resolve all the currently unlinked objects in memory
454 * Returns: 1 if ok, 0 on error.
462 for (oc = objects; oc; oc = oc->next) {
463 if (oc->status != OBJECT_RESOLVED) {
464 # if defined(OBJFORMAT_ELF)
465 r = ocResolve_ELF ( oc );
466 # elif defined(OBJFORMAT_PEi386)
467 r = ocResolve_PEi386 ( oc );
469 barf("resolveObjs: not implemented on this platform");
471 if (!r) { return r; }
472 oc->status = OBJECT_RESOLVED;
478 /* -----------------------------------------------------------------------------
479 * delete an object from the pool
482 unloadObj( char *path )
484 ObjectCode *oc, *prev;
486 ASSERT(symhash != NULL);
487 ASSERT(objects != NULL);
490 for (oc = objects; oc; prev = oc, oc = oc->next) {
491 if (!strcmp(oc->fileName,path)) {
493 /* Remove all the mappings for the symbols within this
498 for (i = 0; i < oc->n_symbols; i++) {
499 if (oc->symbols[i] != NULL) {
500 removeStrHashTable(symhash, oc->symbols[i], NULL);
508 prev->next = oc->next;
511 /* We're going to leave this in place, in case there are
512 any pointers from the heap into it: */
513 /* free(oc->image); */
517 /* The local hash table should have been freed at the end
518 of the ocResolve_ call on it. */
519 ASSERT(oc->lochash == NULL);
525 belch("unloadObj: can't find `%s' to unload", path);
529 /* --------------------------------------------------------------------------
530 * PEi386 specifics (Win32 targets)
531 * ------------------------------------------------------------------------*/
533 /* The information for this linker comes from
534 Microsoft Portable Executable
535 and Common Object File Format Specification
536 revision 5.1 January 1998
537 which SimonM says comes from the MS Developer Network CDs.
541 #if defined(OBJFORMAT_PEi386)
545 typedef unsigned char UChar;
546 typedef unsigned short UInt16;
547 typedef unsigned int UInt32;
554 UInt16 NumberOfSections;
555 UInt32 TimeDateStamp;
556 UInt32 PointerToSymbolTable;
557 UInt32 NumberOfSymbols;
558 UInt16 SizeOfOptionalHeader;
559 UInt16 Characteristics;
563 #define sizeof_COFF_header 20
570 UInt32 VirtualAddress;
571 UInt32 SizeOfRawData;
572 UInt32 PointerToRawData;
573 UInt32 PointerToRelocations;
574 UInt32 PointerToLinenumbers;
575 UInt16 NumberOfRelocations;
576 UInt16 NumberOfLineNumbers;
577 UInt32 Characteristics;
581 #define sizeof_COFF_section 40
588 UInt16 SectionNumber;
591 UChar NumberOfAuxSymbols;
595 #define sizeof_COFF_symbol 18
600 UInt32 VirtualAddress;
601 UInt32 SymbolTableIndex;
606 #define sizeof_COFF_reloc 10
609 /* From PE spec doc, section 3.3.2 */
610 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001
611 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
612 #define IMAGE_FILE_DLL 0x2000
613 #define IMAGE_FILE_SYSTEM 0x1000
614 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
615 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
616 #define IMAGE_FILE_32BIT_MACHINE 0x0100
618 /* From PE spec doc, section 5.4.2 and 5.4.4 */
619 #define IMAGE_SYM_CLASS_EXTERNAL 2
620 #define IMAGE_SYM_CLASS_STATIC 3
621 #define IMAGE_SYM_UNDEFINED 0
623 /* From PE spec doc, section 4.1 */
624 #define IMAGE_SCN_CNT_CODE 0x00000020
625 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
627 /* From PE spec doc, section 5.2.1 */
628 #define IMAGE_REL_I386_DIR32 0x0006
629 #define IMAGE_REL_I386_REL32 0x0014
632 /* We use myindex to calculate array addresses, rather than
633 simply doing the normal subscript thing. That's because
634 some of the above structs have sizes which are not
635 a whole number of words. GCC rounds their sizes up to a
636 whole number of words, which means that the address calcs
637 arising from using normal C indexing or pointer arithmetic
638 are just plain wrong. Sigh.
641 myindex ( int scale, void* base, int index )
644 ((UChar*)base) + scale * index;
649 printName ( UChar* name, UChar* strtab )
651 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
652 UInt32 strtab_offset = * (UInt32*)(name+4);
653 fprintf ( stderr, "%s", strtab + strtab_offset );
656 for (i = 0; i < 8; i++) {
657 if (name[i] == 0) break;
658 fprintf ( stderr, "%c", name[i] );
665 copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
667 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
668 UInt32 strtab_offset = * (UInt32*)(name+4);
669 strncpy ( dst, strtab+strtab_offset, dstSize );
675 if (name[i] == 0) break;
685 cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
688 /* If the string is longer than 8 bytes, look in the
689 string table for it -- this will be correctly zero terminated.
691 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
692 UInt32 strtab_offset = * (UInt32*)(name+4);
693 return ((UChar*)strtab) + strtab_offset;
695 /* Otherwise, if shorter than 8 bytes, return the original,
696 which by defn is correctly terminated.
698 if (name[7]==0) return name;
699 /* The annoying case: 8 bytes. Copy into a temporary
700 (which is never freed ...)
702 newstr = stgMallocBytes(9, "cstring_from_COFF_symbol_name");
704 strncpy(newstr,name,8);
710 /* Just compares the short names (first 8 chars) */
711 static COFF_section *
712 findPEi386SectionCalled ( ObjectCode* oc, char* name )
716 = (COFF_header*)(oc->image);
719 ((UChar*)(oc->image))
720 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
722 for (i = 0; i < hdr->NumberOfSections; i++) {
725 COFF_section* section_i
727 myindex ( sizeof_COFF_section, sectab, i );
728 n1 = (UChar*) &(section_i->Name);
730 if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] &&
731 n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] &&
732 n1[6]==n2[6] && n1[7]==n2[7])
741 zapTrailingAtSign ( UChar* sym )
743 # define my_isdigit(c) ((c) >= '0' && (c) <= '9')
745 if (sym[0] == 0) return;
747 while (sym[i] != 0) i++;
750 while (j > 0 && my_isdigit(sym[j])) j--;
751 if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
757 ocVerifyImage_PEi386 ( ObjectCode* oc )
761 COFF_section* sectab;
765 hdr = (COFF_header*)(oc->image);
766 sectab = (COFF_section*) (
767 ((UChar*)(oc->image))
768 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
770 symtab = (COFF_symbol*) (
771 ((UChar*)(oc->image))
772 + hdr->PointerToSymbolTable
774 strtab = ((UChar*)(oc->image))
775 + hdr->PointerToSymbolTable
776 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
778 if (hdr->Machine != 0x14c) {
779 belch("Not x86 PEi386");
782 if (hdr->SizeOfOptionalHeader != 0) {
783 belch("PEi386 with nonempty optional header");
786 if ( /* (hdr->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) || */
787 (hdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ||
788 (hdr->Characteristics & IMAGE_FILE_DLL) ||
789 (hdr->Characteristics & IMAGE_FILE_SYSTEM) ) {
790 belch("Not a PEi386 object file");
793 if ( (hdr->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI) ||
794 !(hdr->Characteristics & IMAGE_FILE_32BIT_MACHINE) ) {
795 belch("Invalid PEi386 word size or endiannness");
799 /* No further verification after this point; only debug printing. */
801 IF_DEBUG(linker, i=1);
802 if (i == 0) return 1;
805 "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
807 "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
809 "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
811 fprintf ( stderr, "\n" );
813 "Machine: 0x%x\n", (UInt32)(hdr->Machine) );
815 "# sections: %d\n", (UInt32)(hdr->NumberOfSections) );
817 "time/date: 0x%x\n", (UInt32)(hdr->TimeDateStamp) );
819 "symtab offset: %d\n", (UInt32)(hdr->PointerToSymbolTable) );
821 "# symbols: %d\n", (UInt32)(hdr->NumberOfSymbols) );
823 "sz of opt hdr: %d\n", (UInt32)(hdr->SizeOfOptionalHeader) );
825 "characteristics: 0x%x\n", (UInt32)(hdr->Characteristics) );
827 fprintf ( stderr, "\n" );
828 fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
829 fprintf ( stderr, "---START of string table---\n");
830 for (i = 4; i < *(Int32*)strtab; i++) {
832 fprintf ( stderr, "\n"); else
833 fprintf( stderr, "%c", strtab[i] );
835 fprintf ( stderr, "--- END of string table---\n");
837 fprintf ( stderr, "\n" );
838 for (i = 0; i < hdr->NumberOfSections; i++) {
840 COFF_section* sectab_i
842 myindex ( sizeof_COFF_section, sectab, i );
849 printName ( sectab_i->Name, strtab );
858 sectab_i->VirtualSize,
859 sectab_i->VirtualAddress,
860 sectab_i->SizeOfRawData,
861 sectab_i->PointerToRawData,
862 sectab_i->NumberOfRelocations,
863 sectab_i->PointerToRelocations
865 reltab = (COFF_reloc*) (
866 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
868 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
870 COFF_reloc* rel = (COFF_reloc*)
871 myindex ( sizeof_COFF_reloc, reltab, j );
873 " type 0x%-4x vaddr 0x%-8x name `",
875 rel->VirtualAddress );
877 myindex ( sizeof_COFF_symbol, symtab, rel->SymbolTableIndex );
878 printName ( sym->Name, strtab );
879 fprintf ( stderr, "'\n" );
881 fprintf ( stderr, "\n" );
885 fprintf ( stderr, "\n" );
888 COFF_symbol* symtab_i;
889 if (i >= (Int32)(hdr->NumberOfSymbols)) break;
890 symtab_i = (COFF_symbol*)
891 myindex ( sizeof_COFF_symbol, symtab, i );
897 printName ( symtab_i->Name, strtab );
906 (Int32)(symtab_i->SectionNumber) - 1,
907 (UInt32)symtab_i->Type,
908 (UInt32)symtab_i->StorageClass,
909 (UInt32)symtab_i->NumberOfAuxSymbols
911 i += symtab_i->NumberOfAuxSymbols;
915 fprintf ( stderr, "\n" );
922 ocGetNames_PEi386 ( ObjectCode* oc )
925 COFF_section* sectab;
933 hdr = (COFF_header*)(oc->image);
934 sectab = (COFF_section*) (
935 ((UChar*)(oc->image))
936 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
938 symtab = (COFF_symbol*) (
939 ((UChar*)(oc->image))
940 + hdr->PointerToSymbolTable
942 strtab = ((UChar*)(oc->image))
943 + hdr->PointerToSymbolTable
944 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
946 /* Copy exported symbols into the ObjectCode. */
948 oc->n_symbols = hdr->NumberOfSymbols;
949 oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
950 "ocGetNames_PEi386(oc->symbols)");
951 /* Call me paranoid; I don't care. */
952 for (i = 0; i < oc->n_symbols; i++)
953 oc->symbols[i] = NULL;
957 COFF_symbol* symtab_i;
958 if (i >= (Int32)(hdr->NumberOfSymbols)) break;
959 symtab_i = (COFF_symbol*)
960 myindex ( sizeof_COFF_symbol, symtab, i );
962 if (symtab_i->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
963 symtab_i->SectionNumber != IMAGE_SYM_UNDEFINED) {
965 /* This symbol is global and defined, viz, exported */
966 COFF_section* sectabent;
968 /* cstring_from_COFF_symbol_name always succeeds. */
969 sname = cstring_from_COFF_symbol_name ( symtab_i->Name, strtab );
971 /* for IMAGE_SYMCLASS_EXTERNAL
972 && !IMAGE_SYM_UNDEFINED,
973 the address of the symbol is:
974 address of relevant section + offset in section
976 sectabent = (COFF_section*)
977 myindex ( sizeof_COFF_section,
979 symtab_i->SectionNumber-1 );
980 addr = ((UChar*)(oc->image))
981 + (sectabent->PointerToRawData
983 IF_DEBUG(linker, belch("addSymbol %p `%s'\n", addr,sname);)
984 ASSERT(i >= 0 && i < oc->n_symbols);
985 oc->symbols[i] = sname;
986 insertStrHashTable(symhash, sname, addr);
988 i += symtab_i->NumberOfAuxSymbols;
992 /* Copy section information into the ObjectCode. */
994 oc->n_sections = hdr->NumberOfSections;
995 oc->sections = stgMallocBytes( oc->n_sections * sizeof(Section),
996 "ocGetNamesPEi386" );
998 for (i = 0; i < oc->n_sections; i++) {
1003 = SECTIONKIND_OTHER;
1004 COFF_section* sectab_i
1006 myindex ( sizeof_COFF_section, sectab, i );
1007 IF_DEBUG(linker, belchf("section name = %s\n", sectab_i->Name ));
1010 /* I'm sure this is the Right Way to do it. However, the
1011 alternative of testing the sectab_i->Name field seems to
1012 work ok with Cygwin.
1014 if (sectab_i->Characteristics & IMAGE_SCN_CNT_CODE ||
1015 sectab_i->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
1016 kind = SECTIONKIND_CODE_OR_RODATA;
1019 if (0==strcmp(".text",sectab_i->Name))
1020 kind = SECTIONKIND_CODE_OR_RODATA;
1021 if (0==strcmp(".data",sectab_i->Name) ||
1022 0==strcmp(".bss",sectab_i->Name))
1023 kind = SECTIONKIND_RWDATA;
1025 start = ((UChar*)(oc->image))
1026 + sectab_i->PointerToRawData;
1028 + sectab_i->SizeOfRawData - 1;
1030 if (kind == SECTIONKIND_OTHER) {
1031 belch("Unknown PEi386 section name `%s'", sectab_i->Name);
1035 oc->sections[i].start = start;
1036 oc->sections[i].end = end;
1037 oc->sections[i].kind = kind;
1045 ocResolve_PEi386 ( ObjectCode* oc )
1048 COFF_section* sectab;
1049 COFF_symbol* symtab;
1058 /* ToDo: should be variable-sized? But is at least safe in the
1059 sense of buffer-overrun-proof. */
1062 hdr = (COFF_header*)(oc->image);
1063 sectab = (COFF_section*) (
1064 ((UChar*)(oc->image))
1065 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1067 symtab = (COFF_symbol*) (
1068 ((UChar*)(oc->image))
1069 + hdr->PointerToSymbolTable
1071 strtab = ((UChar*)(oc->image))
1072 + hdr->PointerToSymbolTable
1073 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1075 for (i = 0; i < hdr->NumberOfSections; i++) {
1076 COFF_section* sectab_i
1078 myindex ( sizeof_COFF_section, sectab, i );
1081 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
1083 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1085 COFF_reloc* reltab_j
1087 myindex ( sizeof_COFF_reloc, reltab, j );
1089 /* the location to patch */
1091 ((UChar*)(oc->image))
1092 + (sectab_i->PointerToRawData
1093 + reltab_j->VirtualAddress)
1095 /* the existing contents of pP */
1097 /* the symbol to connect to */
1098 sym = (COFF_symbol*)
1099 myindex ( sizeof_COFF_symbol,
1100 symtab, reltab_j->SymbolTableIndex );
1103 "reloc sec %2d num %3d: type 0x%-4x "
1104 "vaddr 0x%-8x name `",
1106 (UInt32)reltab_j->Type,
1107 reltab_j->VirtualAddress );
1108 printName ( sym->Name, strtab );
1109 fprintf ( stderr, "'\n" ));
1111 if (sym->StorageClass == IMAGE_SYM_CLASS_STATIC) {
1112 COFF_section* section_sym
1113 = findPEi386SectionCalled ( oc, sym->Name );
1115 fprintf ( stderr, "bad section = `%s'\n", sym->Name );
1116 barf("Can't find abovementioned PEi386 section");
1119 S = ((UInt32)(oc->image))
1120 + (section_sym->PointerToRawData
1123 copyName ( sym->Name, strtab, symbol, 1000 );
1124 zapTrailingAtSign ( symbol );
1125 (void*)S = lookupLocalSymbol( oc, symbol );
1126 if ((void*)S == NULL)
1127 (void*)S = lookupSymbol( symbol );
1129 belch("ocResolve_PEi386: %s: unknown symbol `%s'",
1130 oc->fileName, symbol);
1135 switch (reltab_j->Type) {
1136 case IMAGE_REL_I386_DIR32:
1139 case IMAGE_REL_I386_REL32:
1140 /* Tricky. We have to insert a displacement at
1141 pP which, when added to the PC for the _next_
1142 insn, gives the address of the target (S).
1143 Problem is to know the address of the next insn
1144 when we only know pP. We assume that this
1145 literal field is always the last in the insn,
1146 so that the address of the next insn is pP+4
1147 -- hence the constant 4.
1148 Also I don't know if A should be added, but so
1149 far it has always been zero.
1152 *pP = S - ((UInt32)pP) - 4;
1156 "unhandled PEi386 relocation type %d\n",
1158 barf("unhandled PEi386 relocation type");
1168 #endif /* defined(OBJFORMAT_PEi386) */
1171 /* --------------------------------------------------------------------------
1173 * ------------------------------------------------------------------------*/
1175 #if defined(OBJFORMAT_ELF)
1180 #if defined(sparc_TARGET_ARCH)
1181 # define ELF_TARGET_SPARC /* Used inside <elf.h> */
1187 findElfSection ( void* objImage, Elf32_Word sh_type )
1190 char* ehdrC = (char*)objImage;
1191 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1192 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1194 for (i = 0; i < ehdr->e_shnum; i++) {
1195 if (shdr[i].sh_type == sh_type &&
1196 i != ehdr->e_shstrndx) {
1197 ptr = ehdrC + shdr[i].sh_offset;
1206 ocVerifyImage_ELF ( ObjectCode* oc )
1210 int i, j, nent, nstrtab, nsymtabs;
1214 char* ehdrC = (char*)(oc->image);
1215 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1217 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1218 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1219 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1220 ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1221 belch("ocVerifyImage_ELF: not an ELF header");
1224 IF_DEBUG(linker,belch( "Is an ELF header" ));
1226 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1227 belch("ocVerifyImage_ELF: not 32 bit ELF" );
1231 IF_DEBUG(linker,belch( "Is 32 bit ELF" ));
1233 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1234 IF_DEBUG(linker,belch( "Is little-endian" ));
1236 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1237 IF_DEBUG(linker,belch( "Is big-endian" ));
1239 belch("ocVerifyImage_ELF: unknown endiannness");
1243 if (ehdr->e_type != ET_REL) {
1244 belch("ocVerifyImage_ELF: not a relocatable object (.o) file");
1247 IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
1249 IF_DEBUG(linker,belch( "Architecture is " ));
1250 switch (ehdr->e_machine) {
1251 case EM_386: IF_DEBUG(linker,belch( "x86" )); break;
1252 case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
1253 default: IF_DEBUG(linker,belch( "unknown" ));
1254 belch("ocVerifyImage_ELF: unknown architecture");
1258 IF_DEBUG(linker,belch(
1259 "\nSection header table: start %d, n_entries %d, ent_size %d",
1260 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize ));
1262 ASSERT (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1264 shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1266 if (ehdr->e_shstrndx == SHN_UNDEF) {
1267 belch("ocVerifyImage_ELF: no section header string table");
1270 IF_DEBUG(linker,belch( "Section header string table is section %d",
1272 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1275 for (i = 0; i < ehdr->e_shnum; i++) {
1276 IF_DEBUG(linker,fprintf(stderr, "%2d: ", i ));
1277 IF_DEBUG(linker,fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type ));
1278 IF_DEBUG(linker,fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size ));
1279 IF_DEBUG(linker,fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset ));
1280 IF_DEBUG(linker,fprintf(stderr, " (%p .. %p) ",
1281 ehdrC + shdr[i].sh_offset,
1282 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
1284 if (shdr[i].sh_type == SHT_REL) {
1285 IF_DEBUG(linker,fprintf(stderr, "Rel " ));
1286 } else if (shdr[i].sh_type == SHT_RELA) {
1287 IF_DEBUG(linker,fprintf(stderr, "RelA " ));
1289 IF_DEBUG(linker,fprintf(stderr," "));
1292 IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
1296 IF_DEBUG(linker,belch( "\nString tables" ));
1299 for (i = 0; i < ehdr->e_shnum; i++) {
1300 if (shdr[i].sh_type == SHT_STRTAB &&
1301 i != ehdr->e_shstrndx) {
1302 IF_DEBUG(linker,belch(" section %d is a normal string table", i ));
1303 strtab = ehdrC + shdr[i].sh_offset;
1308 belch("ocVerifyImage_ELF: no string tables, or too many");
1313 IF_DEBUG(linker,belch( "\nSymbol tables" ));
1314 for (i = 0; i < ehdr->e_shnum; i++) {
1315 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1316 IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
1318 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1319 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1320 IF_DEBUG(linker,belch( " number of entries is apparently %d (%d rem)",
1322 shdr[i].sh_size % sizeof(Elf32_Sym)
1324 if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1325 belch("ocVerifyImage_ELF: non-integral number of symbol table entries");
1328 for (j = 0; j < nent; j++) {
1329 IF_DEBUG(linker,fprintf(stderr, " %2d ", j ));
1330 IF_DEBUG(linker,fprintf(stderr, " sec=%-5d size=%-3d val=%5p ",
1331 (int)stab[j].st_shndx,
1332 (int)stab[j].st_size,
1333 (char*)stab[j].st_value ));
1335 IF_DEBUG(linker,fprintf(stderr, "type=" ));
1336 switch (ELF32_ST_TYPE(stab[j].st_info)) {
1337 case STT_NOTYPE: IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
1338 case STT_OBJECT: IF_DEBUG(linker,fprintf(stderr, "object " )); break;
1339 case STT_FUNC : IF_DEBUG(linker,fprintf(stderr, "func " )); break;
1340 case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
1341 case STT_FILE: IF_DEBUG(linker,fprintf(stderr, "file " )); break;
1342 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1344 IF_DEBUG(linker,fprintf(stderr, " " ));
1346 IF_DEBUG(linker,fprintf(stderr, "bind=" ));
1347 switch (ELF32_ST_BIND(stab[j].st_info)) {
1348 case STB_LOCAL : IF_DEBUG(linker,fprintf(stderr, "local " )); break;
1349 case STB_GLOBAL: IF_DEBUG(linker,fprintf(stderr, "global" )); break;
1350 case STB_WEAK : IF_DEBUG(linker,fprintf(stderr, "weak " )); break;
1351 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1353 IF_DEBUG(linker,fprintf(stderr, " " ));
1355 IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
1359 if (nsymtabs == 0) {
1360 belch("ocVerifyImage_ELF: didn't find any symbol tables");
1369 ocGetNames_ELF ( ObjectCode* oc )
1374 char* ehdrC = (char*)(oc->image);
1375 Elf32_Ehdr* ehdr = (Elf32_Ehdr*)ehdrC;
1376 char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
1377 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1378 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1380 ASSERT(symhash != NULL);
1383 belch("ocGetNames_ELF: no strtab");
1388 oc->n_sections = ehdr->e_shnum;
1389 oc->sections = stgMallocBytes( oc->n_sections * sizeof(Section),
1390 "ocGetNames_ELF(oc->sections)" );
1392 for (i = 0; i < oc->n_sections; i++) {
1394 /* make a section entry for relevant sections */
1395 SectionKind kind = SECTIONKIND_OTHER;
1396 if (!strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1397 !strcmp(".data1",sh_strtab+shdr[i].sh_name))
1398 kind = SECTIONKIND_RWDATA;
1399 if (!strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1400 !strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1401 !strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1402 kind = SECTIONKIND_CODE_OR_RODATA;
1404 /* fill in the section info */
1405 oc->sections[i].start = ehdrC + shdr[i].sh_offset;
1406 oc->sections[i].end = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
1407 oc->sections[i].kind = kind;
1409 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1411 /* copy stuff into this module's object symbol table */
1412 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1413 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1415 oc->n_symbols = nent;
1416 oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
1417 "ocGetNames_ELF(oc->symbols)");
1419 for (j = 0; j < nent; j++) {
1420 if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
1421 || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
1423 /* and not an undefined symbol */
1424 && stab[j].st_shndx != SHN_UNDEF
1425 /* and not in a "special section" */
1426 && stab[j].st_shndx < SHN_LORESERVE
1428 /* and it's a not a section or string table or anything silly */
1429 ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1430 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
1431 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE
1434 char* nm = strtab + stab[j].st_name;
1436 + shdr[ stab[j].st_shndx ].sh_offset
1440 oc->symbols[j] = nm;
1441 if (ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL) {
1442 IF_DEBUG(linker,belch( "addOTabName(LOCL): %10p %s %s",
1443 ad, oc->fileName, nm ));
1444 insertStrHashTable(oc->lochash, nm, ad);
1446 IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p %s %s",
1447 ad, oc->fileName, nm ));
1448 insertStrHashTable(symhash, nm, ad);
1452 IF_DEBUG(linker,belch( "skipping `%s'",
1453 strtab + stab[j].st_name ));
1456 "skipping bind = %d, type = %d, shndx = %d `%s'\n",
1457 (int)ELF32_ST_BIND(stab[j].st_info),
1458 (int)ELF32_ST_TYPE(stab[j].st_info),
1459 (int)stab[j].st_shndx,
1460 strtab + stab[j].st_name
1463 oc->symbols[j] = NULL;
1472 /* Do ELF relocations which lack an explicit addend. All x86-linux
1473 relocations appear to be of this form. */
1474 static int do_Elf32_Rel_relocations ( ObjectCode* oc, char* ehdrC,
1475 Elf32_Shdr* shdr, int shnum,
1476 Elf32_Sym* stab, char* strtab )
1481 Elf32_Rel* rtab = (Elf32_Rel*) (ehdrC + shdr[shnum].sh_offset);
1482 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rel);
1483 int target_shndx = shdr[shnum].sh_info;
1484 int symtab_shndx = shdr[shnum].sh_link;
1485 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1486 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1487 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1488 target_shndx, symtab_shndx ));
1489 for (j = 0; j < nent; j++) {
1490 Elf32_Addr offset = rtab[j].r_offset;
1491 Elf32_Word info = rtab[j].r_info;
1493 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1494 Elf32_Word* pP = (Elf32_Word*)P;
1498 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)",
1499 j, (void*)offset, (void*)info ));
1501 IF_DEBUG(linker,belch( " ZERO" ));
1504 /* First see if it is a nameless local symbol. */
1505 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1506 symbol = "(noname)";
1508 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1509 + stab[ELF32_R_SYM(info)].st_value);
1511 /* No? Should be in a symbol table then; first try the
1513 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1514 (void*)S = lookupLocalSymbol( oc, symbol );
1515 if ((void*)S == NULL)
1516 (void*)S = lookupSymbol( symbol );
1519 barf("do_Elf32_Rel_relocations: %s: unknown symbol `%s'",
1520 oc->fileName, symbol);
1522 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1524 IF_DEBUG(linker,belch( "Reloc: P = %p S = %p A = %p",
1525 (void*)P, (void*)S, (void*)A ));
1526 switch (ELF32_R_TYPE(info)) {
1527 # ifdef i386_TARGET_ARCH
1528 case R_386_32: *pP = S + A; break;
1529 case R_386_PC32: *pP = S + A - P; break;
1532 fprintf(stderr, "unhandled ELF relocation(Rel) type %d\n",
1533 ELF32_R_TYPE(info));
1534 barf("do_Elf32_Rel_relocations: unhandled ELF relocation type");
1543 /* Do ELF relocations for which explicit addends are supplied.
1544 sparc-solaris relocations appear to be of this form. */
1545 static int do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
1546 Elf32_Shdr* shdr, int shnum,
1547 Elf32_Sym* stab, char* strtab )
1552 Elf32_Rela* rtab = (Elf32_Rela*) (ehdrC + shdr[shnum].sh_offset);
1553 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rela);
1554 int target_shndx = shdr[shnum].sh_info;
1555 int symtab_shndx = shdr[shnum].sh_link;
1556 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1557 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1558 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1559 target_shndx, symtab_shndx ));
1560 for (j = 0; j < nent; j++) {
1561 Elf32_Addr offset = rtab[j].r_offset;
1562 Elf32_Word info = rtab[j].r_info;
1563 Elf32_Sword addend = rtab[j].r_addend;
1565 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1566 Elf32_Addr A = addend;
1568 # if defined(sparc_TARGET_ARCH)
1569 /* This #ifdef only serves to avoid unused-var warnings. */
1570 Elf32_Word* pP = (Elf32_Word*)P;
1574 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ",
1575 j, (void*)offset, (void*)info,
1578 IF_DEBUG(linker,belch( " ZERO" ));
1581 /* First see if it is a nameless local symbol. */
1582 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1583 symbol = "(noname)";
1585 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1586 + stab[ELF32_R_SYM(info)].st_value);
1588 /* No? Should be in a symbol table then; first try the
1590 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1591 (void*)S = lookupLocalSymbol( oc, symbol );
1592 if ((void*)S == NULL)
1593 (void*)S = lookupSymbol( symbol );
1596 barf("do_Elf32_Rela_relocations: %s: unknown symbol `%s'",
1597 oc->fileName, symbol);
1600 fprintf ( stderr, "S %p A %p S+A %p S+A-P %p\n",S,A,S+A,S+A-P);
1603 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1605 IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n",
1606 (void*)P, (void*)S, (void*)A ));
1607 switch (ELF32_R_TYPE(info)) {
1608 # if defined(sparc_TARGET_ARCH)
1609 case R_SPARC_WDISP30:
1610 w1 = *pP & 0xC0000000;
1611 w2 = (Elf32_Word)((S + A - P) >> 2);
1612 ASSERT((w2 & 0xC0000000) == 0);
1617 w1 = *pP & 0xFFC00000;
1618 w2 = (Elf32_Word)((S + A) >> 10);
1619 ASSERT((w2 & 0xFFC00000) == 0);
1625 w2 = (Elf32_Word)((S + A) & 0x3FF);
1626 ASSERT((w2 & ~0x3FF) == 0);
1631 w2 = (Elf32_Word)(S + A);
1636 fprintf(stderr, "unhandled ELF relocation(RelA) type %d\n",
1637 ELF32_R_TYPE(info));
1638 barf("do_Elf32_Rela_relocations: unhandled ELF relocation type");
1648 ocResolve_ELF ( ObjectCode* oc )
1652 Elf32_Sym* stab = NULL;
1653 char* ehdrC = (char*)(oc->image);
1654 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1655 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1657 /* first find "the" symbol table */
1658 stab = (Elf32_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
1660 /* also go find the string table */
1661 strtab = findElfSection ( ehdrC, SHT_STRTAB );
1663 if (stab == NULL || strtab == NULL) {
1664 belch("ocResolve_ELF: can't find string or symbol table");
1668 /* Process the relocation sections. */
1669 for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
1670 if (shdr[shnum].sh_type == SHT_REL ) {
1671 ok = do_Elf32_Rel_relocations ( oc, ehdrC, shdr,
1672 shnum, stab, strtab );
1676 if (shdr[shnum].sh_type == SHT_RELA) {
1677 ok = do_Elf32_Rela_relocations ( oc, ehdrC, shdr,
1678 shnum, stab, strtab );
1683 /* Free the local symbol table; we won't need it again. */
1684 freeHashTable(oc->lochash, NULL);