1 /* -----------------------------------------------------------------------------
2 * $Id: Linker.c,v 1.33 2001/03/22 03:51:10 hwloidl 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 {
61 #define Maybe_ForeignObj SymX(mkForeignObjzh_fast)
63 #define Maybe_Stable_Names SymX(mkWeakzh_fast) \
64 SymX(makeStableNamezh_fast) \
65 SymX(finalizzeWeakzh_fast)
67 /* These are not available in GUM!!! -- HWL */
68 #define Maybe_ForeignObj
69 #define Maybe_Stable_Names
87 SymX(stg_update_PAP) \
88 SymX(stg_ap_2_upd_info) \
89 SymX(stg_ap_3_upd_info) \
90 SymX(stg_ap_4_upd_info) \
91 SymX(stg_ap_5_upd_info) \
92 SymX(stg_ap_6_upd_info) \
93 SymX(stg_ap_7_upd_info) \
94 SymX(stg_ap_8_upd_info) \
95 SymX(stg_sel_0_upd_info) \
96 SymX(stg_sel_1_upd_info) \
97 SymX(stg_sel_2_upd_info) \
98 SymX(stg_sel_3_upd_info) \
99 SymX(stg_sel_4_upd_info) \
100 SymX(stg_sel_5_upd_info) \
101 SymX(stg_sel_6_upd_info) \
102 SymX(stg_sel_7_upd_info) \
103 SymX(stg_sel_8_upd_info) \
104 SymX(stg_sel_9_upd_info) \
105 SymX(stg_sel_10_upd_info) \
106 SymX(stg_sel_11_upd_info) \
107 SymX(stg_sel_12_upd_info) \
108 SymX(stg_sel_13_upd_info) \
109 SymX(stg_sel_14_upd_info) \
110 SymX(stg_sel_15_upd_info) \
111 SymX(stg_upd_frame_info) \
112 SymX(stg_seq_frame_info) \
113 SymX(stg_CAF_BLACKHOLE_info) \
114 SymX(stg_IND_STATIC_info) \
115 SymX(stg_EMPTY_MVAR_info) \
116 SymX(stg_MUT_ARR_PTRS_FROZEN_info) \
117 SymX(stg_WEAK_info) \
118 SymX(stg_CHARLIKE_closure) \
119 SymX(stg_INTLIKE_closure) \
121 SymX(newBCOzh_fast) \
122 SymX(mkApUpd0zh_fast) \
123 SymX(putMVarzh_fast) \
124 SymX(newMVarzh_fast) \
125 SymX(takeMVarzh_fast) \
126 SymX(tryTakeMVarzh_fast) \
127 SymX(tryPutMVarzh_fast) \
133 SymX(killThreadzh_fast) \
134 SymX(waitReadzh_fast) \
135 SymX(waitWritezh_fast) \
136 SymX(suspendThread) \
138 SymX(stackOverflow) \
139 SymX(int2Integerzh_fast) \
140 SymX(word2Integerzh_fast) \
142 SymX(__encodeDouble) \
143 SymX(decodeDoublezh_fast) \
144 SymX(decodeFloatzh_fast) \
145 SymX(gcdIntegerzh_fast) \
146 SymX(newArrayzh_fast) \
147 SymX(unsafeThawArrayzh_fast) \
148 SymX(newByteArrayzh_fast) \
149 SymX(newMutVarzh_fast) \
150 SymX(quotRemIntegerzh_fast) \
151 SymX(quotIntegerzh_fast) \
152 SymX(remIntegerzh_fast) \
153 SymX(divExactIntegerzh_fast) \
154 SymX(divModIntegerzh_fast) \
155 SymX(timesIntegerzh_fast) \
156 SymX(minusIntegerzh_fast) \
157 SymX(plusIntegerzh_fast) \
158 SymX(andIntegerzh_fast) \
159 SymX(orIntegerzh_fast) \
160 SymX(xorIntegerzh_fast) \
161 SymX(complementIntegerzh_fast) \
163 SymX(blockAsyncExceptionszh_fast) \
164 SymX(unblockAsyncExceptionszh_fast) \
166 SymX(isDoubleInfinite) \
167 SymX(isDoubleDenormalized) \
168 SymX(isDoubleNegativeZero) \
169 SymX(__encodeFloat) \
171 SymX(isFloatInfinite) \
172 SymX(isFloatDenormalized) \
173 SymX(isFloatNegativeZero) \
174 SymX(__int_encodeFloat) \
175 SymX(__int_encodeDouble) \
176 SymX(__gmpz_cmp_si) \
177 SymX(__gmpz_cmp_ui) \
182 SymX(resetNonBlockingFd) \
184 SymX(stable_ptr_table) \
185 SymX(shutdownHaskellAndExit) \
186 Sym(stg_enterStackTop) \
187 Sym(stg_yield_to_interpreter) \
191 Sym(__init_PrelGHC) \
192 SymX(freeHaskellFunctionPtr) \
195 SymX(NoRunnableThreadsHook) \
196 SymX(StackOverflowHook) \
197 SymX(OutOfHeapHook) \
198 SymX(MallocFailHook) \
199 SymX(PatErrorHdrHook) \
202 SymX(PostTraceHook) \
203 SymX(stg_sig_install) \
205 SymX(createAdjustor) \
207 SymX(rts_mkStablePtr) \
210 SymX(rts_checkSchedStatus) \
213 #ifndef SUPPORT_LONG_LONGS
214 #define RTS_LONG_LONG_SYMS /* nothing */
216 #define RTS_LONG_LONG_SYMS \
229 SymX(stg_remWord64) \
230 SymX(stg_quotWord64) \
232 SymX(stg_quotInt64) \
233 SymX(stg_negateInt64) \
234 SymX(stg_plusInt64) \
235 SymX(stg_minusInt64) \
236 SymX(stg_timesInt64) \
242 SymX(stg_shiftRL64) \
243 SymX(stg_iShiftL64) \
244 SymX(stg_iShiftRL64) \
245 SymX(stg_iShiftRA64) \
246 SymX(stg_intToInt64) \
247 SymX(stg_int64ToInt) \
248 SymX(stg_int64ToWord64) \
249 SymX(stg_wordToWord64) \
250 SymX(stg_word64ToWord) \
251 SymX(stg_word64ToInt64) \
252 SymX(int64ToIntegerzh_fast) \
253 SymX(word64ToIntegerzh_fast)
254 #endif /* SUPPORT_LONG_LONGS */
256 /* entirely bogus claims about types of these symbols */
257 #define Sym(vvv) extern void (vvv);
258 #define SymX(vvv) /**/
263 #ifdef LEADING_UNDERSCORE
264 #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
266 #define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
269 #define Sym(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
271 #define SymX(vvv) Sym(vvv)
273 static RtsSymbolVal rtsSyms[] = {
276 { 0, 0 } /* sentinel */
279 /* -----------------------------------------------------------------------------
280 * initialize the object linker
282 #if defined(OBJFORMAT_ELF)
283 static void *dl_prog_handle;
291 symhash = allocStrHashTable();
293 /* populate the symbol table with stuff from the RTS */
294 for (sym = rtsSyms; sym->lbl != NULL; sym++) {
295 insertStrHashTable(symhash, sym->lbl, sym->addr);
297 # if defined(OBJFORMAT_ELF)
298 dl_prog_handle = dlopen(NULL, RTLD_LAZY);
302 /* -----------------------------------------------------------------------------
303 * Add a DLL from which symbols may be found. In the ELF case, just
304 * do RTLD_GLOBAL-style add, so no further messing around needs to
305 * happen in order that symbols in the loaded .so are findable --
306 * lookupSymbol() will subsequently see them by dlsym on the program's
307 * dl-handle. Returns 0 if fail, 1 if success.
310 addDLL ( char* dll_name )
312 # if defined(OBJFORMAT_ELF)
317 buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
318 sprintf(buf, "lib%s.so", dll_name);
319 hdl = dlopen(buf, RTLD_NOW | RTLD_GLOBAL );
322 /* dlopen failed; return a ptr to the error msg. */
324 if (errmsg == NULL) errmsg = "addDLL: unknown error";
329 ASSERT(0); /*NOTREACHED*/
330 # elif defined(OBJFORMAT_PEi386)
331 barf("addDLL: not implemented on PEi386 yet");
334 barf("addDLL: not implemented on this platform");
338 /* -----------------------------------------------------------------------------
339 * lookup a symbol in the hash table
342 lookupSymbol( char *lbl )
345 ASSERT(symhash != NULL);
346 val = lookupStrHashTable(symhash, lbl);
349 # if defined(OBJFORMAT_ELF)
350 return dlsym(dl_prog_handle, lbl);
351 # elif defined(OBJFORMAT_PEi386)
362 lookupLocalSymbol( ObjectCode* oc, char *lbl )
365 val = lookupStrHashTable(oc->lochash, lbl);
375 /* -----------------------------------------------------------------------------
376 * Load an obj (populate the global symbol table, but don't resolve yet)
378 * Returns: 1 if ok, 0 on error.
381 loadObj( char *path )
389 /* assert that we haven't already loaded this object */
392 for (o = objects; o; o = o->next)
393 ASSERT(strcmp(o->fileName, path));
397 oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
399 # if defined(OBJFORMAT_ELF)
400 oc->formatName = "ELF";
401 # elif defined(OBJFORMAT_PEi386)
402 oc->formatName = "PEi386";
405 barf("loadObj: not implemented on this platform");
409 if (r == -1) { return 0; }
411 /* sigh, strdup() isn't a POSIX function, so do it the long way */
412 oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
413 strcpy(oc->fileName, path);
415 oc->fileSize = st.st_size;
416 oc->image = stgMallocBytes( st.st_size, "loadObj(image)" );
419 oc->lochash = allocStrHashTable();
421 /* chain it onto the list of objects */
425 /* load the image into memory */
426 f = fopen(path, "rb");
428 barf("loadObj: can't read `%s'", path);
430 n = fread ( oc->image, 1, oc->fileSize, f );
431 if (n != oc->fileSize) {
433 barf("loadObj: error whilst reading `%s'", path);
436 /* verify the in-memory image */
437 # if defined(OBJFORMAT_ELF)
438 r = ocVerifyImage_ELF ( oc );
439 # elif defined(OBJFORMAT_PEi386)
440 r = ocVerifyImage_PEi386 ( oc );
442 barf("loadObj: no verify method");
444 if (!r) { return r; }
446 /* build the symbol list for this image */
447 # if defined(OBJFORMAT_ELF)
448 r = ocGetNames_ELF ( oc );
449 # elif defined(OBJFORMAT_PEi386)
450 r = ocGetNames_PEi386 ( oc );
452 barf("loadObj: no getNames method");
454 if (!r) { return r; }
456 /* loaded, but not resolved yet */
457 oc->status = OBJECT_LOADED;
462 /* -----------------------------------------------------------------------------
463 * resolve all the currently unlinked objects in memory
465 * Returns: 1 if ok, 0 on error.
473 for (oc = objects; oc; oc = oc->next) {
474 if (oc->status != OBJECT_RESOLVED) {
475 # if defined(OBJFORMAT_ELF)
476 r = ocResolve_ELF ( oc );
477 # elif defined(OBJFORMAT_PEi386)
478 r = ocResolve_PEi386 ( oc );
480 barf("resolveObjs: not implemented on this platform");
482 if (!r) { return r; }
483 oc->status = OBJECT_RESOLVED;
489 /* -----------------------------------------------------------------------------
490 * delete an object from the pool
493 unloadObj( char *path )
495 ObjectCode *oc, *prev;
497 ASSERT(symhash != NULL);
498 ASSERT(objects != NULL);
501 for (oc = objects; oc; prev = oc, oc = oc->next) {
502 if (!strcmp(oc->fileName,path)) {
504 /* Remove all the mappings for the symbols within this
509 for (i = 0; i < oc->n_symbols; i++) {
510 if (oc->symbols[i] != NULL) {
511 removeStrHashTable(symhash, oc->symbols[i], NULL);
519 prev->next = oc->next;
522 /* We're going to leave this in place, in case there are
523 any pointers from the heap into it: */
524 /* free(oc->image); */
528 /* The local hash table should have been freed at the end
529 of the ocResolve_ call on it. */
530 ASSERT(oc->lochash == NULL);
536 belch("unloadObj: can't find `%s' to unload", path);
540 /* --------------------------------------------------------------------------
541 * PEi386 specifics (Win32 targets)
542 * ------------------------------------------------------------------------*/
544 /* The information for this linker comes from
545 Microsoft Portable Executable
546 and Common Object File Format Specification
547 revision 5.1 January 1998
548 which SimonM says comes from the MS Developer Network CDs.
552 #if defined(OBJFORMAT_PEi386)
556 typedef unsigned char UChar;
557 typedef unsigned short UInt16;
558 typedef unsigned int UInt32;
565 UInt16 NumberOfSections;
566 UInt32 TimeDateStamp;
567 UInt32 PointerToSymbolTable;
568 UInt32 NumberOfSymbols;
569 UInt16 SizeOfOptionalHeader;
570 UInt16 Characteristics;
574 #define sizeof_COFF_header 20
581 UInt32 VirtualAddress;
582 UInt32 SizeOfRawData;
583 UInt32 PointerToRawData;
584 UInt32 PointerToRelocations;
585 UInt32 PointerToLinenumbers;
586 UInt16 NumberOfRelocations;
587 UInt16 NumberOfLineNumbers;
588 UInt32 Characteristics;
592 #define sizeof_COFF_section 40
599 UInt16 SectionNumber;
602 UChar NumberOfAuxSymbols;
606 #define sizeof_COFF_symbol 18
611 UInt32 VirtualAddress;
612 UInt32 SymbolTableIndex;
617 #define sizeof_COFF_reloc 10
620 /* From PE spec doc, section 3.3.2 */
621 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001
622 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
623 #define IMAGE_FILE_DLL 0x2000
624 #define IMAGE_FILE_SYSTEM 0x1000
625 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
626 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
627 #define IMAGE_FILE_32BIT_MACHINE 0x0100
629 /* From PE spec doc, section 5.4.2 and 5.4.4 */
630 #define IMAGE_SYM_CLASS_EXTERNAL 2
631 #define IMAGE_SYM_CLASS_STATIC 3
632 #define IMAGE_SYM_UNDEFINED 0
634 /* From PE spec doc, section 4.1 */
635 #define IMAGE_SCN_CNT_CODE 0x00000020
636 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
638 /* From PE spec doc, section 5.2.1 */
639 #define IMAGE_REL_I386_DIR32 0x0006
640 #define IMAGE_REL_I386_REL32 0x0014
643 /* We use myindex to calculate array addresses, rather than
644 simply doing the normal subscript thing. That's because
645 some of the above structs have sizes which are not
646 a whole number of words. GCC rounds their sizes up to a
647 whole number of words, which means that the address calcs
648 arising from using normal C indexing or pointer arithmetic
649 are just plain wrong. Sigh.
652 myindex ( int scale, void* base, int index )
655 ((UChar*)base) + scale * index;
660 printName ( UChar* name, UChar* strtab )
662 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
663 UInt32 strtab_offset = * (UInt32*)(name+4);
664 fprintf ( stderr, "%s", strtab + strtab_offset );
667 for (i = 0; i < 8; i++) {
668 if (name[i] == 0) break;
669 fprintf ( stderr, "%c", name[i] );
676 copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
678 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
679 UInt32 strtab_offset = * (UInt32*)(name+4);
680 strncpy ( dst, strtab+strtab_offset, dstSize );
686 if (name[i] == 0) break;
696 cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
699 /* If the string is longer than 8 bytes, look in the
700 string table for it -- this will be correctly zero terminated.
702 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
703 UInt32 strtab_offset = * (UInt32*)(name+4);
704 return ((UChar*)strtab) + strtab_offset;
706 /* Otherwise, if shorter than 8 bytes, return the original,
707 which by defn is correctly terminated.
709 if (name[7]==0) return name;
710 /* The annoying case: 8 bytes. Copy into a temporary
711 (which is never freed ...)
713 newstr = stgMallocBytes(9, "cstring_from_COFF_symbol_name");
715 strncpy(newstr,name,8);
721 /* Just compares the short names (first 8 chars) */
722 static COFF_section *
723 findPEi386SectionCalled ( ObjectCode* oc, char* name )
727 = (COFF_header*)(oc->image);
730 ((UChar*)(oc->image))
731 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
733 for (i = 0; i < hdr->NumberOfSections; i++) {
736 COFF_section* section_i
738 myindex ( sizeof_COFF_section, sectab, i );
739 n1 = (UChar*) &(section_i->Name);
741 if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] &&
742 n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] &&
743 n1[6]==n2[6] && n1[7]==n2[7])
752 zapTrailingAtSign ( UChar* sym )
754 # define my_isdigit(c) ((c) >= '0' && (c) <= '9')
756 if (sym[0] == 0) return;
758 while (sym[i] != 0) i++;
761 while (j > 0 && my_isdigit(sym[j])) j--;
762 if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
768 ocVerifyImage_PEi386 ( ObjectCode* oc )
772 COFF_section* sectab;
776 hdr = (COFF_header*)(oc->image);
777 sectab = (COFF_section*) (
778 ((UChar*)(oc->image))
779 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
781 symtab = (COFF_symbol*) (
782 ((UChar*)(oc->image))
783 + hdr->PointerToSymbolTable
785 strtab = ((UChar*)(oc->image))
786 + hdr->PointerToSymbolTable
787 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
789 if (hdr->Machine != 0x14c) {
790 belch("Not x86 PEi386");
793 if (hdr->SizeOfOptionalHeader != 0) {
794 belch("PEi386 with nonempty optional header");
797 if ( /* (hdr->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) || */
798 (hdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ||
799 (hdr->Characteristics & IMAGE_FILE_DLL) ||
800 (hdr->Characteristics & IMAGE_FILE_SYSTEM) ) {
801 belch("Not a PEi386 object file");
804 if ( (hdr->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI) ||
805 !(hdr->Characteristics & IMAGE_FILE_32BIT_MACHINE) ) {
806 belch("Invalid PEi386 word size or endiannness");
810 /* No further verification after this point; only debug printing. */
812 IF_DEBUG(linker, i=1);
813 if (i == 0) return 1;
816 "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
818 "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
820 "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
822 fprintf ( stderr, "\n" );
824 "Machine: 0x%x\n", (UInt32)(hdr->Machine) );
826 "# sections: %d\n", (UInt32)(hdr->NumberOfSections) );
828 "time/date: 0x%x\n", (UInt32)(hdr->TimeDateStamp) );
830 "symtab offset: %d\n", (UInt32)(hdr->PointerToSymbolTable) );
832 "# symbols: %d\n", (UInt32)(hdr->NumberOfSymbols) );
834 "sz of opt hdr: %d\n", (UInt32)(hdr->SizeOfOptionalHeader) );
836 "characteristics: 0x%x\n", (UInt32)(hdr->Characteristics) );
838 fprintf ( stderr, "\n" );
839 fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
840 fprintf ( stderr, "---START of string table---\n");
841 for (i = 4; i < *(Int32*)strtab; i++) {
843 fprintf ( stderr, "\n"); else
844 fprintf( stderr, "%c", strtab[i] );
846 fprintf ( stderr, "--- END of string table---\n");
848 fprintf ( stderr, "\n" );
849 for (i = 0; i < hdr->NumberOfSections; i++) {
851 COFF_section* sectab_i
853 myindex ( sizeof_COFF_section, sectab, i );
860 printName ( sectab_i->Name, strtab );
869 sectab_i->VirtualSize,
870 sectab_i->VirtualAddress,
871 sectab_i->SizeOfRawData,
872 sectab_i->PointerToRawData,
873 sectab_i->NumberOfRelocations,
874 sectab_i->PointerToRelocations
876 reltab = (COFF_reloc*) (
877 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
879 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
881 COFF_reloc* rel = (COFF_reloc*)
882 myindex ( sizeof_COFF_reloc, reltab, j );
884 " type 0x%-4x vaddr 0x%-8x name `",
886 rel->VirtualAddress );
888 myindex ( sizeof_COFF_symbol, symtab, rel->SymbolTableIndex );
889 printName ( sym->Name, strtab );
890 fprintf ( stderr, "'\n" );
892 fprintf ( stderr, "\n" );
896 fprintf ( stderr, "\n" );
899 COFF_symbol* symtab_i;
900 if (i >= (Int32)(hdr->NumberOfSymbols)) break;
901 symtab_i = (COFF_symbol*)
902 myindex ( sizeof_COFF_symbol, symtab, i );
908 printName ( symtab_i->Name, strtab );
917 (Int32)(symtab_i->SectionNumber) - 1,
918 (UInt32)symtab_i->Type,
919 (UInt32)symtab_i->StorageClass,
920 (UInt32)symtab_i->NumberOfAuxSymbols
922 i += symtab_i->NumberOfAuxSymbols;
926 fprintf ( stderr, "\n" );
933 ocGetNames_PEi386 ( ObjectCode* oc )
936 COFF_section* sectab;
944 hdr = (COFF_header*)(oc->image);
945 sectab = (COFF_section*) (
946 ((UChar*)(oc->image))
947 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
949 symtab = (COFF_symbol*) (
950 ((UChar*)(oc->image))
951 + hdr->PointerToSymbolTable
953 strtab = ((UChar*)(oc->image))
954 + hdr->PointerToSymbolTable
955 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
957 /* Copy exported symbols into the ObjectCode. */
959 oc->n_symbols = hdr->NumberOfSymbols;
960 oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
961 "ocGetNames_PEi386(oc->symbols)");
962 /* Call me paranoid; I don't care. */
963 for (i = 0; i < oc->n_symbols; i++)
964 oc->symbols[i] = NULL;
968 COFF_symbol* symtab_i;
969 if (i >= (Int32)(hdr->NumberOfSymbols)) break;
970 symtab_i = (COFF_symbol*)
971 myindex ( sizeof_COFF_symbol, symtab, i );
973 if (symtab_i->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
974 symtab_i->SectionNumber != IMAGE_SYM_UNDEFINED) {
976 /* This symbol is global and defined, viz, exported */
977 COFF_section* sectabent;
979 /* cstring_from_COFF_symbol_name always succeeds. */
980 sname = cstring_from_COFF_symbol_name ( symtab_i->Name, strtab );
982 /* for IMAGE_SYMCLASS_EXTERNAL
983 && !IMAGE_SYM_UNDEFINED,
984 the address of the symbol is:
985 address of relevant section + offset in section
987 sectabent = (COFF_section*)
988 myindex ( sizeof_COFF_section,
990 symtab_i->SectionNumber-1 );
991 addr = ((UChar*)(oc->image))
992 + (sectabent->PointerToRawData
994 IF_DEBUG(linker, belch("addSymbol %p `%s'\n", addr,sname);)
995 ASSERT(i >= 0 && i < oc->n_symbols);
996 oc->symbols[i] = sname;
997 insertStrHashTable(symhash, sname, addr);
999 i += symtab_i->NumberOfAuxSymbols;
1003 /* Copy section information into the ObjectCode. */
1005 oc->n_sections = hdr->NumberOfSections;
1006 oc->sections = stgMallocBytes( oc->n_sections * sizeof(Section),
1007 "ocGetNamesPEi386" );
1009 for (i = 0; i < oc->n_sections; i++) {
1014 = SECTIONKIND_OTHER;
1015 COFF_section* sectab_i
1017 myindex ( sizeof_COFF_section, sectab, i );
1018 IF_DEBUG(linker, belchf("section name = %s\n", sectab_i->Name ));
1021 /* I'm sure this is the Right Way to do it. However, the
1022 alternative of testing the sectab_i->Name field seems to
1023 work ok with Cygwin.
1025 if (sectab_i->Characteristics & IMAGE_SCN_CNT_CODE ||
1026 sectab_i->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
1027 kind = SECTIONKIND_CODE_OR_RODATA;
1030 if (0==strcmp(".text",sectab_i->Name))
1031 kind = SECTIONKIND_CODE_OR_RODATA;
1032 if (0==strcmp(".data",sectab_i->Name) ||
1033 0==strcmp(".bss",sectab_i->Name))
1034 kind = SECTIONKIND_RWDATA;
1036 start = ((UChar*)(oc->image))
1037 + sectab_i->PointerToRawData;
1039 + sectab_i->SizeOfRawData - 1;
1041 if (kind == SECTIONKIND_OTHER) {
1042 belch("Unknown PEi386 section name `%s'", sectab_i->Name);
1046 oc->sections[i].start = start;
1047 oc->sections[i].end = end;
1048 oc->sections[i].kind = kind;
1056 ocResolve_PEi386 ( ObjectCode* oc )
1059 COFF_section* sectab;
1060 COFF_symbol* symtab;
1069 /* ToDo: should be variable-sized? But is at least safe in the
1070 sense of buffer-overrun-proof. */
1073 hdr = (COFF_header*)(oc->image);
1074 sectab = (COFF_section*) (
1075 ((UChar*)(oc->image))
1076 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1078 symtab = (COFF_symbol*) (
1079 ((UChar*)(oc->image))
1080 + hdr->PointerToSymbolTable
1082 strtab = ((UChar*)(oc->image))
1083 + hdr->PointerToSymbolTable
1084 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1086 for (i = 0; i < hdr->NumberOfSections; i++) {
1087 COFF_section* sectab_i
1089 myindex ( sizeof_COFF_section, sectab, i );
1092 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
1094 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1096 COFF_reloc* reltab_j
1098 myindex ( sizeof_COFF_reloc, reltab, j );
1100 /* the location to patch */
1102 ((UChar*)(oc->image))
1103 + (sectab_i->PointerToRawData
1104 + reltab_j->VirtualAddress)
1106 /* the existing contents of pP */
1108 /* the symbol to connect to */
1109 sym = (COFF_symbol*)
1110 myindex ( sizeof_COFF_symbol,
1111 symtab, reltab_j->SymbolTableIndex );
1114 "reloc sec %2d num %3d: type 0x%-4x "
1115 "vaddr 0x%-8x name `",
1117 (UInt32)reltab_j->Type,
1118 reltab_j->VirtualAddress );
1119 printName ( sym->Name, strtab );
1120 fprintf ( stderr, "'\n" ));
1122 if (sym->StorageClass == IMAGE_SYM_CLASS_STATIC) {
1123 COFF_section* section_sym
1124 = findPEi386SectionCalled ( oc, sym->Name );
1126 fprintf ( stderr, "bad section = `%s'\n", sym->Name );
1127 barf("Can't find abovementioned PEi386 section");
1130 S = ((UInt32)(oc->image))
1131 + (section_sym->PointerToRawData
1134 copyName ( sym->Name, strtab, symbol, 1000 );
1135 zapTrailingAtSign ( symbol );
1136 (void*)S = lookupLocalSymbol( oc, symbol );
1137 if ((void*)S == NULL)
1138 (void*)S = lookupSymbol( symbol );
1140 belch("ocResolve_PEi386: %s: unknown symbol `%s'",
1141 oc->fileName, symbol);
1146 switch (reltab_j->Type) {
1147 case IMAGE_REL_I386_DIR32:
1150 case IMAGE_REL_I386_REL32:
1151 /* Tricky. We have to insert a displacement at
1152 pP which, when added to the PC for the _next_
1153 insn, gives the address of the target (S).
1154 Problem is to know the address of the next insn
1155 when we only know pP. We assume that this
1156 literal field is always the last in the insn,
1157 so that the address of the next insn is pP+4
1158 -- hence the constant 4.
1159 Also I don't know if A should be added, but so
1160 far it has always been zero.
1163 *pP = S - ((UInt32)pP) - 4;
1167 "unhandled PEi386 relocation type %d\n",
1169 barf("unhandled PEi386 relocation type");
1179 #endif /* defined(OBJFORMAT_PEi386) */
1182 /* --------------------------------------------------------------------------
1184 * ------------------------------------------------------------------------*/
1186 #if defined(OBJFORMAT_ELF)
1191 #if defined(sparc_TARGET_ARCH)
1192 # define ELF_TARGET_SPARC /* Used inside <elf.h> */
1198 findElfSection ( void* objImage, Elf32_Word sh_type )
1201 char* ehdrC = (char*)objImage;
1202 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1203 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1205 for (i = 0; i < ehdr->e_shnum; i++) {
1206 if (shdr[i].sh_type == sh_type &&
1207 i != ehdr->e_shstrndx) {
1208 ptr = ehdrC + shdr[i].sh_offset;
1217 ocVerifyImage_ELF ( ObjectCode* oc )
1221 int i, j, nent, nstrtab, nsymtabs;
1225 char* ehdrC = (char*)(oc->image);
1226 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1228 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1229 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1230 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1231 ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1232 belch("ocVerifyImage_ELF: not an ELF header");
1235 IF_DEBUG(linker,belch( "Is an ELF header" ));
1237 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1238 belch("ocVerifyImage_ELF: not 32 bit ELF" );
1242 IF_DEBUG(linker,belch( "Is 32 bit ELF" ));
1244 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1245 IF_DEBUG(linker,belch( "Is little-endian" ));
1247 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1248 IF_DEBUG(linker,belch( "Is big-endian" ));
1250 belch("ocVerifyImage_ELF: unknown endiannness");
1254 if (ehdr->e_type != ET_REL) {
1255 belch("ocVerifyImage_ELF: not a relocatable object (.o) file");
1258 IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
1260 IF_DEBUG(linker,belch( "Architecture is " ));
1261 switch (ehdr->e_machine) {
1262 case EM_386: IF_DEBUG(linker,belch( "x86" )); break;
1263 case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
1264 default: IF_DEBUG(linker,belch( "unknown" ));
1265 belch("ocVerifyImage_ELF: unknown architecture");
1269 IF_DEBUG(linker,belch(
1270 "\nSection header table: start %d, n_entries %d, ent_size %d",
1271 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize ));
1273 ASSERT (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1275 shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1277 if (ehdr->e_shstrndx == SHN_UNDEF) {
1278 belch("ocVerifyImage_ELF: no section header string table");
1281 IF_DEBUG(linker,belch( "Section header string table is section %d",
1283 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1286 for (i = 0; i < ehdr->e_shnum; i++) {
1287 IF_DEBUG(linker,fprintf(stderr, "%2d: ", i ));
1288 IF_DEBUG(linker,fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type ));
1289 IF_DEBUG(linker,fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size ));
1290 IF_DEBUG(linker,fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset ));
1291 IF_DEBUG(linker,fprintf(stderr, " (%p .. %p) ",
1292 ehdrC + shdr[i].sh_offset,
1293 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
1295 if (shdr[i].sh_type == SHT_REL) {
1296 IF_DEBUG(linker,fprintf(stderr, "Rel " ));
1297 } else if (shdr[i].sh_type == SHT_RELA) {
1298 IF_DEBUG(linker,fprintf(stderr, "RelA " ));
1300 IF_DEBUG(linker,fprintf(stderr," "));
1303 IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
1307 IF_DEBUG(linker,belch( "\nString tables" ));
1310 for (i = 0; i < ehdr->e_shnum; i++) {
1311 if (shdr[i].sh_type == SHT_STRTAB &&
1312 i != ehdr->e_shstrndx) {
1313 IF_DEBUG(linker,belch(" section %d is a normal string table", i ));
1314 strtab = ehdrC + shdr[i].sh_offset;
1319 belch("ocVerifyImage_ELF: no string tables, or too many");
1324 IF_DEBUG(linker,belch( "\nSymbol tables" ));
1325 for (i = 0; i < ehdr->e_shnum; i++) {
1326 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1327 IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
1329 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1330 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1331 IF_DEBUG(linker,belch( " number of entries is apparently %d (%d rem)",
1333 shdr[i].sh_size % sizeof(Elf32_Sym)
1335 if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1336 belch("ocVerifyImage_ELF: non-integral number of symbol table entries");
1339 for (j = 0; j < nent; j++) {
1340 IF_DEBUG(linker,fprintf(stderr, " %2d ", j ));
1341 IF_DEBUG(linker,fprintf(stderr, " sec=%-5d size=%-3d val=%5p ",
1342 (int)stab[j].st_shndx,
1343 (int)stab[j].st_size,
1344 (char*)stab[j].st_value ));
1346 IF_DEBUG(linker,fprintf(stderr, "type=" ));
1347 switch (ELF32_ST_TYPE(stab[j].st_info)) {
1348 case STT_NOTYPE: IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
1349 case STT_OBJECT: IF_DEBUG(linker,fprintf(stderr, "object " )); break;
1350 case STT_FUNC : IF_DEBUG(linker,fprintf(stderr, "func " )); break;
1351 case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
1352 case STT_FILE: IF_DEBUG(linker,fprintf(stderr, "file " )); break;
1353 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1355 IF_DEBUG(linker,fprintf(stderr, " " ));
1357 IF_DEBUG(linker,fprintf(stderr, "bind=" ));
1358 switch (ELF32_ST_BIND(stab[j].st_info)) {
1359 case STB_LOCAL : IF_DEBUG(linker,fprintf(stderr, "local " )); break;
1360 case STB_GLOBAL: IF_DEBUG(linker,fprintf(stderr, "global" )); break;
1361 case STB_WEAK : IF_DEBUG(linker,fprintf(stderr, "weak " )); break;
1362 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1364 IF_DEBUG(linker,fprintf(stderr, " " ));
1366 IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
1370 if (nsymtabs == 0) {
1371 belch("ocVerifyImage_ELF: didn't find any symbol tables");
1380 ocGetNames_ELF ( ObjectCode* oc )
1385 char* ehdrC = (char*)(oc->image);
1386 Elf32_Ehdr* ehdr = (Elf32_Ehdr*)ehdrC;
1387 char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
1388 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1389 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1391 ASSERT(symhash != NULL);
1394 belch("ocGetNames_ELF: no strtab");
1399 oc->n_sections = ehdr->e_shnum;
1400 oc->sections = stgMallocBytes( oc->n_sections * sizeof(Section),
1401 "ocGetNames_ELF(oc->sections)" );
1403 for (i = 0; i < oc->n_sections; i++) {
1405 /* make a section entry for relevant sections */
1406 SectionKind kind = SECTIONKIND_OTHER;
1407 if (!strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1408 !strcmp(".data1",sh_strtab+shdr[i].sh_name))
1409 kind = SECTIONKIND_RWDATA;
1410 if (!strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1411 !strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1412 !strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1413 kind = SECTIONKIND_CODE_OR_RODATA;
1415 /* fill in the section info */
1416 oc->sections[i].start = ehdrC + shdr[i].sh_offset;
1417 oc->sections[i].end = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
1418 oc->sections[i].kind = kind;
1420 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1422 /* copy stuff into this module's object symbol table */
1423 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1424 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1426 oc->n_symbols = nent;
1427 oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
1428 "ocGetNames_ELF(oc->symbols)");
1430 for (j = 0; j < nent; j++) {
1431 if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
1432 || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
1434 /* and not an undefined symbol */
1435 && stab[j].st_shndx != SHN_UNDEF
1436 /* and not in a "special section" */
1437 && stab[j].st_shndx < SHN_LORESERVE
1439 /* and it's a not a section or string table or anything silly */
1440 ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1441 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
1442 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE
1445 char* nm = strtab + stab[j].st_name;
1447 + shdr[ stab[j].st_shndx ].sh_offset
1451 oc->symbols[j] = nm;
1452 if (ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL) {
1453 IF_DEBUG(linker,belch( "addOTabName(LOCL): %10p %s %s",
1454 ad, oc->fileName, nm ));
1455 insertStrHashTable(oc->lochash, nm, ad);
1457 IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p %s %s",
1458 ad, oc->fileName, nm ));
1459 insertStrHashTable(symhash, nm, ad);
1463 IF_DEBUG(linker,belch( "skipping `%s'",
1464 strtab + stab[j].st_name ));
1467 "skipping bind = %d, type = %d, shndx = %d `%s'\n",
1468 (int)ELF32_ST_BIND(stab[j].st_info),
1469 (int)ELF32_ST_TYPE(stab[j].st_info),
1470 (int)stab[j].st_shndx,
1471 strtab + stab[j].st_name
1474 oc->symbols[j] = NULL;
1483 /* Do ELF relocations which lack an explicit addend. All x86-linux
1484 relocations appear to be of this form. */
1485 static int do_Elf32_Rel_relocations ( ObjectCode* oc, char* ehdrC,
1486 Elf32_Shdr* shdr, int shnum,
1487 Elf32_Sym* stab, char* strtab )
1492 Elf32_Rel* rtab = (Elf32_Rel*) (ehdrC + shdr[shnum].sh_offset);
1493 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rel);
1494 int target_shndx = shdr[shnum].sh_info;
1495 int symtab_shndx = shdr[shnum].sh_link;
1496 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1497 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1498 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1499 target_shndx, symtab_shndx ));
1500 for (j = 0; j < nent; j++) {
1501 Elf32_Addr offset = rtab[j].r_offset;
1502 Elf32_Word info = rtab[j].r_info;
1504 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1505 Elf32_Word* pP = (Elf32_Word*)P;
1509 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)",
1510 j, (void*)offset, (void*)info ));
1512 IF_DEBUG(linker,belch( " ZERO" ));
1515 /* First see if it is a nameless local symbol. */
1516 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1517 symbol = "(noname)";
1519 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1520 + stab[ELF32_R_SYM(info)].st_value);
1522 /* No? Should be in a symbol table then; first try the
1524 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1525 (void*)S = lookupLocalSymbol( oc, symbol );
1526 if ((void*)S == NULL)
1527 (void*)S = lookupSymbol( symbol );
1530 barf("do_Elf32_Rel_relocations: %s: unknown symbol `%s'",
1531 oc->fileName, symbol);
1533 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1535 IF_DEBUG(linker,belch( "Reloc: P = %p S = %p A = %p",
1536 (void*)P, (void*)S, (void*)A ));
1537 switch (ELF32_R_TYPE(info)) {
1538 # ifdef i386_TARGET_ARCH
1539 case R_386_32: *pP = S + A; break;
1540 case R_386_PC32: *pP = S + A - P; break;
1543 fprintf(stderr, "unhandled ELF relocation(Rel) type %d\n",
1544 ELF32_R_TYPE(info));
1545 barf("do_Elf32_Rel_relocations: unhandled ELF relocation type");
1554 /* Do ELF relocations for which explicit addends are supplied.
1555 sparc-solaris relocations appear to be of this form. */
1556 static int do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
1557 Elf32_Shdr* shdr, int shnum,
1558 Elf32_Sym* stab, char* strtab )
1563 Elf32_Rela* rtab = (Elf32_Rela*) (ehdrC + shdr[shnum].sh_offset);
1564 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rela);
1565 int target_shndx = shdr[shnum].sh_info;
1566 int symtab_shndx = shdr[shnum].sh_link;
1567 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1568 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1569 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1570 target_shndx, symtab_shndx ));
1571 for (j = 0; j < nent; j++) {
1572 Elf32_Addr offset = rtab[j].r_offset;
1573 Elf32_Word info = rtab[j].r_info;
1574 Elf32_Sword addend = rtab[j].r_addend;
1576 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1577 Elf32_Addr A = addend;
1579 # if defined(sparc_TARGET_ARCH)
1580 /* This #ifdef only serves to avoid unused-var warnings. */
1581 Elf32_Word* pP = (Elf32_Word*)P;
1585 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ",
1586 j, (void*)offset, (void*)info,
1589 IF_DEBUG(linker,belch( " ZERO" ));
1592 /* First see if it is a nameless local symbol. */
1593 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1594 symbol = "(noname)";
1596 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1597 + stab[ELF32_R_SYM(info)].st_value);
1599 /* No? Should be in a symbol table then; first try the
1601 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1602 (void*)S = lookupLocalSymbol( oc, symbol );
1603 if ((void*)S == NULL)
1604 (void*)S = lookupSymbol( symbol );
1607 barf("do_Elf32_Rela_relocations: %s: unknown symbol `%s'",
1608 oc->fileName, symbol);
1611 fprintf ( stderr, "S %p A %p S+A %p S+A-P %p\n",S,A,S+A,S+A-P);
1614 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1616 IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n",
1617 (void*)P, (void*)S, (void*)A ));
1618 switch (ELF32_R_TYPE(info)) {
1619 # if defined(sparc_TARGET_ARCH)
1620 case R_SPARC_WDISP30:
1621 w1 = *pP & 0xC0000000;
1622 w2 = (Elf32_Word)((S + A - P) >> 2);
1623 ASSERT((w2 & 0xC0000000) == 0);
1628 w1 = *pP & 0xFFC00000;
1629 w2 = (Elf32_Word)((S + A) >> 10);
1630 ASSERT((w2 & 0xFFC00000) == 0);
1636 w2 = (Elf32_Word)((S + A) & 0x3FF);
1637 ASSERT((w2 & ~0x3FF) == 0);
1642 w2 = (Elf32_Word)(S + A);
1647 fprintf(stderr, "unhandled ELF relocation(RelA) type %d\n",
1648 ELF32_R_TYPE(info));
1649 barf("do_Elf32_Rela_relocations: unhandled ELF relocation type");
1659 ocResolve_ELF ( ObjectCode* oc )
1663 Elf32_Sym* stab = NULL;
1664 char* ehdrC = (char*)(oc->image);
1665 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1666 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1668 /* first find "the" symbol table */
1669 stab = (Elf32_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
1671 /* also go find the string table */
1672 strtab = findElfSection ( ehdrC, SHT_STRTAB );
1674 if (stab == NULL || strtab == NULL) {
1675 belch("ocResolve_ELF: can't find string or symbol table");
1679 /* Process the relocation sections. */
1680 for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
1681 if (shdr[shnum].sh_type == SHT_REL ) {
1682 ok = do_Elf32_Rel_relocations ( oc, ehdrC, shdr,
1683 shnum, stab, strtab );
1687 if (shdr[shnum].sh_type == SHT_RELA) {
1688 ok = do_Elf32_Rela_relocations ( oc, ehdrC, shdr,
1689 shnum, stab, strtab );
1694 /* Free the local symbol table; we won't need it again. */
1695 freeHashTable(oc->lochash, NULL);