diff options
Diffstat (limited to 'src/format/elf')
-rw-r--r-- | src/format/elf/symbols.c | 150 |
1 files changed, 112 insertions, 38 deletions
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index dc3fbe0..06d7cab 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -37,6 +37,7 @@ #include "../mangling/demangler.h" #include "../../arch/raw.h" #include "../../common/extstr.h" +#include "../../core/params.h" #include "../../gui/panels/log.h" @@ -123,6 +124,12 @@ bool load_elf_symbols(GElfFormat *format) + /* Symboles internes */ + result = load_elf_internal_symbols(format); + + + + /* Symboles externes */ if (find_elf_sections_by_type(format, SHT_DYNAMIC, §ions, &count)) @@ -137,7 +144,7 @@ bool load_elf_symbols(GElfFormat *format) else log_variadic_message(LMT_INFO, _("Binary is statically linked")); /* Symboles internes */ - result &= load_elf_internal_symbols(format); + //result &= load_elf_internal_symbols(format); return result; @@ -1272,70 +1279,137 @@ static bool annotate_elf_section_header_table(GElfFormat *format) static bool load_elf_internal_symbols(GElfFormat *format) { bool result; /* Bilan à retourner */ - elf_shdr *symtabs; /* Groupe de sections trouvées */ + bool no_name; /* Choix de construction de nom*/ + elf_shdr *sections; /* Groupe de sections trouvées */ size_t count; /* Quantité de données */ size_t i; /* Boucle de parcours */ - elf_shdr strtab; /* Section .strtab trouvée */ - bool has_strtab; /* Présence de cette section */ - off_t sym_start; /* Début de la zone à traiter */ - off_t sym_size; /* Taille de cette même zone */ - off_t iter; /* Boucle de parcours */ - const char *name; /* Nom du symbole trouvé */ - elf_sym sym; /* Symbole aux infos visées */ - GBinRoutine *routine; /* Nouvelle routine trouvée */ - GBinSymbol *symbol; /* Nouveau symbole construit */ result = true; - if (find_elf_sections_by_type(format, SHT_SYMTAB, &symtabs, &count)) - for (i = 0; i < count && result; i++) + /* Charge tous les symboles définis dans une section */ + bool add_all_symbols_from_section(GElfFormat *format, const elf_shdr *section, bool use_virt) + { + elf_shdr strtab; /* Section .strtab trouvée */ + bool has_strtab; /* Présence de cette section */ + off_t start; /* Début de la zone à traiter */ + off_t size; /* Taille de cette même zone */ + off_t iter; /* Boucle de parcours */ + elf_sym sym; /* Symbole aux infos visées */ + vmpa2t addr; /* Localisation d'une routine */ + const char *name; /* Nom du symbole trouvé */ + char alt_name[5 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/ + GBinRoutine *routine; /* Nouvelle routine trouvée */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + + has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, *section, sh_link), &strtab); + + get_elf_section_content(format, section, &start, &size, NULL); + + for (iter = start; iter < (start + size); ) { - has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, symtabs[i], sh_link), &strtab); + result = read_elf_symbol(format, &iter, &sym); + if (!result) break; + + if (ELF_SYM(format, sym, st_value) == 0) continue; + + /* Résolution précise d'adresse */ + + + /* TODO */ + + init_vmpa(&addr, ELF_SYM(format, sym, st_value), VMPA_NO_VIRTUAL); - get_elf_section_content(format, &symtabs[i], &sym_start, &sym_size, NULL); - for (iter = sym_start; iter < (sym_start + sym_size); ) + + /* Première ébauche de nom */ + + if (!has_strtab) name = NULL; + else name = get_elf_symbol_name(format, section, &strtab, + ((iter - start) / ELF_SIZEOF_SYM(format)) - 1); + + /* Traitements particuliers */ + + switch (ELF_ST_TYPE(format, sym)) { - result = read_elf_symbol(format, &iter, &sym); - if (!result) break; + case STT_OBJECT: - if (ELF_SYM(format, sym, st_value) == 0) continue; + /* Création d'un nom unique ? */ - if (!(ELF_ST_TYPE(format, sym) == STT_FUNC)) continue; + if (name != NULL) + { + strcpy(alt_name, "obj_"); - if (!has_strtab) name = NULL; - else name = get_elf_symbol_name(format, &symtabs[i], &strtab, - ((iter - sym_start) / ELF_SIZEOF_SYM(format)) - 1); + if (use_virt) + vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL); + else + vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL); - if (name == NULL) - { - /* FIXME */ - name = "unknown"; - } + } + + + /* TODO */ + + symbol = NULL; - /* Routine */ - routine = try_to_demangle_routine(name); + break; + + case STT_FUNC: + + /* Création d'un nom unique ? */ + + if (name != NULL) + { + strcpy(alt_name, "func_"); + + if (use_virt) + vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); + else + vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); - g_binary_routine_set_address(routine, ELF_SYM(format, sym, st_value)); - g_binary_routine_set_size(routine, ELF_SYM(format, sym, st_size)); + } + + /* Routine */ + + routine = try_to_demangle_routine(name); - ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine); + g_binary_routine_set_address(routine, &addr); + g_binary_routine_set_size(routine, ELF_SYM(format, sym, st_size)); - /* Symbole uniquement */ + /* Symbole uniquement */ - symbol = g_binary_symbol_new(STP_FUNCTION, name, ELF_SYM(format, sym, st_value)); + symbol = g_binary_symbol_new(STP_ROUTINE, name, ~0); + g_binary_symbol_attach_routine(symbol, routine); - g_binary_symbol_attach_routine(symbol, routine); + break; - ///// reactiver g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + default: + symbol = NULL; + break; } + if (symbol != NULL) + g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); } - return true; + return true; + + } + + if (!g_generic_config_get_value(get_main_configuration(), MPK_FORMAT_NO_NAME, &no_name)) + return false; + + if (find_elf_sections_by_type(format, SHT_DYNSYM, §ions, &count)) + for (i = 0; i < count && result; i++) + result = add_all_symbols_from_section(format, §ions[i], no_name); + + if (find_elf_sections_by_type(format, SHT_SYMTAB, §ions, &count)) + for (i = 0; i < count && result; i++) + result = add_all_symbols_from_section(format, §ions[i], no_name); + + return result; } |