[lld] r238686 - [Mips] Reading, merging and writing .MIPS.abiflags section
Simon Atanasyan
simon at atanasyan.com
Sun May 31 13:36:43 PDT 2015
Author: atanasyan
Date: Sun May 31 15:36:43 2015
New Revision: 238686
URL: http://llvm.org/viewvc/llvm-project?rev=238686&view=rev
Log:
[Mips] Reading, merging and writing .MIPS.abiflags section
http://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking
Added:
lld/trunk/test/elf/Mips/abi-flags-01.test
lld/trunk/test/elf/Mips/abi-flags-02.test
lld/trunk/test/elf/Mips/abi-flags-03.test
lld/trunk/test/elf/Mips/abi-flags-04.test
lld/trunk/test/elf/Mips/abi-flags-05.test
lld/trunk/test/elf/Mips/abi-flags-06.test
lld/trunk/test/elf/Mips/abi-flags-07.test
lld/trunk/test/elf/Mips/abi-flags-08.test
Modified:
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp?rev=238686&r1=238685&r2=238686&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp Sun May 31 15:36:43 2015
@@ -12,41 +12,246 @@
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ELF.h"
+#include "llvm/Support/MipsABIFlags.h"
#include "llvm/Support/raw_ostream.h"
+using namespace lld;
+using namespace lld::elf;
+using namespace llvm;
using namespace llvm::ELF;
+using namespace llvm::Mips;
+
+namespace {
+
+// The joined set of MIPS ISAs and MIPS ISA extensions.
+enum MipsISAs {
+ ArchNone,
+
+ // General ISAs
+ Arch1,
+ Arch2,
+ Arch3,
+ Arch4,
+ Arch5,
+ Arch32,
+ Arch32r2,
+ Arch32r3,
+ Arch32r5,
+ Arch32r6,
+ Arch64,
+ Arch64r2,
+ Arch64r3,
+ Arch64r5,
+ Arch64r6,
+
+ // CPU specific ISAs
+ Arch3900,
+ Arch4010,
+ Arch4100,
+ Arch4111,
+ Arch4120,
+ Arch4650,
+ Arch5400,
+ Arch5500,
+ Arch5900,
+ Arch9000,
+ Arch10000,
+ ArchLs2e,
+ ArchLs2f,
+ ArchLs3a,
+ ArchOcteon,
+ ArchOcteonP,
+ ArchOcteon2,
+ ArchOcteon3,
+ ArchSB1,
+ ArchXLR
+};
struct MipsISATreeEdge {
- unsigned child;
- unsigned parent;
+ MipsISAs child;
+ MipsISAs parent;
+};
+
+struct ElfArchPair {
+ uint32_t _elfFlag;
+ MipsISAs _arch;
+};
+
+struct AbiIsaArchPair {
+ uint8_t _isaLevel;
+ uint8_t _isaRev;
+ uint8_t _isaExt;
+ MipsISAs _arch;
+};
+}
+
+static const MipsISATreeEdge isaTree[] = {
+ // MIPS32R6 and MIPS64R6 are not compatible with other extensions
+
+ // MIPS64R2 extensions.
+ {ArchOcteon3, ArchOcteon2},
+ {ArchOcteon2, ArchOcteonP},
+ {ArchOcteonP, ArchOcteon},
+ {ArchOcteon, Arch64r2},
+ {ArchLs3a, Arch64r2},
+
+ // MIPS64 extensions.
+ {Arch64r2, Arch64},
+ {ArchSB1, Arch64},
+ {ArchXLR, Arch64},
+
+ // MIPS V extensions.
+ {Arch64, Arch5},
+
+ // R5000 extensions.
+ {Arch5500, Arch5400},
+
+ // MIPS IV extensions.
+ {Arch5, Arch4},
+ {Arch5400, Arch4},
+ {Arch9000, Arch4},
+
+ // VR4100 extensions.
+ {Arch4120, Arch4100},
+ {Arch4111, Arch4100},
+
+ // MIPS III extensions.
+ {ArchLs2e, Arch3},
+ {ArchLs2f, Arch3},
+ {Arch4650, Arch3},
+ {Arch4100, Arch3},
+ {Arch4010, Arch3},
+ {Arch5900, Arch3},
+ {Arch4, Arch3},
+
+ // MIPS32 extensions.
+ {Arch32r2, Arch32},
+
+ // MIPS II extensions.
+ {Arch3, Arch2},
+ {Arch32, Arch2},
+
+ // MIPS I extensions.
+ {Arch3900, Arch1},
+ {Arch2, Arch1},
};
-static MipsISATreeEdge isaTree[] = {
- // MIPS32R6 and MIPS64R6 are not compatible with other extensions
+// Conversion ELF arch flags => MipsISAs
+static const ElfArchPair elfArchPairs[] = {
+ {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, Arch3900},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, Arch4010},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, Arch4100},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, Arch4111},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, Arch4120},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, Arch4650},
+ {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, Arch5400},
+ {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, Arch5500},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, Arch5900},
+ {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, Arch9000},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, ArchLs2e},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, ArchLs2f},
+ {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, ArchLs3a},
+ {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, ArchOcteon},
+ {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, ArchOcteon2},
+ {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, ArchOcteon3},
+ {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, ArchSB1},
+ {EF_MIPS_ARCH_64 | EF_MIPS_MACH_XLR, ArchXLR},
+ {EF_MIPS_ARCH_1, Arch1},
+ {EF_MIPS_ARCH_2, Arch2},
+ {EF_MIPS_ARCH_3, Arch3},
+ {EF_MIPS_ARCH_4, Arch4},
+ {EF_MIPS_ARCH_5, Arch5},
+ {EF_MIPS_ARCH_32, Arch32},
+ {EF_MIPS_ARCH_32R2, Arch32r2},
+ {EF_MIPS_ARCH_32R6, Arch32r6},
+ {EF_MIPS_ARCH_64, Arch64},
+ {EF_MIPS_ARCH_64R2, Arch64r2},
+ {EF_MIPS_ARCH_64R6, Arch64r6}
+};
- // MIPS64 extensions.
- {EF_MIPS_ARCH_64R2, EF_MIPS_ARCH_64},
- // MIPS V extensions.
- {EF_MIPS_ARCH_64, EF_MIPS_ARCH_5},
- // MIPS IV extensions.
- {EF_MIPS_ARCH_5, EF_MIPS_ARCH_4},
- // MIPS III extensions.
- {EF_MIPS_ARCH_4, EF_MIPS_ARCH_3},
- // MIPS32 extensions.
- {EF_MIPS_ARCH_32R2, EF_MIPS_ARCH_32},
- // MIPS II extensions.
- {EF_MIPS_ARCH_3, EF_MIPS_ARCH_2},
- {EF_MIPS_ARCH_32, EF_MIPS_ARCH_2},
- // MIPS I extensions.
- {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1},
+// Conversion MipsISAs => ELF arch flags
+static const ElfArchPair archElfPairs[] = {
+ {EF_MIPS_ARCH_1, Arch1},
+ {EF_MIPS_ARCH_2, Arch2},
+ {EF_MIPS_ARCH_3, Arch3},
+ {EF_MIPS_ARCH_4, Arch4},
+ {EF_MIPS_ARCH_5, Arch5},
+ {EF_MIPS_ARCH_32, Arch32},
+ {EF_MIPS_ARCH_32R2, Arch32r2},
+ {EF_MIPS_ARCH_32R2, Arch32r3},
+ {EF_MIPS_ARCH_32R2, Arch32r5},
+ {EF_MIPS_ARCH_32R6, Arch32r6},
+ {EF_MIPS_ARCH_64, Arch64},
+ {EF_MIPS_ARCH_64R2, Arch64r2},
+ {EF_MIPS_ARCH_64R2, Arch64r3},
+ {EF_MIPS_ARCH_64R2, Arch64r5},
+ {EF_MIPS_ARCH_64R6, Arch64r6},
+ {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, Arch3900},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, Arch4010},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, Arch4100},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, Arch4111},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, Arch4120},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, Arch4650},
+ {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, Arch5400},
+ {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, Arch5500},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, Arch5900},
+ {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, Arch9000},
+ {EF_MIPS_ARCH_4, Arch10000},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, ArchLs2e},
+ {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, ArchLs2f},
+ {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, ArchLs3a},
+ {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, ArchOcteon},
+ {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, ArchOcteonP},
+ {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, ArchOcteon2},
+ {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, ArchOcteon3},
+ {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, ArchSB1},
+ {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, ArchXLR}
};
-static bool matchMipsISA(unsigned base, unsigned ext) {
+// Conversion .MIPS.abiflags isa/level/extension <=> MipsISAs
+static const AbiIsaArchPair abiIsaArchPair[] = {
+ { 0, 0, 0, ArchNone},
+ { 1, 0, 0, Arch1},
+ { 2, 0, 0, Arch2},
+ { 3, 0, 0, Arch3},
+ { 4, 0, 0, Arch4},
+ { 5, 0, 0, Arch5},
+ {32, 1, 0, Arch32},
+ {32, 2, 0, Arch32r2},
+ {32, 3, 0, Arch32r3},
+ {32, 5, 0, Arch32r5},
+ {32, 6, 0, Arch32r6},
+ {64, 1, 0, Arch64},
+ {64, 2, 0, Arch64r2},
+ {64, 3, 0, Arch64r3},
+ {64, 5, 0, Arch64r5},
+ {64, 6, 0, Arch64r6},
+ { 1, 0, AFL_EXT_3900, Arch3900},
+ { 3, 0, AFL_EXT_4010, Arch4010},
+ { 3, 0, AFL_EXT_4100, Arch4100},
+ { 3, 0, AFL_EXT_4111, Arch4111},
+ { 3, 0, AFL_EXT_4120, Arch4120},
+ { 3, 0, AFL_EXT_4650, Arch4650},
+ { 4, 0, AFL_EXT_5400, Arch5400},
+ { 4, 0, AFL_EXT_5500, Arch5500},
+ { 3, 0, AFL_EXT_5900, Arch5900},
+ { 4, 0, AFL_EXT_10000, Arch10000},
+ { 3, 0, AFL_EXT_LOONGSON_2E, ArchLs2e},
+ { 3, 0, AFL_EXT_LOONGSON_2F, ArchLs2f},
+ {64, 2, AFL_EXT_LOONGSON_3A, ArchLs3a},
+ {64, 2, AFL_EXT_OCTEON, ArchOcteon},
+ {64, 2, AFL_EXT_OCTEON2, ArchOcteon2},
+ {64, 2, AFL_EXT_OCTEON3, ArchOcteon3},
+ {64, 1, AFL_EXT_SB1, ArchSB1},
+ {64, 1, AFL_EXT_XLR, ArchXLR}
+};
+
+static bool matchMipsISA(MipsISAs base, MipsISAs ext) {
if (base == ext)
return true;
- if (base == EF_MIPS_ARCH_32 && matchMipsISA(EF_MIPS_ARCH_64, ext))
+ if (base == Arch32 && matchMipsISA(Arch64, ext))
return true;
- if (base == EF_MIPS_ARCH_32R2 && matchMipsISA(EF_MIPS_ARCH_64R2, ext))
+ if (base == Arch32r2 && matchMipsISA(Arch64r2, ext))
return true;
for (const auto &edge : isaTree) {
if (ext == edge.child) {
@@ -58,84 +263,272 @@ static bool matchMipsISA(unsigned base,
return false;
}
+static bool is32BitElfFlags(unsigned flags) {
+ if (flags & EF_MIPS_32BITMODE)
+ return true;
+
+ unsigned arch = flags & EF_MIPS_ARCH;
+ if (arch == EF_MIPS_ARCH_1 || arch == EF_MIPS_ARCH_2 ||
+ arch == EF_MIPS_ARCH_32 || arch == EF_MIPS_ARCH_32R2 ||
+ arch == EF_MIPS_ARCH_32R6)
+ return true;
+
+ unsigned abi = flags & EF_MIPS_ABI;
+ if (abi == EF_MIPS_ABI_O32 || abi == EF_MIPS_ABI_EABI32)
+ return true;
+
+ return false;
+}
+
+static ErrorOr<MipsISAs> headerFlagsToIsa(uint32_t flags) {
+ uint32_t arch = flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
+ for (const auto &p : elfArchPairs)
+ if (p._elfFlag == arch)
+ return p._arch;
+ return make_dynamic_error_code(
+ StringRef("Unknown EF_MIPS_ARCH | EF_MIPS_MACH flags (0x") +
+ Twine::utohexstr(arch) + ")");
+}
+
+static uint32_t isaToHeaderFlags(unsigned isa) {
+ for (const auto &p : archElfPairs)
+ if (p._arch == isa)
+ return p._elfFlag;
+ llvm_unreachable("Unknown MIPS ISA");
+}
+
+static ErrorOr<uint32_t> flagsToAses(uint32_t flags) {
+ uint32_t ases = flags & EF_MIPS_ARCH_ASE;
+ switch (ases) {
+ case 0:
+ return 0;
+ case EF_MIPS_MICROMIPS:
+ return AFL_ASE_MICROMIPS;
+ case EF_MIPS_ARCH_ASE_M16:
+ return AFL_ASE_MIPS16;
+ case EF_MIPS_ARCH_ASE_MDMX:
+ return AFL_ASE_MDMX;
+ default:
+ return make_dynamic_error_code(
+ StringRef("Unknown EF_MIPS_ARCH_ASE flag (0x") +
+ Twine::utohexstr(ases) + ")");
+ }
+}
+
+static uint32_t asesToFlags(uint32_t ases) {
+ switch (ases) {
+ case AFL_ASE_MICROMIPS:
+ return EF_MIPS_MICROMIPS;
+ case AFL_ASE_MIPS16:
+ return EF_MIPS_ARCH_ASE_M16;
+ case AFL_ASE_MDMX:
+ return EF_MIPS_ARCH_ASE_MDMX;
+ default:
+ return 0;
+ }
+}
+
+static ErrorOr<MipsISAs> sectionFlagsToIsa(uint8_t isaLevel, uint8_t isaRev,
+ uint8_t isaExt) {
+ for (const auto &p : abiIsaArchPair)
+ if (p._isaLevel == isaLevel && p._isaRev == isaRev && p._isaExt == isaExt)
+ return p._arch;
+ return make_dynamic_error_code(
+ StringRef("Unknown ISA level/revision/extension ") + Twine(isaLevel) +
+ "/" + Twine(isaRev) + "/" + Twine(isaExt));
+}
+
+static std::tuple<uint8_t, uint8_t, uint32_t> isaToSectionFlags(unsigned isa) {
+ for (const auto &p : abiIsaArchPair)
+ if (p._arch == isa)
+ return std::make_tuple(p._isaLevel, p._isaRev, p._isaExt);
+ llvm_unreachable("Unknown MIPS ISA");
+}
+
+static bool checkCompatibility(const MipsAbiFlags &hdr,
+ const MipsAbiFlags &sec) {
+ uint32_t secIsa = ArchNone;
+ switch (sec._isa) {
+ case Arch32r3:
+ case Arch32r5:
+ secIsa = Arch32r2;
+ break;
+ case Arch64r3:
+ case Arch64r5:
+ secIsa = Arch64r2;
+ break;
+ default:
+ secIsa = sec._isa;
+ break;
+ }
+ if (secIsa != hdr._isa) {
+ llvm::errs() << "inconsistent ISA between .MIPS.abiflags "
+ "and ELF header e_flags field\n";
+ return false;
+ }
+ if ((sec._ases & hdr._ases) != hdr._ases) {
+ llvm::errs() << "inconsistent ASEs between .MIPS.abiflags "
+ "and ELF header e_flags field\n";
+ return false;
+ }
+ return true;
+}
+
+static int compareFpAbi(uint32_t fpA, uint32_t fpB) {
+ if (fpA == fpB)
+ return 0;
+ if (fpB == Val_GNU_MIPS_ABI_FP_ANY)
+ return 1;
+ if (fpB == Val_GNU_MIPS_ABI_FP_64A && fpA == Val_GNU_MIPS_ABI_FP_64)
+ return 1;
+ if (fpB != Val_GNU_MIPS_ABI_FP_XX)
+ return -1;
+ if (fpA == Val_GNU_MIPS_ABI_FP_DOUBLE || fpA == Val_GNU_MIPS_ABI_FP_64 ||
+ fpA == Val_GNU_MIPS_ABI_FP_64A)
+ return 1;
+ return -1;
+}
+
+static StringRef getFpAbiName(uint32_t fpAbi) {
+ switch (fpAbi) {
+ case Val_GNU_MIPS_ABI_FP_ANY:
+ return "<any>";
+ case Val_GNU_MIPS_ABI_FP_DOUBLE:
+ return "-mdouble-float";
+ case Val_GNU_MIPS_ABI_FP_SINGLE:
+ return "-msingle-float";
+ case Val_GNU_MIPS_ABI_FP_SOFT:
+ return "-msoft-float";
+ case Val_GNU_MIPS_ABI_FP_OLD_64:
+ return "-mips32r2 -mfp64 (old)";
+ case Val_GNU_MIPS_ABI_FP_XX:
+ return "-mfpxx";
+ case Val_GNU_MIPS_ABI_FP_64:
+ return "-mgp32 -mfp64";
+ case Val_GNU_MIPS_ABI_FP_64A:
+ return "-mgp32 -mfp64 -mno-odd-spreg";
+ default:
+ return "<unknown>";
+ }
+}
+
+static uint32_t selectFpAbiFlag(uint32_t oldFp, uint32_t newFp) {
+ if (compareFpAbi(newFp, oldFp) >= 0)
+ return newFp;
+ if (compareFpAbi(oldFp, newFp) < 0)
+ llvm::errs() << "FP ABI " << getFpAbiName(oldFp) << " is incompatible with "
+ << getFpAbiName(newFp) << "\n";
+ return oldFp;
+}
+
namespace lld {
namespace elf {
+template <class ELFT> uint32_t MipsAbiInfoHandler<ELFT>::getFlags() const {
+ std::lock_guard<std::mutex> lock(_mutex);
+ uint32_t flags = 0;
+ if (_abiFlags.hasValue()) {
+ flags |= isaToHeaderFlags(_abiFlags->_isa);
+ flags |= asesToFlags(_abiFlags->_ases);
+ flags |= _abiFlags->_abi;
+ flags |= _abiFlags->_isPic ? EF_MIPS_PIC : 0;
+ flags |= _abiFlags->_isCPic ? EF_MIPS_CPIC : 0;
+ flags |= _abiFlags->_isNoReorder ? EF_MIPS_NOREORDER : 0;
+ flags |= _abiFlags->_is32BitMode ? EF_MIPS_32BITMODE : 0;
+ flags |= _abiFlags->_isNan2008 ? EF_MIPS_NAN2008 : 0;
+ }
+ return flags;
+}
+
+template <class ELFT>
+llvm::Optional<typename MipsAbiInfoHandler<ELFT>::Elf_Mips_RegInfo>
+MipsAbiInfoHandler<ELFT>::getRegistersMask() const {
+ std::lock_guard<std::mutex> lock(_mutex);
+ return _regMask;
+}
+
+template <class ELFT>
+llvm::Optional<typename MipsAbiInfoHandler<ELFT>::Elf_Mips_ABIFlags>
+MipsAbiInfoHandler<ELFT>::getAbiFlags() const {
+ std::lock_guard<std::mutex> lock(_mutex);
+ if (!_hasAbiSection)
+ return llvm::Optional<Elf_Mips_ABIFlags>();
+
+ Elf_Mips_ABIFlags sec;
+ sec.version = 0;
+ std::tie(sec.isa_level, sec.isa_rev, sec.isa_ext) =
+ isaToSectionFlags(_abiFlags->_isa);
+ sec.gpr_size = _abiFlags->_gprSize;
+ sec.cpr1_size = _abiFlags->_cpr1Size;
+ sec.cpr2_size = _abiFlags->_cpr2Size;
+ sec.fp_abi = _abiFlags->_fpAbi;
+ sec.ases = _abiFlags->_ases;
+ sec.flags1 = _abiFlags->_flags1;
+ sec.flags2 = 0;
+ return sec;
+}
+
template <class ELFT>
-std::error_code MipsAbiInfoHandler<ELFT>::mergeFlags(uint32_t newFlags) {
+std::error_code
+MipsAbiInfoHandler<ELFT>::mergeFlags(uint32_t newFlags,
+ const Elf_Mips_ABIFlags *newSec) {
+ std::lock_guard<std::mutex> lock(_mutex);
+
+ ErrorOr<MipsAbiFlags> abiFlags = createAbiFlags(newFlags, newSec);
+ if (auto ec = abiFlags.getError())
+ return ec;
+
// We support two ABI: O32 and N64. The last one does not have
// the corresponding ELF flag.
- uint32_t inAbi = newFlags & EF_MIPS_ABI;
uint32_t supportedAbi = ELFT::Is64Bits ? 0 : uint32_t(EF_MIPS_ABI_O32);
- if (inAbi != supportedAbi)
+ if (abiFlags->_abi != supportedAbi)
return make_dynamic_error_code("Unsupported ABI");
- // ... and reduced set of architectures ...
- uint32_t newArch = newFlags & EF_MIPS_ARCH;
- switch (newArch) {
- case EF_MIPS_ARCH_1:
- case EF_MIPS_ARCH_2:
- case EF_MIPS_ARCH_3:
- case EF_MIPS_ARCH_4:
- case EF_MIPS_ARCH_5:
- case EF_MIPS_ARCH_32:
- case EF_MIPS_ARCH_64:
- case EF_MIPS_ARCH_32R2:
- case EF_MIPS_ARCH_64R2:
- case EF_MIPS_ARCH_32R6:
- case EF_MIPS_ARCH_64R6:
- break;
- default:
- return make_dynamic_error_code("Unsupported instruction set");
- }
-
// ... and still do not support MIPS-16 extension.
- if (newFlags & EF_MIPS_ARCH_ASE_M16)
+ if (abiFlags->_ases & AFL_ASE_MIPS16)
return make_dynamic_error_code("Unsupported extension: MIPS16");
// PIC code is inherently CPIC and may not set CPIC flag explicitly.
// Ensure that this flag will exist in the linked file.
- if (newFlags & EF_MIPS_PIC)
- newFlags |= EF_MIPS_CPIC;
-
- std::lock_guard<std::mutex> lock(_mutex);
+ if (abiFlags->_isPic)
+ abiFlags->_isCPic = true;
// If the old set of flags is empty, use the new one as a result.
- if (!_flags) {
- _flags = newFlags;
+ if (!_abiFlags.hasValue()) {
+ _abiFlags = *abiFlags;
return std::error_code();
}
// Check PIC / CPIC flags compatibility.
- uint32_t newPic = newFlags & (EF_MIPS_PIC | EF_MIPS_CPIC);
- uint32_t oldPic = _flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
-
- if ((newPic != 0) != (oldPic != 0))
+ if (abiFlags->_isCPic != _abiFlags->_isCPic)
llvm::errs() << "lld warning: linking abicalls and non-abicalls files\n";
- if (!(newPic & EF_MIPS_PIC))
- _flags &= ~EF_MIPS_PIC;
- if (newPic)
- _flags |= EF_MIPS_CPIC;
+ if (!abiFlags->_isPic)
+ _abiFlags->_isPic = false;
+ if (abiFlags->_isCPic)
+ _abiFlags->_isCPic = true;
// Check mixing -mnan=2008 / -mnan=legacy modules.
- if ((newFlags & EF_MIPS_NAN2008) != (_flags & EF_MIPS_NAN2008))
+ if (abiFlags->_isNan2008 != _abiFlags->_isNan2008)
return make_dynamic_error_code(
"Linking -mnan=2008 and -mnan=legacy modules");
// Check ISA compatibility and update the extension flag.
- uint32_t oldArch = _flags & EF_MIPS_ARCH;
- if (!matchMipsISA(newArch, oldArch)) {
- if (!matchMipsISA(oldArch, newArch))
+ if (!matchMipsISA(MipsISAs(abiFlags->_isa), MipsISAs(_abiFlags->_isa))) {
+ if (!matchMipsISA(MipsISAs(_abiFlags->_isa), MipsISAs(abiFlags->_isa)))
return make_dynamic_error_code("Linking modules with incompatible ISA");
- _flags &= ~EF_MIPS_ARCH;
- _flags |= newArch;
+ _abiFlags->_isa = abiFlags->_isa;
}
- _flags |= newFlags & EF_MIPS_NOREORDER;
- _flags |= newFlags & EF_MIPS_MICROMIPS;
- _flags |= newFlags & EF_MIPS_NAN2008;
- _flags |= newFlags & EF_MIPS_32BITMODE;
+ _abiFlags->_ases |= abiFlags->_ases;
+ _abiFlags->_isNoReorder = _abiFlags->_isNoReorder || abiFlags->_isNoReorder;
+ _abiFlags->_is32BitMode = _abiFlags->_is32BitMode || abiFlags->_is32BitMode;
+
+ _abiFlags->_fpAbi = selectFpAbiFlag(_abiFlags->_fpAbi, abiFlags->_fpAbi);
+ _abiFlags->_gprSize = std::max(_abiFlags->_gprSize, abiFlags->_gprSize);
+ _abiFlags->_cpr1Size = std::max(_abiFlags->_cpr1Size, abiFlags->_cpr1Size);
+ _abiFlags->_cpr2Size = std::max(_abiFlags->_cpr2Size, abiFlags->_cpr2Size);
+ _abiFlags->_flags1 |= abiFlags->_flags1;
return std::error_code();
}
@@ -155,6 +548,80 @@ void MipsAbiInfoHandler<ELFT>::mergeRegi
_regMask->ri_cprmask[3] = _regMask->ri_cprmask[3] | info.ri_cprmask[3];
}
+template <class ELFT>
+ErrorOr<MipsAbiFlags>
+MipsAbiInfoHandler<ELFT>::createAbiFlags(uint32_t flags,
+ const Elf_Mips_ABIFlags *sec) {
+ ErrorOr<MipsAbiFlags> hdrFlags = createAbiFromHeaderFlags(flags);
+ if (auto ec = hdrFlags.getError())
+ return ec;
+ if (!sec)
+ return *hdrFlags;
+ ErrorOr<MipsAbiFlags> secFlags = createAbiFromSection(*sec);
+ if (auto ec = secFlags.getError())
+ return ec;
+ if (!checkCompatibility(*hdrFlags, *secFlags))
+ return *hdrFlags;
+
+ _hasAbiSection = true;
+
+ secFlags->_abi = hdrFlags->_abi;
+ secFlags->_isPic = hdrFlags->_isPic;
+ secFlags->_isCPic = hdrFlags->_isCPic;
+ secFlags->_isNoReorder = hdrFlags->_isNoReorder;
+ secFlags->_is32BitMode = hdrFlags->_is32BitMode;
+ secFlags->_isNan2008 = hdrFlags->_isNan2008;
+ return *secFlags;
+}
+
+template <class ELFT>
+ErrorOr<MipsAbiFlags>
+MipsAbiInfoHandler<ELFT>::createAbiFromHeaderFlags(uint32_t flags) {
+ MipsAbiFlags abi;
+ ErrorOr<MipsISAs> isa = headerFlagsToIsa(flags);
+ if (auto ec = isa.getError())
+ return ec;
+ abi._isa = *isa;
+
+ abi._fpAbi = Val_GNU_MIPS_ABI_FP_ANY;
+ abi._cpr1Size = AFL_REG_NONE;
+ abi._cpr2Size = AFL_REG_NONE;
+ abi._gprSize = is32BitElfFlags(flags) ? AFL_REG_32 : AFL_REG_64;
+
+ ErrorOr<uint32_t> ases = flagsToAses(flags);
+ if (auto ec = ases.getError())
+ return ec;
+ abi._ases = *ases;
+ abi._flags1 = 0;
+ abi._abi = flags & EF_MIPS_ABI;
+ abi._isPic = flags & EF_MIPS_PIC;
+ abi._isCPic = flags & EF_MIPS_CPIC;
+ abi._isNoReorder = flags & EF_MIPS_NOREORDER;
+ abi._is32BitMode = flags & EF_MIPS_32BITMODE;
+ abi._isNan2008 = flags & EF_MIPS_NAN2008;
+ return abi;
+}
+
+template <class ELFT>
+ErrorOr<MipsAbiFlags>
+MipsAbiInfoHandler<ELFT>::createAbiFromSection(const Elf_Mips_ABIFlags &sec) {
+ MipsAbiFlags abi;
+ ErrorOr<MipsISAs> isa =
+ sectionFlagsToIsa(sec.isa_level, sec.isa_rev, sec.isa_ext);
+ if (auto ec = isa.getError())
+ return ec;
+ abi._isa = *isa;
+ abi._fpAbi = sec.fp_abi;
+ abi._cpr1Size = sec.cpr1_size;
+ abi._cpr2Size = sec.cpr2_size;
+ abi._gprSize = sec.gpr_size;
+ abi._ases = sec.ases;
+ abi._flags1 = sec.flags1;
+ if (sec.flags2 != 0)
+ return make_dynamic_error_code("unexpected non-zero 'flags2' value");
+ return abi;
+}
+
template class MipsAbiInfoHandler<ELF32LE>;
template class MipsAbiInfoHandler<ELF64LE>;
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h?rev=238686&r1=238685&r2=238686&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h Sun May 31 15:36:43 2015
@@ -11,33 +11,60 @@
#include "llvm/ADT/Optional.h"
#include "llvm/Object/ELFTypes.h"
+#include "llvm/Support/ErrorOr.h"
#include <mutex>
#include <system_error>
namespace lld {
namespace elf {
+struct MipsAbiFlags {
+ unsigned _isa = 0;
+ unsigned _fpAbi = 0;
+ unsigned _ases = 0;
+ unsigned _flags1 = 0;
+ unsigned _gprSize = 0;
+ unsigned _cpr1Size = 0;
+ unsigned _cpr2Size = 0;
+
+ unsigned _abi = 0;
+
+ bool _isPic = false;
+ bool _isCPic = false;
+ bool _isNoReorder = false;
+ bool _is32BitMode = false;
+ bool _isNan2008 = false;
+};
+
template <class ELFT> class MipsAbiInfoHandler {
public:
typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
+ typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
MipsAbiInfoHandler() = default;
- uint32_t getFlags() const { return _flags; }
- const llvm::Optional<Elf_Mips_RegInfo> &getRegistersMask() const {
- return _regMask;
- }
+ uint32_t getFlags() const;
+ llvm::Optional<Elf_Mips_RegInfo> getRegistersMask() const;
+ llvm::Optional<Elf_Mips_ABIFlags> getAbiFlags() const;
/// \brief Merge saved ELF header flags and the new set of flags.
- std::error_code mergeFlags(uint32_t newFlags);
+ std::error_code mergeFlags(uint32_t newFlags,
+ const Elf_Mips_ABIFlags *newAbi);
/// \brief Merge saved and new sets of registers usage masks.
void mergeRegistersMask(const Elf_Mips_RegInfo &info);
private:
- std::mutex _mutex;
- uint32_t _flags = 0;
+ mutable std::mutex _mutex;
+ bool _hasAbiSection = false;
+ llvm::Optional<MipsAbiFlags> _abiFlags;
llvm::Optional<Elf_Mips_RegInfo> _regMask;
+
+ llvm::ErrorOr<MipsAbiFlags> createAbiFlags(uint32_t flags,
+ const Elf_Mips_ABIFlags *sec);
+ static llvm::ErrorOr<MipsAbiFlags> createAbiFromHeaderFlags(uint32_t flags);
+ static llvm::ErrorOr<MipsAbiFlags>
+ createAbiFromSection(const Elf_Mips_ABIFlags &sec);
};
} // namespace elf
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp?rev=238686&r1=238685&r2=238686&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp Sun May 31 15:36:43 2015
@@ -9,6 +9,7 @@
#include "MipsELFFile.h"
#include "MipsTargetHandler.h"
+#include "llvm/ADT/StringExtras.h"
namespace lld {
namespace elf {
@@ -156,6 +157,31 @@ MipsELFFile<ELFT>::findRegInfoSec() cons
return nullptr;
}
+template <class ELFT>
+ErrorOr<const typename MipsELFFile<ELFT>::Elf_Mips_ABIFlags *>
+MipsELFFile<ELFT>::findAbiFlagsSec() const {
+ const Elf_Shdr *sec = findSectionByType(SHT_MIPS_ABIFLAGS);
+ if (!sec)
+ return nullptr;
+
+ auto contents = this->getSectionContents(sec);
+ if (std::error_code ec = contents.getError())
+ return ec;
+
+ ArrayRef<uint8_t> raw = contents.get();
+ if (raw.size() != sizeof(Elf_Mips_ABIFlags))
+ return make_dynamic_error_code(
+ StringRef("Invalid size of MIPS_ABIFLAGS section"));
+
+ const auto *abi = reinterpret_cast<const Elf_Mips_ABIFlags *>(raw.data());
+ if (abi->version != 0)
+ return make_dynamic_error_code(
+ StringRef(".MIPS.abiflags section has unsupported version '") +
+ llvm::utostr(abi->version) + "'");
+
+ return abi;
+}
+
template <class ELFT> std::error_code MipsELFFile<ELFT>::readAuxData() {
using namespace llvm::ELF;
if (const Elf_Shdr *sec = findSectionByFlags(SHF_TLS)) {
@@ -175,8 +201,12 @@ template <class ELFT> std::error_code Mi
_gp0 = regInfo->ri_gp_value;
}
+ ErrorOr<const Elf_Mips_ABIFlags *> abiFlagsSec = findAbiFlagsSec();
+ if (auto ec = abiFlagsSec.getError())
+ return ec;
+
const Elf_Ehdr *hdr = this->_objFile->getHeader();
- if (std::error_code ec = abi.mergeFlags(hdr->e_flags))
+ if (std::error_code ec = abi.mergeFlags(hdr->e_flags, abiFlagsSec.get()))
return ec;
return std::error_code();
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h?rev=238686&r1=238685&r2=238686&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h Sun May 31 15:36:43 2015
@@ -100,8 +100,10 @@ private:
typedef typename llvm::object::ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
+ typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
ErrorOr<const Elf_Mips_RegInfo *> findRegInfoSec() const;
+ ErrorOr<const Elf_Mips_ABIFlags*> findAbiFlagsSec() const;
std::error_code readAuxData();
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp?rev=238686&r1=238685&r2=238686&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp Sun May 31 15:36:43 2015
@@ -85,6 +85,16 @@ MipsELFWriter<ELFT>::createOptionsSectio
}
template <class ELFT>
+unique_bump_ptr<Section<ELFT>>
+MipsELFWriter<ELFT>::createAbiFlagsSection(llvm::BumpPtrAllocator &alloc) {
+ typedef unique_bump_ptr<Section<ELFT>> Ptr;
+ const auto &abi = _abiInfo.getAbiFlags();
+ if (!abi.hasValue())
+ return Ptr();
+ return Ptr(new (alloc) MipsAbiFlagsSection<ELFT>(_ctx, _targetLayout, *abi));
+}
+
+template <class ELFT>
void MipsELFWriter<ELFT>::setAtomValue(StringRef name, uint64_t value) {
AtomLayout *atom = _targetLayout.findAbsoluteAtom(name);
assert(atom);
@@ -117,6 +127,9 @@ void MipsDynamicLibraryWriter<ELFT>::cre
_reginfo = _writeHelper.createOptionsSection(this->_alloc);
if (_reginfo)
this->_layout.addSection(_reginfo.get());
+ _abiFlags = _writeHelper.createAbiFlagsSection(this->_alloc);
+ if (_abiFlags)
+ this->_layout.addSection(_abiFlags.get());
}
template <class ELFT>
@@ -235,6 +248,9 @@ template <class ELFT> void MipsExecutabl
_reginfo = _writeHelper.createOptionsSection(this->_alloc);
if (_reginfo)
this->_layout.addSection(_reginfo.get());
+ _abiFlags = _writeHelper.createAbiFlagsSection(this->_alloc);
+ if (_abiFlags)
+ this->_layout.addSection(_abiFlags.get());
}
template <class ELFT>
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h?rev=238686&r1=238685&r2=238686&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h Sun May 31 15:36:43 2015
@@ -31,6 +31,8 @@ public:
std::unique_ptr<RuntimeFile<ELFT>> createRuntimeFile();
unique_bump_ptr<Section<ELFT>>
createOptionsSection(llvm::BumpPtrAllocator &alloc);
+ unique_bump_ptr<Section<ELFT>>
+ createAbiFlagsSection(llvm::BumpPtrAllocator &alloc);
private:
MipsLinkingContext &_ctx;
@@ -64,6 +66,7 @@ private:
MipsELFWriter<ELFT> _writeHelper;
MipsTargetLayout<ELFT> &_targetLayout;
unique_bump_ptr<Section<ELFT>> _reginfo;
+ unique_bump_ptr<Section<ELFT>> _abiFlags;
};
template <class ELFT>
@@ -90,6 +93,7 @@ private:
MipsELFWriter<ELFT> _writeHelper;
MipsTargetLayout<ELFT> &_targetLayout;
unique_bump_ptr<Section<ELFT>> _reginfo;
+ unique_bump_ptr<Section<ELFT>> _abiFlags;
};
} // elf
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp?rev=238686&r1=238685&r2=238686&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp Sun May 31 15:36:43 2015
@@ -89,6 +89,37 @@ template class MipsOptionsSection<ELF32L
template class MipsOptionsSection<ELF64LE>;
template <class ELFT>
+MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(
+ const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout,
+ const Elf_Mips_ABIFlags &abiFlags)
+ : Section<ELFT>(ctx, ".MIPS.abiflags", "MipsAbiFlags"), _abiFlags(abiFlags),
+ _targetLayout(targetLayout) {
+ this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_ABI_FLAGS);
+ this->_alignment = 8;
+ this->_fsize = llvm::RoundUpToAlignment(sizeof(_abiFlags), this->_alignment);
+ this->_msize = this->_fsize;
+ this->_entSize = this->_fsize;
+ this->_type = SHT_MIPS_ABIFLAGS;
+ this->_flags = SHF_ALLOC;
+}
+
+template <class ELFT>
+void MipsAbiFlagsSection<ELFT>::write(ELFWriter *writer,
+ TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
+ uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
+ std::memcpy(dest, &_abiFlags, this->_fsize);
+}
+
+template <class ELFT> void MipsAbiFlagsSection<ELFT>::finalize() {
+ if (this->_outputSection)
+ this->_outputSection->setType(this->_type);
+}
+
+template class MipsAbiFlagsSection<ELF32LE>;
+template class MipsAbiFlagsSection<ELF64LE>;
+
+template <class ELFT>
MipsGOTSection<ELFT>::MipsGOTSection(const MipsLinkingContext &ctx)
: AtomSection<ELFT>(ctx, ".got", DefinedAtom::typeGOT, DefinedAtom::permRW_,
MipsTargetLayout<ELFT>::ORDER_GOT),
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h?rev=238686&r1=238685&r2=238686&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h Sun May 31 15:36:43 2015
@@ -60,6 +60,26 @@ private:
MipsTargetLayout<ELFT> &_targetLayout;
};
+/// \brief Handle .MIPS.abiflags section
+template <class ELFT> class MipsAbiFlagsSection : public Section<ELFT> {
+public:
+ typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
+
+ MipsAbiFlagsSection(const ELFLinkingContext &ctx,
+ MipsTargetLayout<ELFT> &targetLayout,
+ const Elf_Mips_ABIFlags &abiFlags);
+
+ bool hasOutputSegment() const override { return true; }
+
+ void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) override;
+ void finalize() override;
+
+private:
+ Elf_Mips_ABIFlags _abiFlags;
+ MipsTargetLayout<ELFT> &_targetLayout;
+};
+
/// \brief Handle Mips GOT section
template <class ELFT> class MipsGOTSection : public AtomSection<ELFT> {
public:
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp?rev=238686&r1=238685&r2=238686&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp Sun May 31 15:36:43 2015
@@ -38,6 +38,8 @@ MipsTargetLayout<ELFT>::getSegmentType(S
return llvm::ELF::PT_MIPS_REGINFO;
case ORDER_MIPS_OPTIONS:
return llvm::ELF::PT_LOAD;
+ case ORDER_MIPS_ABI_FLAGS:
+ return llvm::ELF::PT_MIPS_ABIFLAGS;
default:
return TargetLayout<ELFT>::getSegmentType(section);
}
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h?rev=238686&r1=238685&r2=238686&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h Sun May 31 15:36:43 2015
@@ -21,8 +21,9 @@ class MipsLinkingContext;
template <class ELFT> class MipsTargetLayout final : public TargetLayout<ELFT> {
public:
enum MipsSectionOrder {
- ORDER_MIPS_REGINFO = TargetLayout<ELFT>::ORDER_RO_NOTE + 1,
- ORDER_MIPS_OPTIONS
+ ORDER_MIPS_ABI_FLAGS = TargetLayout<ELFT>::ORDER_RO_NOTE + 1,
+ ORDER_MIPS_REGINFO,
+ ORDER_MIPS_OPTIONS,
};
MipsTargetLayout(MipsLinkingContext &ctx);
Added: lld/trunk/test/elf/Mips/abi-flags-01.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/abi-flags-01.test?rev=238686&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/abi-flags-01.test (added)
+++ lld/trunk/test/elf/Mips/abi-flags-01.test Sun May 31 15:36:43 2015
@@ -0,0 +1,35 @@
+# Check rejecting .MIPS.abiflags section with a wrong version.
+
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: not lld -flavor gnu -target mipsel -shared -o %t.so %t.o 2>&1 \
+# RUN: | FileCheck %s
+
+# CHECK: {{.*}}abi-flags-01.test.tmp.o: .MIPS.abiflags section has unsupported version '1'
+
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R6]
+
+Sections:
+- Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Size: 4
+ AddressAlign: 16
+
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ Version: 1
+ ISA: MIPS32
+
+Symbols:
+ Global:
+ - Name: T0
+ Section: .text
+ Type: STT_FUNC
+ Value: 0
+ Size: 4
Added: lld/trunk/test/elf/Mips/abi-flags-02.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/abi-flags-02.test?rev=238686&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/abi-flags-02.test (added)
+++ lld/trunk/test/elf/Mips/abi-flags-02.test Sun May 31 15:36:43 2015
@@ -0,0 +1,92 @@
+# Check generation of .MIPS.abiflags section under the following conditions:
+# - There is the only input object file
+# - The input file has valid .MIPS.abiflags section
+#
+# The .MIPS.abiflags section in the output file should have the same
+# settings as the input section.
+
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.o
+# RUN: llvm-readobj -s -program-headers -mips-abi-flags %t.so | FileCheck %s
+
+# CHECK: Section {
+# CHECK: Index: 1
+# CHECK-NEXT: Name: .MIPS.abiflags
+# CHECK-NEXT: Type: SHT_MIPS_ABIFLAGS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x{{[0-9A-F]+}}
+# CHECK-NEXT: Offset: 0x{{[0-9A-F]+}}
+# CHECK-NEXT: Size: 24
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 8
+# CHECK-NEXT: EntrySize: 24
+# CHECK-NEXT: }
+
+# CHECK: ProgramHeaders [
+# CHECK: ProgramHeader {
+# CHECK: 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]+}}
+# CHECK-NEXT: FileSize: 24
+# CHECK-NEXT: MemSize: 24
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: PF_R
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 8
+# CHECK-NEXT: }
+
+# CHECK: MIPS ABI Flags {
+# CHECK-NEXT: Version: 0
+# CHECK-NEXT: ISA: MIPS32r2
+# CHECK-NEXT: ISA Extension: None (0x0)
+# CHECK-NEXT: ASEs [ (0x800)
+# CHECK-NEXT: microMIPS (0x800)
+# CHECK-NEXT: ]
+# CHECK-NEXT: FP ABI: Hard float (32-bit CPU, Any FPU) (0x5)
+# CHECK-NEXT: GPR size: 32
+# CHECK-NEXT: CPR1 size: 32
+# CHECK-NEXT: CPR2 size: 0
+# CHECK-NEXT: Flags 1 [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Flags 2: 0x0
+# CHECK-NEXT: }
+
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [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 ]
+ 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
Added: lld/trunk/test/elf/Mips/abi-flags-03.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/abi-flags-03.test?rev=238686&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/abi-flags-03.test (added)
+++ lld/trunk/test/elf/Mips/abi-flags-03.test Sun May 31 15:36:43 2015
@@ -0,0 +1,149 @@
+# Check generation of .MIPS.abiflags section under the following conditions:
+# - There are multiple input object files
+# - Every input file has valid .MIPS.abiflags section
+# - All .MIPS.abiflags sections are compatible with each other
+#
+# The .MIPS.abiflags section in the output file should reproduce result
+# of merging input object file sections.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t1.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t2.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t3.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t1.o %t2.o %t3.o
+# RUN: llvm-readobj -mips-abi-flags %t.so | FileCheck %s
+
+# CHECK: MIPS ABI Flags {
+# CHECK-NEXT: Version: 0
+# CHECK-NEXT: ISA: MIPS32r2
+# CHECK-NEXT: ISA Extension: None (0x0)
+# CHECK-NEXT: ASEs [ (0x810)
+# CHECK-NEXT: MDMX (0x10)
+# CHECK-NEXT: microMIPS (0x800)
+# CHECK-NEXT: ]
+# CHECK-NEXT: FP ABI: Hard float (double precision) (0x1)
+# CHECK-NEXT: GPR size: 32
+# CHECK-NEXT: CPR1 size: 64
+# CHECK-NEXT: CPR2 size: 0
+# CHECK-NEXT: Flags 1 [ (0x1)
+# CHECK-NEXT: ODDSPREG
+# CHECK-NEXT: ]
+# CHECK-NEXT: Flags 2: 0x0
+# CHECK-NEXT: }
+
+# o1.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+ EF_MIPS_ARCH_32, EF_MIPS_ARCH_ASE_MDMX]
+
+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: 1
+ ISAExtension: EXT_NONE
+ ASEs: [ MDMX ]
+ FpABI: FP_DOUBLE
+ GPRSize: REG_32
+ CPR1Size: REG_64
+ CPR2Size: REG_NONE
+ Flags1: [ ]
+ Flags2: 0x0
+
+Symbols:
+ Global:
+ - Name: T1
+ Section: .text
+ Type: STT_FUNC
+ Value: 0
+ Size: 4
+
+# o2.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [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 ]
+ 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: [ODDSPREG]
+ Flags2: 0x0
+
+Symbols:
+ Global:
+ - Name: T2
+ Section: .text
+ Type: STT_FUNC
+ Value: 0
+ Size: 4
+
+# o3.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [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 ]
+ 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: T3
+ Section: .text
+ Type: STT_FUNC
+ Value: 0
+ Size: 4
+...
Added: lld/trunk/test/elf/Mips/abi-flags-04.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/abi-flags-04.test?rev=238686&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/abi-flags-04.test (added)
+++ lld/trunk/test/elf/Mips/abi-flags-04.test Sun May 31 15:36:43 2015
@@ -0,0 +1,125 @@
+# Check generation of .MIPS.abiflags section under the following conditions:
+# - There are multiple input object files
+# - Every input file has valid .MIPS.abiflags section
+# - .MIPS.abiflags sections have different but compatible FP ABI
+#
+# The .MIPS.abiflags section in the output file should reproduce result
+# of merging FP ABI flags.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-xx.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-double.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-64.o
+# RUN: yaml2obj -format=elf -docnum 4 %s > %t-64a.o
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t1 %t-xx.o %t-double.o
+# RUN: llvm-readobj -mips-abi-flags %t1 | FileCheck -check-prefix=XX-DOUBLE %s
+
+# XX-DOUBLE: FP ABI: Hard float (double precision) (0x1)
+# XX-DOUBLE: GPR size: 32
+# XX-DOUBLE: CPR1 size: 32
+# XX-DOUBLE: Flags 1 [ (0x0)
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t2 %t-xx.o %t-64.o
+# RUN: llvm-readobj -mips-abi-flags %t2 | FileCheck -check-prefix=XX-64 %s
+
+# XX-64: FP ABI: Hard float (32-bit CPU, 64-bit FPU) (0x6)
+# XX-64: GPR size: 32
+# XX-64: CPR1 size: 64
+# XX-64: Flags 1 [ (0x1)
+# XX-64: ODDSPREG (0x1)
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t3 %t-xx.o %t-64a.o
+# RUN: llvm-readobj -mips-abi-flags %t3 | FileCheck -check-prefix=XX-64A %s
+
+# XX-64A: FP ABI: Hard float compat (32-bit CPU, 64-bit FPU) (0x7)
+# XX-64A: GPR size: 32
+# XX-64A: CPR1 size: 64
+# XX-64A: Flags 1 [ (0x0)
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t4 %t-64.o %t-64a.o
+# RUN: llvm-readobj -mips-abi-flags %t4 | FileCheck -check-prefix=64-64A %s
+
+# 64-64A: FP ABI: Hard float (32-bit CPU, 64-bit FPU) (0x6)
+# 64-64A: GPR size: 32
+# 64-64A: CPR1 size: 64
+# 64-64A: Flags 1 [ (0x1)
+# 64-64A: ODDSPREG (0x1)
+
+# xx.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 1
+ FpABI: FP_XX
+ GPRSize: REG_32
+ CPR1Size: REG_32
+
+# double.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 1
+ FpABI: FP_DOUBLE
+ GPRSize: REG_32
+ CPR1Size: REG_32
+
+# 64.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 2
+ FpABI: FP_64
+ GPRSize: REG_32
+ CPR1Size: REG_64
+ Flags1: [ODDSPREG]
+
+# 64a.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 2
+ FpABI: FP_64A
+ GPRSize: REG_32
+ CPR1Size: REG_64
+ Flags1: []
+...
Added: lld/trunk/test/elf/Mips/abi-flags-05.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/abi-flags-05.test?rev=238686&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/abi-flags-05.test (added)
+++ lld/trunk/test/elf/Mips/abi-flags-05.test Sun May 31 15:36:43 2015
@@ -0,0 +1,186 @@
+# Check generation of .MIPS.abiflags section under the following conditions:
+# - There are multiple input object files
+# - Every input file has valid .MIPS.abiflags section
+# - .MIPS.abiflags sections have different and incompatible FP ABI
+#
+# The .MIPS.abiflags section in the output file should reproduce result
+# of merging FP ABI flags but the linker must show a warning.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-xx.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-dbl.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-sgl.o
+# RUN: yaml2obj -format=elf -docnum 4 %s > %t-soft.o
+# RUN: yaml2obj -format=elf -docnum 5 %s > %t-64.o
+# RUN: yaml2obj -format=elf -docnum 6 %s > %t-64a.o
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t1 %t-xx.o %t-sgl.o 2>&1 \
+# RUN: | FileCheck -check-prefix=XX-SINGLE-WARN %s
+
+# XX-SINGLE-WARN: FP ABI {{-mfpxx|-msingle-float}} is incompatible with {{-msingle-float|-mfpxx}}
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t2 %t-xx.o %t-soft.o 2>&1 \
+# RUN: | FileCheck -check-prefix=XX-SOFT-WARN %s
+
+# XX-SOFT-WARN: FP ABI {{-mfpxx|-msoft-float}} is incompatible with {{-msoft-float|-mfpxx}}
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t3 %t-dbl.o %t-sgl.o 2>&1 \
+# RUN: | FileCheck -check-prefix=DOUBLE-SINGLE-WARN %s
+
+# DOUBLE-SINGLE-WARN: FP ABI {{-mdouble-float|-msingle-float}} is incompatible with {{-msingle-float|-mdouble-float}}
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t4 %t-dbl.o %t-soft.o 2>&1 \
+# RUN: | FileCheck -check-prefix=DOUBLE-SOFT-WARN %s
+
+# DOUBLE-SOFT-WARN: FP ABI {{-mdouble-float|-msoft-float}} is incompatible with {{-msoft-float|-mdouble-float}}
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t5 %t-dbl.o %t-64.o 2>&1 \
+# RUN: | FileCheck -check-prefix=DOUBLE-64-WARN %s
+
+# DOUBLE-64-WARN: FP ABI {{-mdouble-float|-mgp32 -mfp64}} is incompatible with {{-mgp32 -mfp64|-mdouble-float}}
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t6 %t-dbl.o %t-64a.o 2>&1 \
+# RUN: | FileCheck -check-prefix=DOUBLE-64A-WARN %s
+
+# DOUBLE-64A-WARN: FP ABI {{-mdouble-float|-mgp32 -mfp64 -mno-odd-spreg}} is incompatible with {{-mgp32 -mfp64 -mno-odd-spreg|-mdouble-float}}
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t7 %t-sgl.o %t-soft.o 2>&1 \
+# RUN: | FileCheck -check-prefix=SINGLE-SOFT-WARN %s
+
+# SINGLE-SOFT-WARN: FP ABI {{-msingle-float|-msoft-float}} is incompatible with {{-msoft-float|-msingle-float}}
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t8 %t-sgl.o %t-64.o 2>&1 \
+# RUN: | FileCheck -check-prefix=SINGLE-64-WARN %s
+
+# SINGLE-64-WARN: FP ABI {{-msingle-float|-mgp32 -mfp64}} is incompatible with {{-mgp32 -mfp64|-msingle-float}}
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t9 %t-sgl.o %t-64a.o 2>&1 \
+# RUN: | FileCheck -check-prefix=SINGLE-64A-WARN %s
+
+# SINGLE-64A-WARN: FP ABI {{-msingle-float|-mgp32 -mfp64 -mno-odd-spreg}} is incompatible with {{-mgp32 -mfp64 -mno-odd-spreg|-msingle-float}}
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t10 %t-soft.o %t-64.o 2>&1 \
+# RUN: | FileCheck -check-prefix=SOFT-64-WARN %s
+
+# SOFT-64-WARN: FP ABI {{-msoft-float|-mgp32 -mfp64}} is incompatible with {{-mgp32 -mfp64|-msoft-float}}
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t11 %t-soft.o %t-64a.o 2>&1 \
+# RUN: | FileCheck -check-prefix=SOFT-64A-WARN %s
+
+# SOFT-64A-WARN: FP ABI {{-msoft-float|-mgp32 -mfp64 -mno-odd-spreg}} is incompatible with {{-mgp32 -mfp64 -mno-odd-spreg|-msoft-float}}
+
+# xx.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 1
+ FpABI: FP_XX
+ GPRSize: REG_32
+ CPR1Size: REG_32
+
+# double.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 1
+ FpABI: FP_DOUBLE
+ GPRSize: REG_32
+ CPR1Size: REG_32
+
+# single.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 1
+ FpABI: FP_SINGLE
+ GPRSize: REG_32
+ CPR1Size: REG_32
+
+# soft.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 1
+ FpABI: FP_SOFT
+ GPRSize: REG_32
+ CPR1Size: REG_NONE
+
+# 64.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 2
+ FpABI: FP_64
+ GPRSize: REG_32
+ CPR1Size: REG_64
+ Flags1: [ODDSPREG]
+
+# 64a.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 2
+ FpABI: FP_64A
+ GPRSize: REG_32
+ CPR1Size: REG_64
+ Flags1: []
+...
Added: lld/trunk/test/elf/Mips/abi-flags-06.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/abi-flags-06.test?rev=238686&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/abi-flags-06.test (added)
+++ lld/trunk/test/elf/Mips/abi-flags-06.test Sun May 31 15:36:43 2015
@@ -0,0 +1,79 @@
+# Check generation of .MIPS.abiflags section under the following conditions:
+# - There are multiple input object files
+# - Not all input files have a .MIPS.abiflags section
+#
+# The .MIPS.abiflags section in the output file should reproduce result
+# of merging input object file sections and data come from ELF header flags.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-abi.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-elf.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-abi.o %t-elf.o
+# RUN: llvm-readobj -mips-abi-flags %t.so | FileCheck %s
+
+# CHECK: MIPS ABI Flags {
+# CHECK-NEXT: Version: 0
+# CHECK-NEXT: ISA: MIPS32r2
+# CHECK-NEXT: ISA Extension: None (0x0)
+# CHECK-NEXT: ASEs [ (0x810)
+# CHECK-NEXT: MDMX (0x10)
+# CHECK-NEXT: microMIPS (0x800)
+# CHECK-NEXT: ]
+# CHECK-NEXT: FP ABI: Hard float (double precision) (0x1)
+# CHECK-NEXT: GPR size: 32
+# CHECK-NEXT: CPR1 size: 64
+# CHECK-NEXT: CPR2 size: 0
+# CHECK-NEXT: Flags 1 [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Flags 2: 0x0
+# CHECK-NEXT: }
+
+# abi.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+ EF_MIPS_ARCH_32, EF_MIPS_ARCH_ASE_MDMX]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 1
+ ISAExtension: EXT_NONE
+ ASEs: [ MDMX ]
+ FpABI: FP_DOUBLE
+ GPRSize: REG_32
+ CPR1Size: REG_64
+ CPR2Size: REG_NONE
+ Flags1: [ ]
+ Flags2: 0x0
+
+# elf.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [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 ]
+ Size: 4
+ AddressAlign: 16
+
+Symbols:
+ Global:
+ - Name: T0
+ Section: .text
+ Type: STT_FUNC
+ Value: 0
+ Size: 4
+...
Added: lld/trunk/test/elf/Mips/abi-flags-07.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/abi-flags-07.test?rev=238686&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/abi-flags-07.test (added)
+++ lld/trunk/test/elf/Mips/abi-flags-07.test Sun May 31 15:36:43 2015
@@ -0,0 +1,60 @@
+# Check that .MIPS.abiflags section is not written if no input object files
+# contain that section.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t1.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t2.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t1.o %t2.o
+# RUN: llvm-readobj -mips-abi-flags %t.so | FileCheck %s
+
+# CHECK: There is no .MIPS.abiflags section in the file.
+
+# abi.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+ EF_MIPS_ARCH_32, EF_MIPS_ARCH_ASE_MDMX]
+
+Sections:
+- Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Size: 4
+ AddressAlign: 16
+
+Symbols:
+ Global:
+ - Name: T0
+ Section: .text
+ Type: STT_FUNC
+ Value: 0
+ Size: 4
+
+# elf.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [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 ]
+ Size: 4
+ AddressAlign: 16
+
+Symbols:
+ Global:
+ - Name: T1
+ Section: .text
+ Type: STT_FUNC
+ Value: 0
+ Size: 4
+...
Added: lld/trunk/test/elf/Mips/abi-flags-08.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/abi-flags-08.test?rev=238686&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/abi-flags-08.test (added)
+++ lld/trunk/test/elf/Mips/abi-flags-08.test Sun May 31 15:36:43 2015
@@ -0,0 +1,71 @@
+# Check that the linker shows errors if ELF header flags
+# and .MIPS.abiflags section are incompatible.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-isa.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-ext.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-ases.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t1.so %t-isa.o 2>&1 \
+# RUN: | FileCheck -check-prefix=ISA-ERR %s
+# RUN: lld -flavor gnu -target mipsel -shared -o %t2.so %t-ext.o 2>&1 \
+# RUN: | FileCheck -check-prefix=EXT-ERR %s
+# RUN: lld -flavor gnu -target mipsel -shared -o %t3.so %t-ases.o 2>&1 \
+# RUN: | FileCheck -check-prefix=ASE-ERR %s
+# RUN: llvm-readobj -mips-abi-flags %t1.so %t2.so %t3.so \
+# RUN: | FileCheck -check-prefix=SEC %s
+
+# ISA-ERR: inconsistent ISA between .MIPS.abiflags and ELF header e_flags field
+# EXT-ERR: inconsistent ISA between .MIPS.abiflags and ELF header e_flags field
+# ASE-ERR: inconsistent ASEs between .MIPS.abiflags and ELF header e_flags field
+
+# SEC: There is no .MIPS.abiflags section in the file.
+
+# isa.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 2
+
+# ext.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_3, EF_MIPS_MACH_4650]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS3
+ ISAExtension: EXT_4120
+
+# ases.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+- Name: .MIPS.abiflags
+ Type: SHT_MIPS_ABIFLAGS
+ AddressAlign: 8
+ ISA: MIPS32
+ ISARevision: 2
+ ASEs: []
+
+...
More information about the llvm-commits
mailing list