summaryrefslogtreecommitdiffstats
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2016-08-12 06:28:49 +0000
committerSimon Atanasyan <simon@atanasyan.com>2016-08-12 06:28:49 +0000
commit85c6b44817227d838a3f3385f707ecf42dc79713 (patch)
tree44760b50e24597364f822efef5081b85ac13d64c /lld/ELF/OutputSections.cpp
parent0f303accded1e45fdb897cf8cd7cd687ab26fdb1 (diff)
downloadbcm5719-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.cpp48
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>;
OpenPOWER on IntegriCloud