summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/ELFWriter.cpp
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2009-07-20 08:52:02 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2009-07-20 08:52:02 +0000
commit447b7fd4bbc5d081ff7e1e606f8a4e7db152086b (patch)
tree9842e6670c2d4dac9691322d82b234eb3eca95f8 /llvm/lib/CodeGen/ELFWriter.cpp
parent34e0370502db426c9e48f2250073009f38ee3e35 (diff)
downloadbcm5719-llvm-447b7fd4bbc5d081ff7e1e606f8a4e7db152086b.tar.gz
bcm5719-llvm-447b7fd4bbc5d081ff7e1e606f8a4e7db152086b.zip
For PC relative relocations where symbols are defined in the same section they
are referenced, ignore the relocation entry and patch the relocatable field with the computed symbol offset directly llvm-svn: 76414
Diffstat (limited to 'llvm/lib/CodeGen/ELFWriter.cpp')
-rw-r--r--llvm/lib/CodeGen/ELFWriter.cpp80
1 files changed, 53 insertions, 27 deletions
diff --git a/llvm/lib/CodeGen/ELFWriter.cpp b/llvm/lib/CodeGen/ELFWriter.cpp
index 527adb821e7..f04efd5c8c7 100644
--- a/llvm/lib/CodeGen/ELFWriter.cpp
+++ b/llvm/lib/CodeGen/ELFWriter.cpp
@@ -145,7 +145,7 @@ bool ELFWriter::doInitialization(Module &M) {
return false;
}
-/// Get jump table section on the section name returned by TAI
+// Get jump table section on the section name returned by TAI
ELFSection &ELFWriter::getJumpTableSection() {
unsigned Align = TM.getTargetData()->getPointerABIAlignment();
return getSection(TAI->getJumpTableDataSection(),
@@ -153,7 +153,7 @@ ELFSection &ELFWriter::getJumpTableSection() {
ELFSection::SHF_ALLOC, Align);
}
-/// Get a constant pool section based on the section name returned by TAI
+// Get a constant pool section based on the section name returned by TAI
ELFSection &ELFWriter::getConstantPoolSection(MachineConstantPoolEntry &CPE) {
std::string CstPoolName =
TAI->SelectSectionForMachineConst(CPE.getType())->getName();
@@ -163,6 +163,19 @@ ELFSection &ELFWriter::getConstantPoolSection(MachineConstantPoolEntry &CPE) {
CPE.getAlignment());
}
+// Return the relocation section of section 'S'. 'RelA' is true
+// if the relocation section contains entries with addends.
+ELFSection &ELFWriter::getRelocSection(ELFSection &S) {
+ unsigned SectionHeaderTy = TEW->hasRelocationAddend() ?
+ ELFSection::SHT_RELA : ELFSection::SHT_REL;
+ std::string RelSName(".rel");
+ if (TEW->hasRelocationAddend())
+ RelSName.append("a");
+ RelSName.append(S.getName());
+
+ return getSection(RelSName, SectionHeaderTy, 0, TEW->getPrefELFAlignment());
+}
+
// getGlobalELFVisibility - Returns the ELF specific visibility type
unsigned ELFWriter::getGlobalELFVisibility(const GlobalValue *GV) {
switch (GV->getVisibility()) {
@@ -474,20 +487,32 @@ bool ELFWriter::doFinalization(Module &M) {
return false;
}
+// RelocateField - Patch relocatable field with 'Offset' in 'BO'
+// using a 'Value' of known 'Size'
+void ELFWriter::RelocateField(BinaryObject &BO, uint32_t Offset,
+ int64_t Value, unsigned Size) {
+ if (Size == 32)
+ BO.fixWord32(Value, Offset);
+ else if (Size == 64)
+ BO.fixWord64(Value, Offset);
+ else
+ llvm_unreachable("don't know howto patch relocatable field");
+}
+
/// EmitRelocations - Emit relocations
void ELFWriter::EmitRelocations() {
+ // True if the target uses the relocation entry to hold the addend,
+ // otherwise the addend is written directly to the relocatable field.
+ bool HasRelA = TEW->hasRelocationAddend();
+
// Create Relocation sections for each section which needs it.
for (unsigned i=0, e=SectionList.size(); i != e; ++i) {
ELFSection &S = *SectionList[i];
// This section does not have relocations
if (!S.hasRelocations()) continue;
-
- // Get the relocation section for section 'S'
- bool HasRelA = TEW->hasRelocationAddend();
- ELFSection &RelSec = getRelocSection(S.getName(), HasRelA,
- TEW->getPrefELFAlignment());
+ ELFSection &RelSec = getRelocSection(S);
// 'Link' - Section hdr idx of the associated symbol table
// 'Info' - Section hdr idx of the section to which the relocation applies
@@ -502,18 +527,15 @@ void ELFWriter::EmitRelocations() {
MRE = Relos.end(); MRI != MRE; ++MRI) {
MachineRelocation &MR = *MRI;
- // Holds the relocatable field address as an offset from the
- // beginning of the section where it lives
- unsigned Offset = MR.getMachineCodeOffset();
+ // Relocatable field offset from the section start
+ unsigned RelOffset = MR.getMachineCodeOffset();
// Symbol index in the symbol table
unsigned SymIdx = 0;
- // Target specific ELF relocation type
+ // Target specific relocation field type and size
unsigned RelType = TEW->getRelocationType(MR.getRelocationType());
-
- // Constant addend used to compute the value to be stored
- // into the relocatable field
+ unsigned RelTySize = TEW->getRelocationTySize(RelType);
int64_t Addend = 0;
// There are several machine relocations types, and each one of
@@ -533,29 +555,33 @@ void ELFWriter::EmitRelocations() {
} else {
// Get the symbol index for the section symbol
unsigned SectionIdx = MR.getConstantVal();
+ SymIdx = SectionList[SectionIdx]->getSymbolTableIndex();
+ Addend = (uint64_t)MR.getResultPointer();
+
+ // For pc relative relocations where symbols are defined in the same
+ // section they are referenced, ignore the relocation entry and patch
+ // the relocatable field with the symbol offset directly.
+ if (S.SectionIdx == SectionIdx && TEW->isPCRelativeRel(RelType)) {
+ int64_t Value = TEW->computeRelocation(Addend, RelOffset, RelType);
+ RelocateField(S, RelOffset, Value, RelTySize);
+ continue;
+ }
// Handle Jump Table Index relocation
if ((SectionIdx == getJumpTableSection().SectionIdx) &&
- TEW->hasCustomJumpTableIndexRelTy())
+ TEW->hasCustomJumpTableIndexRelTy()) {
RelType = TEW->getJumpTableIndexRelTy();
-
- SymIdx = SectionList[SectionIdx]->getSymbolTableIndex();
- Addend = (uint64_t)MR.getResultPointer();
+ RelTySize = TEW->getRelocationTySize(RelType);
+ }
}
// 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");
- }
+ if (!HasRelA)
+ RelocateField(S, RelOffset, Addend, RelTySize);
// Get the relocation entry and emit to the relocation section
- ELFRelocation Rel(Offset, SymIdx, RelType, HasRelA, Addend);
+ ELFRelocation Rel(RelOffset, SymIdx, RelType, HasRelA, Addend);
EmitRelocation(RelSec, Rel, HasRelA);
}
}
OpenPOWER on IntegriCloud