optimization for elfloader
use a rel/rela section's sh_info to resolve which section this rel will be applied to, rather than the section's name
This commit is contained in:
@@ -29,7 +29,7 @@
|
||||
#include "tos_elfloader_relocate.h"
|
||||
|
||||
typedef struct el_section_st {
|
||||
uint8_t shndx;
|
||||
int8_t shndx;
|
||||
void *address;
|
||||
} el_section_t;
|
||||
|
||||
|
@@ -36,7 +36,7 @@ __STATIC__ void *local_symtab_lookup(int fd, char *sym_name,
|
||||
if (sym.st_name) {
|
||||
if (elfloader_fd_read(fd, strtab_offset + sym.st_name, name, sizeof(name)) != ELFLOADER_ERR_NONE) {
|
||||
return K_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(name, sym_name) == 0) {
|
||||
if (sym.st_shndx == bss.shndx && bss.address) {
|
||||
@@ -152,19 +152,16 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
|
||||
el_err_t err;
|
||||
elf32_ehdr_t ehdr;
|
||||
elf32_shdr_t shdr;
|
||||
elf32_shdr_t shstrtab;
|
||||
|
||||
static el_section_t bss, data, rodata, text;
|
||||
|
||||
#define SECTION_NAME_MAX 20
|
||||
static char section_name[SECTION_NAME_MAX];
|
||||
static el_section_t bss = { -1, K_NULL };
|
||||
static el_section_t data = { -1, K_NULL };
|
||||
static el_section_t rodata = { -1, K_NULL };
|
||||
static el_section_t text = { -1, K_NULL };
|
||||
|
||||
void *base = K_NULL, *addr_sec2cp; /* ram base for LOAD sections */
|
||||
|
||||
uint32_t shdr_offset;
|
||||
|
||||
uint32_t shstrtab_offset;
|
||||
|
||||
uint32_t strtab_offset, strtab_size = 0;
|
||||
uint32_t symtab_offset, symtab_size = 0, symtab_entsize;
|
||||
|
||||
@@ -202,13 +199,6 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
|
||||
return ELFLOADER_ERR_TYPE_INVALID;
|
||||
}
|
||||
|
||||
if (elfloader_fd_read(fd, ehdr.e_shoff + ehdr.e_shentsize * ehdr.e_shstrndx,
|
||||
&shstrtab, ehdr.e_shentsize) != ELFLOADER_ERR_NONE) {
|
||||
return ELFLOADER_ERR_FD_READ_FAILED;
|
||||
}
|
||||
|
||||
shstrtab_offset = shstrtab.sh_offset;
|
||||
|
||||
shdr_offset = ehdr.e_shoff;
|
||||
|
||||
for (i = 0; i < ehdr.e_shnum; ++i) {
|
||||
@@ -216,10 +206,6 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
|
||||
return ELFLOADER_ERR_FD_READ_FAILED;
|
||||
}
|
||||
|
||||
if (elfloader_fd_read(fd, shstrtab_offset + shdr.sh_name, section_name, sizeof(section_name)) != ELFLOADER_ERR_NONE) {
|
||||
return ELFLOADER_ERR_FD_READ_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
|-----------------------------------------------------|
|
||||
| Name | sh_type | sh_flag |
|
||||
@@ -258,38 +244,34 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
|
||||
text_size = shdr.sh_size;
|
||||
|
||||
text.shndx = i;
|
||||
} else if (shdr.sh_type == SHT_REL &&
|
||||
strncmp(".rel.data", section_name, 9) == 0) {
|
||||
rel_data_offset = shdr.sh_offset;
|
||||
rel_data_size = shdr.sh_size;
|
||||
rel_data_entsize = shdr.sh_entsize;
|
||||
} else if (shdr.sh_type == SHT_RELA &&
|
||||
strncmp(".rela.data", section_name, 10) == 0) {
|
||||
rela_data_offset = shdr.sh_offset;
|
||||
rela_data_size = shdr.sh_size;
|
||||
rela_data_entsize = shdr.sh_entsize;
|
||||
} else if (shdr.sh_type == SHT_REL &&
|
||||
(strncmp(".rel.rodata", section_name, 11) == 0 ||
|
||||
strncmp(".rel.constdata", section_name, 14) == 0)) {
|
||||
rel_rodata_offset = shdr.sh_offset;
|
||||
rel_rodata_size = shdr.sh_size;
|
||||
rel_rodata_entsize = shdr.sh_entsize;
|
||||
} else if (shdr.sh_type == SHT_RELA &&
|
||||
(strncmp(".rela.rodata", section_name, 12) == 0 ||
|
||||
strncmp(".rela.constdata", section_name, 15) == 0)) {
|
||||
rela_rodata_offset = shdr.sh_offset;
|
||||
rela_rodata_size = shdr.sh_size;
|
||||
rela_rodata_entsize = shdr.sh_entsize;
|
||||
} else if (shdr.sh_type == SHT_REL &&
|
||||
strncmp(".rel.text", section_name, 9) == 0) {
|
||||
rel_text_offset = shdr.sh_offset;
|
||||
rel_text_size = shdr.sh_size;
|
||||
rel_text_entsize = shdr.sh_entsize;
|
||||
} else if (shdr.sh_type == SHT_RELA &&
|
||||
strncmp(".rela.text", section_name, 10) == 0) {
|
||||
rela_text_offset = shdr.sh_offset;
|
||||
rela_text_size = shdr.sh_size;
|
||||
rela_text_entsize = shdr.sh_entsize;
|
||||
} else if (shdr.sh_type == SHT_REL) {
|
||||
if (shdr.sh_info == data.shndx) {
|
||||
rel_data_offset = shdr.sh_offset;
|
||||
rel_data_size = shdr.sh_size;
|
||||
rel_data_entsize = shdr.sh_entsize;
|
||||
} else if (shdr.sh_info == rodata.shndx) {
|
||||
rel_rodata_offset = shdr.sh_offset;
|
||||
rel_rodata_size = shdr.sh_size;
|
||||
rel_rodata_entsize = shdr.sh_entsize;
|
||||
} else if (shdr.sh_info == text.shndx) {
|
||||
rel_text_offset = shdr.sh_offset;
|
||||
rel_text_size = shdr.sh_size;
|
||||
rel_text_entsize = shdr.sh_entsize;
|
||||
}
|
||||
} else if (shdr.sh_type == SHT_RELA) {
|
||||
if (shdr.sh_info == data.shndx) {
|
||||
rela_data_offset = shdr.sh_offset;
|
||||
rela_data_size = shdr.sh_size;
|
||||
rela_data_entsize = shdr.sh_entsize;
|
||||
} else if (shdr.sh_info == rodata.shndx) {
|
||||
rela_rodata_offset = shdr.sh_offset;
|
||||
rela_rodata_size = shdr.sh_size;
|
||||
rela_rodata_entsize = shdr.sh_entsize;
|
||||
} else if (shdr.sh_info == text.shndx) {
|
||||
rela_text_offset = shdr.sh_offset;
|
||||
rela_text_size = shdr.sh_size;
|
||||
rela_text_entsize = shdr.sh_entsize;
|
||||
}
|
||||
}
|
||||
|
||||
shdr_offset += ehdr.e_shentsize;
|
||||
@@ -343,11 +325,13 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
|
||||
addr_sec2cp = (void *)((uint32_t)addr_sec2cp + data_size);
|
||||
}
|
||||
|
||||
/* clear bss */
|
||||
if (bss_size > 0) {
|
||||
bss.address = addr_sec2cp;
|
||||
memset(bss.address, 0, bss_size);
|
||||
}
|
||||
|
||||
/* do relocation */
|
||||
if (rel_data_size > 0) {
|
||||
err = elfloader_relocate(fd, data.address,
|
||||
bss, data, rodata, text,
|
||||
|
@@ -289,6 +289,7 @@ __API__ el_err_t tos_elfloader_load(el_module_t *module, int fd)
|
||||
phdr_offset += ehdr.e_phentsize;
|
||||
}
|
||||
|
||||
/* do relocation */
|
||||
if (rel_dyn_size > 0) {
|
||||
err = elfloader_relocate(fd, load_bias,
|
||||
rel_dyn_offset, rel_dyn_size, rel_entsize,
|
||||
|
Reference in New Issue
Block a user