diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/Makefile.am | 2 | ||||
| -rw-r--r-- | plugins/fmtp/Makefile.am | 13 | ||||
| -rw-r--r-- | plugins/fmtp/def.h | 149 | ||||
| -rw-r--r-- | plugins/fmtp/parser.c | 223 | ||||
| -rw-r--r-- | plugins/fmtp/parser.h | 43 | ||||
| -rw-r--r-- | plugins/readelf/Makefile.am | 3 | ||||
| -rw-r--r-- | plugins/readelf/header.c | 670 | ||||
| -rw-r--r-- | plugins/readelf/header.h | 2 | ||||
| -rw-r--r-- | plugins/readelf/program.c | 405 | ||||
| -rw-r--r-- | plugins/readelf/reader.c | 2 | ||||
| -rw-r--r-- | plugins/readelf/section.c | 530 | 
11 files changed, 1275 insertions, 767 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index d0b8fc8..0cbe6fa 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -4,4 +4,4 @@ if HAVE_PYTHON3_CONFIG  endif  # androhelpers -SUBDIRS = devdbg libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf ropgadgets +SUBDIRS = devdbg fmtp libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf ropgadgets diff --git a/plugins/fmtp/Makefile.am b/plugins/fmtp/Makefile.am new file mode 100644 index 0000000..1c5d0d9 --- /dev/null +++ b/plugins/fmtp/Makefile.am @@ -0,0 +1,13 @@ + +lib_LTLIBRARIES = libfmtp.la + +libfmtp_la_SOURCES =					\ +	def.h								\ +	parser.h parser.c + +libfmtp_la_CFLAGS = $(AM_CFLAGS) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/fmtp/def.h b/plugins/fmtp/def.h new file mode 100644 index 0000000..d69d20a --- /dev/null +++ b/plugins/fmtp/def.h @@ -0,0 +1,149 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * def.h - prototypes pour la définition des unités de lecture + * + * Copyright (C) 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_FMTP_DEF_H +#define _PLUGINS_FMTP_DEF_H + + +#include <stdbool.h> + + +#include <arch/archbase.h> +#include <common/cpp.h> + + + +/** + * Assurément utile pour les déclarations... + */ + +#define __(s) s + + +/** + * Méthodes de définitions des déclarations. + */ + +/* Possibilités pour un champ à commenter */ +typedef struct _field_desc_switch +{ +    bool is_range;                          /* Sélection de définition     */ + +    union +    { +        uint64_t fixed;                     /* Valeur fixe                 */ + +        struct +        { +            uint64_t lower;                 /* Borne basse                 */ +            uint64_t upper;                 /* Borne haute                 */ +        }; + +    }; + +    const char *desc;                       /* Description associée        */ + +} field_desc_switch; + +/* Partie de commentaire */ +typedef struct _comment_part +{ +    bool is_static;                         /* Choix du champ textuel      */ +    bool avoid_i18n;                        /* Pas de traduction !         */ + +    union +    { +        const char *static_text;            /* Texte alloué statiquement   */ +        char *dynamic_text;                 /* Texte alloué dynamiquement  */ +    }; + +} comment_part; + +/* Type de commentaires associés */ +typedef enum _FieldCommentType +{ +    FCT_PLAIN,                              /* Brut et statique            */ +    FCT_SWITCH,                             /* Eventail des possibles      */ +    FCT_MULTI                               /* En plusieurs parties        */ + +} FieldCommentType; + +/* Définition générale */ +typedef struct _fmt_field_def +{ +    const char *name;                       /* Nom du champ                */ + +    MemoryDataSize size;                    /* Taille d'un élément         */ +    size_t repeat;                          /* Quantité d'éléments présents*/ + +    bool is_padding;                        /* Simple bourrage ?           */ + +    bool has_display_rules;                 /* Validité des champs suivants*/ +    const ImmOperandDisplay *disp_rules;    /* Règles d'affichage          */ +    size_t disp_count;                      /* Quantité de ces règles      */ + +    FieldCommentType ctype;                 /* Type de commentaire         */ +    union +    { +        const char *plain;                  /* Commentaire simple          */ + +        struct +        { +            const field_desc_switch *choices; /* Choix multiples           */ +            size_t ccount;                  /* Quantité de ces choix       */ +            const char *def_choice;         /* Commentaire par défaut      */ +        }; + +        struct +        { +            comment_part *parts;            /* Parties à considérer        */ +            size_t pcount;                  /* Quantité de ces parties     */ +        }; + +    } comment; + +} fmt_field_def; + + +/* Règles d'affichage */ + +#define DISPLAY_RULES(...)                                              \ +    .has_display_rules = true,                                          \ +    .disp_rules = (ImmOperandDisplay []) { __VA_ARGS__ },               \ +    .disp_count = ARRAY_SIZE(((ImmOperandDisplay []) { __VA_ARGS__ })) + +/* Rédaction des commentaires */ + +#define PLAIN_COMMENT(txt)                  \ +    .ctype = FCT_PLAIN,                     \ +    .comment.plain = txt + +#define SWITCH_COMMENT(array, def)          \ +    .ctype = FCT_SWITCH,                    \ +    .comment.choices = array,               \ +    .comment.ccount = ARRAY_SIZE(array),    \ +    .comment.def_choice = def + + + +#endif  /* _PLUGINS_FMTP_DEF_H */ diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c new file mode 100644 index 0000000..2f469c1 --- /dev/null +++ b/plugins/fmtp/parser.c @@ -0,0 +1,223 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * parser.c - interprétation des champs d'un format binaire + * + * Copyright (C) 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 <http://www.gnu.org/licenses/>. + */ + + +#include "parser.h" + + +#include <assert.h> + + +#include <i18n.h> +#include <arch/raw.h> + + + +/* Effectue l'interprétation d'une définition de champ. */ +static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *); + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : def    = définition de champ à considérer.                   * +*                format = description de l'exécutable à compléter.            * +*                pos    = tête de lecture pour les données.                   * +*                                                                             * +*  Description : Effectue l'interprétation d'une définition de champ.         * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos) +{ +    GBinContent *content;                   /* Contenu binaire à lire      */ +    SourceEndian endian;                    /* Boutisme utilisé            */ +    bool result;                            /* Bilan à retourner           */ +    GArchInstruction *instr;                /* Instruction décodée         */ +    GImmOperand *imm;                       /* Opérande à transformer      */ +    size_t i;                               /* Boucle de parcours          */ +    const vmpa2t *addr;                     /* Emplacement d'instruction   */ +    GDbComment *comment;                    /* Définition de commentaire   */ +    uint64_t raw;                           /* Valeur brute à étudier      */ +    const comment_part *part;               /* Accès plus direct           */ + + +    GBinSymbol *symbol;                     /* Symbole à intégrer          */ + + +    /* Lecture */ + +    content = g_binary_format_get_content(format); +    endian = g_binary_format_get_endianness(format); + +    assert(def->repeat > 0); + +    instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian); + +    result = (instr != NULL); + +    if (!result) +        goto pfd_exit; + +    if (def->is_padding) +        g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true); + +    if (def->has_display_rules) +    { +        assert(def->disp_count <= def->repeat); + +        for (i = 0; i < def->disp_count; i++) +        { +            imm = G_IMM_OPERAND(g_arch_instruction_get_operand(instr, i)); + +            g_imm_operand_set_default_display(&imm, def->disp_rules[i], G_SHARE_CONTAINER(instr)); +            g_imm_operand_set_display(&imm, def->disp_rules[i], G_SHARE_CONTAINER(instr)); + +            // TODO : unref(imm) + +        } + +    } + +    /* Commentaire */ + +    addr = get_mrange_addr(g_arch_instruction_get_range(instr)); + +    comment = g_db_comment_new_inlined(addr, BLF_HAS_CODE, false); +    g_db_item_set_volatile(G_DB_ITEM(comment), true); + +    switch (def->ctype) +    { +        case FCT_PLAIN: +            g_db_comment_add_static_text(comment, _(def->comment.plain)); +            break; + +        case FCT_SWITCH: + +            imm = G_IMM_OPERAND(g_arch_instruction_get_operand(instr, 0)); +            raw = g_imm_operand_get_raw_value(imm); +            // TODO : unref(imm) + +            for (i = 0; i < def->comment.ccount; i++) +            { +                if (def->comment.choices[i].is_range) +                { +                    if (raw < def->comment.choices[i].lower) +                        continue; +                    if (raw > def->comment.choices[i].upper) +                        continue; +                } + +                else if (raw != def->comment.choices[i].fixed) +                    continue; + +                g_db_comment_add_static_text(comment, _(def->comment.choices[i].desc)); +                break; + +            } + +            if (i == def->comment.ccount) +                g_db_comment_add_static_text(comment, _(def->comment.def_choice)); + +            break; + +        case FCT_MULTI: + +            for (i = 0; i < def->comment.pcount; i++) +            { +                part = &def->comment.parts[i]; + +                if (part->is_static) +                { +                    if (part->avoid_i18n) +                        g_db_comment_add_static_text(comment, part->static_text); +                    else +                        g_db_comment_add_static_text(comment, _(part->static_text)); +                } +                else +                { +                    if (part->avoid_i18n) +                        g_db_comment_add_dynamic_text(comment, part->dynamic_text); +                    else +                        g_db_comment_add_dynamic_text(comment, _(part->dynamic_text)); +                } + +            } + +            break; + +    } + +    /* Insertion */ + +    symbol = g_binary_symbol_new(STP_DATA); + +    g_binary_symbol_attach_instruction(symbol, instr); +    g_binary_symbol_set_comment(symbol, comment); + +    result = g_binary_format_add_symbol(format, symbol); + +    if (!result) +        g_object_unref(G_OBJECT(instr)); + + pfd_exit: + +    g_object_unref(G_OBJECT(content)); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : defs   = liste de définitions à traiter.                     * +*                count  = taille de cette liste.                              * +*                format = description de l'exécutable à compléter.            * +*                pos    = tête de lecture pour les données.                   * +*                                                                             * +*  Description : Lance l'interprétation d'une série de définitions de champs. * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos) +{ +    bool result;                            /* Bilan à retourner           */ +    size_t i;                               /* Boucle de parcours          */ + +    result = true; + +    for (i = 0; i < count && result; i++) +        result = parse_field_definition(defs + i, format, pos); + +    return result; + +} diff --git a/plugins/fmtp/parser.h b/plugins/fmtp/parser.h new file mode 100644 index 0000000..dcd9bf2 --- /dev/null +++ b/plugins/fmtp/parser.h @@ -0,0 +1,43 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * parser.h - prototypes pour l'interprétation des champs d'un format binaire + * + * Copyright (C) 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_FMTP_PARSER_H +#define _PLUGINS_FMTP_PARSER_H + + +#include <stdbool.h> + + +#include <format/format.h> + + +#include "def.h" + + + +/* Lance l'interprétation d'une série de définitions de champs. */ +bool parse_field_definitions(const fmt_field_def *, size_t, GBinFormat *, vmpa2t *); + + + +#endif  /* _PLUGINS_FMTP_PARSER_H */ diff --git a/plugins/readelf/Makefile.am b/plugins/readelf/Makefile.am index 13f45f8..c3cf822 100644 --- a/plugins/readelf/Makefile.am +++ b/plugins/readelf/Makefile.am @@ -10,7 +10,8 @@ libreadelf_la_SOURCES =					\  libreadelf_la_CFLAGS = $(AM_CFLAGS) +libreadelf_la_LDFLAGS = -L../../plugins/fmtp/.libs -lfmtp -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src -I../..  AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/readelf/header.c b/plugins/readelf/header.c index d0aee92..21884a3 100644 --- a/plugins/readelf/header.c +++ b/plugins/readelf/header.c @@ -24,435 +24,473 @@  #include "header.h" -#include <i18n.h> -#include <arch/raw.h> -#include <format/symbol.h> +#include <common/cpp.h> +#include <plugins/fmtp/parser.h> + + + +/* Définition des champs */ + +static field_desc_switch _elf_classes[] = { + +    { .fixed = EV_NONE,    .desc = __("File class: invalid") }, +    { .fixed = ELFCLASS32, .desc = __("File class: 32-bit objects") }, +    { .fixed = ELFCLASS64, .desc = __("File class: 64-bit objects") } + +}; + +static field_desc_switch _elf_data[] = { + +    { .fixed = ELFDATANONE, .desc = __("Data encoding: invalid") }, +    { .fixed = ELFDATA2LSB, .desc = __("Data encoding: 2's complement, little endian") }, +    { .fixed = ELFDATA2MSB, .desc = __("Data encoding: 2's complement, big endian") } + +}; + +static field_desc_switch _elf_versions[] = { + +    { .fixed = EV_NONE,    .desc = __("File version: invalid") }, +    { .fixed = EV_CURRENT, .desc = __("File version: current") } + +}; + +static field_desc_switch _elf_os_abis[] = { + +    { .fixed = ELFOSABI_SYSV,       .desc = __("OS ABI: UNIX System V ABI") }, +    { .fixed = ELFOSABI_HPUX,       .desc = __("OS ABI: HP-UX") }, +    { .fixed = ELFOSABI_NETBSD,     .desc = __("OS ABI: NetBSD") }, +    { .fixed = ELFOSABI_GNU,        .desc = __("OS ABI: Object uses GNU ELF extensions") }, +    { .fixed = ELFOSABI_SOLARIS,    .desc = __("OS ABI: Sun Solaris") }, +    { .fixed = ELFOSABI_AIX,        .desc = __("OS ABI: IBM AIX") }, +    { .fixed = ELFOSABI_IRIX,       .desc = __("OS ABI: SGI Irix") }, +    { .fixed = ELFOSABI_FREEBSD,    .desc = __("OS ABI: FreeBSD") }, +    { .fixed = ELFOSABI_TRU64,      .desc = __("OS ABI: Compaq TRU64 UNIX") }, +    { .fixed = ELFOSABI_MODESTO,    .desc = __("OS ABI: Novell Modesto") }, +    { .fixed = ELFOSABI_OPENBSD,    .desc = __("OS ABI: OpenBSD") }, +    { .fixed = ELFOSABI_ARM_AEABI,  .desc = __("OS ABI: ARM EABI") }, +    { .fixed = ELFOSABI_ARM,        .desc = __("OS ABI: ARM") }, +    { .fixed = ELFOSABI_STANDALONE, .desc = __("OS ABI: Standalone (embedded) application") } + +}; + +static field_desc_switch _elf_types[] = { + +    { .fixed = ET_NONE, .desc = __("Object file type: no file type") }, +    { .fixed = ET_REL,  .desc = __("Object file type: relocatable file") }, +    { .fixed = ET_EXEC, .desc = __("Object file type: executable file") }, +    { .fixed = ET_DYN,  .desc = __("Object file type: shared object file") }, +    { .fixed = ET_CORE, .desc = __("Object file type: core file") }, +    { .lower = ET_LOOS,   .upper = ET_HIOS,   .desc = __("Object file type: OS-specific") }, +    { .lower = ET_LOPROC, .upper = ET_HIPROC, .desc = __("Object file type: processor-specific") } + +}; + +static field_desc_switch _elf_machines[] = { + +    { .fixed = EM_NONE,        .desc = __("Architecture: No machine") }, +    { .fixed = EM_M32,         .desc = __("Architecture: AT&T WE 32100") }, +    { .fixed = EM_SPARC,       .desc = __("Architecture: SUN SPARC") }, +    { .fixed = EM_386,         .desc = __("Architecture: Intel 80386") }, +    { .fixed = EM_68K,         .desc = __("Architecture: Motorola m68k family") }, +    { .fixed = EM_88K,         .desc = __("Architecture: Motorola m88k family") }, +    { .fixed = EM_860,         .desc = __("Architecture: Intel 80860") }, +    { .fixed = EM_MIPS,        .desc = __("Architecture: MIPS R3000 big-endian") }, +    { .fixed = EM_S370,        .desc = __("Architecture: IBM System/370") }, +    { .fixed = EM_MIPS_RS3_LE, .desc = __("Architecture: MIPS R3000 little-endian") }, +    { .fixed = EM_PARISC,      .desc = __("Architecture: HPPA") }, +    { .fixed = EM_VPP500,      .desc = __("Architecture: Fujitsu VPP500") }, +    { .fixed = EM_SPARC32PLUS, .desc = __("Architecture: Sun's \"v8plus\"") }, +    { .fixed = EM_960,         .desc = __("Architecture: Intel 80960") }, +    { .fixed = EM_PPC,         .desc = __("Architecture: PowerPC") }, +    { .fixed = EM_PPC64,       .desc = __("Architecture: PowerPC 64-bit") }, +    { .fixed = EM_S390,        .desc = __("Architecture: IBM S390") }, +    { .fixed = EM_V800,        .desc = __("Architecture: NEC V800 series") }, +    { .fixed = EM_FR20,        .desc = __("Architecture: Fujitsu FR20") }, +    { .fixed = EM_RH32,        .desc = __("Architecture: TRW RH-32") }, +    { .fixed = EM_RCE,         .desc = __("Architecture: Motorola RCE") }, +    { .fixed = EM_ARM,         .desc = __("Architecture: ARM") }, +    { .fixed = EM_FAKE_ALPHA,  .desc = __("Architecture: Digital Alpha") }, +    { .fixed = EM_SH,          .desc = __("Architecture: Hitachi SH") }, +    { .fixed = EM_SPARCV9,     .desc = __("Architecture: SPARC v9 64-bit") }, +    { .fixed = EM_TRICORE,     .desc = __("Architecture: Siemens Tricore") }, +    { .fixed = EM_ARC,         .desc = __("Architecture: Argonaut RISC Core") }, +    { .fixed = EM_H8_300,      .desc = __("Architecture: Hitachi H8/300") }, +    { .fixed = EM_H8_300H,     .desc = __("Architecture: Hitachi H8/300H") }, +    { .fixed = EM_H8S,         .desc = __("Architecture: Hitachi H8S") }, +    { .fixed = EM_H8_500,      .desc = __("Architecture: Hitachi H8/500") }, +    { .fixed = EM_IA_64,       .desc = __("Architecture: Intel Merced") }, +    { .fixed = EM_MIPS_X,      .desc = __("Architecture: Stanford MIPS-X") }, +    { .fixed = EM_COLDFIRE,    .desc = __("Architecture: Motorola Coldfire") }, +    { .fixed = EM_68HC12,      .desc = __("Architecture: Motorola M68HC12") }, +    { .fixed = EM_MMA,         .desc = __("Architecture: Fujitsu MMA Multimedia Accelerator") }, +    { .fixed = EM_PCP,         .desc = __("Architecture: Siemens PCP") }, +    { .fixed = EM_NCPU,        .desc = __("Architecture: Sony nCPU embeeded RISC") }, +    { .fixed = EM_NDR1,        .desc = __("Architecture: Denso NDR1 microprocessor") }, +    { .fixed = EM_STARCORE,    .desc = __("Architecture: Motorola Start*Core processor") }, +    { .fixed = EM_ME16,        .desc = __("Architecture: Toyota ME16 processor") }, +    { .fixed = EM_ST100,       .desc = __("Architecture: STMicroelectronic ST100 processor") }, +    { .fixed = EM_TINYJ,       .desc = __("Architecture: Advanced Logic Corp. Tinyj emb.fam") }, +    { .fixed = EM_X86_64,      .desc = __("Architecture: AMD x86-64 architecture") }, +    { .fixed = EM_PDSP,        .desc = __("Architecture: Sony DSP Processor") }, +    { .fixed = EM_FX66,        .desc = __("Architecture: Siemens FX66 microcontroller") }, +    { .fixed = EM_ST9PLUS,     .desc = __("Architecture: STMicroelectronics ST9+ 8/16 mc") }, +    { .fixed = EM_ST7,         .desc = __("Architecture: STmicroelectronics ST7 8 bit mc") }, +    { .fixed = EM_68HC16,      .desc = __("Architecture: Motorola MC68HC16 microcontroller") }, +    { .fixed = EM_68HC11,      .desc = __("Architecture: Motorola MC68HC11 microcontroller") }, +    { .fixed = EM_68HC08,      .desc = __("Architecture: Motorola MC68HC08 microcontroller") }, +    { .fixed = EM_68HC05,      .desc = __("Architecture: Motorola MC68HC05 microcontroller") }, +    { .fixed = EM_SVX,         .desc = __("Architecture: Silicon Graphics SVx") }, +    { .fixed = EM_ST19,        .desc = __("Architecture: STMicroelectronics ST19 8 bit mc") }, +    { .fixed = EM_VAX,         .desc = __("Architecture: Digital VAX") }, +    { .fixed = EM_CRIS,        .desc = __("Architecture: Axis Communications 32-bit embedded processor") }, +    { .fixed = EM_JAVELIN,     .desc = __("Architecture: Infineon Technologies 32-bit embedded processor") }, +    { .fixed = EM_FIREPATH,    .desc = __("Architecture: Element 14 64-bit DSP Processor") }, +    { .fixed = EM_ZSP,         .desc = __("Architecture: LSI Logic 16-bit DSP Processor") }, +    { .fixed = EM_MMIX,        .desc = __("Architecture: Donald Knuth's educational 64-bit processor") }, +    { .fixed = EM_HUANY,       .desc = __("Architecture: Harvard University machine-independent object files") }, +    { .fixed = EM_PRISM,       .desc = __("Architecture: SiTera Prism") }, +    { .fixed = EM_AVR,         .desc = __("Architecture: Atmel AVR 8-bit microcontroller") }, +    { .fixed = EM_FR30,        .desc = __("Architecture: Fujitsu FR30") }, +    { .fixed = EM_D10V,        .desc = __("Architecture: Mitsubishi D10V") }, +    { .fixed = EM_D30V,        .desc = __("Architecture: Mitsubishi D30V") }, +    { .fixed = EM_V850,        .desc = __("Architecture: NEC v850") }, +    { .fixed = EM_M32R,        .desc = __("Architecture: Mitsubishi M32R") }, +    { .fixed = EM_MN10300,     .desc = __("Architecture: Matsushita MN10300") }, +    { .fixed = EM_MN10200,     .desc = __("Architecture: Matsushita MN10200") }, +    { .fixed = EM_PJ,          .desc = __("Architecture: picoJava") }, +    { .fixed = EM_OPENRISC,    .desc = __("Architecture: OpenRISC 32-bit embedded processor") }, +    { .fixed = EM_ARC_A5,      .desc = __("Architecture: ARC Cores Tangent-A5") }, +    { .fixed = EM_XTENSA,      .desc = __("Architecture: Tensilica Xtensa Architecture") }, +    { .fixed = EM_AARCH64,     .desc = __("Architecture: ARM AARCH64") }, +    { .fixed = EM_TILEPRO,     .desc = __("Architecture: Tilera TILEPro") }, +    { .fixed = EM_MICROBLAZE,  .desc = __("Architecture: Xilinx MicroBlaze") }, +    { .fixed = EM_TILEGX,      .desc = __("Architecture: Tilera TILE-Gx") } + +}; + +static fmt_field_def _elf_header_base[] = { +    { +        .name = "e_ident[EI_MAG]", +        .size = MDS_8_BITS, +        .repeat = 4, -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = description de l'exécutable à compléter.            * -*                                                                             * -*  Description : Charge tous les symboles de l'en-tête ELF.                   * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +        DISPLAY_RULES(IOD_HEX, IOD_CHAR, IOD_CHAR, IOD_CHAR), -bool annotate_elf_header(GElfFormat *format) -{ -    GBinContent *content;                   /* Contenu binaire à lire      */ -    const elf_header *header;               /* En-tête principale          */ -    SourceEndian endian;                    /* Boutisme utilisé            */ -    vmpa2t pos;                             /* Tête de lecture des symboles*/ -    GArchInstruction *instr;                /* Instruction décodée         */ -    GArchOperand *operand;                  /* Opérande à venir modifier   */ -    GDbComment *comment;                    /* Définition de commentaire   */ -    GBinSymbol *symbol;                     /* Symbole à intégrer          */ -    const char *text;                       /* Texte constant à insérer    */ +        PLAIN_COMMENT(__("ELF magic number")) -    content = g_binary_format_get_content(G_BIN_FORMAT(format)); +    }, -    header = g_elf_format_get_header(format); -    endian = g_binary_format_get_endianness(G_BIN_FORMAT(format)); +    { +        .name = "e_ident[EI_CLASS]", + +        .size = MDS_8_BITS, +        .repeat = 1, + +        DISPLAY_RULES(IOD_DEC), -    if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos)) -        return false; +        SWITCH_COMMENT(_elf_classes, __("File class: unknown")) -    /* ELFMAG (0) */ +    }, + +    { +        .name = "e_ident[EI_DATA]", -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 4, &pos, endian); +        .size = MDS_8_BITS, +        .repeat = 1, -    SET_IMM_DISPLAY(instr, operand, 1, IOD_CHAR); -    SET_IMM_DISPLAY(instr, operand, 2, IOD_CHAR); -    SET_IMM_DISPLAY(instr, operand, 3, IOD_CHAR); +        DISPLAY_RULES(IOD_DEC), -    ADD_RAW_AS_SYM_CST(format, symbol, instr, comment, _("ELF magic number")); +        SWITCH_COMMENT(_elf_data, __("Data encoding: unknown")) -    /* EI_CLASS (4) */ +    }, -    switch (header->hdr32.e_ident[EI_CLASS])      { -        case EV_NONE: -            text = _("File class: invalid"); -            break; -        case ELFCLASS32: -            text = _("File class: 32-bit objects"); -            break; -        case ELFCLASS64: -            text = _("File class: 64-bit objects"); -            break; -        default: -            text = _("File class: unknown"); -            break; -    } +        .name = "e_ident[EI_VERSION]", -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian); +        .size = MDS_8_BITS, +        .repeat = 1, -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        DISPLAY_RULES(IOD_DEC), -    ADD_RAW_AS_SYM(format, symbol, instr, comment, text); +        SWITCH_COMMENT(_elf_versions, __("File version: unknown")) -    /* EI_DATA (5) */ +    }, -    switch (header->hdr32.e_ident[EI_DATA])      { -        case ELFDATANONE: -            text = _("Data encoding: invalid"); -            break; -        case ELFDATA2LSB: -            text = _("Data encoding: 2's complement, little endian"); -            break; -        case ELFDATA2MSB: -            text = _("Data encoding: 2's complement, big endian"); -            break; -        default: -            text = _("Data encoding: unknown"); -            break; -    } +        .name = "e_ident[EI_OSABI]", -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian); +        .size = MDS_8_BITS, +        .repeat = 1, -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        DISPLAY_RULES(IOD_DEC), -    ADD_RAW_AS_SYM(format, symbol, instr, comment, text); +        SWITCH_COMMENT(_elf_os_abis, __("OS ABI: unknown")) -    /* EI_VERSION (6) */ +    }, -    switch (header->hdr32.e_ident[EI_VERSION])      { -        case EV_NONE: -            text = _("File version: invalid"); -            break; -        case EV_CURRENT: -            text = _("File version: current"); -            break; -        default: -            text = _("File version: unknown"); -            break; -    } +        .name = "e_ident[EI_ABIVERSION]", -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian); +        .size = MDS_8_BITS, +        .repeat = 1, -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        DISPLAY_RULES(IOD_DEC), -    ADD_RAW_AS_SYM(format, symbol, instr, comment, text); +        PLAIN_COMMENT(__("ABI version")) -    /* EI_OSABI (7) */ +    }, -    switch (header->hdr32.e_ident[EI_OSABI])      { -        case ELFOSABI_SYSV: -            text = _("OS ABI: UNIX System V"); -            break; -        case ELFOSABI_HPUX: -            text = _("OS ABI: HP-UX"); -            break; -        case ELFOSABI_NETBSD: -            text = _("OS ABI: NetBSD"); -            break; -        case ELFOSABI_GNU: -            text = _("OS ABI: object uses GNU ELF extensions"); -            break; -        case ELFOSABI_SOLARIS: -            text = _("OS ABI: Sun Solaris"); -            break; -        case ELFOSABI_AIX: -            text = _("OS ABI: IBM AIX"); -            break; -        case ELFOSABI_IRIX: -            text = _("OS ABI: SGI Irix"); -            break; -        case ELFOSABI_FREEBSD: -            text = _("OS ABI: FreeBSD"); -            break; -        case ELFOSABI_TRU64: -            text = _("OS ABI: Compaq TRU64 UNIX"); -            break; -        case ELFOSABI_MODESTO: -            text = _("OS ABI: Novell Modesto"); -            break; -        case ELFOSABI_OPENBSD: -            text = _("OS ABI: OpenBSD"); -            break; -        case ELFOSABI_ARM_AEABI: -            text = _("OS ABI: ARM EABI"); -            break; -        case ELFOSABI_ARM: -            text = _("OS ABI: ARM"); -            break; -        case ELFOSABI_STANDALONE: -            text = _("OS ABI: standalone (embedded) application"); -            break; -        default: -            text = _("OS ABI: unknown"); -            break; -    } +        .name = "...", + +        .size = MDS_8_BITS, +        .repeat = 7, -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian); +        .is_padding = true, -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        PLAIN_COMMENT(__("Padding")) -    ADD_RAW_AS_SYM(format, symbol, instr, comment, text); +    }, -    /* EI_ABIVERSION (8) */ +    { +        .name = "e_type", + +        .size = MDS_16_BITS, +        .repeat = 1, -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian); +        DISPLAY_RULES(IOD_DEC), -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        SWITCH_COMMENT(_elf_types, __("Object file type: unkown")) -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("ABI version")); +    }, -    /* Padding */ +    { +        .name = "e_machine", -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 7, &pos, endian); +        .size = MDS_16_BITS, +        .repeat = 1, -    g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true); +        DISPLAY_RULES(IOD_DEC), -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Padding")); +        SWITCH_COMMENT(_elf_machines, __("Architecture: unknown")) -    /* Champ "e_type" */ +    }, -    switch (header->hdr32.e_type)      { -        case ET_NONE: -            text = _("Object file type: no file type"); -            break; -        case ET_REL: -            text = _("Object file type: relocatable file"); -            break; -        case ET_EXEC: -            text = _("Object file type: executable file"); -            break; -        case ET_DYN: -            text = _("Object file type: shared object file"); -            break; -        case ET_CORE: -            text = _("Object file type: core file"); -            break; -        case ET_LOOS ... ET_HIOS: -            text = _("Object file type: OS-specific"); -            break; -        case ET_LOPROC ... ET_HIPROC: -            text = _("Object file type: processor-specific"); -            break; -        default: -            text = _("Object file type: unkown"); -            break; +        .name = "e_version", + +        .size = MDS_32_BITS, +        .repeat = 1, + +        DISPLAY_RULES(IOD_DEC), + +        PLAIN_COMMENT(__("Object file version")) +      } -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); +}; + +static fmt_field_def _elf_header_offset_32[] = { + +    { +        .name = "e_entry", -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        .size = MDS_32_BITS, +        .repeat = 1, -    ADD_RAW_AS_SYM(format, symbol, instr, comment, text); +        PLAIN_COMMENT(__("Entry point virtual address")) -    /* Champ "e_machine" */ +    }, -    switch (header->hdr32.e_machine)      { -        case EM_NONE:		text = _("Architecture: No machine"); break; -        case EM_M32:		text = _("Architecture: AT&T WE 32100"); break; -        case EM_SPARC:		text = _("Architecture: SUN SPARC"); break; -        case EM_386:		text = _("Architecture: Intel 80386"); break; -        case EM_68K:		text = _("Architecture: Motorola m68k family"); break; -        case EM_88K:		text = _("Architecture: Motorola m88k family"); break; -        case EM_860:		text = _("Architecture: Intel 80860"); break; -        case EM_MIPS:		text = _("Architecture: MIPS R3000 big-endian"); break; -        case EM_S370:	    text = _("Architecture: IBM System/370"); break; -        case EM_MIPS_RS3_LE:text = _("Architecture: MIPS R3000 little-endian"); break; -        case EM_PARISC:		text = _("Architecture: HPPA"); break; -        case EM_VPP500:		text = _("Architecture: Fujitsu VPP500"); break; -        case EM_SPARC32PLUS:text = _("Architecture: Sun's \"v8plus\""); break; -        case EM_960:		text = _("Architecture: Intel 80960"); break; -        case EM_PPC:		text = _("Architecture: PowerPC"); break; -        case EM_PPC64:		text = _("Architecture: PowerPC 64-bit"); break; -        case EM_S390:		text = _("Architecture: IBM S390"); break; -        case EM_V800:		text = _("Architecture: NEC V800 series"); break; -        case EM_FR20:		text = _("Architecture: Fujitsu FR20"); break; -        case EM_RH32:		text = _("Architecture: TRW RH-32"); break; -        case EM_RCE:		text = _("Architecture: Motorola RCE"); break; -        case EM_ARM:		text = _("Architecture: ARM"); break; -        case EM_FAKE_ALPHA: text = _("Architecture: Digital Alpha"); break; -        case EM_SH:		    text = _("Architecture: Hitachi SH"); break; -        case EM_SPARCV9:	text = _("Architecture: SPARC v9 64-bit"); break; -        case EM_TRICORE:	text = _("Architecture: Siemens Tricore"); break; -        case EM_ARC:		text = _("Architecture: Argonaut RISC Core"); break; -        case EM_H8_300:		text = _("Architecture: Hitachi H8/300"); break; -        case EM_H8_300H:	text = _("Architecture: Hitachi H8/300H"); break; -        case EM_H8S:		text = _("Architecture: Hitachi H8S"); break; -        case EM_H8_500:		text = _("Architecture: Hitachi H8/500"); break; -        case EM_IA_64:		text = _("Architecture: Intel Merced"); break; -        case EM_MIPS_X:		text = _("Architecture: Stanford MIPS-X"); break; -        case EM_COLDFIRE:	text = _("Architecture: Motorola Coldfire"); break; -        case EM_68HC12:		text = _("Architecture: Motorola M68HC12"); break; -        case EM_MMA:		text = _("Architecture: Fujitsu MMA Multimedia Accelerator"); break; -        case EM_PCP:		text = _("Architecture: Siemens PCP"); break; -        case EM_NCPU:		text = _("Architecture: Sony nCPU embeeded RISC"); break; -        case EM_NDR1:		text = _("Architecture: Denso NDR1 microprocessor"); break; -        case EM_STARCORE:	text = _("Architecture: Motorola Start*Core processor"); break; -        case EM_ME16:		text = _("Architecture: Toyota ME16 processor"); break; -        case EM_ST100:		text = _("Architecture: STMicroelectronic ST100 processor"); break; -        case EM_TINYJ:		text = _("Architecture: Advanced Logic Corp. Tinyj emb.fam"); break; -        case EM_X86_64:		text = _("Architecture: AMD x86-64 architecture"); break; -        case EM_PDSP:		text = _("Architecture: Sony DSP Processor"); break; -        case EM_FX66:		text = _("Architecture: Siemens FX66 microcontroller"); break; -        case EM_ST9PLUS:	text = _("Architecture: STMicroelectronics ST9+ 8/16 mc"); break; -        case EM_ST7:		text = _("Architecture: STmicroelectronics ST7 8 bit mc"); break; -        case EM_68HC16:		text = _("Architecture: Motorola MC68HC16 microcontroller"); break; -        case EM_68HC11:		text = _("Architecture: Motorola MC68HC11 microcontroller"); break; -        case EM_68HC08:		text = _("Architecture: Motorola MC68HC08 microcontroller"); break; -        case EM_68HC05:		text = _("Architecture: Motorola MC68HC05 microcontroller"); break; -        case EM_SVX:		text = _("Architecture: Silicon Graphics SVx"); break; -        case EM_ST19:		text = _("Architecture: STMicroelectronics ST19 8 bit mc"); break; -        case EM_VAX:		text = _("Architecture: Digital VAX"); break; -        case EM_CRIS:		text = _("Architecture: Axis Communications 32-bit embedded processor"); break; -        case EM_JAVELIN:	text = _("Architecture: Infineon Technologies 32-bit embedded processor"); break; -        case EM_FIREPATH:	text = _("Architecture: Element 14 64-bit DSP Processor"); break; -        case EM_ZSP:		text = _("Architecture: LSI Logic 16-bit DSP Processor"); break; -        case EM_MMIX:		text = _("Architecture: Donald Knuth's educational 64-bit processor"); break; -        case EM_HUANY:		text = _("Architecture: Harvard University machine-independent object files"); break; -        case EM_PRISM:		text = _("Architecture: SiTera Prism"); break; -        case EM_AVR:		text = _("Architecture: Atmel AVR 8-bit microcontroller"); break; -        case EM_FR30:		text = _("Architecture: Fujitsu FR30"); break; -        case EM_D10V:		text = _("Architecture: Mitsubishi D10V"); break; -        case EM_D30V:		text = _("Architecture: Mitsubishi D30V"); break; -        case EM_V850:		text = _("Architecture: NEC v850"); break; -        case EM_M32R:		text = _("Architecture: Mitsubishi M32R"); break; -        case EM_MN10300:	text = _("Architecture: Matsushita MN10300"); break; -        case EM_MN10200:	text = _("Architecture: Matsushita MN10200"); break; -        case EM_PJ:		    text = _("Architecture: picoJava"); break; -        case EM_OPENRISC:	text = _("Architecture: OpenRISC 32-bit embedded processor"); break; -        case EM_ARC_A5:		text = _("Architecture: ARC Cores Tangent-A5"); break; -        case EM_XTENSA:		text = _("Architecture: Tensilica Xtensa Architecture"); break; -        case EM_AARCH64:	text = _("Architecture: ARM AARCH64"); break; -        case EM_TILEPRO:	text = _("Architecture: Tilera TILEPro"); break; -        case EM_MICROBLAZE:	text = _("Architecture: Xilinx MicroBlaze"); break; -        case EM_TILEGX:		text = _("Architecture: Tilera TILE-Gx"); break; -        default:		    text = _("Architecture: unknown"); break; -    } +        .name = "e_phoff", + +        .size = MDS_32_BITS, +        .repeat = 1, -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); +        PLAIN_COMMENT(__("Program header table file offset")) -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +    }, -    ADD_RAW_AS_SYM(format, symbol, instr, comment, text); +    { +        .name = "e_shoff", -    /* Champ "e_version" */ +        .size = MDS_32_BITS, +        .repeat = 1, -    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); +        PLAIN_COMMENT(__("Section header table file offset")) -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +    } -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Object file version")); +}; + +static fmt_field_def _elf_header_offset_64[] = { -    if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS32)      { -        /* Champ "e_entry" */ +        .name = "e_entry", + +        .size = MDS_64_BITS, +        .repeat = 1, -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); +        PLAIN_COMMENT(__("Entry point virtual address")) -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Entry point virtual address")); +    }, -        /* Champ "e_phoff" */ +    { +        .name = "e_phoff", -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); +        .size = MDS_64_BITS, +        .repeat = 1, -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Program header table file offset")); +        PLAIN_COMMENT(__("Program header table file offset")) -        /* Champ "e_shoff" */ +    }, + +    { +        .name = "e_shoff", -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); +        .size = MDS_64_BITS, +        .repeat = 1, -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section header table file offset")); +        PLAIN_COMMENT(__("Section header table file offset"))      } -    else if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS64) +}; + +static fmt_field_def _elf_header_ending[] = { +      { -        /* Champ "e_entry" */ +        .name = "e_flags", -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, &pos, endian); +        .size = MDS_32_BITS, +        .repeat = 1, -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Entry point virtual address")); +        PLAIN_COMMENT(__("Processor-specific flags")) -        /* Champ "e_phoff" */ +    }, -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, &pos, endian); +    { +        .name = "e_ehsize", -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Program header table file offset")); +        .size = MDS_16_BITS, +        .repeat = 1, -        /* Champ "e_shoff" */ +        DISPLAY_RULES(IOD_DEC), -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, &pos, endian); +        PLAIN_COMMENT(__("ELF header size in bytes")) -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section header table file offset")); +    }, -    } +    { +        .name = "e_phentsize", -    else return false; +        .size = MDS_16_BITS, +        .repeat = 1, -    /* Champ "e_flags" */ +        DISPLAY_RULES(IOD_DEC), -    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); +        PLAIN_COMMENT(__("Program header table entry size")) + +    }, + +    { +        .name = "e_phnum", + +        .size = MDS_16_BITS, +        .repeat = 1, + +        DISPLAY_RULES(IOD_DEC), + +        PLAIN_COMMENT(__("Program header table entry count")) + +    }, + +    { +        .name = "e_shentsize", -    //SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        .size = MDS_16_BITS, +        .repeat = 1, -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Processor-specific flags")); +        DISPLAY_RULES(IOD_DEC), -    /* Champ "e_ehsize" */ +        PLAIN_COMMENT(__("Section header table entry size")) -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); +    }, -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +    { +        .name = "e_shnum", -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("ELF header size in bytes")); +        .size = MDS_16_BITS, +        .repeat = 1, -    /* Champ "e_phentsize" */ +        DISPLAY_RULES(IOD_DEC), -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); +        PLAIN_COMMENT(__("Section header table entry count")) -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +    }, -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Program header table entry size")); +    { +        .name = "e_shstrndx", -    /* Champ "e_phnum" */ +        .size = MDS_16_BITS, +        .repeat = 1, -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); +        DISPLAY_RULES(IOD_DEC), -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        PLAIN_COMMENT(__("Section header string table index")) -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Program header table entry count")); +    } -    /* Champ "e_shentsize" */ +}; -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section header table entry size")); +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                                                                             * +*  Description : Charge tous les symboles de l'en-tête ELF.                   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    /* Champ "e_shnum" */ +bool annotate_elf_header(GBinFormat *format) +{ +    bool result;                            /* Bilan à retourner           */ +    const elf_header *header;               /* En-tête principale          */ +    vmpa2t pos;                             /* Tête de lecture des symboles*/ -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); +    header = g_elf_format_get_header(G_ELF_FORMAT(format)); -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +    result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos); -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section header table entry count")); +    if (result) +        result = parse_field_definitions(_elf_header_base, ARRAY_SIZE(_elf_header_base), format, &pos); -    /* Champ "e_shstrndx" */ +    if (result) +    { +        if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS32) +            result = parse_field_definitions(_elf_header_offset_32, ARRAY_SIZE(_elf_header_offset_32), +                                             format, &pos); -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); +        else if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS64) +            result = parse_field_definitions(_elf_header_offset_64, ARRAY_SIZE(_elf_header_offset_64), +                                             format, &pos); -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        else +            result = false; -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section header string table index")); +    } -    g_object_unref(G_OBJECT(content)); +    if (result) +        result = parse_field_definitions(_elf_header_ending, ARRAY_SIZE(_elf_header_ending), format, &pos); -    return true; +    return result;  } diff --git a/plugins/readelf/header.h b/plugins/readelf/header.h index 87724e3..9d1744e 100644 --- a/plugins/readelf/header.h +++ b/plugins/readelf/header.h @@ -30,7 +30,7 @@  /* Charge tous les symboles de l'en-tête ELF. */ -bool annotate_elf_header(GElfFormat *); +bool annotate_elf_header(GBinFormat *); diff --git a/plugins/readelf/program.c b/plugins/readelf/program.c index 6bf117c..ba47639 100644 --- a/plugins/readelf/program.c +++ b/plugins/readelf/program.c @@ -24,284 +24,297 @@  #include "program.h" +#include <string.h> + +  #include <i18n.h> -#include <arch/raw.h> +#include <common/cpp.h>  #include <common/extstr.h> -#include <format/symbol.h>  #include <format/elf/elf-int.h> +#include <plugins/fmtp/parser.h> -/* Charge tous les symboles liés à un en-tête de programme ELF. */ -static bool annotate_elf_program_header(GElfFormat *, SourceEndian, vmpa2t *); +/* Définition des champs */ +static field_desc_switch _elf_prgm_types[] = { +    { .fixed = PT_NULL,         .desc = __("Segment type: unused") }, +    { .fixed = PT_LOAD,         .desc = __("Segment type: loadable program segment") }, +    { .fixed = PT_DYNAMIC,      .desc = __("Segment type: dynamic linking information") }, +    { .fixed = PT_INTERP,       .desc = __("Segment type: program interpreter") }, +    { .fixed = PT_NOTE,         .desc = __("Segment type: auxiliary information") }, +    { .fixed = PT_SHLIB,        .desc = __("Segment type: reserved") }, +    { .fixed = PT_PHDR,         .desc = __("Segment type: entry for header table itself") }, +    { .fixed = PT_TLS,          .desc = __("Segment type: thread-local storage segment") }, +    { .fixed = PT_GNU_EH_FRAME, .desc = __("Segment type: GCC .eh_frame_hdr segment") }, +    { .fixed = PT_GNU_STACK,    .desc = __("Segment type: indicates stack executability") }, +    { .fixed = PT_GNU_RELRO,    .desc = __("Segment type: read-only after relocation") }, +    { .fixed = PT_SUNWSTACK,    .desc = __("Segment type: Sun Stack segment") }, +    { .lower = PT_LOSUNW, .upper = PT_HISUNW, .desc = __("Segment type: Sun specific segment") }, +    { .lower = PT_LOOS,   .upper = PT_HIOS,   .desc = __("Segment type: OS-specific") }, +    { .lower = PT_LOPROC, .upper = PT_HIPROC, .desc = __("Segment type: processor-specific") } -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = description de l'exécutable à compléter.            * -*                endian = boutisme présentement utilisé.                      * -*                pos    = tête de lecture à déplacer. [OUT]                   * -*                                                                             * -*  Description : Charge tous les symboles liés à un en-tête de programme ELF. * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +}; -static bool annotate_elf_program_header(GElfFormat *format, SourceEndian endian, vmpa2t *pos) -{ -    elf_phdr phdr;                          /* En-tête de programme ELF    */ -    GBinContent *content;                   /* Contenu binaire à lire      */ -    ImmOperandDisplay disp;                 /* Afficahge de valeur         */ -    const char *text;                       /* Texte constant à insérer    */ -    GArchInstruction *instr;                /* Instruction décodée         */ -    GArchOperand *operand;                  /* Opérande à venir modifier   */ -    GDbComment *comment;                    /* Définition de commentaire   */ -    GBinSymbol *symbol;                     /* Symbole à intégrer          */ -    char *dtext;                            /* Texte dynamique à créer     */ -    bool filled;                            /* Suivi de mise en place      */ - -    if (!read_elf_program_header(format, get_phy_addr(pos), &phdr)) -        return false; +static fmt_field_def _elf_phdr_base[] = { -    content = g_binary_format_get_content(G_BIN_FORMAT(format)); +    { +        .name = "p_type", -    /* Champ "p_type" */ +        .size = MDS_32_BITS, +        .repeat = 1, -    disp = IOD_DEC; +        SWITCH_COMMENT(_elf_prgm_types, __("Segment type: unknown")) -    switch (ELF_PHDR(format, phdr, p_type)) -    { -        case PT_NULL: -            text = _("Segment type: unused"); -            break; -        case PT_LOAD: -            text = _("Segment type: loadable program segment"); -            break; -        case PT_DYNAMIC: -            text = _("Segment type: dynamic linking information"); -            break; -        case PT_INTERP: -            text = _("Segment type: program interpreter"); -            break; -        case PT_NOTE: -            text = _("Segment type: auxiliary information"); -            break; -        case PT_SHLIB: -            text = _("Segment type: reserved"); -            break; -        case PT_PHDR: -            text = _("Segment type: entry for header table itself"); -            break; -        case PT_TLS: -            text = _("Segment type: thread-local storage segment"); -            break; -        case PT_LOOS ... PT_HIOS: -            disp = IOD_HEX; -            switch (ELF_PHDR(format, phdr, p_type)) -            { -                case PT_GNU_EH_FRAME: -                    text = _("Segment type: GCC .eh_frame_hdr segment"); -                    break; -                case PT_GNU_STACK: -                    text = _("Segment type: indicates stack executability"); -                    break; -                case PT_GNU_RELRO: -                    text = _("Segment type: read-only after relocation"); -                    break; -                case PT_LOSUNW ... PT_HISUNW: -                    switch (ELF_PHDR(format, phdr, p_type)) -                    { -                        case PT_SUNWSTACK: -                            text = _("Segment type: Sun Stack segment"); -                            break; -                        default: -                            text = _("Segment type: Sun specific segment"); -                            break; -                    } -                    break; -                default: -                    text = _("Segment type: OS-specific"); -                    break; -            } -            break; -        case PT_LOPROC ... PT_HIPROC: -            disp = IOD_HEX; -            text = _("Segment type: processor-specific"); -            break; -        default: -            disp = IOD_HEX; -            text = _("Segment type: unknown"); -            break;      } -    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +}; + +static fmt_field_def _elf_phdr_32b_a[] = { -    SET_IMM_DISPLAY(instr, operand, 0, disp); +    { +        .name = "p_offset", -    ADD_RAW_AS_SYM(format, symbol, instr, comment, text); +        .size = MDS_32_BITS, +        .repeat = 1, + +        PLAIN_COMMENT(__("Segment file offset")) + +    }, -    if (format->is_32b)      { -        /* Champ "p_offset" */ +        .name = "p_vaddr", + +        .size = MDS_32_BITS, +        .repeat = 1, + +        PLAIN_COMMENT(__("Segment virtual address")) -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +    }, -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment file offset")); +    { +        .name = "p_paddr", + +        .size = MDS_32_BITS, +        .repeat = 1, -        /* Champ "p_vaddr" */ +        PLAIN_COMMENT(__("Segment physical address")) -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +    }, -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment virtual address")); +    { +        .name = "p_filesz", -        /* Champ "p_paddr" */ +        .size = MDS_32_BITS, +        .repeat = 1, -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +        PLAIN_COMMENT(__("Segment size in file")) -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment physical address")); +    }, -        /* Champ "p_filesz" */ +    { +        .name = "p_memsz", -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +        .size = MDS_32_BITS, +        .repeat = 1, -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment size in file")); +        PLAIN_COMMENT(__("Segment size in memory")) -        /* Champ "p_memsz" */ +    } -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +}; -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment size in memory")); +static fmt_field_def _elf_phdr_32b_b[] = { -        /* Champ "p_flags" */ +    { +        .name = "p_align", -        dtext = strdup(_("Segment flags: ")); -        filled = false; +        .size = MDS_32_BITS, +        .repeat = 1, -        if (ELF_PHDR(format, phdr, p_flags) & PF_R) -        { -            dtext = stradd(dtext, "R"); -            filled = true; -        } +        PLAIN_COMMENT(__("Segment alignment")) -        if (ELF_PHDR(format, phdr, p_flags) & PF_W) -        { -            dtext = stradd(dtext, "W"); -            filled = true; -        } +    } -        if (ELF_PHDR(format, phdr, p_flags) & PF_X) -        { -            dtext = stradd(dtext, "X"); -            filled = true; -        } +}; -        if (ELF_PHDR(format, phdr, p_flags) & PF_MASKOS) -            /* TODO */; +static fmt_field_def _elf_phdr_64b[] = { -        if (ELF_PHDR(format, phdr, p_flags) & PF_MASKPROC) -            /* TODO */; +    { +        .name = "p_offset", -        if (!filled) -            dtext = stradd(dtext, _("none")); +        .size = MDS_64_BITS, +        .repeat = 1, -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +        PLAIN_COMMENT(__("Segment file offset")) -        ADD_RAW_AS_SYM(format, symbol, instr, comment, dtext); +    }, -        free(dtext); +    { +        .name = "p_vaddr", -        /* Champ "p_align" */ +        .size = MDS_64_BITS, +        .repeat = 1, -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +        PLAIN_COMMENT(__("Segment virtual address")) -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment alignment")); +    }, -    } -    else      { -        /* Champ "p_flags" */ +        .name = "p_paddr", -        dtext = strdup(_("Segment flags: ")); -        filled = false; +        .size = MDS_64_BITS, +        .repeat = 1, -        if (ELF_PHDR(format, phdr, p_flags) & PF_R) -        { -            dtext = stradd(dtext, "R"); -            filled = true; -        } +        PLAIN_COMMENT(__("Segment physical address")) -        if (ELF_PHDR(format, phdr, p_flags) & PF_W) -        { -            dtext = stradd(dtext, "W"); -            filled = true; -        } +    }, -        if (ELF_PHDR(format, phdr, p_flags) & PF_X) -        { -            dtext = stradd(dtext, "X"); -            filled = true; -        } +    { +        .name = "p_filesz", -        if (ELF_PHDR(format, phdr, p_flags) & PF_MASKOS) -            /* TODO */; +        .size = MDS_64_BITS, +        .repeat = 1, -        if (ELF_PHDR(format, phdr, p_flags) & PF_MASKPROC) -            /* TODO */; +        PLAIN_COMMENT(__("Segment size in file")) -        if (!filled) -            dtext = stradd(dtext, _("none")); +    }, -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +    { +        .name = "p_memsz", -        ADD_RAW_AS_SYM(format, symbol, instr, comment, dtext); +        .size = MDS_64_BITS, +        .repeat = 1, -        free(dtext); +        PLAIN_COMMENT(__("Segment size in memory")) -        /* Champ "p_offset" */ +    }, -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +    { +        .name = "p_align", -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment file offset")); +        .size = MDS_64_BITS, +        .repeat = 1, -        /* Champ "p_vaddr" */ +        PLAIN_COMMENT(__("Segment alignment")) -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +    } -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment virtual address")); +}; -        /* Champ "p_paddr" */ -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment physical address")); +/* Charge tous les symboles liés à un en-tête de programme ELF. */ +static bool annotate_elf_program_header(GElfFormat *, SourceEndian, vmpa2t *); -        /* Champ "p_filesz" */ -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment size in file")); +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                endian = boutisme présentement utilisé.                      * +*                pos    = tête de lecture à déplacer. [OUT]                   * +*                                                                             * +*  Description : Charge tous les symboles liés à un en-tête de programme ELF. * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -        /* Champ "p_memsz" */ +static bool annotate_elf_program_header(GElfFormat *format, SourceEndian endian, vmpa2t *pos) +{ +    bool result;                            /* Bilan à retourner           */ +    elf_phdr phdr;                          /* En-tête de programme ELF    */ +    fmt_field_def flags_field;              /* Définition des drapeaux     */ +    char *rights;                           /* Reconstruction dynamique    */ +    comment_part parts[2];                  /* Mise en place des parties   */ +    GBinFormat *bformat;                    /* Autre version du format     */ + +    result = read_elf_program_header(format, get_phy_addr(pos), &phdr); + +    if (!result) +        goto aeph_exit; -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +    /* Préparation de la partie des drapeaux */ -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment size in memory")); +    memset(&flags_field, 0, sizeof(flags_field)); -        /* Champ "p_align" */ +    flags_field.name = "p_flags"; -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +    flags_field.size = MDS_32_BITS; +    flags_field.repeat = 1; -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment alignment")); +    rights = NULL; +    if (ELF_PHDR(format, phdr, p_flags) & PF_R) +        rights = stradd(rights, "R"); + +    if (ELF_PHDR(format, phdr, p_flags) & PF_W) +        rights = stradd(rights, "W"); + +    if (ELF_PHDR(format, phdr, p_flags) & PF_X) +        rights = stradd(rights, "X"); + +    if (ELF_PHDR(format, phdr, p_flags) & PF_MASKOS) +        /* TODO */; + +    if (ELF_PHDR(format, phdr, p_flags) & PF_MASKPROC) +        /* TODO */; + +    if (rights == NULL) +    { +        flags_field.ctype = FCT_PLAIN; +        flags_field.comment.plain = __("Segment flags: none");      } +    else +    { +        parts[0].is_static = true; +        parts[0].static_text = __("Segment flags: "); + +        parts[1].is_static = false; +        parts[1].dynamic_text = rights; + +        flags_field.ctype = FCT_MULTI; +        flags_field.comment.parts = parts; +        flags_field.comment.pcount = ARRAY_SIZE(parts); + +    } + +    /* Interprétation générale */ + +    bformat = G_BIN_FORMAT(format); + +    result = parse_field_definitions(_elf_phdr_base, ARRAY_SIZE(_elf_phdr_base), bformat, pos); + +    if (format->is_32b) +    { +        if (result) +            result = parse_field_definitions(_elf_phdr_32b_a, ARRAY_SIZE(_elf_phdr_32b_a), bformat, pos); -    g_object_unref(G_OBJECT(content)); +        if (result) +            result = parse_field_definitions(&flags_field, 1, bformat, pos); -    return true; +        if (result) +            result = parse_field_definitions(_elf_phdr_32b_b, ARRAY_SIZE(_elf_phdr_32b_b), bformat, pos); + +    } +    else +    { + +        if (result) +            result = parse_field_definitions(&flags_field, 1, bformat, pos); + +        if (result) +            result = parse_field_definitions(_elf_phdr_64b, ARRAY_SIZE(_elf_phdr_64b), bformat, pos); + +    } + + aeph_exit: + +    return result;  } diff --git a/plugins/readelf/reader.c b/plugins/readelf/reader.c index 01d5d90..62efdf4 100644 --- a/plugins/readelf/reader.c +++ b/plugins/readelf/reader.c @@ -66,7 +66,7 @@ G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *plugin, PluginAct      elf_fmt = G_ELF_FORMAT(format); -    result = annotate_elf_header(elf_fmt); +    result = annotate_elf_header(format);      result &= annotate_elf_program_header_table(elf_fmt, status); diff --git a/plugins/readelf/section.c b/plugins/readelf/section.c index f2cae76..e689aac 100644 --- a/plugins/readelf/section.c +++ b/plugins/readelf/section.c @@ -24,357 +24,385 @@  #include "section.h" +#include <string.h> + +  #include <i18n.h> -#include <arch/raw.h> +#include <common/cpp.h>  #include <common/extstr.h> -#include <format/symbol.h>  #include <format/elf/elf-int.h>  #include <format/elf/section.h> +#include <plugins/fmtp/parser.h> + + + +/* Définition des champs */ + +static field_desc_switch _elf_section_types[] = { + +    { .fixed = SHT_NULL,           .desc = __("Section type: unused") }, +    { .fixed = SHT_PROGBITS,       .desc = __("Section type: program data") }, +    { .fixed = SHT_SYMTAB,         .desc = __("Section type: symbol table") }, +    { .fixed = SHT_STRTAB,         .desc = __("Section type: string table") }, +    { .fixed = SHT_RELA,           .desc = __("Section type: relocation entries with addends") }, +    { .fixed = SHT_HASH,           .desc = __("Section type: symbol hash table") }, +    { .fixed = SHT_DYNAMIC,        .desc = __("Section type: dynamic linking information") }, +    { .fixed = SHT_NOTE,           .desc = __("Section type: notes") }, +    { .fixed = SHT_NOBITS,         .desc = __("Section type: program space with no data (bss)") }, +    { .fixed = SHT_REL,            .desc = __("Section type: relocation entries, no addends") }, +    { .fixed = SHT_SHLIB,          .desc = __("Section type: reserved") }, +    { .fixed = SHT_DYNSYM,         .desc = __("Section type: dynamic linker symbol table") }, +    { .fixed = SHT_INIT_ARRAY,     .desc = __("Section type: array of constructors") }, +    { .fixed = SHT_FINI_ARRAY,     .desc = __("Section type: array of destructors") }, +    { .fixed = SHT_PREINIT_ARRAY,  .desc = __("Section type: array of pre-constructors") }, +    { .fixed = SHT_GROUP,          .desc = __("Section type: section group") }, +    { .fixed = SHT_SYMTAB_SHNDX,   .desc = __("Section type: extended section indeces") }, +    { .fixed = SHT_GNU_ATTRIBUTES, .desc = __("Section type: object attributes") }, +    { .fixed = SHT_GNU_HASH,       .desc = __("Section type: GNU-style hash table") }, +    { .fixed = SHT_GNU_LIBLIST,    .desc = __("Section type: prelink library list") }, +    { .fixed = SHT_CHECKSUM,       .desc = __("Section type: checksum for DSO content") }, +    { .fixed = SHT_SUNW_move,      .desc = __("Section type: SHT_SUNW_move") }, +    { .fixed = SHT_SUNW_COMDAT,    .desc = __("Section type: SHT_SUNW_COMDAT") }, +    { .fixed = SHT_SUNW_syminfo,   .desc = __("Section type: SHT_SUNW_syminfo") }, +    { .fixed = SHT_GNU_verdef,     .desc = __("Section type: version definition section") }, +    { .fixed = SHT_GNU_verneed,    .desc = __("Section type: version needs section") }, +    { .fixed = SHT_GNU_versym,     .desc = __("Section type: version symbol table") }, +    { .lower = SHT_LOSUNW, .upper = SHT_HISUNW, .desc = __("Section type: Sun-specific") }, +    { .lower = SHT_LOOS,   .upper = SHT_HIOS,   .desc = __("Section type: OS-specific") }, +    { .lower = SHT_LOPROC, .upper = SHT_HIPROC, .desc = __("Section type: processor-specific") }, +    { .lower = SHT_LOUSER, .upper = SHT_HIUSER, .desc = __("Section type: application-specific") } + +}; + +static fmt_field_def _elf_sh_type[] = { +    { +        .name = "sh_type", +        .size = MDS_32_BITS, +        .repeat = 1, -/* Charge tous les symboles liés à un en-tête de section ELF. */ -static bool annotate_elf_section_header(GElfFormat *, SourceEndian, const elf_shdr *, vmpa2t *); +        SWITCH_COMMENT(_elf_section_types, __("Section type: unknown")) +    } +}; -/****************************************************************************** -*                                                                             * -*  Paramètres  : format  = description de l'exécutable à compléter.           * -*                endian  = boutisme présentement utilisé.                     * -*                strings = section renvoyant vers des chaînes de caractères.  * -*                pos     = tête de lecture à déplacer. [OUT]                  * -*                                                                             * -*  Description : Charge tous les symboles liés à un en-tête de section ELF.   * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +static fmt_field_def _elf_shdr_32b[] = { -static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian, const elf_shdr *strings, vmpa2t *pos) -{ -    elf_shdr shdr;                          /* En-tête de programme ELF    */ -    GBinContent *content;                   /* Contenu binaire à lire      */ -    const char *secname;                    /* Nom d'une section analysée  */ -    ImmOperandDisplay disp;                 /* Afficahge de valeur         */ -    const char *text;                       /* Texte constant à insérer    */ -    GArchInstruction *instr;                /* Instruction décodée         */ -    GArchOperand *operand;                  /* Opérande à venir modifier   */ -    GDbComment *comment;                    /* Définition de commentaire   */ -    GBinSymbol *symbol;                     /* Symbole à intégrer          */ -    char *dtext;                            /* Texte dynamique à créer     */ -    bool filled;                            /* Suivi de mise en place      */ - -    if (!read_elf_section_header(format, get_phy_addr(pos), &shdr)) -        return false; +    { +        .name = "sh_addr", -    content = g_binary_format_get_content(G_BIN_FORMAT(format)); +        .size = MDS_32_BITS, +        .repeat = 1, -    /* Champ "sh_name" */ +        PLAIN_COMMENT(__("Section virtual addr at execution")) -    secname = extract_name_from_elf_string_section(format, strings, -                                                   ELF_SHDR(format, shdr, sh_name)); +    }, -    if (secname == NULL) -        dtext = strdup(_("Section name: <invalid>")); -    else      { -        dtext = strdup(_("Section name: '")); -        dtext = stradd(dtext, secname); -        dtext = stradd(dtext, "'"); -    } +        .name = "sh_offset", -    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +        .size = MDS_32_BITS, +        .repeat = 1, -    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        PLAIN_COMMENT(__("Section file offset")) -    ADD_RAW_AS_SYM(format, symbol, instr, comment, dtext); +    }, -    free(dtext); +    { +        .name = "sh_size", -    /* Champ "sh_type" */ +        .size = MDS_32_BITS, +        .repeat = 1, -    disp = IOD_DEC; +        DISPLAY_RULES(IOD_DEC), -    switch (ELF_SHDR(format, shdr, sh_type)) -    { -        case SHT_NULL: -            text = _("Section type: unused"); -            break; -        case SHT_PROGBITS: -            text = _("Section type: program data"); -            break; -        case SHT_SYMTAB: -            text = _("Section type: symbol table"); -            break; -        case SHT_STRTAB: -            text = _("Section type: string table"); -            break; -        case SHT_RELA: -            text = _("Section type: relocation entries with addends"); -            break; -        case SHT_HASH: -            text = _("Section type: symbol hash table"); -            break; -        case SHT_DYNAMIC: -            text = _("Section type: dynamic linking information"); -            break; -        case SHT_NOTE: -            text = _("Section type: notes"); -            break; -        case SHT_NOBITS: -            text = _("Section type: program space with no data (bss)"); -            break; -        case SHT_REL: -            text = _("Section type: relocation entries, no addends"); -            break; -        case SHT_SHLIB: -            text = _("Section type: reserved"); -            break; -        case SHT_DYNSYM: -            text = _("Section type: dynamic linker symbol table"); -            break; -        case SHT_INIT_ARRAY: -            text = _("Section type: array of constructors"); -            break; -        case SHT_FINI_ARRAY: -            text = _("Section type: array of destructors"); -            break; -        case SHT_PREINIT_ARRAY: -            text = _("Section type: array of pre-constructors"); -            break; -        case SHT_GROUP: -            text = _("Section type: section group"); -            break; -        case SHT_SYMTAB_SHNDX: -            text = _("Section type: extended section indeces"); -            break; -        case SHT_LOOS ... SHT_HIOS: -            disp = IOD_HEX; -            switch (ELF_SHDR(format, shdr, sh_type)) -            { -                case SHT_GNU_ATTRIBUTES: -                    text = _("Section type: object attributes"); -                    break; -                case SHT_GNU_HASH: -                    text = _("Section type: GNU-style hash table"); -                    break; -                case SHT_GNU_LIBLIST: -                    text = _("Section type: prelink library list"); -                    break; -                case SHT_CHECKSUM: -                    text = _("Section type: checksum for DSO content"); -                    break; -                case SHT_LOSUNW ... SHT_HISUNW: -                    switch (ELF_SHDR(format, shdr, sh_type)) -                    { -                        case SHT_SUNW_move: -                            text = _("Section type: SHT_SUNW_move"); -                            break; -                        case SHT_SUNW_COMDAT: -                            text = _("Section type: SHT_SUNW_COMDAT"); -                            break; -                        case SHT_SUNW_syminfo: -                            text = _("Section type: SHT_SUNW_syminfo"); -                            break; -                        case SHT_GNU_verdef: -                            text = _("Section type: version definition section"); -                            break; -                        case SHT_GNU_verneed: -                            text = _("Section type: version needs section"); -                            break; -                        case SHT_GNU_versym: -                            text = _("Section type: version symbol table"); -                            break; -                        default: -                            text = _("Section type: Sun-specific"); -                            break; -                    } -                    break; -                default: -                    text = _("Section type: OS-specific"); -                    break; -            } -            break; -        case SHT_LOPROC ... SHT_HIPROC: -            disp = IOD_HEX; -            text = _("Section type: processor-specific"); -            break; -        case SHT_LOUSER ... SHT_HIUSER: -            disp = IOD_HEX; -            text = _("Section type: application-specific"); -            break; -        default: -            disp = IOD_HEX; -            text = _("Section type: unknown"); -            break; -    } +        PLAIN_COMMENT(__("Section size in bytes")) -    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +    }, -    SET_IMM_DISPLAY(instr, operand, 0, disp); +    { +        .name = "sh_link", -    ADD_RAW_AS_SYM(format, symbol, instr, comment, text); +        .size = MDS_32_BITS, +        .repeat = 1, -    /* Champ "sh_flags"... */ +        PLAIN_COMMENT(__("Link to another section")) -    dtext = strdup(_("Section flags: ")); -    filled = false; +    }, -    if (ELF_SHDR(format, shdr, sh_type) & SHF_WRITE)      { -        dtext = stradd(dtext, "W"); -        filled = true; -    } +        .name = "sh_info", + +        .size = MDS_32_BITS, +        .repeat = 1, + +        PLAIN_COMMENT(__("Additional section information")) + +    }, -    if (ELF_SHDR(format, shdr, sh_type) & SHF_ALLOC)      { -        dtext = stradd(dtext, "A"); -        filled = true; -    } +        .name = "sh_addralign", + +        .size = MDS_32_BITS, +        .repeat = 1, + +        PLAIN_COMMENT(__("Section alignment")) + +    }, -    if (ELF_SHDR(format, shdr, sh_type) & SHF_EXECINSTR)      { -        dtext = stradd(dtext, "X"); -        filled = true; +        .name = "sh_entsize", + +        .size = MDS_32_BITS, +        .repeat = 1, + +        DISPLAY_RULES(IOD_DEC), + +        PLAIN_COMMENT(__("Entry size if section holds table")) +      } -    if (ELF_SHDR(format, shdr, sh_type) & SHF_MERGE) +}; + +static fmt_field_def _elf_shdr_64b[] = { +      { -        dtext = stradd(dtext, "M"); -        filled = true; -    } +        .name = "sh_addr", + +        .size = MDS_64_BITS, +        .repeat = 1, + +        PLAIN_COMMENT(__("Section virtual addr at execution")) + +    }, -    if (ELF_SHDR(format, shdr, sh_type) & SHF_LINK_ORDER)      { -        dtext = stradd(dtext, "L"); -        filled = true; -    } +        .name = "sh_offset", + +        .size = MDS_64_BITS, +        .repeat = 1, + +        PLAIN_COMMENT(__("Section file offset")) + +    }, -    if (ELF_SHDR(format, shdr, sh_type) & SHF_TLS)      { -        dtext = stradd(dtext, "T"); -        filled = true; -    } +        .name = "sh_size", -    if (!filled) -        dtext = stradd(dtext, _("none")); +        .size = MDS_64_BITS, +        .repeat = 1, + +        DISPLAY_RULES(IOD_DEC), + +        PLAIN_COMMENT(__("Section size in bytes")) + +    }, -    if (format->is_32b)      { -        /* Champ "sh_flags" (suite) */ +        .name = "sh_link", + +        .size = MDS_32_BITS, +        .repeat = 1, -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +        PLAIN_COMMENT(__("Link to another section")) -        ADD_RAW_AS_SYM(format, symbol, instr, comment, dtext); +    }, -        free(dtext); +    { +        .name = "sh_info", + +        .size = MDS_32_BITS, +        .repeat = 1, -        /* Champ "sh_addr" */ +        PLAIN_COMMENT(__("Additional section information")) -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +    }, -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section virtual addr at execution")); +    { +        .name = "sh_addralign", -        /* Champ "sh_offset" */ +        .size = MDS_64_BITS, +        .repeat = 1, -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +        PLAIN_COMMENT(__("Section alignment")) -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section file offset")); +    }, -        /* Champ "sh_size" */ +    { +        .name = "sh_entsize", -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +        .size = MDS_64_BITS, +        .repeat = 1, -        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        DISPLAY_RULES(IOD_DEC), -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section size in bytes")); +        PLAIN_COMMENT(__("Entry size if section holds table"))      } -    else -    { -        /* Champ "sh_flags" (suite) */ -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +}; + + -        ADD_RAW_AS_SYM(format, symbol, instr, comment, dtext); +/* Charge tous les symboles liés à un en-tête de section ELF. */ +static bool annotate_elf_section_header(GElfFormat *, SourceEndian, const elf_shdr *, vmpa2t *); -        free(dtext); -        /* Champ "sh_addr" */ -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +/****************************************************************************** +*                                                                             * +*  Paramètres  : format  = description de l'exécutable à compléter.           * +*                endian  = boutisme présentement utilisé.                     * +*                strings = section renvoyant vers des chaînes de caractères.  * +*                pos     = tête de lecture à déplacer. [OUT]                  * +*                                                                             * +*  Description : Charge tous les symboles liés à un en-tête de section ELF.   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian, const elf_shdr *strings, vmpa2t *pos) +{ +    bool result;                            /* Bilan à retourner           */ +    elf_shdr shdr;                          /* En-tête de programme ELF    */ +    fmt_field_def name_field;               /* Définition du nom de section*/ +    const char *secname;                    /* Nom d'une section analysée  */ +    comment_part nparts[2];                 /* Mise en place des parties   */ +    fmt_field_def flags_field;              /* Définition des drapeaux     */ +    char *rights;                           /* Reconstruction dynamique    */ +    comment_part fparts[2];                 /* Mise en place des parties   */ +    GBinFormat *bformat;                    /* Autre version du format     */ -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section virtual addr at execution")); +    result = read_elf_section_header(format, get_phy_addr(pos), &shdr); -        /* Champ "sh_offset" */ +    if (!result) +        goto aesh_exit; -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +    /* Préparation de la partie nominative */ -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section file offset")); +    memset(&name_field, 0, sizeof(name_field)); -        /* Champ "sh_size" */ +    name_field.name = "sh_name"; -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +    name_field.size = MDS_32_BITS; +    name_field.repeat = 1; -        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +    name_field.has_display_rules = true; +    name_field.disp_rules = (ImmOperandDisplay []) { IOD_DEC }; +    name_field.disp_count = 1; -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section size in bytes")); +    secname = extract_name_from_elf_string_section(format, strings, +                                                   ELF_SHDR(format, shdr, sh_name)); +    if (secname == NULL) +    { +        name_field.ctype = FCT_PLAIN; +        name_field.comment.plain = __("Section name: <invalid>");      } +    else +    { +        nparts[0].is_static = true; +        nparts[0].static_text = __("Segment name: "); -    /* Champ "sh_link" */ +        nparts[1].is_static = true; +        nparts[1].avoid_i18n = true; +        nparts[1].static_text = secname; -    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +        name_field.ctype = FCT_MULTI; +        name_field.comment.parts = nparts; +        name_field.comment.pcount = ARRAY_SIZE(nparts); -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Link to another section")); +    } -    /* Champ "sh_info" */ +    /* Préparation de la partie des drapeaux */ -    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +    memset(&flags_field, 0, sizeof(flags_field)); -    ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Additional section information")); +    flags_field.name = "sh_flags"; -    if (format->is_32b) -    { -        /* Champ "sh_addralign" */ +    flags_field.repeat = 1; + +    rights = NULL; -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +    if (ELF_SHDR(format, shdr, sh_type) & SHF_WRITE) +        rights = stradd(rights, "W"); -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section alignment")); +    if (ELF_SHDR(format, shdr, sh_type) & SHF_ALLOC) +        rights = stradd(rights, "A"); -        /* Champ "sh_entsize" */ +    if (ELF_SHDR(format, shdr, sh_type) & SHF_EXECINSTR) +        rights = stradd(rights, "X"); -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +    if (ELF_SHDR(format, shdr, sh_type) & SHF_MERGE) +        rights = stradd(rights, "M"); -        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +    if (ELF_SHDR(format, shdr, sh_type) & SHF_LINK_ORDER) +        rights = stradd(rights, "L"); -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Entry size if section holds table")); +    if (ELF_SHDR(format, shdr, sh_type) & SHF_TLS) +        rights = stradd(rights, "T"); +    if (rights == NULL) +    { +        flags_field.ctype = FCT_PLAIN; +        flags_field.comment.plain = __("Section flags: none");      }      else      { -        /* Champ "sh_addralign" */ +        fparts[0].is_static = true; +        fparts[0].static_text = __("Section flags: "); + +        fparts[1].is_static = false; +        fparts[1].dynamic_text = rights; + +        flags_field.ctype = FCT_MULTI; +        flags_field.comment.parts = fparts; +        flags_field.comment.pcount = ARRAY_SIZE(fparts); + +    } + +    /* Interprétation générale */ -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +    bformat = G_BIN_FORMAT(format); -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section alignment")); +    result = parse_field_definitions(&name_field, 1, bformat, pos); -        /* Champ "sh_entsize" */ +    if (result) +        result = parse_field_definitions(_elf_sh_type, ARRAY_SIZE(_elf_sh_type), bformat, pos); -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +    if (format->is_32b) +    { +        if (result) +        { +            flags_field.size = MDS_32_BITS; +            result = parse_field_definitions(&flags_field, 1, bformat, pos); +        } -        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); +        if (result) +            result = parse_field_definitions(_elf_shdr_32b, ARRAY_SIZE(_elf_shdr_32b), bformat, pos); + +    } +    else +    { +        if (result) +        { +            flags_field.size = MDS_64_BITS; +            result = parse_field_definitions(&flags_field, 1, bformat, pos); +        } -        ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Entry size if section holds table")); +        if (result) +            result = parse_field_definitions(_elf_shdr_64b, ARRAY_SIZE(_elf_shdr_64b), bformat, pos);      } -    g_object_unref(G_OBJECT(content)); + aesh_exit: -    return true; +    return result;  } @@ -415,7 +443,7 @@ bool annotate_elf_section_header_table(GElfFormat *format, GtkStatusStack *statu      offset = ELF_HDR(format, *header, e_shoff);      if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos)) -        return false; +        init_vmpa(&pos, offset, VMPA_NO_VIRTUAL);      e_shnum = ELF_HDR(format, *header, e_shnum);  | 
