cbfstool: Fix segmentation fault for data segment relocation
`cbfstool add-stage' crashes with a segmentation fault when generating
the program binary out of a romstage ELF containing relocation within
the data segment.
This commit makes `parse_elf_to_xip_stage()' look for the segment to
which the current relocation applies and compute the appropriate
location within the program binary.
This issue can be reproduced by defining a global variable with a
pointer to constant data. This variable is defined within the .data
section and contains a pointer to a constant which resides in the
.text section. As a result, a relocation entry is generated in the ELF
file.
struct my_struct {
const char *name;
};
struct my_struct my_global = { .name = "EXAMPLE" };
void fun(void)
{
printk(BIOS_DEBUG, "my_global.name=%s\n", my_global.name);
}
TEST=global data structure with a pointer to a constant does not make
cbfstool crash
Change-Id: I480b4b047546c8aa4e12dfb688e0299f80283235
Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/84864
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Shuo Liu <shuo.liu@intel.com>
Reviewed-by: Wonkyu Kim <wonkyu.kim@intel.com>
This commit is contained in:
parent
87f0224c0a
commit
892257ec21
1 changed files with 13 additions and 1 deletions
|
|
@ -403,11 +403,23 @@ int parse_elf_to_xip_stage(const struct buffer *input, struct buffer *output,
|
|||
size_t reloc_offset;
|
||||
uint32_t val;
|
||||
struct buffer in, out;
|
||||
Elf64_Addr reloc = rmodctx->emitted_relocs[i];
|
||||
|
||||
/* The relocations represent in-program addresses of the
|
||||
* linked program. Obtain the offset into the program to do
|
||||
* the adjustment. */
|
||||
reloc_offset = rmodctx->emitted_relocs[i] - pelf->phdr->p_vaddr;
|
||||
reloc_offset = 0;
|
||||
for (phdr = toload; *phdr; phdr++) {
|
||||
if (reloc >= (*phdr)->p_vaddr &&
|
||||
reloc < (*phdr)->p_vaddr + (*phdr)->p_memsz)
|
||||
break;
|
||||
reloc_offset += (*phdr)->p_filesz;
|
||||
}
|
||||
if (!*phdr) {
|
||||
ERROR("Relocation outside of loadable segments\n");
|
||||
goto out;
|
||||
}
|
||||
reloc_offset += reloc - (*phdr)->p_vaddr;
|
||||
|
||||
buffer_clone(&out, &boutput);
|
||||
buffer_seek(&out, reloc_offset);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue