diff --git a/repos/base/src/lib/ldso/include/relocation_generic.h b/repos/base/src/lib/ldso/include/relocation_generic.h index 33d0ca2b4..4ba6a707b 100644 --- a/repos/base/src/lib/ldso/include/relocation_generic.h +++ b/repos/base/src/lib/ldso/include/relocation_generic.h @@ -31,7 +31,7 @@ extern "C" void _jmp_slot(void); namespace Linker { - struct Plt_got; + template struct Plt_got_generic; template class Reloc_jmpslot_generic; template struct Reloc_plt_generic; template struct Reloc_bind_now_generic; @@ -43,15 +43,15 @@ namespace Linker * Set 2nd and 3rd GOT entry (see: SYSTEM V APPLICATION BINARY INTERFACE * Intel386 Architecture Processor Supplement - 5.9 */ -struct Linker::Plt_got +template struct Linker::Plt_got_generic { - Plt_got(Dependency const &dep, Elf::Addr *pltgot) + Plt_got_generic(Dependency const &dep, Elf::Addr *pltgot) { if (verbose_relocation) log("OBJ: ", dep.obj().name(), " (", &dep, ")"); - pltgot[1] = (Elf::Addr) &dep; /* ELF object */ - pltgot[2] = (Elf::Addr) &_jmp_slot; /* Linker entry */ + pltgot[1] = (Elf::Addr) &dep; /* ELF object */ + pltgot[JUMP_INDEX] = (Elf::Addr) &_jmp_slot; /* Linker entry */ } }; diff --git a/repos/base/src/lib/ldso/spec/arm/relocation.h b/repos/base/src/lib/ldso/spec/arm/relocation.h index 5bf0396b1..1b4ffebb9 100644 --- a/repos/base/src/lib/ldso/spec/arm/relocation.h +++ b/repos/base/src/lib/ldso/spec/arm/relocation.h @@ -29,6 +29,7 @@ namespace Linker { class Reloc_non_plt; + typedef Plt_got_generic<2> Plt_got; typedef Reloc_plt_generic Reloc_plt; typedef Reloc_jmpslot_generic Reloc_jmpslot; typedef Reloc_bind_now_generic Reloc_bind_now; diff --git a/repos/base/src/lib/ldso/spec/riscv/jmp_slot.s b/repos/base/src/lib/ldso/spec/riscv/jmp_slot.s index 9610e9956..2bb865567 100644 --- a/repos/base/src/lib/ldso/spec/riscv/jmp_slot.s +++ b/repos/base/src/lib/ldso/spec/riscv/jmp_slot.s @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2015-2017 Genode Labs GmbH + * Copyright (C) 2015-2019 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -15,9 +15,49 @@ .globl _jmp_slot .type _jmp_slot,%function /* - * stack[0] = RA - * ip = &GOT[n+3] - * lr = &GOT[2] + * t0 = GOT[1] = Dependency + * t1 = PLT offset */ _jmp_slot: - jal jmp_slot + + /* stack frame */ + addi sp, sp, -(8*9) + + /* save arguments and return address */ + sd a0, (0)(sp) + sd a1, (1 * 8)(sp) + sd a2, (2 * 8)(sp) + sd a3, (3 * 8)(sp) + sd a4, (4 * 8)(sp) + sd a5, (5 * 8)(sp) + sd a6, (6 * 8)(sp) + sd a7, (7 * 8)(sp) + sd ra, (8 * 8)(sp) + + /* GOT[1] = Dependency */ + mv a0, t0 /* arg 0 */ + + /* calculate symbol index from PLT offset (index = offset / 8) */ + srli a1, t1, 3 /* arg 1 */ + + jal jmp_slot + + /* save address of function to call */ + mv t0, a0 + + /* restore arguments and return address */ + ld a0, (0)(sp) + ld a1, (1 * 8)(sp) + ld a2, (2 * 8)(sp) + ld a3, (3 * 8)(sp) + ld a4, (4 * 8)(sp) + ld a5, (5 * 8)(sp) + ld a6, (6 * 8)(sp) + ld a7, (7 * 8)(sp) + ld ra, (8 * 8)(sp) + + /* stack frame */ + addi sp, sp,(8*9) + + /* call function */ + jr t0 diff --git a/repos/base/src/lib/ldso/spec/riscv/relocation.h b/repos/base/src/lib/ldso/spec/riscv/relocation.h index 035bd9eb0..ca86d2fcf 100644 --- a/repos/base/src/lib/ldso/spec/riscv/relocation.h +++ b/repos/base/src/lib/ldso/spec/riscv/relocation.h @@ -38,6 +38,7 @@ namespace Linker { class Reloc_non_plt; + typedef Plt_got_generic<0> Plt_got; typedef Reloc_plt_generic Reloc_plt; typedef Reloc_jmpslot_generic Reloc_jmpslot; typedef Reloc_bind_now_generic Reloc_bind_now; @@ -87,9 +88,9 @@ class Linker::Reloc_non_plt : public Reloc_non_plt_generic log("LD: reloc: ", rel, " type: ", (int)rel->type()); switch(rel->type()) { - case R_JMPSLOT: _glob_dat_64(rel, addr, false); break; case R_64: _glob_dat_64(rel, addr, true); break; case R_RELATIVE: _relative(rel, addr); break; + case R_JMPSLOT: break; default: if (!_dep.obj().is_linker()) { diff --git a/repos/base/src/lib/ldso/spec/x86_32/relocation.h b/repos/base/src/lib/ldso/spec/x86_32/relocation.h index 4005717b2..0b01cf293 100644 --- a/repos/base/src/lib/ldso/spec/x86_32/relocation.h +++ b/repos/base/src/lib/ldso/spec/x86_32/relocation.h @@ -29,6 +29,7 @@ namespace Linker { class Reloc_non_plt; + typedef Plt_got_generic<2> Plt_got; typedef Reloc_plt_generic Reloc_plt; typedef Reloc_jmpslot_generic Reloc_jmpslot; typedef Reloc_bind_now_generic Reloc_bind_now; diff --git a/repos/base/src/lib/ldso/spec/x86_64/relocation.h b/repos/base/src/lib/ldso/spec/x86_64/relocation.h index 667e3a19e..a95f15c08 100644 --- a/repos/base/src/lib/ldso/spec/x86_64/relocation.h +++ b/repos/base/src/lib/ldso/spec/x86_64/relocation.h @@ -32,6 +32,7 @@ namespace Linker { class Reloc_non_plt; + typedef Plt_got_generic<2> Plt_got; typedef Reloc_plt_generic Reloc_plt; typedef Reloc_jmpslot_generic Reloc_jmpslot; typedef Reloc_bind_now_generic Reloc_bind_now;