[lld] r223359 - [ELF] Adjust ELF header entry symbol value if this symbol is microMIPS encoded
Simon Atanasyan
simon at atanasyan.com
Thu Dec 4 05:43:35 PST 2014
Author: atanasyan
Date: Thu Dec 4 07:43:35 2014
New Revision: 223359
URL: http://llvm.org/viewvc/llvm-project?rev=223359&view=rev
Log:
[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.
Added:
lld/trunk/test/elf/Mips/dynlib-fileheader-micro.test
lld/trunk/test/elf/Mips/exe-fileheader-micro.test
Modified:
lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
lld/trunk/lib/ReaderWriter/ELF/Layout.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=223359&r1=223358&r2=223359&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Thu Dec 4 07:43:35 2014
@@ -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; }
Modified: lld/trunk/lib/ReaderWriter/ELF/Layout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Layout.h?rev=223359&r1=223358&r2=223359&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Layout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Layout.h Thu Dec 4 07:43:35 2014
@@ -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
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h?rev=223359&r1=223358&r2=223359&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h Thu Dec 4 07:43:35 2014
@@ -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;
@@ -60,6 +55,25 @@ MipsExecutableWriter<ELFT>::MipsExecutab
_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
// if they have a corresponding entries in a global part of GOT.
Modified: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=223359&r1=223358&r2=223359&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Thu Dec 4 07:43:35 2014
@@ -428,9 +428,10 @@ template <class ELFT> std::error_code Ou
_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();
}
Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=223359&r1=223358&r2=223359&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Thu Dec 4 07:43:35 2014
@@ -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
Added: lld/trunk/test/elf/Mips/dynlib-fileheader-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/dynlib-fileheader-micro.test?rev=223359&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/dynlib-fileheader-micro.test (added)
+++ lld/trunk/test/elf/Mips/dynlib-fileheader-micro.test Thu Dec 4 07:43:35 2014
@@ -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 ]
Added: lld/trunk/test/elf/Mips/exe-fileheader-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/exe-fileheader-micro.test?rev=223359&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/exe-fileheader-micro.test (added)
+++ lld/trunk/test/elf/Mips/exe-fileheader-micro.test Thu Dec 4 07:43:35 2014
@@ -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 ]
+...
More information about the llvm-commits
mailing list