forked from OSchip/llvm-project
parent
de9a44e3e9
commit
7167585c94
|
@ -91,13 +91,13 @@ template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
|
||||||
this->openELF(MB);
|
this->openELF(MB);
|
||||||
|
|
||||||
// Read section and symbol tables.
|
// Read section and symbol tables.
|
||||||
initializeChunks();
|
initializeSections();
|
||||||
initializeSymbols();
|
initializeSymbols();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void elf2::ObjectFile<ELFT>::initializeChunks() {
|
template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSections() {
|
||||||
uint64_t Size = this->ELFObj->getNumSections();
|
uint64_t Size = this->ELFObj->getNumSections();
|
||||||
Chunks.resize(Size);
|
Sections.resize(Size);
|
||||||
unsigned I = 0;
|
unsigned I = 0;
|
||||||
for (const Elf_Shdr &Sec : this->ELFObj->sections()) {
|
for (const Elf_Shdr &Sec : this->ELFObj->sections()) {
|
||||||
switch (Sec.sh_type) {
|
switch (Sec.sh_type) {
|
||||||
|
@ -119,14 +119,14 @@ template <class ELFT> void elf2::ObjectFile<ELFT>::initializeChunks() {
|
||||||
uint32_t RelocatedSectionIndex = Sec.sh_info;
|
uint32_t RelocatedSectionIndex = Sec.sh_info;
|
||||||
if (RelocatedSectionIndex >= Size)
|
if (RelocatedSectionIndex >= Size)
|
||||||
error("Invalid relocated section index");
|
error("Invalid relocated section index");
|
||||||
InputSection<ELFT> *RelocatedSection = Chunks[RelocatedSectionIndex];
|
InputSection<ELFT> *RelocatedSection = Sections[RelocatedSectionIndex];
|
||||||
if (!RelocatedSection)
|
if (!RelocatedSection)
|
||||||
error("Unsupported relocation reference");
|
error("Unsupported relocation reference");
|
||||||
RelocatedSection->RelocSections.push_back(&Sec);
|
RelocatedSection->RelocSections.push_back(&Sec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
Chunks[I] = new (Alloc) InputSection<ELFT>(this, &Sec);
|
Sections[I] = new (Alloc) InputSection<ELFT>(this, &Sec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++I;
|
++I;
|
||||||
|
@ -162,8 +162,7 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SecIndex >= Chunks.size() ||
|
if (SecIndex >= Sections.size() || (SecIndex != 0 && !Sections[SecIndex]))
|
||||||
(SecIndex != 0 && !Chunks[SecIndex]))
|
|
||||||
error("Invalid section index");
|
error("Invalid section index");
|
||||||
|
|
||||||
switch (Sym->getBinding()) {
|
switch (Sym->getBinding()) {
|
||||||
|
@ -171,7 +170,7 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
|
||||||
error("unexpected binding");
|
error("unexpected binding");
|
||||||
case STB_GLOBAL:
|
case STB_GLOBAL:
|
||||||
case STB_WEAK:
|
case STB_WEAK:
|
||||||
return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Chunks[SecIndex]);
|
return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sections[SecIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ public:
|
||||||
: ObjectFileBase(getStaticELFKind<ELFT>(), M) {}
|
: ObjectFileBase(getStaticELFKind<ELFT>(), M) {}
|
||||||
void parse() override;
|
void parse() override;
|
||||||
|
|
||||||
ArrayRef<InputSection<ELFT> *> getChunks() const { return Chunks; }
|
ArrayRef<InputSection<ELFT> *> getSections() const { return Sections; }
|
||||||
|
|
||||||
SymbolBody *getSymbolBody(uint32_t SymbolIndex) const {
|
SymbolBody *getSymbolBody(uint32_t SymbolIndex) const {
|
||||||
uint32_t FirstNonLocal = this->Symtab->sh_info;
|
uint32_t FirstNonLocal = this->Symtab->sh_info;
|
||||||
|
@ -147,13 +147,13 @@ public:
|
||||||
ArrayRef<Elf_Word> getSymbolTableShndx() const { return SymtabSHNDX; };
|
ArrayRef<Elf_Word> getSymbolTableShndx() const { return SymtabSHNDX; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initializeChunks();
|
void initializeSections();
|
||||||
void initializeSymbols();
|
void initializeSymbols();
|
||||||
|
|
||||||
SymbolBody *createSymbolBody(StringRef StringTable, const Elf_Sym *Sym);
|
SymbolBody *createSymbolBody(StringRef StringTable, const Elf_Sym *Sym);
|
||||||
|
|
||||||
// List of all chunks defined by this file.
|
// List of all sections defined by this file.
|
||||||
std::vector<InputSection<ELFT> *> Chunks;
|
std::vector<InputSection<ELFT> *> Sections;
|
||||||
|
|
||||||
ArrayRef<Elf_Word> SymtabSHNDX;
|
ArrayRef<Elf_Word> SymtabSHNDX;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@ template <class ELFT> class OutputSection;
|
||||||
template <class ELFT> class PltSection;
|
template <class ELFT> class PltSection;
|
||||||
template <class ELFT> class GotSection;
|
template <class ELFT> class GotSection;
|
||||||
|
|
||||||
// A chunk corresponding a section of an input file.
|
// This corresponds to a section of an input file.
|
||||||
template <class ELFT> class InputSection {
|
template <class ELFT> class InputSection {
|
||||||
typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
|
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_Rela Elf_Rela;
|
||||||
|
@ -32,10 +32,10 @@ template <class ELFT> class InputSection {
|
||||||
public:
|
public:
|
||||||
InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
|
InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
|
||||||
|
|
||||||
// Returns the size of this chunk (even if this is a common or BSS.)
|
// Returns the size of this section (even if this is a common or BSS.)
|
||||||
size_t getSize() const { return Header->sh_size; }
|
size_t getSize() const { return Header->sh_size; }
|
||||||
|
|
||||||
// Write this chunk to a mmap'ed file, assuming Buf is pointing to
|
// Write this section to a mmap'ed file, assuming Buf is pointing to
|
||||||
// beginning of the output section.
|
// beginning of the output section.
|
||||||
void writeTo(uint8_t *Buf, const PltSection<ELFT> &PltSec,
|
void writeTo(uint8_t *Buf, const PltSection<ELFT> &PltSec,
|
||||||
const GotSection<ELFT> &GotSec);
|
const GotSection<ELFT> &GotSec);
|
||||||
|
@ -72,11 +72,11 @@ private:
|
||||||
const ObjectFile<ELFT> &File, uintX_t BaseAddr,
|
const ObjectFile<ELFT> &File, uintX_t BaseAddr,
|
||||||
const PltSection<ELFT> &PltSec, const GotSection<ELFT> &GotSec);
|
const PltSection<ELFT> &PltSec, const GotSection<ELFT> &GotSec);
|
||||||
|
|
||||||
// The offset from beginning of the output sections this chunk was assigned
|
// The offset from beginning of the output sections this section was assigned
|
||||||
// to. The writer sets a value.
|
// to. The writer sets a value.
|
||||||
uint64_t OutputSectionOff = 0;
|
uint64_t OutputSectionOff = 0;
|
||||||
|
|
||||||
// The file this chunk was created from.
|
// The file this section is from.
|
||||||
ObjectFile<ELFT> *File;
|
ObjectFile<ELFT> *File;
|
||||||
|
|
||||||
OutputSection<ELFT> *Out = nullptr;
|
OutputSection<ELFT> *Out = nullptr;
|
||||||
|
|
|
@ -240,8 +240,8 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
void OutputSection<ELFT>::addChunk(InputSection<ELFT> *C) {
|
void OutputSection<ELFT>::addSection(InputSection<ELFT> *C) {
|
||||||
Chunks.push_back(C);
|
Sections.push_back(C);
|
||||||
C->setOutputSection(this);
|
C->setOutputSection(this);
|
||||||
uint32_t Align = C->getAlign();
|
uint32_t Align = C->getAlign();
|
||||||
if (Align > this->Header.sh_addralign)
|
if (Align > this->Header.sh_addralign)
|
||||||
|
@ -271,14 +271,14 @@ lld::elf2::getLocalSymVA(const typename ELFFile<ELFT>::Elf_Sym *Sym,
|
||||||
if (SecIndex == SHN_XINDEX)
|
if (SecIndex == SHN_XINDEX)
|
||||||
SecIndex = File.getObj()->getExtendedSymbolTableIndex(
|
SecIndex = File.getObj()->getExtendedSymbolTableIndex(
|
||||||
Sym, File.getSymbolTable(), File.getSymbolTableShndx());
|
Sym, File.getSymbolTable(), File.getSymbolTableShndx());
|
||||||
ArrayRef<InputSection<ELFT> *> Chunks = File.getChunks();
|
ArrayRef<InputSection<ELFT> *> Sections = File.getSections();
|
||||||
InputSection<ELFT> *Section = Chunks[SecIndex];
|
InputSection<ELFT> *Section = Sections[SecIndex];
|
||||||
OutputSection<ELFT> *Out = Section->getOutputSection();
|
OutputSection<ELFT> *Out = Section->getOutputSection();
|
||||||
return Out->getVA() + Section->getOutputSectionOff() + Sym->st_value;
|
return Out->getVA() + Section->getOutputSectionOff() + Sym->st_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
|
template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||||
for (InputSection<ELFT> *C : Chunks)
|
for (InputSection<ELFT> *C : Sections)
|
||||||
C->writeTo(Buf, PltSec, GotSec);
|
C->writeTo(Buf, PltSec, GotSec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,8 +323,8 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||||
if (SecIndex == SHN_XINDEX)
|
if (SecIndex == SHN_XINDEX)
|
||||||
SecIndex = File.getObj()->getExtendedSymbolTableIndex(
|
SecIndex = File.getObj()->getExtendedSymbolTableIndex(
|
||||||
&Sym, File.getSymbolTable(), File.getSymbolTableShndx());
|
&Sym, File.getSymbolTable(), File.getSymbolTableShndx());
|
||||||
ArrayRef<InputSection<ELFT> *> Chunks = File.getChunks();
|
ArrayRef<InputSection<ELFT> *> Sections = File.getSections();
|
||||||
Section = Chunks[SecIndex];
|
Section = Sections[SecIndex];
|
||||||
assert(Section != nullptr);
|
assert(Section != nullptr);
|
||||||
Out = Section->getOutputSection();
|
Out = Section->getOutputSection();
|
||||||
assert(Out != nullptr);
|
assert(Out != nullptr);
|
||||||
|
|
|
@ -43,10 +43,10 @@ getLocalSymVA(const typename llvm::object::ELFFile<ELFT>::Elf_Sym *Sym,
|
||||||
|
|
||||||
bool includeInSymtab(const SymbolBody &B);
|
bool includeInSymtab(const SymbolBody &B);
|
||||||
|
|
||||||
// OutputSection represents a section in an output file. It's a
|
// This represents a section in an output file.
|
||||||
// container of chunks. OutputSection and Chunk are 1:N relationship.
|
// Different sub classes represent different types of sections. Some contain
|
||||||
// Chunks cannot belong to more than one OutputSections. The writer
|
// input sections, others are created by the linker.
|
||||||
// creates multiple OutputSections and assign them unique,
|
// The writer creates multiple OutputSections and assign them unique,
|
||||||
// non-overlapping file offsets and VAs.
|
// non-overlapping file offsets and VAs.
|
||||||
template <bool Is64Bits> class OutputSectionBase {
|
template <bool Is64Bits> class OutputSectionBase {
|
||||||
public:
|
public:
|
||||||
|
@ -242,11 +242,11 @@ public:
|
||||||
: OutputSectionBase<ELFT::Is64Bits>(Name, sh_type, sh_flags),
|
: OutputSectionBase<ELFT::Is64Bits>(Name, sh_type, sh_flags),
|
||||||
PltSec(PltSec), GotSec(GotSec) {}
|
PltSec(PltSec), GotSec(GotSec) {}
|
||||||
|
|
||||||
void addChunk(InputSection<ELFT> *C);
|
void addSection(InputSection<ELFT> *C);
|
||||||
void writeTo(uint8_t *Buf) override;
|
void writeTo(uint8_t *Buf) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<InputSection<ELFT> *> Chunks;
|
std::vector<InputSection<ELFT> *> Sections;
|
||||||
const PltSection<ELFT> &PltSec;
|
const PltSection<ELFT> &PltSec;
|
||||||
const GotSection<ELFT> &GotSec;
|
const GotSection<ELFT> &GotSec;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,6 @@ namespace lld {
|
||||||
namespace elf2 {
|
namespace elf2 {
|
||||||
|
|
||||||
class ArchiveFile;
|
class ArchiveFile;
|
||||||
class Chunk;
|
|
||||||
class InputFile;
|
class InputFile;
|
||||||
class SymbolBody;
|
class SymbolBody;
|
||||||
template <class ELFT> class ObjectFile;
|
template <class ELFT> class ObjectFile;
|
||||||
|
|
|
@ -333,13 +333,13 @@ template <class ELFT> void Writer<ELFT>::createSections() {
|
||||||
SymTabSec.addSymbol(*SymName, true);
|
SymTabSec.addSymbol(*SymName, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (InputSection<ELFT> *C : File.getChunks()) {
|
for (InputSection<ELFT> *C : File.getSections()) {
|
||||||
if (!C)
|
if (!C)
|
||||||
continue;
|
continue;
|
||||||
const Elf_Shdr *H = C->getSectionHdr();
|
const Elf_Shdr *H = C->getSectionHdr();
|
||||||
OutputSection<ELFT> *Sec =
|
OutputSection<ELFT> *Sec =
|
||||||
getSection(C->getSectionName(), H->sh_type, H->sh_flags);
|
getSection(C->getSectionName(), H->sh_type, H->sh_flags);
|
||||||
Sec->addChunk(C);
|
Sec->addSection(C);
|
||||||
scanRelocs(*C);
|
scanRelocs(*C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue