diff --git a/arch/x86_64/include/elf.h b/arch/x86_64/include/elf.h index f4c87f1402..0019cd05d5 100644 --- a/arch/x86_64/include/elf.h +++ b/arch/x86_64/include/elf.h @@ -25,13 +25,14 @@ * Pre-processor Prototypes ****************************************************************************/ -#define R_X86_64_NONE 0 -#define R_X86_64_64 1 -#define R_X86_64_PC32 2 -#define R_X86_64_PLT32 4 -#define R_X86_64_32 10 -#define R_X86_64_32S 11 -#define R_X86_64_PC64 24 +#define R_X86_64_NONE 0 +#define R_X86_64_64 1 +#define R_X86_64_PC32 2 +#define R_X86_64_PLT32 4 +#define R_X86_64_32 10 +#define R_X86_64_32S 11 +#define R_X86_64_PC64 24 +#define R_X86_64_REX_GOTPCRELX 42 /* 4.3.1 ELF Identification. Should have: * diff --git a/libs/libc/machine/x86_64/arch_elf64.c b/libs/libc/machine/x86_64/arch_elf64.c index 7dad5fb70c..7da06ed0d1 100644 --- a/libs/libc/machine/x86_64/arch_elf64.c +++ b/libs/libc/machine/x86_64/arch_elf64.c @@ -37,6 +37,13 @@ #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define OPCODE_MOV 0x8b +#define OPCODE_LEA 0x8d + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -174,6 +181,26 @@ int up_relocateadd(const Elf64_Rela *rel, const Elf64_Sym *sym, *(uint32_t *)addr = value; break; +#ifdef CONFIG_ARCH_ADDRENV + case R_X86_64_REX_GOTPCRELX: + + /* Handle like R_X86_64_PC32 but with load offset */ + + value = (sym->st_value + rel->r_addend - addr + + CONFIG_ARCH_TEXT_VBASE); + + /* Convert MOV to LEA - other relocations not suported */ + + if (*(uint8_t *)(addr - 2) != OPCODE_MOV) + { + berr("ERROR: not supported REX_GOTPCRELX relocation\n"); + return -EINVAL; + } + + *(uint8_t *)(addr - 2) = OPCODE_LEA; + *(uint32_t *)(addr) = value; + break; +#endif default: berr("ERROR: Unsupported relocation: %d\n", relotype); return -EINVAL;