[llvm-commits] [llvm] r74760 - in /llvm/trunk/lib/CodeGen: ELFCodeEmitter.cpp ELFCodeEmitter.h ELFWriter.cpp ELFWriter.h
Bruno Cardoso Lopes
bruno.cardoso at gmail.com
Thu Jul 2 21:36:27 PDT 2009
Author: bruno
Date: Thu Jul 2 23:36:26 2009
New Revision: 74760
URL: http://llvm.org/viewvc/llvm-project?rev=74760&view=rev
Log:
Factor some code out and support for Jump Table relocations
Modified:
llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp
llvm/trunk/lib/CodeGen/ELFCodeEmitter.h
llvm/trunk/lib/CodeGen/ELFWriter.cpp
llvm/trunk/lib/CodeGen/ELFWriter.h
Modified: llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp?rev=74760&r1=74759&r2=74760&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp (original)
+++ llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp Thu Jul 2 23:36:26 2009
@@ -97,6 +97,9 @@
// Emit constant pool to appropriate section(s)
emitConstantPool(MF.getConstantPool());
+ // Emit jump tables to appropriate section
+ emitJumpTables(MF.getJumpTableInfo());
+
// Relocations
// -----------
// If we have emitted any relocations to function-specific objects such as
@@ -116,13 +119,22 @@
Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]);
MR.setResultPointer((void*)Addr);
+ } else if (MR.isJumpTableIndex()) {
+ Addr = getJumpTableEntryAddress(MR.getJumpTableIndex());
+ MR.setResultPointer((void*)Addr);
+ MR.setConstantVal(JumpTableSectionIdx);
} else {
assert(0 && "Unhandled relocation type");
}
ES->addRelocation(MR);
}
- Relocations.clear();
+ // Clear per-function data structures.
+ Relocations.clear();
+ CPLocations.clear();
+ CPSections.clear();
+ JTLocations.clear();
+ MBBLocations.clear();
return false;
}
@@ -158,4 +170,56 @@
}
}
+/// emitJumpTables - Emit all the jump tables for a given jump table info
+/// record to the appropriate section.
+void ELFCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
+ const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+ if (JT.empty()) return;
+
+ // FIXME: handle PIC codegen
+ assert(TM.getRelocationModel() != Reloc::PIC_ &&
+ "PIC codegen not yet handled for elf jump tables!");
+
+ const TargetAsmInfo *TAI = TM.getTargetAsmInfo();
+
+ // Get the ELF Section to emit the jump table
+ unsigned Align = TM.getTargetData()->getPointerABIAlignment();
+ std::string JTName(TAI->getJumpTableDataSection());
+ ELFSection &JTSection = EW.getJumpTableSection(JTName, Align);
+ 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 (unsigned i = 0, e = JT.size(); i != e; ++i) {
+ 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
+ JTLocations.push_back(JTSection.size());
+
+ // Each MBB entry in the Jump table section has a relocation entry
+ // against the current text section.
+ for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
+ MachineRelocation MR =
+ MachineRelocation::getBB(JTSection.size(),
+ MachineRelocation::VANILLA,
+ 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
+ JTSection.addRelocation(MR);
+
+ // Output placeholder for MBB in the JT section
+ JTSection.emitWord(0);
+ }
+ }
+}
+
} // end namespace llvm
Modified: llvm/trunk/lib/CodeGen/ELFCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFCodeEmitter.h?rev=74760&r1=74759&r2=74760&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ELFCodeEmitter.h (original)
+++ llvm/trunk/lib/CodeGen/ELFCodeEmitter.h Thu Jul 2 23:36:26 2009
@@ -40,6 +40,10 @@
/// containing the constant pool entry for that index.
std::vector<unsigned> CPSections;
+ /// JTLocations - This is a map of jump table indices to offsets from the
+ /// start of the section for that jump table index.
+ std::vector<uintptr_t> JTLocations;
+
/// MBBLocations - This vector is a mapping from MBB ID's to their address.
/// It is filled in by the StartMachineBasicBlock callback and queried by
/// the getMachineBasicBlockAddress callback.
@@ -48,8 +52,12 @@
/// FnStartPtr - Pointer to the start location of the current function
/// in the buffer
uint8_t *FnStartPtr;
+
+ /// JumpTableSectionIdx - Holds the index of the Jump Table Section
+ unsigned JumpTableSectionIdx;
public:
- explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM) {}
+ explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM),
+ JumpTableSectionIdx(0) {}
void startFunction(MachineFunction &F);
bool finishFunction(MachineFunction &F);
@@ -64,25 +72,20 @@
MBBLocations[MBB->getNumber()] = getCurrentPCOffset();
}
- virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) {
- assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
- MBBLocations[MBB->getNumber()] && "MBB not emitted!");
- return MBBLocations[MBB->getNumber()];
- }
-
virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
assert(CPLocations.size() > Index && "CP not emitted!");
return CPLocations[Index];
}
virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
- assert(0 && "JT not implementated yet!");
- return 0;
+ assert(JTLocations.size() > Index && "JT not emitted!");
+ return JTLocations[Index];
}
virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
- assert(0 && "JT not implementated yet!");
- return 0;
+ assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
+ MBBLocations[MBB->getNumber()] && "MBB not emitted!");
+ return MBBLocations[MBB->getNumber()];
}
virtual uintptr_t getLabelAddress(uint64_t Label) const {
@@ -100,7 +103,11 @@
/// the constant should live in and emit the constant.
void emitConstantPool(MachineConstantPool *MCP);
- virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
+ /// emitJumpTables - Emit all the jump tables for a given jump table info
+ /// record to the appropriate section.
+ void emitJumpTables(MachineJumpTableInfo *MJTI);
+
+ virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) {}
/// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
void startGVStub(const GlobalValue* F, unsigned StubSize,
Modified: llvm/trunk/lib/CodeGen/ELFWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFWriter.cpp?rev=74760&r1=74759&r2=74760&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ELFWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/ELFWriter.cpp Thu Jul 2 23:36:26 2009
@@ -166,43 +166,51 @@
return ELFSym::STB_GLOBAL;
}
+// getElfSectionFlags - Get the ELF Section Header based on the
+// flags defined in ELFTargetAsmInfo.
+unsigned ELFWriter::getElfSectionFlags(unsigned Flags) {
+ unsigned ElfSectionFlags = ELFSection::SHF_ALLOC;
+
+ if (Flags & SectionFlags::Code)
+ ElfSectionFlags |= ELFSection::SHF_EXECINSTR;
+ if (Flags & SectionFlags::Writeable)
+ ElfSectionFlags |= ELFSection::SHF_WRITE;
+ if (Flags & SectionFlags::Mergeable)
+ ElfSectionFlags |= ELFSection::SHF_MERGE;
+ if (Flags & SectionFlags::TLS)
+ ElfSectionFlags |= ELFSection::SHF_TLS;
+ if (Flags & SectionFlags::Strings)
+ ElfSectionFlags |= ELFSection::SHF_STRINGS;
+
+ return ElfSectionFlags;
+}
+
// For global symbols without a section, return the Null section as a
// placeholder
ELFSection &ELFWriter::getGlobalSymELFSection(const GlobalVariable *GV,
ELFSym &Sym) {
- const Section *S = TAI->SectionForGlobal(GV);
- unsigned Flags = S->getFlags();
- unsigned SectionType = ELFSection::SHT_PROGBITS;
- unsigned SHdrFlags = ELFSection::SHF_ALLOC;
- DOUT << "Section " << S->getName() << " for global " << GV->getName() << "\n";
-
- // If this is an external global, the symbol does not have a section.
+ // If this is a declaration, the symbol does not have a section.
if (!GV->hasInitializer()) {
Sym.SectionIdx = ELFSection::SHN_UNDEF;
return getNullSection();
}
+ // Get the name and flags of the section for the global
+ const Section *S = TAI->SectionForGlobal(GV);
+ unsigned SectionType = ELFSection::SHT_PROGBITS;
+ unsigned SectionFlags = getElfSectionFlags(S->getFlags());
+ DOUT << "Section " << S->getName() << " for global " << GV->getName() << "\n";
+
const TargetData *TD = TM.getTargetData();
unsigned Align = TD->getPreferredAlignment(GV);
Constant *CV = GV->getInitializer();
- if (Flags & SectionFlags::Code)
- SHdrFlags |= ELFSection::SHF_EXECINSTR;
- if (Flags & SectionFlags::Writeable)
- SHdrFlags |= ELFSection::SHF_WRITE;
- if (Flags & SectionFlags::Mergeable)
- SHdrFlags |= ELFSection::SHF_MERGE;
- if (Flags & SectionFlags::TLS)
- SHdrFlags |= ELFSection::SHF_TLS;
- if (Flags & SectionFlags::Strings)
- SHdrFlags |= ELFSection::SHF_STRINGS;
-
// If this global has a zero initializer, go to .bss or common section.
// Variables are part of the common block if they are zero initialized
// and allowed to be merged with other symbols.
if (CV->isNullValue() || isa<UndefValue>(CV)) {
SectionType = ELFSection::SHT_NOBITS;
- ELFSection &ElfS = getSection(S->getName(), SectionType, SHdrFlags);
+ ELFSection &ElfS = getSection(S->getName(), SectionType, SectionFlags);
if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
GV->hasCommonLinkage()) {
Sym.SectionIdx = ELFSection::SHN_COMMON;
@@ -218,7 +226,7 @@
}
Sym.IsConstant = true;
- ELFSection &ElfS = getSection(S->getName(), SectionType, SHdrFlags);
+ ELFSection &ElfS = getSection(S->getName(), SectionType, SectionFlags);
Sym.SectionIdx = ElfS.SectionIdx;
ElfS.Align = std::max(ElfS.Align, Align);
return ElfS;
Modified: llvm/trunk/lib/CodeGen/ELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFWriter.h?rev=74760&r1=74759&r2=74760&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ELFWriter.h (original)
+++ llvm/trunk/lib/CodeGen/ELFWriter.h Thu Jul 2 23:36:26 2009
@@ -118,19 +118,33 @@
/// is seen, the symbol will move from this list to the SymbolList.
SetVector<GlobalValue*> PendingGlobals;
+ // Remove tab from section name prefix. This is necessary becase TAI
+ // sometimes return a section name prefixed with a "\t" char. This is
+ // a little bit dirty. FIXME: find a better approach, maybe add more
+ // methods to TAI to get the clean name?
+ void fixNameForSection(std::string &Name) {
+ size_t Pos = Name.find("\t");
+ if (Pos != std::string::npos)
+ Name.erase(Pos, 1);
+
+ Pos = Name.find(".section ");
+ if (Pos != std::string::npos)
+ Name.erase(Pos, 9);
+
+ Pos = Name.find("\n");
+ if (Pos != std::string::npos)
+ Name.erase(Pos, 1);
+ }
+
/// getSection - Return the section with the specified name, creating a new
/// section if one does not already exist.
ELFSection &getSection(const std::string &Name, unsigned Type,
unsigned Flags = 0, unsigned Align = 0) {
- ELFSection *&SN = SectionLookup[Name];
- if (SN) return *SN;
-
- // Remove tab from section name prefix. This is necessary becase TAI
- // sometimes return a section name prefixed with a "\t" char.
std::string SectionName(Name);
- size_t Pos = SectionName.find("\t");
- if (Pos != std::string::npos)
- SectionName.erase(Pos, 1);
+ fixNameForSection(SectionName);
+
+ ELFSection *&SN = SectionLookup[SectionName];
+ if (SN) return *SN;
SectionList.push_back(ELFSection(SectionName, isLittleEndian, is64Bit));
SN = &SectionList.back();
@@ -149,6 +163,12 @@
ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC);
}
+ /// Get jump table section on the section name returned by TAI
+ ELFSection &getJumpTableSection(std::string SName, unsigned Align) {
+ return getSection(SName, ELFSection::SHT_PROGBITS,
+ ELFSection::SHF_ALLOC, Align);
+ }
+
/// Get a constant pool section based on the section name returned by TAI
ELFSection &getConstantPoolSection(std::string SName, unsigned Align) {
return getSection(SName, ELFSection::SHT_PROGBITS,
@@ -197,9 +217,10 @@
return getSection("", ELFSection::SHT_NULL, 0);
}
- // Helpers for obtaining ELF specific Linkage and Visibility info.
+ // Helpers for obtaining ELF specific info.
unsigned getGlobalELFLinkage(const GlobalValue *GV);
unsigned getGlobalELFVisibility(const GlobalValue *GV);
+ unsigned getElfSectionFlags(unsigned Flags);
// As we complete the ELF file, we need to update fields in the ELF header
// (e.g. the location of the section table). These members keep track of
More information about the llvm-commits
mailing list