mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
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>
This commit is contained in:
parent
ccb5ad8d3c
commit
c3e6e14a12
2 changed files with 59 additions and 4 deletions
|
@ -395,6 +395,41 @@ reloc_read(const struct buffer *in, struct parsed_elf *pelf,
|
||||||
return 0;
|
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)
|
int parse_elf(const struct buffer *pinput, struct parsed_elf *pelf, int flags)
|
||||||
{
|
{
|
||||||
struct xdr *xdr = &xdr_le;
|
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)
|
if (flags & ELF_PARSE_RELOC)
|
||||||
flags |= ELF_PARSE_SHDR;
|
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))
|
if ((flags & ELF_PARSE_PHDR) && phdr_read(pinput, pelf, xdr, bit64))
|
||||||
goto fail;
|
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))
|
if ((flags & ELF_PARSE_RELOC) && reloc_read(pinput, pelf, xdr, bit64))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if ((flags & ELF_PARSE_STRTAB) && strtab_read(pinput, pelf))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -446,15 +488,21 @@ fail:
|
||||||
|
|
||||||
void parsed_elf_destroy(struct parsed_elf *pelf)
|
void parsed_elf_destroy(struct parsed_elf *pelf)
|
||||||
{
|
{
|
||||||
|
Elf64_Half i;
|
||||||
|
|
||||||
free(pelf->phdr);
|
free(pelf->phdr);
|
||||||
free(pelf->shdr);
|
free(pelf->shdr);
|
||||||
if (pelf->relocs != NULL) {
|
if (pelf->relocs != NULL) {
|
||||||
Elf64_Half i;
|
|
||||||
|
|
||||||
for (i = 0; i < pelf->ehdr.e_shnum; i++)
|
for (i = 0; i < pelf->ehdr.e_shnum; i++)
|
||||||
free(pelf->relocs[i]);
|
free(pelf->relocs[i]);
|
||||||
}
|
}
|
||||||
free(pelf->relocs);
|
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.
|
/* Get the headers from the buffer.
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
#define ELFPARSING_H
|
#define ELFPARSING_H
|
||||||
|
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
#include "common.h"
|
||||||
struct buffer;
|
|
||||||
|
|
||||||
struct parsed_elf {
|
struct parsed_elf {
|
||||||
Elf64_Ehdr ehdr;
|
Elf64_Ehdr ehdr;
|
||||||
|
@ -35,11 +34,19 @@ struct parsed_elf {
|
||||||
* NULL.
|
* NULL.
|
||||||
*/
|
*/
|
||||||
Elf64_Rela **relocs;
|
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_PHDR (1 << 0)
|
||||||
#define ELF_PARSE_SHDR (1 << 1)
|
#define ELF_PARSE_SHDR (1 << 1)
|
||||||
#define ELF_PARSE_RELOC (1 << 2)
|
#define ELF_PARSE_RELOC (1 << 2)
|
||||||
|
#define ELF_PARSE_STRTAB (1 << 3)
|
||||||
|
|
||||||
#define ELF_PARSE_ALL (-1)
|
#define ELF_PARSE_ALL (-1)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue