forked from OSchip/llvm-project
Copy DT_SONAME to DT_NEEDED.
If a shared library has a DT_SONAME entry, that is what should be included in the DT_NEEDED of a program using it. We don't implement -soname yet, so check in a .so for now. llvm-svn: 249025
This commit is contained in:
parent
bd35d75e42
commit
c8b158155c
|
@ -216,14 +216,39 @@ SharedFile<ELFT>::SharedFile(MemoryBufferRef M)
|
|||
: SharedFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {}
|
||||
|
||||
template <class ELFT> void SharedFile<ELFT>::parse() {
|
||||
for (const Elf_Shdr &Sec : this->ELFObj.sections()) {
|
||||
if (Sec.sh_type == SHT_DYNSYM) {
|
||||
typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
|
||||
typedef typename ELFFile<ELFT>::uintX_t uintX_t;
|
||||
const Elf_Shdr *DynamicSec = nullptr;
|
||||
|
||||
const ELFFile<ELFT> Obj = this->ELFObj;
|
||||
for (const Elf_Shdr &Sec : Obj.sections()) {
|
||||
uint32_t Type = Sec.sh_type;
|
||||
if (Type == SHT_DYNSYM)
|
||||
this->Symtab = &Sec;
|
||||
break;
|
||||
else if (Type == SHT_DYNAMIC)
|
||||
DynamicSec = &Sec;
|
||||
}
|
||||
|
||||
// Also sets StringTable
|
||||
Elf_Sym_Range Syms = this->getNonLocalSymbols();
|
||||
SoName = getName();
|
||||
|
||||
if (DynamicSec) {
|
||||
auto *Begin =
|
||||
reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset);
|
||||
const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn);
|
||||
|
||||
for (const Elf_Dyn &Dyn : make_range(Begin, End)) {
|
||||
if (Dyn.d_tag == DT_SONAME) {
|
||||
uintX_t Val = Dyn.getVal();
|
||||
if (Val >= this->StringTable.size())
|
||||
error("Invalid DT_SONAME entry");
|
||||
SoName = StringRef(this->StringTable.data() + Val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Elf_Sym_Range Syms = this->getNonLocalSymbols();
|
||||
uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
|
||||
SymbolBodies.reserve(NumSymbols);
|
||||
for (const Elf_Sym &Sym : Syms) {
|
||||
|
|
|
@ -185,10 +185,14 @@ private:
|
|||
|
||||
// .so file.
|
||||
class SharedFileBase : public ELFFileBase {
|
||||
protected:
|
||||
StringRef SoName;
|
||||
|
||||
public:
|
||||
SharedFileBase(ELFKind EKind, MemoryBufferRef M)
|
||||
: ELFFileBase(SharedKind, EKind, M) {}
|
||||
static bool classof(const InputFile *F) { return F->kind() == SharedKind; }
|
||||
StringRef getSoName() const { return SoName; }
|
||||
};
|
||||
|
||||
template <class ELFT>
|
||||
|
|
|
@ -207,7 +207,7 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
|
|||
const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =
|
||||
SymTab.getSharedFiles();
|
||||
for (const std::unique_ptr<SharedFileBase> &File : SharedFiles)
|
||||
DynStrSec.add(File->getName());
|
||||
DynStrSec.add(File->getSoName());
|
||||
NumEntries += SharedFiles.size();
|
||||
|
||||
++NumEntries; // DT_NULL
|
||||
|
@ -266,7 +266,7 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||
SymTab.getSharedFiles();
|
||||
for (const std::unique_ptr<SharedFileBase> &File : SharedFiles) {
|
||||
P->d_tag = DT_NEEDED;
|
||||
P->d_un.d_val = DynStrSec.getFileOff(File->getName());
|
||||
P->d_un.d_val = DynStrSec.getFileOff(File->getSoName());
|
||||
++P;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,8 @@
|
|||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
// RUN: lld -flavor gnu2 %t.o %p/Inputs/soname.so -o %t
|
||||
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s
|
||||
|
||||
// CHECK: 0x0000000000000001 NEEDED SharedLibrary (bar)
|
||||
|
||||
.global _start
|
||||
_start:
|
Loading…
Reference in New Issue