1 /* -----------------------------------------------------------------------------
2 * $Id: Linker.c,v 1.50 2001/07/17 03:53:25 qrczak 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
38 /* Hash table mapping symbol names to Symbol */
39 /*Str*/HashTable *symhash;
41 #if defined(OBJFORMAT_ELF)
42 static int ocVerifyImage_ELF ( ObjectCode* oc );
43 static int ocGetNames_ELF ( ObjectCode* oc );
44 static int ocResolve_ELF ( ObjectCode* oc );
45 #elif defined(OBJFORMAT_PEi386)
46 static int ocVerifyImage_PEi386 ( ObjectCode* oc );
47 static int ocGetNames_PEi386 ( ObjectCode* oc );
48 static int ocResolve_PEi386 ( ObjectCode* oc );
51 /* -----------------------------------------------------------------------------
52 * Built-in symbols from the RTS
55 typedef struct _RtsSymbolVal {
62 #define Maybe_ForeignObj SymX(mkForeignObjzh_fast)
64 #define Maybe_Stable_Names SymX(mkWeakzh_fast) \
65 SymX(makeStableNamezh_fast) \
66 SymX(finalizzeWeakzh_fast)
68 /* These are not available in GUM!!! -- HWL */
69 #define Maybe_ForeignObj
70 #define Maybe_Stable_Names
73 #if !defined (mingw32_TARGET_OS)
75 #define RTS_POSIX_ONLY_SYMBOLS \
76 SymX(stg_sig_install) \
78 #define RTS_MINGW_ONLY_SYMBOLS /**/
82 #define RTS_POSIX_ONLY_SYMBOLS
84 /* These are statically linked from the mingw libraries into the ghc
85 executable, so we have to employ this hack. */
86 #define RTS_MINGW_ONLY_SYMBOLS \
100 SymX(getprotobynumber) \
101 SymX(getprotobyname) \
102 SymX(gethostbyname) \
103 SymX(gethostbyaddr) \
138 Sym(_imp___timezone) \
148 SymX(GetCurrentProcess) \
149 SymX(GetProcessTimes) \
151 SymX(GetExitCodeProcess) \
152 SymX(WaitForSingleObject) \
153 SymX(CreateProcessA) \
158 #define RTS_SYMBOLS \
160 Sym(stg_gc_enter_1) \
167 Sym(stg_gc_unpt_r1) \
168 Sym(stg_gc_unbx_r1) \
173 SymX(stg_update_PAP) \
174 SymX(stg_ap_1_upd_info) \
175 SymX(stg_ap_2_upd_info) \
176 SymX(stg_ap_3_upd_info) \
177 SymX(stg_ap_4_upd_info) \
178 SymX(stg_ap_5_upd_info) \
179 SymX(stg_ap_6_upd_info) \
180 SymX(stg_ap_7_upd_info) \
181 SymX(stg_ap_8_upd_info) \
182 SymX(stg_sel_0_upd_info) \
183 SymX(stg_sel_1_upd_info) \
184 SymX(stg_sel_2_upd_info) \
185 SymX(stg_sel_3_upd_info) \
186 SymX(stg_sel_4_upd_info) \
187 SymX(stg_sel_5_upd_info) \
188 SymX(stg_sel_6_upd_info) \
189 SymX(stg_sel_7_upd_info) \
190 SymX(stg_sel_8_upd_info) \
191 SymX(stg_sel_9_upd_info) \
192 SymX(stg_sel_10_upd_info) \
193 SymX(stg_sel_11_upd_info) \
194 SymX(stg_sel_12_upd_info) \
195 SymX(stg_sel_13_upd_info) \
196 SymX(stg_sel_14_upd_info) \
197 SymX(stg_sel_15_upd_info) \
198 SymX(stg_upd_frame_info) \
199 SymX(stg_seq_frame_info) \
200 SymX(stg_CAF_BLACKHOLE_info) \
201 SymX(stg_IND_STATIC_info) \
202 SymX(stg_EMPTY_MVAR_info) \
203 SymX(stg_MUT_ARR_PTRS_FROZEN_info) \
204 SymX(stg_WEAK_info) \
205 SymX(stg_CHARLIKE_closure) \
206 SymX(stg_INTLIKE_closure) \
208 SymX(newBCOzh_fast) \
209 SymX(mkApUpd0zh_fast) \
210 SymX(putMVarzh_fast) \
211 SymX(newMVarzh_fast) \
212 SymX(takeMVarzh_fast) \
213 SymX(tryTakeMVarzh_fast) \
214 SymX(tryPutMVarzh_fast) \
220 SymX(killThreadzh_fast) \
221 SymX(waitReadzh_fast) \
222 SymX(waitWritezh_fast) \
223 SymX(suspendThread) \
225 SymX(stackOverflow) \
226 SymX(int2Integerzh_fast) \
227 SymX(word2Integerzh_fast) \
229 SymX(__encodeDouble) \
230 SymX(decodeDoublezh_fast) \
231 SymX(decodeFloatzh_fast) \
232 SymX(gcdIntegerzh_fast) \
233 SymX(newArrayzh_fast) \
234 SymX(unsafeThawArrayzh_fast) \
235 SymX(newByteArrayzh_fast) \
236 SymX(newMutVarzh_fast) \
237 SymX(quotRemIntegerzh_fast) \
238 SymX(quotIntegerzh_fast) \
239 SymX(remIntegerzh_fast) \
240 SymX(divExactIntegerzh_fast) \
241 SymX(divModIntegerzh_fast) \
242 SymX(timesIntegerzh_fast) \
243 SymX(minusIntegerzh_fast) \
244 SymX(plusIntegerzh_fast) \
245 SymX(andIntegerzh_fast) \
246 SymX(orIntegerzh_fast) \
247 SymX(xorIntegerzh_fast) \
248 SymX(complementIntegerzh_fast) \
250 SymX(blockAsyncExceptionszh_fast) \
251 SymX(unblockAsyncExceptionszh_fast) \
253 SymX(isDoubleInfinite) \
254 SymX(isDoubleDenormalized) \
255 SymX(isDoubleNegativeZero) \
256 SymX(__encodeFloat) \
258 SymX(isFloatInfinite) \
259 SymX(isFloatDenormalized) \
260 SymX(isFloatNegativeZero) \
261 SymX(__int_encodeFloat) \
262 SymX(__int_encodeDouble) \
263 SymX(__gmpz_cmp_si) \
264 SymX(__gmpz_cmp_ui) \
267 SymX(__gmpz_get_si) \
268 SymX(__gmpz_get_ui) \
271 SymX(resetNonBlockingFd) \
274 SymX(stable_ptr_table) \
275 SymX(shutdownHaskellAndExit) \
276 Sym(stg_enterStackTop) \
277 Sym(stg_yield_to_interpreter) \
281 Sym(__init_PrelGHC) \
282 SymX(freeHaskellFunctionPtr) \
285 SymX(NoRunnableThreadsHook) \
286 SymX(StackOverflowHook) \
287 SymX(OutOfHeapHook) \
288 SymX(MallocFailHook) \
289 SymX(PatErrorHdrHook) \
292 SymX(PostTraceHook) \
293 SymX(createAdjustor) \
308 SymX(rts_mkStablePtr) \
317 SymX(rts_getWord32) \
320 SymX(rts_getDouble) \
321 SymX(rts_getStablePtr) \
327 SymX(rts_evalLazyIO) \
328 SymX(rts_checkSchedStatus)
330 #ifndef SUPPORT_LONG_LONGS
331 #define RTS_LONG_LONG_SYMS /* nothing */
333 #define RTS_LONG_LONG_SYMS \
334 SymX(int64ToIntegerzh_fast) \
335 SymX(word64ToIntegerzh_fast)
336 #endif /* SUPPORT_LONG_LONGS */
338 /* entirely bogus claims about types of these symbols */
339 #define Sym(vvv) extern void (vvv);
340 #define SymX(vvv) /**/
343 RTS_POSIX_ONLY_SYMBOLS
344 RTS_MINGW_ONLY_SYMBOLS
348 #ifdef LEADING_UNDERSCORE
349 #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
351 #define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
354 #define Sym(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
356 #define SymX(vvv) Sym(vvv)
358 static RtsSymbolVal rtsSyms[] = {
361 RTS_POSIX_ONLY_SYMBOLS
362 RTS_MINGW_ONLY_SYMBOLS
363 { 0, 0 } /* sentinel */
366 /* -----------------------------------------------------------------------------
367 * initialize the object linker
369 #if defined(OBJFORMAT_ELF)
370 static void *dl_prog_handle;
378 symhash = allocStrHashTable();
380 /* populate the symbol table with stuff from the RTS */
381 for (sym = rtsSyms; sym->lbl != NULL; sym++) {
382 insertStrHashTable(symhash, sym->lbl, sym->addr);
384 # if defined(OBJFORMAT_ELF)
385 dl_prog_handle = dlopen(NULL, RTLD_LAZY);
389 /* -----------------------------------------------------------------------------
390 * Add a DLL from which symbols may be found. In the ELF case, just
391 * do RTLD_GLOBAL-style add, so no further messing around needs to
392 * happen in order that symbols in the loaded .so are findable --
393 * lookupSymbol() will subsequently see them by dlsym on the program's
394 * dl-handle. Returns NULL if success, otherwise ptr to an err msg.
396 * In the PEi386 case, open the DLLs and put handles to them in a
397 * linked list. When looking for a symbol, try all handles in the
401 #if defined(OBJFORMAT_PEi386)
402 /* A record for storing handles into DLLs. */
407 struct _OpenedDLL* next;
412 /* A list thereof. */
413 static OpenedDLL* opened_dlls = NULL;
419 addDLL ( char* path, char* dll_name )
421 # if defined(OBJFORMAT_ELF)
426 if (path == NULL || strlen(path) == 0) {
427 buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
428 sprintf(buf, "lib%s.so", dll_name);
430 buf = stgMallocBytes(strlen(path) + 1 + strlen(dll_name) + 10, "addDll");
431 sprintf(buf, "%s/lib%s.so", path, dll_name);
433 hdl = dlopen(buf, RTLD_NOW | RTLD_GLOBAL );
436 /* dlopen failed; return a ptr to the error msg. */
438 if (errmsg == NULL) errmsg = "addDLL: unknown error";
445 # elif defined(OBJFORMAT_PEi386)
447 /* Add this DLL to the list of DLLs in which to search for symbols.
448 The path argument is ignored. */
453 /* fprintf(stderr, "\naddDLL; path=`%s', dll_name = `%s'\n", path, dll_name); */
455 /* See if we've already got it, and ignore if so. */
456 for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
457 if (0 == strcmp(o_dll->name, dll_name))
461 buf = stgMallocBytes(strlen(dll_name) + 10, "addDLL");
462 sprintf(buf, "%s.DLL", dll_name);
463 instance = LoadLibrary(buf);
465 if (instance == NULL) {
466 /* LoadLibrary failed; return a ptr to the error msg. */
467 return "addDLL: unknown error";
470 o_dll = stgMallocBytes( sizeof(OpenedDLL), "addDLL" );
471 o_dll->name = stgMallocBytes(1+strlen(dll_name), "addDLL");
472 strcpy(o_dll->name, dll_name);
473 o_dll->instance = instance;
474 o_dll->next = opened_dlls;
479 barf("addDLL: not implemented on this platform");
483 /* -----------------------------------------------------------------------------
484 * lookup a symbol in the hash table
487 lookupSymbol( char *lbl )
490 ASSERT(symhash != NULL);
491 val = lookupStrHashTable(symhash, lbl);
494 # if defined(OBJFORMAT_ELF)
495 return dlsym(dl_prog_handle, lbl);
496 # elif defined(OBJFORMAT_PEi386)
499 for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
500 /* fprintf(stderr, "look in %s for %s\n", o_dll->name, lbl); */
501 sym = GetProcAddress(o_dll->instance, lbl);
502 if (sym != NULL) return sym;
513 lookupLocalSymbol( ObjectCode* oc, char *lbl )
516 val = lookupStrHashTable(oc->lochash, lbl);
526 /* -----------------------------------------------------------------------------
527 * Load an obj (populate the global symbol table, but don't resolve yet)
529 * Returns: 1 if ok, 0 on error.
532 loadObj( char *path )
539 /* fprintf(stderr, "loadObj %s\n", path ); */
541 /* assert that we haven't already loaded this object */
544 for (o = objects; o; o = o->next)
545 ASSERT(strcmp(o->fileName, path));
549 oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
551 # if defined(OBJFORMAT_ELF)
552 oc->formatName = "ELF";
553 # elif defined(OBJFORMAT_PEi386)
554 oc->formatName = "PEi386";
557 barf("loadObj: not implemented on this platform");
561 if (r == -1) { return 0; }
563 /* sigh, strdup() isn't a POSIX function, so do it the long way */
564 oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
565 strcpy(oc->fileName, path);
567 oc->fileSize = st.st_size;
568 oc->image = stgMallocBytes( st.st_size, "loadObj(image)" );
571 oc->lochash = allocStrHashTable();
573 /* chain it onto the list of objects */
577 /* load the image into memory */
578 f = fopen(path, "rb");
580 barf("loadObj: can't read `%s'", path);
582 n = fread ( oc->image, 1, oc->fileSize, f );
583 if (n != oc->fileSize) {
585 barf("loadObj: error whilst reading `%s'", path);
588 /* verify the in-memory image */
589 # if defined(OBJFORMAT_ELF)
590 r = ocVerifyImage_ELF ( oc );
591 # elif defined(OBJFORMAT_PEi386)
592 r = ocVerifyImage_PEi386 ( oc );
594 barf("loadObj: no verify method");
596 if (!r) { return r; }
598 /* build the symbol list for this image */
599 # if defined(OBJFORMAT_ELF)
600 r = ocGetNames_ELF ( oc );
601 # elif defined(OBJFORMAT_PEi386)
602 r = ocGetNames_PEi386 ( oc );
604 barf("loadObj: no getNames method");
606 if (!r) { return r; }
608 /* loaded, but not resolved yet */
609 oc->status = OBJECT_LOADED;
614 /* -----------------------------------------------------------------------------
615 * resolve all the currently unlinked objects in memory
617 * Returns: 1 if ok, 0 on error.
625 for (oc = objects; oc; oc = oc->next) {
626 if (oc->status != OBJECT_RESOLVED) {
627 # if defined(OBJFORMAT_ELF)
628 r = ocResolve_ELF ( oc );
629 # elif defined(OBJFORMAT_PEi386)
630 r = ocResolve_PEi386 ( oc );
632 barf("resolveObjs: not implemented on this platform");
634 if (!r) { return r; }
635 oc->status = OBJECT_RESOLVED;
641 /* -----------------------------------------------------------------------------
642 * delete an object from the pool
645 unloadObj( char *path )
647 ObjectCode *oc, *prev;
649 ASSERT(symhash != NULL);
650 ASSERT(objects != NULL);
653 for (oc = objects; oc; prev = oc, oc = oc->next) {
654 if (!strcmp(oc->fileName,path)) {
656 /* Remove all the mappings for the symbols within this
661 for (i = 0; i < oc->n_symbols; i++) {
662 if (oc->symbols[i] != NULL) {
663 removeStrHashTable(symhash, oc->symbols[i], NULL);
671 prev->next = oc->next;
674 /* We're going to leave this in place, in case there are
675 any pointers from the heap into it: */
676 /* free(oc->image); */
680 /* The local hash table should have been freed at the end
681 of the ocResolve_ call on it. */
682 ASSERT(oc->lochash == NULL);
688 belch("unloadObj: can't find `%s' to unload", path);
692 /* --------------------------------------------------------------------------
693 * PEi386 specifics (Win32 targets)
694 * ------------------------------------------------------------------------*/
696 /* The information for this linker comes from
697 Microsoft Portable Executable
698 and Common Object File Format Specification
699 revision 5.1 January 1998
700 which SimonM says comes from the MS Developer Network CDs.
704 #if defined(OBJFORMAT_PEi386)
708 typedef unsigned char UChar;
709 typedef unsigned short UInt16;
710 typedef unsigned int UInt32;
717 UInt16 NumberOfSections;
718 UInt32 TimeDateStamp;
719 UInt32 PointerToSymbolTable;
720 UInt32 NumberOfSymbols;
721 UInt16 SizeOfOptionalHeader;
722 UInt16 Characteristics;
726 #define sizeof_COFF_header 20
733 UInt32 VirtualAddress;
734 UInt32 SizeOfRawData;
735 UInt32 PointerToRawData;
736 UInt32 PointerToRelocations;
737 UInt32 PointerToLinenumbers;
738 UInt16 NumberOfRelocations;
739 UInt16 NumberOfLineNumbers;
740 UInt32 Characteristics;
744 #define sizeof_COFF_section 40
751 UInt16 SectionNumber;
754 UChar NumberOfAuxSymbols;
758 #define sizeof_COFF_symbol 18
763 UInt32 VirtualAddress;
764 UInt32 SymbolTableIndex;
769 #define sizeof_COFF_reloc 10
772 /* From PE spec doc, section 3.3.2 */
773 /* Note use of MYIMAGE_* since IMAGE_* are already defined in
774 windows.h -- for the same purpose, but I want to know what I'm
776 #define MYIMAGE_FILE_RELOCS_STRIPPED 0x0001
777 #define MYIMAGE_FILE_EXECUTABLE_IMAGE 0x0002
778 #define MYIMAGE_FILE_DLL 0x2000
779 #define MYIMAGE_FILE_SYSTEM 0x1000
780 #define MYIMAGE_FILE_BYTES_REVERSED_HI 0x8000
781 #define MYIMAGE_FILE_BYTES_REVERSED_LO 0x0080
782 #define MYIMAGE_FILE_32BIT_MACHINE 0x0100
784 /* From PE spec doc, section 5.4.2 and 5.4.4 */
785 #define MYIMAGE_SYM_CLASS_EXTERNAL 2
786 #define MYIMAGE_SYM_CLASS_STATIC 3
787 #define MYIMAGE_SYM_UNDEFINED 0
789 /* From PE spec doc, section 4.1 */
790 #define MYIMAGE_SCN_CNT_CODE 0x00000020
791 #define MYIMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
793 /* From PE spec doc, section 5.2.1 */
794 #define MYIMAGE_REL_I386_DIR32 0x0006
795 #define MYIMAGE_REL_I386_REL32 0x0014
798 /* We use myindex to calculate array addresses, rather than
799 simply doing the normal subscript thing. That's because
800 some of the above structs have sizes which are not
801 a whole number of words. GCC rounds their sizes up to a
802 whole number of words, which means that the address calcs
803 arising from using normal C indexing or pointer arithmetic
804 are just plain wrong. Sigh.
807 myindex ( int scale, void* base, int index )
810 ((UChar*)base) + scale * index;
815 printName ( UChar* name, UChar* strtab )
817 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
818 UInt32 strtab_offset = * (UInt32*)(name+4);
819 fprintf ( stderr, "%s", strtab + strtab_offset );
822 for (i = 0; i < 8; i++) {
823 if (name[i] == 0) break;
824 fprintf ( stderr, "%c", name[i] );
831 copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
833 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
834 UInt32 strtab_offset = * (UInt32*)(name+4);
835 strncpy ( dst, strtab+strtab_offset, dstSize );
841 if (name[i] == 0) break;
851 cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
854 /* If the string is longer than 8 bytes, look in the
855 string table for it -- this will be correctly zero terminated.
857 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
858 UInt32 strtab_offset = * (UInt32*)(name+4);
859 return ((UChar*)strtab) + strtab_offset;
861 /* Otherwise, if shorter than 8 bytes, return the original,
862 which by defn is correctly terminated.
864 if (name[7]==0) return name;
865 /* The annoying case: 8 bytes. Copy into a temporary
866 (which is never freed ...)
868 newstr = stgMallocBytes(9, "cstring_from_COFF_symbol_name");
870 strncpy(newstr,name,8);
876 /* Just compares the short names (first 8 chars) */
877 static COFF_section *
878 findPEi386SectionCalled ( ObjectCode* oc, char* name )
882 = (COFF_header*)(oc->image);
885 ((UChar*)(oc->image))
886 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
888 for (i = 0; i < hdr->NumberOfSections; i++) {
891 COFF_section* section_i
893 myindex ( sizeof_COFF_section, sectab, i );
894 n1 = (UChar*) &(section_i->Name);
896 if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] &&
897 n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] &&
898 n1[6]==n2[6] && n1[7]==n2[7])
907 zapTrailingAtSign ( UChar* sym )
909 # define my_isdigit(c) ((c) >= '0' && (c) <= '9')
911 if (sym[0] == 0) return;
913 while (sym[i] != 0) i++;
916 while (j > 0 && my_isdigit(sym[j])) j--;
917 if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
923 ocVerifyImage_PEi386 ( ObjectCode* oc )
927 COFF_section* sectab;
930 /* fprintf(stderr, "\nLOADING %s\n", oc->fileName); */
931 hdr = (COFF_header*)(oc->image);
932 sectab = (COFF_section*) (
933 ((UChar*)(oc->image))
934 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
936 symtab = (COFF_symbol*) (
937 ((UChar*)(oc->image))
938 + hdr->PointerToSymbolTable
940 strtab = ((UChar*)symtab)
941 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
943 if (hdr->Machine != 0x14c) {
944 belch("Not x86 PEi386");
947 if (hdr->SizeOfOptionalHeader != 0) {
948 belch("PEi386 with nonempty optional header");
951 if ( /* (hdr->Characteristics & MYIMAGE_FILE_RELOCS_STRIPPED) || */
952 (hdr->Characteristics & MYIMAGE_FILE_EXECUTABLE_IMAGE) ||
953 (hdr->Characteristics & MYIMAGE_FILE_DLL) ||
954 (hdr->Characteristics & MYIMAGE_FILE_SYSTEM) ) {
955 belch("Not a PEi386 object file");
958 if ( (hdr->Characteristics & MYIMAGE_FILE_BYTES_REVERSED_HI)
959 /* || !(hdr->Characteristics & MYIMAGE_FILE_32BIT_MACHINE) */ ) {
960 belch("Invalid PEi386 word size or endiannness: %d",
961 (int)(hdr->Characteristics));
964 /* fprintf(stderr, "strtab size %d\n", * (UInt32*)strtab); */
965 if (* (UInt32*)strtab > 510000) {
966 belch("PEi386 object has suspiciously large string table; > 64k relocs?");
970 /* No further verification after this point; only debug printing. */
972 IF_DEBUG(linker, i=1);
973 if (i == 0) return 1;
976 "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
978 "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
980 "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
982 fprintf ( stderr, "\n" );
984 "Machine: 0x%x\n", (UInt32)(hdr->Machine) );
986 "# sections: %d\n", (UInt32)(hdr->NumberOfSections) );
988 "time/date: 0x%x\n", (UInt32)(hdr->TimeDateStamp) );
990 "symtab offset: %d\n", (UInt32)(hdr->PointerToSymbolTable) );
992 "# symbols: %d\n", (UInt32)(hdr->NumberOfSymbols) );
994 "sz of opt hdr: %d\n", (UInt32)(hdr->SizeOfOptionalHeader) );
996 "characteristics: 0x%x\n", (UInt32)(hdr->Characteristics) );
998 /* Print the section table. */
999 fprintf ( stderr, "\n" );
1000 for (i = 0; i < hdr->NumberOfSections; i++) {
1002 COFF_section* sectab_i
1004 myindex ( sizeof_COFF_section, sectab, i );
1011 printName ( sectab_i->Name, strtab );
1020 sectab_i->VirtualSize,
1021 sectab_i->VirtualAddress,
1022 sectab_i->SizeOfRawData,
1023 sectab_i->PointerToRawData,
1024 sectab_i->NumberOfRelocations,
1025 sectab_i->PointerToRelocations
1027 reltab = (COFF_reloc*) (
1028 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
1031 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1033 COFF_reloc* rel = (COFF_reloc*)
1034 myindex ( sizeof_COFF_reloc, reltab, j );
1036 " type 0x%-4x vaddr 0x%-8x name `",
1038 rel->VirtualAddress );
1039 sym = (COFF_symbol*)
1040 myindex ( sizeof_COFF_symbol, symtab, rel->SymbolTableIndex );
1041 printName ( sym->Name, strtab -10 );
1042 fprintf ( stderr, "'\n" );
1044 fprintf ( stderr, "\n" );
1047 fprintf ( stderr, "\n" );
1048 fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
1049 fprintf ( stderr, "---START of string table---\n");
1050 for (i = 4; i < *(Int32*)strtab; i++) {
1052 fprintf ( stderr, "\n"); else
1053 fprintf( stderr, "%c", strtab[i] );
1055 fprintf ( stderr, "--- END of string table---\n");
1057 fprintf ( stderr, "\n" );
1060 COFF_symbol* symtab_i;
1061 if (i >= (Int32)(hdr->NumberOfSymbols)) break;
1062 symtab_i = (COFF_symbol*)
1063 myindex ( sizeof_COFF_symbol, symtab, i );
1069 printName ( symtab_i->Name, strtab );
1078 (Int32)(symtab_i->SectionNumber) - 1,
1079 (UInt32)symtab_i->Type,
1080 (UInt32)symtab_i->StorageClass,
1081 (UInt32)symtab_i->NumberOfAuxSymbols
1083 i += symtab_i->NumberOfAuxSymbols;
1087 fprintf ( stderr, "\n" );
1093 ocGetNames_PEi386 ( ObjectCode* oc )
1096 COFF_section* sectab;
1097 COFF_symbol* symtab;
1104 hdr = (COFF_header*)(oc->image);
1105 sectab = (COFF_section*) (
1106 ((UChar*)(oc->image))
1107 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1109 symtab = (COFF_symbol*) (
1110 ((UChar*)(oc->image))
1111 + hdr->PointerToSymbolTable
1113 strtab = ((UChar*)(oc->image))
1114 + hdr->PointerToSymbolTable
1115 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1117 /* Copy exported symbols into the ObjectCode. */
1119 oc->n_symbols = hdr->NumberOfSymbols;
1120 oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
1121 "ocGetNames_PEi386(oc->symbols)");
1122 /* Call me paranoid; I don't care. */
1123 for (i = 0; i < oc->n_symbols; i++)
1124 oc->symbols[i] = NULL;
1128 COFF_symbol* symtab_i;
1129 if (i >= (Int32)(hdr->NumberOfSymbols)) break;
1130 symtab_i = (COFF_symbol*)
1131 myindex ( sizeof_COFF_symbol, symtab, i );
1133 if (symtab_i->StorageClass == MYIMAGE_SYM_CLASS_EXTERNAL &&
1134 symtab_i->SectionNumber != MYIMAGE_SYM_UNDEFINED) {
1136 /* This symbol is global and defined, viz, exported */
1137 COFF_section* sectabent;
1139 /* cstring_from_COFF_symbol_name always succeeds. */
1140 sname = cstring_from_COFF_symbol_name ( symtab_i->Name, strtab );
1142 /* for MYIMAGE_SYMCLASS_EXTERNAL
1143 && !MYIMAGE_SYM_UNDEFINED,
1144 the address of the symbol is:
1145 address of relevant section + offset in section
1147 sectabent = (COFF_section*)
1148 myindex ( sizeof_COFF_section,
1150 symtab_i->SectionNumber-1 );
1151 addr = ((UChar*)(oc->image))
1152 + (sectabent->PointerToRawData
1154 /* fprintf(stderr,"addSymbol %p `%s'\n", addr,sname); */
1155 IF_DEBUG(linker, belch("addSymbol %p `%s'\n", addr,sname);)
1156 ASSERT(i >= 0 && i < oc->n_symbols);
1157 oc->symbols[i] = sname;
1158 insertStrHashTable(symhash, sname, addr);
1160 i += symtab_i->NumberOfAuxSymbols;
1164 /* Copy section information into the ObjectCode. */
1166 oc->n_sections = hdr->NumberOfSections;
1167 oc->sections = stgMallocBytes( oc->n_sections * sizeof(Section),
1168 "ocGetNamesPEi386" );
1170 for (i = 0; i < oc->n_sections; i++) {
1175 = SECTIONKIND_OTHER;
1176 COFF_section* sectab_i
1178 myindex ( sizeof_COFF_section, sectab, i );
1179 IF_DEBUG(linker, belch("section name = %s\n", sectab_i->Name ));
1182 /* I'm sure this is the Right Way to do it. However, the
1183 alternative of testing the sectab_i->Name field seems to
1184 work ok with Cygwin.
1186 if (sectab_i->Characteristics & MYIMAGE_SCN_CNT_CODE ||
1187 sectab_i->Characteristics & MYIMAGE_SCN_CNT_INITIALIZED_DATA)
1188 kind = SECTIONKIND_CODE_OR_RODATA;
1191 if (0==strcmp(".text",sectab_i->Name) ||
1192 0==strcmp(".rodata",sectab_i->Name))
1193 kind = SECTIONKIND_CODE_OR_RODATA;
1194 if (0==strcmp(".data",sectab_i->Name) ||
1195 0==strcmp(".bss",sectab_i->Name))
1196 kind = SECTIONKIND_RWDATA;
1198 start = ((UChar*)(oc->image))
1199 + sectab_i->PointerToRawData;
1201 + sectab_i->SizeOfRawData - 1;
1203 if (kind == SECTIONKIND_OTHER) {
1204 belch("Unknown PEi386 section name `%s'", sectab_i->Name);
1208 oc->sections[i].start = start;
1209 oc->sections[i].end = end;
1210 oc->sections[i].kind = kind;
1218 ocResolve_PEi386 ( ObjectCode* oc )
1221 COFF_section* sectab;
1222 COFF_symbol* symtab;
1231 /* ToDo: should be variable-sized? But is at least safe in the
1232 sense of buffer-overrun-proof. */
1234 /* fprintf(stderr, "resolving for %s\n", oc->fileName); */
1236 hdr = (COFF_header*)(oc->image);
1237 sectab = (COFF_section*) (
1238 ((UChar*)(oc->image))
1239 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1241 symtab = (COFF_symbol*) (
1242 ((UChar*)(oc->image))
1243 + hdr->PointerToSymbolTable
1245 strtab = ((UChar*)(oc->image))
1246 + hdr->PointerToSymbolTable
1247 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1249 for (i = 0; i < hdr->NumberOfSections; i++) {
1250 COFF_section* sectab_i
1252 myindex ( sizeof_COFF_section, sectab, i );
1255 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
1257 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1259 COFF_reloc* reltab_j
1261 myindex ( sizeof_COFF_reloc, reltab, j );
1263 /* the location to patch */
1265 ((UChar*)(oc->image))
1266 + (sectab_i->PointerToRawData
1267 + reltab_j->VirtualAddress
1268 - sectab_i->VirtualAddress )
1270 /* the existing contents of pP */
1272 /* the symbol to connect to */
1273 sym = (COFF_symbol*)
1274 myindex ( sizeof_COFF_symbol,
1275 symtab, reltab_j->SymbolTableIndex );
1278 "reloc sec %2d num %3d: type 0x%-4x "
1279 "vaddr 0x%-8x name `",
1281 (UInt32)reltab_j->Type,
1282 reltab_j->VirtualAddress );
1283 printName ( sym->Name, strtab );
1284 fprintf ( stderr, "'\n" ));
1286 if (sym->StorageClass == MYIMAGE_SYM_CLASS_STATIC) {
1287 COFF_section* section_sym
1288 = findPEi386SectionCalled ( oc, sym->Name );
1290 fprintf ( stderr, "bad section = `%s'\n", sym->Name );
1291 barf("Can't find abovementioned PEi386 section");
1294 S = ((UInt32)(oc->image))
1295 + (section_sym->PointerToRawData
1298 copyName ( sym->Name, strtab, symbol, 1000-1 );
1299 zapTrailingAtSign ( symbol );
1300 (void*)S = lookupLocalSymbol( oc, symbol );
1301 if ((void*)S == NULL)
1302 (void*)S = lookupSymbol( symbol );
1304 belch("ocResolve_PEi386: %s: unknown symbol `%s'",
1305 oc->fileName, symbol);
1310 switch (reltab_j->Type) {
1311 case MYIMAGE_REL_I386_DIR32:
1314 case MYIMAGE_REL_I386_REL32:
1315 /* Tricky. We have to insert a displacement at
1316 pP which, when added to the PC for the _next_
1317 insn, gives the address of the target (S).
1318 Problem is to know the address of the next insn
1319 when we only know pP. We assume that this
1320 literal field is always the last in the insn,
1321 so that the address of the next insn is pP+4
1322 -- hence the constant 4.
1323 Also I don't know if A should be added, but so
1324 far it has always been zero.
1327 *pP = S - ((UInt32)pP) - 4;
1331 "unhandled PEi386 relocation type %d\n",
1333 barf("unhandled PEi386 relocation type");
1340 /* fprintf(stderr, "completed %s\n", oc->fileName); */
1344 #endif /* defined(OBJFORMAT_PEi386) */
1347 /* --------------------------------------------------------------------------
1349 * ------------------------------------------------------------------------*/
1351 #if defined(OBJFORMAT_ELF)
1356 #if defined(sparc_TARGET_ARCH)
1357 # define ELF_TARGET_SPARC /* Used inside <elf.h> */
1363 findElfSection ( void* objImage, Elf32_Word sh_type )
1366 char* ehdrC = (char*)objImage;
1367 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1368 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1370 for (i = 0; i < ehdr->e_shnum; i++) {
1371 if (shdr[i].sh_type == sh_type &&
1372 i != ehdr->e_shstrndx) {
1373 ptr = ehdrC + shdr[i].sh_offset;
1382 ocVerifyImage_ELF ( ObjectCode* oc )
1386 int i, j, nent, nstrtab, nsymtabs;
1390 char* ehdrC = (char*)(oc->image);
1391 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1393 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1394 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1395 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1396 ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1397 belch("ocVerifyImage_ELF: not an ELF header");
1400 IF_DEBUG(linker,belch( "Is an ELF header" ));
1402 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1403 belch("ocVerifyImage_ELF: not 32 bit ELF" );
1407 IF_DEBUG(linker,belch( "Is 32 bit ELF" ));
1409 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1410 IF_DEBUG(linker,belch( "Is little-endian" ));
1412 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1413 IF_DEBUG(linker,belch( "Is big-endian" ));
1415 belch("ocVerifyImage_ELF: unknown endiannness");
1419 if (ehdr->e_type != ET_REL) {
1420 belch("ocVerifyImage_ELF: not a relocatable object (.o) file");
1423 IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
1425 IF_DEBUG(linker,belch( "Architecture is " ));
1426 switch (ehdr->e_machine) {
1427 case EM_386: IF_DEBUG(linker,belch( "x86" )); break;
1428 case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
1429 default: IF_DEBUG(linker,belch( "unknown" ));
1430 belch("ocVerifyImage_ELF: unknown architecture");
1434 IF_DEBUG(linker,belch(
1435 "\nSection header table: start %d, n_entries %d, ent_size %d",
1436 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize ));
1438 ASSERT (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1440 shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1442 if (ehdr->e_shstrndx == SHN_UNDEF) {
1443 belch("ocVerifyImage_ELF: no section header string table");
1446 IF_DEBUG(linker,belch( "Section header string table is section %d",
1448 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1451 for (i = 0; i < ehdr->e_shnum; i++) {
1452 IF_DEBUG(linker,fprintf(stderr, "%2d: ", i ));
1453 IF_DEBUG(linker,fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type ));
1454 IF_DEBUG(linker,fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size ));
1455 IF_DEBUG(linker,fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset ));
1456 IF_DEBUG(linker,fprintf(stderr, " (%p .. %p) ",
1457 ehdrC + shdr[i].sh_offset,
1458 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
1460 if (shdr[i].sh_type == SHT_REL) {
1461 IF_DEBUG(linker,fprintf(stderr, "Rel " ));
1462 } else if (shdr[i].sh_type == SHT_RELA) {
1463 IF_DEBUG(linker,fprintf(stderr, "RelA " ));
1465 IF_DEBUG(linker,fprintf(stderr," "));
1468 IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
1472 IF_DEBUG(linker,belch( "\nString tables" ));
1475 for (i = 0; i < ehdr->e_shnum; i++) {
1476 if (shdr[i].sh_type == SHT_STRTAB &&
1477 i != ehdr->e_shstrndx) {
1478 IF_DEBUG(linker,belch(" section %d is a normal string table", i ));
1479 strtab = ehdrC + shdr[i].sh_offset;
1484 belch("ocVerifyImage_ELF: no string tables, or too many");
1489 IF_DEBUG(linker,belch( "\nSymbol tables" ));
1490 for (i = 0; i < ehdr->e_shnum; i++) {
1491 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1492 IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
1494 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1495 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1496 IF_DEBUG(linker,belch( " number of entries is apparently %d (%d rem)",
1498 shdr[i].sh_size % sizeof(Elf32_Sym)
1500 if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1501 belch("ocVerifyImage_ELF: non-integral number of symbol table entries");
1504 for (j = 0; j < nent; j++) {
1505 IF_DEBUG(linker,fprintf(stderr, " %2d ", j ));
1506 IF_DEBUG(linker,fprintf(stderr, " sec=%-5d size=%-3d val=%5p ",
1507 (int)stab[j].st_shndx,
1508 (int)stab[j].st_size,
1509 (char*)stab[j].st_value ));
1511 IF_DEBUG(linker,fprintf(stderr, "type=" ));
1512 switch (ELF32_ST_TYPE(stab[j].st_info)) {
1513 case STT_NOTYPE: IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
1514 case STT_OBJECT: IF_DEBUG(linker,fprintf(stderr, "object " )); break;
1515 case STT_FUNC : IF_DEBUG(linker,fprintf(stderr, "func " )); break;
1516 case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
1517 case STT_FILE: IF_DEBUG(linker,fprintf(stderr, "file " )); break;
1518 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1520 IF_DEBUG(linker,fprintf(stderr, " " ));
1522 IF_DEBUG(linker,fprintf(stderr, "bind=" ));
1523 switch (ELF32_ST_BIND(stab[j].st_info)) {
1524 case STB_LOCAL : IF_DEBUG(linker,fprintf(stderr, "local " )); break;
1525 case STB_GLOBAL: IF_DEBUG(linker,fprintf(stderr, "global" )); break;
1526 case STB_WEAK : IF_DEBUG(linker,fprintf(stderr, "weak " )); break;
1527 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1529 IF_DEBUG(linker,fprintf(stderr, " " ));
1531 IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
1535 if (nsymtabs == 0) {
1536 belch("ocVerifyImage_ELF: didn't find any symbol tables");
1545 ocGetNames_ELF ( ObjectCode* oc )
1550 char* ehdrC = (char*)(oc->image);
1551 Elf32_Ehdr* ehdr = (Elf32_Ehdr*)ehdrC;
1552 char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
1553 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1554 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1556 ASSERT(symhash != NULL);
1559 belch("ocGetNames_ELF: no strtab");
1564 oc->n_sections = ehdr->e_shnum;
1565 oc->sections = stgMallocBytes( oc->n_sections * sizeof(Section),
1566 "ocGetNames_ELF(oc->sections)" );
1568 for (i = 0; i < oc->n_sections; i++) {
1570 /* make a section entry for relevant sections */
1571 SectionKind kind = SECTIONKIND_OTHER;
1572 if (!strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1573 !strcmp(".data1",sh_strtab+shdr[i].sh_name))
1574 kind = SECTIONKIND_RWDATA;
1575 if (!strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1576 !strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1577 !strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1578 kind = SECTIONKIND_CODE_OR_RODATA;
1580 /* fill in the section info */
1581 oc->sections[i].start = ehdrC + shdr[i].sh_offset;
1582 oc->sections[i].end = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
1583 oc->sections[i].kind = kind;
1585 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1587 /* copy stuff into this module's object symbol table */
1588 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1589 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1591 oc->n_symbols = nent;
1592 oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
1593 "ocGetNames_ELF(oc->symbols)");
1595 for (j = 0; j < nent; j++) {
1596 if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
1597 || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
1599 /* and not an undefined symbol */
1600 && stab[j].st_shndx != SHN_UNDEF
1601 /* and not in a "special section" */
1602 && stab[j].st_shndx < SHN_LORESERVE
1604 /* and it's a not a section or string table or anything silly */
1605 ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1606 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
1607 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE
1610 char* nm = strtab + stab[j].st_name;
1612 + shdr[ stab[j].st_shndx ].sh_offset
1616 oc->symbols[j] = nm;
1617 if (ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL) {
1618 IF_DEBUG(linker,belch( "addOTabName(LOCL): %10p %s %s",
1619 ad, oc->fileName, nm ));
1620 insertStrHashTable(oc->lochash, nm, ad);
1622 IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p %s %s",
1623 ad, oc->fileName, nm ));
1624 insertStrHashTable(symhash, nm, ad);
1628 IF_DEBUG(linker,belch( "skipping `%s'",
1629 strtab + stab[j].st_name ));
1632 "skipping bind = %d, type = %d, shndx = %d `%s'\n",
1633 (int)ELF32_ST_BIND(stab[j].st_info),
1634 (int)ELF32_ST_TYPE(stab[j].st_info),
1635 (int)stab[j].st_shndx,
1636 strtab + stab[j].st_name
1639 oc->symbols[j] = NULL;
1648 /* Do ELF relocations which lack an explicit addend. All x86-linux
1649 relocations appear to be of this form. */
1650 static int do_Elf32_Rel_relocations ( ObjectCode* oc, char* ehdrC,
1651 Elf32_Shdr* shdr, int shnum,
1652 Elf32_Sym* stab, char* strtab )
1657 Elf32_Rel* rtab = (Elf32_Rel*) (ehdrC + shdr[shnum].sh_offset);
1658 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rel);
1659 int target_shndx = shdr[shnum].sh_info;
1660 int symtab_shndx = shdr[shnum].sh_link;
1661 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1662 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1663 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1664 target_shndx, symtab_shndx ));
1665 for (j = 0; j < nent; j++) {
1666 Elf32_Addr offset = rtab[j].r_offset;
1667 Elf32_Word info = rtab[j].r_info;
1669 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1670 Elf32_Word* pP = (Elf32_Word*)P;
1674 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)",
1675 j, (void*)offset, (void*)info ));
1677 IF_DEBUG(linker,belch( " ZERO" ));
1680 /* First see if it is a nameless local symbol. */
1681 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1682 symbol = "(noname)";
1684 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1685 + stab[ELF32_R_SYM(info)].st_value);
1687 /* No? Should be in a symbol table then; first try the
1689 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1690 (void*)S = lookupLocalSymbol( oc, symbol );
1691 if ((void*)S == NULL)
1692 (void*)S = lookupSymbol( symbol );
1695 barf("do_Elf32_Rel_relocations: %s: unknown symbol `%s'",
1696 oc->fileName, symbol);
1698 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1700 IF_DEBUG(linker,belch( "Reloc: P = %p S = %p A = %p",
1701 (void*)P, (void*)S, (void*)A ));
1702 switch (ELF32_R_TYPE(info)) {
1703 # ifdef i386_TARGET_ARCH
1704 case R_386_32: *pP = S + A; break;
1705 case R_386_PC32: *pP = S + A - P; break;
1708 fprintf(stderr, "unhandled ELF relocation(Rel) type %d\n",
1709 ELF32_R_TYPE(info));
1710 barf("do_Elf32_Rel_relocations: unhandled ELF relocation type");
1719 /* Do ELF relocations for which explicit addends are supplied.
1720 sparc-solaris relocations appear to be of this form. */
1721 static int do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
1722 Elf32_Shdr* shdr, int shnum,
1723 Elf32_Sym* stab, char* strtab )
1728 Elf32_Rela* rtab = (Elf32_Rela*) (ehdrC + shdr[shnum].sh_offset);
1729 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rela);
1730 int target_shndx = shdr[shnum].sh_info;
1731 int symtab_shndx = shdr[shnum].sh_link;
1732 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1733 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1734 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1735 target_shndx, symtab_shndx ));
1736 for (j = 0; j < nent; j++) {
1737 Elf32_Addr offset = rtab[j].r_offset;
1738 Elf32_Word info = rtab[j].r_info;
1739 Elf32_Sword addend = rtab[j].r_addend;
1741 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1742 Elf32_Addr A = addend;
1744 # if defined(sparc_TARGET_ARCH)
1745 /* This #ifdef only serves to avoid unused-var warnings. */
1746 Elf32_Word* pP = (Elf32_Word*)P;
1750 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ",
1751 j, (void*)offset, (void*)info,
1754 IF_DEBUG(linker,belch( " ZERO" ));
1757 /* First see if it is a nameless local symbol. */
1758 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1759 symbol = "(noname)";
1761 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1762 + stab[ELF32_R_SYM(info)].st_value);
1764 /* No? Should be in a symbol table then; first try the
1766 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1767 (void*)S = lookupLocalSymbol( oc, symbol );
1768 if ((void*)S == NULL)
1769 (void*)S = lookupSymbol( symbol );
1772 barf("do_Elf32_Rela_relocations: %s: unknown symbol `%s'",
1773 oc->fileName, symbol);
1776 fprintf ( stderr, "S %p A %p S+A %p S+A-P %p\n",S,A,S+A,S+A-P);
1779 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1781 IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n",
1782 (void*)P, (void*)S, (void*)A ));
1783 switch (ELF32_R_TYPE(info)) {
1784 # if defined(sparc_TARGET_ARCH)
1785 case R_SPARC_WDISP30:
1786 w1 = *pP & 0xC0000000;
1787 w2 = (Elf32_Word)((S + A - P) >> 2);
1788 ASSERT((w2 & 0xC0000000) == 0);
1793 w1 = *pP & 0xFFC00000;
1794 w2 = (Elf32_Word)((S + A) >> 10);
1795 ASSERT((w2 & 0xFFC00000) == 0);
1801 w2 = (Elf32_Word)((S + A) & 0x3FF);
1802 ASSERT((w2 & ~0x3FF) == 0);
1807 w2 = (Elf32_Word)(S + A);
1812 fprintf(stderr, "unhandled ELF relocation(RelA) type %d\n",
1813 ELF32_R_TYPE(info));
1814 barf("do_Elf32_Rela_relocations: unhandled ELF relocation type");
1824 ocResolve_ELF ( ObjectCode* oc )
1828 Elf32_Sym* stab = NULL;
1829 char* ehdrC = (char*)(oc->image);
1830 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1831 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1833 /* first find "the" symbol table */
1834 stab = (Elf32_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
1836 /* also go find the string table */
1837 strtab = findElfSection ( ehdrC, SHT_STRTAB );
1839 if (stab == NULL || strtab == NULL) {
1840 belch("ocResolve_ELF: can't find string or symbol table");
1844 /* Process the relocation sections. */
1845 for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
1846 if (shdr[shnum].sh_type == SHT_REL ) {
1847 ok = do_Elf32_Rel_relocations ( oc, ehdrC, shdr,
1848 shnum, stab, strtab );
1852 if (shdr[shnum].sh_type == SHT_RELA) {
1853 ok = do_Elf32_Rela_relocations ( oc, ehdrC, shdr,
1854 shnum, stab, strtab );
1859 /* Free the local symbol table; we won't need it again. */
1860 freeHashTable(oc->lochash, NULL);