diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-11-21 00:48:25 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-11-21 00:48:25 +0000 |
commit | 26cb15a5496acc2163d0169c74061cc55e9d143f (patch) | |
tree | 3cbb1e8f4686dec8ef1828e94ab5a7727f5a03dc /llvm | |
parent | 58f9f5871657b1b050ea8360fc93148ee2fe53b8 (diff) | |
download | bcm5719-llvm-26cb15a5496acc2163d0169c74061cc55e9d143f.tar.gz bcm5719-llvm-26cb15a5496acc2163d0169c74061cc55e9d143f.zip |
Handle PCRel relocations with absolute values. Fixes PR8656.
llvm-svn: 119917
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 32 | ||||
-rw-r--r-- | llvm/test/MC/ELF/relocation-386.s | 7 |
2 files changed, 30 insertions, 9 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 4e09b4df195..4ea6308f45c 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -948,10 +948,12 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { ELFRelocationEntry entry = Relocs[e - i - 1]; - if (entry.Index < 0) + if (!entry.Index) + ; + else if (entry.Index < 0) entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); else - entry.Index += LocalSymbolData.size() + 1; + entry.Index += LocalSymbolData.size(); if (Is64Bit) { String64(*F, entry.r_offset); @@ -1085,13 +1087,22 @@ bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, } const MCSection *SectionB = 0; + const MCSymbol *SymbolB = 0; if (const MCSymbolRefExpr *B = Target.getSymB()) { - SectionB = &B->getSymbol().AliasedSymbol().getSection(); + SymbolB = &B->getSymbol(); + SectionB = &SymbolB->AliasedSymbol().getSection(); } if (!BaseSection) return SectionA == SectionB; + if (SymbolB) + return false; + + // Absolute address but PCrel instruction, so we need a relocation. + if (!SymbolA) + return false; + // FIXME: This is in here just to match gnu as output. If the two ends // are in the same section, there is nothing that the linker can do to // break it. @@ -1099,7 +1110,7 @@ bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, if (DataA.isExternal()) return false; - return !SectionB && BaseSection == SectionA; + return BaseSection == SectionA; } void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm, @@ -1391,12 +1402,14 @@ void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, int64_t Addend = 0; int Index = 0; int64_t Value = Target.getConstant(); - const MCSymbol &Symbol = Target.getSymA()->getSymbol(); - const MCSymbol &ASymbol = Symbol.AliasedSymbol(); - const MCSymbol *RelocSymbol = SymbolToReloc(Asm, Target, *Fragment); + const MCSymbol *RelocSymbol = NULL; bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind()); if (!Target.isAbsolute()) { + const MCSymbol &Symbol = Target.getSymA()->getSymbol(); + const MCSymbol &ASymbol = Symbol.AliasedSymbol(); + RelocSymbol = SymbolToReloc(Asm, Target, *Fragment); + if (const MCSymbolRefExpr *RefB = Target.getSymB()) { const MCSymbol &SymbolB = RefB->getSymbol(); MCSymbolData &SDB = Asm.getSymbolData(SymbolB); @@ -1415,7 +1428,7 @@ void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, MCSymbolData &SD = Asm.getSymbolData(ASymbol); MCFragment *F = SD.getFragment(); - Index = F->getParent()->getOrdinal(); + Index = F->getParent()->getOrdinal() + 1; MCSectionData *FSD = F->getParent(); // Offset of the symbol in the section @@ -1437,7 +1450,8 @@ void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, // determine the type of the relocation - MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind(); + MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? + MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); unsigned Type; if (Is64Bit) { if (IsPCRel) { diff --git a/llvm/test/MC/ELF/relocation-386.s b/llvm/test/MC/ELF/relocation-386.s index c3903236187..48cdc353e30 100644 --- a/llvm/test/MC/ELF/relocation-386.s +++ b/llvm/test/MC/ELF/relocation-386.s @@ -98,6 +98,12 @@ // CHECK-NEXT: ('r_sym', 0x0000000b) // CHECK-NEXT: ('r_type', 0x00000020) // CHECK-NEXT: ), +// Relocation 12 (calll 4096) is of type R_386_PC32 +// CHECK-NEXT: # Relocation 0x0000000c +// CHECK-NEXT: (('r_offset', 0x00000048) +// CHECK-NEXT: ('r_sym', 0x00000000) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ), .text bar: @@ -122,6 +128,7 @@ bar2: addl foo@GOTNTPOFF(%ebx), %ecx leal foo@TLSLDM(%ebx), %eax leal foo@DTPOFF(%eax), %edx + calll 4096 .section .rodata.str1.16,"aMS",@progbits,1 .Lfoo: |