aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2009-06-25 07:36:24 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2009-06-25 07:36:24 +0000
commita5e0abd0d454ffdb22f8647f4319b178901b08be (patch)
tree5a6eb50876c8ca647efe9e5141c7b237262adb76 /lib
parentc9028e69f11246a051c3de1457cd89d46e82ca60 (diff)
Support Constant Pool Sections
Add section symbols to the symbol table git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74170 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/ELF.h10
-rw-r--r--lib/CodeGen/ELFCodeEmitter.cpp48
-rw-r--r--lib/CodeGen/ELFCodeEmitter.h17
-rw-r--r--lib/CodeGen/ELFWriter.cpp41
-rw-r--r--lib/CodeGen/ELFWriter.h6
5 files changed, 111 insertions, 11 deletions
diff --git a/lib/CodeGen/ELF.h b/lib/CodeGen/ELF.h
index 28b6be8910..8d92373b71 100644
--- a/lib/CodeGen/ELF.h
+++ b/lib/CodeGen/ELF.h
@@ -144,6 +144,9 @@ namespace llvm {
uint8_t Other;
unsigned short SectionIdx;
+ // Symbol index into the Symbol table
+ unsigned SymTabIdx;
+
enum {
STB_LOCAL = 0,
STB_GLOBAL = 1,
@@ -168,7 +171,8 @@ namespace llvm {
ELFSym(const GlobalValue *gv) : GV(gv), IsCommon(false), IsBss(false),
IsConstant(false), NameIdx(0), Value(0),
Size(0), Info(0), Other(STV_DEFAULT),
- SectionIdx(ELFSection::SHN_UNDEF) {
+ SectionIdx(ELFSection::SHN_UNDEF),
+ SymTabIdx(0) {
if (!GV)
return;
@@ -191,6 +195,10 @@ namespace llvm {
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);
diff --git a/lib/CodeGen/ELFCodeEmitter.cpp b/lib/CodeGen/ELFCodeEmitter.cpp
index 8cb7c94c5d..168fed56c1 100644
--- a/lib/CodeGen/ELFCodeEmitter.cpp
+++ b/lib/CodeGen/ELFCodeEmitter.cpp
@@ -16,6 +16,7 @@
#include "llvm/CodeGen/BinaryObject.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
@@ -103,21 +104,28 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
break;
}
+ // Emit constant pool to appropriate section(s)
+ emitConstantPool(MF.getConstantPool());
+
// Relocations
// -----------
- // If we have emitted any relocations to function-specific objects such as
+ // If we have emitted any relocations to function-specific objects such as
// basic blocks, constant pools entries, or jump tables, record their
// addresses now so that we can rewrite them with the correct addresses
// later.
for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
MachineRelocation &MR = Relocations[i];
intptr_t Addr;
- if (MR.isBasicBlock()) {
+ if (MR.isGlobalValue()) {
+ EW.PendingGlobals.insert(MR.getGlobalValue());
+ } else if (MR.isBasicBlock()) {
Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
MR.setConstantVal(ES->SectionIdx);
MR.setResultPointer((void*)Addr);
- } else if (MR.isGlobalValue()) {
- EW.PendingGlobals.insert(MR.getGlobalValue());
+ } else if (MR.isConstantPoolIndex()) {
+ Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
+ MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]);
+ MR.setResultPointer((void*)Addr);
} else {
assert(0 && "Unhandled relocation type");
}
@@ -128,4 +136,36 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
return false;
}
+/// emitConstantPool - For each constant pool entry, figure out which section
+/// the constant should live in and emit the constant
+void ELFCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
+ const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
+ if (CP.empty()) return;
+
+ // TODO: handle PIC codegen
+ assert(TM.getRelocationModel() != Reloc::PIC_ &&
+ "PIC codegen not yet handled for elf constant pools!");
+
+ const TargetAsmInfo *TAI = TM.getTargetAsmInfo();
+ for (unsigned i = 0, e = CP.size(); i != e; ++i) {
+ MachineConstantPoolEntry CPE = CP[i];
+
+ // Get the right ELF Section for this constant pool entry
+ std::string CstPoolName =
+ TAI->SelectSectionForMachineConst(CPE.getType())->getName();
+ ELFSection &CstPoolSection =
+ EW.getConstantPoolSection(CstPoolName, CPE.getAlignment());
+
+ // Record the constant pool location and the section index
+ CPLocations.push_back(CstPoolSection.size());
+ CPSections.push_back(CstPoolSection.SectionIdx);
+
+ if (CPE.isMachineConstantPoolEntry())
+ assert("CPE.isMachineConstantPoolEntry not supported yet");
+
+ // Emit the constant to constant pool section
+ EW.EmitGlobalConstant(CPE.Val.ConstVal, CstPoolSection);
+ }
+}
+
} // end namespace llvm
diff --git a/lib/CodeGen/ELFCodeEmitter.h b/lib/CodeGen/ELFCodeEmitter.h
index c0289daf3e..c309ef7597 100644
--- a/lib/CodeGen/ELFCodeEmitter.h
+++ b/lib/CodeGen/ELFCodeEmitter.h
@@ -31,6 +31,14 @@ namespace llvm {
/// emitted.
std::vector<MachineRelocation> Relocations;
+ /// CPLocations - This is a map of constant pool indices to offsets from the
+ /// start of the section for that constant pool index.
+ std::vector<uintptr_t> CPLocations;
+
+ /// CPSections - This is a map of constant pool indices to the MachOSection
+ /// containing the constant pool entry for that index.
+ std::vector<unsigned> CPSections;
+
/// 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.
@@ -62,9 +70,10 @@ namespace llvm {
}
virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
- assert(0 && "CP not implementated yet!");
- return 0;
+ 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;
@@ -86,6 +95,10 @@ namespace llvm {
abort();
}
+ /// emitConstantPool - For each constant pool entry, figure out which section
+ /// the constant should live in and emit the constant.
+ void emitConstantPool(MachineConstantPool *MCP);
+
virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
/// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index 03db65699a..041defa523 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -389,6 +389,24 @@ bool ELFWriter::doFinalization(Module &M) {
if (TAI->getNonexecutableStackDirective())
getNonExecStackSection();
+ // Emit a symbol for each section created until now
+ for (std::map<std::string, ELFSection*>::iterator I = SectionLookup.begin(),
+ E = SectionLookup.end(); I != E; ++I) {
+ ELFSection *ES = I->second;
+
+ // Skip null section
+ if (ES->SectionIdx == 0) continue;
+
+ ELFSym SectionSym(0);
+ SectionSym.SectionIdx = ES->SectionIdx;
+ SectionSym.Size = 0;
+ SectionSym.setBind(ELFSym::STB_LOCAL);
+ SectionSym.setType(ELFSym::STT_SECTION);
+
+ // Local symbols go in the list front
+ SymbolList.push_front(SectionSym);
+ }
+
// Emit string table
EmitStringTable();
@@ -451,15 +469,25 @@ void ELFWriter::EmitRelocations() {
// Constant addend used to compute the value to be stored
// into the relocatable field
- int64_t Addend = TEW->getAddendForRelTy(RelType);
+ int64_t Addend = 0;
// There are several machine relocations types, and each one of
// them needs a different approach to retrieve the symbol table index.
if (MR.isGlobalValue()) {
const GlobalValue *G = MR.getGlobalValue();
SymIdx = GblSymLookup[G];
+ Addend = TEW->getAddendForRelTy(RelType);
} else {
- assert(0 && "dunno how to handle other relocation types");
+ unsigned SectionIdx = MR.getConstantVal();
+ // TODO: use a map for this.
+ 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();
}
// Get the relocation entry and emit to the relocation section
@@ -540,7 +568,8 @@ void ELFWriter::EmitStringTable() {
E = SymbolList.end(); I != E; ++I) {
// Use the name mangler to uniquify the LLVM symbol.
- std::string Name = Mang->getValueName(I->GV);
+ std::string Name;
+ if (I->GV) Name.append(Mang->getValueName(I->GV));
if (Name.empty()) {
I->NameIdx = 0;
@@ -589,7 +618,11 @@ void ELFWriter::EmitSymbolTable() {
EmitSymbol(SymTab, *I);
// Record the symbol table index for each global value
- GblSymLookup[I->GV] = Index;
+ if (I->GV)
+ GblSymLookup[I->GV] = Index;
+
+ // Keep track on the symbol index into the symbol table
+ I->SymTabIdx = Index;
}
SymTab.Info = FirstNonLocalSymbol;
diff --git a/lib/CodeGen/ELFWriter.h b/lib/CodeGen/ELFWriter.h
index 39577d9a97..e0e71d01fa 100644
--- a/lib/CodeGen/ELFWriter.h
+++ b/lib/CodeGen/ELFWriter.h
@@ -147,6 +147,12 @@ namespace llvm {
ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC);
}
+ /// 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,
+ ELFSection::SHF_MERGE | ELFSection::SHF_ALLOC, Align);
+ }
+
/// Return the relocation section of section 'S'. 'RelA' is true
/// if the relocation section contains entries with addends.
ELFSection &getRelocSection(std::string SName, bool RelA) {