Files
clang-p2996/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
Denis Protivensky cdc1246750 [ELF] Apply segments from linker scripts
Put sections to segments according to linker scripts if available.
Rework the code of TargetLayout::assignSectionsToSegments so it operates
on the given list of segments, which can be either read from linker scripts
or constructed as before.
Handle NONE segments defined in linker scripts by putting corresponding sections
to PT_NULL segment.
Consider flags set for segments through linker scripts.

Differential Revision: http://reviews.llvm.org/D10918

llvm-svn: 243002
2015-07-23 10:34:30 +00:00

112 lines
4.0 KiB
C++

//===- lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp ---------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MipsLinkingContext.h"
#include "MipsTargetLayout.h"
namespace lld {
namespace elf {
template <class ELFT>
MipsTargetLayout<ELFT>::MipsTargetLayout(MipsLinkingContext &ctx,
MipsAbiInfoHandler<ELFT> &abi)
: TargetLayout<ELFT>(ctx), _abiInfo(abi),
_gotSection(new (this->_allocator) MipsGOTSection<ELFT>(ctx)),
_pltSection(new (this->_allocator) MipsPLTSection<ELFT>(ctx)) {}
template <class ELFT>
AtomSection<ELFT> *MipsTargetLayout<ELFT>::createSection(
StringRef name, int32_t type, DefinedAtom::ContentPermissions permissions,
typename TargetLayout<ELFT>::SectionOrder order) {
if (type == DefinedAtom::typeGOT && name == ".got")
return _gotSection;
if (type == DefinedAtom::typeStub && name == ".plt")
return _pltSection;
return TargetLayout<ELFT>::createSection(name, type, permissions, order);
}
template <class ELFT>
typename TargetLayout<ELFT>::SegmentType
MipsTargetLayout<ELFT>::getSegmentType(const Section<ELFT> *section) const {
switch (section->order()) {
case ORDER_MIPS_REGINFO:
return _abiInfo.hasMipsAbiSection() ? llvm::ELF::PT_LOAD
: 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);
}
}
template <class ELFT> uint64_t MipsTargetLayout<ELFT>::getGPAddr() {
std::call_once(_gpOnce, [this]() {
if (AtomLayout *a = this->findAbsoluteAtom("_gp"))
_gpAddr = a->_virtualAddr;
});
return _gpAddr;
}
template <class ELFT>
typename TargetLayout<ELFT>::SectionOrder
MipsTargetLayout<ELFT>::getSectionOrder(StringRef name, int32_t contentType,
int32_t contentPermissions) {
if ((contentType == DefinedAtom::typeStub) && (name.startswith(".text")))
return TargetLayout<ELFT>::ORDER_TEXT;
return TargetLayout<ELFT>::getSectionOrder(name, contentType,
contentPermissions);
}
template <class ELFT>
unique_bump_ptr<RelocationTable<ELFT>>
MipsTargetLayout<ELFT>::createRelocationTable(StringRef name, int32_t order) {
return unique_bump_ptr<RelocationTable<ELFT>>(new (
this->_allocator) MipsRelocationTable<ELFT>(this->_ctx, name, order));
}
template <class ELFT>
uint64_t MipsTargetLayout<ELFT>::getLookupSectionFlags(
const OutputSection<ELFT> *os) const {
uint64_t flags = TargetLayout<ELFT>::getLookupSectionFlags(os);
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 or PT_MIPS_REGINFO right after PT_INTERP.
auto abiIt =
std::find_if(this->_segments.begin(), this->_segments.end(),
[](const Segment<ELFT> *s) {
auto typ = s->segmentType();
return typ == PT_MIPS_ABIFLAGS || typ == PT_MIPS_REGINFO;
});
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<ELF32BE>;
template class MipsTargetLayout<ELF32LE>;
template class MipsTargetLayout<ELF64BE>;
template class MipsTargetLayout<ELF64LE>;
} // end namespace elf
} // end namespace lld