Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle .relr.dyn section #1626

Merged
merged 1 commit into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/elfs/elfload_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,18 @@ void DumpRelATable(elfheader_t *h, int cnt, Elf64_Rela *rela, const char* name)
}
}

void DumpRelRTable(elfheader_t *h, int cnt, Elf64_Relr *relr, const char *name)
{
if(box64_dump && h->relr) {
const char* elfname = ElfName(h);
printf_dump(LOG_NEVER, "ELF Dump %s Table(%d) @%p\n", name, cnt, relr);
for (int i = 0; i<cnt; ++i)
printf_dump(LOG_NEVER, " %s:%s[%d] = %p\n", elfname, name,
i, (void*)relr[i]);
printf_dump(LOG_NEVER, "ELF Dump %s Table=====\n", name);
}
}

void DumpBinary(char* p, int sz)
{
// dump p as
Expand Down
28 changes: 28 additions & 0 deletions src/elfs/elfloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,12 +784,40 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
}
return bindnow?ret_ok:0;
}

int RelocateElfRELR(elfheader_t *head, int cnt, Elf64_Relr *relr) {
Elf64_Addr *where = NULL;
for (int i = 0; i < cnt; i++) {
Elf64_Relr p = relr[i];
if ((p & 1) == 0) {
where = (Elf64_Addr *)(p + head->delta);
printf_dump(LOG_NEVER, "Apply (even) RELR %p -> %p\n", *where, *where + head->delta);
*where++ += head->delta;
} else {
for (long j = 0; (p >>= 1) != 0; j++)
if ((p & 1) != 0) {
printf_dump(LOG_NEVER, "Apply (odd) RELR %p -> %p\n", where[j], where[j] + head->delta);
where[j] += head->delta;
}
where += CHAR_BIT * sizeof(Elf64_Relr) - 1;
}
}
return 0;
}

int RelocateElf(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbind, elfheader_t* head)
{
if((head->flags&DF_BIND_NOW) && !bindnow) {
bindnow = 1;
printf_log(LOG_DEBUG, "Forcing %s to Bind Now\n", head->name);
}
if(head->relr) {
int cnt = head->relrsz / head->relrent;
DumpRelRTable(head, cnt, (Elf64_Relr *)(head->relr + head->delta), "RelR");
printf_dump(LOG_DEBUG, "Applying %d Relocation(s) without Addend for %s bindnow=%d, deepbind=%d\n", cnt, head->name, bindnow, deepbind);
if(RelocateElfRELR(head, cnt, (Elf64_Relr *)(head->relr + head->delta)))
return -1;
}
if(head->rel) {
int cnt = head->relsz / head->relent;
DumpRelTable(head, cnt, (Elf64_Rel *)(head->rel + head->delta), "Rel");
Expand Down
3 changes: 3 additions & 0 deletions src/elfs/elfloader_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ typedef struct elfheader_s {
uintptr_t rela;
size_t relasz;
int relaent;
uintptr_t relr;
size_t relrsz;
int relrent;
uintptr_t jmprel;
size_t pltsz;
int pltent;
Expand Down
9 changes: 9 additions & 0 deletions src/elfs/elfparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,15 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
case DT_RELAENT:
h->relaent = val;
break;
case DT_RELR:
h->relr = ptr;
break;
case DT_RELRSZ:
h->relrsz = val;
break;
case DT_RELRENT:
h->relrent = val;
break;
case DT_PLTGOT:
h->pltgot = ptr;
break;
Expand Down
2 changes: 1 addition & 1 deletion src/emu/x64int3.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
#include "wrapper.h"
#include "box64context.h"
#include "librarian.h"
#include "elfload_dump.h"
#include "signals.h"
#include "tools/bridge_private.h"

#include <elf.h>
#include "elfloader.h"
#include "elfload_dump.h"
#include "elfs/elfloader_private.h"

typedef int32_t (*iFpppp_t)(void*, void*, void*, void*);
Expand Down
1 change: 1 addition & 0 deletions src/include/elfload_dump.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ void DumpDynamicRPath(elfheader_t *h);
void DumpDynSym(elfheader_t *h);
void DumpRelTable(elfheader_t *h, int cnt, Elf64_Rel *rel, const char* name);
void DumpRelATable(elfheader_t *h, int cnt, Elf64_Rela *rela, const char* name);
void DumpRelRTable(elfheader_t *h, int cnt, Elf64_Relr *relr, const char *name);

void DumpBinary(char* p, int sz);

Expand Down
19 changes: 19 additions & 0 deletions src/include/elfloader.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef __ELF_LOADER_H_
#define __ELF_LOADER_H_
#include <stdio.h>
#include <elf.h>

typedef struct elfheader_s elfheader_t;
typedef struct lib_s lib_t;
Expand All @@ -14,6 +15,24 @@ typedef struct kh_defaultversion_s kh_defaultversion_t;
typedef struct dynablock_s dynablock_t;
#endif

// Define for handling .relr.dyn section (since glibc 2.36)
// See Also https://lists.gnu.org/archive/html/info-gnu/2022-08/msg00000.html
//
// if glibc 2.36 is widely used in the future, this part can be removed
#ifndef DT_RELR

// Copy from (glibc 2.36) elf.h

#define SHT_RELR 19 /* RELR relative relocations */

typedef Elf32_Word Elf32_Relr;
typedef Elf64_Xword Elf64_Relr;

#define DT_RELRSZ 35 /* Total size of RELR relative relocations */
#define DT_RELR 36 /* Address of RELR relative relocations */
#define DT_RELRENT 37 /* Size of one RELR relative relocaction */
#endif // DT_RELR

// Open an elfheader. Transfert control of f to elfheader also!
elfheader_t* LoadAndCheckElfHeader(FILE* f, const char* name, int exec); // exec : 0 = lib, 1 = exec
void FreeElfHeader(elfheader_t** head);
Expand Down