summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/cbfstool/rmodule.c70
-rw-r--r--util/cbfstool/rmodule.h2
2 files changed, 43 insertions, 29 deletions
diff --git a/util/cbfstool/rmodule.c b/util/cbfstool/rmodule.c
index 429bbf37fb..258a4d8803 100644
--- a/util/cbfstool/rmodule.c
+++ b/util/cbfstool/rmodule.c
@@ -72,7 +72,7 @@ static int valid_reloc_arm(Elf64_Rela *rel)
/* Only these 6 relocations are expected to be found. */
return (type == R_ARM_ABS32 || type == R_ARM_THM_PC22 ||
- type == R_ARM_THM_JUMP24 || type == R_ARM_V4BX ||
+ type == R_ARM_THM_JUMP24 || type == R_ARM_V4BX ||
type == R_ARM_CALL || type == R_ARM_JUMP24);
}
@@ -137,6 +137,19 @@ static const struct arch_ops reloc_ops[] = {
},
};
+static int relocation_for_absolute_symbol(struct rmod_context *ctx, Elf64_Rela *r)
+{
+ Elf64_Sym *s = &ctx->pelf.syms[ELF64_R_SYM(r->r_info)];
+
+ if (s->st_shndx == SHN_ABS) {
+ DEBUG("Omitting relocation for absolute symbol: %s\n",
+ &ctx->strtab[s->st_name]);
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* Relocation processing loops.
*/
@@ -172,6 +185,9 @@ static int for_each_reloc(struct rmod_context *ctx, struct reloc_filter *f,
return -1;
}
+ if (relocation_for_absolute_symbol(ctx, r))
+ continue;
+
/* Allow the provided filter to have precedence. */
if (f != NULL) {
filter_emit = f->filter(f, r);
@@ -341,7 +357,7 @@ int rmodule_collect_relocations(struct rmod_context *ctx,
static int
populate_sym(struct rmod_context *ctx, const char *sym_name, Elf64_Addr *addr,
- int nsyms, const char *strtab, int optional)
+ int nsyms, int optional)
{
int i;
Elf64_Sym *syms;
@@ -351,7 +367,7 @@ populate_sym(struct rmod_context *ctx, const char *sym_name, Elf64_Addr *addr,
for (i = 0; i < nsyms; i++) {
if (syms[i].st_name == 0)
continue;
- if (strcmp(sym_name, &strtab[syms[i].st_name]))
+ if (strcmp(sym_name, &ctx->strtab[syms[i].st_name]))
continue;
DEBUG("%s -> 0x%llx\n", sym_name, (long long)syms[i].st_value);
*addr = syms[i].st_value;
@@ -371,7 +387,6 @@ populate_sym(struct rmod_context *ctx, const char *sym_name, Elf64_Addr *addr,
static int populate_rmodule_info(struct rmod_context *ctx)
{
int i;
- const char *strtab;
struct parsed_elf *pelf;
Elf64_Ehdr *ehdr;
int nsyms;
@@ -379,23 +394,6 @@ static int populate_rmodule_info(struct rmod_context *ctx)
pelf = &ctx->pelf;
ehdr = &pelf->ehdr;
- /* Obtain the string table. */
- strtab = NULL;
- for (i = 0; i < ehdr->e_shnum; i++) {
- if (ctx->pelf.strtabs[i] == NULL)
- continue;
- /* Don't use the section headers' string table. */
- if (i == ehdr->e_shstrndx)
- continue;
- strtab = buffer_get(ctx->pelf.strtabs[i]);
- break;
- }
-
- if (strtab == NULL) {
- ERROR("No string table found.\n");
- return -1;
- }
-
/* Determine number of symbols. */
nsyms = 0;
for (i = 0; i < ehdr->e_shnum; i++) {
@@ -406,18 +404,16 @@ static int populate_rmodule_info(struct rmod_context *ctx)
break;
}
- if (populate_sym(ctx, "_rmodule_params", &ctx->parameters_begin,
- nsyms, strtab, 1))
+ if (populate_sym(ctx, "_rmodule_params", &ctx->parameters_begin, nsyms, 1))
return -1;
- if (populate_sym(ctx, "_ermodule_params", &ctx->parameters_end,
- nsyms, strtab, 1))
+ if (populate_sym(ctx, "_ermodule_params", &ctx->parameters_end, nsyms, 1))
return -1;
- if (populate_sym(ctx, "_bss", &ctx->bss_begin, nsyms, strtab, 0))
+ if (populate_sym(ctx, "_bss", &ctx->bss_begin, nsyms, 0))
return -1;
- if (populate_sym(ctx, "_ebss", &ctx->bss_end, nsyms, strtab, 0))
+ if (populate_sym(ctx, "_ebss", &ctx->bss_end, nsyms, 0))
return -1;
return 0;
@@ -425,7 +421,7 @@ static int populate_rmodule_info(struct rmod_context *ctx)
static int
add_section(struct elf_writer *ew, struct buffer *data, const char *name,
- Elf64_Addr addr, Elf64_Word size)
+ Elf64_Addr addr, Elf64_Word size)
{
Elf64_Shdr shdr;
int ret;
@@ -452,7 +448,7 @@ add_section(struct elf_writer *ew, struct buffer *data, const char *name,
static int
write_elf(const struct rmod_context *ctx, const struct buffer *in,
- struct buffer *out)
+ struct buffer *out)
{
int ret;
int bit64;
@@ -658,6 +654,22 @@ int rmodule_init(struct rmod_context *ctx, const struct buffer *elfin)
else
ctx->xdr = &xdr_le;
+ /* Obtain the string table. */
+ for (i = 0; i < pelf->ehdr.e_shnum; i++) {
+ if (pelf->strtabs[i] == NULL)
+ continue;
+ /* Don't use the section headers' string table. */
+ if (i == pelf->ehdr.e_shstrndx)
+ continue;
+ ctx->strtab = buffer_get(pelf->strtabs[i]);
+ break;
+ }
+
+ if (ctx->strtab == NULL) {
+ ERROR("No string table found.\n");
+ return -1;
+ }
+
if (find_program_segment(ctx))
goto out;
diff --git a/util/cbfstool/rmodule.h b/util/cbfstool/rmodule.h
index a62562b98f..ec0971e27e 100644
--- a/util/cbfstool/rmodule.h
+++ b/util/cbfstool/rmodule.h
@@ -29,6 +29,8 @@ struct rmod_context {
struct parsed_elf pelf;
/* Program segment. */
Elf64_Phdr *phdr;
+ /* Symbol string table. */
+ char *strtab;
/* Collection of relocation addresses fixup in the module. */
Elf64_Xword nrelocs;