summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/memlayout.h18
-rw-r--r--tests/Makefile.inc4
-rw-r--r--util/cbfstool/rmodule.c70
-rw-r--r--util/cbfstool/rmodule.h2
4 files changed, 56 insertions, 38 deletions
diff --git a/src/include/memlayout.h b/src/include/memlayout.h
index bf830b7d24..424a28a20a 100644
--- a/src/include/memlayout.h
+++ b/src/include/memlayout.h
@@ -31,7 +31,7 @@
#define SYMBOL(name, addr) \
SET_COUNTER(name, addr) \
- _##name = .;
+ _##name = ABSOLUTE(.);
#define REGION(name, addr, size, expected_align) \
SYMBOL(name, addr) \
@@ -40,8 +40,8 @@
SYMBOL(e##name, addr + size)
#define ALIAS_REGION(name, alias) \
- _##alias = _##name; \
- _e##alias = _e##name;
+ _##alias = ABSOLUTE(_##name); \
+ _e##alias = ABSOLUTE(_e##name); \
/* Declare according to SRAM/DRAM ranges in SoC hardware-defined address map. */
#define SRAM_START(addr) SYMBOL(sram, addr)
@@ -92,7 +92,7 @@
#if ENV_DECOMPRESSOR
#define DECOMPRESSOR(addr, sz) \
SYMBOL(decompressor, addr) \
- _edecompressor = _decompressor + sz; \
+ _edecompressor = ABSOLUTE(_decompressor + sz); \
_ = ASSERT(_eprogram - _program <= sz, \
STR(decompressor exceeded its allotted size! (sz))); \
INCLUDE "decompressor/lib/program.ld"
@@ -112,7 +112,7 @@
#if ENV_BOOTBLOCK
#define BOOTBLOCK(addr, sz) \
SYMBOL(bootblock, addr) \
- _ebootblock = _bootblock + sz; \
+ _ebootblock = ABSOLUTE(_bootblock + sz); \
_ = ASSERT(_eprogram - _program <= sz, \
STR(Bootblock exceeded its allotted size! (sz))); \
INCLUDE "bootblock/lib/program.ld"
@@ -124,7 +124,7 @@
#if ENV_ROMSTAGE
#define ROMSTAGE(addr, sz) \
SYMBOL(romstage, addr) \
- _eromstage = _romstage + sz; \
+ _eromstage = ABSOLUTE(_romstage + sz); \
_ = ASSERT(_eprogram - _program <= sz, \
STR(Romstage exceeded its allotted size! (sz))); \
INCLUDE "romstage/lib/program.ld"
@@ -136,7 +136,7 @@
#if ENV_RAMSTAGE
#define RAMSTAGE(addr, sz) \
SYMBOL(ramstage, addr) \
- _eramstage = _ramstage + sz; \
+ _eramstage = ABSOLUTE(_ramstage + sz); \
_ = ASSERT(_eprogram - _program <= sz, \
STR(Ramstage exceeded its allotted size! (sz))); \
INCLUDE "ramstage/lib/program.ld"
@@ -160,7 +160,7 @@
#if ENV_SEPARATE_VERSTAGE
#define VERSTAGE(addr, sz) \
SYMBOL(verstage, addr) \
- _everstage = _verstage + sz; \
+ _everstage = ABSOLUTE(_verstage + sz); \
_ = ASSERT(_eprogram - _program <= sz, \
STR(Verstage exceeded its allotted size! (sz))); \
INCLUDE "verstage/lib/program.ld"
@@ -179,7 +179,7 @@
#if ENV_POSTCAR
#define POSTCAR(addr, sz) \
SYMBOL(postcar, addr) \
- _epostcar = _postcar + sz; \
+ _epostcar = ABSOLUTE(_postcar + sz); \
_ = ASSERT(_eprogram - _program <= sz, \
STR(Aftercar exceeded its allotted size! (sz))); \
INCLUDE "postcar/lib/program.ld"
diff --git a/tests/Makefile.inc b/tests/Makefile.inc
index 56d557879e..a10e9bf73b 100644
--- a/tests/Makefile.inc
+++ b/tests/Makefile.inc
@@ -48,6 +48,10 @@ TEST_CFLAGS += -I$(cmockasrc)/include
TEST_LDFLAGS = -L$(cmockaobj)/src -lcmocka -Wl,-rpath=$(cmockaobj)/src
TEST_LDFLAGS += -Wl,--gc-sections
+# Some memlayout symbols don't work with userspace relocation -- disable it.
+TEST_CFLAGS += -fno-pie -fno-pic
+TEST_LDFLAGS += -no-pie
+
# Extra attributes for unit tests, declared per test
attributes:= srcs cflags mocks stage
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;