tools: relocate-rela: Add M68K support

Add M68K ELF32 support into this tool, so it can patch static rela
into M68K u-boot-nodtb.bin . This is the first step toward M68K
relocation support, and in turn, removal of NEEDS_MANUAL_RELOC
from the codebase altogether.

Tested-by: Michal Simek <michal.simek@amd.com> # microblaze, arm64
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
This commit is contained in:
Marek Vasut 2023-08-27 00:25:35 +02:00 committed by Angelo Dureghello
parent 0ad3eef381
commit bf10b9201c

View file

@ -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;
@ -111,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");
@ -245,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");
@ -262,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);
@ -488,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)
@ -569,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",
@ -585,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;
@ -632,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);