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
This commit is contained in:
Christian Prochaska 2017-01-05 15:56:00 +01:00 committed by Norman Feske
parent e89cab4433
commit 7948a7261b
5 changed files with 9 additions and 5 deletions

View File

@ -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);

View File

@ -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");

View File

@ -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));

View File

@ -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");

View File

@ -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;