diff options
Diffstat (limited to 'tools/objtool/elf.c')
-rw-r--r-- | tools/objtool/elf.c | 59 |
1 files changed, 28 insertions, 31 deletions
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index d897702ce742..1a7e8aa2af58 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -37,6 +37,9 @@ #define ELF_C_READ_MMAP ELF_C_READ #endif +#define WARN_ELF(format, ...) \ + WARN(format ": %s", ##__VA_ARGS__, elf_errmsg(-1)) + struct section *find_section_by_name(struct elf *elf, const char *name) { struct section *sec; @@ -139,12 +142,12 @@ static int read_sections(struct elf *elf) int i; if (elf_getshdrnum(elf->elf, §ions_nr)) { - perror("elf_getshdrnum"); + WARN_ELF("elf_getshdrnum"); return -1; } if (elf_getshdrstrndx(elf->elf, &shstrndx)) { - perror("elf_getshdrstrndx"); + WARN_ELF("elf_getshdrstrndx"); return -1; } @@ -165,37 +168,36 @@ static int read_sections(struct elf *elf) s = elf_getscn(elf->elf, i); if (!s) { - perror("elf_getscn"); + WARN_ELF("elf_getscn"); return -1; } sec->idx = elf_ndxscn(s); if (!gelf_getshdr(s, &sec->sh)) { - perror("gelf_getshdr"); + WARN_ELF("gelf_getshdr"); return -1; } sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name); if (!sec->name) { - perror("elf_strptr"); + WARN_ELF("elf_strptr"); return -1; } - sec->elf_data = elf_getdata(s, NULL); - if (!sec->elf_data) { - perror("elf_getdata"); + sec->data = elf_getdata(s, NULL); + if (!sec->data) { + WARN_ELF("elf_getdata"); return -1; } - if (sec->elf_data->d_off != 0 || - sec->elf_data->d_size != sec->sh.sh_size) { + if (sec->data->d_off != 0 || + sec->data->d_size != sec->sh.sh_size) { WARN("unexpected data attributes for %s", sec->name); return -1; } - sec->data = (unsigned long)sec->elf_data->d_buf; - sec->len = sec->elf_data->d_size; + sec->len = sec->data->d_size; } /* sanity check, one more call to elf_nextscn() should return NULL */ @@ -232,15 +234,15 @@ static int read_symbols(struct elf *elf) sym->idx = i; - if (!gelf_getsym(symtab->elf_data, i, &sym->sym)) { - perror("gelf_getsym"); + if (!gelf_getsym(symtab->data, i, &sym->sym)) { + WARN_ELF("gelf_getsym"); goto err; } sym->name = elf_strptr(elf->elf, symtab->sh.sh_link, sym->sym.st_name); if (!sym->name) { - perror("elf_strptr"); + WARN_ELF("elf_strptr"); goto err; } @@ -322,8 +324,8 @@ static int read_relas(struct elf *elf) } memset(rela, 0, sizeof(*rela)); - if (!gelf_getrela(sec->elf_data, i, &rela->rela)) { - perror("gelf_getrela"); + if (!gelf_getrela(sec->data, i, &rela->rela)) { + WARN_ELF("gelf_getrela"); return -1; } @@ -362,12 +364,6 @@ struct elf *elf_open(const char *name) INIT_LIST_HEAD(&elf->sections); - elf->name = strdup(name); - if (!elf->name) { - perror("strdup"); - goto err; - } - elf->fd = open(name, O_RDONLY); if (elf->fd == -1) { perror("open"); @@ -376,12 +372,12 @@ struct elf *elf_open(const char *name) elf->elf = elf_begin(elf->fd, ELF_C_READ_MMAP, NULL); if (!elf->elf) { - perror("elf_begin"); + WARN_ELF("elf_begin"); goto err; } if (!gelf_getehdr(elf->elf, &elf->ehdr)) { - perror("gelf_getehdr"); + WARN_ELF("gelf_getehdr"); goto err; } @@ -407,6 +403,12 @@ void elf_close(struct elf *elf) struct symbol *sym, *tmpsym; struct rela *rela, *tmprela; + if (elf->elf) + elf_end(elf->elf); + + if (elf->fd > 0) + close(elf->fd); + list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) { list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) { list_del(&sym->list); @@ -421,11 +423,6 @@ void elf_close(struct elf *elf) list_del(&sec->list); free(sec); } - if (elf->name) - free(elf->name); - if (elf->fd > 0) - close(elf->fd); - if (elf->elf) - elf_end(elf->elf); + free(elf); } |