From 750c11c0991484675ce3722393e174ebc416f43b Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Thu, 16 Feb 2017 04:39:45 +0000 Subject: [PATCH] Split a function and add comments. This is slightly inefficient than the previous code, but that is really negligible as this function is usually called at most only a few times. llvm-svn: 295282 --- lld/ELF/Relocations.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 9e0f46291857..4bdcfb8f446f 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -413,10 +413,30 @@ template static bool isReadOnly(SharedSymbol *SS) { return false; } +// Returns symbols at the same offset as a given symbol. +// +// If two or more symbols are at the same offset, and at least one of +// them are copied by a copy relocation, all of them need to be copied. +// Otherwise, they would refer different places at runtime. +template +static std::vector *> getAliases(SharedSymbol *SS) { + typedef typename ELFT::Sym Elf_Sym; + + std::vector *> Ret; + for (const Elf_Sym &S : SS->file()->getGlobalSymbols()) { + if (S.st_shndx != SS->Sym.st_shndx || S.st_value != SS->Sym.st_value) + continue; + StringRef Name = check(S.getName(SS->file()->getStringTable())); + SymbolBody *Sym = Symtab::X->find(Name); + if (auto *Alias = dyn_cast_or_null>(Sym)) + Ret.push_back(Alias); + } + return Ret; +} + // Reserve space in .bss or .bss.rel.ro for copy relocation. template static void addCopyRelSymbol(SharedSymbol *SS) { typedef typename ELFT::uint uintX_t; - typedef typename ELFT::Sym Elf_Sym; // Copy relocation against zero-sized symbol doesn't make sense. uintX_t SymSize = SS->template getSize(); @@ -436,17 +456,12 @@ template static void addCopyRelSymbol(SharedSymbol *SS) { // Look through the DSO's dynamic symbol table for aliases and create a // dynamic symbol for each one. This causes the copy relocation to correctly // interpose any aliases. - for (const Elf_Sym &S : SS->file()->getGlobalSymbols()) { - if (S.st_shndx != SS->Sym.st_shndx || S.st_value != SS->Sym.st_value) - continue; - auto *Alias = dyn_cast_or_null>( - Symtab::X->find(check(S.getName(SS->file()->getStringTable())))); - if (!Alias) - continue; + for (SharedSymbol *Alias : getAliases(SS)) { Alias->CopySection = ISec; Alias->NeedsCopyOrPltAddr = true; Alias->symbol()->IsUsedInRegularObj = true; } + In::RelaDyn->addReloc({Target->CopyRel, ISec, 0, false, SS, 0}); }