[coreboot-gerrit] New patch to review for coreboot: afa2a5a cbfstool: add symbol table parsing to the ELF parser

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Tue Mar 11 18:11:48 CET 2014


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5376

-gerrit

commit afa2a5a17f2c83f145d57aeee08c91f8c6c54e41
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Wed Mar 5 16:41:27 2014 -0600

    cbfstool: add symbol table parsing to the ELF parser
    
    Optionally parse the symbol table contained within an ELF
    file. It currently assumes there is only one symbol table present,
    and it errors out if more than one is found.
    
    Change-Id: I4ac4ad03184a319562576d8ab24fa620e701672a
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 util/cbfstool/elfheaders.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++
 util/cbfstool/elfparsing.h |  3 ++
 2 files changed, 74 insertions(+)

diff --git a/util/cbfstool/elfheaders.c b/util/cbfstool/elfheaders.c
index fe64e17..6818d72 100644
--- a/util/cbfstool/elfheaders.c
+++ b/util/cbfstool/elfheaders.c
@@ -435,6 +435,69 @@ static int strtab_read(const struct buffer *in, struct parsed_elf *pelf)
 	return 0;
 }
 
+static int
+symtab_read(const struct buffer *in, struct parsed_elf *pelf,
+            struct xdr *xdr, int bit64)
+{
+	Elf64_Ehdr *ehdr;
+	Elf64_Shdr *shdr;
+	Elf64_Half i;
+	Elf64_Xword nsyms;
+	Elf64_Sym *sym;
+	struct buffer b;
+
+	ehdr = &pelf->ehdr;
+
+	shdr = NULL;
+	for (i = 0; i < ehdr->e_shnum; i++) {
+		if (pelf->shdr[i].sh_type != SHT_SYMTAB)
+			continue;
+
+		if (shdr != NULL) {
+			ERROR("Multiple symbol sections found. %u and %u\n",
+			      (unsigned int)(shdr - pelf->shdr), i);
+			return -1;
+		}
+
+		shdr = &pelf->shdr[i];
+	}
+
+	if (shdr == NULL) {
+		ERROR("No symbol table found.\n");
+		return -1;
+	}
+
+	buffer_splice(&b, in, shdr->sh_offset, shdr->sh_size);
+	if (check_size(in, shdr->sh_offset, buffer_size(&b), "symtab"))
+		return -1;
+
+	nsyms = shdr->sh_size / shdr->sh_entsize;
+
+	pelf->syms = calloc(nsyms, sizeof(Elf64_Sym));
+
+	for (i = 0; i < nsyms; i++) {
+		sym = &pelf->syms[i];
+
+		if (bit64) {
+			sym->st_name = xdr->get32(&b);
+			sym->st_info = xdr->get8(&b);
+			sym->st_other = xdr->get8(&b);
+			sym->st_shndx = xdr->get16(&b);
+			sym->st_value = xdr->get64(&b);
+			sym->st_size = xdr->get64(&b);
+		} else {
+			sym->st_name = xdr->get32(&b);
+			sym->st_value = xdr->get32(&b);
+			sym->st_size = xdr->get32(&b);
+			sym->st_info = xdr->get8(&b);
+			sym->st_other = xdr->get8(&b);
+			sym->st_shndx = xdr->get16(&b);
+		}
+	}
+
+	return 0;
+}
+
 int parse_elf(const struct buffer *pinput, struct parsed_elf *pelf, int flags)
 {
 	struct xdr *xdr = &xdr_le;
@@ -472,6 +535,10 @@ int parse_elf(const struct buffer *pinput, struct parsed_elf *pelf, int flags)
 	if (flags & ELF_PARSE_STRTAB)
 		flags |= ELF_PARSE_SHDR;
 
+	/* Symbole table processing requires section header parsing. */
+	if (flags & ELF_PARSE_SYMTAB)
+		flags |= ELF_PARSE_SHDR;
+
 	if ((flags & ELF_PARSE_PHDR) && phdr_read(pinput, pelf, xdr, bit64))
 		goto fail;
 
@@ -484,6 +551,9 @@ int parse_elf(const struct buffer *pinput, struct parsed_elf *pelf, int flags)
 	if ((flags & ELF_PARSE_STRTAB) && strtab_read(pinput, pelf))
 		goto fail;
 
+	if ((flags & ELF_PARSE_SYMTAB) && symtab_read(pinput, pelf, xdr, bit64))
+		goto fail;
+
 	return 0;
 
 fail:
@@ -508,6 +578,7 @@ void parsed_elf_destroy(struct parsed_elf *pelf)
 			free(pelf->strtabs[i]);
 	}
 	free(pelf->strtabs);
+	free(pelf->syms);
 }
 
 /* Get the headers from the buffer.
diff --git a/util/cbfstool/elfparsing.h b/util/cbfstool/elfparsing.h
index 9107c21..113301a 100644
--- a/util/cbfstool/elfparsing.h
+++ b/util/cbfstool/elfparsing.h
@@ -41,12 +41,15 @@ struct parsed_elf {
 	 * entry.
 	 */
 	struct buffer **strtabs;
+	/* Parsed symbols. */
+	Elf64_Sym *syms;
 };
 
 #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_SYMTAB	(1 << 4)
 
 #define ELF_PARSE_ALL		(-1)
 



More information about the coreboot-gerrit mailing list