X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FLinker.c;h=e6e82aabb25f3b7a1e76cb3bfebcb06225497316;hb=423d477bfecd490de1449c59325c8776f91d7aac;hp=af7291e43458f82d7d3c8b05d91b89c856dc7dc4;hpb=4c450140141cc3068f15a4154815db5414971aab;p=ghc-hetmet.git diff --git a/ghc/rts/Linker.c b/ghc/rts/Linker.c index af7291e..e6e82aa 100644 --- a/ghc/rts/Linker.c +++ b/ghc/rts/Linker.c @@ -1,7 +1,6 @@ /* ----------------------------------------------------------------------------- - * $Id: Linker.c,v 1.145 2004/02/15 13:29:44 krasimir Exp $ * - * (c) The GHC Team, 2000-2003 + * (c) The GHC Team, 2000-2004 * * RTS Object Linker * @@ -23,8 +22,8 @@ #include "Linker.h" #include "LinkerInternals.h" #include "RtsUtils.h" -#include "StoragePriv.h" #include "Schedule.h" +#include "Storage.h" #ifdef HAVE_SYS_TYPES_H #include @@ -59,10 +58,17 @@ #include #endif -#if defined(ia64_TARGET_ARCH) +#if defined(ia64_TARGET_ARCH) || defined(openbsd_TARGET_OS) #define USE_MMAP #include #include + +#if defined(openbsd_TARGET_OS) +#ifdef HAVE_UNISTD_H +#include +#endif +#endif + #endif #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS) || defined(freebsd_TARGET_OS) || defined(netbsd_TARGET_OS) || defined(openbsd_TARGET_OS) @@ -306,12 +312,34 @@ typedef struct _RtsSymbolVal { # define MAIN_CAP_SYM #endif +#ifdef TABLES_NEXT_TO_CODE +#define RTS_RET_SYMBOLS /* nothing */ +#else +#define RTS_RET_SYMBOLS \ + SymX(stg_enter_ret) \ + SymX(stg_gc_fun_ret) \ + SymX(stg_ap_0_ret) \ + SymX(stg_ap_v_ret) \ + SymX(stg_ap_f_ret) \ + SymX(stg_ap_d_ret) \ + SymX(stg_ap_l_ret) \ + SymX(stg_ap_n_ret) \ + SymX(stg_ap_p_ret) \ + SymX(stg_ap_pv_ret) \ + SymX(stg_ap_pp_ret) \ + SymX(stg_ap_ppv_ret) \ + SymX(stg_ap_ppp_ret) \ + SymX(stg_ap_pppv_ret) \ + SymX(stg_ap_pppp_ret) \ + SymX(stg_ap_ppppp_ret) \ + SymX(stg_ap_pppppp_ret) +#endif + #define RTS_SYMBOLS \ Maybe_ForeignObj \ Maybe_Stable_Names \ Sym(StgReturn) \ SymX(stg_enter_info) \ - SymX(stg_enter_ret) \ SymX(stg_gc_void_info) \ SymX(__stg_gc_enter_1) \ SymX(stg_gc_noregs) \ @@ -327,7 +355,6 @@ typedef struct _RtsSymbolVal { SymX(stg_gc_l1) \ SymX(__stg_gc_fun) \ SymX(stg_gc_fun_info) \ - SymX(stg_gc_fun_ret) \ SymX(stg_gc_gen) \ SymX(stg_gc_gen_info) \ SymX(stg_gc_gen_hp) \ @@ -348,6 +375,7 @@ typedef struct _RtsSymbolVal { SymX(StackOverflowHook) \ SymX(__encodeDouble) \ SymX(__encodeFloat) \ + SymX(addDLL) \ SymX(__gmpn_gcd_1) \ SymX(__gmpz_cmp) \ SymX(__gmpz_cmp_si) \ @@ -357,6 +385,7 @@ typedef struct _RtsSymbolVal { SymX(__int_encodeDouble) \ SymX(__int_encodeFloat) \ SymX(andIntegerzh_fast) \ + SymX(barf) \ SymX(blockAsyncExceptionszh_fast) \ SymX(catchzh_fast) \ SymX(cmp_thread) \ @@ -383,6 +412,7 @@ typedef struct _RtsSymbolVal { SymX(genSymZh) \ SymX(getProgArgv) \ SymX(getStablePtr) \ + SymX(initLinker) \ SymX(int2Integerzh_fast) \ SymX(integer2Intzh_fast) \ SymX(integer2Wordzh_fast) \ @@ -397,6 +427,8 @@ typedef struct _RtsSymbolVal { SymX(isFloatNaN) \ SymX(isFloatNegativeZero) \ SymX(killThreadzh_fast) \ + SymX(loadObj) \ + SymX(lookupSymbol) \ SymX(makeStablePtrzh_fast) \ SymX(minusIntegerzh_fast) \ SymX(mkApUpd0zh_fast) \ @@ -424,6 +456,7 @@ typedef struct _RtsSymbolVal { SymX(remIntegerzh_fast) \ SymX(resetNonBlockingFd) \ SymX(resumeThread) \ + SymX(resolveObjs) \ SymX(rts_apply) \ SymX(rts_checkSchedStatus) \ SymX(rts_eval) \ @@ -492,25 +525,10 @@ typedef struct _RtsSymbolVal { SymX(stg_ap_pp_info) \ SymX(stg_ap_ppv_info) \ SymX(stg_ap_ppp_info) \ + SymX(stg_ap_pppv_info) \ SymX(stg_ap_pppp_info) \ SymX(stg_ap_ppppp_info) \ SymX(stg_ap_pppppp_info) \ - SymX(stg_ap_ppppppp_info) \ - SymX(stg_ap_0_ret) \ - SymX(stg_ap_v_ret) \ - SymX(stg_ap_f_ret) \ - SymX(stg_ap_d_ret) \ - SymX(stg_ap_l_ret) \ - SymX(stg_ap_n_ret) \ - SymX(stg_ap_p_ret) \ - SymX(stg_ap_pv_ret) \ - SymX(stg_ap_pp_ret) \ - SymX(stg_ap_ppv_ret) \ - SymX(stg_ap_ppp_ret) \ - SymX(stg_ap_pppp_ret) \ - SymX(stg_ap_ppppp_ret) \ - SymX(stg_ap_pppppp_ret) \ - SymX(stg_ap_ppppppp_ret) \ SymX(stg_ap_1_upd_info) \ SymX(stg_ap_2_upd_info) \ SymX(stg_ap_3_upd_info) \ @@ -518,7 +536,6 @@ typedef struct _RtsSymbolVal { SymX(stg_ap_5_upd_info) \ SymX(stg_ap_6_upd_info) \ SymX(stg_ap_7_upd_info) \ - SymX(stg_ap_8_upd_info) \ SymX(stg_exit) \ SymX(stg_sel_0_upd_info) \ SymX(stg_sel_10_upd_info) \ @@ -543,6 +560,7 @@ typedef struct _RtsSymbolVal { SymX(tryPutMVarzh_fast) \ SymX(tryTakeMVarzh_fast) \ SymX(unblockAsyncExceptionszh_fast) \ + SymX(unloadObj) \ SymX(unsafeThawArrayzh_fast) \ SymX(waitReadzh_fast) \ SymX(waitWritezh_fast) \ @@ -595,6 +613,7 @@ typedef struct _RtsSymbolVal { #define SymX(vvv) /**/ #define SymX_redirect(vvv,xxx) /**/ RTS_SYMBOLS +RTS_RET_SYMBOLS RTS_LONG_LONG_SYMS RTS_POSIX_ONLY_SYMBOLS RTS_MINGW_ONLY_SYMBOLS @@ -675,6 +694,11 @@ static int linker_init_done = 0 ; static void *dl_prog_handle; #endif +/* dlopen(NULL,..) doesn't work so we grab libc explicitly */ +#if defined(openbsd_TARGET_OS) +static void *dl_libc_handle; +#endif + void initLinker( void ) { @@ -703,6 +727,9 @@ initLinker( void ) dl_prog_handle = RTLD_DEFAULT; # else dl_prog_handle = dlopen(NULL, RTLD_LAZY); +# if defined(openbsd_TARGET_OS) + dl_libc_handle = dlopen("libc.so", RTLD_LAZY); +# endif # endif // RTLD_DEFAULT # endif } @@ -833,7 +860,12 @@ lookupSymbol( char *lbl ) if (val == NULL) { # if defined(OBJFORMAT_ELF) +# if defined(openbsd_TARGET_OS) + val = dlsym(dl_prog_handle, lbl); + return (val != NULL) ? val : dlsym(dl_libc_handle,lbl); +# else /* not openbsd */ return dlsym(dl_prog_handle, lbl); +# endif # elif defined(OBJFORMAT_MACHO) if(NSIsSymbolNameDefined(lbl)) { NSSymbol symbol = NSLookupAndBindSymbol(lbl); @@ -948,7 +980,7 @@ loadObj( char *path ) int r, n; #ifdef USE_MMAP int fd, pagesize; - void *map_addr; + void *map_addr = NULL; #else FILE *f; #endif @@ -957,24 +989,25 @@ loadObj( char *path ) /* fprintf(stderr, "loadObj %s\n", path ); */ - /* Check that we haven't already loaded this object. Don't give up - at this stage; ocGetNames_* will barf later. */ + /* Check that we haven't already loaded this object. + Ignore requests to load multiple times */ { ObjectCode *o; int is_dup = 0; for (o = objects; o; o = o->next) { - if (0 == strcmp(o->fileName, path)) + if (0 == strcmp(o->fileName, path)) { is_dup = 1; + break; /* don't need to search further */ + } } if (is_dup) { - fprintf(stderr, - "\n\n" + IF_DEBUG(linker, belch( "GHCi runtime linker: warning: looks like you're trying to load the\n" "same object file twice:\n" " %s\n" - "GHCi will continue, but a duplicate-symbol error may shortly follow.\n" - "\n" - , path); + "GHCi will ignore this, but be warned.\n" + , path)); + return 1; /* success */ } } @@ -1013,7 +1046,11 @@ loadObj( char *path ) /* On many architectures malloc'd memory isn't executable, so we need to use mmap. */ +#if defined(openbsd_TARGET_OS) + fd = open(path, O_RDONLY, S_IRUSR); +#else fd = open(path, O_RDONLY); +#endif if (fd == -1) barf("loadObj: can't open `%s'", path); @@ -3216,7 +3253,45 @@ static int relocateSection( - relocateAddress(oc, nSections, sections, pair->r_value)); i++; } - else + else if(scat->r_type == PPC_RELOC_HI16 + || scat->r_type == PPC_RELOC_LO16 + || scat->r_type == PPC_RELOC_HA16 + || scat->r_type == PPC_RELOC_LO14) + { // these are generated by label+offset things + struct relocation_info *pair = &relocs[i+1]; + if((pair->r_address & R_SCATTERED) || pair->r_type != PPC_RELOC_PAIR) + barf("Invalid Mach-O file: " + "PPC_RELOC_* not followed by PPC_RELOC_PAIR"); + + if(scat->r_type == PPC_RELOC_LO16) + { + word = ((unsigned short*) wordPtr)[1]; + word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16; + } + else if(scat->r_type == PPC_RELOC_LO14) + { + barf("Unsupported Relocation: PPC_RELOC_LO14"); + word = ((unsigned short*) wordPtr)[1] & 0xFFFC; + word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16; + } + else if(scat->r_type == PPC_RELOC_HI16) + { + word = ((unsigned short*) wordPtr)[1] << 16; + word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF); + } + else if(scat->r_type == PPC_RELOC_HA16) + { + word = ((unsigned short*) wordPtr)[1] << 16; + word += ((short)relocs[i+1].r_address & (short)0xFFFF); + } + + + word += (unsigned long) relocateAddress(oc, nSections, sections, scat->r_value) + - scat->r_value; + + i++; + } + else continue; // ignore the others if(scat->r_type == GENERIC_RELOC_VANILLA @@ -3224,15 +3299,15 @@ static int relocateSection( { *wordPtr = word; } - else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF) + else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF || scat->r_type == PPC_RELOC_LO16) { ((unsigned short*) wordPtr)[1] = word & 0xFFFF; } - else if(scat->r_type == PPC_RELOC_HI16_SECTDIFF) + else if(scat->r_type == PPC_RELOC_HI16_SECTDIFF || scat->r_type == PPC_RELOC_HI16) { ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF; } - else if(scat->r_type == PPC_RELOC_HA16_SECTDIFF) + else if(scat->r_type == PPC_RELOC_HA16_SECTDIFF || scat->r_type == PPC_RELOC_HA16) { ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF) + ((word & (1<<15)) ? 1 : 0); @@ -3296,15 +3371,17 @@ static int relocateSection( { struct nlist *symbol = &nlist[reloc->r_symbolnum]; char *nm = image + symLC->stroff + symbol->n_un.n_strx; - word = (unsigned long) (lookupSymbol(nm)); - if(!word) + unsigned long symbolAddress = (unsigned long) (lookupSymbol(nm)); + if(!symbolAddress) { belch("\nunknown symbol `%s'", nm); return 0; } if(reloc->r_pcrel) - { + { + ASSERT(word == 0); + word = symbolAddress; jumpIsland = (long) makeJumpIsland(oc,reloc->r_symbolnum,(void*)word); word -= ((long)image) + sect->offset + reloc->r_address; if(jumpIsland != 0) @@ -3313,6 +3390,10 @@ static int relocateSection( - (((long)image) + sect->offset + reloc->r_address); } } + else + { + word += symbolAddress; + } } if(reloc->r_type == GENERIC_RELOC_VANILLA)