forked from OSchip/llvm-project
[Mips] Read GP0 value from .MIPS.options section
llvm-svn: 229442
This commit is contained in:
parent
371e1128b3
commit
fbe1348ef4
|
@ -24,15 +24,26 @@ struct Elf_RegInfo<ELFType<TargetEndianness, MaxAlign, false>> {
|
|||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
|
||||
Elf_Word ri_gprmask; // bit-mask of used general registers
|
||||
Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
|
||||
Elf_Sword ri_gp_value; // gp register value
|
||||
Elf_Addr ri_gp_value; // gp register value
|
||||
};
|
||||
|
||||
template <llvm::support::endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_RegInfo<ELFType<TargetEndianness, MaxAlign, true>> {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
|
||||
Elf_Word ri_gprmask; // bit-mask of used general registers
|
||||
Elf_Word ri_pad; // unused padding field
|
||||
Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
|
||||
Elf_Sword ri_gp_value; // gp register value
|
||||
Elf_Addr ri_gp_value; // gp register value
|
||||
};
|
||||
|
||||
template <class ELFT> struct Elf_Mips_Options {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment,
|
||||
ELFT::Is64Bits)
|
||||
uint8_t kind; // Determines interpretation of variable part of descriptor
|
||||
uint8_t size; // Byte size of descriptor, including this header
|
||||
Elf_Half section; // Section header index of section affected,
|
||||
// or 0 for global options
|
||||
Elf_Word info; // Kind-specific information
|
||||
};
|
||||
|
||||
} // end namespace object.
|
||||
|
@ -146,13 +157,34 @@ private:
|
|||
}
|
||||
|
||||
std::error_code readAuxData() {
|
||||
if (const Elf_Shdr *sec = findSectionByFlags(llvm::ELF::SHF_TLS)) {
|
||||
using namespace llvm::ELF;
|
||||
if (const Elf_Shdr *sec = findSectionByFlags(SHF_TLS)) {
|
||||
_tpOff = sec->sh_addr + TP_OFFSET;
|
||||
_dtpOff = sec->sh_addr + DTP_OFFSET;
|
||||
}
|
||||
if (const Elf_Shdr *sec = findSectionByType(llvm::ELF::SHT_MIPS_REGINFO)) {
|
||||
typedef llvm::object::Elf_RegInfo<ELFT> Elf_RegInfo;
|
||||
|
||||
typedef llvm::object::Elf_RegInfo<ELFT> Elf_RegInfo;
|
||||
typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
|
||||
|
||||
if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_OPTIONS)) {
|
||||
auto contents = this->getSectionContents(sec);
|
||||
if (std::error_code ec = contents.getError())
|
||||
return ec;
|
||||
|
||||
ArrayRef<uint8_t> raw = contents.get();
|
||||
while (!raw.empty()) {
|
||||
if (raw.size() < sizeof(Elf_Mips_Options))
|
||||
return make_dynamic_error_code(
|
||||
StringRef("Invalid size of MIPS_OPTIONS section"));
|
||||
|
||||
const auto *opt = reinterpret_cast<const Elf_Mips_Options *>(raw.data());
|
||||
if (opt->kind == 1/*ODK_REGINFO*/) {
|
||||
_gp0 = reinterpret_cast<const Elf_RegInfo *>(opt + 1)->ri_gp_value;
|
||||
break;
|
||||
}
|
||||
raw = raw.slice(opt->size);
|
||||
}
|
||||
} else if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_REGINFO)) {
|
||||
auto contents = this->getSectionContents(sec);
|
||||
if (std::error_code ec = contents.getError())
|
||||
return ec;
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
# Check reading GP0 value from .MIPS.options section
|
||||
#
|
||||
# RUN: yaml2obj -format=elf %s > %t.o
|
||||
# RUN: lld -flavor gnu -target mipsel -e G1 -shared -o %t.so %t.o
|
||||
# RUN: llvm-readobj -symbols %t.so | FileCheck -check-prefix=SYM %s
|
||||
# RUN: llvm-objdump -s %t.so | FileCheck -check-prefix=SEC %s
|
||||
|
||||
# SYM: Name: L1 (1)
|
||||
# SYM-NEXT: Value: 0xCC
|
||||
# SYM-NEXT: Size: 4
|
||||
# SYM-NEXT: Binding: Local (0x0)
|
||||
# SYM-NEXT: Type: Function (0x2)
|
||||
# SYM-NEXT: Other: 0
|
||||
# SYM-NEXT: Section: .text (0x4)
|
||||
|
||||
# SYM: Name: _gp (34)
|
||||
# SYM-NEXT: Value: 0x8FF0
|
||||
# SYM-NEXT: Size: 0
|
||||
# SYM-NEXT: Binding: Global (0x1)
|
||||
# SYM-NEXT: Type: Object (0x1)
|
||||
# SYM-NEXT: Other: 0
|
||||
# SYM-NEXT: Section: Absolute (0xFFF1)
|
||||
|
||||
# 0xffff80dc == 0x0 (addend) + 0x00cc (L1) + 0x1000 (GP0) - 0x8ff0 (_gp)
|
||||
# SEC: Contents of section .rodata:
|
||||
# SEC-NEXT: 00d4 dc80ffff 00000000 00000000 00000000 ................
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_MIPS
|
||||
Flags: [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
|
||||
EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2 ]
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x04
|
||||
Size: 0x08
|
||||
|
||||
- Name: .rodata
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC ]
|
||||
AddressAlign: 0x04
|
||||
Size: 16
|
||||
|
||||
- Name: .rel.rodata
|
||||
Type: SHT_REL
|
||||
Link: .symtab
|
||||
Info: .rodata
|
||||
AddressAlign: 0x04
|
||||
Relocations:
|
||||
- Offset: 0
|
||||
Symbol: L1
|
||||
Type: R_MIPS_GPREL32
|
||||
|
||||
- Name: .MIPS.options
|
||||
Type: SHT_MIPS_OPTIONS
|
||||
Flags: [ SHF_ALLOC ]
|
||||
AddressAlign: 0x01
|
||||
Content: "0128000000000000000000000000000000000000000000000000000000100000"
|
||||
|
||||
Symbols:
|
||||
Local:
|
||||
- Name: L1
|
||||
Section: .text
|
||||
Value: 0x00
|
||||
Size: 0x04
|
||||
- Name: .rodata
|
||||
Type: STT_SECTION
|
||||
Section: .rodata
|
||||
Global:
|
||||
- Name: G1
|
||||
Section: .text
|
||||
Value: 0x04
|
||||
Size: 0x04
|
Loading…
Reference in New Issue