diff options
| -rw-r--r-- | ChangeLog | 38 | ||||
| -rw-r--r-- | src/analysis/binary.h | 2 | ||||
| -rw-r--r-- | src/analysis/disass/fetch.c | 6 | ||||
| -rw-r--r-- | src/analysis/disass/output.c | 78 | ||||
| -rw-r--r-- | src/arch/immediate.h | 2 | ||||
| -rw-r--r-- | src/arch/instruction-int.h | 2 | ||||
| -rw-r--r-- | src/arch/instruction.c | 26 | ||||
| -rw-r--r-- | src/arch/instruction.h | 2 | ||||
| -rw-r--r-- | src/arch/raw.c | 96 | ||||
| -rw-r--r-- | src/arch/raw.h | 6 | ||||
| -rw-r--r-- | src/arch/vmpa.c | 2 | ||||
| -rw-r--r-- | src/format/elf/elf-int.c | 46 | ||||
| -rw-r--r-- | src/format/elf/elf_def.h | 156 | ||||
| -rw-r--r-- | src/format/elf/symbols.c | 932 | ||||
| -rw-r--r-- | src/format/format.c | 3 | ||||
| -rw-r--r-- | src/format/symbol.c | 54 | ||||
| -rw-r--r-- | src/format/symbol.h | 31 | 
17 files changed, 1399 insertions, 83 deletions
@@ -1,3 +1,41 @@ +14-08-25  Cyrille Bagard <nocbos@gmail.com> + +	* src/analysis/binary.h: +	Typo. + +	* src/analysis/disass/fetch.c: +	Update code. + +	* src/analysis/disass/output.c: +	Add comments from some kinds of loaded symbols. + +	* src/arch/immediate.h: +	Fix a typo bug. + +	* src/arch/instruction.c: +	* src/arch/instruction.h: +	* src/arch/instruction-int.h: +	Return a buffer line when printing one instruction. + +	* src/arch/raw.c: +	* src/arch/raw.h: +	Show data as padding when required. + +	* src/arch/vmpa.c: +	Fix a typo bug. + +	* src/format/elf/elf_def.h: +	* src/format/elf/elf-int.c: +	* src/format/elf/symbols.c: +	Load lots of ELF header information as symbols. + +	* src/format/format.c: +	Remove debug code. + +	* src/format/symbol.c: +	* src/format/symbol.h: +	Attach comments to symbols. +  14-08-20  Cyrille Bagard <nocbos@gmail.com>  	* src/glibext/gbuffersegment.c: diff --git a/src/analysis/binary.h b/src/analysis/binary.h index 2a7e7d9..17da200 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -116,7 +116,7 @@ void g_loaded_binary_set_storage(GLoadedBinary *, DBFeatures, DBStorage);  /* Trouve une collection assurant une fonctionnalité donnée. */ -GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *, DBFeatures ); +GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *, DBFeatures);  /* Demande l'intégration d'une modification dans une collection. */  bool g_loaded_binary_add_to_collection(GLoadedBinary *, DBFeatures, GDbItem *); diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 9ef6f29..73474b3 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -189,8 +189,8 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt                  g_object_ref(G_OBJECT(instr));                  border = g_arch_instruction_get_location2(instr, &length); -                length = 4; - +                // Utiliser : ??? +                // const vmpa2t *g_binary_symbol_get_address2(const GBinSymbol *symbol)                  break; @@ -218,8 +218,6 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt          advance_vmpa(last, length); -        printf("length :: %d\n", length); -      }      /* Raccord final ? */ diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index 97f9989..927088f 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -25,6 +25,7 @@  #include "../../arch/processor.h" +#include "../../common/extstr.h"  #include "../../decomp/lang/asm.h"  #include "../../format/format.h" @@ -58,11 +59,42 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form      vmpa_t end;                             /* Adresse de fin              */      const GArchInstruction *iter;           /* Boucle de parcours #1       */      size_t i;                               /* Boucle de parcours #2       */ -    vmpa_t iaddr;                           /* Adresse d'instruction       */ -    vmpa_t raddr;                           /* Adresse de routine          */ +    const vmpa2t *iaddr;                    /* Adresse d'instruction       */ +    const vmpa2t *saddr;                    /* Adresse de symbole          */ + +    GBufferLine *line; + + +    GBinSymbol **symbols;                   /* Symboles à représenter      */ +    size_t sym_count;                       /* Qté de symboles présents    */ + + +    size_t sym_index;                       /* Prochain symbole non traité */ + + +    GDbComment *comment;                    /* Commentaire à ajouter       */ + + + +    const char *text; + +    char *prefixed; + +      output = g_asm_output_new(); + +    symbols = g_binary_format_get_symbols(format, &sym_count); + +    sym_index = 0; + + +    //GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *, DBFeatures); + + + +      proc = get_arch_processor_from_format(format);      msize = g_arch_processor_get_memory_size(proc); @@ -90,7 +122,47 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form          }  #endif -        g_arch_instruction_print(iter, buffer, msize, content, ASX_INTEL); + + + +        line = g_arch_instruction_print(iter, buffer, msize, content, ASX_INTEL); + +        if (sym_index < sym_count) +        { +            iaddr = g_arch_instruction_get_location2(iter, NULL); +            saddr = g_binary_symbol_get_address2(symbols[sym_index]); + +            if (cmp_vmpa_by_phy(iaddr, saddr) == 0) +            { + + +                comment = g_binary_symbol_get_comment(symbols[sym_index]); + +                if (comment != NULL) +                { + +                    text = g_db_comment_get_text(comment); + + +                    prefixed = strdup("; "); +                    prefixed = stradd(prefixed, text); + + + +                    g_buffer_line_insert_text(line, BLC_COMMENTS, prefixed, strlen(prefixed), RTT_COMMENT); + + +                    free(prefixed); + +                } + +                sym_index++; + + +            } + +        } +          //gtk_extended_status_bar_update_activity(statusbar, id, (iaddr - start) * 1.0 / (end - start)); diff --git a/src/arch/immediate.h b/src/arch/immediate.h index 71d482a..99d1b7f 100644 --- a/src/arch/immediate.h +++ b/src/arch/immediate.h @@ -70,7 +70,7 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const bin_t *, off_t  /* Crée un opérande réprésentant une valeur numérique. */  GArchOperand *_g_imm_operand_new_from_data2(MemoryDataSize, const bin_t *, vmpa2t *, off_t, bool *, SourceEndian); -#define g_imm_operand_new_from_data2(size, data, pos, len, endian) _g_imm_operand_new_from_data(size, data, pos, len, NULL, endian) +#define g_imm_operand_new_from_data2(size, data, pos, len, endian) _g_imm_operand_new_from_data2(size, data, pos, len, NULL, endian)  /* Crée un opérande réprésentant une valeur numérique. */  GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, ...); diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 8730792..28caf78 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -36,7 +36,7 @@  typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *);  /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -typedef void (* print_instruction_fc) (const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); +typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax);  /* Traduit une instruction en version humainement lisible. */  typedef const char * (* get_instruction_keyword_fc) (const GArchInstruction *, AsmSyntax); diff --git a/src/arch/instruction.c b/src/arch/instruction.c index e1ee023..ea713cd 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -51,7 +51,7 @@ static void g_arch_instruction_finalize(GArchInstruction *);  /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -static void _g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); +static GBufferLine *_g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); @@ -692,39 +692,41 @@ const char *g_arch_instruction_get_keyword(const GArchInstruction *instr, AsmSyn  *                                                                             *  ******************************************************************************/ -static void _g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) +static GBufferLine *_g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax)  { -    GBufferLine *line;                      /* Ligne de destination        */ +    GBufferLine *result;                    /* Ligne de destination        */      const char *key;                        /* Mot clef principal          */      size_t klen;                            /* Taille de ce mot clef       */      size_t i;                               /* Boucle de parcours          */ -    line = g_code_buffer_append_new_line(buffer, &instr->address2); +    result = g_code_buffer_append_new_line(buffer, &instr->address2); -    g_buffer_line_fill_for_instr(line, msize/* TODO ! */, msize, content, instr->length, true); +    g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, instr->length, true);      /* Instruction proprement dite */      key = g_arch_instruction_get_keyword(instr, syntax);      klen = strlen(key); -    g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION); +    g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION);      if (instr->operands_count > 0)      { -        g_arch_operand_print(instr->operands[0], line, syntax); +        g_arch_operand_print(instr->operands[0], result, syntax);          for (i = 1; i < instr->operands_count; i++)          { -            g_buffer_line_insert_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); -            g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW); +            g_buffer_line_insert_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); +            g_buffer_line_insert_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW); -            g_arch_operand_print(instr->operands[i], line, syntax); +            g_arch_operand_print(instr->operands[i], result, syntax);          }      } +    return result; +  } @@ -742,9 +744,9 @@ static void _g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer  *                                                                             *  ******************************************************************************/ -void g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) +GBufferLine *g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax)  { -    G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, buffer, msize, content, syntax); +    return G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, buffer, msize, content, syntax);  } diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 08135a9..f04a458 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -152,7 +152,7 @@ size_t g_arch_instruction_compute_group_index(GArchInstruction **, GArchInstruct  const char *g_arch_instruction_get_keyword(const GArchInstruction *, AsmSyntax);  /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -void g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); +GBufferLine *g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax);  /* Décompile une instruction de façon générique. */  GDecInstruction *g_arch_instruction_decompile(const GArchInstruction *, GDecContext *); diff --git a/src/arch/raw.c b/src/arch/raw.c index 0d6ae4a..842c2b4 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -37,6 +37,8 @@ struct _GRawInstruction  {      GArchInstruction parent;                /* A laisser en premier        */ +    bool is_padding;                        /* Bourrage à représenter ?    */ +  };  /* Définition générique d'une instruction d'architecture inconnue (classe) */ @@ -59,6 +61,9 @@ static void g_raw_instruction_dispose(GRawInstruction *);  /* Procède à la libération totale de la mémoire. */  static void g_raw_instruction_finalize(GRawInstruction *); +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static GBufferLine *g_raw_instruction_print(const GRawInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); +  /* Fournit le nom humain de l'instruction manipulée. */  static const char *g_raw_instruction_get_keyword(const GRawInstruction *, AsmSyntax); @@ -97,6 +102,7 @@ static void g_raw_instruction_class_init(GRawInstructionClass *klass)      instr = G_ARCH_INSTRUCTION_CLASS(klass); +    instr->print = (print_instruction_fc)g_raw_instruction_print;      instr->get_key = (get_instruction_keyword_fc)g_raw_instruction_get_keyword;  } @@ -219,6 +225,54 @@ GArchInstruction *g_raw_instruction_new_array(const bin_t *data, MemoryDataSize  /******************************************************************************  *                                                                             * +*  Paramètres  : instr  = instruction d'assemblage à représenter.             * +*                buffer = espace où placer ledit contenu.                     * +*                syntax = type de représentation demandée.                    * +*                                                                             * +*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBufferLine *g_raw_instruction_print(const GRawInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) +{ +    GBufferLine *result;                    /* Ligne de destination        */ +    GArchInstruction *base;                 /* Autre version de l'instance */ +    const char *key;                        /* Mot clef principal          */ +    size_t klen;                            /* Taille de ce mot clef       */ + +    base = G_ARCH_INSTRUCTION(instr); + +    if (!instr->is_padding) +        result = G_ARCH_INSTRUCTION_CLASS(g_raw_instruction_parent_class)->print(base, buffer, msize, content, syntax); + +    else +    { +        result = g_code_buffer_append_new_line(buffer, &base->address2); + +        g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, base->length, true); + +        /* Instruction proprement dite */ + +        key = g_arch_instruction_get_keyword(base, syntax); +        klen = strlen(key); + +        g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION); + +        g_buffer_line_insert_text(result, BLC_ASSEMBLY, "...", 3, RTT_RAW); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : instr  = instruction à traiter.                              *  *                format = format du binaire manipulé.                         *  *                syntax = type de représentation demandée.                    * @@ -238,9 +292,49 @@ static const char *g_raw_instruction_get_keyword(const GRawInstruction *instr, A      static char *defines[] = { "dn", "db", "dw", "dd", "dq" }; -    operand = g_arch_instruction_get_operand(instr, 0); +    operand = g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 0);      size = g_imm_operand_get_size(G_IMM_OPERAND(operand));      return defines[MDS_RANGE(size)];  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr      = instruction à traiter.                          * +*                is_padding = nouveau statut à associer au contenu.           * +*                                                                             * +*  Description : Marque l'instruction comme ne contenant que du bourrage.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_raw_instruction_mark_as_padding(GRawInstruction *instr, bool is_padding) +{ +    instr->is_padding = is_padding; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr      = instruction à traiter.                          * +*                is_padding = nouveau statut à associer au contenu.           * +*                                                                             * +*  Description : Indique si le contenu de l'instruction est du bourrage.      * +*                                                                             * +*  Retour      : Statut du contenu de l'instruction.                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_raw_instruction_is_padding(const GRawInstruction *instr) +{ +    return instr->is_padding; + +} diff --git a/src/arch/raw.h b/src/arch/raw.h index 08dc620..ce324f5 100644 --- a/src/arch/raw.h +++ b/src/arch/raw.h @@ -55,6 +55,12 @@ GType g_raw_instruction_get_type(void);  /* Crée une instruction de type 'db/dw/etc' étendue. */  GArchInstruction *g_raw_instruction_new_array(const bin_t *, MemoryDataSize, size_t, vmpa2t *, off_t, SourceEndian); +/* Marque l'instruction comme ne contenant que du bourrage. */ +void g_raw_instruction_mark_as_padding(GRawInstruction *, bool); + +/* Indique si le contenu de l'instruction est du bourrage. */ +bool g_raw_instruction_is_padding(const GRawInstruction *); +  #endif  /* _ARCH_RAW_H */ diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index 93bbfc8..edff789 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -191,7 +191,7 @@ void advance_vmpa(vmpa2t *addr, off_t qty)          addr->physical += qty;      if (addr->virtual != VMPA_NO_VIRTUAL) -        addr->virtual =+ qty; +        addr->virtual += qty;  } diff --git a/src/format/elf/elf-int.c b/src/format/elf/elf-int.c index 17aeaf2..677a9ef 100644 --- a/src/format/elf/elf-int.c +++ b/src/format/elf/elf-int.c @@ -27,9 +27,6 @@  #include <string.h> -#include "../../arch/raw.h" - -  /******************************************************************************  *                                                                             * @@ -52,18 +49,6 @@ bool read_elf_header(GElfFormat *format, elf_header *header, bool *is_32b, Sourc      const bin_t *content;                   /* Contenu binaire à lire      */      off_t length;                           /* Taille totale du contenu    */      off_t pos;                              /* Position de lecture         */ -    GArchInstruction *instr;                /* Instruction décodée         */ - - -    vmpa2t *pos2; - - -    GBinSymbol *symbol; - -    size_t i;                               /* Boucle de parcours          */ -    GArchOperand *operand;                  /* Opérande à venir modifier   */ - -      content = G_BIN_FORMAT(format)->content;      length = G_BIN_FORMAT(format)->length; @@ -108,37 +93,6 @@ bool read_elf_header(GElfFormat *format, elf_header *header, bool *is_32b, Sourc                  break;          } - -    pos2 = make_vmpa(0, 0x123); - - - -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 4, pos2, 4, *endian); - - -    for (i = 1; i < 4; i++) -    { -        operand = g_arch_instruction_get_operand(instr, i); -        g_imm_operand_set_display(G_IMM_OPERAND(operand), IOD_CHAR); -    } - - - - -    symbol = g_binary_symbol_new(STP_OBJECT, "toto", 0); - -    printf("TOTO\n"); - -    g_binary_symbol_attach_instruction(symbol, instr); -    g_binary_format_add_symbol(format, symbol); - - - - - - - -      if (*is_32b)      {          result &= read_u16(&header->hdr32.e_type, content, &pos, length, *endian); diff --git a/src/format/elf/elf_def.h b/src/format/elf/elf_def.h index 9d872f4..91e1c18 100644 --- a/src/format/elf/elf_def.h +++ b/src/format/elf/elf_def.h @@ -103,6 +103,8 @@ typedef union _elf_header  #define EI_CLASS        4                   /* Indice de classe du fichier */  #define EI_DATA         5                   /* Indice de l'encodage        */ +#define EI_VERSION      6                   /* Version de fichier ELF      */ +#define EI_OSABI        7                   /* Identification de l'ABI OS  */  /* ... EI_CLASS */ @@ -117,20 +119,122 @@ typedef union _elf_header  #define ELFDATA2LSB     1                   /* Complément à 2, petit bout. */  #define ELFDATA2MSB     2                   /* Complément à 2, grand bout. */ +/* ... EI_VERSION */ + +#define EV_NONE         0                   /* Version ELF invalide        */ +#define EV_CURRENT      1                   /* Version d'ELF courante      */ + +/* ... EI_OSABI */ + +#define ELFOSABI_NONE           0           /* UNIX System V ABI */ +#define ELFOSABI_SYSV           0           /* Alias.  */ +#define ELFOSABI_HPUX           1           /* HP-UX */ +#define ELFOSABI_NETBSD         2           /* NetBSD.  */ +#define ELFOSABI_GNU            3           /* Object uses GNU ELF extensions.  */ +#define ELFOSABI_LINUX          ELFOSABI_GNU /* Compatibility alias.  */ +#define ELFOSABI_SOLARIS        6           /* Sun Solaris.  */ +#define ELFOSABI_AIX            7           /* IBM AIX.  */ +#define ELFOSABI_IRIX           8           /* SGI Irix.  */ +#define ELFOSABI_FREEBSD        9           /* FreeBSD.  */ +#define ELFOSABI_TRU64          10          /* Compaq TRU64 UNIX.  */ +#define ELFOSABI_MODESTO        11          /* Novell Modesto.  */ +#define ELFOSABI_OPENBSD        12          /* OpenBSD.  */ +#define ELFOSABI_ARM_AEABI      64          /* ARM EABI */ +#define ELFOSABI_ARM            97          /* ARM */ +#define ELFOSABI_STANDALONE     255         /* Standalone (embedded) application */  /* Valeurs possibles pour e_type */  #define ET_NONE         0                   /* Aucun type défini           */ +#define ET_REL          1                   /* Fichier relogeable          */  #define ET_EXEC         2                   /* Fichier exécutable          */  #define ET_DYN          3                   /* Bibliothèque dynamique      */ +#define ET_CORE         4                   /* Fichier Core                */ +#define ET_LOOS         0xfe00              /* Spécifique OS : début       */ +#define ET_HIOS         0xfeff              /* Spécifique OS : fin         */ +#define ET_LOPROC       0xff00              /* Spécifique processeur : deb.*/ +#define ET_HIPROC       0xffff              /* Spécifique processeur : fin */  /* Valeurs possibles pour e_machine */ -#define EM_NONE         0                   /* Aucune machine              */ -#define EM_386          3                   /* Intel 80386                 */ -#define EM_MIPS         8                   /* MIPS R3000 big-endian       */ -#define EM_MIPS_RS3_LE  10                  /* MIPS R3000 little-endian    */ -#define EM_ARM          40                  /* ARM                         */ +#define EM_NONE          0                  /* No machine */ +#define EM_M32           1                  /* AT&T WE 32100 */ +#define EM_SPARC         2                  /* SUN SPARC */ +#define EM_386           3                  /* Intel 80386 */ +#define EM_68K           4                  /* Motorola m68k family */ +#define EM_88K           5                  /* Motorola m88k family */ +#define EM_860           7                  /* Intel 80860 */ +#define EM_MIPS          8                  /* MIPS R3000 big-endian */ +#define EM_S370          9                  /* IBM System/370 */ +#define EM_MIPS_RS3_LE  10                  /* MIPS R3000 little-endian */ +#define EM_PARISC       15                  /* HPPA */ +#define EM_VPP500       17                  /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS  18                  /* Sun's "v8plus" */ +#define EM_960          19                  /* Intel 80960 */ +#define EM_PPC          20                  /* PowerPC */ +#define EM_PPC64        21                  /* PowerPC 64-bit */ +#define EM_S390         22                  /* IBM S390 */ +#define EM_V800         36                  /* NEC V800 series */ +#define EM_FR20         37                  /* Fujitsu FR20 */ +#define EM_RH32         38                  /* TRW RH-32 */ +#define EM_RCE          39                  /* Motorola RCE */ +#define EM_ARM          40                  /* ARM */ +#define EM_FAKE_ALPHA   41                  /* Digital Alpha */ +#define EM_SH           42                  /* Hitachi SH */ +#define EM_SPARCV9      43                  /* SPARC v9 64-bit */ +#define EM_TRICORE      44                  /* Siemens Tricore */ +#define EM_ARC          45                  /* Argonaut RISC Core */ +#define EM_H8_300       46                  /* Hitachi H8/300 */ +#define EM_H8_300H      47                  /* Hitachi H8/300H */ +#define EM_H8S          48                  /* Hitachi H8S */ +#define EM_H8_500       49                  /* Hitachi H8/500 */ +#define EM_IA_64        50                  /* Intel Merced */ +#define EM_MIPS_X       51                  /* Stanford MIPS-X */ +#define EM_COLDFIRE     52                  /* Motorola Coldfire */ +#define EM_68HC12       53                  /* Motorola M68HC12 */ +#define EM_MMA          54                  /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP          55                  /* Siemens PCP */ +#define EM_NCPU         56                  /* Sony nCPU embeeded RISC */ +#define EM_NDR1         57                  /* Denso NDR1 microprocessor */ +#define EM_STARCORE     58                  /* Motorola Start*Core processor */ +#define EM_ME16         59                  /* Toyota ME16 processor */ +#define EM_ST100        60                  /* STMicroelectronic ST100 processor */ +#define EM_TINYJ        61                  /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64       62                  /* AMD x86-64 architecture */ +#define EM_PDSP         63                  /* Sony DSP Processor */ +#define EM_FX66         66                  /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS      67                  /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7          68                  /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16       69                  /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11       70                  /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08       71                  /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05       72                  /* Motorola MC68HC05 microcontroller */ +#define EM_SVX          73                  /* Silicon Graphics SVx */ +#define EM_ST19         74                  /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX          75                  /* Digital VAX */ +#define EM_CRIS         76                  /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN      77                  /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH     78                  /* Element 14 64-bit DSP Processor */ +#define EM_ZSP          79                  /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX         80                  /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY        81                  /* Harvard University machine-independent object files */ +#define EM_PRISM        82                  /* SiTera Prism */ +#define EM_AVR          83                  /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30         84                  /* Fujitsu FR30 */ +#define EM_D10V         85                  /* Mitsubishi D10V */ +#define EM_D30V         86                  /* Mitsubishi D30V */ +#define EM_V850         87                  /* NEC v850 */ +#define EM_M32R         88                  /* Mitsubishi M32R */ +#define EM_MN10300      89                  /* Matsushita MN10300 */ +#define EM_MN10200      90                  /* Matsushita MN10200 */ +#define EM_PJ           91                  /* picoJava */ +#define EM_OPENRISC     92                  /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5       93                  /* ARC Cores Tangent-A5 */ +#define EM_XTENSA       94                  /* Tensilica Xtensa Architecture */ +#define EM_AARCH64      183                 /* ARM AARCH64 */ +#define EM_TILEPRO      188                 /* Tilera TILEPro */ +#define EM_MICROBLAZE   189                 /* Xilinx MicroBlaze */ +#define EM_TILEGX       191                 /* Tilera TILE-Gx */ @@ -203,9 +307,11 @@ typedef union _elf_phdr  /* Valeurs possibles pour p_flags */ -#define PF_X    (1 << 0)                    /* Le segment est exécutable   */ -#define PF_W    (1 << 1)                    /* Le segment est écrasable    */ -#define PF_R    (1 << 2)                    /* Le segment est lisible      */ +#define PF_X        (1 << 0)                /* Le segment est exécutable   */ +#define PF_W        (1 << 1)                /* Le segment est écrasable    */ +#define PF_R        (1 << 2)                /* Le segment est lisible      */ +#define PF_MASKOS   0x0ff00000              /* Spécifique à l'OS           */ +#define PF_MASKPROC 0xf0000000              /* Spécifique au processeur    */ @@ -263,8 +369,42 @@ typedef union _elf_shdr  #define SHT_PROGBITS    1                   /* Données de programme        */  #define SHT_SYMTAB      2                   /* Table des symboles          */  #define SHT_STRTAB      3                   /* Table de chaînes de carac.  */ + +#define SHT_RELA          4             /* Relocation entries with addends */ +#define SHT_HASH          5             /* Symbol hash table */ +  #define SHT_DYNAMIC     6                   /* Info. de liaison dynamique  */ +#define SHT_NOTE          7             /* Notes */ +#define SHT_NOBITS        8             /* Program space with no data (bss) */ +#define SHT_REL           9             /* Relocation entries, no addends */ +#define SHT_SHLIB         10            /* Reserved */ +#define SHT_DYNSYM        11            /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY    14            /* Array of constructors */ +#define SHT_FINI_ARRAY    15            /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16            /* Array of pre-constructors */ +#define SHT_GROUP         17            /* Section group */ +#define SHT_SYMTAB_SHNDX  18            /* Extended section indeces */ +#define SHT_NUM           19            /* Number of defined types.  */ +#define SHT_LOOS          0x60000000    /* Start OS-specific.  */ +#define SHT_GNU_ATTRIBUTES 0x6ffffff5   /* Object attributes.  */ +#define SHT_GNU_HASH      0x6ffffff6    /* GNU-style hash table.  */ +#define SHT_GNU_LIBLIST   0x6ffffff7    /* Prelink library list */ +#define SHT_CHECKSUM      0x6ffffff8    /* Checksum for DSO content.  */ +#define SHT_LOSUNW        0x6ffffffa    /* Sun-specific low bound.  */ +#define SHT_SUNW_move     0x6ffffffa +#define SHT_SUNW_COMDAT   0x6ffffffb +#define SHT_SUNW_syminfo  0x6ffffffc +#define SHT_GNU_verdef    0x6ffffffd    /* Version definition section.  */ +#define SHT_GNU_verneed   0x6ffffffe    /* Version needs section.  */ +#define SHT_GNU_versym    0x6fffffff    /* Version symbol table.  */ +#define SHT_HISUNW        0x6fffffff    /* Sun-specific high bound.  */ +#define SHT_HIOS          0x6fffffff    /* End OS-specific type */ +#define SHT_LOPROC        0x70000000    /* Start of processor-specific */ +#define SHT_HIPROC        0x7fffffff    /* End of processor-specific */ +#define SHT_LOUSER        0x80000000    /* Start of application-specific */ +#define SHT_HIUSER        0x8fffffff    /* End of application-specific */ +  /* Valeurs possibles pour sh_flags */ diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index c480c51..33a8c3f 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -35,6 +35,8 @@  #include "helper_x86.h"  #include "section.h"  #include "../mangling/demangler.h" +#include "../../arch/raw.h" +#include "../../common/extstr.h"  #include "../../gui/panels/log.h" @@ -48,6 +50,23 @@ const char *get_elf_symbol_name(GElfFormat *, const elf_shdr *, const elf_shdr * + + + +/* ------------------------ CHARGEMENT DE SYMBOLES DU FORMAT ------------------------ */ + + +/* Charge tous les symboles de l'en-tête ELF. */ +static bool annotate_elf_header(GElfFormat *); + +/* Charge tous les symboles liés aux en-têtes de programme ELF. */ +static bool annotate_elf_program_header_table(GElfFormat *); + +/* Charge tous les symboles liés aux en-têtes de section ELF. */ +static bool annotate_elf_section_header_table(GElfFormat *); + + +  /* -------------------------- DETAIL DES SYMBOLES INTERNES -------------------------- */ @@ -72,6 +91,8 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *); + +  /******************************************************************************  *                                                                             *  *  Paramètres  : format = description de l'exécutable à compléter.            * @@ -92,6 +113,16 @@ bool load_elf_symbols(GElfFormat *format)      result = true; + + +    annotate_elf_header(format); + +    annotate_elf_program_header_table(format); + +    annotate_elf_section_header_table(format); + + +      /* Symboles externes */      if (find_elf_sections_by_type(format, SHT_DYNAMIC, §ions, &count)) @@ -155,6 +186,907 @@ const char *get_elf_symbol_name(GElfFormat *format, const elf_shdr *sym, const e + +/* ---------------------------------------------------------------------------------- */ +/*                          CHARGEMENT DE SYMBOLES DU FORMAT                          */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  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   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool annotate_elf_header(GElfFormat *format) +{ +    const bin_t *content;                   /* Contenu binaire à lire      */ +    off_t length;                           /* Taille totale du contenu    */ +    vmpa2t *pos;                            /* Localisation des symboles   */ +    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          */ + +    content = G_BIN_FORMAT(format)->content; +    length = G_BIN_FORMAT(format)->length; + +    pos = make_vmpa(0, 0x123); + +    /* ELFMAG (0) */ + +    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 4, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 1, IOD_CHAR); +    SET_IMM_DISPLAY(instr, operand, 2, IOD_CHAR); +    SET_IMM_DISPLAY(instr, operand, 3, IOD_CHAR); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("ELF magic number")); + +    /* EI_CLASS (4) */ + +    switch (format->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; +    } + +    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +    /* EI_DATA (5) */ + +    switch (format->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; +    } + +    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +    /* EI_VERSION (6) */ + +    switch (format->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; +    } + +    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +    /* EI_OSABI (7) */ + +    switch (format->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; +    } + +    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +    /* EI_ABIVERSION (8) */ + +    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("ABI version")); + +    /* Padding */ + +    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 7, pos, length, format->endian); + +    g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Padding")); + +    /* Champ "e_type" */ + +    switch (format->header.hdr32.e_ident[EI_DATA]) +    { +        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; +    } + +    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +    /* Champ "e_machine" */ + +    switch (format->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; +    } + +    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +    /* Champ "e_version" */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Object file version")); + +    if (format->header.hdr32.e_ident[EI_CLASS] == ELFCLASS32) +    { +        /* Champ "e_entry" */ + +        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +        ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Entry point virtual address")); + +        /* Champ "e_phoff" */ + +        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +        ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Program header table file offset")); + +        /* Champ "e_shoff" */ + +        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +        ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section header table file offset")); + +    } + +    else if (format->header.hdr32.e_ident[EI_CLASS] == ELFCLASS64) +    { +        /* Champ "e_entry" */ + +        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); + +        ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Entry point virtual address")); + +        /* Champ "e_phoff" */ + +        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); + +        ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Program header table file offset")); + +        /* Champ "e_shoff" */ + +        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); + +        ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section header table file offset")); + +    } + +    else return false; + +    /* Champ "e_flags" */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +    //SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Processor-specific flags")); + +    /* Champ "e_ehsize" */ + +    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("ELF header size in bytes")); + +    /* Champ "e_phentsize" */ + +    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Program header table entry size")); + +    /* Champ "e_phnum" */ + +    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Program header table entry count")); + +    /* Champ "e_shentsize" */ + +    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section header table entry size")); + +    /* Champ "e_shnum" */ + +    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section header table entry count")); + +    /* Champ "e_shstrndx" */ + +    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section header string table index")); + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                                                                             * +*  Description : Charge tous les symboles liés aux en-têtes de programme ELF. * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool annotate_elf_program_header_table(GElfFormat *format) +{ +    const bin_t *content;                   /* Contenu binaire à lire      */ +    off_t length;                           /* Taille totale du contenu    */ +    off_t offset;                           /* Tête de lecture du bbinaire */ +    vmpa2t *pos;                            /* Localisation des symboles   */ +    uint16_t e_phnum;                       /* Nombre d'éléments 'Program' */ +    uint16_t i;                             /* Boucle de parcours          */ +    elf_phdr phdr;                          /* En-tête de programme ELF    */ +    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      */ + +    content = G_BIN_FORMAT(format)->content; +    length = G_BIN_FORMAT(format)->length; + +    offset = ELF_HDR(format, format->header, e_phoff); + +    pos = make_vmpa(offset, 0x5500); + +    e_phnum = ELF_HDR(format, format->header, e_phnum); + +    for (i = 0; i < e_phnum; i++) +    { +        if (!read_elf_program_header(format, &offset, &phdr)) +            break; + +        /* Champ "p_type" */ + +        disp = IOD_DEC; + +        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, length, format->endian); + +        SET_IMM_DISPLAY(instr, operand, 0, disp); + +        ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +        if (format->is_32b) +        { +            /* Champ "p_offset" */ + +            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment file offset")); + +            /* Champ "p_vaddr" */ + +            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment virtual address")); + +            /* Champ "p_paddr" */ + +            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment physical address")); + +            /* Champ "p_filesz" */ + +            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment size in file")); + +            /* Champ "p_memsz" */ + +            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment size in memory")); + +            /* Champ "p_flags" */ + +            dtext = strdup(_("Segment flags: ")); +            filled = false; + +            if (ELF_PHDR(format, phdr, p_flags) & PF_R) +            { +                dtext = stradd(dtext, "R"); +                filled = true; +            } + +            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 */; + +            if (ELF_PHDR(format, phdr, p_flags) & PF_MASKPROC) +                /* TODO */; + +            if (!filled) +                dtext = stradd(dtext, _("none")); + +            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, dtext); + +            free(dtext); + +            /* Champ "p_align" */ + +            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment alignment")); + +        } +        else +        { +            /* Champ "p_flags" */ + +            dtext = strdup(_("Segment flags: ")); +            filled = false; + +            if (ELF_PHDR(format, phdr, p_flags) & PF_R) +            { +                dtext = stradd(dtext, "R"); +                filled = true; +            } + +            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 */; + +            if (ELF_PHDR(format, phdr, p_flags) & PF_MASKPROC) +                /* TODO */; + +            if (!filled) +                dtext = stradd(dtext, _("none")); + +            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, dtext); + +            free(dtext); + +            /* Champ "p_offset" */ + +            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment file offset")); + +            /* Champ "p_vaddr" */ + +            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment virtual address")); + +            /* Champ "p_paddr" */ + +            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment physical address")); + +            /* Champ "p_filesz" */ + +            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment size in file")); + +            /* Champ "p_memsz" */ + +            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment size in memory")); + +            /* Champ "p_align" */ + +            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); + +            ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment alignment")); + +        } + +    } + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                                                                             * +*  Description : Charge tous les symboles liés aux en-têtes de section ELF.   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool annotate_elf_section_header_table(GElfFormat *format) +{ +    const bin_t *content;                   /* Contenu binaire à lire      */ +    off_t length;                           /* Taille totale du contenu    */ +    off_t offset;                           /* Tête de lecture du bbinaire */ +    vmpa2t *pos;                            /* Localisation des symboles   */ +    uint16_t e_shnum;                       /* Nombre d'éléments 'Program' */ +    uint16_t i;                             /* Boucle de parcours          */ +    elf_shdr shdr;                          /* En-tête de programme ELF    */ +    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      */ + +    content = G_BIN_FORMAT(format)->content; +    length = G_BIN_FORMAT(format)->length; + +    offset = ELF_HDR(format, format->header, e_shoff); + +    pos = make_vmpa(offset, 0x9900); + +    e_shnum = ELF_HDR(format, format->header, e_shnum); + +    for (i = 0; i < e_shnum; i++) +    { +        if (!read_elf_section_header(format, offset, &shdr)) +            break; + +        /* Champ "sh_name" */ + +        text = _("Section name"); + +        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +        SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + +        ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +        /* Champ "sh_type" */ + +        disp = 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; +        } + +        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); + +        SET_IMM_DISPLAY(instr, operand, 0, disp); + +        ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + + + + + + + + + + + +    } + +    return true; + +} + + +  /* ---------------------------------------------------------------------------------- */  /*                            DETAIL DES SYMBOLES INTERNES                            */  /* ---------------------------------------------------------------------------------- */ diff --git a/src/format/format.c b/src/format/format.c index 8771c46..4b5dfb5 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -193,9 +193,6 @@ const bin_t *g_binary_format_get_content(const GBinFormat *format, off_t *length  void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)  { - -    printf("current :: %d (%p)\n", (int)format->symbols_count, format->symbols); -      format->symbols = (GBinSymbol **)realloc(format->symbols,                                               ++format->symbols_count * sizeof(GBinSymbol *)); diff --git a/src/format/symbol.c b/src/format/symbol.c index b478dc7..f1183cb 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -47,6 +47,8 @@ struct _GBinSymbol      } extra; +    GDbComment *comment;                    /* Eventuel commentaire lié    */ +  };  /* Symbole d'exécutable (classe) */ @@ -203,14 +205,25 @@ const vmpa2t *g_binary_symbol_get_address2(const GBinSymbol *symbol)  {      const vmpa2t *result;                   /* Localisation à retourner    */ +    result = NULL; +      switch (symbol->type)      {          case STP_DATA:              result = g_arch_instruction_get_location2(symbol->extra.instr, NULL);              break; +    default: +        result = NULL; +        break; +      } + +    if (result == NULL) +        printf("got addr=%p for symbol=%p (data=%d)\n", result, symbol, symbol->type == STP_DATA); + +      return result;  } @@ -293,7 +306,7 @@ void g_binary_symbol_attach_routine(GBinSymbol *symbol, GBinRoutine *routine)  /******************************************************************************  *                                                                             * -*  Paramètres  : symbol = symbole à venir consulter.                          * +*  Paramètres  : symbol = symbole à venir manipuler.                          *  *                instr  = représentation du symbole associé.                  *  *                                                                             *  *  Description : Attache l'instruction associée au symbole.                   * @@ -330,3 +343,42 @@ GArchInstruction *g_binary_symbol_get_instruction(const GBinSymbol *symbol)      return symbol->extra.instr;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol  = symbole à venir manipuler.                         * +*                comment = commentaire construit à propos du symbole.         * +*                                                                             * +*  Description : Ajoute un commentaire facultatif au symbole.                 * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_symbol_set_comment(GBinSymbol *symbol, GDbComment *comment) +{ +    symbol->comment = comment; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = symbole à venir consulter.                          * +*                                                                             * +*  Description : Fournit l'éventuel commentaire associé au symbole.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : Il n'y a pas de transfert de propriété ici !                 * +*                                                                             * +******************************************************************************/ + +GDbComment *g_binary_symbol_get_comment(const GBinSymbol *symbol) +{ +    return symbol->comment; + +} diff --git a/src/format/symbol.h b/src/format/symbol.h index bfbf541..407375f 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -29,6 +29,7 @@  #include "../analysis/routine.h" +#include "../analysis/db/items/comment.h" @@ -92,6 +93,36 @@ void g_binary_symbol_attach_instruction(GBinSymbol *, GArchInstruction *);  /* Fournit l'éventuelle instruction associée au symbole. */  GArchInstruction *g_binary_symbol_get_instruction(const GBinSymbol *); +/* Ajoute un commentaire facultatif au symbole. */ +void g_binary_symbol_set_comment(GBinSymbol *, GDbComment *); + +/* Fournit l'éventuel commentaire associé au symbole. */ +GDbComment *g_binary_symbol_get_comment(const GBinSymbol *); + + +/** + * Confort pour l'ajout de symboles basés sur des formats. + */ + +#define SET_IMM_DISPLAY(_ins, _op, _idx, _dsp)                  \ +    do                                                          \ +    {                                                           \ +        _op = g_arch_instruction_get_operand(_ins, _idx);       \ +        g_imm_operand_set_display(G_IMM_OPERAND(_op), _dsp);    \ +    }                                                           \ +    while (0) + +#define ADD_RAW_AS_SYM(_fmt, _sym, _pos, _ins, _cmt, _txt)      \ +    do                                                          \ +    {                                                           \ +        _cmt = g_db_comment_new(_pos, _txt, true);              \ +        _sym = g_binary_symbol_new(STP_DATA, NULL, 0);          \ +        g_binary_symbol_attach_instruction(_sym, _ins);         \ +        g_binary_symbol_set_comment(_sym, _cmt);                \ +        g_binary_format_add_symbol(G_BIN_FORMAT(_fmt), _sym);   \ +    }                                                           \ +    while (0) +  #endif  /* _FORMAT_SYMBOL_H */  | 
