summaryrefslogtreecommitdiff
path: root/plugins/readelf/section.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/readelf/section.c')
-rw-r--r--plugins/readelf/section.c530
1 files changed, 279 insertions, 251 deletions
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);