diff options
Diffstat (limited to 'plugins/readelf/section.c')
-rw-r--r-- | plugins/readelf/section.c | 530 |
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); |