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>
Reviewed-on: http://review.coreboot.org/5375
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marc.jones@se-eng.com>
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 @@
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 @@
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 @@
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 @@
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 @@
* 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)