/* Chrysalide - Outil d'analyse de fichiers binaires
* helper_x86.c - gestion auxiliaire de l'architecture x86
*
* Copyright (C) 2014-2017 Cyrille Bagard
*
* This file is part of Chrysalide.
*
* Chrysalide is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Chrysalide is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see .
*/
#include "helper_arm.h"
#include
#include
#include "elf_def_arm.h"
#include "elf-int.h"
#include "symbols.h"
/******************************************************************************
* *
* Paramètres : p_type = type associé à un en-tête de programme. *
* *
* Description : Fournit la description humaine d'un type de segment ELF. *
* *
* Retour : Désignation prête à emploi ou NULL si aucune. *
* *
* Remarques : - *
* *
******************************************************************************/
const char *get_elf_program_arm_type_desc(uint32_t p_type)
{
const char *result; /* Description à renvoyer */
#define MAKE_STRING_FROM_PT(pt) case pt: result = #pt; break;
switch(p_type)
{
MAKE_STRING_FROM_PT(PT_ARM_EXIDX);
default:
result = NULL;
break;
}
return result;
}
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
* relxxx = section .rel.xxx trouvée (zone à traiter). *
* dynsym = section .dynsym trouvée (info. dynamiques). *
* dynstr = section .dynstr trouvée (chaînes de caractères). *
* *
* Description : Charge en mémoire la liste des symboles relogés. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, const elf_shdr *dynsym, const elf_shdr *dynstr)
{
bool result; /* Bilan à retourner */
phys_t rel_start; /* Début de la zone à traiter */
phys_t rel_size; /* Taille de cette même zone */
GBinFormat *base; /* Autre version du format */
phys_t iter; /* Boucle de parcours */
elf_rel reloc; /* Infos de relocalisation */
off_t index; /* Indice de la portion visée */
elf_sym sym; /* Définition complète */
const char *name; /* Nom du symbole trouvé */
virt_t virt; /* Adresse en mémoire virtuelle*/
virt_t final_virt; /* Adresse virtuelle retenue */
bool status; /* Bilan d'une opération */
vmpa2t addr; /* Localisation d'une routine */
GBinRoutine *routine; /* Nouvelle routine trouvée */
GBinSymbol *symbol; /* Nouveau symbole construit */
mrange_t range; /* Couverture mémoire associée */
result = true;
get_elf_section_content(format, relxxx, &rel_start, &rel_size, NULL);
base = G_BIN_FORMAT(format);
for (iter = rel_start; iter < (rel_start + rel_size); )
{
result = read_elf_relocation(format, &iter, &reloc);
if (!result) break;
index = ELF_REL_SYM(format, reloc);
if (!get_elf_symbol_by_index(format, dynsym, index, &sym))
continue;
name = get_elf_symbol_name(format, dynsym, dynstr, index);
if (name == NULL)
{
/* FIXME */
name = "unknown";
}
switch (ELF_REL_TYPE(format, reloc))
{
case R_ARM_JUMP_SLOT:
virt = ELF_SYM(format, sym, st_value);
if (virt == 0) continue;
final_virt = virt & ~0x1;
status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr);
if (!status) continue;
routine = try_to_demangle_routine(name);
symbol = G_BIN_SYMBOL(routine);
init_mrange(&range, &addr, 0);
g_binary_symbol_set_range(symbol, &range);
/* Comptabilisation pour le désassemblage brut */
g_binary_format_register_code_point(base, virt, false);
break;
default:
assert(false);
symbol = NULL;
break;
}
if (symbol != NULL)
g_binary_format_add_symbol(base, symbol);
}
return result;
}