From 7948a7261b40bdc56a430ee02f7538c44f42d874 Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Thu, 5 Jan 2017 15:56:00 +0100 Subject: [PATCH] ldso: constrain second linker symbol relocation pass on x86_64 Handle only GLOB_DAT relocations in the second relocation pass, like it is done on x86_32 and ARM. Fixes #2219 --- repos/base/src/lib/ldso/include/dynamic.h | 2 +- repos/base/src/lib/ldso/spec/arm/relocation.h | 2 +- repos/base/src/lib/ldso/spec/riscv/relocation.h | 2 +- repos/base/src/lib/ldso/spec/x86_32/relocation.h | 2 +- repos/base/src/lib/ldso/spec/x86_64/relocation.h | 6 +++++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/repos/base/src/lib/ldso/include/dynamic.h b/repos/base/src/lib/ldso/include/dynamic.h index 275bf1bcaa..20af5f1fd7 100644 --- a/repos/base/src/lib/ldso/include/dynamic.h +++ b/repos/base/src/lib/ldso/include/dynamic.h @@ -336,7 +336,7 @@ class Linker::Dynamic void relocate_non_plt(Bind bind, Pass pass) { if (_reloca) - Reloc_non_plt r(*_dep, _reloca, _reloca_size); + Reloc_non_plt r(*_dep, _reloca, _reloca_size, pass == SECOND_PASS); if (_rel) Reloc_non_plt r(*_dep, _rel, _rel_size, pass == SECOND_PASS); diff --git a/repos/base/src/lib/ldso/spec/arm/relocation.h b/repos/base/src/lib/ldso/spec/arm/relocation.h index 841b4f26ed..79abb6caa3 100644 --- a/repos/base/src/lib/ldso/spec/arm/relocation.h +++ b/repos/base/src/lib/ldso/spec/arm/relocation.h @@ -78,7 +78,7 @@ class Linker::Reloc_non_plt : public Reloc_non_plt_generic public: - Reloc_non_plt(Dependency const &dep, Elf::Rela const *, unsigned long) + Reloc_non_plt(Dependency const &dep, Elf::Rela const *, unsigned long, bool) : Reloc_non_plt_generic(dep) { error("LD: DT_RELA not supported"); diff --git a/repos/base/src/lib/ldso/spec/riscv/relocation.h b/repos/base/src/lib/ldso/spec/riscv/relocation.h index 67e928fd41..9652ac64ba 100644 --- a/repos/base/src/lib/ldso/spec/riscv/relocation.h +++ b/repos/base/src/lib/ldso/spec/riscv/relocation.h @@ -75,7 +75,7 @@ class Linker::Reloc_non_plt : public Reloc_non_plt_generic public: - Reloc_non_plt(Dependency const &dep, Elf::Rela const *rel, unsigned long size) + Reloc_non_plt(Dependency const &dep, Elf::Rela const *rel, unsigned long size, bool) : Reloc_non_plt_generic(dep) { Elf::Rela const *end = rel + (size / sizeof(Elf::Rela)); 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 dcbc30b568..6ddf34e57e 100644 --- a/repos/base/src/lib/ldso/spec/x86_32/relocation.h +++ b/repos/base/src/lib/ldso/spec/x86_32/relocation.h @@ -58,7 +58,7 @@ class Linker::Reloc_non_plt : public Reloc_non_plt_generic public: - Reloc_non_plt(Dependency const &dep, Elf::Rela const *, unsigned long) + Reloc_non_plt(Dependency const &dep, Elf::Rela const *, unsigned long, bool) : Reloc_non_plt_generic(dep) { error("LD: DT_RELA not supported"); 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 a9fce645f9..8988104983 100644 --- a/repos/base/src/lib/ldso/spec/x86_64/relocation.h +++ b/repos/base/src/lib/ldso/spec/x86_64/relocation.h @@ -68,7 +68,8 @@ class Linker::Reloc_non_plt : public Reloc_non_plt_generic public: - Reloc_non_plt(Dependency const &dep, Elf::Rela const *rel, unsigned long size) + Reloc_non_plt(Dependency const &dep, Elf::Rela const *rel, unsigned long size, + bool second_pass) : Reloc_non_plt_generic(dep) { Elf::Rela const *end = rel + (size / sizeof(Elf::Rela)); @@ -76,6 +77,9 @@ class Linker::Reloc_non_plt : public Reloc_non_plt_generic for (; rel < end; rel++) { Elf::Addr *addr = (Elf::Addr *)(_dep.obj().reloc_base() + rel->offset); + if (second_pass && rel->type() != R_GLOB_DAT) + continue; + switch(rel->type()) { case R_64: _glob_dat_64(rel, addr, true); break; case R_GLOB_DAT: _glob_dat_64(rel, addr, false); break;