summaryrefslogtreecommitdiff
path: root/util/cbfstool
diff options
context:
space:
mode:
authorJeremy Compostella <jeremy.compostella@intel.com>2024-10-24 14:38:52 -0700
committerJérémy Compostella <jeremy.compostella@intel.com>2024-10-25 23:01:45 +0000
commit892257ec2187e84c1610d97367ca59270bcbadda (patch)
tree0c792ad30c9d0d8720f2c91b4e13be68fd8389cd /util/cbfstool
parent87f0224c0a9eb266b44c622713511047404c05c2 (diff)
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>
Diffstat (limited to 'util/cbfstool')
-rw-r--r--util/cbfstool/cbfs-mkstage.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/util/cbfstool/cbfs-mkstage.c b/util/cbfstool/cbfs-mkstage.c
index 2338adc7ae..a72b387c2b 100644
--- a/util/cbfstool/cbfs-mkstage.c
+++ b/util/cbfstool/cbfs-mkstage.c
@@ -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);