From 9c0a05c7af7f85ef931109e9e4a171cd9eec0a0f Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Wed, 8 Jan 2014 10:22:54 +0000 Subject: [PATCH] [patch] Adjust behavior of FDE cross-section relocs for targets that don't support abs-differences. Modern versions of OSX/Darwin's ld (ld64 > 97.17) have an optimisation present that allows the back end to omit relocations (and replace them with an absolute difference) for FDE some text section refs. This patch allows a backend to opt-in to this behaviour by setting "DwarfFDESymbolsUseAbsDiff". At present, this is only enabled for modern x86 OSX ports. test changes by David Fang. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198744 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCAsmInfo.h | 7 +++ lib/MC/MCAsmInfo.cpp | 1 + lib/MC/MCDwarf.cpp | 16 ++++--- lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp | 5 ++ test/CodeGen/X86/pr10420.ll | 48 +++++++++++++++++++- 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index a46c300bf26..0d1052be6d8 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -292,6 +292,10 @@ namespace llvm { /// uses relocations for references to other .debug_* sections. bool DwarfUsesRelocationsAcrossSections; + /// DwarfFDESymbolsUseAbsDiff - true if DWARF FDE symbol reference + /// relocations should be replaced by an absolute difference. + bool DwarfFDESymbolsUseAbsDiff; + /// DwarfRegNumForCFI - True if dwarf register numbers are printed /// instead of symbolic register names in .cfi_* directives. bool DwarfRegNumForCFI; // Defaults to false; @@ -513,6 +517,9 @@ namespace llvm { bool doesDwarfUseRelocationsAcrossSections() const { return DwarfUsesRelocationsAcrossSections; } + bool doDwarfFDESymbolsUseAbsDiff() const { + return DwarfFDESymbolsUseAbsDiff; + } bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; } diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index 466a94d8e87..2c19e8511b3 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -84,6 +84,7 @@ MCAsmInfo::MCAsmInfo() { SupportsDebugInformation = false; ExceptionsType = ExceptionHandling::None; DwarfUsesRelocationsAcrossSections = true; + DwarfFDESymbolsUseAbsDiff = false; DwarfRegNumForCFI = false; NeedsDwarfSectionOffsetDirective = false; UseParensForSymbolVariant = false; diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 479f4452d4a..12070f36ea6 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -839,8 +839,9 @@ static unsigned getSizeForEncoding(MCStreamer &streamer, } } -static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol, - unsigned symbolEncoding, const char *comment = 0) { +static void EmitFDESymbol(MCStreamer &streamer, const MCSymbol &symbol, + unsigned symbolEncoding, bool isEH, + const char *comment = 0) { MCContext &context = streamer.getContext(); const MCAsmInfo *asmInfo = context.getAsmInfo(); const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol, @@ -848,7 +849,10 @@ static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol, streamer); unsigned size = getSizeForEncoding(streamer, symbolEncoding); if (streamer.isVerboseAsm() && comment) streamer.AddComment(comment); - streamer.EmitAbsValue(v, size); + if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH) + streamer.EmitAbsValue(v, size); + else + streamer.EmitValue(v, size); } static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, @@ -1347,7 +1351,7 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, unsigned PCEncoding = IsEH ? MOFI->getFDEEncoding(UsingCFI) : (unsigned)dwarf::DW_EH_PE_absptr; unsigned PCSize = getSizeForEncoding(streamer, PCEncoding); - EmitSymbol(streamer, *frame.Begin, PCEncoding, "FDE initial location"); + EmitFDESymbol(streamer, *frame.Begin, PCEncoding, IsEH, "FDE initial location"); // PC Range const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin, @@ -1367,8 +1371,8 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, // Augmentation Data if (frame.Lsda) - EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding, - "Language Specific Data Area"); + EmitFDESymbol(streamer, *frame.Lsda, frame.LsdaEncoding, true, + "Language Specific Data Area"); } // Call Frame Instructions diff --git a/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp b/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp index e450f5dc5fd..7d935558721 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp @@ -71,6 +71,11 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T) { // rather than OS version if (T.isMacOSX() && T.isMacOSXVersionLT(10, 6)) HasWeakDefCanBeHiddenDirective = false; + + // FIXME: this should not depend on the target OS version, but on the ld64 + // version in use. From at least >= ld64-97.17 (Xcode 3.2.6) the abs-ified + // FDE relocs may be used. + DwarfFDESymbolsUseAbsDiff = T.isMacOSX() && !T.isMacOSXVersionLT(10, 6); } X86_64MCAsmInfoDarwin::X86_64MCAsmInfoDarwin(const Triple &Triple) diff --git a/test/CodeGen/X86/pr10420.ll b/test/CodeGen/X86/pr10420.ll index 3993f24954e..62951892619 100644 --- a/test/CodeGen/X86/pr10420.ll +++ b/test/CodeGen/X86/pr10420.ll @@ -1,4 +1,9 @@ -; RUN: llc < %s -mtriple=x86_64-apple-macosx -disable-cfi | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-macosx10.7 -disable-cfi | FileCheck --check-prefix=CHECK-64-D11 %s +; RUN: llc < %s -mtriple=x86_64-apple-macosx10.6 -disable-cfi | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-macosx10.5 -disable-cfi | FileCheck --check-prefix=CHECK-64-D89 %s +; RUN: llc < %s -mtriple=i686-apple-macosx10.6 -disable-cfi | FileCheck --check-prefix=CHECK-I686-D10 %s +; RUN: llc < %s -mtriple=i686-apple-macosx10.5 -disable-cfi | FileCheck --check-prefix=CHECK-I686-D89 %s +; RUN: llc < %s -mtriple=i686-apple-macosx10.4 -disable-cfi | FileCheck --check-prefix=CHECK-I686-D89 %s define private void @foo() { ret void @@ -19,3 +24,44 @@ define void @bar() { ; CHECK: Ltmp19: ; CHECK-NEXT: Ltmp20 = Ltmp2-Ltmp19 ## FDE initial location ; CHECK-NEXT: .quad Ltmp20 + + +; CHECK-64-D11: Ltmp13: +; CHECK-64-D11-NEXT: Ltmp14 = L_foo-Ltmp13 ## FDE initial location +; CHECK-64-D11-NEXT: .quad Ltmp14 + +; CHECK-64-D11: Ltmp20: +; CHECK-64-D11-NEXT: Ltmp21 = Ltmp2-Ltmp20 ## FDE initial location +; CHECK-64-D11-NEXT: .quad Ltmp21 + + +; CHECK-64-D89: Ltmp12: +; CHECK-64-D89-NEXT: .quad L_foo-Ltmp12 ## FDE initial location +; CHECK-64-D89-NEXT: Ltmp13 = (Ltmp0-L_foo)-0 ## FDE address range +; CHECK-64-D89-NEXT: .quad Ltmp13 + +; CHECK-64-D89: Ltmp18: +; CHECK-64-D89-NEXT: .quad Ltmp2-Ltmp18 ## FDE initial location +; CHECK-64-D89-NEXT: Ltmp19 = (Ltmp4-Ltmp2)-0 ## FDE address range +; CHECK-64-D89-NEXT: .quad Ltmp19 + + +; CHECK-I686-D10: Ltmp12: +; CHECK-I686-D10-NEXT: Ltmp13 = L_foo-Ltmp12 ## FDE initial location +; CHECK-I686-D10-NEXT: .long Ltmp13 + +; CHECK-I686-D10: Ltmp19: +; CHECK-I686-D10-NEXT: Ltmp20 = Ltmp2-Ltmp19 ## FDE initial location +; CHECK-I686-D10-NEXT: .long Ltmp20 + + +; CHECK-I686-D89: Ltmp12: +; CHECK-I686-D89-NEXT: .long L_foo-Ltmp12 ## FDE initial location +; CHECK-I686-D89-NEXT: Ltmp13 = (Ltmp0-L_foo)-0 ## FDE address range +; CHECK-I686-D89-NEXT: .long Ltmp13 + +; CHECK-I686-D89: Ltmp18: +; CHECK-I686-D89-NEXT: .long Ltmp2-Ltmp18 ## FDE initial location +; CHECK-I686-D89-NEXT: Ltmp19 = (Ltmp4-Ltmp2)-0 ## FDE address range +; CHECK-I686-D89-NEXT: .long Ltmp19 + -- 2.34.1