ldso: lazy binding support for RISC-V
* added assembler invocation path for jump slot relocations * fix GOT initialization (jmp_slot pointer goes to GOT[0] not GOT[2] on RISC-V) Fixes #3339
This commit is contained in:
parent
4f0b17a4dc
commit
467b96abf4
|
@ -31,7 +31,7 @@ extern "C" void _jmp_slot(void);
|
||||||
|
|
||||||
namespace Linker
|
namespace Linker
|
||||||
{
|
{
|
||||||
struct Plt_got;
|
template <unsigned JUMP_INDEX = 2> struct Plt_got_generic;
|
||||||
template <typename REL, unsigned TYPE, bool DIV> class Reloc_jmpslot_generic;
|
template <typename REL, unsigned TYPE, bool DIV> class Reloc_jmpslot_generic;
|
||||||
template <typename REL, unsigned TYPE, unsigned JMPSLOT> struct Reloc_plt_generic;
|
template <typename REL, unsigned TYPE, unsigned JMPSLOT> struct Reloc_plt_generic;
|
||||||
template <typename REL, unsigned TYPE> struct Reloc_bind_now_generic;
|
template <typename REL, unsigned TYPE> struct Reloc_bind_now_generic;
|
||||||
|
@ -43,15 +43,15 @@ namespace Linker
|
||||||
* Set 2nd and 3rd GOT entry (see: SYSTEM V APPLICATION BINARY INTERFACE
|
* Set 2nd and 3rd GOT entry (see: SYSTEM V APPLICATION BINARY INTERFACE
|
||||||
* Intel386 Architecture Processor Supplement - 5.9
|
* Intel386 Architecture Processor Supplement - 5.9
|
||||||
*/
|
*/
|
||||||
struct Linker::Plt_got
|
template <unsigned JUMP_INDEX> 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)
|
if (verbose_relocation)
|
||||||
log("OBJ: ", dep.obj().name(), " (", &dep, ")");
|
log("OBJ: ", dep.obj().name(), " (", &dep, ")");
|
||||||
|
|
||||||
pltgot[1] = (Elf::Addr) &dep; /* ELF object */
|
pltgot[1] = (Elf::Addr) &dep; /* ELF object */
|
||||||
pltgot[2] = (Elf::Addr) &_jmp_slot; /* Linker entry */
|
pltgot[JUMP_INDEX] = (Elf::Addr) &_jmp_slot; /* Linker entry */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace Linker {
|
||||||
|
|
||||||
class Reloc_non_plt;
|
class Reloc_non_plt;
|
||||||
|
|
||||||
|
typedef Plt_got_generic<2> Plt_got;
|
||||||
typedef Reloc_plt_generic<Elf::Rel, DT_REL, R_JMPSLOT> Reloc_plt;
|
typedef Reloc_plt_generic<Elf::Rel, DT_REL, R_JMPSLOT> Reloc_plt;
|
||||||
typedef Reloc_jmpslot_generic<Elf::Rel, DT_REL, false> Reloc_jmpslot;
|
typedef Reloc_jmpslot_generic<Elf::Rel, DT_REL, false> Reloc_jmpslot;
|
||||||
typedef Reloc_bind_now_generic<Elf::Rel, DT_REL> Reloc_bind_now;
|
typedef Reloc_bind_now_generic<Elf::Rel, DT_REL> Reloc_bind_now;
|
||||||
|
|
|
@ -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
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
@ -15,9 +15,49 @@
|
||||||
.globl _jmp_slot
|
.globl _jmp_slot
|
||||||
.type _jmp_slot,%function
|
.type _jmp_slot,%function
|
||||||
/*
|
/*
|
||||||
* stack[0] = RA
|
* t0 = GOT[1] = Dependency
|
||||||
* ip = &GOT[n+3]
|
* t1 = PLT offset
|
||||||
* lr = &GOT[2]
|
|
||||||
*/
|
*/
|
||||||
_jmp_slot:
|
_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
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace Linker {
|
||||||
|
|
||||||
class Reloc_non_plt;
|
class Reloc_non_plt;
|
||||||
|
|
||||||
|
typedef Plt_got_generic<0> Plt_got;
|
||||||
typedef Reloc_plt_generic<Elf::Rela, DT_RELA, R_JMPSLOT> Reloc_plt;
|
typedef Reloc_plt_generic<Elf::Rela, DT_RELA, R_JMPSLOT> Reloc_plt;
|
||||||
typedef Reloc_jmpslot_generic<Elf::Rela, DT_RELA, false> Reloc_jmpslot;
|
typedef Reloc_jmpslot_generic<Elf::Rela, DT_RELA, false> Reloc_jmpslot;
|
||||||
typedef Reloc_bind_now_generic<Elf::Rela, DT_RELA> Reloc_bind_now;
|
typedef Reloc_bind_now_generic<Elf::Rela, DT_RELA> 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());
|
log("LD: reloc: ", rel, " type: ", (int)rel->type());
|
||||||
|
|
||||||
switch(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_64: _glob_dat_64(rel, addr, true); break;
|
||||||
case R_RELATIVE: _relative(rel, addr); break;
|
case R_RELATIVE: _relative(rel, addr); break;
|
||||||
|
case R_JMPSLOT: break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (!_dep.obj().is_linker()) {
|
if (!_dep.obj().is_linker()) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace Linker {
|
||||||
|
|
||||||
class Reloc_non_plt;
|
class Reloc_non_plt;
|
||||||
|
|
||||||
|
typedef Plt_got_generic<2> Plt_got;
|
||||||
typedef Reloc_plt_generic<Elf::Rel, DT_REL, R_JMPSLOT> Reloc_plt;
|
typedef Reloc_plt_generic<Elf::Rel, DT_REL, R_JMPSLOT> Reloc_plt;
|
||||||
typedef Reloc_jmpslot_generic<Elf::Rel, DT_REL, true> Reloc_jmpslot;
|
typedef Reloc_jmpslot_generic<Elf::Rel, DT_REL, true> Reloc_jmpslot;
|
||||||
typedef Reloc_bind_now_generic<Elf::Rel, DT_REL> Reloc_bind_now;
|
typedef Reloc_bind_now_generic<Elf::Rel, DT_REL> Reloc_bind_now;
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace Linker {
|
||||||
|
|
||||||
class Reloc_non_plt;
|
class Reloc_non_plt;
|
||||||
|
|
||||||
|
typedef Plt_got_generic<2> Plt_got;
|
||||||
typedef Reloc_plt_generic<Elf::Rela, DT_RELA, R_JMPSLOT> Reloc_plt;
|
typedef Reloc_plt_generic<Elf::Rela, DT_RELA, R_JMPSLOT> Reloc_plt;
|
||||||
typedef Reloc_jmpslot_generic<Elf::Rela, DT_RELA, false> Reloc_jmpslot;
|
typedef Reloc_jmpslot_generic<Elf::Rela, DT_RELA, false> Reloc_jmpslot;
|
||||||
typedef Reloc_bind_now_generic<Elf::Rela, DT_RELA> Reloc_bind_now;
|
typedef Reloc_bind_now_generic<Elf::Rela, DT_RELA> Reloc_bind_now;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user