Skip to content

Commit

Permalink
Handle .relr.dyn section
Browse files Browse the repository at this point in the history
  • Loading branch information
Coekjan committed Jul 2, 2024
1 parent 15a7c4d commit 87bdf2c
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 1 deletion.
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

0 comments on commit 87bdf2c

Please sign in to comment.