forked from OSchip/llvm-project
MC/Mach-O: Factor out ExecutePostLayoutBinding, to separate the post-layout changes the object writer may need to make to the assembler from the actual .o writing.
llvm-svn: 98943
This commit is contained in:
parent
563d40eda6
commit
d84d196a86
|
@ -590,6 +590,8 @@ public:
|
||||||
typedef SymbolDataListType::const_iterator const_symbol_iterator;
|
typedef SymbolDataListType::const_iterator const_symbol_iterator;
|
||||||
typedef SymbolDataListType::iterator symbol_iterator;
|
typedef SymbolDataListType::iterator symbol_iterator;
|
||||||
|
|
||||||
|
typedef std::vector<IndirectSymbolData>::const_iterator
|
||||||
|
const_indirect_symbol_iterator;
|
||||||
typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
|
typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -742,10 +744,16 @@ public:
|
||||||
indirect_symbol_iterator indirect_symbol_begin() {
|
indirect_symbol_iterator indirect_symbol_begin() {
|
||||||
return IndirectSymbols.begin();
|
return IndirectSymbols.begin();
|
||||||
}
|
}
|
||||||
|
const_indirect_symbol_iterator indirect_symbol_begin() const {
|
||||||
|
return IndirectSymbols.begin();
|
||||||
|
}
|
||||||
|
|
||||||
indirect_symbol_iterator indirect_symbol_end() {
|
indirect_symbol_iterator indirect_symbol_end() {
|
||||||
return IndirectSymbols.end();
|
return IndirectSymbols.end();
|
||||||
}
|
}
|
||||||
|
const_indirect_symbol_iterator indirect_symbol_end() const {
|
||||||
|
return IndirectSymbols.end();
|
||||||
|
}
|
||||||
|
|
||||||
size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
|
size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
|
||||||
|
|
||||||
|
|
|
@ -778,23 +778,28 @@ public:
|
||||||
StringTable += '\x00';
|
StringTable += '\x00';
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteObject(MCAssembler &Asm) {
|
void ExecutePostLayoutBinding(MCAssembler &Asm) {
|
||||||
unsigned NumSections = Asm.size();
|
|
||||||
|
|
||||||
// Create symbol data for any indirect symbols.
|
// Create symbol data for any indirect symbols.
|
||||||
BindIndirectSymbols(Asm);
|
BindIndirectSymbols(Asm);
|
||||||
|
|
||||||
// Compute symbol table information.
|
// Compute symbol table information and bind symbol indices.
|
||||||
SmallString<256> StringTable;
|
ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
|
||||||
std::vector<MachSymbolData> LocalSymbolData;
|
UndefinedSymbolData);
|
||||||
std::vector<MachSymbolData> ExternalSymbolData;
|
|
||||||
std::vector<MachSymbolData> UndefinedSymbolData;
|
|
||||||
unsigned NumSymbols = Asm.symbol_size();
|
|
||||||
|
|
||||||
// No symbol table command is written if there are no symbols.
|
// Compute relocations.
|
||||||
if (NumSymbols)
|
for (MCAssembler::iterator it = Asm.begin(),
|
||||||
ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
|
ie = Asm.end(); it != ie; ++it) {
|
||||||
UndefinedSymbolData);
|
MCSectionData &SD = *it;
|
||||||
|
for (MCSectionData::iterator it2 = SD.begin(),
|
||||||
|
ie2 = SD.end(); it2 != ie2; ++it2)
|
||||||
|
if (MCDataFragment *DF = dyn_cast<MCDataFragment>(&*it2))
|
||||||
|
for (unsigned i = 0, e = DF->fixup_size(); i != e; ++i)
|
||||||
|
ComputeRelocationInfo(Asm, *DF, DF->getFixups()[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteObject(const MCAssembler &Asm) {
|
||||||
|
unsigned NumSections = Asm.size();
|
||||||
|
|
||||||
// The section data starts after the header, the segment load command (and
|
// The section data starts after the header, the segment load command (and
|
||||||
// section headers) and the symbol table.
|
// section headers) and the symbol table.
|
||||||
|
@ -804,6 +809,8 @@ public:
|
||||||
SegmentLoadCommand32Size + NumSections * Section32Size;
|
SegmentLoadCommand32Size + NumSections * Section32Size;
|
||||||
|
|
||||||
// Add the symbol table load command sizes, if used.
|
// Add the symbol table load command sizes, if used.
|
||||||
|
unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
|
||||||
|
UndefinedSymbolData.size();
|
||||||
if (NumSymbols) {
|
if (NumSymbols) {
|
||||||
NumLoadCommands += 2;
|
NumLoadCommands += 2;
|
||||||
LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize;
|
LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize;
|
||||||
|
@ -816,9 +823,9 @@ public:
|
||||||
uint64_t SectionDataSize = 0;
|
uint64_t SectionDataSize = 0;
|
||||||
uint64_t SectionDataFileSize = 0;
|
uint64_t SectionDataFileSize = 0;
|
||||||
uint64_t VMSize = 0;
|
uint64_t VMSize = 0;
|
||||||
for (MCAssembler::iterator it = Asm.begin(),
|
for (MCAssembler::const_iterator it = Asm.begin(),
|
||||||
ie = Asm.end(); it != ie; ++it) {
|
ie = Asm.end(); it != ie; ++it) {
|
||||||
MCSectionData &SD = *it;
|
const MCSectionData &SD = *it;
|
||||||
|
|
||||||
VMSize = std::max(VMSize, SD.getAddress() + SD.getSize());
|
VMSize = std::max(VMSize, SD.getAddress() + SD.getSize());
|
||||||
|
|
||||||
|
@ -843,19 +850,9 @@ public:
|
||||||
WriteSegmentLoadCommand(NumSections, VMSize,
|
WriteSegmentLoadCommand(NumSections, VMSize,
|
||||||
SectionDataStart, SectionDataSize);
|
SectionDataStart, SectionDataSize);
|
||||||
|
|
||||||
for (MCAssembler::iterator it = Asm.begin(),
|
|
||||||
ie = Asm.end(); it != ie; ++it) {
|
|
||||||
MCSectionData &SD = *it;
|
|
||||||
for (MCSectionData::iterator it2 = SD.begin(),
|
|
||||||
ie2 = SD.end(); it2 != ie2; ++it2)
|
|
||||||
if (MCDataFragment *DF = dyn_cast<MCDataFragment>(&*it2))
|
|
||||||
for (unsigned i = 0, e = DF->fixup_size(); i != e; ++i)
|
|
||||||
ComputeRelocationInfo(Asm, *DF, DF->getFixups()[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... and then the section headers.
|
// ... and then the section headers.
|
||||||
uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
|
uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
|
||||||
for (MCAssembler::iterator it = Asm.begin(),
|
for (MCAssembler::const_iterator it = Asm.begin(),
|
||||||
ie = Asm.end(); it != ie; ++it) {
|
ie = Asm.end(); it != ie; ++it) {
|
||||||
std::vector<MachRelocationEntry> &Relocs = Relocations[it];
|
std::vector<MachRelocationEntry> &Relocs = Relocations[it];
|
||||||
unsigned NumRelocs = Relocs.size();
|
unsigned NumRelocs = Relocs.size();
|
||||||
|
@ -899,14 +896,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the actual section data.
|
// Write the actual section data.
|
||||||
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
|
for (MCAssembler::const_iterator it = Asm.begin(),
|
||||||
|
ie = Asm.end(); it != ie; ++it)
|
||||||
WriteFileData(OS, *it, *this);
|
WriteFileData(OS, *it, *this);
|
||||||
|
|
||||||
// Write the extra padding.
|
// Write the extra padding.
|
||||||
WriteZeros(SectionDataPadding);
|
WriteZeros(SectionDataPadding);
|
||||||
|
|
||||||
// Write the relocation entries.
|
// Write the relocation entries.
|
||||||
for (MCAssembler::iterator it = Asm.begin(),
|
for (MCAssembler::const_iterator it = Asm.begin(),
|
||||||
ie = Asm.end(); it != ie; ++it) {
|
ie = Asm.end(); it != ie; ++it) {
|
||||||
// Write the section relocation entries, in reverse order to match 'as'
|
// Write the section relocation entries, in reverse order to match 'as'
|
||||||
// (approximately, the exact algorithm is more complicated than this).
|
// (approximately, the exact algorithm is more complicated than this).
|
||||||
|
@ -920,7 +918,7 @@ public:
|
||||||
// Write the symbol table data, if used.
|
// Write the symbol table data, if used.
|
||||||
if (NumSymbols) {
|
if (NumSymbols) {
|
||||||
// Write the indirect symbol entries.
|
// Write the indirect symbol entries.
|
||||||
for (MCAssembler::indirect_symbol_iterator
|
for (MCAssembler::const_indirect_symbol_iterator
|
||||||
it = Asm.indirect_symbol_begin(),
|
it = Asm.indirect_symbol_begin(),
|
||||||
ie = Asm.indirect_symbol_end(); it != ie; ++it) {
|
ie = Asm.indirect_symbol_end(); it != ie; ++it) {
|
||||||
// Indirect symbols in the non lazy symbol pointer section have some
|
// Indirect symbols in the non lazy symbol pointer section have some
|
||||||
|
@ -1478,11 +1476,15 @@ void MCAssembler::Finish() {
|
||||||
llvm::errs() << "assembler backend - post-layout\n--\n";
|
llvm::errs() << "assembler backend - post-layout\n--\n";
|
||||||
dump(); });
|
dump(); });
|
||||||
|
|
||||||
// Write the object file.
|
|
||||||
//
|
|
||||||
// FIXME: Factor out MCObjectWriter.
|
// FIXME: Factor out MCObjectWriter.
|
||||||
bool Is64Bit = StringRef(getBackend().getTarget().getName()) == "x86-64";
|
bool Is64Bit = StringRef(getBackend().getTarget().getName()) == "x86-64";
|
||||||
MachObjectWriter MOW(OS, Is64Bit);
|
MachObjectWriter MOW(OS, Is64Bit);
|
||||||
|
|
||||||
|
// Allow the object writer a chance to perform post-layout binding (for
|
||||||
|
// example, to set the index fields in the symbol data).
|
||||||
|
MOW.ExecutePostLayoutBinding(*this);
|
||||||
|
|
||||||
|
// Write the object file.
|
||||||
MOW.WriteObject(*this);
|
MOW.WriteObject(*this);
|
||||||
|
|
||||||
OS.flush();
|
OS.flush();
|
||||||
|
|
Loading…
Reference in New Issue