Merge InputSectionData and InputSectionBase.
Now that InputSectionBase is not a template there is no reason to have the two. llvm-svn: 295924
This commit is contained in:
parent
b4c9b81aad
commit
c404d50d7c
|
@ -848,7 +848,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
|||
if (S && S != &InputSection<ELFT>::Discarded)
|
||||
Symtab.Sections.push_back(S);
|
||||
for (BinaryFile *F : Symtab.getBinaryFiles())
|
||||
for (InputSectionData *S : F->getSections())
|
||||
for (InputSectionBase *S : F->getSections())
|
||||
Symtab.Sections.push_back(cast<InputSection<ELFT>>(S));
|
||||
|
||||
// Do size optimizations: garbage collection and identical code folding.
|
||||
|
|
|
@ -322,10 +322,10 @@ public:
|
|||
explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
|
||||
static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
|
||||
template <class ELFT> void parse();
|
||||
ArrayRef<InputSectionData *> getSections() const { return Sections; }
|
||||
ArrayRef<InputSectionBase *> getSections() const { return Sections; }
|
||||
|
||||
private:
|
||||
std::vector<InputSectionData *> Sections;
|
||||
std::vector<InputSectionBase *> Sections;
|
||||
};
|
||||
|
||||
InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
|
||||
|
|
|
@ -53,10 +53,10 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
|
|||
uint32_t Link, uint32_t Info,
|
||||
uint64_t Addralign, ArrayRef<uint8_t> Data,
|
||||
StringRef Name, Kind SectionKind)
|
||||
: InputSectionData(SectionKind, Name, Data,
|
||||
!Config->GcSections || !(Flags & SHF_ALLOC)),
|
||||
File(File), Flags(Flags), Entsize(Entsize), Type(Type), Link(Link),
|
||||
Info(Info), Repl(this) {
|
||||
: File(File), Data(Data), Name(Name), SectionKind(SectionKind),
|
||||
Live(!Config->GcSections || !(Flags & SHF_ALLOC)), Assigned(false),
|
||||
Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info),
|
||||
Repl(this) {
|
||||
NumRelocations = 0;
|
||||
AreRelocsRela = false;
|
||||
|
||||
|
@ -198,7 +198,7 @@ InputSection<ELFT>::InputSection(elf::ObjectFile<ELFT> *F,
|
|||
: InputSectionBase(F, Header, Name, InputSectionBase::Regular) {}
|
||||
|
||||
template <class ELFT>
|
||||
bool InputSection<ELFT>::classof(const InputSectionData *S) {
|
||||
bool InputSection<ELFT>::classof(const InputSectionBase *S) {
|
||||
return S->kind() == InputSectionBase::Regular ||
|
||||
S->kind() == InputSectionBase::Synthetic;
|
||||
}
|
||||
|
@ -583,7 +583,7 @@ EhInputSection<ELFT>::EhInputSection(elf::ObjectFile<ELFT> *F,
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
bool EhInputSection<ELFT>::classof(const InputSectionData *S) {
|
||||
bool EhInputSection<ELFT>::classof(const InputSectionBase *S) {
|
||||
return S->kind() == InputSectionBase::EHFrame;
|
||||
}
|
||||
|
||||
|
@ -711,7 +711,7 @@ template <class ELFT> void MergeInputSection<ELFT>::splitIntoPieces() {
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
bool MergeInputSection<ELFT>::classof(const InputSectionData *S) {
|
||||
bool MergeInputSection<ELFT>::classof(const InputSectionBase *S) {
|
||||
return S->kind() == InputSectionBase::Merge;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,50 +33,28 @@ template <class ELFT> class ObjectFile;
|
|||
template <class ELFT> class OutputSection;
|
||||
class OutputSectionBase;
|
||||
|
||||
// We need non-template input section class to store symbol layout
|
||||
// in linker script parser structures, where we do not have ELFT
|
||||
// template parameter. For each scripted output section symbol we
|
||||
// store pointer to preceding InputSectionData object or nullptr,
|
||||
// if symbol should be placed at the very beginning of the output
|
||||
// section
|
||||
class InputSectionData {
|
||||
// This corresponds to a section of an input file.
|
||||
class InputSectionBase {
|
||||
public:
|
||||
enum Kind { Regular, EHFrame, Merge, Synthetic, };
|
||||
|
||||
// The garbage collector sets sections' Live bits.
|
||||
// If GC is disabled, all sections are considered live by default.
|
||||
InputSectionData(Kind SectionKind, StringRef Name, ArrayRef<uint8_t> Data,
|
||||
bool Live)
|
||||
: SectionKind(SectionKind), Live(Live), Assigned(false), Name(Name),
|
||||
Data(Data) {}
|
||||
|
||||
private:
|
||||
unsigned SectionKind : 3;
|
||||
|
||||
public:
|
||||
Kind kind() const { return (Kind)SectionKind; }
|
||||
|
||||
unsigned Live : 1; // for garbage collection
|
||||
unsigned Assigned : 1; // for linker script
|
||||
uint32_t Alignment;
|
||||
StringRef Name;
|
||||
ArrayRef<uint8_t> Data;
|
||||
|
||||
template <typename T> llvm::ArrayRef<T> getDataAs() const {
|
||||
size_t S = Data.size();
|
||||
assert(S % sizeof(T) == 0);
|
||||
return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
|
||||
}
|
||||
|
||||
std::vector<Relocation> Relocations;
|
||||
};
|
||||
|
||||
// This corresponds to a section of an input file.
|
||||
class InputSectionBase : public InputSectionData {
|
||||
public:
|
||||
// The file this section is from.
|
||||
InputFile *File;
|
||||
|
||||
ArrayRef<uint8_t> Data;
|
||||
|
||||
StringRef Name;
|
||||
|
||||
unsigned SectionKind : 3;
|
||||
|
||||
// The garbage collector sets sections' Live bits.
|
||||
// If GC is disabled, all sections are considered live by default.
|
||||
unsigned Live : 1; // for garbage collection
|
||||
unsigned Assigned : 1; // for linker script
|
||||
|
||||
uint32_t Alignment;
|
||||
|
||||
// These corresponds to the fields in Elf_Shdr.
|
||||
uint64_t Flags;
|
||||
uint64_t Offset = 0;
|
||||
|
@ -86,7 +64,7 @@ public:
|
|||
uint32_t Info;
|
||||
|
||||
InputSectionBase()
|
||||
: InputSectionData(Regular, "", ArrayRef<uint8_t>(), false), Repl(this) {
|
||||
: SectionKind(Regular), Live(false), Assigned(false), Repl(this) {
|
||||
NumRelocations = 0;
|
||||
AreRelocsRela = false;
|
||||
}
|
||||
|
@ -153,6 +131,14 @@ public:
|
|||
template <class ELFT> std::string getLocation(uint64_t Offset);
|
||||
|
||||
template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd);
|
||||
|
||||
std::vector<Relocation> Relocations;
|
||||
|
||||
template <typename T> llvm::ArrayRef<T> getDataAs() const {
|
||||
size_t S = Data.size();
|
||||
assert(S % sizeof(T) == 0);
|
||||
return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
// SectionPiece represents a piece of splittable section contents.
|
||||
|
@ -179,7 +165,7 @@ template <class ELFT> class MergeInputSection : public InputSectionBase {
|
|||
public:
|
||||
MergeInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header,
|
||||
StringRef Name);
|
||||
static bool classof(const InputSectionData *S);
|
||||
static bool classof(const InputSectionBase *S);
|
||||
void splitIntoPieces();
|
||||
|
||||
// Mark the piece at a given offset live. Used by GC.
|
||||
|
@ -233,11 +219,11 @@ private:
|
|||
};
|
||||
|
||||
struct EhSectionPiece : public SectionPiece {
|
||||
EhSectionPiece(size_t Off, InputSectionData *ID, uint32_t Size,
|
||||
EhSectionPiece(size_t Off, InputSectionBase *ID, uint32_t Size,
|
||||
unsigned FirstRelocation)
|
||||
: SectionPiece(Off, false), ID(ID), Size(Size),
|
||||
FirstRelocation(FirstRelocation) {}
|
||||
InputSectionData *ID;
|
||||
InputSectionBase *ID;
|
||||
uint32_t Size;
|
||||
uint32_t size() const { return Size; }
|
||||
|
||||
|
@ -251,7 +237,7 @@ public:
|
|||
typedef typename ELFT::Shdr Elf_Shdr;
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
EhInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header, StringRef Name);
|
||||
static bool classof(const InputSectionData *S);
|
||||
static bool classof(const InputSectionBase *S);
|
||||
void split();
|
||||
template <class RelTy> void split(ArrayRef<RelTy> Rels);
|
||||
|
||||
|
@ -267,13 +253,11 @@ template <class ELFT> class InputSection : public InputSectionBase {
|
|||
typedef typename ELFT::Rel Elf_Rel;
|
||||
typedef typename ELFT::Sym Elf_Sym;
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
typedef InputSectionData::Kind Kind;
|
||||
|
||||
public:
|
||||
InputSection();
|
||||
InputSection(uintX_t Flags, uint32_t Type, uintX_t Addralign,
|
||||
ArrayRef<uint8_t> Data, StringRef Name,
|
||||
Kind K = InputSectionData::Regular);
|
||||
ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
|
||||
InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header, StringRef Name);
|
||||
|
||||
static InputSection<ELFT> Discarded;
|
||||
|
@ -286,7 +270,7 @@ public:
|
|||
// to. The writer sets a value.
|
||||
uint64_t OutSecOff = 0;
|
||||
|
||||
static bool classof(const InputSectionData *S);
|
||||
static bool classof(const InputSectionBase *S);
|
||||
|
||||
InputSectionBase *getRelocatedSection();
|
||||
|
||||
|
|
|
@ -196,22 +196,22 @@ template <class ELFT> bool LinkerScript<ELFT>::shouldKeep(InputSectionBase *S) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool comparePriority(InputSectionData *A, InputSectionData *B) {
|
||||
static bool comparePriority(InputSectionBase *A, InputSectionBase *B) {
|
||||
return getPriority(A->Name) < getPriority(B->Name);
|
||||
}
|
||||
|
||||
static bool compareName(InputSectionData *A, InputSectionData *B) {
|
||||
static bool compareName(InputSectionBase *A, InputSectionBase *B) {
|
||||
return A->Name < B->Name;
|
||||
}
|
||||
|
||||
static bool compareAlignment(InputSectionData *A, InputSectionData *B) {
|
||||
static bool compareAlignment(InputSectionBase *A, InputSectionBase *B) {
|
||||
// ">" is not a mistake. Larger alignments are placed before smaller
|
||||
// alignments in order to reduce the amount of padding necessary.
|
||||
// This is compatible with GNU.
|
||||
return A->Alignment > B->Alignment;
|
||||
}
|
||||
|
||||
static std::function<bool(InputSectionData *, InputSectionData *)>
|
||||
static std::function<bool(InputSectionBase *, InputSectionBase *)>
|
||||
getComparator(SortSectionPolicy K) {
|
||||
switch (K) {
|
||||
case SortSectionPolicy::Alignment:
|
||||
|
@ -230,7 +230,7 @@ static bool matchConstraints(ArrayRef<InputSectionBase *> Sections,
|
|||
ConstraintKind Kind) {
|
||||
if (Kind == ConstraintKind::NoConstraint)
|
||||
return true;
|
||||
bool IsRW = llvm::any_of(Sections, [=](InputSectionData *Sec2) {
|
||||
bool IsRW = llvm::any_of(Sections, [=](InputSectionBase *Sec2) {
|
||||
auto *Sec = static_cast<InputSectionBase *>(Sec2);
|
||||
return Sec->Flags & SHF_WRITE;
|
||||
});
|
||||
|
@ -238,7 +238,7 @@ static bool matchConstraints(ArrayRef<InputSectionBase *> Sections,
|
|||
(!IsRW && Kind == ConstraintKind::ReadOnly);
|
||||
}
|
||||
|
||||
static void sortSections(InputSectionData **Begin, InputSectionData **End,
|
||||
static void sortSections(InputSectionBase **Begin, InputSectionBase **End,
|
||||
SortSectionPolicy K) {
|
||||
if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
|
||||
std::stable_sort(Begin, End, getComparator(K));
|
||||
|
@ -281,8 +281,8 @@ void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) {
|
|||
// --sort-section is handled as an inner SORT command.
|
||||
// 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
|
||||
// 4. If no SORT command is given, sort according to --sort-section.
|
||||
InputSectionData **Begin = I->Sections.data() + SizeBefore;
|
||||
InputSectionData **End = I->Sections.data() + I->Sections.size();
|
||||
InputSectionBase **Begin = I->Sections.data() + SizeBefore;
|
||||
InputSectionBase **End = I->Sections.data() + I->Sections.size();
|
||||
if (Pat.SortOuter != SortSectionPolicy::None) {
|
||||
if (Pat.SortInner == SortSectionPolicy::Default)
|
||||
sortSections(Begin, End, Config->SortSection);
|
||||
|
@ -313,7 +313,7 @@ LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
|
|||
if (!Cmd)
|
||||
continue;
|
||||
computeInputSections(Cmd);
|
||||
for (InputSectionData *S : Cmd->Sections)
|
||||
for (InputSectionBase *S : Cmd->Sections)
|
||||
Ret.push_back(static_cast<InputSectionBase *>(S));
|
||||
}
|
||||
|
||||
|
@ -492,7 +492,7 @@ template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) {
|
|||
// calculates and assigns the offsets for each section and also
|
||||
// updates the output section size.
|
||||
auto &ICmd = cast<InputSectionDescription>(Base);
|
||||
for (InputSectionData *ID : ICmd.Sections) {
|
||||
for (InputSectionBase *ID : ICmd.Sections) {
|
||||
// We tentatively added all synthetic sections at the beginning and removed
|
||||
// empty ones afterwards (because there is no way to know whether they were
|
||||
// going be empty or not other than actually running linker scripts.)
|
||||
|
|
|
@ -35,7 +35,7 @@ class InputSectionBase;
|
|||
template <class ELFT> class InputSection;
|
||||
class OutputSectionBase;
|
||||
template <class ELFT> class OutputSectionFactory;
|
||||
class InputSectionData;
|
||||
class InputSectionBase;
|
||||
|
||||
// This represents an expression in the linker script.
|
||||
// ScriptParser::readExpr reads an expression and returns an Expr.
|
||||
|
@ -159,7 +159,7 @@ struct InputSectionDescription : BaseCommand {
|
|||
// will be associated with this InputSectionDescription.
|
||||
std::vector<SectionPattern> SectionPatterns;
|
||||
|
||||
std::vector<InputSectionData *> Sections;
|
||||
std::vector<InputSectionBase *> Sections;
|
||||
};
|
||||
|
||||
// Represents an ASSERT().
|
||||
|
@ -307,7 +307,7 @@ private:
|
|||
void output(InputSection<ELFT> *Sec);
|
||||
void process(BaseCommand &Base);
|
||||
llvm::DenseSet<OutputSectionBase *> AlreadyOutputOS;
|
||||
llvm::DenseSet<InputSectionData *> AlreadyOutputIS;
|
||||
llvm::DenseSet<InputSectionBase *> AlreadyOutputIS;
|
||||
};
|
||||
|
||||
// Variable template is a C++14 feature, so we can't template
|
||||
|
|
|
@ -107,7 +107,7 @@ static void writeMapFile2(raw_fd_ostream &OS,
|
|||
OS << '\n';
|
||||
|
||||
StringRef PrevName = "";
|
||||
Sec->forEachInputSection([&](InputSectionData *S) {
|
||||
Sec->forEachInputSection([&](InputSectionBase *S) {
|
||||
if (const auto *IS = dyn_cast<InputSection<ELFT>>(S))
|
||||
writeInputSection(OS, IS, PrevName);
|
||||
});
|
||||
|
|
|
@ -89,8 +89,8 @@ template <typename ELFT>
|
|||
static bool compareByFilePosition(InputSection<ELFT> *A,
|
||||
InputSection<ELFT> *B) {
|
||||
// Synthetic doesn't have link order dependecy, stable_sort will keep it last
|
||||
if (A->kind() == InputSectionData::Synthetic ||
|
||||
B->kind() == InputSectionData::Synthetic)
|
||||
if (A->kind() == InputSectionBase::Synthetic ||
|
||||
B->kind() == InputSectionBase::Synthetic)
|
||||
return false;
|
||||
auto *LA = cast<InputSection<ELFT>>(A->template getLinkOrderDep<ELFT>());
|
||||
auto *LB = cast<InputSection<ELFT>>(B->template getLinkOrderDep<ELFT>());
|
||||
|
@ -131,7 +131,7 @@ template <class ELFT> void OutputSection<ELFT>::finalize() {
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
void OutputSection<ELFT>::addSection(InputSectionData *C) {
|
||||
void OutputSection<ELFT>::addSection(InputSectionBase *C) {
|
||||
assert(C->Live);
|
||||
auto *S = cast<InputSection<ELFT>>(C);
|
||||
Sections.push_back(S);
|
||||
|
@ -145,7 +145,7 @@ void OutputSection<ELFT>::addSection(InputSectionData *C) {
|
|||
|
||||
template <class ELFT>
|
||||
void OutputSection<ELFT>::forEachInputSection(
|
||||
std::function<void(InputSectionData *)> F) {
|
||||
std::function<void(InputSectionBase *)> F) {
|
||||
for (InputSection<ELFT> *S : Sections)
|
||||
F(S);
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ template <class ELFT> void OutputSection<ELFT>::assignOffsets() {
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
void OutputSection<ELFT>::sort(std::function<int(InputSectionData *S)> Order) {
|
||||
void OutputSection<ELFT>::sort(std::function<int(InputSectionBase *S)> Order) {
|
||||
typedef std::pair<unsigned, InputSection<ELFT> *> Pair;
|
||||
auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; };
|
||||
|
||||
|
@ -184,7 +184,7 @@ void OutputSection<ELFT>::sort(std::function<int(InputSectionData *S)> Order) {
|
|||
// For more detail, read the section of the GCC's manual about init_priority.
|
||||
template <class ELFT> void OutputSection<ELFT>::sortInitFini() {
|
||||
// Sort sections by priority.
|
||||
sort([](InputSectionData *S) { return getPriority(S->Name); });
|
||||
sort([](InputSectionBase *S) { return getPriority(S->Name); });
|
||||
}
|
||||
|
||||
// Returns true if S matches /Filename.?\.o$/.
|
||||
|
@ -277,7 +277,7 @@ EhOutputSection<ELFT>::EhOutputSection()
|
|||
|
||||
template <class ELFT>
|
||||
void EhOutputSection<ELFT>::forEachInputSection(
|
||||
std::function<void(InputSectionData *)> F) {
|
||||
std::function<void(InputSectionBase *)> F) {
|
||||
for (EhInputSection<ELFT> *S : Sections)
|
||||
F(S);
|
||||
}
|
||||
|
@ -366,7 +366,7 @@ void EhOutputSection<ELFT>::addSectionAux(EhInputSection<ELFT> *Sec,
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
void EhOutputSection<ELFT>::addSection(InputSectionData *C) {
|
||||
void EhOutputSection<ELFT>::addSection(InputSectionBase *C) {
|
||||
auto *Sec = cast<EhInputSection<ELFT>>(C);
|
||||
Sec->OutSec = this;
|
||||
this->updateAlignment(Sec->Alignment);
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
|
||||
StringRef getName() const { return Name; }
|
||||
|
||||
virtual void addSection(InputSectionData *C) {}
|
||||
virtual void addSection(InputSectionBase *C) {}
|
||||
virtual Kind getKind() const { return Base; }
|
||||
static bool classof(const OutputSectionBase *B) {
|
||||
return B->getKind() == Base;
|
||||
|
@ -81,7 +81,7 @@ public:
|
|||
OutputSectionBase *FirstInPtLoad = nullptr;
|
||||
|
||||
virtual void finalize() {}
|
||||
virtual void forEachInputSection(std::function<void(InputSectionData *)> F) {}
|
||||
virtual void forEachInputSection(std::function<void(InputSectionBase *)> F) {}
|
||||
virtual void assignOffsets() {}
|
||||
virtual void writeTo(uint8_t *Buf) {}
|
||||
virtual ~OutputSectionBase() = default;
|
||||
|
@ -111,13 +111,13 @@ public:
|
|||
typedef typename ELFT::Rela Elf_Rela;
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
OutputSection(StringRef Name, uint32_t Type, uintX_t Flags);
|
||||
void addSection(InputSectionData *C) override;
|
||||
void sort(std::function<int(InputSectionData *S)> Order);
|
||||
void addSection(InputSectionBase *C) override;
|
||||
void sort(std::function<int(InputSectionBase *S)> Order);
|
||||
void sortInitFini();
|
||||
void sortCtorsDtors();
|
||||
void writeTo(uint8_t *Buf) override;
|
||||
void finalize() override;
|
||||
void forEachInputSection(std::function<void(InputSectionData *)> F) override;
|
||||
void forEachInputSection(std::function<void(InputSectionBase *)> F) override;
|
||||
void assignOffsets() override;
|
||||
Kind getKind() const override { return Regular; }
|
||||
static bool classof(const OutputSectionBase *B) {
|
||||
|
@ -146,9 +146,9 @@ public:
|
|||
void writeTo(uint8_t *Buf) override;
|
||||
void finalize() override;
|
||||
bool empty() const { return Sections.empty(); }
|
||||
void forEachInputSection(std::function<void(InputSectionData *)> F) override;
|
||||
void forEachInputSection(std::function<void(InputSectionBase *)> F) override;
|
||||
|
||||
void addSection(InputSectionData *S) override;
|
||||
void addSection(InputSectionBase *S) override;
|
||||
Kind getKind() const override { return EHFrame; }
|
||||
static bool classof(const OutputSectionBase *B) {
|
||||
return B->getKind() == EHFrame;
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
SyntheticSection(uintX_t Flags, uint32_t Type, uintX_t Addralign,
|
||||
StringRef Name)
|
||||
: InputSection<ELFT>(Flags, Type, Addralign, {}, Name,
|
||||
InputSectionData::Synthetic) {
|
||||
InputSectionBase::Synthetic) {
|
||||
this->Live = true;
|
||||
}
|
||||
|
||||
|
@ -54,8 +54,8 @@ public:
|
|||
return this->OutSec ? this->OutSec->Addr + this->OutSecOff : 0;
|
||||
}
|
||||
|
||||
static bool classof(const InputSectionData *D) {
|
||||
return D->kind() == InputSectionData::Synthetic;
|
||||
static bool classof(const InputSectionBase *D) {
|
||||
return D->kind() == InputSectionBase::Synthetic;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
|
|||
static void or32be(uint8_t *P, int32_t V) { write32be(P, read32be(P) | V); }
|
||||
|
||||
template <class ELFT> static std::string getErrorLoc(uint8_t *Loc) {
|
||||
for (InputSectionData *D : Symtab<ELFT>::X->Sections) {
|
||||
for (InputSectionBase *D : Symtab<ELFT>::X->Sections) {
|
||||
auto *IS = dyn_cast_or_null<InputSection<ELFT>>(D);
|
||||
if (!IS || !IS->OutSec)
|
||||
continue;
|
||||
|
@ -226,8 +226,8 @@ public:
|
|||
void writePltHeader(uint8_t *Buf) const override;
|
||||
void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
|
||||
int32_t Index, unsigned RelOff) const override;
|
||||
void addPltSymbols(InputSectionData *IS, uint64_t Off) const override;
|
||||
void addPltHeaderSymbols(InputSectionData *ISD) const override;
|
||||
void addPltSymbols(InputSectionBase *IS, uint64_t Off) const override;
|
||||
void addPltHeaderSymbols(InputSectionBase *ISD) const override;
|
||||
bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
|
||||
const SymbolBody &S) const override;
|
||||
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
|
||||
|
@ -1758,7 +1758,7 @@ void ARMTargetInfo::writePltHeader(uint8_t *Buf) const {
|
|||
write32le(Buf + 16, GotPlt - L1 - 8);
|
||||
}
|
||||
|
||||
void ARMTargetInfo::addPltHeaderSymbols(InputSectionData *ISD) const {
|
||||
void ARMTargetInfo::addPltHeaderSymbols(InputSectionBase *ISD) const {
|
||||
auto *IS = cast<InputSection<ELF32LE>>(ISD);
|
||||
addSyntheticLocal<ELF32LE>("$a", STT_NOTYPE, 0, 0, IS);
|
||||
addSyntheticLocal<ELF32LE>("$d", STT_NOTYPE, 16, 0, IS);
|
||||
|
@ -1781,7 +1781,7 @@ void ARMTargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
|
|||
write32le(Buf + 12, GotEntryAddr - L1 - 8);
|
||||
}
|
||||
|
||||
void ARMTargetInfo::addPltSymbols(InputSectionData *ISD, uint64_t Off) const {
|
||||
void ARMTargetInfo::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const {
|
||||
auto *IS = cast<InputSection<ELF32LE>>(ISD);
|
||||
addSyntheticLocal<ELF32LE>("$a", STT_NOTYPE, Off, 0, IS);
|
||||
addSyntheticLocal<ELF32LE>("$d", STT_NOTYPE, Off + 12, 0, IS);
|
||||
|
|
|
@ -41,8 +41,8 @@ public:
|
|||
virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
|
||||
uint64_t PltEntryAddr, int32_t Index,
|
||||
unsigned RelOff) const {}
|
||||
virtual void addPltHeaderSymbols(InputSectionData *IS) const {}
|
||||
virtual void addPltSymbols(InputSectionData *IS, uint64_t Off) const {}
|
||||
virtual void addPltHeaderSymbols(InputSectionBase *IS) const {}
|
||||
virtual void addPltSymbols(InputSectionBase *IS, uint64_t Off) const {}
|
||||
// Returns true if a relocation only uses the low bits of a value such that
|
||||
// all those bits are in in the same page. For example, if the relocation
|
||||
// only uses the low 12 bits in a system with 4k pages. If this is true, the
|
||||
|
|
|
@ -526,8 +526,8 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
|
|||
// Create one STT_SECTION symbol for each output section we might
|
||||
// have a relocation with.
|
||||
for (OutputSectionBase *Sec : OutputSections) {
|
||||
InputSectionData *First = nullptr;
|
||||
Sec->forEachInputSection([&](InputSectionData *D) {
|
||||
InputSectionBase *First = nullptr;
|
||||
Sec->forEachInputSection([&](InputSectionBase *D) {
|
||||
if (!First)
|
||||
First = D;
|
||||
});
|
||||
|
@ -885,7 +885,7 @@ static void sortBySymbolsOrder(ArrayRef<OutputSectionBase *> OutputSections) {
|
|||
SymbolOrder.insert({S, Priority++});
|
||||
|
||||
// Build a map from sections to their priorities.
|
||||
DenseMap<InputSectionData *, int> SectionOrder;
|
||||
DenseMap<InputSectionBase *, int> SectionOrder;
|
||||
for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) {
|
||||
for (SymbolBody *Body : File->getSymbols()) {
|
||||
auto *D = dyn_cast<DefinedRegular<ELFT>>(Body);
|
||||
|
@ -899,7 +899,7 @@ static void sortBySymbolsOrder(ArrayRef<OutputSectionBase *> OutputSections) {
|
|||
// Sort sections by priority.
|
||||
for (OutputSectionBase *Base : OutputSections)
|
||||
if (auto *Sec = dyn_cast<OutputSection<ELFT>>(Base))
|
||||
Sec->sort([&](InputSectionData *S) { return SectionOrder.lookup(S); });
|
||||
Sec->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); });
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
|
Loading…
Reference in New Issue