diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2009-07-14 23:43:09 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2009-07-14 23:43:09 (GMT) |
commit | b5a2692820a0b85a03ff28fc2154f8d50f26d5e2 (patch) | |
tree | 9b6760ddedcb46ece3ec577f7494e40fabce7b87 /src/format/elf/symbol.c | |
parent | 24d7c72a124df20339a50bb61e66385352e68a1b (diff) |
Restored the code loading the ELF relocations.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@93 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/elf/symbol.c')
-rw-r--r-- | src/format/elf/symbol.c | 251 |
1 files changed, 52 insertions, 199 deletions
diff --git a/src/format/elf/symbol.c b/src/format/elf/symbol.c index 225e032..4fd56fe 100644 --- a/src/format/elf/symbol.c +++ b/src/format/elf/symbol.c @@ -36,6 +36,7 @@ #include "elf-int.h" +#include "helper_mips.h" #include "section.h" @@ -51,12 +52,6 @@ bool load_elf_relocation_table(elf_format *, const off_t *, const off_t *, const /* Récupère les informations d'un symbole dynamique donné. */ char *get_elf_dynamic_symbol_info(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *); -/* Décode les instructions liées à la relocalisation. */ -//asm_instr **decode_elf_relocations(elf_format *, size_t *); - -/* Déduit les adresses effectives des relocalisations. */ -//void translate_elf_relocations(elf_format *, asm_instr **, size_t); - @@ -102,8 +97,6 @@ bool load_elf_symbols(elf_format *format) off_t dyn_size; /* Taille de section */ - //asm_instr **instructions; /* Instructions décodées */ - result = true; @@ -137,56 +130,11 @@ bool load_elf_symbols(elf_format *format) } - /* Liaison dynamique (si elle existe) */ - - test = find_elf_section_by_name(format, ".dynsym", §ion); - - if (!test) - { - test = find_elf_section_by_type(format, SHT_HASH, §ions, &count); - - if (test) - test = find_elf_section_by_index(format, ELF_SHDR(format, §ions[0], sh_link), §ion); - - } - - if (test) - { - get_elf_section_content(format, §ion, &dyn_start, &dyn_size, NULL); - - result &= find_elf_section_by_index(format, ELF_SHDR(format, §ion, sh_link), §ion); - - } - - if (result) - { - get_elf_section_content(format, §ion, &str_start, &str_size, NULL); + /* Relocalisations */ - switch (get_elf_target_machine(format)) - { - case FTM_MIPS: - result = g_elf_format_find_mips_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size); - break; - default: - break; - - } - - } - - - - - - - - - - - -#if 0 + /* TODO : fixme ! */ find_elf_section_by_type(format, SHT_REL, §ions, &count); @@ -215,35 +163,59 @@ bool load_elf_symbols(elf_format *format) result = load_elf_relocation_table(format, &rel_start, &rel_size, &dyn_start, &dyn_size, &str_start, &str_size); - } } free(sections); - /* Récupération (seconde partie) */ + /* TODO : fixme ! */ - /* switch ... */ - g_elf_format_translate_mips_external_calls(format); - exit(0); + /* Liaison dynamique (si elle existe) */ - if (result) + test = find_elf_section_by_name(format, ".dynsym", §ion); + + if (!test) { -#if 0 - instructions = decode_elf_relocations(format, &count); + test = find_elf_section_by_type(format, SHT_HASH, §ions, &count); - translate_elf_relocations(format, instructions, count); + if (test) + test = find_elf_section_by_index(format, ELF_SHDR(format, §ions[0], sh_link), §ion); + + } + + if (test) + { + get_elf_section_content(format, §ion, &dyn_start, &dyn_size, NULL); + + result &= find_elf_section_by_index(format, ELF_SHDR(format, §ion, sh_link), §ion); - /* TODO : free instructions */ -#endif } -#endif + if (result) + { + get_elf_section_content(format, §ion, &str_start, &str_size, NULL); + + switch (get_elf_target_machine(format)) + { + case FTM_MIPS: + result = g_elf_format_find_mips_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size); + break; + + case FTM_386: + result = g_elf_format_find_x86_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size); + break; + + default: + break; + + } + + } return result; @@ -274,6 +246,7 @@ bool load_elf_symbol_table_32(elf_format *format, const off_t *sym_start, const { off_t iter; /* Boucle de parcours */ Elf32_Sym symbol; /* Symbole ELF lu */ + GBinRoutine *routine; /* Nouvelle routine trouvée */ if (*sym_size % sizeof(Elf32_Sym) != 0) return false; @@ -293,11 +266,16 @@ bool load_elf_symbol_table_32(elf_format *format, const off_t *sym_start, const /* Si le symbole possède un nom... */ if (strlen(&EXE_FORMAT(format)->content[*str_start + symbol.st_name]) > 0) { - format->symbols = (elf_symbol *)realloc(format->symbols, ++format->sym_count * sizeof(elf_symbol)); + routine = g_binary_routine_new(); - format->symbols[format->sym_count - 1].name = &EXE_FORMAT(format)->content[*str_start + symbol.st_name]; - format->symbols[format->sym_count - 1].address = symbol.st_value; - format->symbols[format->sym_count - 1].size = symbol.st_size; + g_binary_routine_set_name(routine, strdup(&EXE_FORMAT(format)->content[*str_start + symbol.st_name])); + g_binary_routine_set_address(routine, symbol.st_value); + g_binary_routine_set_size(routine, symbol.st_size); + + format->routines = (GBinRoutine **)realloc(format->routines, + ++format->routines_count * sizeof(GBinRoutine *)); + + format->routines[format->routines_count - 1] = routine; } @@ -456,10 +434,10 @@ bool load_elf_relocation_table(elf_format *format, const off_t *plt_start, const if (name != NULL) { - format->symbols = (elf_symbol *)realloc(format->symbols, ++format->sym_count * sizeof(elf_symbol)); + format->relocations = (elf_symbol *)realloc(format->relocations, ++format->rel_count * sizeof(elf_symbol)); - format->symbols[format->sym_count - 1].name = name; - format->symbols[format->sym_count - 1].address = ELF_REL(format, reloc, r_offset); + format->relocations[format->rel_count - 1].name = name; + format->relocations[format->rel_count - 1].address = ELF_REL(format, reloc, r_offset); } @@ -519,128 +497,3 @@ char *get_elf_dynamic_symbol_info(elf_format *format, const off_t *dyn_start, co return (char *)&EXE_FORMAT(format)->content[*str_start + ELF_SYM(format, symbol, st_name)]; } - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* count = nombre d'instructions lues. [OUT] * -* * -* Description : Décode les instructions liées à la relocalisation. * -* * -* Retour : Liste des instructions décodées ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ -#if 0 -asm_instr **decode_elf_relocations(elf_format *format, size_t *count) -{ - asm_instr **result; /* Liste à renvoyer */ - off_t rel_start; /* Début de section */ - off_t rel_size; /* Taille de section */ - uint64_t rel_vaddress; /* Adresse virtuelle associée */ - Elf_Shdr *sections; /* Groupe de sections trouvées */ - size_t sec_count; /* Quantité de données */ - size_t i; /* Boucle de parcours */ - off_t pos; /* Tête de lecture */ - uint64_t offset; /* Adresse virtuelle courante */ - asm_instr *instr; /* Instruction décodée */ -#if 0 - asm_processor *proc; /* TODO : remove me ! */ - proc = create_x86_processor(); - - result = NULL; - *count = 0; - - if (!find_elf_section_content_by_name(format, ".plt", &rel_start, &rel_size, &rel_vaddress)) - { - printf("No .plt section found ! Trying to guess it...\n"); - - find_elf_section_by_type(format, SHT_PROGBITS, §ions, &sec_count); - - for (i = 0; i < sec_count; i++) - if (ELF_SHDR(format, §ions[i], sh_entsize) > 0) - { - get_elf_section_content(format, §ions[i], &rel_start, &rel_size, &rel_vaddress); - break; - } - - free(sections); - - if (i == sec_count) return NULL; - - } - - for (pos = 0; pos < rel_size; ) - { - offset = rel_vaddress + pos; - - instr = decode_instruction(proc, &EXE_FORMAT(format)->content[rel_start], &pos, rel_size, 0/* FIXME*/, offset); - - result = (asm_instr **)realloc(result, ++(*count) * sizeof(asm_instr *)); - result[*count - 1] = instr; - - } -#endif - - result = NULL; - *count = 0; - - return result; - -} -#endif -#if 0 -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* instructions = listes des instructions à interpréter. * -* count = nombre d'instructions lues. * -* * -* Description : Déduit les adresses effectives des relocalisations. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void translate_elf_relocations(elf_format *format, asm_instr **instructions, size_t count) -{ - size_t i; /* Boucle de parcours #1 */ - uint64_t address; /* Adresse virtuelle finale */ - size_t j; /* Boucle de parcours #2 */ - size_t new_len; /* Taille du nouveau nom */ - char *new_name; /* Nom avec suffixe @plt */ - - for (i = 0; (i + 2) < count; ) - { - if ((instructions[i]->type == AIT_JUMP || instructions[i]->type == AIT_CALL) - && instructions[i + 1]->type == AIT_PUSH - && instructions[i + 2]->type == AIT_JUMP) - { - if (get_imm_operand_value(instructions[i]->operands[0], AOS_64_BITS_UNSIGNED, &address)) - for (j = 0; j < format->sym_count; j++) - if (format->symbols[j].address == address) - { - new_len = strlen(format->symbols[j].name) + 4 + 1; - new_name = calloc(new_len, sizeof(char)); - snprintf(new_name, new_len, "%s@plt", format->symbols[j].name); - - format->symbols = (elf_symbol *)realloc(format->symbols, ++format->sym_count * sizeof(elf_symbol)); - - format->symbols[format->sym_count - 1].name = new_name; - format->symbols[format->sym_count - 1].address = instructions[i]->vaddress; - - } - - i += 3; - - } - else i++; - - } - -} -#endif |