mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-26 05:25:47 +00:00
use std::vector instead of std::list for both Section and Symbol lists because
we care more about random access than insertion/deletion of elements. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75828 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -52,6 +52,70 @@ namespace llvm {
|
|||||||
EV_CURRENT = 1
|
EV_CURRENT = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// ELFSym - This struct contains information about each symbol that is
|
||||||
|
/// added to logical symbol table for the module. This is eventually
|
||||||
|
/// turned into a real symbol table in the file.
|
||||||
|
struct ELFSym {
|
||||||
|
// The global value this symbol matches. This should be null if the symbol
|
||||||
|
// is not a global value.
|
||||||
|
const GlobalValue *GV;
|
||||||
|
|
||||||
|
// ELF specific fields
|
||||||
|
unsigned NameIdx; // Index in .strtab of name, once emitted.
|
||||||
|
uint64_t Value;
|
||||||
|
unsigned Size;
|
||||||
|
uint8_t Info;
|
||||||
|
uint8_t Other;
|
||||||
|
unsigned short SectionIdx;
|
||||||
|
|
||||||
|
// Symbol index into the Symbol table
|
||||||
|
unsigned SymTabIdx;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STB_LOCAL = 0,
|
||||||
|
STB_GLOBAL = 1,
|
||||||
|
STB_WEAK = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STT_NOTYPE = 0,
|
||||||
|
STT_OBJECT = 1,
|
||||||
|
STT_FUNC = 2,
|
||||||
|
STT_SECTION = 3,
|
||||||
|
STT_FILE = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STV_DEFAULT = 0, // Visibility is specified by binding type
|
||||||
|
STV_INTERNAL = 1, // Defined by processor supplements
|
||||||
|
STV_HIDDEN = 2, // Not visible to other components
|
||||||
|
STV_PROTECTED = 3 // Visible in other components but not preemptable
|
||||||
|
};
|
||||||
|
|
||||||
|
ELFSym(const GlobalValue *gv) : GV(gv), NameIdx(0), Value(0),
|
||||||
|
Size(0), Info(0), Other(STV_DEFAULT),
|
||||||
|
SectionIdx(0), SymTabIdx(0) {}
|
||||||
|
|
||||||
|
unsigned getBind() const { return (Info >> 4) & 0xf; }
|
||||||
|
unsigned getType() const { return Info & 0xf; }
|
||||||
|
bool isLocalBind() const { return getBind() == STB_LOCAL; }
|
||||||
|
|
||||||
|
void setBind(unsigned X) {
|
||||||
|
assert(X == (X & 0xF) && "Bind value out of range!");
|
||||||
|
Info = (Info & 0x0F) | (X << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setType(unsigned X) {
|
||||||
|
assert(X == (X & 0xF) && "Type value out of range!");
|
||||||
|
Info = (Info & 0xF0) | X;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVisibility(unsigned V) {
|
||||||
|
assert(V == (V & 0x3) && "Visibility value out of range!");
|
||||||
|
Other = V;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// ELFSection - This struct contains information about each section that is
|
/// ELFSection - This struct contains information about each section that is
|
||||||
/// emitted to the file. This is eventually turned into the section header
|
/// emitted to the file. This is eventually turned into the section header
|
||||||
/// table at the end of the file.
|
/// table at the end of the file.
|
||||||
@@ -117,73 +181,12 @@ namespace llvm {
|
|||||||
/// SectionIdx - The number of the section in the Section Table.
|
/// SectionIdx - The number of the section in the Section Table.
|
||||||
unsigned short SectionIdx;
|
unsigned short SectionIdx;
|
||||||
|
|
||||||
|
/// Sym - The symbol to represent this section if it has one.
|
||||||
|
ELFSym *Sym;
|
||||||
|
|
||||||
ELFSection(const std::string &name, bool isLittleEndian, bool is64Bit)
|
ELFSection(const std::string &name, bool isLittleEndian, bool is64Bit)
|
||||||
: BinaryObject(name, isLittleEndian, is64Bit), Type(0), Flags(0), Addr(0),
|
: BinaryObject(name, isLittleEndian, is64Bit), Type(0), Flags(0), Addr(0),
|
||||||
Offset(0), Size(0), Link(0), Info(0), Align(0), EntSize(0) {}
|
Offset(0), Size(0), Link(0), Info(0), Align(0), EntSize(0), Sym(0) {}
|
||||||
};
|
|
||||||
|
|
||||||
/// ELFSym - This struct contains information about each symbol that is
|
|
||||||
/// added to logical symbol table for the module. This is eventually
|
|
||||||
/// turned into a real symbol table in the file.
|
|
||||||
struct ELFSym {
|
|
||||||
// The global value this symbol matches. This should be null if the symbol
|
|
||||||
// is not a global value.
|
|
||||||
const GlobalValue *GV;
|
|
||||||
|
|
||||||
// ELF specific fields
|
|
||||||
unsigned NameIdx; // Index in .strtab of name, once emitted.
|
|
||||||
uint64_t Value;
|
|
||||||
unsigned Size;
|
|
||||||
uint8_t Info;
|
|
||||||
uint8_t Other;
|
|
||||||
unsigned short SectionIdx;
|
|
||||||
|
|
||||||
// Symbol index into the Symbol table
|
|
||||||
unsigned SymTabIdx;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
STB_LOCAL = 0,
|
|
||||||
STB_GLOBAL = 1,
|
|
||||||
STB_WEAK = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
STT_NOTYPE = 0,
|
|
||||||
STT_OBJECT = 1,
|
|
||||||
STT_FUNC = 2,
|
|
||||||
STT_SECTION = 3,
|
|
||||||
STT_FILE = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
STV_DEFAULT = 0, // Visibility is specified by binding type
|
|
||||||
STV_INTERNAL = 1, // Defined by processor supplements
|
|
||||||
STV_HIDDEN = 2, // Not visible to other components
|
|
||||||
STV_PROTECTED = 3 // Visible in other components but not preemptable
|
|
||||||
};
|
|
||||||
|
|
||||||
ELFSym(const GlobalValue *gv) : GV(gv), NameIdx(0), Value(0),
|
|
||||||
Size(0), Info(0), Other(STV_DEFAULT),
|
|
||||||
SectionIdx(ELFSection::SHN_UNDEF),
|
|
||||||
SymTabIdx(0) {}
|
|
||||||
|
|
||||||
unsigned getBind() { return (Info >> 4) & 0xf; }
|
|
||||||
unsigned getType() { return Info & 0xf; }
|
|
||||||
|
|
||||||
void setBind(unsigned X) {
|
|
||||||
assert(X == (X & 0xF) && "Bind value out of range!");
|
|
||||||
Info = (Info & 0x0F) | (X << 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setType(unsigned X) {
|
|
||||||
assert(X == (X & 0xF) && "Type value out of range!");
|
|
||||||
Info = (Info & 0xF0) | X;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setVisibility(unsigned V) {
|
|
||||||
assert(V == (V & 0x3) && "Type value out of range!");
|
|
||||||
Other = V;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ELFRelocation - This class contains all the information necessary to
|
/// ELFRelocation - This class contains all the information necessary to
|
||||||
|
@@ -60,23 +60,18 @@ void ELFCodeEmitter::startFunction(MachineFunction &MF) {
|
|||||||
bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
|
bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
|
||||||
// Add a symbol to represent the function.
|
// Add a symbol to represent the function.
|
||||||
const Function *F = MF.getFunction();
|
const Function *F = MF.getFunction();
|
||||||
ELFSym FnSym(F);
|
ELFSym *FnSym = new ELFSym(F);
|
||||||
FnSym.setType(ELFSym::STT_FUNC);
|
FnSym->setType(ELFSym::STT_FUNC);
|
||||||
FnSym.setBind(EW.getGlobalELFBinding(F));
|
FnSym->setBind(EW.getGlobalELFBinding(F));
|
||||||
FnSym.setVisibility(EW.getGlobalELFVisibility(F));
|
FnSym->setVisibility(EW.getGlobalELFVisibility(F));
|
||||||
FnSym.SectionIdx = ES->SectionIdx;
|
FnSym->SectionIdx = ES->SectionIdx;
|
||||||
FnSym.Size = ES->getCurrentPCOffset()-FnStartOff;
|
FnSym->Size = ES->getCurrentPCOffset()-FnStartOff;
|
||||||
|
|
||||||
// Offset from start of Section
|
// Offset from start of Section
|
||||||
FnSym.Value = FnStartOff;
|
FnSym->Value = FnStartOff;
|
||||||
|
|
||||||
// Locals should go on the symbol list front
|
if (!F->hasPrivateLinkage())
|
||||||
if (!F->hasPrivateLinkage()) {
|
EW.SymbolList.push_back(FnSym);
|
||||||
if (FnSym.getBind() == ELFSym::STB_LOCAL)
|
|
||||||
EW.SymbolList.push_front(FnSym);
|
|
||||||
else
|
|
||||||
EW.SymbolList.push_back(FnSym);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emit constant pool to appropriate section(s)
|
// Emit constant pool to appropriate section(s)
|
||||||
emitConstantPool(MF.getConstantPool());
|
emitConstantPool(MF.getConstantPool());
|
||||||
|
@@ -235,13 +235,13 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
|
|||||||
|
|
||||||
// Handle ELF Bind, Visibility and Type for the current symbol
|
// Handle ELF Bind, Visibility and Type for the current symbol
|
||||||
unsigned SymBind = getGlobalELFBinding(GV);
|
unsigned SymBind = getGlobalELFBinding(GV);
|
||||||
ELFSym GblSym(GV);
|
ELFSym *GblSym = new ELFSym(GV);
|
||||||
GblSym.setBind(SymBind);
|
GblSym->setBind(SymBind);
|
||||||
GblSym.setVisibility(getGlobalELFVisibility(GV));
|
GblSym->setVisibility(getGlobalELFVisibility(GV));
|
||||||
GblSym.setType(getGlobalELFType(GV));
|
GblSym->setType(getGlobalELFType(GV));
|
||||||
|
|
||||||
if (isELFUndefSym(GV)) {
|
if (isELFUndefSym(GV)) {
|
||||||
GblSym.SectionIdx = ELFSection::SHN_UNDEF;
|
GblSym->SectionIdx = ELFSection::SHN_UNDEF;
|
||||||
} else {
|
} else {
|
||||||
assert(isa<GlobalVariable>(GV) && "GV not a global variable!");
|
assert(isa<GlobalVariable>(GV) && "GV not a global variable!");
|
||||||
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
|
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
|
||||||
@@ -254,41 +254,41 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
|
|||||||
const TargetData *TD = TM.getTargetData();
|
const TargetData *TD = TM.getTargetData();
|
||||||
unsigned Align = TD->getPreferredAlignment(GVar);
|
unsigned Align = TD->getPreferredAlignment(GVar);
|
||||||
unsigned Size = TD->getTypeAllocSize(GVar->getInitializer()->getType());
|
unsigned Size = TD->getTypeAllocSize(GVar->getInitializer()->getType());
|
||||||
GblSym.Size = Size;
|
GblSym->Size = Size;
|
||||||
|
|
||||||
if (isELFCommonSym(GV)) {
|
if (isELFCommonSym(GV)) {
|
||||||
GblSym.SectionIdx = ELFSection::SHN_COMMON;
|
GblSym->SectionIdx = ELFSection::SHN_COMMON;
|
||||||
getSection(S->getName(), ELFSection::SHT_NOBITS, SectionFlags, 1);
|
getSection(S->getName(), ELFSection::SHT_NOBITS, SectionFlags, 1);
|
||||||
|
|
||||||
// A new linkonce section is created for each global in the
|
// A new linkonce section is created for each global in the
|
||||||
// common section, the default alignment is 1 and the symbol
|
// common section, the default alignment is 1 and the symbol
|
||||||
// value contains its alignment.
|
// value contains its alignment.
|
||||||
GblSym.Value = Align;
|
GblSym->Value = Align;
|
||||||
|
|
||||||
} else if (isELFBssSym(GV)) {
|
} else if (isELFBssSym(GV)) {
|
||||||
ELFSection &ES =
|
ELFSection &ES =
|
||||||
getSection(S->getName(), ELFSection::SHT_NOBITS, SectionFlags);
|
getSection(S->getName(), ELFSection::SHT_NOBITS, SectionFlags);
|
||||||
GblSym.SectionIdx = ES.SectionIdx;
|
GblSym->SectionIdx = ES.SectionIdx;
|
||||||
|
|
||||||
// Update the size with alignment and the next object can
|
// Update the size with alignment and the next object can
|
||||||
// start in the right offset in the section
|
// start in the right offset in the section
|
||||||
if (Align) ES.Size = (ES.Size + Align-1) & ~(Align-1);
|
if (Align) ES.Size = (ES.Size + Align-1) & ~(Align-1);
|
||||||
ES.Align = std::max(ES.Align, Align);
|
ES.Align = std::max(ES.Align, Align);
|
||||||
|
|
||||||
// GblSym.Value should contain the virtual offset inside the section.
|
// GblSym->Value should contain the virtual offset inside the section.
|
||||||
// Virtual because the BSS space is not allocated on ELF objects
|
// Virtual because the BSS space is not allocated on ELF objects
|
||||||
GblSym.Value = ES.Size;
|
GblSym->Value = ES.Size;
|
||||||
ES.Size += Size;
|
ES.Size += Size;
|
||||||
|
|
||||||
} else if (isELFDataSym(GV)) {
|
} else if (isELFDataSym(GV)) {
|
||||||
ELFSection &ES =
|
ELFSection &ES =
|
||||||
getSection(S->getName(), ELFSection::SHT_PROGBITS, SectionFlags);
|
getSection(S->getName(), ELFSection::SHT_PROGBITS, SectionFlags);
|
||||||
GblSym.SectionIdx = ES.SectionIdx;
|
GblSym->SectionIdx = ES.SectionIdx;
|
||||||
|
|
||||||
// GblSym.Value should contain the symbol offset inside the section,
|
// GblSym->Value should contain the symbol offset inside the section,
|
||||||
// and all symbols should start on their required alignment boundary
|
// and all symbols should start on their required alignment boundary
|
||||||
ES.Align = std::max(ES.Align, Align);
|
ES.Align = std::max(ES.Align, Align);
|
||||||
GblSym.Value = (ES.size() + (Align-1)) & (-Align);
|
GblSym->Value = (ES.size() + (Align-1)) & (-Align);
|
||||||
ES.emitAlignment(ES.Align);
|
ES.emitAlignment(ES.Align);
|
||||||
|
|
||||||
// Emit the global to the data section 'ES'
|
// Emit the global to the data section 'ES'
|
||||||
@@ -296,13 +296,8 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local symbols should come first on the symbol table.
|
if (!GV->hasPrivateLinkage())
|
||||||
if (!GV->hasPrivateLinkage()) {
|
SymbolList.push_back(GblSym);
|
||||||
if (SymBind == ELFSym::STB_LOCAL)
|
|
||||||
SymbolList.push_front(GblSym);
|
|
||||||
else
|
|
||||||
SymbolList.push_back(GblSym);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELFWriter::EmitGlobalConstantStruct(const ConstantStruct *CVS,
|
void ELFWriter::EmitGlobalConstantStruct(const ConstantStruct *CVS,
|
||||||
@@ -419,23 +414,17 @@ bool ELFWriter::doFinalization(Module &M) {
|
|||||||
if (TAI->getNonexecutableStackDirective())
|
if (TAI->getNonexecutableStackDirective())
|
||||||
getNonExecStackSection();
|
getNonExecStackSection();
|
||||||
|
|
||||||
// Emit a symbol for each section created until now
|
// Emit a symbol for each section created until now, skip null section
|
||||||
for (std::map<std::string, ELFSection*>::iterator I = SectionLookup.begin(),
|
for (unsigned i = 1, e = SectionList.size(); i < e; ++i) {
|
||||||
E = SectionLookup.end(); I != E; ++I) {
|
ELFSection &ES = *SectionList[i];
|
||||||
ELFSection *ES = I->second;
|
ELFSym *SectionSym = new ELFSym(0);
|
||||||
|
SectionSym->SectionIdx = ES.SectionIdx;
|
||||||
// Skip null section
|
SectionSym->Size = 0;
|
||||||
if (ES->SectionIdx == 0) continue;
|
SectionSym->setBind(ELFSym::STB_LOCAL);
|
||||||
|
SectionSym->setType(ELFSym::STT_SECTION);
|
||||||
ELFSym SectionSym(0);
|
SectionSym->setVisibility(ELFSym::STV_DEFAULT);
|
||||||
SectionSym.SectionIdx = ES->SectionIdx;
|
SymbolList.push_back(SectionSym);
|
||||||
SectionSym.Size = 0;
|
ES.Sym = SymbolList.back();
|
||||||
SectionSym.setBind(ELFSym::STB_LOCAL);
|
|
||||||
SectionSym.setType(ELFSym::STT_SECTION);
|
|
||||||
SectionSym.setVisibility(ELFSym::STV_DEFAULT);
|
|
||||||
|
|
||||||
// Local symbols go in the list front
|
|
||||||
SymbolList.push_front(SectionSym);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit string table
|
// Emit string table
|
||||||
@@ -454,6 +443,7 @@ bool ELFWriter::doFinalization(Module &M) {
|
|||||||
OutputSectionsAndSectionTable();
|
OutputSectionsAndSectionTable();
|
||||||
|
|
||||||
// We are done with the abstract symbols.
|
// We are done with the abstract symbols.
|
||||||
|
SymbolList.clear();
|
||||||
SectionList.clear();
|
SectionList.clear();
|
||||||
NumSections = 0;
|
NumSections = 0;
|
||||||
|
|
||||||
@@ -466,26 +456,26 @@ bool ELFWriter::doFinalization(Module &M) {
|
|||||||
void ELFWriter::EmitRelocations() {
|
void ELFWriter::EmitRelocations() {
|
||||||
|
|
||||||
// Create Relocation sections for each section which needs it.
|
// Create Relocation sections for each section which needs it.
|
||||||
for (std::list<ELFSection>::iterator I = SectionList.begin(),
|
for (unsigned i=0, e=SectionList.size(); i < e; ++i) {
|
||||||
E = SectionList.end(); I != E; ++I) {
|
ELFSection &S = *SectionList[i];
|
||||||
|
|
||||||
// This section does not have relocations
|
// This section does not have relocations
|
||||||
if (!I->hasRelocations()) continue;
|
if (!S.hasRelocations()) continue;
|
||||||
|
|
||||||
// Get the relocation section for section 'I'
|
// Get the relocation section for section 'S'
|
||||||
bool HasRelA = TEW->hasRelocationAddend();
|
bool HasRelA = TEW->hasRelocationAddend();
|
||||||
ELFSection &RelSec = getRelocSection(I->getName(), HasRelA,
|
ELFSection &RelSec = getRelocSection(S.getName(), HasRelA,
|
||||||
TEW->getPrefELFAlignment());
|
TEW->getPrefELFAlignment());
|
||||||
|
|
||||||
// 'Link' - Section hdr idx of the associated symbol table
|
// 'Link' - Section hdr idx of the associated symbol table
|
||||||
// 'Info' - Section hdr idx of the section to which the relocation applies
|
// 'Info' - Section hdr idx of the section to which the relocation applies
|
||||||
ELFSection &SymTab = getSymbolTableSection();
|
ELFSection &SymTab = getSymbolTableSection();
|
||||||
RelSec.Link = SymTab.SectionIdx;
|
RelSec.Link = SymTab.SectionIdx;
|
||||||
RelSec.Info = I->SectionIdx;
|
RelSec.Info = S.SectionIdx;
|
||||||
RelSec.EntSize = TEW->getRelocationEntrySize();
|
RelSec.EntSize = TEW->getRelocationEntrySize();
|
||||||
|
|
||||||
// Get the relocations from Section
|
// Get the relocations from Section
|
||||||
std::vector<MachineRelocation> Relos = I->getRelocations();
|
std::vector<MachineRelocation> Relos = S.getRelocations();
|
||||||
for (std::vector<MachineRelocation>::iterator MRI = Relos.begin(),
|
for (std::vector<MachineRelocation>::iterator MRI = Relos.begin(),
|
||||||
MRE = Relos.end(); MRI != MRE; ++MRI) {
|
MRE = Relos.end(); MRI != MRE; ++MRI) {
|
||||||
MachineRelocation &MR = *MRI;
|
MachineRelocation &MR = *MRI;
|
||||||
@@ -510,15 +500,10 @@ void ELFWriter::EmitRelocations() {
|
|||||||
SymIdx = GblSymLookup[G];
|
SymIdx = GblSymLookup[G];
|
||||||
Addend = TEW->getAddendForRelTy(RelType);
|
Addend = TEW->getAddendForRelTy(RelType);
|
||||||
} else {
|
} else {
|
||||||
|
// Get the symbol index for the section symbol referenced
|
||||||
|
// by the relocation
|
||||||
unsigned SectionIdx = MR.getConstantVal();
|
unsigned SectionIdx = MR.getConstantVal();
|
||||||
// TODO: use a map for this.
|
SymIdx = SectionList[SectionIdx]->Sym->SymTabIdx;
|
||||||
for (std::list<ELFSym>::iterator I = SymbolList.begin(),
|
|
||||||
E = SymbolList.end(); I != E; ++I)
|
|
||||||
if ((SectionIdx == I->SectionIdx) &&
|
|
||||||
(I->getType() == ELFSym::STT_SECTION)) {
|
|
||||||
SymIdx = I->SymTabIdx;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Addend = (uint64_t)MR.getResultPointer();
|
Addend = (uint64_t)MR.getResultPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,17 +581,17 @@ void ELFWriter::EmitStringTable() {
|
|||||||
// Walk on the symbol list and write symbol names into the
|
// Walk on the symbol list and write symbol names into the
|
||||||
// string table.
|
// string table.
|
||||||
unsigned Index = 1;
|
unsigned Index = 1;
|
||||||
for (std::list<ELFSym>::iterator I = SymbolList.begin(),
|
for (unsigned i = 0, e = SymbolList.size(); i < e; ++i) {
|
||||||
E = SymbolList.end(); I != E; ++I) {
|
ELFSym &Sym = *SymbolList[i];
|
||||||
|
|
||||||
// Use the name mangler to uniquify the LLVM symbol.
|
// Use the name mangler to uniquify the LLVM symbol.
|
||||||
std::string Name;
|
std::string Name;
|
||||||
if (I->GV) Name.append(Mang->getMangledName(I->GV));
|
if (Sym.GV) Name.append(Mang->getMangledName(Sym.GV));
|
||||||
|
|
||||||
if (Name.empty()) {
|
if (Name.empty()) {
|
||||||
I->NameIdx = 0;
|
Sym.NameIdx = 0;
|
||||||
} else {
|
} else {
|
||||||
I->NameIdx = Index;
|
Sym.NameIdx = Index;
|
||||||
StrTab.emitString(Name);
|
StrTab.emitString(Name);
|
||||||
|
|
||||||
// Keep track of the number of bytes emitted to this section.
|
// Keep track of the number of bytes emitted to this section.
|
||||||
@@ -617,11 +602,38 @@ void ELFWriter::EmitStringTable() {
|
|||||||
StrTab.Size = Index;
|
StrTab.Size = Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SortSymbols - On the symbol table local symbols must come before
|
||||||
|
// all other symbols with non-local bindings. The return value is
|
||||||
|
// the position of the first non local symbol.
|
||||||
|
unsigned ELFWriter::SortSymbols() {
|
||||||
|
unsigned FirstNonLocalSymbol, i, e;
|
||||||
|
std::vector<ELFSym*> LocalSyms, OtherSyms;
|
||||||
|
|
||||||
|
for (i = 0, e = SymbolList.size(); i < e; ++i) {
|
||||||
|
if (SymbolList[i]->isLocalBind())
|
||||||
|
LocalSyms.push_back(SymbolList[i]);
|
||||||
|
else
|
||||||
|
OtherSyms.push_back(SymbolList[i]);
|
||||||
|
}
|
||||||
|
SymbolList.clear();
|
||||||
|
FirstNonLocalSymbol = LocalSyms.size();
|
||||||
|
|
||||||
|
for (i = 0; i < FirstNonLocalSymbol; ++i)
|
||||||
|
SymbolList.push_back(LocalSyms[i]);
|
||||||
|
|
||||||
|
for (i = 0, e = OtherSyms.size(); i < e; ++i)
|
||||||
|
SymbolList.push_back(OtherSyms[i]);
|
||||||
|
|
||||||
|
LocalSyms.clear();
|
||||||
|
OtherSyms.clear();
|
||||||
|
|
||||||
|
return FirstNonLocalSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
/// EmitSymbolTable - Emit the symbol table itself.
|
/// EmitSymbolTable - Emit the symbol table itself.
|
||||||
void ELFWriter::EmitSymbolTable() {
|
void ELFWriter::EmitSymbolTable() {
|
||||||
if (!SymbolList.size()) return; // Empty symbol table.
|
if (!SymbolList.size()) return; // Empty symbol table.
|
||||||
|
|
||||||
unsigned FirstNonLocalSymbol = 1;
|
|
||||||
// Now that we have emitted the string table and know the offset into the
|
// Now that we have emitted the string table and know the offset into the
|
||||||
// string table of each symbol, emit the symbol table itself.
|
// string table of each symbol, emit the symbol table itself.
|
||||||
ELFSection &SymTab = getSymbolTableSection();
|
ELFSection &SymTab = getSymbolTableSection();
|
||||||
@@ -634,29 +646,26 @@ void ELFWriter::EmitSymbolTable() {
|
|||||||
SymTab.EntSize = TEW->getSymTabEntrySize();
|
SymTab.EntSize = TEW->getSymTabEntrySize();
|
||||||
|
|
||||||
// The first entry in the symtab is the null symbol
|
// The first entry in the symtab is the null symbol
|
||||||
ELFSym NullSym = ELFSym(0);
|
SymbolList.insert(SymbolList.begin(), new ELFSym(0));
|
||||||
EmitSymbol(SymTab, NullSym);
|
|
||||||
|
|
||||||
// Emit all the symbols to the symbol table. Skip the null
|
// Reorder the symbol table with local symbols first!
|
||||||
// symbol, cause it's emitted already
|
unsigned FirstNonLocalSymbol = SortSymbols();
|
||||||
unsigned Index = 1;
|
|
||||||
for (std::list<ELFSym>::iterator I = SymbolList.begin(),
|
// Emit all the symbols to the symbol table.
|
||||||
E = SymbolList.end(); I != E; ++I, ++Index) {
|
for (unsigned i = 0, e = SymbolList.size(); i < e; ++i) {
|
||||||
// Keep track of the first non-local symbol
|
ELFSym &Sym = *SymbolList[i];
|
||||||
if (I->getBind() == ELFSym::STB_LOCAL)
|
|
||||||
FirstNonLocalSymbol++;
|
|
||||||
|
|
||||||
// Emit symbol to the symbol table
|
// Emit symbol to the symbol table
|
||||||
EmitSymbol(SymTab, *I);
|
EmitSymbol(SymTab, Sym);
|
||||||
|
|
||||||
// Record the symbol table index for each global value
|
// Record the symbol table index for each global value
|
||||||
if (I->GV)
|
if (Sym.GV) GblSymLookup[Sym.GV] = i;
|
||||||
GblSymLookup[I->GV] = Index;
|
|
||||||
|
|
||||||
// Keep track on the symbol index into the symbol table
|
// Keep track on the symbol index into the symbol table
|
||||||
I->SymTabIdx = Index;
|
Sym.SymTabIdx = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// One greater than the symbol table index of the last local symbol
|
||||||
SymTab.Info = FirstNonLocalSymbol;
|
SymTab.Info = FirstNonLocalSymbol;
|
||||||
SymTab.Size = SymTab.size();
|
SymTab.Size = SymTab.size();
|
||||||
}
|
}
|
||||||
@@ -676,15 +685,14 @@ void ELFWriter::EmitSectionTableStringTable() {
|
|||||||
// the string table.
|
// the string table.
|
||||||
unsigned Index = 0;
|
unsigned Index = 0;
|
||||||
|
|
||||||
for (std::list<ELFSection>::iterator I = SectionList.begin(),
|
for (unsigned i=0, e=SectionList.size(); i < e; ++i) {
|
||||||
E = SectionList.end(); I != E; ++I) {
|
|
||||||
// Set the index into the table. Note if we have lots of entries with
|
// Set the index into the table. Note if we have lots of entries with
|
||||||
// common suffixes, we could memoize them here if we cared.
|
// common suffixes, we could memoize them here if we cared.
|
||||||
I->NameIdx = Index;
|
SectionList[i]->NameIdx = Index;
|
||||||
SHStrTab.emitString(I->getName());
|
SHStrTab.emitString(SectionList[i]->getName());
|
||||||
|
|
||||||
// Keep track of the number of bytes emitted to this section.
|
// Keep track of the number of bytes emitted to this section.
|
||||||
Index += I->getName().size()+1;
|
Index += SectionList[i]->getName().size()+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the size of .shstrtab now that we know what it is.
|
// Set the size of .shstrtab now that we know what it is.
|
||||||
@@ -699,29 +707,24 @@ void ELFWriter::OutputSectionsAndSectionTable() {
|
|||||||
// Pass #1: Compute the file offset for each section.
|
// Pass #1: Compute the file offset for each section.
|
||||||
size_t FileOff = ElfHdr.size(); // File header first.
|
size_t FileOff = ElfHdr.size(); // File header first.
|
||||||
|
|
||||||
// Adjust alignment of all section if needed.
|
// Adjust alignment of all section if needed, skip the null section.
|
||||||
for (std::list<ELFSection>::iterator I = SectionList.begin(),
|
for (unsigned i=1, e=SectionList.size(); i < e; ++i) {
|
||||||
E = SectionList.end(); I != E; ++I) {
|
ELFSection &ES = *SectionList[i];
|
||||||
|
if (!ES.size()) {
|
||||||
// Section idx 0 has 0 offset
|
ES.Offset = FileOff;
|
||||||
if (!I->SectionIdx)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!I->size()) {
|
|
||||||
I->Offset = FileOff;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Section size
|
// Update Section size
|
||||||
if (!I->Size)
|
if (!ES.Size)
|
||||||
I->Size = I->size();
|
ES.Size = ES.size();
|
||||||
|
|
||||||
// Align FileOff to whatever the alignment restrictions of the section are.
|
// Align FileOff to whatever the alignment restrictions of the section are.
|
||||||
if (I->Align)
|
if (ES.Align)
|
||||||
FileOff = (FileOff+I->Align-1) & ~(I->Align-1);
|
FileOff = (FileOff+ES.Align-1) & ~(ES.Align-1);
|
||||||
|
|
||||||
I->Offset = FileOff;
|
ES.Offset = FileOff;
|
||||||
FileOff += I->Size;
|
FileOff += ES.Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Align Section Header.
|
// Align Section Header.
|
||||||
@@ -745,8 +748,8 @@ void ELFWriter::OutputSectionsAndSectionTable() {
|
|||||||
BinaryObject SHdrTable(isLittleEndian, is64Bit);
|
BinaryObject SHdrTable(isLittleEndian, is64Bit);
|
||||||
|
|
||||||
// Emit all of sections to the file and build the section header table.
|
// Emit all of sections to the file and build the section header table.
|
||||||
while (!SectionList.empty()) {
|
for (unsigned i=0, e=SectionList.size(); i < e; ++i) {
|
||||||
ELFSection &S = *SectionList.begin();
|
ELFSection &S = *SectionList[i];
|
||||||
DOUT << "SectionIdx: " << S.SectionIdx << ", Name: " << S.getName()
|
DOUT << "SectionIdx: " << S.SectionIdx << ", Name: " << S.getName()
|
||||||
<< ", Size: " << S.Size << ", Offset: " << S.Offset
|
<< ", Size: " << S.Size << ", Offset: " << S.Offset
|
||||||
<< ", SectionData Size: " << S.size() << "\n";
|
<< ", SectionData Size: " << S.size() << "\n";
|
||||||
@@ -763,7 +766,6 @@ void ELFWriter::OutputSectionsAndSectionTable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EmitSectionHeader(SHdrTable, S);
|
EmitSectionHeader(SHdrTable, S);
|
||||||
SectionList.pop_front();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Align output for the section table.
|
// Align output for the section table.
|
||||||
|
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
#include "llvm/ADT/SetVector.h"
|
#include "llvm/ADT/SetVector.h"
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
#include <list>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@@ -95,13 +94,13 @@ namespace llvm {
|
|||||||
BinaryObject ElfHdr;
|
BinaryObject ElfHdr;
|
||||||
|
|
||||||
/// SectionList - This is the list of sections that we have emitted to the
|
/// SectionList - This is the list of sections that we have emitted to the
|
||||||
/// file. Once the file has been completely built, the section header table
|
/// file. Once the file has been completely built, the section header table
|
||||||
/// is constructed from this info.
|
/// is constructed from this info.
|
||||||
std::list<ELFSection> SectionList;
|
std::vector<ELFSection*> SectionList;
|
||||||
unsigned NumSections; // Always = SectionList.size()
|
unsigned NumSections; // Always = SectionList.size()
|
||||||
|
|
||||||
/// SectionLookup - This is a mapping from section name to section number in
|
/// SectionLookup - This is a mapping from section name to section number in
|
||||||
/// the SectionList.
|
/// the SectionList. Used to quickly gather the Section Index from TAI names
|
||||||
std::map<std::string, ELFSection*> SectionLookup;
|
std::map<std::string, ELFSection*> SectionLookup;
|
||||||
|
|
||||||
/// GblSymLookup - This is a mapping from global value to a symbol index
|
/// GblSymLookup - This is a mapping from global value to a symbol index
|
||||||
@@ -109,17 +108,18 @@ namespace llvm {
|
|||||||
/// must be quickly mapped to a symbol table index
|
/// must be quickly mapped to a symbol table index
|
||||||
std::map<const GlobalValue*, uint32_t> GblSymLookup;
|
std::map<const GlobalValue*, uint32_t> GblSymLookup;
|
||||||
|
|
||||||
/// SymbolList - This is the list of symbols emitted to the symbol table
|
/// SymbolList - This is the list of symbols emitted to the symbol table.
|
||||||
/// Local symbols go to the front and Globals to the back.
|
/// When the SymbolList is finally built, local symbols must be placed in
|
||||||
std::list<ELFSym> SymbolList;
|
/// the beginning while non-locals at the end.
|
||||||
|
std::vector<ELFSym*> SymbolList;
|
||||||
|
|
||||||
/// PendingGlobals - List of externally defined symbols that we have been
|
/// PendingGlobals - List of externally defined symbols that we have been
|
||||||
/// asked to emit, but have not seen a reference to. When a reference
|
/// asked to emit, but have not seen a reference to. When a reference
|
||||||
/// is seen, the symbol will move from this list to the SymbolList.
|
/// is seen, the symbol will move from this list to the SymbolList.
|
||||||
SetVector<GlobalValue*> PendingGlobals;
|
SetVector<GlobalValue*> PendingGlobals;
|
||||||
|
|
||||||
// Remove tab from section name prefix. This is necessary becase TAI
|
// Remove tab from section name prefix. This is necessary becase TAI
|
||||||
// sometimes return a section name prefixed with a "\t" char. This is
|
// sometimes return a section name prefixed with elf unused chars. This is
|
||||||
// a little bit dirty. FIXME: find a better approach, maybe add more
|
// a little bit dirty. FIXME: find a better approach, maybe add more
|
||||||
// methods to TAI to get the clean name?
|
// methods to TAI to get the clean name?
|
||||||
void fixNameForSection(std::string &Name) {
|
void fixNameForSection(std::string &Name) {
|
||||||
@@ -140,14 +140,14 @@ namespace llvm {
|
|||||||
/// section if one does not already exist.
|
/// section if one does not already exist.
|
||||||
ELFSection &getSection(const std::string &Name, unsigned Type,
|
ELFSection &getSection(const std::string &Name, unsigned Type,
|
||||||
unsigned Flags = 0, unsigned Align = 0) {
|
unsigned Flags = 0, unsigned Align = 0) {
|
||||||
std::string SectionName(Name);
|
std::string SName(Name);
|
||||||
fixNameForSection(SectionName);
|
fixNameForSection(SName);
|
||||||
|
|
||||||
ELFSection *&SN = SectionLookup[SectionName];
|
ELFSection *&SN = SectionLookup[SName];
|
||||||
if (SN) return *SN;
|
if (SN) return *SN;
|
||||||
|
|
||||||
SectionList.push_back(ELFSection(SectionName, isLittleEndian, is64Bit));
|
SectionList.push_back(new ELFSection(SName, isLittleEndian, is64Bit));
|
||||||
SN = &SectionList.back();
|
SN = SectionList.back();
|
||||||
SN->SectionIdx = NumSections++;
|
SN->SectionIdx = NumSections++;
|
||||||
SN->Type = Type;
|
SN->Type = Type;
|
||||||
SN->Flags = Flags;
|
SN->Flags = Flags;
|
||||||
@@ -245,6 +245,7 @@ namespace llvm {
|
|||||||
void EmitSymbolTable();
|
void EmitSymbolTable();
|
||||||
void EmitStringTable();
|
void EmitStringTable();
|
||||||
void OutputSectionsAndSectionTable();
|
void OutputSectionsAndSectionTable();
|
||||||
|
unsigned SortSymbols();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -65,6 +65,8 @@ long int X86ELFWriterInfo::getAddendForRelTy(unsigned RelTy) const {
|
|||||||
switch(RelTy) {
|
switch(RelTy) {
|
||||||
case R_X86_64_PC32: return -4;
|
case R_X86_64_PC32: return -4;
|
||||||
break;
|
break;
|
||||||
|
case R_X86_64_32: return 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("unknown x86 relocation type");
|
llvm_unreachable("unknown x86 relocation type");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user