diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2016-12-29 10:30:28 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2016-12-29 10:30:28 (GMT) | 
| commit | 9f9041e11efa71cb043425cd5e89daea0247e76c (patch) | |
| tree | 84d8704c291a5efef46af1e14a2aa3544dc29455 /src/format/elf | |
| parent | 403a0519ec85a156a7f306b045d9cab619302473 (diff) | |
Cut binary data into several areas using all the available CPUs and less memory.
Diffstat (limited to 'src/format/elf')
| -rw-r--r-- | src/format/elf/elf.c | 155 | 
1 files changed, 28 insertions, 127 deletions
| diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index 2dd41e1..a51fe33 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -69,7 +69,7 @@ static SourceEndian g_elf_format_get_endianness(const GElfFormat *);  static const char *g_elf_format_get_target_machine(const GElfFormat *);  /* Etend la définition des portions au sein d'un binaire. */ -static void g_elf_format_refine_portions(const GElfFormat *, GPortionLayer *); +static void g_elf_format_refine_portions(GElfFormat *);  /* Fournit l'emplacement correspondant à une position physique. */  static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *, phys_t, vmpa2t *); @@ -244,10 +244,12 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatus  {      GElfFormat *result;                     /* Structure à retourner       */      GBinFormat *base;                       /* Version basique du format   */ +    GExeFormat *exe_format;                 /* Autre version du format     */      result = g_object_new(G_TYPE_ELF_FORMAT, NULL);      base = G_BIN_FORMAT(result); +    exe_format = G_EXE_FORMAT(result);      g_binary_format_set_content(base, content); @@ -305,7 +307,7 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatus      } -    if (!g_binary_format_complete_loading(base, status)) +    if (!g_executable_format_complete_loading(exe_format, status))          goto gefn_error;      return base; @@ -383,7 +385,6 @@ static const char *g_elf_format_get_target_machine(const GElfFormat *format)  /******************************************************************************  *                                                                             *  *  Paramètres  : format = informations chargées à consulter.                  * -*                main   = couche de portions principale à raffiner.           *  *                                                                             *  *  Description : Etend la définition des portions au sein d'un binaire.       *  *                                                                             * @@ -393,14 +394,13 @@ static const char *g_elf_format_get_target_machine(const GElfFormat *format)  *                                                                             *  ******************************************************************************/ -static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer *main) +static void g_elf_format_refine_portions(GElfFormat *format)  { -    GPortionLayer *layer;                   /* Couche à mettre en place    */ +    GExeFormat *exe_format;                 /* Autre version du format     */      uint16_t max;                           /* Décompte d'éléments traités */ -    elf_phdr *sorted_phdrs;                 /* Liste de segments triée     */      uint16_t i;                             /* Boucle de parcours          */      off_t offset;                           /* Début de part de programme  */ -    elf_phdr *phdr;                         /* En-tête de programme ELF    */ +    elf_phdr phdr;                          /* En-tête de programme ELF    */      uint32_t p_flags;                       /* Droits associés à une partie*/      const char *background;                 /* Fond signigicatif           */      GBinPortion *new;                       /* Nouvelle portion définie    */ @@ -409,11 +409,12 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer      PortionAccessRights rights;             /* Droits d'une portion        */      elf_shdr strings;                       /* Section des descriptions    */      bool has_strings;                       /* Section trouvée ?           */ -    elf_shdr *sorted_shdrs;                 /* Liste de sections triée     */ -    elf_shdr *section;                      /* En-tête de section ELF      */ +    elf_shdr shdr;                          /* En-tête de section ELF      */      uint64_t sh_flags;                      /* Droits associés à une partie*/      const char *name;                       /* Nom trouvé ou NULL          */ +    exe_format = G_EXE_FORMAT(format); +      /**       * La copie des différents en-têtes cherche à reproduire l'inclusion native       * du format : @@ -429,83 +430,35 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer       * Côté segments basiques.       */ -    layer = g_portion_layer_new(NO_LENGTH_YET, _("Segment")); - -    g_portion_layer_attach_sub(main, layer); - -    /* Constitution d'une liste de travail */ -      max = ELF_HDR(format, format->header, e_phnum); -    sorted_phdrs = (elf_phdr *)calloc(max, sizeof(elf_phdr)); -      for (i = 0; i < max; i++)      {          offset = ELF_HDR(format, format->header, e_phoff)              + ELF_HDR(format, format->header, e_phentsize) * i; -        if (!read_elf_program_header(format, offset, &sorted_phdrs[i])) -        { -            if (format->is_32b) -                sorted_phdrs[i].phdr32.p_type = PT_NULL; -            else -                sorted_phdrs[i].phdr64.p_type = PT_NULL; -        } - -    } - -    /* Tri de cette liste */ - -    int sort_phdr(elf_phdr *a, elf_phdr *b) -    { -        uint64_t filesz_a;                  /* Taille de l'en-tête 'a'     */ -        uint64_t filesz_b;                  /* Taille de l'en-tête 'b'     */ -        int status;                         /* Bilan d'une comparaison     */ - -        filesz_a = ELF_PHDR(format, *a, p_filesz); -        filesz_b = ELF_PHDR(format, *b, p_filesz); - -        if (filesz_a < filesz_b) -            status = 1; - -        else if (filesz_a > filesz_b) -            status = -1; - -        else -            status = 0; - -        return status; - -    } - -    qsort(sorted_phdrs, max, sizeof(elf_phdr), (__compar_fn_t)sort_phdr); - -    /* Inclusion de ces en-têtes */ - -    for (i = 0; i < max; i++) -    { -        phdr = &sorted_phdrs[i]; +        if (!read_elf_program_header(format, offset, &phdr)) +            continue; -        if (ELF_PHDR(format, *phdr, p_type) == PT_NULL) +        if (ELF_PHDR(format, phdr, p_type) == PT_NULL)              continue; -        p_flags = ELF_PHDR(format, *phdr, p_flags); +        p_flags = ELF_PHDR(format, phdr, p_flags);          if (p_flags & PF_X) background = BPC_CODE;          else if (p_flags & PF_W) background = BPC_DATA;          else background = BPC_DATA_RO; -        new = g_binary_portion_new(background); +        init_vmpa(&addr, ELF_PHDR(format, phdr, p_offset), ELF_PHDR(format, phdr, p_vaddr)); + +        new = g_binary_portion_new(background, &addr, ELF_PHDR(format, phdr, p_filesz));          snprintf(desc, MAX_PORTION_DESC, "%s \"%s\"",                   _("Segment"), -                 get_elf_program_type_desc(ELF_PHDR(format, *phdr, p_type))); +                 get_elf_program_type_desc(ELF_PHDR(format, phdr, p_type)));          g_binary_portion_set_desc(new, desc); -        init_vmpa(&addr, ELF_PHDR(format, *phdr, p_offset), ELF_PHDR(format, *phdr, p_vaddr)); -        g_binary_portion_set_values(new, &addr, ELF_PHDR(format, *phdr, p_filesz)); -          rights = PAC_NONE;          if (p_flags & PF_R) rights |= PAC_READ;          if (p_flags & PF_W) rights |= PAC_WRITE; @@ -513,12 +466,10 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer          g_binary_portion_set_rights(new, rights); -        g_portion_layer_include(layer, new); +        g_exe_format_include_portion(exe_format, new);      } -    free(sorted_phdrs); -      /**       * Inclusion des sections, si possible...       */ @@ -527,64 +478,17 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer                                              ELF_HDR(format, format->header, e_shstrndx),                                              &strings); -    layer = g_portion_layer_new(NO_LENGTH_YET, _("Section")); - -    g_portion_layer_attach_sub(main, layer); - -    /* Constitution d'une liste de travail */ -      max = ELF_HDR(format, format->header, e_shnum); -    sorted_shdrs = (elf_shdr *)calloc(max, sizeof(elf_shdr)); - -    for (i = 0; i < max; i++) -    { -        if (!find_elf_section_by_index(format, i, &sorted_shdrs[i])) -        { -            if (format->is_32b) -                sorted_shdrs[i].shdr32.sh_offset = 0; -            else -                sorted_shdrs[i].shdr64.sh_offset = 0; -        } - -    } - -    /* Tri de cette liste */ - -    int sort_shdr(elf_shdr *a, elf_shdr *b) -    { -        uint64_t size_a;                    /* Taille de l'en-tête 'a'     */ -        uint64_t size_b;                    /* Taille de l'en-tête 'b'     */ -        int status;                         /* Bilan d'une comparaison     */ - -        size_a = ELF_SHDR(format, *a, sh_size); -        size_b = ELF_SHDR(format, *b, sh_size); - -        if (size_a < size_b) -            status = 1; - -        else if (size_a > size_b) -            status = -1; - -        else -            status = 0; - -        return status; - -    } - -    qsort(sorted_shdrs, max, sizeof(elf_shdr), (__compar_fn_t)sort_shdr); - -    /* Inclusion de ces en-têtes */ -      for (i = 0; i < max; i++)      { -        section = &sorted_shdrs[i]; +        if (!find_elf_section_by_index(format, i, &shdr)) +            continue; -        if (ELF_SHDR(format, *section, sh_offset) == 0) +        if (ELF_SHDR(format, shdr, sh_offset) == 0)              continue; -        sh_flags = ELF_SHDR(format, *section, sh_flags); +        sh_flags = ELF_SHDR(format, shdr, sh_flags);          if ((sh_flags & SHF_ALLOC) == 0)              continue; @@ -593,11 +497,13 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer          else if (sh_flags & SHF_WRITE) background = BPC_DATA;          else background = BPC_DATA_RO; -        new = g_binary_portion_new(background); +        init_vmpa(&addr, ELF_SHDR(format, shdr, sh_offset), ELF_SHDR(format, shdr, sh_addr)); + +        new = g_binary_portion_new(background, &addr, ELF_SHDR(format, shdr, sh_size));          if (has_strings)              name = extract_name_from_elf_string_section(format, &strings, -                                                        ELF_SHDR(format, *section, sh_name)); +                                                        ELF_SHDR(format, shdr, sh_name));          else name = NULL;          if (name != NULL) @@ -607,9 +513,6 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer          g_binary_portion_set_desc(new, desc); -        init_vmpa(&addr, ELF_SHDR(format, *section, sh_offset), ELF_SHDR(format, *section, sh_addr)); -        g_binary_portion_set_values(new, &addr, ELF_SHDR(format, *section, sh_size)); -          rights = PAC_NONE;          if (sh_flags & SHF_ALLOC) rights |= PAC_READ;          if (sh_flags & SHF_WRITE) rights |= PAC_WRITE; @@ -617,12 +520,10 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer          g_binary_portion_set_rights(new, rights); -        g_portion_layer_include(layer, new); +        g_exe_format_include_portion(exe_format, new);      } -    free(sorted_shdrs); -  } | 
