[ELF] Adjust ELF header entry symbol value if this symbol is microMIPS encoded

To find an AtomLayout object for the given symbol I replace the
`Layout::findAtomAddrByName` method by `Layout::findAtomLayoutByName` method.

llvm-svn: 223359
This commit is contained in:
Simon Atanasyan 2014-12-04 13:43:35 +00:00
parent 8435a6938d
commit c9bcffd201
7 changed files with 190 additions and 25 deletions

View File

@ -236,12 +236,12 @@ public:
si->doPreFlight();
}
inline bool findAtomAddrByName(StringRef name, uint64_t &addr) override {
inline const AtomLayout *findAtomLayoutByName(StringRef name) const override {
for (auto sec : _sections)
if (auto section = dyn_cast<Section<ELFT> >(sec))
if (section->findAtomAddrByName(name, addr))
return true;
return false;
if (auto section = dyn_cast<Section<ELFT>>(sec))
if (auto *al = section->findAtomLayoutByName(name))
return al;
return nullptr;
}
inline void setHeader(ELFHeader<ELFT> *elfHeader) { _elfHeader = elfHeader; }

View File

@ -41,8 +41,8 @@ public:
/// \returns A reference to the atom layout or an error. The atom layout will
/// be updated as linking progresses.
virtual ErrorOr<const lld::AtomLayout &> addAtom(const Atom *atom) = 0;
/// find the Atom Address in the current layout
virtual bool findAtomAddrByName(StringRef name, uint64_t &addr) = 0;
/// find the Atom in the current layout
virtual const AtomLayout *findAtomLayoutByName(StringRef name) const = 0;
/// associates a section to a segment
virtual void assignSectionsToSegments() = 0;
/// associates a virtual address to the segment, section, and the atom

View File

@ -32,12 +32,7 @@ protected:
bool createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
void finalizeDefaultAtomValues() override;
std::error_code setELFHeader() override {
ExecutableWriter<ELFT>::setELFHeader();
_writeHelper.setELFHeader(*this->_elfHeader);
return std::error_code();
}
std::error_code setELFHeader() override;
LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) createSymbolTable() override;
LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable() override;
@ -59,6 +54,25 @@ MipsExecutableWriter<ELFT>::MipsExecutableWriter(
_writeHelper(ctx, layout, elfFlagsMerger), _mipsContext(ctx),
_mipsTargetLayout(layout) {}
template <class ELFT>
std::error_code MipsExecutableWriter<ELFT>::setELFHeader() {
std::error_code ec = ExecutableWriter<ELFT>::setELFHeader();
if (ec)
return ec;
StringRef entryName = _mipsContext.entrySymbolName();
if (const AtomLayout *al = this->_layout.findAtomLayoutByName(entryName)) {
const auto *ea = cast<DefinedAtom>(al->_atom);
if (ea->codeModel() == DefinedAtom::codeMipsMicro ||
ea->codeModel() == DefinedAtom::codeMipsMicroPIC)
// Adjust entry symbol value if this symbol is microMIPS encoded.
this->_elfHeader->e_entry(al->_virtualAddr + 1);
}
_writeHelper.setELFHeader(*this->_elfHeader);
return std::error_code();
}
template <class ELFT>
void MipsExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
// MIPS ABI requires to add to dynsym even undefined symbols

View File

@ -428,9 +428,10 @@ template <class ELFT> std::error_code OutputELFWriter<ELFT>::setELFHeader() {
_elfHeader->e_shentsize(_shdrtab->entsize());
_elfHeader->e_shnum(_shdrtab->numHeaders());
_elfHeader->e_shstrndx(_shstrtab->ordinal());
uint64_t virtualAddr = 0;
_layout.findAtomAddrByName(_context.entrySymbolName(), virtualAddr);
_elfHeader->e_entry(virtualAddr);
if (const auto *al = _layout.findAtomLayoutByName(_context.entrySymbolName()))
_elfHeader->e_entry(al->_virtualAddr);
else
_elfHeader->e_entry(0);
return std::error_code();
}

View File

@ -95,7 +95,9 @@ public:
this->_segmentType = segmentType;
}
virtual bool findAtomAddrByName(StringRef, uint64_t &) { return false; }
virtual const AtomLayout *findAtomLayoutByName(StringRef) const {
return nullptr;
}
void setOutputSection(OutputSection<ELFT> *os, bool isFirst = false) {
_outputSection = os;
@ -237,14 +239,11 @@ public:
/// \brief Find the Atom address given a name, this is needed to properly
/// apply relocation. The section class calls this to find the atom address
/// to fix the relocation
virtual bool findAtomAddrByName(StringRef name, uint64_t &addr) {
for (auto ai : _atoms) {
if (ai->_atom->name() == name) {
addr = ai->_virtualAddr;
return true;
}
}
return false;
const AtomLayout *findAtomLayoutByName(StringRef name) const override {
for (auto ai : _atoms)
if (ai->_atom->name() == name)
return ai;
return nullptr;
}
/// \brief Return the raw flags, we need this to sort segments

View File

@ -0,0 +1,82 @@
# Check ELF Header for shared library in case of microMIPS symbols.
# Build shared library
# RUN: yaml2obj -format=elf %s > %t.o
# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.o
# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
# CHECK: Format: ELF32-mips
# CHECK-NEXT: Arch: mipsel
# CHECK-NEXT: AddressSize: 32bit
# CHECK-NEXT: LoadName:
# CHECK-NEXT: ElfHeader {
# CHECK-NEXT: Ident {
# CHECK-NEXT: Magic: (7F 45 4C 46)
# CHECK-NEXT: Class: 32-bit (0x1)
# CHECK-NEXT: DataEncoding: LittleEndian (0x1)
# CHECK-NEXT: FileVersion: 1
# CHECK-NEXT: OS/ABI: SystemV (0x0)
# CHECK-NEXT: ABIVersion: 0
# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
# CHECK-NEXT: }
# CHECK-NEXT: Type: SharedObject (0x3)
# CHECK-NEXT: Machine: EM_MIPS (0x8)
# CHECK-NEXT: Version: 1
# CHECK-NEXT: Entry: 0x100
# CHECK-NEXT: ProgramHeaderOffset: 0x34
# CHECK-NEXT: SectionHeaderOffset: 0x2100
# CHECK-NEXT: Flags [ (0x72001007)
# CHECK-NEXT: EF_MIPS_ABI_O32 (0x1000)
# CHECK-NEXT: EF_MIPS_ARCH_32R2 (0x70000000)
# CHECK-NEXT: EF_MIPS_CPIC (0x4)
# CHECK-NEXT: EF_MIPS_MICROMIPS (0x2000000)
# CHECK-NEXT: EF_MIPS_NOREORDER (0x1)
# CHECK-NEXT: EF_MIPS_PIC (0x2)
# CHECK-NEXT: ]
# CHECK-NEXT: HeaderSize: 52
# CHECK-NEXT: ProgramHeaderEntrySize: 32
# CHECK-NEXT: ProgramHeaderCount: 4
# CHECK-NEXT: SectionHeaderEntrySize: 40
# CHECK-NEXT: SectionHeaderCount: 11
# CHECK-NEXT: StringTableSectionIndex: 8
# CHECK-NEXT:}
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, EF_MIPS_MICROMIPS ]
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x04
Size: 0x04
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
AddressAlign: 0x04
Size: 0x00
- Name: .bss
Type: SHT_NOBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
AddressAlign: 0x04
Size: 0x00
- Name: .reginfo
Type: SHT_MIPS_REGINFO
Flags: [ SHF_ALLOC ]
AddressAlign: 0x01
Size: 0x18
- Name: .MIPS.abiflags
Type: SHT_MIPS_ABIFLAGS
Flags: [ SHF_ALLOC ]
AddressAlign: 0x08
Size: 0x18
Symbols:
Global:
- Name: glob
Section: .text
Other: [ STO_MIPS_MICROMIPS ]

View File

@ -0,0 +1,69 @@
# Check ELF Header for non-pic executable file in case
# of microMIPS entry symbol.
# Build executable
# RUN: yaml2obj -format=elf %s > %t-o.o
# RUN: lld -flavor gnu -target mipsel -e glob -o %t.exe %t-o.o
# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
# CHECK: Format: ELF32-mips
# CHECK-NEXT: Arch: mipsel
# CHECK-NEXT: AddressSize: 32bit
# CHECK-NEXT: LoadName:
# CHECK-NEXT: ElfHeader {
# CHECK-NEXT: Ident {
# CHECK-NEXT: Magic: (7F 45 4C 46)
# CHECK-NEXT: Class: 32-bit (0x1)
# CHECK-NEXT: DataEncoding: LittleEndian (0x1)
# CHECK-NEXT: FileVersion: 1
# CHECK-NEXT: OS/ABI: SystemV (0x0)
# CHECK-NEXT: ABIVersion: 0
# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
# CHECK-NEXT: }
# CHECK-NEXT: Type: Executable (0x2)
# CHECK-NEXT: Machine: EM_MIPS (0x8)
# CHECK-NEXT: Version: 1
# CHECK-NEXT: Entry: 0x400109
# CHECK-NEXT: ProgramHeaderOffset: 0x34
# CHECK-NEXT: SectionHeaderOffset: 0x1268
# CHECK-NEXT: Flags [ (0x72001005)
# CHECK-NEXT: EF_MIPS_ABI_O32 (0x1000)
# CHECK-NEXT: EF_MIPS_ARCH_32R2 (0x70000000)
# CHECK-NEXT: EF_MIPS_CPIC (0x4)
# CHECK-NEXT: EF_MIPS_MICROMIPS (0x2000000)
# CHECK-NEXT: EF_MIPS_NOREORDER (0x1)
# CHECK-NEXT: ]
# CHECK-NEXT: HeaderSize: 52
# CHECK-NEXT: ProgramHeaderEntrySize: 32
# CHECK-NEXT: ProgramHeaderCount: 5
# CHECK-NEXT: SectionHeaderEntrySize: 40
# CHECK-NEXT: SectionHeaderCount: 11
# CHECK-NEXT: StringTableSectionIndex: 8
# CHECK-NEXT: }
# o.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: [ EF_MIPS_NOREORDER, EF_MIPS_CPIC,
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: 0x08
Symbols:
Local:
- Name: .text
Type: STT_SECTION
Section: .text
Global:
- Name: glob
Section: .text
Other: [ STO_MIPS_MICROMIPS ]
...