Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/bif.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ static error bif_parse_file(lexer_t *lex, bif_cfg_t *cfg, bif_node_t *node) {
node->load = 0;
node->offset = 0;
node->bootloader = 0;
node->elf_use_ph = 0;
node->fsbl_config = 0;
node->pmufw_image = 0;
node->exception_level = BOOTROM_PART_ATTR_EXC_LVL_EL0;
Expand Down Expand Up @@ -462,6 +463,11 @@ error bif_node_set_attr(
return SUCCESS;
}

if (strcmp(attr_name, "elf_use_ph") == 0) {
node->elf_use_ph = 0xFF;
return SUCCESS;
}

if (strcmp(attr_name, "partition_owner") == 0) {
if (!value) {
perrorf(lex, "the \"%s\" attribute requires an argument\n", attr_name);
Expand Down
1 change: 1 addition & 0 deletions src/bif.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typedef struct bif_node_t {
uint32_t load;
uint32_t offset;
uint32_t partition_owner;
uint8_t elf_use_ph; /* boolean */

/* supported zynqmp attributes */
uint8_t fsbl_config; /* boolean */
Expand Down
6 changes: 4 additions & 2 deletions src/bootrom.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ error append_file_to_image(uint32_t *addr,
img_size,
&elf_nbits,
&elf_load,
&elf_entry);
&elf_entry,
node.elf_use_ph);
if (err) {
errorf("ELF file reading failed\n");

Expand Down Expand Up @@ -372,7 +373,8 @@ error create_boot_image(uint32_t *img_ptr,
&pmufw_img_size,
&pmufw_img_nbits,
&pmufw_img_load,
&pmufw_img_entry);
&pmufw_img_entry,
bif_cfg->nodes[i].elf_use_ph);
if (err) {
errorf("failed to parse ELF file: %s\n", bif_cfg->nodes[i].fname);
return ERROR_BOOTROM_ELF;
Expand Down
99 changes: 89 additions & 10 deletions src/file/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,73 @@
#include <gelf.h>
#include <unistd.h>

static error elf_create_image_from_ph(Elf *elf, uint32_t start_addr, uint8_t *out_buf) {
size_t n_phdrs;

if(elf_getphdrnum(elf, &n_phdrs) != 0) {
printf("elf_getphdrnum failed\n");
return ERROR_BOOTROM_ELF;
}
size_t file_size;
uint8_t *raw_data = elf_rawfile(elf, &file_size);
if (raw_data == NULL) {
return ERROR_BOOTROM_ELF;
}
for (size_t i = 0; i < n_phdrs; ++i) {
GElf_Phdr phdr;
if (gelf_getphdr(elf, i, &phdr) == NULL) {
printf("gelf_getphdr returned no address\n");
continue;
}
if (phdr.p_type == PT_LOAD) {
if (phdr.p_offset + phdr.p_filesz > file_size) {
return ERROR_BOOTROM_ELF;
}
if (phdr.p_filesz > 0) {
uint8_t *segment_data = raw_data + phdr.p_offset;
size_t segment_size = phdr.p_filesz;

memcpy(out_buf + phdr.p_paddr - start_addr,
segment_data,
segment_size);
}
}
}
return SUCCESS;
}

static bool elf_is_loadable_section(const GElf_Shdr *elf_shdr) {
return elf_shdr->sh_type != SHT_NOBITS && (elf_shdr->sh_flags & SHF_ALLOC) &&
elf_shdr->sh_size != 0;
}

static error elf_get_startaddr_endaddr_from_ph(Elf *elf, uint32_t *start_addr, uint32_t *end_addr) {
size_t n_phdrs;
*start_addr = -1;
*end_addr = 0;

if (elf_getphdrnum(elf, &n_phdrs) != 0) {
return ERROR_BOOTROM_ELF;
}

for (size_t i = 0; i < n_phdrs; ++i) {
GElf_Phdr phdr;
if (gelf_getphdr(elf, i, &phdr) == NULL) {
continue;
}
if (phdr.p_type == PT_LOAD) {
if (*start_addr > phdr.p_paddr) {
*start_addr = phdr.p_paddr;
}

if (phdr.p_paddr + phdr.p_filesz > *end_addr) {
*end_addr = phdr.p_paddr + phdr.p_filesz;
}
}
}
return SUCCESS;
}

static error elf_get_startaddr_endaddr(Elf *elf, uint32_t *start_addr, uint32_t *end_addr) {
Elf_Scn *elf_scn = NULL;
GElf_Shdr elf_shdr;
Expand Down Expand Up @@ -95,7 +157,8 @@ error elf_append(void *addr,
uint32_t *img_size,
uint8_t *elf_nbits,
uint32_t *elf_load,
uint32_t *elf_entry) {
uint32_t *elf_entry,
uint8_t elf_use_ph) {
error err;
int fd_elf;
Elf *elf;
Expand Down Expand Up @@ -124,10 +187,18 @@ error elf_append(void *addr,
return ERROR_BOOTROM_ELF;
}

if ((err = elf_get_startaddr_endaddr(elf, &start_addr, &end_addr))) {
elf_end(elf);
close(fd_elf);
return err;
if (elf_use_ph) {
if ((err = elf_get_startaddr_endaddr_from_ph(elf, &start_addr, &end_addr))) {
elf_end(elf);
close(fd_elf);
return err;
}
} else {
if ((err = elf_get_startaddr_endaddr(elf, &start_addr, &end_addr))) {
elf_end(elf);
close(fd_elf);
return err;
}
}

if (end_addr - start_addr > img_max_size) {
Expand All @@ -138,10 +209,18 @@ error elf_append(void *addr,

memset(addr, 0, end_addr - start_addr);

if ((err = elf_create_image(elf, start_addr, addr))) {
elf_end(elf);
close(fd_elf);
return err;
if (elf_use_ph) {
if ((err = elf_create_image_from_ph(elf, start_addr, addr))) {
elf_end(elf);
close(fd_elf);
return err;
}
} else {
if ((err = elf_create_image(elf, start_addr, addr))) {
elf_end(elf);
close(fd_elf);
return err;
}
}

if (gelf_getehdr(elf, &elf_ehdr) != &elf_ehdr) {
Expand All @@ -159,4 +238,4 @@ error elf_append(void *addr,
close(fd_elf);

return SUCCESS;
}
}
3 changes: 2 additions & 1 deletion src/file/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ error elf_append(void *addr,
uint32_t *img_size,
uint8_t *elf_nbits,
uint32_t *elf_load,
uint32_t *elf_entry);
uint32_t *elf_entry,
uint8_t elf_use_ph);

#endif