Aaron Durbin (adurbin@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5375
-gerrit
commit c346aa65a7ce329aea76e6f5e3ec1cdbcf306956 Author: Aaron Durbin adurbin@chromium.org Date: Wed Mar 5 14:33:42 2014 -0600
cbfstool: add string table parsing to ELF parser
Optionally parse the string tables within an ELF file.
Change-Id: I89f9da50b4fcf1fed7ac44f00c60b495c35555ef Signed-off-by: Aaron Durbin adurbin@chromium.org --- util/cbfstool/elfheaders.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-- util/cbfstool/elfparsing.h | 11 ++++++++-- 2 files changed, 59 insertions(+), 4 deletions(-)
diff --git a/util/cbfstool/elfheaders.c b/util/cbfstool/elfheaders.c index 8e06f5e..37371e2 100644 --- a/util/cbfstool/elfheaders.c +++ b/util/cbfstool/elfheaders.c @@ -395,6 +395,41 @@ reloc_read(const struct buffer *in, struct parsed_elf *pelf, return 0; }
+static int strtab_read(const struct buffer *in, struct parsed_elf *pelf) +{ + Elf64_Ehdr *ehdr; + Elf64_Word i; + + ehdr = &pelf->ehdr; + + if (ehdr->e_shstrndx >= ehdr->e_shnum) { + ERROR("Section header string table index out of range: %d\n", + ehdr->e_shstrndx); + return -1; + } + + /* For each section of type SHT_STRTAB create a symtab buffer. */ + pelf->strtabs = calloc(ehdr->e_shnum, sizeof(struct buffer *)); + + for (i = 0; i < ehdr->e_shnum; i++) { + struct buffer *b; + Elf64_Shdr *shdr = &pelf->shdr[i]; + + if (shdr->sh_type != SHT_STRTAB) + continue; + + b = calloc(1, sizeof(*b)); + buffer_splice(b, in, shdr->sh_offset, shdr->sh_size); + if (check_size(in, shdr->sh_offset, buffer_size(b), "strtab")) { + ERROR("STRTAB section not within bounds: %d\n", i); + return -1; + } + pelf->strtabs[i] = b; + } + + return 0; +} + int parse_elf(const struct buffer *pinput, struct parsed_elf *pelf, int flags) { struct xdr *xdr = &xdr_le; @@ -428,6 +463,10 @@ int parse_elf(const struct buffer *pinput, struct parsed_elf *pelf, int flags) if (flags & ELF_PARSE_RELOC) flags |= ELF_PARSE_SHDR;
+ /* String table processing requires section header parsing. */ + if (flags & ELF_PARSE_STRTAB) + flags |= ELF_PARSE_SHDR; + if ((flags & ELF_PARSE_PHDR) && phdr_read(pinput, pelf, xdr, bit64)) goto fail;
@@ -437,6 +476,9 @@ int parse_elf(const struct buffer *pinput, struct parsed_elf *pelf, int flags) if ((flags & ELF_PARSE_RELOC) && reloc_read(pinput, pelf, xdr, bit64)) goto fail;
+ if ((flags & ELF_PARSE_STRTAB) && strtab_read(pinput, pelf)) + goto fail; + return 0;
fail: @@ -446,15 +488,21 @@ fail:
void parsed_elf_destroy(struct parsed_elf *pelf) { + Elf64_Half i; + free(pelf->phdr); free(pelf->shdr); if (pelf->relocs != NULL) { - Elf64_Half i; - for (i = 0; i < pelf->ehdr.e_shnum; i++) free(pelf->relocs[i]); } free(pelf->relocs); + + if (pelf->strtabs != NULL) { + for (i = 0; i < pelf->ehdr.e_shnum; i++) + free(pelf->strtabs[i]); + } + free(pelf->strtabs); }
/* Get the headers from the buffer. diff --git a/util/cbfstool/elfparsing.h b/util/cbfstool/elfparsing.h index 2827748..9107c21 100644 --- a/util/cbfstool/elfparsing.h +++ b/util/cbfstool/elfparsing.h @@ -19,8 +19,7 @@ #define ELFPARSING_H
#include "elf.h" - -struct buffer; +#include "common.h"
struct parsed_elf { Elf64_Ehdr ehdr; @@ -35,11 +34,19 @@ struct parsed_elf { * NULL. */ Elf64_Rela **relocs; + /* + * Similarly to the relocs array the strtabs array consists of an + * array of pointers where each entry represents a potential struct + * buffer pointer. Only setions of type SHT_STRTAB will have a non-NULL + * entry. + */ + struct buffer **strtabs; };
#define ELF_PARSE_PHDR (1 << 0) #define ELF_PARSE_SHDR (1 << 1) #define ELF_PARSE_RELOC (1 << 2) +#define ELF_PARSE_STRTAB (1 << 3)
#define ELF_PARSE_ALL (-1)