diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2009-07-18 19:30:09 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2009-07-18 19:30:09 +0000 |
commit | 171375f73a733edcd7a5f839491cc8da4fdeddfe (patch) | |
tree | 4443b1ad020ebce746c558e8da7477ea90337b27 /lib/CodeGen | |
parent | 76e7ba893fecd35422719acad5ab19af09bf4139 (diff) |
Add support to properly reference private symbols on relocation entries.
Use proper relocation type to build relocations for JumpTables (rodata
sections).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76326 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/ELF.h | 7 | ||||
-rw-r--r-- | lib/CodeGen/ELFCodeEmitter.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/ELFWriter.cpp | 40 | ||||
-rw-r--r-- | lib/CodeGen/ELFWriter.h | 8 |
4 files changed, 49 insertions, 11 deletions
diff --git a/lib/CodeGen/ELF.h b/lib/CodeGen/ELF.h index 8bbb29c7bc..d4dc151494 100644 --- a/lib/CodeGen/ELF.h +++ b/lib/CodeGen/ELF.h @@ -184,6 +184,13 @@ namespace llvm { /// Sym - The symbol to represent this section if it has one. ELFSym *Sym; + /// getSymIndex - Returns the symbol table index of the symbol + /// representing this section. + unsigned getSymbolTableIndex() const { + assert(Sym && "section not present in the symbol table"); + return Sym->SymTabIdx; + } + ELFSection(const std::string &name, bool isLittleEndian, bool is64Bit) : BinaryObject(name, isLittleEndian, is64Bit), Type(0), Flags(0), Addr(0), Offset(0), Size(0), Link(0), Info(0), Align(0), EntSize(0), Sym(0) {} diff --git a/lib/CodeGen/ELFCodeEmitter.cpp b/lib/CodeGen/ELFCodeEmitter.cpp index 1d150032c3..6e6ba8ec6a 100644 --- a/lib/CodeGen/ELFCodeEmitter.cpp +++ b/lib/CodeGen/ELFCodeEmitter.cpp @@ -20,6 +20,7 @@ #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineRelocation.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetELFWriterInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Support/Debug.h" @@ -160,6 +161,7 @@ void ELFCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) { "PIC codegen not yet handled for elf jump tables!"); const TargetAsmInfo *TAI = TM.getTargetAsmInfo(); + const TargetELFWriterInfo *TEW = TM.getELFWriterInfo(); // Get the ELF Section to emit the jump table unsigned Align = TM.getTargetData()->getPointerABIAlignment(); @@ -183,9 +185,10 @@ void ELFCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) { // 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) { + unsigned MachineRelTy = TEW->getJumpTableMachineRelocationTy(); MachineRelocation MR = MachineRelocation::getBB(JTSection.size(), - MachineRelocation::VANILLA, + MachineRelTy, MBBs[mi]); // Offset of JT 'i' in JT section diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index 3e1645b2c3..69220f9aea 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/lib/CodeGen/ELFWriter.cpp @@ -296,8 +296,16 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) { } } - if (!GV->hasPrivateLinkage()) + // Private symbols must never go to the symbol table. + unsigned SymIdx = 0; + if (GV->hasPrivateLinkage()) { + PrivateSyms.push_back(GblSym); + SymIdx = PrivateSyms.size()-1; + } else { SymbolList.push_back(GblSym); + } + + GblSymLookup[GV] = SymIdx; } void ELFWriter::EmitGlobalConstantStruct(const ConstantStruct *CVS, @@ -394,20 +402,16 @@ bool ELFWriter::doFinalization(Module &M) { for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { EmitGlobal(I); - GblSymLookup[I] = 0; } // Emit all pending globals // TODO: this should be done only for referenced symbols for (SetVector<GlobalValue*>::const_iterator I = PendingGlobals.begin(), E = PendingGlobals.end(); I != E; ++I) { - // No need to emit the symbol again if (GblSymLookup.find(*I) != GblSymLookup.end()) continue; - EmitGlobal(*I); - GblSymLookup[*I] = 0; } // Emit non-executable stack note @@ -480,7 +484,8 @@ void ELFWriter::EmitRelocations() { MRE = Relos.end(); MRI != MRE; ++MRI) { MachineRelocation &MR = *MRI; - // Offset from the start of the section containing the symbol + // Holds the relocatable field address as an offset from the + // beginning of the section where it lives unsigned Offset = MR.getMachineCodeOffset(); // Symbol index in the symbol table @@ -498,15 +503,34 @@ void ELFWriter::EmitRelocations() { if (MR.isGlobalValue()) { const GlobalValue *G = MR.getGlobalValue(); SymIdx = GblSymLookup[G]; - Addend = TEW->getAddendForRelTy(RelType); + if (G->hasPrivateLinkage()) { + // If the target uses a section offset in the relocation: + // SymIdx + Addend = section sym for global + section offset + unsigned SectionIdx = PrivateSyms[SymIdx]->SectionIdx; + Addend = PrivateSyms[SymIdx]->Value; + SymIdx = SectionList[SectionIdx]->getSymbolTableIndex(); + } else { + Addend = TEW->getDefaultAddendForRelTy(RelType); + } } else { // Get the symbol index for the section symbol referenced // by the relocation unsigned SectionIdx = MR.getConstantVal(); - SymIdx = SectionList[SectionIdx]->Sym->SymTabIdx; + SymIdx = SectionList[SectionIdx]->getSymbolTableIndex(); Addend = (uint64_t)MR.getResultPointer(); } + // The target without addend on the relocation symbol must be + // patched in the relocation place itself to contain the addend + if (!HasRelA) { + if (TEW->getRelocationTySize(RelType) == 32) + S.fixWord32(Addend, Offset); + else if (TEW->getRelocationTySize(RelType) == 64) + S.fixWord64(Addend, Offset); + else + llvm_unreachable("don't know howto patch relocatable field"); + } + // Get the relocation entry and emit to the relocation section ELFRelocation Rel(Offset, SymIdx, RelType, HasRelA, Addend); EmitRelocation(RelSec, Rel, HasRelA); diff --git a/lib/CodeGen/ELFWriter.h b/lib/CodeGen/ELFWriter.h index ee5a856ac2..89ab00c397 100644 --- a/lib/CodeGen/ELFWriter.h +++ b/lib/CodeGen/ELFWriter.h @@ -107,8 +107,8 @@ namespace llvm { std::map<std::string, ELFSection*> SectionLookup; /// GblSymLookup - This is a mapping from global value to a symbol index - /// in the symbol table. This is useful since relocations symbol references - /// must be quickly mapped to a symbol table index + /// in the symbol table or private symbols list. This is useful since reloc + /// symbol references must be quickly mapped to their indices on the lists std::map<const GlobalValue*, uint32_t> GblSymLookup; /// SymbolList - This is the list of symbols emitted to the symbol table. @@ -116,6 +116,10 @@ namespace llvm { /// the beginning while non-locals at the end. std::vector<ELFSym*> SymbolList; + /// PrivateSyms - Record private symbols, every symbol here must never be + /// present in the SymbolList. + std::vector<ELFSym*> PrivateSyms; + /// PendingGlobals - List of externally defined symbols that we have been /// 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. |