Revert "bionic/linker: fix symbol lookup during relocations"
This reverts commit 8d0c0334f1.
			
			
This commit is contained in:
		@@ -87,12 +87,6 @@ static soinfo *freelist = NULL;
 | 
				
			|||||||
static soinfo *solist = &libdl_info;
 | 
					static soinfo *solist = &libdl_info;
 | 
				
			||||||
static soinfo *sonext = &libdl_info;
 | 
					static soinfo *sonext = &libdl_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int validate_soinfo(soinfo *si)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (si >= sopool && si < sopool + SO_MAX) ||
 | 
					 | 
				
			||||||
        si == &libdl_info;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char ldpaths_buf[LDPATH_BUFSIZE];
 | 
					static char ldpaths_buf[LDPATH_BUFSIZE];
 | 
				
			||||||
static const char *ldpaths[LDPATH_MAX + 1];
 | 
					static const char *ldpaths[LDPATH_MAX + 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -427,70 +421,32 @@ _do_lookup_in_so(soinfo *si, const char *name, unsigned *elf_hash)
 | 
				
			|||||||
    return _elf_lookup (si, *elf_hash, name);
 | 
					    return _elf_lookup (si, *elf_hash, name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Elf32_Sym *
 | 
					/* This is used by dl_sym() */
 | 
				
			||||||
_do_lookup(soinfo *si, const char *name, unsigned *base)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned elf_hash = 0;
 | 
					 | 
				
			||||||
    Elf32_Sym *s;
 | 
					 | 
				
			||||||
    unsigned *d;
 | 
					 | 
				
			||||||
    soinfo *lsi = si;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Look for symbols in the local scope first (the object who is
 | 
					 | 
				
			||||||
     * searching). This happens with C++ templates on i386 for some
 | 
					 | 
				
			||||||
     * reason. */
 | 
					 | 
				
			||||||
    s = _do_lookup_in_so(si, name, &elf_hash);
 | 
					 | 
				
			||||||
    if(s != NULL)
 | 
					 | 
				
			||||||
        goto done;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for(d = si->dynamic; *d; d += 2) {
 | 
					 | 
				
			||||||
        if(d[0] == DT_NEEDED){
 | 
					 | 
				
			||||||
            lsi = (soinfo *)d[1];
 | 
					 | 
				
			||||||
            if (!validate_soinfo(lsi)) {
 | 
					 | 
				
			||||||
                DL_ERR("%5d bad DT_NEEDED pointer in %s",
 | 
					 | 
				
			||||||
                       pid, si->name);
 | 
					 | 
				
			||||||
                return 0;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            DEBUG("%5d %s: looking up %s in %s\n",
 | 
					 | 
				
			||||||
                  pid, si->name, name, lsi->name);
 | 
					 | 
				
			||||||
            s = _do_lookup_in_so(lsi, name, &elf_hash);
 | 
					 | 
				
			||||||
            if(s != NULL)
 | 
					 | 
				
			||||||
                goto done;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
done:
 | 
					 | 
				
			||||||
    if(s != NULL) {
 | 
					 | 
				
			||||||
        TRACE_TYPE(LOOKUP, "%5d si %s sym %s s->st_value = 0x%08x, "
 | 
					 | 
				
			||||||
                   "found in %s, base = 0x%08x\n",
 | 
					 | 
				
			||||||
                   pid, si->name, name, s->st_value, lsi->name, lsi->base);
 | 
					 | 
				
			||||||
        *base = lsi->base;
 | 
					 | 
				
			||||||
        return s;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* This is used by dl_sym().  It performs symbol lookup only within the
 | 
					 | 
				
			||||||
   specified soinfo object and not in any of its dependencies.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
Elf32_Sym *lookup_in_library(soinfo *si, const char *name)
 | 
					Elf32_Sym *lookup_in_library(soinfo *si, const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    unsigned unused = 0;
 | 
					    unsigned unused = 0;
 | 
				
			||||||
    return _do_lookup_in_so(si, name, &unused);
 | 
					    return _do_lookup_in_so(si, name, &unused);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This is used by dl_sym().  It performs a global symbol lookup.
 | 
					static Elf32_Sym *
 | 
				
			||||||
 */
 | 
					_do_lookup(soinfo *user_si, const char *name, unsigned *base)
 | 
				
			||||||
Elf32_Sym *lookup(const char *name, unsigned *base)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    unsigned elf_hash = 0;
 | 
					    unsigned elf_hash = 0;
 | 
				
			||||||
    Elf32_Sym *s = NULL;
 | 
					    Elf32_Sym *s = NULL;
 | 
				
			||||||
    soinfo *si;
 | 
					    soinfo *si;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Look for symbols in the local scope first (the object who is
 | 
				
			||||||
 | 
					     * searching). This happens with C++ templates on i386 for some
 | 
				
			||||||
 | 
					     * reason. */
 | 
				
			||||||
 | 
					    if (user_si) {
 | 
				
			||||||
 | 
					        s = _do_lookup_in_so(user_si, name, &elf_hash);
 | 
				
			||||||
 | 
					        if (s != NULL)
 | 
				
			||||||
 | 
					            *base = user_si->base;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(si = solist; (s == NULL) && (si != NULL); si = si->next)
 | 
					    for(si = solist; (s == NULL) && (si != NULL); si = si->next)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if(si->flags & FLAG_ERROR)
 | 
					        if((si->flags & FLAG_ERROR) || (si == user_si))
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        s = _do_lookup_in_so(si, name, &elf_hash);
 | 
					        s = _do_lookup_in_so(si, name, &elf_hash);
 | 
				
			||||||
        if (s != NULL) {
 | 
					        if (s != NULL) {
 | 
				
			||||||
@@ -499,7 +455,7 @@ Elf32_Sym *lookup(const char *name, unsigned *base)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(s != NULL) {
 | 
					    if (s != NULL) {
 | 
				
			||||||
        TRACE_TYPE(LOOKUP, "%5d %s s->st_value = 0x%08x, "
 | 
					        TRACE_TYPE(LOOKUP, "%5d %s s->st_value = 0x%08x, "
 | 
				
			||||||
                   "si->base = 0x%08x\n", pid, name, s->st_value, si->base);
 | 
					                   "si->base = 0x%08x\n", pid, name, s->st_value, si->base);
 | 
				
			||||||
        return s;
 | 
					        return s;
 | 
				
			||||||
@@ -508,6 +464,12 @@ Elf32_Sym *lookup(const char *name, unsigned *base)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This is used by dl_sym() */
 | 
				
			||||||
 | 
					Elf32_Sym *lookup(const char *name, unsigned *base)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return _do_lookup(NULL, name, base);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
static void dump(soinfo *si)
 | 
					static void dump(soinfo *si)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -1154,16 +1116,14 @@ unsigned unload_library(soinfo *si)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        for(d = si->dynamic; *d; d += 2) {
 | 
					        for(d = si->dynamic; *d; d += 2) {
 | 
				
			||||||
            if(d[0] == DT_NEEDED){
 | 
					            if(d[0] == DT_NEEDED){
 | 
				
			||||||
                soinfo *lsi = (soinfo *)d[1];
 | 
					 | 
				
			||||||
                d[1] = 0;
 | 
					 | 
				
			||||||
                if (validate_soinfo(lsi)) {
 | 
					 | 
				
			||||||
                TRACE("%5d %s needs to unload %s\n", pid,
 | 
					                TRACE("%5d %s needs to unload %s\n", pid,
 | 
				
			||||||
                          si->name, lsi->name);
 | 
					                      si->name, si->strtab + d[1]);
 | 
				
			||||||
 | 
					                soinfo *lsi = find_library(si->strtab + d[1]);
 | 
				
			||||||
 | 
					                if(lsi)
 | 
				
			||||||
                    unload_library(lsi);
 | 
					                    unload_library(lsi);
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    DL_ERR("%5d %s: could not unload dependent library",
 | 
					                    DL_ERR("%5d could not unload '%s'",
 | 
				
			||||||
                           pid, si->name);
 | 
					                          pid, si->strtab + d[1]);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1681,14 +1641,6 @@ static int link_image(soinfo *si, unsigned wr_offset)
 | 
				
			|||||||
                       pid, si->strtab + d[1], si->name, tmp_err_buf);
 | 
					                       pid, si->strtab + d[1], si->name, tmp_err_buf);
 | 
				
			||||||
                goto fail;
 | 
					                goto fail;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            /* Save the soinfo of the loaded DT_NEEDED library in the payload
 | 
					 | 
				
			||||||
               of the DT_NEEDED entry itself, so that we can retrieve the
 | 
					 | 
				
			||||||
               soinfo directly later from the dynamic segment.  This is a hack,
 | 
					 | 
				
			||||||
               but it allows us to map from DT_NEEDED to soinfo efficiently
 | 
					 | 
				
			||||||
               later on when we resolve relocations, trying to look up a symgol
 | 
					 | 
				
			||||||
               with dlsym().
 | 
					 | 
				
			||||||
            */
 | 
					 | 
				
			||||||
            d[1] = (unsigned)lsi;
 | 
					 | 
				
			||||||
            lsi->refcount++;
 | 
					            lsi->refcount++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user