diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2016-08-12 06:28:49 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2016-08-12 06:28:49 +0000 |
| commit | 85c6b44817227d838a3f3385f707ecf42dc79713 (patch) | |
| tree | 44760b50e24597364f822efef5081b85ac13d64c /lld/ELF/OutputSections.cpp | |
| parent | 0f303accded1e45fdb897cf8cd7cd687ab26fdb1 (diff) | |
| download | bcm5719-llvm-85c6b44817227d838a3f3385f707ecf42dc79713.tar.gz bcm5719-llvm-85c6b44817227d838a3f3385f707ecf42dc79713.zip | |
[ELF][MIPS] Support .MIPS.abiflags section
This section supersedes .reginfo and .MIPS.options sections. But for now
we have to support all three sections for ABI transition period.
llvm-svn: 278482
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 8371fe473ba..139e67505c7 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1738,6 +1738,46 @@ void MipsOptionsOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) { } template <class ELFT> +MipsAbiFlagsOutputSection<ELFT>::MipsAbiFlagsOutputSection() + : OutputSectionBase<ELFT>(".MIPS.abiflags", SHT_MIPS_ABIFLAGS, SHF_ALLOC) { + this->Header.sh_addralign = 8; + this->Header.sh_entsize = sizeof(Elf_Mips_ABIFlags); + this->Header.sh_size = sizeof(Elf_Mips_ABIFlags); + memset(&Flags, 0, sizeof(Flags)); +} + +template <class ELFT> +void MipsAbiFlagsOutputSection<ELFT>::writeTo(uint8_t *Buf) { + memcpy(Buf, &Flags, sizeof(Flags)); +} + +template <class ELFT> +void MipsAbiFlagsOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) { + // Check compatibility and merge fields from input .MIPS.abiflags + // to the output one. + auto *S = cast<MipsAbiFlagsInputSection<ELFT>>(C); + S->OutSec = this; + if (S->Flags->version != 0) { + error(getFilename(S->getFile()) + ": unexpected .MIPS.abiflags version " + + Twine(S->Flags->version)); + return; + } + // LLD checks ISA compatibility in getMipsEFlags(). Here we just + // select the highest number of ISA/Rev/Ext. + Flags.isa_level = std::max(Flags.isa_level, S->Flags->isa_level); + Flags.isa_rev = std::max(Flags.isa_rev, S->Flags->isa_rev); + Flags.isa_ext = std::max(Flags.isa_ext, S->Flags->isa_ext); + Flags.gpr_size = std::max(Flags.gpr_size, S->Flags->gpr_size); + Flags.cpr1_size = std::max(Flags.cpr1_size, S->Flags->cpr1_size); + Flags.cpr2_size = std::max(Flags.cpr2_size, S->Flags->cpr2_size); + Flags.ases |= S->Flags->ases; + Flags.flags1 |= S->Flags->flags1; + Flags.flags2 |= S->Flags->flags2; + Flags.fp_abi = elf::getMipsFpAbiFlag(Flags.fp_abi, S->Flags->fp_abi, + getFilename(S->getFile())); +} + +template <class ELFT> std::pair<OutputSectionBase<ELFT> *, bool> OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C, StringRef OutsecName) { @@ -1762,6 +1802,9 @@ OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C, case InputSectionBase<ELFT>::MipsOptions: Sec = new MipsOptionsOutputSection<ELFT>(); break; + case InputSectionBase<ELFT>::MipsAbiFlags: + Sec = new MipsAbiFlagsOutputSection<ELFT>(); + break; case InputSectionBase<ELFT>::Layout: llvm_unreachable("Invalid section type"); } @@ -1891,6 +1934,11 @@ template class MipsOptionsOutputSection<ELF32BE>; template class MipsOptionsOutputSection<ELF64LE>; template class MipsOptionsOutputSection<ELF64BE>; +template class MipsAbiFlagsOutputSection<ELF32LE>; +template class MipsAbiFlagsOutputSection<ELF32BE>; +template class MipsAbiFlagsOutputSection<ELF64LE>; +template class MipsAbiFlagsOutputSection<ELF64BE>; + template class MergeOutputSection<ELF32LE>; template class MergeOutputSection<ELF32BE>; template class MergeOutputSection<ELF64LE>; |

