Commit c7c530cd authored by Stefan Weil's avatar Stefan Weil Committed by Andrzej Zaborowski
Browse files

elf: Improve symbol lookup (optimize, fix for bsd-user)



Coverity complained about local variable key which was only partially
initiated. Only key.st_value was set. As this was also the only part
of key which was used in function symfind, the code could be optimized
by directly passing a pointer to orig_addr.

In bsd-user/elfload.c, fix ec822001
was missing. This was a simple replacement of > by >= in symfind, so
I fixed it here without creating an additional patch.

Signed-off-by: default avatarStefan Weil <sw@weilnetz.de>
Signed-off-by: default avatarAndrzej Zaborowski <andrew.zaborowski@intel.com>
parent 563c2bf3
Loading
Loading
Loading
Loading
+4 −7
Original line number Diff line number Diff line
@@ -993,12 +993,12 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex,

static int symfind(const void *s0, const void *s1)
{
    struct elf_sym *key = (struct elf_sym *)s0;
    target_ulong addr = *(target_ulong *)s0;
    struct elf_sym *sym = (struct elf_sym *)s1;
    int result = 0;
    if (key->st_value < sym->st_value) {
    if (addr < sym->st_value) {
        result = -1;
    } else if (key->st_value > sym->st_value + sym->st_size) {
    } else if (addr >= sym->st_value + sym->st_size) {
        result = 1;
    }
    return result;
@@ -1013,12 +1013,9 @@ static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr)
#endif

    // binary search
    struct elf_sym key;
    struct elf_sym *sym;

    key.st_value = orig_addr;

    sym = bsearch(&key, syms, s->disas_num_syms, sizeof(*syms), symfind);
    sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms), symfind);
    if (sym != NULL) {
        return s->disas_strtab + sym->st_name;
    }
+5 −7
Original line number Diff line number Diff line
@@ -62,12 +62,12 @@ static struct elf_shdr *glue(find_section, SZ)(struct elf_shdr *shdr_table,

static int glue(symfind, SZ)(const void *s0, const void *s1)
{
    struct elf_sym *key = (struct elf_sym *)s0;
    target_phys_addr_t addr = *(target_phys_addr_t *)s0;
    struct elf_sym *sym = (struct elf_sym *)s1;
    int result = 0;
    if (key->st_value < sym->st_value) {
    if (addr < sym->st_value) {
        result = -1;
    } else if (key->st_value >= sym->st_value + sym->st_size) {
    } else if (addr >= sym->st_value + sym->st_size) {
        result = 1;
    }
    return result;
@@ -77,12 +77,10 @@ static const char *glue(lookup_symbol, SZ)(struct syminfo *s,
                                           target_phys_addr_t orig_addr)
{
    struct elf_sym *syms = glue(s->disas_symtab.elf, SZ);
    struct elf_sym key;
    struct elf_sym *sym;

    key.st_value = orig_addr;

    sym = bsearch(&key, syms, s->disas_num_syms, sizeof(*syms), glue(symfind, SZ));
    sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms),
                  glue(symfind, SZ));
    if (sym != NULL) {
        return s->disas_strtab + sym->st_name;
    }
+4 −7
Original line number Diff line number Diff line
@@ -1683,12 +1683,12 @@ static void load_elf_interp(const char *filename, struct image_info *info,

static int symfind(const void *s0, const void *s1)
{
    struct elf_sym *key = (struct elf_sym *)s0;
    target_ulong addr = *(target_ulong *)s0;
    struct elf_sym *sym = (struct elf_sym *)s1;
    int result = 0;
    if (key->st_value < sym->st_value) {
    if (addr < sym->st_value) {
        result = -1;
    } else if (key->st_value >= sym->st_value + sym->st_size) {
    } else if (addr >= sym->st_value + sym->st_size) {
        result = 1;
    }
    return result;
@@ -1703,12 +1703,9 @@ static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr)
#endif

    // binary search
    struct elf_sym key;
    struct elf_sym *sym;

    key.st_value = orig_addr;

    sym = bsearch(&key, syms, s->disas_num_syms, sizeof(*syms), symfind);
    sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms), symfind);
    if (sym != NULL) {
        return s->disas_strtab + sym->st_name;
    }