Change ELFCodeEmitter logic to emit the constant pool and jump tables to

their appropriate sections before the code itself. They need to be emitted
before the function because on some targets (x86 but not x86_64) the later
may reference a JT or CP entry address


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76672 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bruno Cardoso Lopes 2009-07-21 23:13:26 +00:00
parent 0f4b285a5b
commit 82a70ccb24
3 changed files with 30 additions and 28 deletions

View File

@ -120,7 +120,7 @@ namespace llvm {
virtual unsigned getAbsoluteLabelMachineRelTy() const = 0; virtual unsigned getAbsoluteLabelMachineRelTy() const = 0;
/// computeRelocation - Some relocatable fields could be relocated /// computeRelocation - Some relocatable fields could be relocated
/// directly, avoiding the emission of a relocation symbol, compute the /// directly, avoiding the relocation symbol emission, compute the
/// final relocation value for this symbol. /// final relocation value for this symbol.
virtual long int computeRelocation(unsigned SymOffset, unsigned RelOffset, virtual long int computeRelocation(unsigned SymOffset, unsigned RelOffset,
unsigned RelTy) const = 0; unsigned RelTy) const = 0;

View File

@ -54,6 +54,12 @@ void ELFCodeEmitter::startFunction(MachineFunction &MF) {
// Record the function start offset // Record the function start offset
FnStartOff = ES->getCurrentPCOffset(); FnStartOff = ES->getCurrentPCOffset();
// Emit constant pool and jump tables to their appropriate sections.
// They need to be emitted before the function because in some targets
// the later may reference JT or CP entry address.
emitConstantPool(MF.getConstantPool());
emitJumpTables(MF.getJumpTableInfo());
} }
/// finishFunction - This callback is invoked after the function is completely /// finishFunction - This callback is invoked after the function is completely
@ -78,11 +84,17 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
if (!F->hasPrivateLinkage()) if (!F->hasPrivateLinkage())
EW.SymbolList.push_back(FnSym); EW.SymbolList.push_back(FnSym);
// Emit constant pool to appropriate section(s) // Patch up Jump Table Section relocations to use the real MBBs offsets
emitConstantPool(MF.getConstantPool()); // now that the MBB label offsets inside the function are known.
ELFSection &JTSection = EW.getJumpTableSection();
// Emit jump tables to appropriate section for (std::vector<MachineRelocation>::iterator MRI = JTRelocations.begin(),
emitJumpTables(MF.getJumpTableInfo()); MRE = JTRelocations.end(); MRI != MRE; ++MRI) {
MachineRelocation &MR = *MRI;
unsigned MBBOffset = getMachineBasicBlockAddress(MR.getBasicBlock());
MR.setResultPointer((void*)MBBOffset);
MR.setConstantVal(ES->SectionIdx);
JTSection.addRelocation(MR);
}
// Relocations // Relocations
// ----------- // -----------
@ -105,7 +117,7 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
MR.setResultPointer((void*)Addr); MR.setResultPointer((void*)Addr);
} else if (MR.isJumpTableIndex()) { } else if (MR.isJumpTableIndex()) {
Addr = getJumpTableEntryAddress(MR.getJumpTableIndex()); Addr = getJumpTableEntryAddress(MR.getJumpTableIndex());
MR.setConstantVal(JumpTableSectionIdx); MR.setConstantVal(JTSection.SectionIdx);
MR.setResultPointer((void*)Addr); MR.setResultPointer((void*)Addr);
} else { } else {
llvm_unreachable("Unhandled relocation type"); llvm_unreachable("Unhandled relocation type");
@ -114,6 +126,7 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
} }
// Clear per-function data structures. // Clear per-function data structures.
JTRelocations.clear();
Relocations.clear(); Relocations.clear();
CPLocations.clear(); CPLocations.clear();
CPSections.clear(); CPSections.clear();
@ -159,21 +172,15 @@ void ELFCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
"PIC codegen not yet handled for elf jump tables!"); "PIC codegen not yet handled for elf jump tables!");
const TargetELFWriterInfo *TEW = TM.getELFWriterInfo(); const TargetELFWriterInfo *TEW = TM.getELFWriterInfo();
unsigned EntrySize = MJTI->getEntrySize();
// Get the ELF Section to emit the jump table // Get the ELF Section to emit the jump table
ELFSection &JTSection = EW.getJumpTableSection(); ELFSection &JTSection = EW.getJumpTableSection();
JumpTableSectionIdx = JTSection.SectionIdx;
// Entries in the JT Section are relocated against the text section
ELFSection &TextSection = EW.getTextSection();
// For each JT, record its offset from the start of the section // For each JT, record its offset from the start of the section
for (unsigned i = 0, e = JT.size(); i != e; ++i) { for (unsigned i = 0, e = JT.size(); i != e; ++i) {
const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs; const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
DOUT << "JTSection.size(): " << JTSection.size() << "\n";
DOUT << "JTLocations.size: " << JTLocations.size() << "\n";
// Record JT 'i' offset in the JT section // Record JT 'i' offset in the JT section
JTLocations.push_back(JTSection.size()); JTLocations.push_back(JTSection.size());
@ -182,19 +189,14 @@ void ELFCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) { for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
unsigned MachineRelTy = TEW->getAbsoluteLabelMachineRelTy(); unsigned MachineRelTy = TEW->getAbsoluteLabelMachineRelTy();
MachineRelocation MR = MachineRelocation MR =
MachineRelocation::getBB(JTSection.size(), MachineRelocation::getBB(JTSection.size(), MachineRelTy, MBBs[mi]);
MachineRelTy,
MBBs[mi]);
// Offset of JT 'i' in JT section
MR.setResultPointer((void*)getMachineBasicBlockAddress(MBBs[mi]));
MR.setConstantVal(TextSection.SectionIdx);
// Add the relocation to the Jump Table section // Add the relocation to the Jump Table section
JTSection.addRelocation(MR); JTRelocations.push_back(MR);
// Output placeholder for MBB in the JT section // Output placeholder for MBB in the JT section
JTSection.emitWord(0); for (unsigned s=0; s < EntrySize; ++s)
JTSection.emitByte(0);
} }
} }
} }

View File

@ -31,14 +31,14 @@ namespace llvm {
/// Relocations - Record relocations needed by the current function /// Relocations - Record relocations needed by the current function
std::vector<MachineRelocation> Relocations; std::vector<MachineRelocation> Relocations;
/// JTRelocations - Record relocations needed by the relocation
/// section.
std::vector<MachineRelocation> JTRelocations;
/// FnStartPtr - Function offset from the beginning of ELFSection 'ES' /// FnStartPtr - Function offset from the beginning of ELFSection 'ES'
uintptr_t FnStartOff; uintptr_t FnStartOff;
/// JumpTableSectionIdx - Holds the index of the Jump Table Section
unsigned JumpTableSectionIdx;
public: public:
explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM) {}
JumpTableSectionIdx(0) {}
/// addRelocation - Register new relocations for this function /// addRelocation - Register new relocations for this function
void addRelocation(const MachineRelocation &MR) { void addRelocation(const MachineRelocation &MR) {