cbfstool: Read XIP stage alignment requirements from ELF
On x86_64 romstage can contain page tables and a page table pointer which have an larger alignment requirement of 4096. Instead of hardcoding it, read if from the ELF phdrs. Change-Id: I94e4a4209b7441ecb2966a1342c3d46625771bb8 Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/c/coreboot/+/82102 Reviewed-by: Shuo Liu <shuo.liu@intel.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Jérémy Compostella <jeremy.compostella@intel.com> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
parent
71c9010443
commit
6ed0ba1e93
@ -1276,15 +1276,6 @@ ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM),y)
|
||||
$(CONFIG_CBFS_PREFIX)/romstage-options := -b 0
|
||||
endif
|
||||
ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y)
|
||||
# Use a 64 byte alignment to provide a minimum alignment
|
||||
# requirement for the overall romstage. While the first object within
|
||||
# romstage could have a 4 byte minimum alignment that doesn't mean the linker
|
||||
# won't decide the entire section should be aligned to a larger value. In the
|
||||
# future cbfstool should add XIP files proper and honor the alignment
|
||||
# requirements of the program segment.
|
||||
#
|
||||
# Make sure that segment for .car.data is ignored while adding romstage.
|
||||
$(CONFIG_CBFS_PREFIX)/romstage-align := 64
|
||||
ifeq ($(CONFIG_NO_XIP_EARLY_STAGES),y)
|
||||
$(CONFIG_CBFS_PREFIX)/romstage-options := -S ".car.data"
|
||||
else
|
||||
|
@ -1156,23 +1156,26 @@ static int cbfstool_convert_mkstage(struct buffer *buffer, uint32_t *offset,
|
||||
struct cbfs_file *header)
|
||||
{
|
||||
struct buffer output;
|
||||
size_t data_size;
|
||||
int ret;
|
||||
|
||||
if (elf_program_file_size(buffer, &data_size) < 0) {
|
||||
ERROR("Could not obtain ELF size\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need a final location for XIP parsing, so we need to call do_cbfs_locate() early
|
||||
* here. That is okay because XIP stages may not be compressed, so their size cannot
|
||||
* change anymore at a later point.
|
||||
*/
|
||||
if (param.stage_xip &&
|
||||
do_cbfs_locate(offset, data_size)) {
|
||||
ERROR("Could not find location for stage.\n");
|
||||
return 1;
|
||||
if (param.stage_xip) {
|
||||
size_t data_size, alignment;
|
||||
if (elf_program_file_size_align(buffer, &data_size, &alignment) < 0) {
|
||||
ERROR("Could not obtain ELF size & alignment\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
param.alignment = MAX(alignment, param.alignment);
|
||||
|
||||
if (do_cbfs_locate(offset, data_size)) {
|
||||
ERROR("Could not find location for stage.\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct cbfs_file_attr_stageheader *stageheader = (void *)
|
||||
|
@ -1434,12 +1434,13 @@ int elf_writer_add_rel(struct elf_writer *ew, const char *sym, Elf64_Addr addr)
|
||||
return add_rel(rel_sec, &rel);
|
||||
}
|
||||
|
||||
int elf_program_file_size(const struct buffer *input, size_t *file_size)
|
||||
int elf_program_file_size_align(const struct buffer *input, size_t *file_size, size_t *align)
|
||||
{
|
||||
Elf64_Ehdr ehdr;
|
||||
Elf64_Phdr *phdr;
|
||||
int i;
|
||||
size_t loadable_file_size = 0;
|
||||
size_t align_size = 0;
|
||||
|
||||
if (elf_headers(input, &ehdr, &phdr, NULL))
|
||||
return -1;
|
||||
@ -1448,9 +1449,11 @@ int elf_program_file_size(const struct buffer *input, size_t *file_size)
|
||||
if (phdr[i].p_type != PT_LOAD)
|
||||
continue;
|
||||
loadable_file_size += phdr[i].p_filesz;
|
||||
align_size = MAX(align_size, phdr[i].p_align);
|
||||
}
|
||||
|
||||
*file_size = loadable_file_size;
|
||||
*align = align_size;
|
||||
|
||||
free(phdr);
|
||||
|
||||
|
@ -114,9 +114,9 @@ int elf_writer_add_rel(struct elf_writer *ew, const char *sym, Elf64_Addr addr);
|
||||
int elf_writer_serialize(struct elf_writer *ew, struct buffer *out);
|
||||
|
||||
/*
|
||||
* Calculate the loadable program's file size footprint. Returns < 0 on error,
|
||||
* 0 on success.
|
||||
* Calculate the loadable program's file size footprint and alignment requirements.
|
||||
* Returns < 0 on error, 0 on success.
|
||||
*/
|
||||
int elf_program_file_size(const struct buffer *input, size_t *file_size);
|
||||
int elf_program_file_size_align(const struct buffer *input, size_t *file_size, size_t *align);
|
||||
|
||||
#endif /* ELFPARSING_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user