1 /* -----------------------------------------------------------------------------
2 * $Id: Linker.c,v 1.57 2001/08/14 13:40:09 sewardj Exp $
4 * (c) The GHC Team, 2000
8 * ---------------------------------------------------------------------------*/
10 #include "PosixSource.h"
16 #include "LinkerInternals.h"
18 #include "StoragePriv.h"
20 #ifdef HAVE_SYS_TYPES_H
21 #include <sys/types.h>
24 #ifdef HAVE_SYS_STAT_H
32 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS) || defined(freebsd_TARGET_OS)
33 # define OBJFORMAT_ELF
34 #elif defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS)
35 # define OBJFORMAT_PEi386
39 /* Hash table mapping symbol names to Symbol */
40 /*Str*/HashTable *symhash;
42 #if defined(OBJFORMAT_ELF)
43 static int ocVerifyImage_ELF ( ObjectCode* oc );
44 static int ocGetNames_ELF ( ObjectCode* oc );
45 static int ocResolve_ELF ( ObjectCode* oc );
46 #elif defined(OBJFORMAT_PEi386)
47 static int ocVerifyImage_PEi386 ( ObjectCode* oc );
48 static int ocGetNames_PEi386 ( ObjectCode* oc );
49 static int ocResolve_PEi386 ( ObjectCode* oc );
52 /* -----------------------------------------------------------------------------
53 * Built-in symbols from the RTS
56 typedef struct _RtsSymbolVal {
63 #define Maybe_ForeignObj SymX(mkForeignObjzh_fast)
65 #define Maybe_Stable_Names SymX(mkWeakzh_fast) \
66 SymX(makeStableNamezh_fast) \
67 SymX(finalizzeWeakzh_fast)
69 /* These are not available in GUM!!! -- HWL */
70 #define Maybe_ForeignObj
71 #define Maybe_Stable_Names
74 #if !defined (mingw32_TARGET_OS)
76 #define RTS_POSIX_ONLY_SYMBOLS \
77 SymX(stg_sig_install) \
79 #define RTS_MINGW_ONLY_SYMBOLS /**/
83 #define RTS_POSIX_ONLY_SYMBOLS
85 /* These are statically linked from the mingw libraries into the ghc
86 executable, so we have to employ this hack. */
87 #define RTS_MINGW_ONLY_SYMBOLS \
100 SymX(getservbyport) \
101 SymX(getprotobynumber) \
102 SymX(getprotobyname) \
103 SymX(gethostbyname) \
104 SymX(gethostbyaddr) \
139 Sym(_imp___timezone) \
149 SymX(GetCurrentProcess) \
150 SymX(GetProcessTimes) \
152 SymX(GetExitCodeProcess) \
153 SymX(WaitForSingleObject) \
154 SymX(CreateProcessA) \
163 #define RTS_SYMBOLS \
165 Sym(stg_gc_enter_1) \
172 Sym(stg_gc_unpt_r1) \
173 Sym(stg_gc_unbx_r1) \
178 SymX(stg_update_PAP) \
179 SymX(stg_ap_1_upd_info) \
180 SymX(stg_ap_2_upd_info) \
181 SymX(stg_ap_3_upd_info) \
182 SymX(stg_ap_4_upd_info) \
183 SymX(stg_ap_5_upd_info) \
184 SymX(stg_ap_6_upd_info) \
185 SymX(stg_ap_7_upd_info) \
186 SymX(stg_ap_8_upd_info) \
187 SymX(stg_sel_0_upd_info) \
188 SymX(stg_sel_1_upd_info) \
189 SymX(stg_sel_2_upd_info) \
190 SymX(stg_sel_3_upd_info) \
191 SymX(stg_sel_4_upd_info) \
192 SymX(stg_sel_5_upd_info) \
193 SymX(stg_sel_6_upd_info) \
194 SymX(stg_sel_7_upd_info) \
195 SymX(stg_sel_8_upd_info) \
196 SymX(stg_sel_9_upd_info) \
197 SymX(stg_sel_10_upd_info) \
198 SymX(stg_sel_11_upd_info) \
199 SymX(stg_sel_12_upd_info) \
200 SymX(stg_sel_13_upd_info) \
201 SymX(stg_sel_14_upd_info) \
202 SymX(stg_sel_15_upd_info) \
203 SymX(stg_upd_frame_info) \
204 SymX(stg_seq_frame_info) \
205 SymX(stg_CAF_BLACKHOLE_info) \
206 SymX(stg_IND_STATIC_info) \
207 SymX(stg_EMPTY_MVAR_info) \
208 SymX(stg_MUT_ARR_PTRS_FROZEN_info) \
209 SymX(stg_WEAK_info) \
210 SymX(stg_CHARLIKE_closure) \
211 SymX(stg_INTLIKE_closure) \
213 SymX(newBCOzh_fast) \
214 SymX(mkApUpd0zh_fast) \
215 SymX(putMVarzh_fast) \
216 SymX(newMVarzh_fast) \
217 SymX(takeMVarzh_fast) \
218 SymX(tryTakeMVarzh_fast) \
219 SymX(tryPutMVarzh_fast) \
225 SymX(killThreadzh_fast) \
226 SymX(waitReadzh_fast) \
227 SymX(waitWritezh_fast) \
228 SymX(suspendThread) \
230 SymX(stackOverflow) \
231 SymX(int2Integerzh_fast) \
232 SymX(word2Integerzh_fast) \
234 SymX(__encodeDouble) \
235 SymX(decodeDoublezh_fast) \
236 SymX(decodeFloatzh_fast) \
237 SymX(gcdIntegerzh_fast) \
238 SymX(newArrayzh_fast) \
239 SymX(unsafeThawArrayzh_fast) \
240 SymX(newByteArrayzh_fast) \
241 SymX(newPinnedByteArrayzh_fast) \
242 SymX(newMutVarzh_fast) \
243 SymX(quotRemIntegerzh_fast) \
244 SymX(quotIntegerzh_fast) \
245 SymX(remIntegerzh_fast) \
246 SymX(divExactIntegerzh_fast) \
247 SymX(divModIntegerzh_fast) \
248 SymX(timesIntegerzh_fast) \
249 SymX(minusIntegerzh_fast) \
250 SymX(plusIntegerzh_fast) \
251 SymX(andIntegerzh_fast) \
252 SymX(orIntegerzh_fast) \
253 SymX(xorIntegerzh_fast) \
254 SymX(complementIntegerzh_fast) \
256 SymX(blockAsyncExceptionszh_fast) \
257 SymX(unblockAsyncExceptionszh_fast) \
259 SymX(isDoubleInfinite) \
260 SymX(isDoubleDenormalized) \
261 SymX(isDoubleNegativeZero) \
262 SymX(__encodeFloat) \
264 SymX(isFloatInfinite) \
265 SymX(isFloatDenormalized) \
266 SymX(isFloatNegativeZero) \
267 SymX(__int_encodeFloat) \
268 SymX(__int_encodeDouble) \
269 SymX(__gmpz_cmp_si) \
270 SymX(__gmpz_cmp_ui) \
273 SymX(__gmpz_get_si) \
274 SymX(__gmpz_get_ui) \
277 SymX(resetNonBlockingFd) \
280 SymX(stable_ptr_table) \
281 SymX(shutdownHaskellAndExit) \
282 Sym(stg_enterStackTop) \
283 Sym(stg_yield_to_interpreter) \
287 Sym(__init_PrelGHC) \
288 SymX(freeHaskellFunctionPtr) \
291 SymX(NoRunnableThreadsHook) \
292 SymX(StackOverflowHook) \
293 SymX(OutOfHeapHook) \
294 SymX(MallocFailHook) \
295 SymX(PatErrorHdrHook) \
298 SymX(PostTraceHook) \
299 SymX(createAdjustor) \
314 SymX(rts_mkStablePtr) \
323 SymX(rts_getWord32) \
326 SymX(rts_getDouble) \
327 SymX(rts_getStablePtr) \
333 SymX(rts_evalLazyIO) \
334 SymX(rts_checkSchedStatus)
336 #ifndef SUPPORT_LONG_LONGS
337 #define RTS_LONG_LONG_SYMS /* nothing */
339 #define RTS_LONG_LONG_SYMS \
340 SymX(int64ToIntegerzh_fast) \
341 SymX(word64ToIntegerzh_fast)
342 #endif /* SUPPORT_LONG_LONGS */
344 /* entirely bogus claims about types of these symbols */
345 #define Sym(vvv) extern void (vvv);
346 #define SymX(vvv) /**/
349 RTS_POSIX_ONLY_SYMBOLS
350 RTS_MINGW_ONLY_SYMBOLS
354 #ifdef LEADING_UNDERSCORE
355 #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
357 #define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
360 #define Sym(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
362 #define SymX(vvv) Sym(vvv)
364 static RtsSymbolVal rtsSyms[] = {
367 RTS_POSIX_ONLY_SYMBOLS
368 RTS_MINGW_ONLY_SYMBOLS
369 { 0, 0 } /* sentinel */
372 /* -----------------------------------------------------------------------------
373 * initialize the object linker
375 #if defined(OBJFORMAT_ELF)
376 static void *dl_prog_handle;
384 symhash = allocStrHashTable();
386 /* populate the symbol table with stuff from the RTS */
387 for (sym = rtsSyms; sym->lbl != NULL; sym++) {
388 insertStrHashTable(symhash, sym->lbl, sym->addr);
390 # if defined(OBJFORMAT_ELF)
391 dl_prog_handle = dlopen(NULL, RTLD_LAZY);
395 /* -----------------------------------------------------------------------------
396 * Add a DLL from which symbols may be found. In the ELF case, just
397 * do RTLD_GLOBAL-style add, so no further messing around needs to
398 * happen in order that symbols in the loaded .so are findable --
399 * lookupSymbol() will subsequently see them by dlsym on the program's
400 * dl-handle. Returns NULL if success, otherwise ptr to an err msg.
402 * In the PEi386 case, open the DLLs and put handles to them in a
403 * linked list. When looking for a symbol, try all handles in the
407 #if defined(OBJFORMAT_PEi386)
408 /* A record for storing handles into DLLs. */
413 struct _OpenedDLL* next;
418 /* A list thereof. */
419 static OpenedDLL* opened_dlls = NULL;
425 addDLL ( char* path, char* dll_name )
427 # if defined(OBJFORMAT_ELF)
432 if (path == NULL || strlen(path) == 0) {
433 buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
434 sprintf(buf, "lib%s.so", dll_name);
436 buf = stgMallocBytes(strlen(path) + 1 + strlen(dll_name) + 10, "addDll");
437 sprintf(buf, "%s/lib%s.so", path, dll_name);
439 hdl = dlopen(buf, RTLD_NOW | RTLD_GLOBAL );
442 /* dlopen failed; return a ptr to the error msg. */
444 if (errmsg == NULL) errmsg = "addDLL: unknown error";
451 # elif defined(OBJFORMAT_PEi386)
453 /* Add this DLL to the list of DLLs in which to search for symbols.
454 The path argument is ignored. */
459 /* fprintf(stderr, "\naddDLL; path=`%s', dll_name = `%s'\n", path, dll_name); */
461 /* See if we've already got it, and ignore if so. */
462 for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
463 if (0 == strcmp(o_dll->name, dll_name))
467 buf = stgMallocBytes(strlen(dll_name) + 10, "addDLL");
468 sprintf(buf, "%s.DLL", dll_name);
469 instance = LoadLibrary(buf);
471 if (instance == NULL) {
472 /* LoadLibrary failed; return a ptr to the error msg. */
473 return "addDLL: unknown error";
476 o_dll = stgMallocBytes( sizeof(OpenedDLL), "addDLL" );
477 o_dll->name = stgMallocBytes(1+strlen(dll_name), "addDLL");
478 strcpy(o_dll->name, dll_name);
479 o_dll->instance = instance;
480 o_dll->next = opened_dlls;
485 barf("addDLL: not implemented on this platform");
489 /* -----------------------------------------------------------------------------
490 * lookup a symbol in the hash table
493 lookupSymbol( char *lbl )
496 ASSERT(symhash != NULL);
497 val = lookupStrHashTable(symhash, lbl);
500 # if defined(OBJFORMAT_ELF)
501 return dlsym(dl_prog_handle, lbl);
502 # elif defined(OBJFORMAT_PEi386)
505 for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
506 /* fprintf(stderr, "look in %s for %s\n", o_dll->name, lbl); */
508 /* HACK: if the name has an initial underscore, try stripping
509 it off & look that up first. I've yet to verify whether there's
510 a Rule that governs whether an initial '_' *should always* be
511 stripped off when mapping from import lib name to the DLL name.
513 sym = GetProcAddress(o_dll->instance, (lbl+1));
514 if (sym != NULL) return sym;
516 sym = GetProcAddress(o_dll->instance, lbl);
517 if (sym != NULL) return sym;
531 lookupLocalSymbol( ObjectCode* oc, char *lbl )
534 val = lookupStrHashTable(oc->lochash, lbl);
544 /* -----------------------------------------------------------------------------
545 * Load an obj (populate the global symbol table, but don't resolve yet)
547 * Returns: 1 if ok, 0 on error.
550 loadObj( char *path )
557 /* fprintf(stderr, "loadObj %s\n", path ); */
559 /* assert that we haven't already loaded this object */
562 for (o = objects; o; o = o->next)
563 ASSERT(strcmp(o->fileName, path));
567 oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
569 # if defined(OBJFORMAT_ELF)
570 oc->formatName = "ELF";
571 # elif defined(OBJFORMAT_PEi386)
572 oc->formatName = "PEi386";
575 barf("loadObj: not implemented on this platform");
579 if (r == -1) { return 0; }
581 /* sigh, strdup() isn't a POSIX function, so do it the long way */
582 oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
583 strcpy(oc->fileName, path);
585 oc->fileSize = st.st_size;
586 oc->image = stgMallocBytes( st.st_size, "loadObj(image)" );
589 oc->lochash = allocStrHashTable();
591 /* chain it onto the list of objects */
595 /* load the image into memory */
596 f = fopen(path, "rb");
598 barf("loadObj: can't read `%s'", path);
600 n = fread ( oc->image, 1, oc->fileSize, f );
601 if (n != oc->fileSize) {
603 barf("loadObj: error whilst reading `%s'", path);
606 /* verify the in-memory image */
607 # if defined(OBJFORMAT_ELF)
608 r = ocVerifyImage_ELF ( oc );
609 # elif defined(OBJFORMAT_PEi386)
610 r = ocVerifyImage_PEi386 ( oc );
612 barf("loadObj: no verify method");
614 if (!r) { return r; }
616 /* build the symbol list for this image */
617 # if defined(OBJFORMAT_ELF)
618 r = ocGetNames_ELF ( oc );
619 # elif defined(OBJFORMAT_PEi386)
620 r = ocGetNames_PEi386 ( oc );
622 barf("loadObj: no getNames method");
624 if (!r) { return r; }
626 /* loaded, but not resolved yet */
627 oc->status = OBJECT_LOADED;
632 /* -----------------------------------------------------------------------------
633 * resolve all the currently unlinked objects in memory
635 * Returns: 1 if ok, 0 on error.
643 for (oc = objects; oc; oc = oc->next) {
644 if (oc->status != OBJECT_RESOLVED) {
645 # if defined(OBJFORMAT_ELF)
646 r = ocResolve_ELF ( oc );
647 # elif defined(OBJFORMAT_PEi386)
648 r = ocResolve_PEi386 ( oc );
650 barf("resolveObjs: not implemented on this platform");
652 if (!r) { return r; }
653 oc->status = OBJECT_RESOLVED;
659 /* -----------------------------------------------------------------------------
660 * delete an object from the pool
663 unloadObj( char *path )
665 ObjectCode *oc, *prev;
667 ASSERT(symhash != NULL);
668 ASSERT(objects != NULL);
671 for (oc = objects; oc; prev = oc, oc = oc->next) {
672 if (!strcmp(oc->fileName,path)) {
674 /* Remove all the mappings for the symbols within this
679 for (i = 0; i < oc->n_symbols; i++) {
680 if (oc->symbols[i] != NULL) {
681 removeStrHashTable(symhash, oc->symbols[i], NULL);
689 prev->next = oc->next;
692 /* We're going to leave this in place, in case there are
693 any pointers from the heap into it: */
694 /* free(oc->image); */
698 /* The local hash table should have been freed at the end
699 of the ocResolve_ call on it. */
700 ASSERT(oc->lochash == NULL);
706 belch("unloadObj: can't find `%s' to unload", path);
710 /* --------------------------------------------------------------------------
711 * PEi386 specifics (Win32 targets)
712 * ------------------------------------------------------------------------*/
714 /* The information for this linker comes from
715 Microsoft Portable Executable
716 and Common Object File Format Specification
717 revision 5.1 January 1998
718 which SimonM says comes from the MS Developer Network CDs.
722 #if defined(OBJFORMAT_PEi386)
726 typedef unsigned char UChar;
727 typedef unsigned short UInt16;
728 typedef unsigned int UInt32;
735 UInt16 NumberOfSections;
736 UInt32 TimeDateStamp;
737 UInt32 PointerToSymbolTable;
738 UInt32 NumberOfSymbols;
739 UInt16 SizeOfOptionalHeader;
740 UInt16 Characteristics;
744 #define sizeof_COFF_header 20
751 UInt32 VirtualAddress;
752 UInt32 SizeOfRawData;
753 UInt32 PointerToRawData;
754 UInt32 PointerToRelocations;
755 UInt32 PointerToLinenumbers;
756 UInt16 NumberOfRelocations;
757 UInt16 NumberOfLineNumbers;
758 UInt32 Characteristics;
762 #define sizeof_COFF_section 40
769 UInt16 SectionNumber;
772 UChar NumberOfAuxSymbols;
776 #define sizeof_COFF_symbol 18
781 UInt32 VirtualAddress;
782 UInt32 SymbolTableIndex;
787 #define sizeof_COFF_reloc 10
790 /* From PE spec doc, section 3.3.2 */
791 /* Note use of MYIMAGE_* since IMAGE_* are already defined in
792 windows.h -- for the same purpose, but I want to know what I'm
794 #define MYIMAGE_FILE_RELOCS_STRIPPED 0x0001
795 #define MYIMAGE_FILE_EXECUTABLE_IMAGE 0x0002
796 #define MYIMAGE_FILE_DLL 0x2000
797 #define MYIMAGE_FILE_SYSTEM 0x1000
798 #define MYIMAGE_FILE_BYTES_REVERSED_HI 0x8000
799 #define MYIMAGE_FILE_BYTES_REVERSED_LO 0x0080
800 #define MYIMAGE_FILE_32BIT_MACHINE 0x0100
802 /* From PE spec doc, section 5.4.2 and 5.4.4 */
803 #define MYIMAGE_SYM_CLASS_EXTERNAL 2
804 #define MYIMAGE_SYM_CLASS_STATIC 3
805 #define MYIMAGE_SYM_UNDEFINED 0
807 /* From PE spec doc, section 4.1 */
808 #define MYIMAGE_SCN_CNT_CODE 0x00000020
809 #define MYIMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
811 /* From PE spec doc, section 5.2.1 */
812 #define MYIMAGE_REL_I386_DIR32 0x0006
813 #define MYIMAGE_REL_I386_REL32 0x0014
816 /* We use myindex to calculate array addresses, rather than
817 simply doing the normal subscript thing. That's because
818 some of the above structs have sizes which are not
819 a whole number of words. GCC rounds their sizes up to a
820 whole number of words, which means that the address calcs
821 arising from using normal C indexing or pointer arithmetic
822 are just plain wrong. Sigh.
825 myindex ( int scale, void* base, int index )
828 ((UChar*)base) + scale * index;
833 printName ( UChar* name, UChar* strtab )
835 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
836 UInt32 strtab_offset = * (UInt32*)(name+4);
837 fprintf ( stderr, "%s", strtab + strtab_offset );
840 for (i = 0; i < 8; i++) {
841 if (name[i] == 0) break;
842 fprintf ( stderr, "%c", name[i] );
849 copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
851 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
852 UInt32 strtab_offset = * (UInt32*)(name+4);
853 strncpy ( dst, strtab+strtab_offset, dstSize );
859 if (name[i] == 0) break;
869 cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
872 /* If the string is longer than 8 bytes, look in the
873 string table for it -- this will be correctly zero terminated.
875 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
876 UInt32 strtab_offset = * (UInt32*)(name+4);
877 return ((UChar*)strtab) + strtab_offset;
879 /* Otherwise, if shorter than 8 bytes, return the original,
880 which by defn is correctly terminated.
882 if (name[7]==0) return name;
883 /* The annoying case: 8 bytes. Copy into a temporary
884 (which is never freed ...)
886 newstr = stgMallocBytes(9, "cstring_from_COFF_symbol_name");
888 strncpy(newstr,name,8);
894 /* Just compares the short names (first 8 chars) */
895 static COFF_section *
896 findPEi386SectionCalled ( ObjectCode* oc, char* name )
900 = (COFF_header*)(oc->image);
903 ((UChar*)(oc->image))
904 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
906 for (i = 0; i < hdr->NumberOfSections; i++) {
909 COFF_section* section_i
911 myindex ( sizeof_COFF_section, sectab, i );
912 n1 = (UChar*) &(section_i->Name);
914 if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] &&
915 n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] &&
916 n1[6]==n2[6] && n1[7]==n2[7])
925 zapTrailingAtSign ( UChar* sym )
927 # define my_isdigit(c) ((c) >= '0' && (c) <= '9')
929 if (sym[0] == 0) return;
931 while (sym[i] != 0) i++;
934 while (j > 0 && my_isdigit(sym[j])) j--;
935 if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
941 ocVerifyImage_PEi386 ( ObjectCode* oc )
945 COFF_section* sectab;
948 /* fprintf(stderr, "\nLOADING %s\n", oc->fileName); */
949 hdr = (COFF_header*)(oc->image);
950 sectab = (COFF_section*) (
951 ((UChar*)(oc->image))
952 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
954 symtab = (COFF_symbol*) (
955 ((UChar*)(oc->image))
956 + hdr->PointerToSymbolTable
958 strtab = ((UChar*)symtab)
959 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
961 if (hdr->Machine != 0x14c) {
962 belch("Not x86 PEi386");
965 if (hdr->SizeOfOptionalHeader != 0) {
966 belch("PEi386 with nonempty optional header");
969 if ( /* (hdr->Characteristics & MYIMAGE_FILE_RELOCS_STRIPPED) || */
970 (hdr->Characteristics & MYIMAGE_FILE_EXECUTABLE_IMAGE) ||
971 (hdr->Characteristics & MYIMAGE_FILE_DLL) ||
972 (hdr->Characteristics & MYIMAGE_FILE_SYSTEM) ) {
973 belch("Not a PEi386 object file");
976 if ( (hdr->Characteristics & MYIMAGE_FILE_BYTES_REVERSED_HI)
977 /* || !(hdr->Characteristics & MYIMAGE_FILE_32BIT_MACHINE) */ ) {
978 belch("Invalid PEi386 word size or endiannness: %d",
979 (int)(hdr->Characteristics));
982 /* fprintf(stderr, "strtab size %d\n", * (UInt32*)strtab); */
983 if (* (UInt32*)strtab > 510000) {
984 belch("PEi386 object has suspiciously large string table; > 64k relocs?");
988 /* No further verification after this point; only debug printing. */
990 IF_DEBUG(linker, i=1);
991 if (i == 0) return 1;
994 "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
996 "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
998 "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
1000 fprintf ( stderr, "\n" );
1002 "Machine: 0x%x\n", (UInt32)(hdr->Machine) );
1004 "# sections: %d\n", (UInt32)(hdr->NumberOfSections) );
1006 "time/date: 0x%x\n", (UInt32)(hdr->TimeDateStamp) );
1008 "symtab offset: %d\n", (UInt32)(hdr->PointerToSymbolTable) );
1010 "# symbols: %d\n", (UInt32)(hdr->NumberOfSymbols) );
1012 "sz of opt hdr: %d\n", (UInt32)(hdr->SizeOfOptionalHeader) );
1014 "characteristics: 0x%x\n", (UInt32)(hdr->Characteristics) );
1016 /* Print the section table. */
1017 fprintf ( stderr, "\n" );
1018 for (i = 0; i < hdr->NumberOfSections; i++) {
1020 COFF_section* sectab_i
1022 myindex ( sizeof_COFF_section, sectab, i );
1029 printName ( sectab_i->Name, strtab );
1038 sectab_i->VirtualSize,
1039 sectab_i->VirtualAddress,
1040 sectab_i->SizeOfRawData,
1041 sectab_i->PointerToRawData,
1042 sectab_i->NumberOfRelocations,
1043 sectab_i->PointerToRelocations
1045 reltab = (COFF_reloc*) (
1046 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
1049 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1051 COFF_reloc* rel = (COFF_reloc*)
1052 myindex ( sizeof_COFF_reloc, reltab, j );
1054 " type 0x%-4x vaddr 0x%-8x name `",
1056 rel->VirtualAddress );
1057 sym = (COFF_symbol*)
1058 myindex ( sizeof_COFF_symbol, symtab, rel->SymbolTableIndex );
1059 printName ( sym->Name, strtab -10 );
1060 fprintf ( stderr, "'\n" );
1062 fprintf ( stderr, "\n" );
1065 fprintf ( stderr, "\n" );
1066 fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
1067 fprintf ( stderr, "---START of string table---\n");
1068 for (i = 4; i < *(Int32*)strtab; i++) {
1070 fprintf ( stderr, "\n"); else
1071 fprintf( stderr, "%c", strtab[i] );
1073 fprintf ( stderr, "--- END of string table---\n");
1075 fprintf ( stderr, "\n" );
1078 COFF_symbol* symtab_i;
1079 if (i >= (Int32)(hdr->NumberOfSymbols)) break;
1080 symtab_i = (COFF_symbol*)
1081 myindex ( sizeof_COFF_symbol, symtab, i );
1087 printName ( symtab_i->Name, strtab );
1096 (Int32)(symtab_i->SectionNumber) - 1,
1097 (UInt32)symtab_i->Type,
1098 (UInt32)symtab_i->StorageClass,
1099 (UInt32)symtab_i->NumberOfAuxSymbols
1101 i += symtab_i->NumberOfAuxSymbols;
1105 fprintf ( stderr, "\n" );
1111 ocGetNames_PEi386 ( ObjectCode* oc )
1114 COFF_section* sectab;
1115 COFF_symbol* symtab;
1122 hdr = (COFF_header*)(oc->image);
1123 sectab = (COFF_section*) (
1124 ((UChar*)(oc->image))
1125 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1127 symtab = (COFF_symbol*) (
1128 ((UChar*)(oc->image))
1129 + hdr->PointerToSymbolTable
1131 strtab = ((UChar*)(oc->image))
1132 + hdr->PointerToSymbolTable
1133 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1135 /* Copy exported symbols into the ObjectCode. */
1137 oc->n_symbols = hdr->NumberOfSymbols;
1138 oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
1139 "ocGetNames_PEi386(oc->symbols)");
1140 /* Call me paranoid; I don't care. */
1141 for (i = 0; i < oc->n_symbols; i++)
1142 oc->symbols[i] = NULL;
1146 COFF_symbol* symtab_i;
1147 if (i >= (Int32)(hdr->NumberOfSymbols)) break;
1148 symtab_i = (COFF_symbol*)
1149 myindex ( sizeof_COFF_symbol, symtab, i );
1151 if (symtab_i->StorageClass == MYIMAGE_SYM_CLASS_EXTERNAL &&
1152 symtab_i->SectionNumber != MYIMAGE_SYM_UNDEFINED) {
1154 /* This symbol is global and defined, viz, exported */
1155 COFF_section* sectabent;
1157 /* cstring_from_COFF_symbol_name always succeeds. */
1158 sname = cstring_from_COFF_symbol_name ( symtab_i->Name, strtab );
1160 /* for MYIMAGE_SYMCLASS_EXTERNAL
1161 && !MYIMAGE_SYM_UNDEFINED,
1162 the address of the symbol is:
1163 address of relevant section + offset in section
1165 sectabent = (COFF_section*)
1166 myindex ( sizeof_COFF_section,
1168 symtab_i->SectionNumber-1 );
1169 addr = ((UChar*)(oc->image))
1170 + (sectabent->PointerToRawData
1172 /* fprintf(stderr,"addSymbol %p `%s'\n", addr,sname); */
1173 IF_DEBUG(linker, belch("addSymbol %p `%s'\n", addr,sname);)
1174 ASSERT(i >= 0 && i < oc->n_symbols);
1175 oc->symbols[i] = sname;
1176 insertStrHashTable(symhash, sname, addr);
1178 i += symtab_i->NumberOfAuxSymbols;
1182 /* Copy section information into the ObjectCode. */
1184 oc->n_sections = hdr->NumberOfSections;
1185 oc->sections = stgMallocBytes( oc->n_sections * sizeof(Section),
1186 "ocGetNamesPEi386" );
1188 for (i = 0; i < oc->n_sections; i++) {
1193 = SECTIONKIND_OTHER;
1194 COFF_section* sectab_i
1196 myindex ( sizeof_COFF_section, sectab, i );
1197 IF_DEBUG(linker, belch("section name = %s\n", sectab_i->Name ));
1200 /* I'm sure this is the Right Way to do it. However, the
1201 alternative of testing the sectab_i->Name field seems to
1202 work ok with Cygwin.
1204 if (sectab_i->Characteristics & MYIMAGE_SCN_CNT_CODE ||
1205 sectab_i->Characteristics & MYIMAGE_SCN_CNT_INITIALIZED_DATA)
1206 kind = SECTIONKIND_CODE_OR_RODATA;
1209 if (0==strcmp(".text",sectab_i->Name) ||
1210 0==strcmp(".rodata",sectab_i->Name))
1211 kind = SECTIONKIND_CODE_OR_RODATA;
1212 if (0==strcmp(".data",sectab_i->Name) ||
1213 0==strcmp(".bss",sectab_i->Name))
1214 kind = SECTIONKIND_RWDATA;
1216 start = ((UChar*)(oc->image))
1217 + sectab_i->PointerToRawData;
1219 + sectab_i->SizeOfRawData - 1;
1221 if (kind == SECTIONKIND_OTHER) {
1222 belch("Unknown PEi386 section name `%s'", sectab_i->Name);
1226 oc->sections[i].start = start;
1227 oc->sections[i].end = end;
1228 oc->sections[i].kind = kind;
1236 ocResolve_PEi386 ( ObjectCode* oc )
1239 COFF_section* sectab;
1240 COFF_symbol* symtab;
1249 /* ToDo: should be variable-sized? But is at least safe in the
1250 sense of buffer-overrun-proof. */
1252 /* fprintf(stderr, "resolving for %s\n", oc->fileName); */
1254 hdr = (COFF_header*)(oc->image);
1255 sectab = (COFF_section*) (
1256 ((UChar*)(oc->image))
1257 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1259 symtab = (COFF_symbol*) (
1260 ((UChar*)(oc->image))
1261 + hdr->PointerToSymbolTable
1263 strtab = ((UChar*)(oc->image))
1264 + hdr->PointerToSymbolTable
1265 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1267 for (i = 0; i < hdr->NumberOfSections; i++) {
1268 COFF_section* sectab_i
1270 myindex ( sizeof_COFF_section, sectab, i );
1273 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
1275 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1277 COFF_reloc* reltab_j
1279 myindex ( sizeof_COFF_reloc, reltab, j );
1281 /* the location to patch */
1283 ((UChar*)(oc->image))
1284 + (sectab_i->PointerToRawData
1285 + reltab_j->VirtualAddress
1286 - sectab_i->VirtualAddress )
1288 /* the existing contents of pP */
1290 /* the symbol to connect to */
1291 sym = (COFF_symbol*)
1292 myindex ( sizeof_COFF_symbol,
1293 symtab, reltab_j->SymbolTableIndex );
1296 "reloc sec %2d num %3d: type 0x%-4x "
1297 "vaddr 0x%-8x name `",
1299 (UInt32)reltab_j->Type,
1300 reltab_j->VirtualAddress );
1301 printName ( sym->Name, strtab );
1302 fprintf ( stderr, "'\n" ));
1304 if (sym->StorageClass == MYIMAGE_SYM_CLASS_STATIC) {
1305 COFF_section* section_sym
1306 = findPEi386SectionCalled ( oc, sym->Name );
1308 belch("%s: can't find section `%s'", oc->fileName, sym->Name);
1311 S = ((UInt32)(oc->image))
1312 + (section_sym->PointerToRawData
1315 copyName ( sym->Name, strtab, symbol, 1000-1 );
1316 zapTrailingAtSign ( symbol );
1317 (void*)S = lookupLocalSymbol( oc, symbol );
1318 if ((void*)S == NULL)
1319 (void*)S = lookupSymbol( symbol );
1321 belch("%s: unknown symbol `%s'", oc->fileName, symbol);
1326 switch (reltab_j->Type) {
1327 case MYIMAGE_REL_I386_DIR32:
1330 case MYIMAGE_REL_I386_REL32:
1331 /* Tricky. We have to insert a displacement at
1332 pP which, when added to the PC for the _next_
1333 insn, gives the address of the target (S).
1334 Problem is to know the address of the next insn
1335 when we only know pP. We assume that this
1336 literal field is always the last in the insn,
1337 so that the address of the next insn is pP+4
1338 -- hence the constant 4.
1339 Also I don't know if A should be added, but so
1340 far it has always been zero.
1343 *pP = S - ((UInt32)pP) - 4;
1346 belch("%s: unhandled PEi386 relocation type %d",
1347 oc->fileName, reltab_j->Type);
1354 IF_DEBUG(linker, belch("completed %s", oc->fileName));
1358 #endif /* defined(OBJFORMAT_PEi386) */
1361 /* --------------------------------------------------------------------------
1363 * ------------------------------------------------------------------------*/
1365 #if defined(OBJFORMAT_ELF)
1370 #if defined(sparc_TARGET_ARCH)
1371 # define ELF_TARGET_SPARC /* Used inside <elf.h> */
1372 #elif defined(i386_TARGET_ARCH)
1373 # define ELF_TARGET_386 /* Used inside <elf.h> */
1375 /* There is a similar case for IA64 in the Solaris2 headers if this
1376 * ever becomes relevant.
1382 findElfSection ( void* objImage, Elf32_Word sh_type )
1385 char* ehdrC = (char*)objImage;
1386 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1387 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1389 for (i = 0; i < ehdr->e_shnum; i++) {
1390 if (shdr[i].sh_type == sh_type &&
1391 i != ehdr->e_shstrndx) {
1392 ptr = ehdrC + shdr[i].sh_offset;
1401 ocVerifyImage_ELF ( ObjectCode* oc )
1405 int i, j, nent, nstrtab, nsymtabs;
1409 char* ehdrC = (char*)(oc->image);
1410 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1412 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1413 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1414 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1415 ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1416 belch("%s: not an ELF header", oc->fileName);
1419 IF_DEBUG(linker,belch( "Is an ELF header" ));
1421 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1422 belch("%s: not 32 bit ELF", oc->fileName);
1426 IF_DEBUG(linker,belch( "Is 32 bit ELF" ));
1428 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1429 IF_DEBUG(linker,belch( "Is little-endian" ));
1431 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1432 IF_DEBUG(linker,belch( "Is big-endian" ));
1434 belch("%s: unknown endiannness", oc->fileName);
1438 if (ehdr->e_type != ET_REL) {
1439 belch("%s: not a relocatable object (.o) file", oc->fileName);
1442 IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
1444 IF_DEBUG(linker,belch( "Architecture is " ));
1445 switch (ehdr->e_machine) {
1446 case EM_386: IF_DEBUG(linker,belch( "x86" )); break;
1447 case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
1448 default: IF_DEBUG(linker,belch( "unknown" ));
1449 belch("%s: unknown architecture", oc->fileName);
1453 IF_DEBUG(linker,belch(
1454 "\nSection header table: start %d, n_entries %d, ent_size %d",
1455 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize ));
1457 ASSERT (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1459 shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1461 if (ehdr->e_shstrndx == SHN_UNDEF) {
1462 belch("%s: no section header string table", oc->fileName);
1465 IF_DEBUG(linker,belch( "Section header string table is section %d",
1467 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1470 for (i = 0; i < ehdr->e_shnum; i++) {
1471 IF_DEBUG(linker,fprintf(stderr, "%2d: ", i ));
1472 IF_DEBUG(linker,fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type ));
1473 IF_DEBUG(linker,fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size ));
1474 IF_DEBUG(linker,fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset ));
1475 IF_DEBUG(linker,fprintf(stderr, " (%p .. %p) ",
1476 ehdrC + shdr[i].sh_offset,
1477 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
1479 if (shdr[i].sh_type == SHT_REL) {
1480 IF_DEBUG(linker,fprintf(stderr, "Rel " ));
1481 } else if (shdr[i].sh_type == SHT_RELA) {
1482 IF_DEBUG(linker,fprintf(stderr, "RelA " ));
1484 IF_DEBUG(linker,fprintf(stderr," "));
1487 IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
1491 IF_DEBUG(linker,belch( "\nString tables" ));
1494 for (i = 0; i < ehdr->e_shnum; i++) {
1495 if (shdr[i].sh_type == SHT_STRTAB &&
1496 i != ehdr->e_shstrndx) {
1497 IF_DEBUG(linker,belch(" section %d is a normal string table", i ));
1498 strtab = ehdrC + shdr[i].sh_offset;
1503 belch("%s: no string tables, or too many", oc->fileName);
1508 IF_DEBUG(linker,belch( "\nSymbol tables" ));
1509 for (i = 0; i < ehdr->e_shnum; i++) {
1510 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1511 IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
1513 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1514 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1515 IF_DEBUG(linker,belch( " number of entries is apparently %d (%d rem)",
1517 shdr[i].sh_size % sizeof(Elf32_Sym)
1519 if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1520 belch("%s: non-integral number of symbol table entries", oc->fileName);
1523 for (j = 0; j < nent; j++) {
1524 IF_DEBUG(linker,fprintf(stderr, " %2d ", j ));
1525 IF_DEBUG(linker,fprintf(stderr, " sec=%-5d size=%-3d val=%5p ",
1526 (int)stab[j].st_shndx,
1527 (int)stab[j].st_size,
1528 (char*)stab[j].st_value ));
1530 IF_DEBUG(linker,fprintf(stderr, "type=" ));
1531 switch (ELF32_ST_TYPE(stab[j].st_info)) {
1532 case STT_NOTYPE: IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
1533 case STT_OBJECT: IF_DEBUG(linker,fprintf(stderr, "object " )); break;
1534 case STT_FUNC : IF_DEBUG(linker,fprintf(stderr, "func " )); break;
1535 case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
1536 case STT_FILE: IF_DEBUG(linker,fprintf(stderr, "file " )); break;
1537 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1539 IF_DEBUG(linker,fprintf(stderr, " " ));
1541 IF_DEBUG(linker,fprintf(stderr, "bind=" ));
1542 switch (ELF32_ST_BIND(stab[j].st_info)) {
1543 case STB_LOCAL : IF_DEBUG(linker,fprintf(stderr, "local " )); break;
1544 case STB_GLOBAL: IF_DEBUG(linker,fprintf(stderr, "global" )); break;
1545 case STB_WEAK : IF_DEBUG(linker,fprintf(stderr, "weak " )); break;
1546 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1548 IF_DEBUG(linker,fprintf(stderr, " " ));
1550 IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
1554 if (nsymtabs == 0) {
1555 belch("%s: didn't find any symbol tables", oc->fileName);
1564 ocGetNames_ELF ( ObjectCode* oc )
1569 char* ehdrC = (char*)(oc->image);
1570 Elf32_Ehdr* ehdr = (Elf32_Ehdr*)ehdrC;
1571 char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
1572 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1573 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1575 ASSERT(symhash != NULL);
1578 belch("%s: no strtab", oc->fileName);
1583 oc->n_sections = ehdr->e_shnum;
1584 oc->sections = stgMallocBytes( oc->n_sections * sizeof(Section),
1585 "ocGetNames_ELF(oc->sections)" );
1587 for (i = 0; i < oc->n_sections; i++) {
1589 /* make a section entry for relevant sections */
1590 SectionKind kind = SECTIONKIND_OTHER;
1591 if (!strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1592 !strcmp(".data1",sh_strtab+shdr[i].sh_name))
1593 kind = SECTIONKIND_RWDATA;
1594 if (!strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1595 !strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1596 !strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1597 kind = SECTIONKIND_CODE_OR_RODATA;
1599 /* fill in the section info */
1600 oc->sections[i].start = ehdrC + shdr[i].sh_offset;
1601 oc->sections[i].end = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
1602 oc->sections[i].kind = kind;
1604 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1606 /* copy stuff into this module's object symbol table */
1607 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1608 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1610 oc->n_symbols = nent;
1611 oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
1612 "ocGetNames_ELF(oc->symbols)");
1614 for (j = 0; j < nent; j++) {
1615 if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
1616 || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
1618 /* and not an undefined symbol */
1619 && stab[j].st_shndx != SHN_UNDEF
1620 /* and not in a "special section" */
1621 && stab[j].st_shndx < SHN_LORESERVE
1623 /* and it's a not a section or string table or anything silly */
1624 ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1625 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
1626 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE
1629 char* nm = strtab + stab[j].st_name;
1631 + shdr[ stab[j].st_shndx ].sh_offset
1635 oc->symbols[j] = nm;
1636 if (ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL) {
1637 IF_DEBUG(linker,belch( "addOTabName(LOCL): %10p %s %s",
1638 ad, oc->fileName, nm ));
1639 insertStrHashTable(oc->lochash, nm, ad);
1641 IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p %s %s",
1642 ad, oc->fileName, nm ));
1643 insertStrHashTable(symhash, nm, ad);
1647 IF_DEBUG(linker,belch( "skipping `%s'",
1648 strtab + stab[j].st_name ));
1651 "skipping bind = %d, type = %d, shndx = %d `%s'\n",
1652 (int)ELF32_ST_BIND(stab[j].st_info),
1653 (int)ELF32_ST_TYPE(stab[j].st_info),
1654 (int)stab[j].st_shndx,
1655 strtab + stab[j].st_name
1658 oc->symbols[j] = NULL;
1667 /* Do ELF relocations which lack an explicit addend. All x86-linux
1668 relocations appear to be of this form. */
1670 do_Elf32_Rel_relocations ( ObjectCode* oc, char* ehdrC,
1671 Elf32_Shdr* shdr, int shnum,
1672 Elf32_Sym* stab, char* strtab )
1677 Elf32_Rel* rtab = (Elf32_Rel*) (ehdrC + shdr[shnum].sh_offset);
1678 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rel);
1679 int target_shndx = shdr[shnum].sh_info;
1680 int symtab_shndx = shdr[shnum].sh_link;
1681 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1682 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1683 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1684 target_shndx, symtab_shndx ));
1685 for (j = 0; j < nent; j++) {
1686 Elf32_Addr offset = rtab[j].r_offset;
1687 Elf32_Word info = rtab[j].r_info;
1689 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1690 Elf32_Word* pP = (Elf32_Word*)P;
1694 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)",
1695 j, (void*)offset, (void*)info ));
1697 IF_DEBUG(linker,belch( " ZERO" ));
1700 /* First see if it is a nameless local symbol. */
1701 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1702 symbol = "(noname)";
1704 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1705 + stab[ELF32_R_SYM(info)].st_value);
1707 /* No? Should be in a symbol table then; first try the
1709 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1710 (void*)S = lookupLocalSymbol( oc, symbol );
1711 if ((void*)S == NULL)
1712 (void*)S = lookupSymbol( symbol );
1715 belch("%s: unknown symbol `%s'", oc->fileName, symbol);
1718 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1720 IF_DEBUG(linker,belch( "Reloc: P = %p S = %p A = %p",
1721 (void*)P, (void*)S, (void*)A ));
1722 switch (ELF32_R_TYPE(info)) {
1723 # ifdef i386_TARGET_ARCH
1724 case R_386_32: *pP = S + A; break;
1725 case R_386_PC32: *pP = S + A - P; break;
1728 belch("%s: unhandled ELF relocation(Rel) type %d\n",
1729 oc->fileName, ELF32_R_TYPE(info));
1738 /* Do ELF relocations for which explicit addends are supplied.
1739 sparc-solaris relocations appear to be of this form. */
1741 do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
1742 Elf32_Shdr* shdr, int shnum,
1743 Elf32_Sym* stab, char* strtab )
1748 Elf32_Rela* rtab = (Elf32_Rela*) (ehdrC + shdr[shnum].sh_offset);
1749 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rela);
1750 int target_shndx = shdr[shnum].sh_info;
1751 int symtab_shndx = shdr[shnum].sh_link;
1752 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1753 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1754 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1755 target_shndx, symtab_shndx ));
1756 for (j = 0; j < nent; j++) {
1757 Elf32_Addr offset = rtab[j].r_offset;
1758 Elf32_Word info = rtab[j].r_info;
1759 Elf32_Sword addend = rtab[j].r_addend;
1761 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1762 Elf32_Addr A = addend;
1764 # if defined(sparc_TARGET_ARCH)
1765 /* This #ifdef only serves to avoid unused-var warnings. */
1766 Elf32_Word* pP = (Elf32_Word*)P;
1770 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ",
1771 j, (void*)offset, (void*)info,
1774 IF_DEBUG(linker,belch( " ZERO" ));
1777 /* First see if it is a nameless local symbol. */
1778 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1779 symbol = "(noname)";
1781 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1782 + stab[ELF32_R_SYM(info)].st_value);
1784 /* No? Should be in a symbol table then; first try the
1786 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1787 (void*)S = lookupLocalSymbol( oc, symbol );
1788 if ((void*)S == NULL)
1789 (void*)S = lookupSymbol( symbol );
1792 belch("%s: unknown symbol `%s'", oc->fileName, symbol);
1796 fprintf ( stderr, "S %p A %p S+A %p S+A-P %p\n",S,A,S+A,S+A-P);
1799 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1801 IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n",
1802 (void*)P, (void*)S, (void*)A ));
1803 switch (ELF32_R_TYPE(info)) {
1804 # if defined(sparc_TARGET_ARCH)
1805 case R_SPARC_WDISP30:
1806 w1 = *pP & 0xC0000000;
1807 w2 = (Elf32_Word)((S + A - P) >> 2);
1808 ASSERT((w2 & 0xC0000000) == 0);
1813 w1 = *pP & 0xFFC00000;
1814 w2 = (Elf32_Word)((S + A) >> 10);
1815 ASSERT((w2 & 0xFFC00000) == 0);
1821 w2 = (Elf32_Word)((S + A) & 0x3FF);
1822 ASSERT((w2 & ~0x3FF) == 0);
1827 w2 = (Elf32_Word)(S + A);
1832 belch("%s: unhandled ELF relocation(RelA) type %d\n",
1833 oc->fileName, ELF32_R_TYPE(info));
1843 ocResolve_ELF ( ObjectCode* oc )
1847 Elf32_Sym* stab = NULL;
1848 char* ehdrC = (char*)(oc->image);
1849 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1850 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1852 /* first find "the" symbol table */
1853 stab = (Elf32_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
1855 /* also go find the string table */
1856 strtab = findElfSection ( ehdrC, SHT_STRTAB );
1858 if (stab == NULL || strtab == NULL) {
1859 belch("%s: can't find string or symbol table", oc->fileName);
1863 /* Process the relocation sections. */
1864 for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
1865 if (shdr[shnum].sh_type == SHT_REL ) {
1866 ok = do_Elf32_Rel_relocations ( oc, ehdrC, shdr,
1867 shnum, stab, strtab );
1871 if (shdr[shnum].sh_type == SHT_RELA) {
1872 ok = do_Elf32_Rela_relocations ( oc, ehdrC, shdr,
1873 shnum, stab, strtab );
1878 /* Free the local symbol table; we won't need it again. */
1879 freeHashTable(oc->lochash, NULL);