summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/WinCOFFObjectWriter.cpp
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2010-10-07 23:55:40 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2010-10-07 23:55:40 +0000
commitaaf4643a31f776d3285f2069d53e9be30391712e (patch)
tree3a2b02462bbf089092a8171578aa7cba396b86c3 /llvm/lib/MC/WinCOFFObjectWriter.cpp
parent5947e1626aa2e1c1255c4d09fe63b077e08316b6 (diff)
downloadbcm5719-llvm-aaf4643a31f776d3285f2069d53e9be30391712e.tar.gz
bcm5719-llvm-aaf4643a31f776d3285f2069d53e9be30391712e.zip
MC-COFF: Handle relaxation in COFF better. Fixes PR8321.
llvm-svn: 116013
Diffstat (limited to 'llvm/lib/MC/WinCOFFObjectWriter.cpp')
-rw-r--r--llvm/lib/MC/WinCOFFObjectWriter.cpp30
1 files changed, 29 insertions, 1 deletions
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index 5ebdb714a26..7bb19b2481c 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -639,6 +639,11 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
COFFSymbol *coff_symbol = SymbolMap[&A_SD];
if (Target.getSymB()) {
+ if (&Target.getSymA()->getSymbol().getSection()
+ != &Target.getSymB()->getSymbol().getSection()) {
+ llvm_unreachable("Symbol relative relocations are only allowed between "
+ "symbols in the same section");
+ }
const MCSymbol *B = &Target.getSymB()->getSymbol();
MCSymbolData &B_SD = Asm.getSymbolData(*B);
@@ -701,7 +706,30 @@ bool WinCOFFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
const MCValue Target,
bool IsPCRel,
const MCFragment *DF) const {
- return false;
+ // If this is a PCrel relocation, find the section this fixup value is
+ // relative to.
+ const MCSection *BaseSection = 0;
+ if (IsPCRel) {
+ BaseSection = &DF->getParent()->getSection();
+ assert(BaseSection);
+ }
+
+ const MCSection *SectionA = 0;
+ const MCSymbol *SymbolA = 0;
+ if (const MCSymbolRefExpr *A = Target.getSymA()) {
+ SymbolA = &A->getSymbol();
+ SectionA = &SymbolA->getSection();
+ }
+
+ const MCSection *SectionB = 0;
+ if (const MCSymbolRefExpr *B = Target.getSymB()) {
+ SectionB = &B->getSymbol().getSection();
+ }
+
+ if (!BaseSection)
+ return SectionA == SectionB;
+
+ return !SectionB && BaseSection == SectionA;
}
void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
OpenPOWER on IntegriCloud