Ticket #5748: 0001-check-for-failed-external-symbol-lookups-partial-fix.patch

File 0001-check-for-failed-external-symbol-lookups-partial-fix.patch, 7.9 KB (added by gwright, 4 years ago)
  • rts/Linker.c

    From b27d8adc075a89b5ca122a7a4a11d490a71fbf45 Mon Sep 17 00:00:00 2001
    From: Gregory Wright <[email protected]>
    Date: Sat, 7 Jan 2012 09:58:00 -0500
    Subject: [PATCH] check for failed external symbol lookups (partial fix for #5748)
    
    ---
     rts/Linker.c |   96 +++++++++++++++++++++++++++++++++++++++++++++++++---------
     1 files changed, 81 insertions(+), 15 deletions(-)
    
    diff --git a/rts/Linker.c b/rts/Linker.c
    index 7e3c7b1..9b4e7d0 100644
    a b lookupSymbol( char *lbl ) 
    14921492        /* On OS X 10.3 and later, we use dlsym instead of the old legacy
    14931493           interface.
    14941494
    1495            HACK: On OS X, global symbols are prefixed with an underscore.
     1495           HACK: On OS X, all symbols are prefixed with an underscore.
    14961496                 However, dlsym wants us to omit the leading underscore from the
    1497                  symbol name. For now, we simply strip it off here (and ONLY
     1497                 symbol name -- the dlsym routine puts it back on before searching
     1498                 for the symbol. For now, we simply strip it off here (and ONLY
    14981499                 here).
    14991500        */
    15001501        IF_DEBUG(linker, debugBelch("lookupSymbol: looking up %s with dlsym\n", lbl));
    1501         ASSERT(lbl[0] == '_');
    1502         return dlsym(dl_prog_handle, lbl+1);
     1502        ASSERT(lbl[0] == '_');
     1503        return dlsym(dl_prog_handle, lbl + 1);
    15031504#       else
    1504         if(NSIsSymbolNameDefined(lbl)) {
     1505        if (NSIsSymbolNameDefined(lbl)) {
    15051506            NSSymbol symbol = NSLookupAndBindSymbol(lbl);
    15061507            return NSAddressOfSymbol(symbol);
    15071508        } else {
    resolveImports( 
    47354736
    47364737#endif
    47374738
    4738     for(i=0; i*itemSize < sect->size;i++)
     4739    for(i = 0; i * itemSize < sect->size; i++)
    47394740    {
    47404741        // according to otool, reserved1 contains the first index into the indirect symbol table
    47414742        struct nlist *symbol = &nlist[indirectSyms[sect->reserved1+i]];
    resolveImports( 
    47524753            addr = lookupSymbol(nm);
    47534754            IF_DEBUG(linker, debugBelch("resolveImports: looking up %s, %p\n", nm, addr));
    47544755        }
    4755         if (!addr)
     4756
     4757        if (addr == NULL)
    47564758        {
    4757             errorBelch("\n%s: unknown symbol `%s'", oc->fileName, nm);
     4759            errorBelch("\nlookupSymbol failed in resolveImports\n"
     4760                       "%s: unknown symbol `%s'", oc->fileName, nm);
    47584761            return 0;
    47594762        }
    47604763        ASSERT(addr);
    resolveImports( 
    47794782    return 1;
    47804783}
    47814784
    4782 static unsigned long relocateAddress(
     4785static unsigned long
     4786relocateAddress(
    47834787    ObjectCode* oc,
    47844788    int nSections,
    47854789    struct section* sections,
    static unsigned long relocateAddress( 
    48024806    return 0;
    48034807}
    48044808
    4805 static int relocateSection(
     4809static int
     4810relocateSection(
    48064811    ObjectCode* oc,
    48074812    char *image,
    48084813    struct symtab_command *symLC, struct nlist *nlist,
    static int relocateSection( 
    48274832
    48284833    relocs = (struct relocation_info*) (image + sect->reloff);
    48294834
    4830     for(i=0;i<n;i++)
     4835    for(i = 0; i < n; i++)
    48314836    {
    48324837#ifdef x86_64_HOST_ARCH
    48334838        struct relocation_info *reloc = &relocs[i];
    static int relocateSection( 
    48404845        uint64_t baseValue;
    48414846        int type = reloc->r_type;
    48424847
     4848        IF_DEBUG(linker, debugBelch("relocateSection: relocation %d\n", i));
     4849        IF_DEBUG(linker, debugBelch("               : type      = %d\n", reloc->r_type));
     4850        IF_DEBUG(linker, debugBelch("               : address   = %d\n", reloc->r_address));
     4851        IF_DEBUG(linker, debugBelch("               : symbolnum = %u\n", reloc->r_symbolnum));
     4852        IF_DEBUG(linker, debugBelch("               : pcrel     = %d\n", reloc->r_pcrel));
     4853        IF_DEBUG(linker, debugBelch("               : length    = %d\n", reloc->r_length));
     4854        IF_DEBUG(linker, debugBelch("               : extern    = %d\n", reloc->r_extern));
     4855        IF_DEBUG(linker, debugBelch("               : type      = %d\n", reloc->r_type));
     4856
    48434857        checkProddableBlock(oc,thingPtr);
    48444858        switch(reloc->r_length)
    48454859        {
    static int relocateSection( 
    48684882                            reloc->r_length, thing, (char *)baseValue));
    48694883
    48704884        if (type == X86_64_RELOC_GOT
    4871            || type == X86_64_RELOC_GOT_LOAD)
     4885         || type == X86_64_RELOC_GOT_LOAD)
    48724886        {
    48734887            struct nlist *symbol = &nlist[reloc->r_symbolnum];
    48744888            char *nm = image + symLC->stroff + symbol->n_un.n_strx;
     4889            void *addr = NULL;
    48754890
    48764891            IF_DEBUG(linker, debugBelch("relocateSection: making jump island for %s, extern = %d, X86_64_RELOC_GOT\n", nm, reloc->r_extern));
     4892
    48774893            ASSERT(reloc->r_extern);
    4878             value = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, (unsigned long)lookupSymbol(nm))->addr;
     4894            if (reloc->r_extern == 0) {
     4895                    errorBelch("\nrelocateSection: global offset table relocation for symbol with r_extern == 0\n");
     4896            }
     4897
     4898            if (symbol->n_type & N_EXT) {
     4899                    // The external bit is set, meaning the symbol is exported,
     4900                    // and therefore can be looked up in this object module's
     4901                    // symtab, or it is undefined, meaning dlsym must be used
     4902                    // to resolve it.
     4903
     4904                    addr = lookupSymbol(nm);
     4905                    IF_DEBUG(linker, debugBelch("relocateSection: looked up %s, "
     4906                                                "external X86_64_RELOC_GOT or X86_64_RELOC_GOT_LOAD\n", nm));
     4907                    IF_DEBUG(linker, debugBelch("               : addr = %p\n", addr));
     4908
     4909                    if (addr == NULL) {
     4910                            errorBelch("\nlookupSymbol failed in relocateSection (RELOC_GOT)\n"
     4911                                       "%s: unknown symbol `%s'", oc->fileName, nm);
     4912                            return 0;
     4913                    }
     4914            } else {
     4915                    IF_DEBUG(linker, debugBelch("relocateSection: %s is not an exported symbol\n", nm));
     4916
     4917                    // The symbol is not exported, or defined in another
     4918                    // module, so it must be in the current object module,
     4919                    // at the location given by the section index and
     4920                    // symbol address (symbol->n_value)
     4921
     4922                    if ((symbol->n_type & N_TYPE) == N_SECT) {
     4923                            addr = (void *)relocateAddress(oc, nSections, sections, symbol->n_value);
     4924                            IF_DEBUG(linker, debugBelch("relocateSection: calculated relocation %p of "
     4925                                                        "non-external X86_64_RELOC_GOT or X86_64_RELOC_GOT_LOAD\n",
     4926                                                        (void *)symbol->n_value));
     4927                            IF_DEBUG(linker, debugBelch("               : addr = %p\n", addr));
     4928                    } else {
     4929                            errorBelch("\nrelocateSection: %s is not exported,"
     4930                                       " and should be defined in a section, but isn't!\n", nm);
     4931                    }
     4932            }
     4933           
     4934            value = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, (unsigned long)addr)->addr;
    48794935
    48804936            type = X86_64_RELOC_SIGNED;
    48814937        }
    4882         else if(reloc->r_extern)
     4938        else if (reloc->r_extern)
    48834939        {
    48844940            struct nlist *symbol = &nlist[reloc->r_symbolnum];
    48854941            char *nm = image + symLC->stroff + symbol->n_un.n_strx;
     4942            void *addr = NULL;
    48864943
    48874944            IF_DEBUG(linker, debugBelch("relocateSection: looking up external symbol %s\n", nm));
    48884945            IF_DEBUG(linker, debugBelch("               : type  = %d\n", symbol->n_type));
    48894946            IF_DEBUG(linker, debugBelch("               : sect  = %d\n", symbol->n_sect));
    48904947            IF_DEBUG(linker, debugBelch("               : desc  = %d\n", symbol->n_desc));
    48914948            IF_DEBUG(linker, debugBelch("               : value = %p\n", (void *)symbol->n_value));
     4949
    48924950            if ((symbol->n_type & N_TYPE) == N_SECT) {
    48934951                value = relocateAddress(oc, nSections, sections,
    48944952                                        symbol->n_value);
    48954953                IF_DEBUG(linker, debugBelch("relocateSection, defined external symbol %s, relocated address %p\n", nm, (void *)value));
    48964954            }
    48974955            else {
    4898                 value = (uint64_t) lookupSymbol(nm);
     4956                addr = lookupSymbol(nm);
     4957                if (addr == NULL)
     4958                {
     4959                     errorBelch("\nlookupSymbol failed in relocateSection (relocate external)\n"
     4960                                "%s: unknown symbol `%s'", oc->fileName, nm);
     4961                     return 0;
     4962                }
     4963
     4964                value = (uint64_t) addr;
    48994965                IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s, address %p\n", nm, (void *)value));
    49004966            }
    49014967        }