summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2015-05-31 20:36:58 +0000
committerSimon Atanasyan <simon@atanasyan.com>2015-05-31 20:36:58 +0000
commitc140b41c39f7a5441ec07667484aa83f908cd0e8 (patch)
tree3bf0d480f7a54f49e2c7742ed7ca47e6528d9bc6
parentc90c425735c2b803616c19dab30fcb73a1b5b9ed (diff)
downloadbcm5719-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.cpp20
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h1
-rw-r--r--lld/lib/ReaderWriter/ELF/SegmentChunks.h2
-rw-r--r--lld/lib/ReaderWriter/ELF/TargetLayout.cpp6
-rw-r--r--lld/lib/ReaderWriter/ELF/TargetLayout.h3
-rw-r--r--lld/test/elf/Mips/abi-flags-02.test4
-rw-r--r--lld/test/elf/Mips/abi-flags-09.test67
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
OpenPOWER on IntegriCloud