aboutsummaryrefslogtreecommitdiff
path: root/tools/relocate-rela.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-10-02 10:55:44 -0400
committerTom Rini <trini@konsulko.com>2023-10-02 10:55:44 -0400
commitac897385bbfa30cfdfb62ccf24acfcd4b274b2ff (patch)
treeae567980737beb24ca24e2ee8cfeaf6eb9e26e3f /tools/relocate-rela.c
parent4459ed60cb1e0562bc5b40405e2b4b9bbf766d57 (diff)
parente29b932aa07fa0226d325b35d96cd4eea0370129 (diff)
downloadu-boot-ac897385bbfa30cfdfb62ccf24acfcd4b274b2ff.zip
u-boot-ac897385bbfa30cfdfb62ccf24acfcd4b274b2ff.tar.gz
u-boot-ac897385bbfa30cfdfb62ccf24acfcd4b274b2ff.tar.bz2
Merge branch 'next'
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'tools/relocate-rela.c')
-rw-r--r--tools/relocate-rela.c134
1 files changed, 99 insertions, 35 deletions
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c
index f230ec5..613abd2 100644
--- a/tools/relocate-rela.c
+++ b/tools/relocate-rela.c
@@ -24,6 +24,30 @@
#define R_AARCH64_RELATIVE 1027
#endif
+#ifndef EM_M68K
+#define EM_M68K 4
+#endif
+
+#ifndef R_68K_NONE
+#define R_68K_NONE 0
+#endif
+
+#ifndef R_68K_32
+#define R_68K_32 1
+#endif
+
+#ifndef R_68K_GLOB_DAT
+#define R_68K_GLOB_DAT 20
+#endif
+
+#ifndef R_68K_JMP_SLOT
+#define R_68K_JMP_SLOT 21
+#endif
+
+#ifndef R_68K_RELATIVE
+#define R_68K_RELATIVE 22
+#endif
+
#ifndef EM_MICROBLAZE
#define EM_MICROBLAZE 189
#endif
@@ -46,6 +70,7 @@
static int ei_class;
static int ei_data;
+static int machine;
static uint64_t rela_start, rela_end, text_base, dyn_start;
@@ -78,6 +103,14 @@ static uint32_t elf32_to_cpu(uint32_t data)
return be32_to_cpu(data);
}
+static uint32_t cpu_to_elf32(uint32_t data)
+{
+ if (ei_data == ELFDATA2LSB)
+ return cpu_to_le32(data);
+
+ return cpu_to_be32(data);
+}
+
static bool supported_rela(Elf64_Rela *rela)
{
uint64_t mask = 0xffffffffULL; /* would be different on 32-bit */
@@ -103,7 +136,7 @@ static int decode_elf64(FILE *felf, char **argv)
uint64_t sh_addr, sh_offset, sh_size;
Elf64_Half sh_index, sh_num;
Elf64_Shdr *sh_table; /* Elf symbol table */
- int ret, i, machine;
+ int ret, i;
char *sh_str;
debug("64bit version\n");
@@ -237,7 +270,7 @@ static int decode_elf32(FILE *felf, char **argv)
uint32_t sh_addr, sh_offset, sh_size;
Elf32_Half sh_index, sh_num;
Elf32_Shdr *sh_table; /* Elf symbol table */
- int ret, i, machine;
+ int ret, i;
char *sh_str;
debug("32bit version\n");
@@ -254,12 +287,20 @@ static int decode_elf32(FILE *felf, char **argv)
machine = elf16_to_cpu(header.e_machine);
debug("Machine %d\n", machine);
- if (machine != EM_MICROBLAZE) {
+ if (machine != EM_MICROBLAZE && machine != EM_M68K) {
fprintf(stderr, "%s: Not supported machine type\n", argv[0]);
return 30;
}
text_base = elf32_to_cpu(header.e_entry);
+ /*
+ * M68K ELF entry point is MONITOR_BASE, not TEXT_BASE.
+ * TEXT_BASE is always MONITOR_BASE &~ 0x7ff, so clear
+ * those bits here.
+ */
+ if (machine == EM_M68K)
+ text_base &= ~0x7ff;
+
section_header_base = elf32_to_cpu(header.e_shoff);
section_header_size = elf16_to_cpu(header.e_shentsize) *
elf16_to_cpu(header.e_shnum);
@@ -480,25 +521,44 @@ static bool supported_rela32(Elf32_Rela *rela, uint32_t *type)
debug("Type:\t");
- switch (*type) {
- case R_MICROBLAZE_32:
- debug("R_MICROBLAZE_32\n");
- return true;
- case R_MICROBLAZE_GLOB_DAT:
- debug("R_MICROBLAZE_GLOB_DAT\n");
- return true;
- case R_MICROBLAZE_NONE:
- debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
- return false;
- case R_MICROBLAZE_REL:
- debug("R_MICROBLAZE_REL\n");
- return true;
- default:
- fprintf(stderr, "warning: unsupported relocation type %"
- PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);
-
- return false;
+ if (machine == EM_M68K) {
+ switch (*type) {
+ case R_68K_32:
+ debug("R_68K_32\n");
+ return true;
+ case R_68K_GLOB_DAT:
+ debug("R_68K_GLOB_DAT\n");
+ return true;
+ case R_68K_JMP_SLOT:
+ debug("R_68K_JMP_SLOT\n");
+ return true;
+ case R_68K_NONE:
+ debug("R_68K_NONE - ignoring - do nothing\n");
+ return false;
+ case R_68K_RELATIVE:
+ debug("R_68K_RELATIVE\n");
+ return true;
+ }
+ } else {
+ switch (*type) {
+ case R_MICROBLAZE_32:
+ debug("R_MICROBLAZE_32\n");
+ return true;
+ case R_MICROBLAZE_GLOB_DAT:
+ debug("R_MICROBLAZE_GLOB_DAT\n");
+ return true;
+ case R_MICROBLAZE_NONE:
+ debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
+ return false;
+ case R_MICROBLAZE_REL:
+ debug("R_MICROBLAZE_REL\n");
+ return true;
+ }
}
+ fprintf(stderr, "warning: unsupported relocation type %"
+ PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);
+
+ return false;
}
static int rela_elf32(char **argv, FILE *f)
@@ -561,8 +621,8 @@ static int rela_elf32(char **argv, FILE *f)
debug("Addr:\t0x%" PRIx32 "\n", addr);
- switch (type) {
- case R_MICROBLAZE_REL:
+ if ((machine == EM_M68K && type == R_68K_RELATIVE) ||
+ (machine == EM_MICROBLAZE && type == R_MICROBLAZE_REL)) {
if (fseek(f, addr, SEEK_SET) < 0) {
fprintf(stderr, "%s: %s: seek to %"
PRIx32 " failed: %s\n",
@@ -577,9 +637,12 @@ static int rela_elf32(char **argv, FILE *f)
argv[0], argv[1], addr);
return 4;
}
- break;
- case R_MICROBLAZE_32:
- case R_MICROBLAZE_GLOB_DAT:
+ } else if ((machine == EM_M68K &&
+ (type == R_68K_32 || type == R_68K_GLOB_DAT ||
+ type == R_68K_JMP_SLOT)) ||
+ (machine == EM_MICROBLAZE &&
+ (type == R_MICROBLAZE_32 ||
+ type == R_MICROBLAZE_GLOB_DAT))) {
/* global symbols read it and add reloc offset */
index = swrela.r_info >> 8;
pos_dyn = dyn_start + sizeof(Elf32_Sym) * index;
@@ -602,14 +665,16 @@ static int rela_elf32(char **argv, FILE *f)
}
debug("Symbol description:\n");
- debug(" st_name:\t0x%x\n", symbols.st_name);
- debug(" st_value:\t0x%x\n", symbols.st_value);
- debug(" st_size:\t0x%x\n", symbols.st_size);
+ debug(" st_name:\t0x%x\n", elf32_to_cpu(symbols.st_name));
+ debug(" st_value:\t0x%x\n", elf32_to_cpu(symbols.st_value));
+ debug(" st_size:\t0x%x\n", elf32_to_cpu(symbols.st_size));
- value = swrela.r_addend + symbols.st_value;
+ value = swrela.r_addend + elf32_to_cpu(symbols.st_value);
debug("Value:\t0x%x\n", value);
+ value = cpu_to_elf32(value);
+
if (fseek(f, addr, SEEK_SET) < 0) {
fprintf(stderr, "%s: %s: seek to %"
PRIx32 " failed: %s\n",
@@ -622,12 +687,11 @@ static int rela_elf32(char **argv, FILE *f)
argv[0], argv[1], addr);
return 4;
}
-
- break;
- case R_MICROBLAZE_NONE:
+ } else if (machine == EM_M68K && type == R_68K_NONE) {
+ debug("R_68K_NONE - skip\n");
+ } else if (machine == EM_MICROBLAZE && type == R_MICROBLAZE_NONE) {
debug("R_MICROBLAZE_NONE - skip\n");
- break;
- default:
+ } else {
fprintf(stderr, "warning: unsupported relocation type %"
PRIu32 " at %" PRIx32 "\n",
type, rela.r_offset);