X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FLinker.c;h=06240812c2bfcff59c353fdcba93950de088e6e7;hp=a2b69f93ddf94f7d60f0f0cf2b50eb6ea8b27360;hb=5d52d9b64c21dcf77849866584744722f8121389;hpb=c3685050fd288d928c4e26fb2e43fc33e304391c diff --git a/rts/Linker.c b/rts/Linker.c index a2b69f9..0624081 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -21,6 +21,7 @@ #include "HsFFI.h" #include "sm/Storage.h" +#include "Stats.h" #include "Hash.h" #include "LinkerInternals.h" #include "RtsUtils.h" @@ -32,12 +33,19 @@ #include "posix/Signals.h" #endif +#if defined(mingw32_HOST_OS) +// get protos for is*() +#include +#endif + #ifdef HAVE_SYS_TYPES_H #include #endif #include #include +#include +#include #ifdef HAVE_SYS_STAT_H #include @@ -63,12 +71,12 @@ #include #endif -#if defined(ia64_HOST_ARCH) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS) +#if defined(ia64_HOST_ARCH) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS) #define USE_MMAP #include #include -#if defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS) +#if defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS) #ifdef HAVE_UNISTD_H #include #endif @@ -76,14 +84,17 @@ #endif -#if defined(linux_HOST_OS) || defined(solaris2_HOST_OS) || defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS) +#if defined(linux_HOST_OS) || defined(solaris2_HOST_OS) || defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS) # define OBJFORMAT_ELF +# include // regex is already used by dlopen() so this is OK + // to use here without requiring an additional lib #elif defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS) # define OBJFORMAT_PEi386 # include # include #elif defined(darwin_HOST_OS) # define OBJFORMAT_MACHO +# include # include # include # include @@ -381,17 +392,17 @@ typedef struct _RtsSymbolVal { SymI_HasProto(strncpy) \ SymI_HasProto(abort) \ SymI_NeedsProto(_alloca) \ - SymI_NeedsProto(isxdigit) \ - SymI_NeedsProto(isupper) \ - SymI_NeedsProto(ispunct) \ - SymI_NeedsProto(islower) \ - SymI_NeedsProto(isspace) \ - SymI_NeedsProto(isprint) \ - SymI_NeedsProto(isdigit) \ - SymI_NeedsProto(iscntrl) \ - SymI_NeedsProto(isalpha) \ - SymI_NeedsProto(isalnum) \ - SymI_NeedsProto(isascii) \ + SymI_HasProto(isxdigit) \ + SymI_HasProto(isupper) \ + SymI_HasProto(ispunct) \ + SymI_HasProto(islower) \ + SymI_HasProto(isspace) \ + SymI_HasProto(isprint) \ + SymI_HasProto(isdigit) \ + SymI_HasProto(iscntrl) \ + SymI_HasProto(isalpha) \ + SymI_HasProto(isalnum) \ + SymI_HasProto(isascii) \ RTS___MINGW_VFPRINTF_SYM \ SymI_HasProto(strcmp) \ SymI_HasProto(memmove) \ @@ -505,10 +516,13 @@ typedef struct _RtsSymbolVal { #if !defined(mingw32_HOST_OS) #define RTS_USER_SIGNALS_SYMBOLS \ SymI_HasProto(setIOManagerPipe) \ + SymI_HasProto(ioManagerWakeup) \ + SymI_HasProto(ioManagerSync) \ SymI_HasProto(blockUserSignals) \ SymI_HasProto(unblockUserSignals) #else #define RTS_USER_SIGNALS_SYMBOLS \ + SymI_HasProto(ioManagerWakeup) \ SymI_HasProto(sendIOManagerEvent) \ SymI_HasProto(readIOManagerEvent) \ SymI_HasProto(getIOManagerEvent) \ @@ -666,6 +680,21 @@ typedef struct _RtsSymbolVal { SymI_HasProto(RET_SEMI_loads_avoided) +// On most platforms, the garbage collector rewrites references +// to small integer and char objects to a set of common, shared ones. +// +// We don't do this when compiling to Windows DLLs at the moment because +// it doesn't support cross package data references well. +// +#if defined(__PIC__) && defined(mingw32_HOST_OS) +#define RTS_INTCHAR_SYMBOLS +#else +#define RTS_INTCHAR_SYMBOLS \ + SymI_HasProto(stg_CHARLIKE_closure) \ + SymI_HasProto(stg_INTLIKE_closure) +#endif + + #define RTS_SYMBOLS \ Maybe_Stable_Names \ RTS_TICKY_SYMBOLS \ @@ -736,7 +765,11 @@ typedef struct _RtsSymbolVal { SymI_HasProto(forkOS_createThread) \ SymI_HasProto(freeHaskellFunctionPtr) \ SymI_HasProto(getOrSetTypeableStore) \ - SymI_HasProto(getOrSetSignalHandlerStore) \ + SymI_HasProto(getOrSetGHCConcSignalHandlerStore) \ + SymI_HasProto(getOrSetGHCConcPendingEventsStore) \ + SymI_HasProto(getOrSetGHCConcPendingDelaysStore) \ + SymI_HasProto(getOrSetGHCConcIOManagerThreadStore) \ + SymI_HasProto(getOrSetGHCConcProddingStore) \ SymI_HasProto(genSymZh) \ SymI_HasProto(genericRaise) \ SymI_HasProto(getProgArgv) \ @@ -844,13 +877,14 @@ typedef struct _RtsSymbolVal { SymI_HasProto(stable_ptr_table) \ SymI_HasProto(stackOverflow) \ SymI_HasProto(stg_CAF_BLACKHOLE_info) \ + SymI_HasProto(stg_BLACKHOLE_info) \ SymI_HasProto(__stg_EAGER_BLACKHOLE_info) \ + SymI_HasProto(stg_BLOCKING_QUEUE_CLEAN_info) \ + SymI_HasProto(stg_BLOCKING_QUEUE_DIRTY_info) \ SymI_HasProto(startTimer) \ - SymI_HasProto(stg_CHARLIKE_closure) \ SymI_HasProto(stg_MVAR_CLEAN_info) \ SymI_HasProto(stg_MVAR_DIRTY_info) \ SymI_HasProto(stg_IND_STATIC_info) \ - SymI_HasProto(stg_INTLIKE_closure) \ SymI_HasProto(stg_ARR_WORDS_info) \ SymI_HasProto(stg_MUT_ARR_PTRS_DIRTY_info) \ SymI_HasProto(stg_MUT_ARR_PTRS_FROZEN_info) \ @@ -910,6 +944,7 @@ typedef struct _RtsSymbolVal { SymI_HasProto(stg_sel_8_upd_info) \ SymI_HasProto(stg_sel_9_upd_info) \ SymI_HasProto(stg_upd_frame_info) \ + SymI_HasProto(stg_bh_upd_frame_info) \ SymI_HasProto(suspendThread) \ SymI_HasProto(stg_takeMVarzh) \ SymI_HasProto(stg_threadStatuszh) \ @@ -923,9 +958,9 @@ typedef struct _RtsSymbolVal { SymI_HasProto(stg_writeTVarzh) \ SymI_HasProto(stg_yieldzh) \ SymI_NeedsProto(stg_interp_constr_entry) \ - SymI_HasProto(alloc_blocks) \ SymI_HasProto(alloc_blocks_lim) \ - SymI_HasProto(allocateLocal) \ + SymI_HasProto(g0) \ + SymI_HasProto(allocate) \ SymI_HasProto(allocateExec) \ SymI_HasProto(freeExec) \ SymI_HasProto(getAllocations) \ @@ -938,7 +973,8 @@ typedef struct _RtsSymbolVal { SymI_HasProto(n_capabilities) \ SymI_HasProto(stg_traceCcszh) \ SymI_HasProto(stg_traceEventzh) \ - RTS_USER_SIGNALS_SYMBOLS + RTS_USER_SIGNALS_SYMBOLS \ + RTS_INTCHAR_SYMBOLS // 64-bit support functions in libgcc.a @@ -951,8 +987,7 @@ typedef struct _RtsSymbolVal { SymI_NeedsProto(__muldi3) \ SymI_NeedsProto(__ashldi3) \ SymI_NeedsProto(__ashrdi3) \ - SymI_NeedsProto(__lshrdi3) \ - SymI_NeedsProto(__eprintf) + SymI_NeedsProto(__lshrdi3) #else #define RTS_LIBGCC_SYMBOLS #endif @@ -1073,12 +1108,20 @@ static int linker_init_done = 0 ; #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) static void *dl_prog_handle; +static regex_t re_invalid; +static regex_t re_realso; +#ifdef THREADED_RTS +static Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section +#endif #endif void initLinker( void ) { RtsSymbolVal *sym; +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + int compileResult; +#endif /* Make initLinker idempotent, so we can call it before evey relevant operation; that means we @@ -1087,6 +1130,9 @@ initLinker( void ) linker_init_done = 1; } +#if defined(THREADED_RTS) && (defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)) + initMutex(&dl_mutex); +#endif stablehash = allocStrHashTable(); symhash = allocStrHashTable(); @@ -1105,6 +1151,15 @@ initLinker( void ) # else dl_prog_handle = dlopen(NULL, RTLD_LAZY); # endif /* RTLD_DEFAULT */ + + compileResult = regcomp(&re_invalid, + "(([^ \t()])+\\.so([^ \t:()])*):([ \t])*invalid ELF header", + REG_EXTENDED); + ASSERT( compileResult == 0 ); + compileResult = regcomp(&re_realso, + "GROUP *\\( *(([^ )])+)", + REG_EXTENDED); + ASSERT( compileResult == 0 ); # endif #if defined(x86_64_HOST_ARCH) @@ -1125,6 +1180,19 @@ initLinker( void ) #endif } +void +exitLinker( void ) { +#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + if (linker_init_done == 1) { + regfree(&re_invalid); + regfree(&re_realso); +#ifdef THREADED_RTS + closeMutex(&dl_mutex); +#endif + } +#endif +} + /* ----------------------------------------------------------------------------- * Loading DLL or .so dynamic libraries * ----------------------------------------------------------------------------- @@ -1160,29 +1228,112 @@ typedef static OpenedDLL* opened_dlls = NULL; #endif -const char * -addDLL( char *dll_name ) -{ # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) - /* ------------------- ELF DLL loader ------------------- */ - void *hdl; - const char *errmsg; - initLinker(); +static char * +internal_dlopen(const char *dll_name) +{ + void *hdl; + char *errmsg, *errmsg_copy; // omitted: RTLD_NOW // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html - hdl= dlopen(dll_name, RTLD_LAZY | RTLD_GLOBAL); + IF_DEBUG(linker, + debugBelch("internal_dlopen: dll_name = '%s'\n", dll_name)); + + //-------------- Begin critical section ------------------ + // This critical section is necessary because dlerror() is not + // required to be reentrant (see POSIX -- IEEE Std 1003.1-2008) + // Also, the error message returned must be copied to preserve it + // (see POSIX also) + + ACQUIRE_LOCK(&dl_mutex); + hdl = dlopen(dll_name, RTLD_LAZY | RTLD_GLOBAL); + errmsg = NULL; if (hdl == NULL) { /* dlopen failed; return a ptr to the error msg. */ errmsg = dlerror(); if (errmsg == NULL) errmsg = "addDLL: unknown error"; - return errmsg; - } else { + errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL"); + strcpy(errmsg_copy, errmsg); + errmsg = errmsg_copy; + } + RELEASE_LOCK(&dl_mutex); + //--------------- End critical section ------------------- + + return errmsg; +} +# endif + +const char * +addDLL( char *dll_name ) +{ +# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO) + /* ------------------- ELF DLL loader ------------------- */ + +#define NMATCH 5 + regmatch_t match[NMATCH]; + char *errmsg; + FILE* fp; + size_t match_length; +#define MAXLINE 1000 + char line[MAXLINE]; + int result; + + initLinker(); + + IF_DEBUG(linker, debugBelch("addDLL: dll_name = '%s'\n", dll_name)); + errmsg = internal_dlopen(dll_name); + + if (errmsg == NULL) { return NULL; } - /*NOTREACHED*/ + + // GHC Trac ticket #2615 + // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so) + // contain linker scripts rather than ELF-format object code. This + // code handles the situation by recognizing the real object code + // file name given in the linker script. + // + // If an "invalid ELF header" error occurs, it is assumed that the + // .so file contains a linker script instead of ELF object code. + // In this case, the code looks for the GROUP ( ... ) linker + // directive. If one is found, the first file name inside the + // parentheses is treated as the name of a dynamic library and the + // code attempts to dlopen that file. If this is also unsuccessful, + // an error message is returned. + + // see if the error message is due to an invalid ELF header + IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", errmsg)); + result = regexec(&re_invalid, errmsg, (size_t) NMATCH, match, 0); + IF_DEBUG(linker, debugBelch("result = %i\n", result)); + if (result == 0) { + // success -- try to read the named file as a linker script + match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so), + MAXLINE-1); + strncpy(line, (errmsg+(match[1].rm_so)),match_length); + line[match_length] = '\0'; // make sure string is null-terminated + IF_DEBUG(linker, debugBelch ("file name = '%s'\n", line)); + if ((fp = fopen(line, "r")) == NULL) { + return errmsg; // return original error if open fails + } + // try to find a GROUP ( ... ) command + while (fgets(line, MAXLINE, fp) != NULL) { + IF_DEBUG(linker, debugBelch("input line = %s", line)); + if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) { + // success -- try to dlopen the first named file + IF_DEBUG(linker, debugBelch("match%s\n","")); + line[match[1].rm_eo] = '\0'; + errmsg = internal_dlopen(line+match[1].rm_so); + break; + } + // if control reaches here, no GROUP ( ... ) directive was found + // and the original error message is returned to the caller + } + fclose(fp); + } + return errmsg; # elif defined(OBJFORMAT_PEi386) /* ------------------- Win32 DLL loader ------------------- */ @@ -1310,13 +1461,13 @@ lookupSymbol( char *lbl ) # elif defined(OBJFORMAT_PEi386) void* sym; - sym = lookupSymbolInDLLs(lbl); + sym = lookupSymbolInDLLs((unsigned char*)lbl); if (sym != NULL) { return sym; }; // Also try looking up the symbol without the @N suffix. Some // DLLs have the suffixes on their symbols, some don't. - zapTrailingAtSign ( lbl ); - sym = lookupSymbolInDLLs(lbl); + zapTrailingAtSign ( (unsigned char*)lbl ); + sym = lookupSymbolInDLLs((unsigned char*)lbl); if (sym != NULL) { return sym; }; return NULL; @@ -1403,7 +1554,7 @@ mmap_again: } else { if ((W_)result > 0x80000000) { // oops, we were given memory over 2Gb -#if defined(freebsd_HOST_OS) +#if defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS) // Some platforms require MAP_FIXED. This is normally // a bad idea, because MAP_FIXED will overwrite // existing mappings. @@ -2065,7 +2216,7 @@ copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize ) { if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) { UInt32 strtab_offset = * (UInt32*)(name+4); - strncpy ( dst, strtab+strtab_offset, dstSize ); + strncpy ( (char*)dst, (char*)strtab+strtab_offset, dstSize ); dst[dstSize-1] = 0; } else { int i = 0; @@ -2100,7 +2251,7 @@ cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab ) */ newstr = stgMallocBytes(9, "cstring_from_COFF_symbol_name"); ASSERT(newstr); - strncpy(newstr,name,8); + strncpy((char*)newstr,(char*)name,8); newstr[8] = 0; return newstr; } @@ -2108,7 +2259,7 @@ cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab ) /* Just compares the short names (first 8 chars) */ static COFF_section * -findPEi386SectionCalled ( ObjectCode* oc, char* name ) +findPEi386SectionCalled ( ObjectCode* oc, UChar* name ) { int i; COFF_header* hdr @@ -2166,13 +2317,13 @@ lookupSymbolInDLLs ( UChar *lbl ) a Rule that governs whether an initial '_' *should always* be stripped off when mapping from import lib name to the DLL name. */ - sym = GetProcAddress(o_dll->instance, (lbl+1)); + sym = GetProcAddress(o_dll->instance, (char*)(lbl+1)); if (sym != NULL) { /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/ return sym; } } - sym = GetProcAddress(o_dll->instance, lbl); + sym = GetProcAddress(o_dll->instance, (char*)lbl); if (sym != NULL) { /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/ return sym; @@ -2403,7 +2554,7 @@ ocGetNames_PEi386 ( ObjectCode* oc ) COFF_section* sectab_i = (COFF_section*) myindex ( sizeof_COFF_section, sectab, i ); - if (0 != strcmp(sectab_i->Name, ".bss")) continue; + if (0 != strcmp((char*)sectab_i->Name, ".bss")) continue; /* sof 10/05: the PE spec text isn't too clear regarding what * the SizeOfRawData field is supposed to hold for object * file sections containing just uninitialized data -- for executables, @@ -2456,12 +2607,12 @@ ocGetNames_PEi386 ( ObjectCode* oc ) kind = SECTIONKIND_CODE_OR_RODATA; # endif - if (0==strcmp(".text",sectab_i->Name) || - 0==strcmp(".rdata",sectab_i->Name)|| - 0==strcmp(".rodata",sectab_i->Name)) + if (0==strcmp(".text",(char*)sectab_i->Name) || + 0==strcmp(".rdata",(char*)sectab_i->Name)|| + 0==strcmp(".rodata",(char*)sectab_i->Name)) kind = SECTIONKIND_CODE_OR_RODATA; - if (0==strcmp(".data",sectab_i->Name) || - 0==strcmp(".bss",sectab_i->Name)) + if (0==strcmp(".data",(char*)sectab_i->Name) || + 0==strcmp(".bss",(char*)sectab_i->Name)) kind = SECTIONKIND_RWDATA; ASSERT(sectab_i->SizeOfRawData == 0 || sectab_i->VirtualSize == 0); @@ -2474,14 +2625,14 @@ ocGetNames_PEi386 ( ObjectCode* oc ) if (kind == SECTIONKIND_OTHER /* Ignore sections called which contain stabs debugging information. */ - && 0 != strcmp(".stab", sectab_i->Name) - && 0 != strcmp(".stabstr", sectab_i->Name) + && 0 != strcmp(".stab", (char*)sectab_i->Name) + && 0 != strcmp(".stabstr", (char*)sectab_i->Name) /* ignore constructor section for now */ - && 0 != strcmp(".ctors", sectab_i->Name) + && 0 != strcmp(".ctors", (char*)sectab_i->Name) /* ignore section generated from .ident */ - && 0!= strcmp("/4", sectab_i->Name) + && 0!= strcmp("/4", (char*)sectab_i->Name) /* ignore unknown section that appeared in gcc 3.4.5(?) */ - && 0!= strcmp(".reloc", sectab_i->Name) + && 0!= strcmp(".reloc", (char*)sectab_i->Name) ) { errorBelch("Unknown PEi386 section name `%s' (while processing: %s)", sectab_i->Name, oc->fileName); return 0; @@ -2546,8 +2697,8 @@ ocGetNames_PEi386 ( ObjectCode* oc ) IF_DEBUG(linker, debugBelch("addSymbol %p `%s'\n", addr,sname);) ASSERT(i >= 0 && i < oc->n_symbols); /* cstring_from_COFF_symbol_name always succeeds. */ - oc->symbols[i] = sname; - ghciInsertStrHashTable(oc->fileName, symhash, sname, addr); + oc->symbols[i] = (char*)sname; + ghciInsertStrHashTable(oc->fileName, symhash, (char*)sname, addr); } else { # if 0 debugBelch( @@ -2597,7 +2748,7 @@ ocResolve_PEi386 ( ObjectCode* oc ) /* ToDo: should be variable-sized? But is at least safe in the sense of buffer-overrun-proof. */ - char symbol[1000]; + UChar symbol[1000]; /* debugBelch("resolving for %s\n", oc->fileName); */ hdr = (COFF_header*)(oc->image); @@ -2624,9 +2775,9 @@ ocResolve_PEi386 ( ObjectCode* oc ) /* Ignore sections called which contain stabs debugging information. */ - if (0 == strcmp(".stab", sectab_i->Name) - || 0 == strcmp(".stabstr", sectab_i->Name) - || 0 == strcmp(".ctors", sectab_i->Name)) + if (0 == strcmp(".stab", (char*)sectab_i->Name) + || 0 == strcmp(".stabstr", (char*)sectab_i->Name) + || 0 == strcmp(".ctors", (char*)sectab_i->Name)) continue; if ( sectab_i->Characteristics & MYIMAGE_SCN_LNK_NRELOC_OVFL ) { @@ -2699,7 +2850,7 @@ ocResolve_PEi386 ( ObjectCode* oc ) + sym->Value); } else { copyName ( sym->Name, strtab, symbol, 1000-1 ); - S = (UInt32) lookupSymbol( symbol ); + S = (UInt32) lookupSymbol( (char*)symbol ); if ((void*)S != NULL) goto foundit; errorBelch("%s: unknown symbol `%s'", oc->fileName, symbol); return 0; @@ -4174,7 +4325,14 @@ static int relocateSection( } #endif else - continue; // ignore the others + { + barf ("Don't know how to handle this Mach-O " + "scattered relocation entry: " + "object file %s; entry type %ld; " + "address %#lx\n", + oc->fileName, scat->r_type, scat->r_address); + return 0; + } #ifdef powerpc_HOST_ARCH if(scat->r_type == GENERIC_RELOC_VANILLA @@ -4203,11 +4361,28 @@ static int relocateSection( } #endif } + else + { + barf("Can't handle Mach-O scattered relocation entry " + "with this r_length tag: " + "object file %s; entry type %ld; " + "r_length tag %ld; address %#lx\n", + oc->fileName, scat->r_type, scat->r_length, + scat->r_address); + return 0; + } + } + else /* scat->r_pcrel */ + { + barf("Don't know how to handle *PC-relative* Mach-O " + "scattered relocation entry: " + "object file %s; entry type %ld; address %#lx\n", + oc->fileName, scat->r_type, scat->r_address); + return 0; } - continue; // FIXME: I hope it's OK to ignore all the others. } - else + else /* !(relocs[i].r_address & R_SCATTERED) */ { struct relocation_info *reloc = &relocs[i]; if(reloc->r_pcrel && !reloc->r_extern) @@ -4252,6 +4427,14 @@ static int relocateSection( word = (word & 0x03FFFFFC) | ((word & 0x02000000) ? 0xFC000000 : 0); } #endif + else + { + barf("Can't handle this Mach-O relocation entry " + "(not scattered): " + "object file %s; entry type %ld; address %#lx\n", + oc->fileName, reloc->r_type, reloc->r_address); + return 0; + } if(!reloc->r_extern) { @@ -4343,8 +4526,16 @@ static int relocateSection( } #endif } - barf("\nunknown relocation %d",reloc->r_type); - return 0; + else + { + barf("Can't handle Mach-O relocation entry (not scattered) " + "with this r_length tag: " + "object file %s; entry type %ld; " + "r_length tag %ld; address %#lx\n", + oc->fileName, reloc->r_type, reloc->r_length, + reloc->r_address); + return 0; + } } #endif } @@ -4569,9 +4760,10 @@ static int ocResolve_MachO(ObjectCode* oc) * Yuck. */ +extern void* symbolsWithoutUnderscore[]; + static void machoInitSymbolsWithoutUnderscore() { - extern void* symbolsWithoutUnderscore[]; void **p = symbolsWithoutUnderscore; __asm__ volatile(".globl _symbolsWithoutUnderscore\n.data\n_symbolsWithoutUnderscore:");