int elf32_syms(FILE *in, stab_t stab) { struct elf32_info info; Elf32_Shdr *s; int ret = 0; if (read_all(&info, in) < 0) return -1; s = find_shdr(&info, SHT_SYMTAB); if (!s) { fprintf(stderr, "elf32: no symbol table\n"); return -1; } if (s->sh_link <= 0 || s->sh_link >= info.file_ehdr.e_shnum) { fprintf(stderr, "elf32: no string table\n"); return -1; } if (syms_load_strings(&info, in, &info.file_shdrs[s->sh_link]) < 0 || syms_load_syms(&info, in, s, stab) < 0) ret = -1; if (info.string_tab) free(info.string_tab); return ret; }
static int syms_load_syms(struct elf32_info *info, FILE *in, GElf_Shdr *s) { const char sym_debug = 0; int number = 0; int added = 0; char *name; /* now loop through the symbol table and print it*/ #if 1 /* Good: This works. */ Elf32_Sym *esym; Elf32_Sym *lastsym; esym = (Elf32_Sym*) info->string_data->d_buf; lastsym = (Elf32_Sym*) ((char*)info->string_data->d_buf + info->string_data->d_size); for (; esym && (esym < lastsym); esym++) { #else /* BAD: For some reason, st_value = 0 for all symbols? */ GElf_Sym isym; GElf_Sym *esym; while ((esym = gelf_getsym(info->string_data, number, &isym))) { #endif int st; st = ELF32_ST_TYPE(esym->st_info); name = elf_strptr(info->elf, s->sh_link, (size_t)esym->st_name); if (sym_debug) { printc("[%3d] name:%16s st:%d sz:%d info:%d other:%d value:%d ", number, name ? name : "<NULL>", st, esym->st_size, esym->st_info, esym->st_other, esym->st_value); } if ((name != NULL && name[0] != 0) && (st == STT_OBJECT || st == STT_FUNC || st == STT_SECTION || st == STT_COMMON || st == STT_TLS)) { if (sym_debug) { printc("stab_set(%s, %d)\n", name, esym->st_value); } if (stab_set(name, esym->st_value) < 0) { printc_err("elf32: stab_set #%d failed\n", number); return -1; } added++; } else { if (sym_debug) { printc("was ignored\n"); } } if (name == NULL) { printc_err("elf32: null symbol name %s\n", elf_errmsg(elf_errno())); exit(-1); } number++; } printc("load_syms found %d symbols, added %d\n", number, added); return 0; } int elf32_syms(FILE *in) { struct elf32_info info; GElf_Shdr *s; int ret = 0; if (read_all(&info, in) < 0) return -1; s = find_shdr(&info, SHT_SYMTAB); if (!s) { printc_err("elf32: no symbol table\n"); return -1; } if (s->sh_link <= 0 || s->sh_link >= info.file_ehdr.e_shnum) { printc_err("elf32: no string table\n"); return -1; } if (syms_load_strings(&info, in, &info.file_shdrs[s->sh_link]) < 0 || syms_load_syms(&info, in, s) < 0) ret = -1; return ret; }