forked from OSchip/llvm-project
Convert MipsReginfoSection to SyntheticSection.
llvm-svn: 287614
This commit is contained in:
parent
12f2da870e
commit
b71cae90de
|
@ -221,30 +221,46 @@ template <class ELFT> void MipsOptionsSection<ELFT>::finalize() {
|
||||||
|
|
||||||
// MIPS .reginfo section.
|
// MIPS .reginfo section.
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
MipsReginfoSection<ELFT>::MipsReginfoSection()
|
MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo Reginfo)
|
||||||
: InputSection<ELFT>(SHF_ALLOC, SHT_MIPS_REGINFO, 4, ArrayRef<uint8_t>(),
|
: SyntheticSection<ELFT>(SHF_ALLOC, SHT_MIPS_REGINFO, 4, ".reginfo"),
|
||||||
".reginfo") {
|
Reginfo(Reginfo) {}
|
||||||
auto Func = [this](ObjectFile<ELFT> *F, ArrayRef<uint8_t> D) {
|
|
||||||
if (D.size() != sizeof(Elf_Mips_RegInfo)) {
|
|
||||||
error(getFilename(F) + ": invalid size of .reginfo section");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(D.data());
|
|
||||||
if (Config->Relocatable && R->ri_gp_value)
|
|
||||||
error(getFilename(F) + ": unsupported non-zero ri_gp_value");
|
|
||||||
Reginfo.ri_gprmask |= R->ri_gprmask;
|
|
||||||
F->MipsGp0 = R->ri_gp_value;
|
|
||||||
};
|
|
||||||
iterateSectionContents<ELFT>(SHT_MIPS_REGINFO, Func);
|
|
||||||
|
|
||||||
this->Data = ArrayRef<uint8_t>((const uint8_t *)&Reginfo, sizeof(Reginfo));
|
template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||||
// Section should be alive for O32 and N32 ABIs only.
|
|
||||||
this->Live = !ELFT::Is64Bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT> void MipsReginfoSection<ELFT>::finalize() {
|
|
||||||
if (!Config->Relocatable)
|
if (!Config->Relocatable)
|
||||||
Reginfo.ri_gp_value = In<ELFT>::MipsGot->getVA() + MipsGPOffset;
|
Reginfo.ri_gp_value = In<ELFT>::MipsGot->getVA() + MipsGPOffset;
|
||||||
|
memcpy(Buf, &Reginfo, sizeof(Reginfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() {
|
||||||
|
// Section should be alive for O32 and N32 ABIs only.
|
||||||
|
if (ELFT::Is64Bits)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
Elf_Mips_RegInfo Reginfo = {};
|
||||||
|
bool Create = false;
|
||||||
|
|
||||||
|
for (InputSectionBase<ELFT> *Sec : Symtab<ELFT>::X->Sections) {
|
||||||
|
if (!Sec->Live || Sec->Type != SHT_MIPS_REGINFO)
|
||||||
|
continue;
|
||||||
|
Sec->Live = false;
|
||||||
|
Create = true;
|
||||||
|
|
||||||
|
if (Sec->Data.size() != sizeof(Elf_Mips_RegInfo)) {
|
||||||
|
error(getFilename(Sec->getFile()) + ": invalid size of .reginfo section");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->Data.data());
|
||||||
|
if (Config->Relocatable && R->ri_gp_value)
|
||||||
|
error(getFilename(Sec->getFile()) + ": unsupported non-zero ri_gp_value");
|
||||||
|
|
||||||
|
Reginfo.ri_gprmask |= R->ri_gprmask;
|
||||||
|
Sec->getFile()->MipsGp0 = R->ri_gp_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Create)
|
||||||
|
return make<MipsReginfoSection<ELFT>>(Reginfo);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ArrayRef<uint8_t> createInterp() {
|
static ArrayRef<uint8_t> createInterp() {
|
||||||
|
|
|
@ -35,19 +35,6 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// MIPS .reginfo section.
|
|
||||||
template <class ELFT>
|
|
||||||
class MipsReginfoSection final : public InputSection<ELFT> {
|
|
||||||
typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MipsReginfoSection();
|
|
||||||
void finalize();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Elf_Mips_RegInfo Reginfo = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ELFT> class SyntheticSection : public InputSection<ELFT> {
|
template <class ELFT> class SyntheticSection : public InputSection<ELFT> {
|
||||||
typedef typename ELFT::uint uintX_t;
|
typedef typename ELFT::uint uintX_t;
|
||||||
|
|
||||||
|
@ -593,6 +580,22 @@ private:
|
||||||
Elf_Mips_ABIFlags Flags;
|
Elf_Mips_ABIFlags Flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// MIPS .reginfo section.
|
||||||
|
template <class ELFT>
|
||||||
|
class MipsReginfoSection final : public SyntheticSection<ELFT> {
|
||||||
|
typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static MipsReginfoSection *create();
|
||||||
|
|
||||||
|
MipsReginfoSection(Elf_Mips_RegInfo Reginfo);
|
||||||
|
size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); }
|
||||||
|
void writeTo(uint8_t *Buf) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Elf_Mips_RegInfo Reginfo;
|
||||||
|
};
|
||||||
|
|
||||||
template <class ELFT> InputSection<ELFT> *createCommonSection();
|
template <class ELFT> InputSection<ELFT> *createCommonSection();
|
||||||
template <class ELFT> InputSection<ELFT> *createInterpSection();
|
template <class ELFT> InputSection<ELFT> *createInterpSection();
|
||||||
template <class ELFT> MergeInputSection<ELFT> *createCommentSection();
|
template <class ELFT> MergeInputSection<ELFT> *createCommentSection();
|
||||||
|
|
|
@ -318,10 +318,9 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
||||||
Symtab<ELFT>::X->Sections.push_back(OptSec);
|
Symtab<ELFT>::X->Sections.push_back(OptSec);
|
||||||
}
|
}
|
||||||
// MIPS .reginfo
|
// MIPS .reginfo
|
||||||
auto *RegSec = make<MipsReginfoSection<ELFT>>();
|
if (auto *Sec = MipsReginfoSection<ELFT>::create()) {
|
||||||
if (RegSec->Live) {
|
In<ELFT>::MipsReginfo = Sec;
|
||||||
In<ELFT>::MipsReginfo = RegSec;
|
Symtab<ELFT>::X->Sections.push_back(Sec);
|
||||||
Symtab<ELFT>::X->Sections.push_back(RegSec);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1500,10 +1499,8 @@ template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
|
||||||
template <class ELFT> void Writer<ELFT>::writeSections() {
|
template <class ELFT> void Writer<ELFT>::writeSections() {
|
||||||
uint8_t *Buf = Buffer->getBufferStart();
|
uint8_t *Buf = Buffer->getBufferStart();
|
||||||
|
|
||||||
// Finalize MIPS .reginfo and .MIPS.options sections
|
// Finalize MIPS .MIPS.options sections because that contains
|
||||||
// because they contain offsets to .got and _gp.
|
// offsets to .got and _gp.
|
||||||
if (In<ELFT>::MipsReginfo)
|
|
||||||
In<ELFT>::MipsReginfo->finalize();
|
|
||||||
if (In<ELFT>::MipsOptions)
|
if (In<ELFT>::MipsOptions)
|
||||||
In<ELFT>::MipsOptions->finalize();
|
In<ELFT>::MipsOptions->finalize();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue