[Mips] In case of executable file linking MIPS ABI requires to add even

undefined symbols to '.dynsym' if these symbols have corresponding entries
in a global part of GOT.

llvm-svn: 200716
This commit is contained in:
Simon Atanasyan 2014-02-03 20:10:40 +00:00
parent 0912fe06dc
commit b828ebb5dd
4 changed files with 92 additions and 0 deletions

View File

@ -64,6 +64,10 @@ protected:
}
}
bool hasGlobalGOTEntry(const Atom *a) const {
return _mipsTargetLayout.getGOTSection().hasGlobalGOTEntry(a);
}
private:
MipsLinkingContext &_mipsLinkingContext LLVM_ATTRIBUTE_UNUSED;
MipsTargetLayout<ELFT> &_mipsTargetLayout;

View File

@ -27,6 +27,8 @@ public:
MipsTargetLayout<ELFT> &layout);
protected:
virtual void buildDynamicSymbolTable(const File &file);
// Add any runtime files and their atoms to the output
virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
@ -64,6 +66,20 @@ MipsExecutableWriter<ELFT>::MipsExecutableWriter(MipsLinkingContext &context,
_mipsRuntimeFile(new MipsRuntimeFile<ELFT>(context)),
_mipsContext(context), _mipsTargetLayout(layout) {}
template <class ELFT>
void MipsExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
// MIPS ABI requires to add to dynsym even undefined symbols
// if they have a corresponding entries in a global part of GOT.
for (const UndefinedAtom *a : file.undefined())
// FIXME (simon): Consider to move this check to the
// MipsELFUndefinedAtom class method. That allows to
// handle more complex coditions in the future.
if (this->hasGlobalGOTEntry(a))
this->_dynamicSymbolTable->addSymbol(a, ELF::SHN_UNDEF);
ExecutableWriter<ELFT>::buildDynamicSymbolTable(file);
}
template <class ELFT>
bool MipsExecutableWriter<ELFT>::createImplicitFiles(
std::vector<std::unique_ptr<File>> &result) {

View File

@ -35,6 +35,9 @@ public:
/// \brief Number of global GOT entries.
std::size_t getGlobalCount() const { return _globalCount; }
/// \brief Does the atom have a global GOT entry?
bool hasGlobalGOTEntry(const Atom *a) const { return _posMap.count(a); }
/// \brief Compare two atoms accordingly theirs positions in the GOT.
bool compare(const Atom *a, const Atom *b) const {
auto ia = _posMap.find(a);

View File

@ -0,0 +1,69 @@
# Check that symbol referenced by an entry in the global part of GOT
# has a corresponded entry in the .dynsym section.
# Build executable
# RUN: llvm-mc -triple=mipsel -filetype=obj -o=%t-main %s
# RUN: lld -flavor gnu -target mipsel -e glob -o %t-exe %t-main
# RUN: llvm-readobj -dyn-symbols %t-exe | FileCheck -check-prefix=CHECK-DYN %s
# Build executabl (yaml format)e
# RUN: lld -flavor gnu -target mipsel -e glob \
# RUN: --output-filetype=yaml -o %t-yaml %t-main
# RUN: FileCheck -check-prefix=CHECK-GOT %s < %t-yaml
# CHECK-DYN: Format: ELF32-mips
# CHECK-DYN: Arch: mipsel
# CHECK-DYN: AddressSize: 32bit
# CHECK-DYN: LoadName:
# CHECK-DYN: DynamicSymbols [
# CHECK-DYN: Symbol {
# CHECK-DYN: Name: @ (0)
# CHECK-DYN: Value: 0x0
# CHECK-DYN: Size: 0
# CHECK-DYN: Binding: Local (0x0)
# CHECK-DYN: Type: None (0x0)
# CHECK-DYN: Other: 0
# CHECK-DYN: Section: (0x0)
# CHECK-DYN: }
# CHECK-DYN: Symbol {
# CHECK-DYN: Name: weakf@ (1)
# CHECK-DYN: Value: 0x0
# CHECK-DYN: Size: 0
# CHECK-DYN: Binding: Weak (0x2)
# CHECK-DYN: Type: None (0x0)
# CHECK-DYN: Other: 0
# CHECK-DYN: Section: (0x0)
# CHECK-DYN: }
# CHECK-DYN: ]
# CHECK-GOT: - type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
# CHECK-GOT: alignment: 2^2
# CHECK-GOT: section-choice: custom-required
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: - type: got
# CHECK-GOT: content: [ 00, 00, 00, 80 ]
# CHECK-GOT: alignment: 2^2
# CHECK-GOT: section-choice: custom-required
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: - ref-name: L000
# CHECK-GOT: type: got
# CHECK-GOT: content: [ 00, 00, 00, 00 ]
# CHECK-GOT: alignment: 2^2
# CHECK-GOT: section-choice: custom-required
# CHECK-GOT: section-name: .got
# CHECK-GOT: permissions: rw-
# CHECK-GOT: references:
# CHECK-GOT: - kind: LLD_R_MIPS_GLOBAL_GOT
# CHECK-GOT: offset: 0
# CHECK-GOT: target: weakf
.abicalls
.global glob
.ent glob
glob:
lw $4,%got(weakf)($28)
.end glob
.weak weakf