diff options
author | Simon Atanasyan <simon@atanasyan.com> | 2015-05-31 20:36:58 +0000 |
---|---|---|
committer | Simon Atanasyan <simon@atanasyan.com> | 2015-05-31 20:36:58 +0000 |
commit | c140b41c39f7a5441ec07667484aa83f908cd0e8 (patch) | |
tree | 3bf0d480f7a54f49e2c7742ed7ca47e6528d9bc6 | |
parent | c90c425735c2b803616c19dab30fcb73a1b5b9ed (diff) | |
download | bcm5719-llvm-c140b41c39f7a5441ec07667484aa83f908cd0e8.tar.gz bcm5719-llvm-c140b41c39f7a5441ec07667484aa83f908cd0e8.zip |
[Mips] Sort segments so PT_MIPS_ABIFLAGS goes right after the PT_INTERP
llvm-svn: 238687
-rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp | 20 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h | 1 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/SegmentChunks.h | 2 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/TargetLayout.cpp | 6 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/TargetLayout.h | 3 | ||||
-rw-r--r-- | lld/test/elf/Mips/abi-flags-02.test | 4 | ||||
-rw-r--r-- | lld/test/elf/Mips/abi-flags-09.test | 67 |
7 files changed, 99 insertions, 4 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp index c80f1565365..1d62c1d7db3 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp @@ -78,6 +78,26 @@ uint64_t MipsTargetLayout<ELFT>::getLookupSectionFlags( return flags & ~llvm::ELF::SHF_MIPS_NOSTRIP; } +template <class ELFT> void MipsTargetLayout<ELFT>::sortSegments() { + using namespace llvm::ELF; + TargetLayout<ELFT>::sortSegments(); + // Move PT_MIPS_ABIFLAGS right after PT_INTERP. + auto abiIt = std::find_if(this->_segments.begin(), this->_segments.end(), + [](const Segment<ELFT> *s) { + return s->segmentType() == PT_MIPS_ABIFLAGS; + }); + if (abiIt == this->_segments.end()) + return; + Segment<ELFT> *abiSeg = *abiIt; + this->_segments.erase(abiIt); + auto outIt = std::find_if(this->_segments.begin(), this->_segments.end(), + [](const Segment<ELFT> *s) { + auto typ = s->segmentType(); + return typ != PT_PHDR && typ != PT_INTERP; + }); + this->_segments.insert(outIt, abiSeg); +} + template class MipsTargetLayout<ELF32LE>; template class MipsTargetLayout<ELF64LE>; diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h index 09431cb8280..a4099f70458 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h @@ -54,6 +54,7 @@ protected: unique_bump_ptr<RelocationTable<ELFT>> createRelocationTable(StringRef name, int32_t order) override; uint64_t getLookupSectionFlags(const OutputSection<ELFT> *os) const override; + void sortSegments() override; private: MipsGOTSection<ELFT> *_gotSection; diff --git a/lld/lib/ReaderWriter/ELF/SegmentChunks.h b/lld/lib/ReaderWriter/ELF/SegmentChunks.h index 2d8c34ee8eb..2882cdbbf94 100644 --- a/lld/lib/ReaderWriter/ELF/SegmentChunks.h +++ b/lld/lib/ReaderWriter/ELF/SegmentChunks.h @@ -157,7 +157,7 @@ public: int32_t sectionCount() const { return _sections.size(); } /// \brief, this function returns the type of segment (PT_*) - typename TargetLayout<ELFT>::SegmentType segmentType() { + typename TargetLayout<ELFT>::SegmentType segmentType() const { return _segmentType; } diff --git a/lld/lib/ReaderWriter/ELF/TargetLayout.cpp b/lld/lib/ReaderWriter/ELF/TargetLayout.cpp index 05c6dc8aa6c..87cbcd5cab5 100644 --- a/lld/lib/ReaderWriter/ELF/TargetLayout.cpp +++ b/lld/lib/ReaderWriter/ELF/TargetLayout.cpp @@ -439,11 +439,15 @@ template <class ELFT> void TargetLayout<ELFT>::assignSectionsToSegments() { } } +template <class ELFT> void TargetLayout<ELFT>::sortSegments() { + std::sort(_segments.begin(), _segments.end(), Segment<ELFT>::compareSegments); +} + template <class ELFT> void TargetLayout<ELFT>::assignVirtualAddress() { if (_segments.empty()) return; - std::sort(_segments.begin(), _segments.end(), Segment<ELFT>::compareSegments); + sortSegments(); uint64_t baseAddress = _ctx.getBaseAddress(); diff --git a/lld/lib/ReaderWriter/ELF/TargetLayout.h b/lld/lib/ReaderWriter/ELF/TargetLayout.h index 3642a757fcf..7162cd5fe08 100644 --- a/lld/lib/ReaderWriter/ELF/TargetLayout.h +++ b/lld/lib/ReaderWriter/ELF/TargetLayout.h @@ -302,6 +302,9 @@ protected: virtual uint64_t getLookupSectionFlags(const OutputSection<ELFT> *os) const; + /// \brief Sort segements stored in the _segments + virtual void sortSegments(); + protected: llvm::BumpPtrAllocator _allocator; SectionMapT _sectionMap; diff --git a/lld/test/elf/Mips/abi-flags-02.test b/lld/test/elf/Mips/abi-flags-02.test index 6436ddd19e7..33c50263592 100644 --- a/lld/test/elf/Mips/abi-flags-02.test +++ b/lld/test/elf/Mips/abi-flags-02.test @@ -26,8 +26,8 @@ # CHECK-NEXT: } # CHECK: ProgramHeaders [ -# CHECK: ProgramHeader { -# CHECK: Type: PT_MIPS_ABIFLAGS (0x70000003) +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_MIPS_ABIFLAGS (0x70000003) # CHECK-NEXT: Offset: 0x{{[0-9A-F]+}} # CHECK-NEXT: VirtualAddress: 0x{{[0-9A-F]+}} # CHECK-NEXT: PhysicalAddress: 0x{{[0-9A-F]+}} diff --git a/lld/test/elf/Mips/abi-flags-09.test b/lld/test/elf/Mips/abi-flags-09.test new file mode 100644 index 00000000000..8175466c708 --- /dev/null +++ b/lld/test/elf/Mips/abi-flags-09.test @@ -0,0 +1,67 @@ +# Check position of PT_MIPS_ABIFLAGS segment. +# It should go right after the PT_INTERP segment. + +# RUN: yaml2obj -format=elf %s > %t.o +# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t.o +# RUN: llvm-readobj -program-headers %t.exe | FileCheck %s + +# CHECK: ProgramHeader { +# CHECK: Type: PT_INTERP +# CHECK-NEXT: Offset: 0x{{[0-9A-F]+}} +# CHECK-NEXT: VirtualAddress: 0x{{[0-9A-F]+}} +# CHECK-NEXT: PhysicalAddress: 0x{{[0-9A-F]+}} +# CHECK-NEXT: FileSize: 13 +# CHECK-NEXT: MemSize: 13 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 1 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_MIPS_ABIFLAGS +# CHECK-NEXT: Offset: 0x{{[0-9A-F]+}} +# CHECK-NEXT: VirtualAddress: 0x{{[0-9A-F]+}} +# CHECK-NEXT: PhysicalAddress: 0x{{[0-9A-F]+}} +# CHECK-NEXT: FileSize: 24 +# CHECK-NEXT: MemSize: 24 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } + +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [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 ] + Size: 4 + AddressAlign: 16 + +- Name: .MIPS.abiflags + Type: SHT_MIPS_ABIFLAGS + AddressAlign: 8 + ISA: MIPS32 + ISARevision: 2 + ISAExtension: EXT_NONE + ASEs: [ MICROMIPS ] + FpABI: FP_XX + GPRSize: REG_32 + CPR1Size: REG_32 + CPR2Size: REG_NONE + Flags1: [ ] + Flags2: 0x0 + +Symbols: + Global: + - Name: T0 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 |