summaryrefslogtreecommitdiff
path: root/src/format/elf/elf.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-04-05 19:11:16 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-04-05 19:11:16 (GMT)
commitc853ed6c88a82e2859033c4111b0edb0372bc570 (patch)
treefba98d186b6e80539c1e5aad9910316c0cb3725c /src/format/elf/elf.c
parentb6fd6dc823615aaee8661e8e2365181c1ea1775f (diff)
Reorganized the ELF header (32 or 64 bits).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@148 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/elf/elf.c')
-rw-r--r--src/format/elf/elf.c168
1 files changed, 27 insertions, 141 deletions
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index e7bb48c..ccd00ae 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -25,10 +25,12 @@
#include <malloc.h>
+#include <stddef.h>
#include <string.h>
#include "elf-int.h"
+#include "program.h"
#include "section.h"
#include "strings.h"
#include "symbols.h"
@@ -50,9 +52,6 @@ static void g_elf_format_class_init(GElfFormatClass *);
/* Initialise une instance de format d'exécutable ELF. */
static void g_elf_format_init(GElfFormat *);
-/* Procède à la lecture de l'en-tête d'un contenu binaire. */
-static bool read_elf_header(const bin_t *, off_t, elf_header *, bool *, SourceEndian *);
-
/* Indique le type d'architecture visée par le format. */
static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *);
@@ -152,126 +151,6 @@ static void g_elf_format_init(GElfFormat *format)
* *
* Paramètres : content = contenu binaire à parcourir. *
* length = taille du contenu en question. *
-* header = en-tête à déterminer. [OUT] *
-* is_32b = indique si le format est en 32 ou 64 bits. [OUT] *
-* endian = boutisme reconnu dans le format. [OUT] *
-* *
-* Description : Procède à la lecture de l'en-tête d'un contenu binaire. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool read_elf_header(const bin_t *content, off_t length, elf_header *header, bool *is_32b, SourceEndian *endian)
-{
- bool result; /* Bilan à retourner */
- off_t pos; /* Position de lecture */
-
- result = (length >= EI_NIDENT);
-
- pos = 0;
-
- if (result)
- {
- memcpy(header->e_ident, content, EI_NIDENT);
- pos += EI_NIDENT;
- }
-
- /* Détermination de l'espace d'adressage */
- if (result)
- switch (header->e_ident[EI_CLASS])
- {
- case ELFCLASS32:
- *is_32b = true;
- break;
- case ELFDATA2MSB:
- *is_32b = false;
- break;
- default:
- result = false;
- break;
- }
-
- /* Détermination du boutisme */
- if (result)
- switch (header->e_ident[EI_DATA])
- {
- case ELFDATA2LSB:
- *endian = SRE_LITTLE;
- break;
- case ELFDATA2MSB:
- *endian = SRE_BIG;
- break;
- default:
- result = false;
- break;
- }
-
- if (result)
- result = read_u16(&header->e_type, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_machine, content, &pos, length, *endian);
-
- if (result)
- result = read_u32(&header->e_version, content, &pos, length, *endian);
-
- if (result)
- {
- if (*is_32b)
- result = read_u32(&header->e_entry.addr32, content, &pos, length, *endian);
- else
- result = read_u64(&header->e_entry.addr64, content, &pos, length, *endian);
- }
-
- if (result)
- {
- if (*is_32b)
- result = read_u32(&header->e_phoff.off32, content, &pos, length, *endian);
- else
- result = read_u64(&header->e_phoff.off64, content, &pos, length, *endian);
- }
-
- if (result)
- {
- if (*is_32b)
- result = read_u32(&header->e_shoff.off32, content, &pos, length, *endian);
- else
- result = read_u64(&header->e_shoff.off64, content, &pos, length, *endian);
- }
-
- if (result)
- result = read_u32(&header->e_flags, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_ehsize, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_phentsize, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_phnum, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_shentsize, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_shnum, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_shstrndx, content, &pos, length, *endian);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : content = contenu binaire à parcourir. *
-* length = taille du contenu en question. *
* *
* Description : Prend en charge un nouveau format ELF. *
* *
@@ -298,25 +177,31 @@ GBinFormat *g_elf_format_new(const bin_t *content, off_t length)
/* Vérification des tailles d'entrée de table */
- if (result->header.e_phentsize != ELF_SIZEOF_PHDR(result))
+ if (ELF_HDR(result, result->header, e_phentsize) != ELF_SIZEOF_PHDR(result))
{
- log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"),
- result->header.e_phentsize);
- result->header.e_phentsize = ELF_SIZEOF_PHDR(result);
+ log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed ! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"),
+ ELF_HDR(result, result->header, e_phentsize),
+ ELF_HDR(result, result->header, e_phentsize),
+ ELF_SIZEOF_PHDR(result), ELF_HDR_OFFSET_OF(result, e_phentsize));
+ ELF_HDR_SET(result, result->header, e_phentsize, ELF_SIZEOF_PHDR(result));
}
- if (result->header.e_shentsize != ELF_SIZEOF_SHDR(result))
+ if (ELF_HDR(result, result->header, e_shentsize) != ELF_SIZEOF_SHDR(result))
{
- log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"),
- result->header.e_shentsize);
- result->header.e_shentsize = ELF_SIZEOF_SHDR(result);
+ log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed ! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"),
+ ELF_HDR(result, result->header, e_shentsize),
+ ELF_HDR(result, result->header, e_shentsize),
+ ELF_SIZEOF_SHDR(result), ELF_HDR_OFFSET_OF(result, e_shentsize));
+ ELF_HDR_SET(result, result->header, e_shentsize, ELF_SIZEOF_SHDR(result));
}
/* FIXME : à améliorer */
- if ((result->header.e_shnum * result->header.e_shentsize) >= length)
+ if ((ELF_HDR(result, result->header, e_shnum) * ELF_HDR(result, result->header, e_shentsize)) >= length)
{
- log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset !"));
- result->header.e_shnum = 0;
+ log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset ! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"),
+ ELF_HDR(result, result->header, e_shnum),
+ 0, ELF_HDR_OFFSET_OF(result, e_shnum));
+ ELF_HDR_SET(result, result->header, e_shnum, 0);
}
@@ -358,7 +243,7 @@ static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *for
{
FormatTargetMachine result; /* Identifiant à retourner */
- switch (format->header.e_machine)
+ switch (ELF_HDR(format, format->header, e_machine))
{
case EM_MIPS:
result = FTM_MIPS;
@@ -394,7 +279,7 @@ static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *for
static vmpa_t g_elf_format_get_entry_point(const GElfFormat *format)
{
- return (format->is_32b ? format->header.e_entry.addr32 : format->header.e_entry.addr64);
+ return ELF_HDR(format, format->header, e_entry);
}
@@ -427,11 +312,11 @@ static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count
result = NULL;
*count = 0;
- has_strings = find_elf_section_by_index(format, format->header.e_shstrndx, &strings);
+ has_strings = find_elf_section_by_index(format, ELF_HDR(format, format->header, e_shstrndx), &strings);
/* Première tentative : les sections */
- for (i = 0; i < format->header.e_shnum; i++)
+ for (i = 0; i < ELF_HDR(format, format->header, e_shnum); i++)
{
if (!find_elf_section_by_index(format, i, &section))
continue;
@@ -465,9 +350,10 @@ static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count
/* En désespoir de cause, on se rabbat sur les parties de programme directement */
if (*count == 0)
- for (i = 0; i < format->header.e_phnum; i++)
+ for (i = 0; i < ELF_HDR(format, format->header, e_phnum); i++)
{
- offset = ELF_OFF(format, format->header.e_phoff) + format->header.e_phentsize * i;
+ offset = ELF_HDR(format, format->header, e_phoff)
+ + ELF_HDR(format, format->header, e_phentsize) * i;
if (!read_elf_program_header(format, &offset, &phdr))
continue;
@@ -517,7 +403,7 @@ static bool g_elf_format_translate_address_into_offset(const GElfFormat *format,
result = translate_address_into_offset_using_elf_sections(format, addr, pos);
if (!result)
- /* TODO : prgm... */;
+ result = translate_address_into_offset_using_elf_programs(format, addr, pos);
return result;