rtld: add rudimentary support for procedure linkage tables (plt)

This commit is contained in:
John Törnblom committed 2024-12-27 21:24:56 +01:00
1 parent ae4ed3db5b
commit 74804c5bd9
6 files changed
+67 -10

No files matched your search

+8 -6
View File
@@ -20,12 +20,14 @@ along with this program; see the file COPYING. If not, see
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define DT_NULL 0
#define DT_NEEDED 1
#define DT_STRTAB 5
#define DT_SYMTAB 6
#define DT_RELA 7
#define DT_RELASZ 8
#define DT_NULL 0
#define DT_NEEDED 1
#define DT_PLTRELSZ 2
#define DT_STRTAB 5
#define DT_SYMTAB 6
#define DT_RELA 7
#define DT_RELASZ 8
#define DT_JMPREL 23
#define DT_GNU_HASH 0x6ffffef5
#define R_X86_64_64 1
+26 -1
View File
@@ -244,8 +244,10 @@ dynsym_count(unsigned int *gnu_hash) {
static int
payload_load(void) {
unsigned int *gnu_hash = 0;
unsigned long relasz = 0;
unsigned long pltsz = 0;
Elf64_Rela* rela = 0;
long relasz = 0;
Elf64_Rela* plt = 0;
// find lookup tables
for(int i=0; _DYNAMIC[i].d_tag!=DT_NULL; i++) {
@@ -269,6 +271,14 @@ payload_load(void) {
case DT_RELASZ:
relasz = _DYNAMIC[i].d_un.d_val;
break;
case DT_JMPREL:
plt = (Elf64_Rela*)(__image_start + _DYNAMIC[i].d_un.d_ptr);
break;
case DT_PLTRELSZ:
pltsz = _DYNAMIC[i].d_un.d_val;
break;
}
}
@@ -322,6 +332,21 @@ payload_load(void) {
}
}
for(int i=0; i<pltsz/sizeof(Elf64_Rela); i++) {
switch(plt[i].r_info & 0xffffffffl) {
case R_X86_64_JMP_SLOT:
if(r_jmp_slot(&plt[i])) {
return -1;
}
break;
default:
klog_printf("Unsupported plt type %x\n",
plt[i].r_info);
break;
}
}
return 0;
}
+24
View File
@@ -530,6 +530,15 @@ pt_dynamic(rtld_so_lib_t *lib, Elf64_Phdr *phdr) {
lib->strtab = (char*)(lib->image + lib->phdr->p_offset +
dyn[i].d_un.d_ptr);
break;
case DT_JMPREL:
lib->plt = (Elf64_Rela*)(lib->image + lib->phdr->p_offset +
dyn[i].d_un.d_ptr);
break;
case DT_PLTRELSZ:
lib->plt_size = dyn[i].d_un.d_val;
break;
}
}
@@ -643,6 +652,21 @@ so_load(rtld_so_lib_t* lib, const char* path) {
}
}
for(int i=0; i<lib->plt_size/sizeof(Elf64_Rela); i++) {
switch(lib->plt[i].r_info & 0xffffffffl) {
case R_X86_64_JMP_SLOT:
if(r_jmp_slot(lib, &lib->plt[i])) {
return -1;
}
break;
default:
klog_printf("Unsupported plt relocation type %x\n",
lib->plt[i].r_info);
break;
}
}
// set protection bits on mapped memory
for(int i=0; i<lib->ehdr->e_phnum && !error; i++) {
if(lib->phdr[i].p_type != PT_LOAD || lib->phdr[i].p_memsz == 0) {
+1 -1
View File
@@ -67,7 +67,7 @@ exec -a "${SCRIPT_NAME}" "${SCRIPT_DIR}/clang" \
-isystem "${PS5_PAYLOAD_SDK}/target/include" \
-L "${PS5_PAYLOAD_SDK}/target/lib" \
-L "${PS5_PAYLOAD_HBROOT}/lib" \
-fno-stack-protector -fno-plt -femulated-tls \
-fno-stack-protector -femulated-tls \
$LIBS_C \
--end-no-unused-arguments \
"$@" \
+1 -1
View File
@@ -73,7 +73,7 @@ exec -a "${SCRIPT_NAME}" "${SCRIPT_DIR}/clang++" \
-stdlib++-isystem "${PS5_PAYLOAD_SDK}/target/include/c++/v1" \
-L "${PS5_PAYLOAD_SDK}/target/lib" \
-L "${PS5_PAYLOAD_HBROOT}/lib" \
-fno-stack-protector -fno-plt -femulated-tls \
-fno-stack-protector -femulated-tls \
-frtti -fexceptions \
$LIBS_CXX $LIBS_C \
--end-no-unused-arguments \
+7 -1
View File
@@ -33,6 +33,8 @@ SECTIONS {
PROVIDE_HIDDEN (__text_end = .);
} : ph_text
.plt : { *(.plt) }
.rodata : ALIGN(CONSTANT(MAXPAGESIZE)) {
*(.rodata .rodata.*)
@@ -47,6 +49,8 @@ SECTIONS {
PROVIDE_HIDDEN(__fini_array_end = .);
} : ph_rodata
.gcc_except_table : { *(.gcc_except_table*) }
.eh_frame_hdr : ALIGN(CONSTANT(MAXPAGESIZE)) {
PROVIDE_HIDDEN(__eh_frame_hdr_start = .);
KEEP(*(.eh_frame_hdr))
@@ -59,7 +63,9 @@ SECTIONS {
PROVIDE_HIDDEN(__eh_frame_end = .);
}
.rela : { *(.rela *.rela.*) }
.data.rel.ro : { *(.data.rel.ro .data.rel.ro.*); }
.got : { *(.got) }
.got.plt : { *(.got.plt) }
.data : ALIGN(CONSTANT(MAXPAGESIZE)) {
*(.data .data.*)