forked from OSchip/llvm-project
[ELF] Allow target to adjust a symbol's value for using in a dynamic tag
Some targets like microMIPS and ARM Thumb use the last bit of a symbol's value to mark 'compressed' code. This patch adds new virtual function `DynamicTable::getAtomVirtualAddress` which allows to adjust a symbol's value before using it in a dynamic table tags like DT_INIT / DT_FINI. llvm-svn: 223963
This commit is contained in:
parent
80f57f6842
commit
87a559212b
|
@ -91,6 +91,16 @@ public:
|
|||
|
||||
int64_t getGotPltTag() override { return DT_MIPS_PLTGOT; }
|
||||
|
||||
protected:
|
||||
/// \brief Adjust the symbol's value for microMIPS code.
|
||||
uint64_t getAtomVirtualAddress(const AtomLayout *al) const override {
|
||||
if (const auto *da = dyn_cast<DefinedAtom>(al->_atom))
|
||||
if (da->codeModel() == DefinedAtom::codeMipsMicro ||
|
||||
da->codeModel() == DefinedAtom::codeMipsMicroPIC)
|
||||
return al->_virtualAddr + 1;
|
||||
return al->_virtualAddr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _dt_symtabno;
|
||||
std::size_t _dt_localgot;
|
||||
|
|
|
@ -1188,9 +1188,9 @@ public:
|
|||
_entries[_dt_fini_arraysz].d_un.d_val = finiArray->memSize();
|
||||
}
|
||||
if (const auto *al = getInitAtomLayout())
|
||||
_entries[_dt_init].d_un.d_val = al->_virtualAddr;
|
||||
_entries[_dt_init].d_un.d_val = getAtomVirtualAddress(al);
|
||||
if (const auto *al = getFiniAtomLayout())
|
||||
_entries[_dt_fini].d_un.d_val = al->_virtualAddr;
|
||||
_entries[_dt_fini].d_un.d_val = getAtomVirtualAddress(al);
|
||||
if (_layout.hasDynamicRelocationTable()) {
|
||||
auto relaTbl = _layout.getDynamicRelocationTable();
|
||||
_entries[_dt_rela].d_un.d_val = relaTbl->virtualAddr();
|
||||
|
@ -1209,6 +1209,14 @@ public:
|
|||
protected:
|
||||
EntriesT _entries;
|
||||
|
||||
/// \brief Return a virtual address (maybe adjusted) for the atom layout
|
||||
/// Some targets like microMIPS and ARM Thumb use the last bit
|
||||
/// of a symbol's value to mark 'compressed' code. This function allows
|
||||
/// to adjust a virtal address before using it in the dynamic table tag.
|
||||
virtual uint64_t getAtomVirtualAddress(const AtomLayout *al) const {
|
||||
return al->_virtualAddr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _dt_hash;
|
||||
std::size_t _dt_strtab;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# Check that if _init/_fini symbols are microMIPS encoded, DT_INIT/DT_FINI tags
|
||||
# use adjusted values with set the last bit.
|
||||
|
||||
# RUN: yaml2obj -format=elf %s > %t.o
|
||||
# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.o
|
||||
# RUN: llvm-readobj -symbols -dynamic-table %t.so | FileCheck %s
|
||||
|
||||
# CHECK: Name: _init (1)
|
||||
# CHECK-NEXT: Value: 0xF5
|
||||
# CHECK: Name: _fini (7)
|
||||
# CHECK-NEXT: Value: 0xF9
|
||||
#
|
||||
# CHECK: 0x0000000C INIT 0xF5
|
||||
# CHECK: 0x0000000D FINI 0xF9
|
||||
|
||||
---
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_MIPS
|
||||
Flags: [ EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS ]
|
||||
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x04
|
||||
Size: 0x18
|
||||
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: _init
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x0
|
||||
Size: 0x4
|
||||
Other: [ STO_MIPS_MICROMIPS ]
|
||||
- Name: _fini
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x4
|
||||
Size: 0x4
|
||||
Other: [ STO_MIPS_MICROMIPS ]
|
||||
...
|
Loading…
Reference in New Issue