summaryrefslogtreecommitdiff
path: root/src/format/elf/symbol.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2009-07-14 23:43:09 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2009-07-14 23:43:09 (GMT)
commitb5a2692820a0b85a03ff28fc2154f8d50f26d5e2 (patch)
tree9b6760ddedcb46ece3ec577f7494e40fabce7b87 /src/format/elf/symbol.c
parent24d7c72a124df20339a50bb61e66385352e68a1b (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.c251
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", &section);
-
- if (!test)
- {
- test = find_elf_section_by_type(format, SHT_HASH, &sections, &count);
-
- if (test)
- test = find_elf_section_by_index(format, ELF_SHDR(format, &sections[0], sh_link), &section);
-
- }
-
- if (test)
- {
- get_elf_section_content(format, &section, &dyn_start, &dyn_size, NULL);
-
- result &= find_elf_section_by_index(format, ELF_SHDR(format, &section, sh_link), &section);
-
- }
-
- if (result)
- {
- get_elf_section_content(format, &section, &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, &sections, &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", &section);
+
+ if (!test)
{
-#if 0
- instructions = decode_elf_relocations(format, &count);
+ test = find_elf_section_by_type(format, SHT_HASH, &sections, &count);
- translate_elf_relocations(format, instructions, count);
+ if (test)
+ test = find_elf_section_by_index(format, ELF_SHDR(format, &sections[0], sh_link), &section);
+
+ }
+
+ if (test)
+ {
+ get_elf_section_content(format, &section, &dyn_start, &dyn_size, NULL);
+
+ result &= find_elf_section_by_index(format, ELF_SHDR(format, &section, sh_link), &section);
- /* TODO : free instructions */
-#endif
}
-#endif
+ if (result)
+ {
+ get_elf_section_content(format, &section, &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, &sections, &sec_count);
-
- for (i = 0; i < sec_count; i++)
- if (ELF_SHDR(format, &sections[i], sh_entsize) > 0)
- {
- get_elf_section_content(format, &sections[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