[lld] r248215 - Make InputSection able to relocate itself.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 23 18:03:44 PDT 2015
Thanks!
On Mon, Sep 21, 2015 at 3:01 PM, Rafael Espindola via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: rafael
> Date: Mon Sep 21 17:01:00 2015
> New Revision: 248215
>
> URL: http://llvm.org/viewvc/llvm-project?rev=248215&view=rev
> Log:
> Make InputSection able to relocate itself.
>
> This matches the organization used in COFF.
>
> Modified:
> lld/trunk/ELF/Chunks.cpp
> lld/trunk/ELF/Chunks.h
> lld/trunk/ELF/OutputSections.cpp
> lld/trunk/ELF/OutputSections.h
>
> Modified: lld/trunk/ELF/Chunks.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Chunks.cpp?rev=248215&r1=248214&r2=248215&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Chunks.cpp (original)
> +++ lld/trunk/ELF/Chunks.cpp Mon Sep 21 17:01:00 2015
> @@ -10,9 +10,13 @@
> #include "Chunks.h"
> #include "Error.h"
> #include "InputFiles.h"
> +#include "OutputSections.h"
> +
> +#include "llvm/Support/raw_ostream.h"
>
> using namespace llvm;
> using namespace llvm::ELF;
> +using namespace llvm::object;
>
> using namespace lld;
> using namespace lld::elf2;
> @@ -21,12 +25,134 @@ template <class ELFT>
> InputSection<ELFT>::InputSection(ObjectFile<ELFT> *F, const Elf_Shdr
> *Header)
> : File(F), Header(Header) {}
>
> -template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
> +template <class ELFT>
> +void InputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rel &Rel,
> + uint32_t Type, uintX_t BaseAddr,
> + uintX_t SymVA) {
> + uintX_t Offset = Rel.r_offset;
> + uint8_t *Location = Buf + Offset;
> + switch (Type) {
> + case R_386_32:
> + support::endian::write32le(Location, SymVA);
> + break;
> + default:
> + llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';
> + break;
> + }
> +}
> +
> +template <class ELFT>
> +void InputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rela &Rel,
> + uint32_t Type, uintX_t BaseAddr,
> + uintX_t SymVA) {
> + uintX_t Offset = Rel.r_offset;
> + uint8_t *Location = Buf + Offset;
> + switch (Type) {
> + case R_X86_64_PC32:
> + support::endian::write32le(Location,
> + SymVA + (Rel.r_addend - (BaseAddr +
> Offset)));
> + break;
> + case R_X86_64_64:
> + support::endian::write64le(Location, SymVA + Rel.r_addend);
> + break;
> + case R_X86_64_32: {
> + case R_X86_64_32S:
> + uint64_t VA = SymVA + Rel.r_addend;
> + if (Type == R_X86_64_32 && !isUInt<32>(VA))
> + error("R_X86_64_32 out of range");
> + else if (!isInt<32>(VA))
> + error("R_X86_64_32S out of range");
> +
> + support::endian::write32le(Location, VA);
> + break;
> + }
> + default:
> + llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';
> + break;
> + }
> +}
> +
> +template <class ELFT>
> +template <bool isRela>
> +void InputSection<ELFT>::relocate(
> + uint8_t *Buf, iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels,
> + const ObjectFile<ELFT> &File, uintX_t BaseAddr,
> + const PltSection<ELFT> &PltSec, const GotSection<ELFT> &GotSec) {
> + typedef Elf_Rel_Impl<ELFT, isRela> RelType;
> + bool IsMips64EL = File.getObj()->isMips64EL();
> + for (const RelType &RI : Rels) {
> + uint32_t SymIndex = RI.getSymbol(IsMips64EL);
> + uint32_t Type = RI.getType(IsMips64EL);
> + uintX_t SymVA;
> +
> + // Handle relocations for local symbols -- they never get
> + // resolved so we don't allocate a SymbolBody.
> + const Elf_Shdr *SymTab = File.getSymbolTable();
> + if (SymIndex < SymTab->sh_info) {
> + const Elf_Sym *Sym = File.getObj()->getRelocationSymbol(&RI,
> SymTab);
> + if (!Sym)
> + continue;
> + SymVA = getLocalSymVA(Sym, File);
> + } else {
> + const SymbolBody *Body = File.getSymbolBody(SymIndex);
> + if (!Body)
> + continue;
> + switch (Body->kind()) {
> + case SymbolBody::DefinedRegularKind:
> + SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));
> + break;
> + case SymbolBody::DefinedAbsoluteKind:
> + SymVA = cast<DefinedAbsolute<ELFT>>(Body)->Sym.st_value;
> + break;
> + case SymbolBody::DefinedCommonKind: {
> + auto *DC = cast<DefinedCommon<ELFT>>(Body);
> + SymVA = DC->OutputSec->getVA() + DC->OffsetInBSS;
> + break;
> + }
> + case SymbolBody::SharedKind:
> + if (relocNeedsPLT(Type)) {
> + SymVA = PltSec.getEntryAddr(*Body);
> + Type = R_X86_64_PC32;
> + } else if (relocNeedsGOT(Type)) {
> + SymVA = GotSec.getEntryAddr(*Body);
> + Type = R_X86_64_PC32;
> + } else {
> + continue;
> + }
> + break;
> + case SymbolBody::UndefinedKind:
> + assert(Body->isWeak() && "Undefined symbol reached writer");
> + SymVA = 0;
> + break;
> + case SymbolBody::LazyKind:
> + llvm_unreachable("Lazy symbol reached writer");
> + }
> + }
> +
> + relocateOne(Buf, RI, Type, BaseAddr, SymVA);
> + }
> +}
> +
> +template <class ELFT>
> +void InputSection<ELFT>::writeTo(uint8_t *Buf, const PltSection<ELFT>
> &PltSec,
> + const GotSection<ELFT> &GotSec) {
> if (Header->sh_type == SHT_NOBITS)
> return;
> // Copy section contents from source object file to output file.
> ArrayRef<uint8_t> Data = *File->getObj()->getSectionContents(Header);
> memcpy(Buf + OutputSectionOff, Data.data(), Data.size());
> +
> + const ObjectFile<ELFT> *File = getFile();
> + ELFFile<ELFT> *EObj = File->getObj();
> + uint8_t *Base = Buf + getOutputSectionOff();
> + uintX_t BaseAddr = Out->getVA() + getOutputSectionOff();
> + // Iterate over all relocation sections that apply to this section.
> + for (const Elf_Shdr *RelSec : RelocSections) {
> + if (RelSec->sh_type == SHT_RELA)
> + relocate(Base, EObj->relas(RelSec), *File, BaseAddr, PltSec,
> GotSec);
> + else
> + relocate(Base, EObj->rels(RelSec), *File, BaseAddr, PltSec, GotSec);
> + }
> }
>
> template <class ELFT> StringRef InputSection<ELFT>::getSectionName()
> const {
>
> Modified: lld/trunk/ELF/Chunks.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Chunks.h?rev=248215&r1=248214&r2=248215&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Chunks.h (original)
> +++ lld/trunk/ELF/Chunks.h Mon Sep 21 17:01:00 2015
> @@ -18,12 +18,15 @@ namespace elf2 {
>
> template <class ELFT> class ObjectFile;
> template <class ELFT> class OutputSection;
> +template <class ELFT> class PltSection;
> +template <class ELFT> class GotSection;
>
> // A chunk corresponding a section of an input file.
> template <class ELFT> class InputSection {
> typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
> typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
> typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
> + typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
> typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
>
> public:
> @@ -34,7 +37,8 @@ public:
>
> // Write this chunk to a mmap'ed file, assuming Buf is pointing to
> // beginning of the output section.
> - void writeTo(uint8_t *Buf);
> + void writeTo(uint8_t *Buf, const PltSection<ELFT> &PltSec,
> + const GotSection<ELFT> &GotSec);
>
> StringRef getSectionName() const;
> const Elf_Shdr *getSectionHdr() const { return Header; }
> @@ -56,6 +60,18 @@ public:
> SmallVector<const Elf_Shdr *, 1> RelocSections;
>
> private:
> + void relocateOne(uint8_t *Buf, const Elf_Rela &Rel, uint32_t Type,
> + uintX_t BaseAddr, uintX_t SymVA);
> + void relocateOne(uint8_t *Buf, const Elf_Rel &Rel, uint32_t Type,
> + uintX_t BaseAddr, uintX_t SymVA);
> +
> + template <bool isRela>
> + void relocate(uint8_t *Buf,
> + llvm::iterator_range<
> + const llvm::object::Elf_Rel_Impl<ELFT, isRela> *>
> Rels,
> + const ObjectFile<ELFT> &File, uintX_t BaseAddr,
> + const PltSection<ELFT> &PltSec, const GotSection<ELFT>
> &GotSec);
> +
> // The offset from beginning of the output sections this chunk was
> assigned
> // to. The writer sets a value.
> uint64_t OutputSectionOff = 0;
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=248215&r1=248214&r2=248215&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Mon Sep 21 17:01:00 2015
> @@ -260,53 +260,6 @@ void OutputSection<ELFT>::addChunk(Input
> }
>
> template <class ELFT>
> -void OutputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rel &Rel,
> - uint32_t Type, uintX_t BaseAddr,
> - uintX_t SymVA) {
> - uintX_t Offset = Rel.r_offset;
> - uint8_t *Location = Buf + Offset;
> - switch (Type) {
> - case R_386_32:
> - support::endian::write32le(Location, SymVA);
> - break;
> - default:
> - llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';
> - break;
> - }
> -}
> -
> -template <class ELFT>
> -void OutputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rela &Rel,
> - uint32_t Type, uintX_t BaseAddr,
> - uintX_t SymVA) {
> - uintX_t Offset = Rel.r_offset;
> - uint8_t *Location = Buf + Offset;
> - switch (Type) {
> - case R_X86_64_PC32:
> - support::endian::write32le(Location,
> - SymVA + (Rel.r_addend - (BaseAddr +
> Offset)));
> - break;
> - case R_X86_64_64:
> - support::endian::write64le(Location, SymVA + Rel.r_addend);
> - break;
> - case R_X86_64_32: {
> - case R_X86_64_32S:
> - uint64_t VA = SymVA + Rel.r_addend;
> - if (Type == R_X86_64_32 && !isUInt<32>(VA))
> - error("R_X86_64_32 out of range");
> - else if (!isInt<32>(VA))
> - error("R_X86_64_32S out of range");
> -
> - support::endian::write32le(Location, VA);
> - break;
> - }
> - default:
> - llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';
> - break;
> - }
> -}
> -
> -template <class ELFT>
> typename ELFFile<ELFT>::uintX_t
> lld::elf2::getSymVA(const DefinedRegular<ELFT> *DR) {
> const InputSection<ELFT> *SC = &DR->Section;
> @@ -329,81 +282,9 @@ lld::elf2::getLocalSymVA(const typename
> return Out->getVA() + Section->getOutputSectionOff() + Sym->st_value;
> }
>
> -template <class ELFT>
> -template <bool isRela>
> -void OutputSection<ELFT>::relocate(
> - uint8_t *Buf, iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels,
> - const ObjectFile<ELFT> &File, uintX_t BaseAddr) {
> - typedef Elf_Rel_Impl<ELFT, isRela> RelType;
> - bool IsMips64EL = File.getObj()->isMips64EL();
> - for (const RelType &RI : Rels) {
> - uint32_t SymIndex = RI.getSymbol(IsMips64EL);
> - uint32_t Type = RI.getType(IsMips64EL);
> - uintX_t SymVA;
> -
> - // Handle relocations for local symbols -- they never get
> - // resolved so we don't allocate a SymbolBody.
> - const Elf_Shdr *SymTab = File.getSymbolTable();
> - if (SymIndex < SymTab->sh_info) {
> - const Elf_Sym *Sym = File.getObj()->getRelocationSymbol(&RI,
> SymTab);
> - if (!Sym)
> - continue;
> - SymVA = getLocalSymVA(Sym, File);
> - } else {
> - const SymbolBody *Body = File.getSymbolBody(SymIndex);
> - if (!Body)
> - continue;
> - switch (Body->kind()) {
> - case SymbolBody::DefinedRegularKind:
> - SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));
> - break;
> - case SymbolBody::DefinedAbsoluteKind:
> - SymVA = cast<DefinedAbsolute<ELFT>>(Body)->Sym.st_value;
> - break;
> - case SymbolBody::DefinedCommonKind: {
> - auto *DC = cast<DefinedCommon<ELFT>>(Body);
> - SymVA = DC->OutputSec->getVA() + DC->OffsetInBSS;
> - break;
> - }
> - case SymbolBody::SharedKind:
> - if (relocNeedsPLT(Type)) {
> - SymVA = PltSec.getEntryAddr(*Body);
> - Type = R_X86_64_PC32;
> - } else if (relocNeedsGOT(Type)) {
> - SymVA = GotSec.getEntryAddr(*Body);
> - Type = R_X86_64_PC32;
> - } else {
> - continue;
> - }
> - break;
> - case SymbolBody::UndefinedKind:
> - assert(Body->isWeak() && "Undefined symbol reached writer");
> - SymVA = 0;
> - break;
> - case SymbolBody::LazyKind:
> - llvm_unreachable("Lazy symbol reached writer");
> - }
> - }
> -
> - relocateOne(Buf, RI, Type, BaseAddr, SymVA);
> - }
> -}
> -
> template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
> - for (InputSection<ELFT> *C : Chunks) {
> - C->writeTo(Buf);
> - const ObjectFile<ELFT> *File = C->getFile();
> - ELFFile<ELFT> *EObj = File->getObj();
> - uint8_t *Base = Buf + C->getOutputSectionOff();
> - uintX_t BaseAddr = this->getVA() + C->getOutputSectionOff();
> - // Iterate over all relocation sections that apply to this section.
> - for (const Elf_Shdr *RelSec : C->RelocSections) {
> - if (RelSec->sh_type == SHT_RELA)
> - relocate(Base, EObj->relas(RelSec), *File, BaseAddr);
> - else
> - relocate(Base, EObj->rels(RelSec), *File, BaseAddr);
> - }
> - }
> + for (InputSection<ELFT> *C : Chunks)
> + C->writeTo(Buf, PltSec, GotSec);
> }
>
> template <bool Is64Bits>
> @@ -582,5 +463,21 @@ getSymVA(const DefinedRegular<ELF64LE> *
>
> template typename ELFFile<ELF64BE>::uintX_t
> getSymVA(const DefinedRegular<ELF64BE> *DR);
> +
> +template typename ELFFile<ELF32LE>::uintX_t
> +lld::elf2::getLocalSymVA(const typename ELFFile<ELF32LE>::Elf_Sym *Sym,
> + const ObjectFile<ELF32LE> &File);
> +
> +template typename ELFFile<ELF32BE>::uintX_t
> +lld::elf2::getLocalSymVA(const typename ELFFile<ELF32BE>::Elf_Sym *Sym,
> + const ObjectFile<ELF32BE> &File);
> +
> +template typename ELFFile<ELF64LE>::uintX_t
> +lld::elf2::getLocalSymVA(const typename ELFFile<ELF64LE>::Elf_Sym *Sym,
> + const ObjectFile<ELF64LE> &File);
> +
> +template typename ELFFile<ELF64BE>::uintX_t
> +lld::elf2::getLocalSymVA(const typename ELFFile<ELF64BE>::Elf_Sym *Sym,
> + const ObjectFile<ELF64BE> &File);
> }
> }
>
> Modified: lld/trunk/ELF/OutputSections.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=248215&r1=248214&r2=248215&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.h (original)
> +++ lld/trunk/ELF/OutputSections.h Mon Sep 21 17:01:00 2015
> @@ -245,17 +245,6 @@ public:
> void addChunk(InputSection<ELFT> *C);
> void writeTo(uint8_t *Buf) override;
>
> - template <bool isRela>
> - void relocate(uint8_t *Buf,
> - llvm::iterator_range<
> - const llvm::object::Elf_Rel_Impl<ELFT, isRela> *>
> Rels,
> - const ObjectFile<ELFT> &File, uintX_t BaseAddr);
> -
> - void relocateOne(uint8_t *Buf, const Elf_Rela &Rel, uint32_t Type,
> - uintX_t BaseAddr, uintX_t SymVA);
> - void relocateOne(uint8_t *Buf, const Elf_Rel &Rel, uint32_t Type,
> - uintX_t BaseAddr, uintX_t SymVA);
> -
> private:
> std::vector<InputSection<ELFT> *> Chunks;
> const PltSection<ELFT> &PltSec;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150923/4b8daba4/attachment-0001.html>
More information about the llvm-commits
mailing list