]> granicus.if.org Git - llvm/commitdiff
[AsmPrinter] Make the encoding of call sites in .gcc_except_table configurable and...
authorAlex Bradbury <asb@lowrisc.org>
Wed, 17 Jul 2019 14:00:35 +0000 (14:00 +0000)
committerAlex Bradbury <asb@lowrisc.org>
Wed, 17 Jul 2019 14:00:35 +0000 (14:00 +0000)
The original behavior was to always emit the offsets to each call site in the
call site table as uleb128 values, however on some architectures (eg RISCV)
these uleb128 offsets into the code cannot always be resolved until link time
(because relaxation will invalidate any calculated offsets), and there are no
appropriate relocations for uleb128 values. As a consequence it needs to be
possible to specify an alternative.

This also switches RISCV to use DW_EH_PE_udata4 for call side encodings in
.gcc_except_table

Differential Revision: https://reviews.llvm.org/D63415
Patch by Edward Jones.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366329 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/AsmPrinter.h
include/llvm/Target/TargetLoweringObjectFile.h
lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
lib/CodeGen/AsmPrinter/EHStreamer.cpp
lib/CodeGen/TargetLoweringObjectFileImpl.cpp
lib/Target/TargetLoweringObjectFile.cpp
test/CodeGen/RISCV/dwarf-eh.ll

index 9c2097b299520bd6d55e53021e403892ce3e11fe..d110f8b01cb5bab4f69555d2093257afb6f642f8 100644 (file)
@@ -543,6 +543,12 @@ public:
     emitDwarfStringOffset(S.getEntry());
   }
 
+  /// Emit reference to a call site with a specified encoding
+  void EmitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo,
+                          unsigned Encoding) const;
+  /// Emit an integer value corresponding to the call site encoding
+  void EmitCallSiteValue(uint64_t Value, unsigned Encoding) const;
+
   /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
   virtual unsigned getISAEncoding() { return 0; }
 
index 7e094a1738b71048763d02639369a8b8fca37d88..3a2497bff11e84708684047f5fa03abf88f4bbee 100644 (file)
@@ -51,6 +51,7 @@ protected:
   unsigned PersonalityEncoding = 0;
   unsigned LSDAEncoding = 0;
   unsigned TTypeEncoding = 0;
+  unsigned CallSiteEncoding = 0;
 
   /// This section contains the static constructor pointer list.
   MCSection *StaticCtorSection = nullptr;
@@ -147,6 +148,7 @@ public:
   unsigned getPersonalityEncoding() const { return PersonalityEncoding; }
   unsigned getLSDAEncoding() const { return LSDAEncoding; }
   unsigned getTTypeEncoding() const { return TTypeEncoding; }
+  unsigned getCallSiteEncoding() const { return CallSiteEncoding; }
 
   const MCExpr *getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
                                   MCStreamer &Streamer) const;
index 7bc64d091a0d6bbc4500b02b456f96edeff496c8..992e44d95306214793c738e85b9b6ff38276a081 100644 (file)
@@ -183,6 +183,25 @@ void AsmPrinter::EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
   EmitLabelPlusOffset(Label, Offset, MAI->getCodePointerSize());
 }
 
+void AsmPrinter::EmitCallSiteOffset(const MCSymbol *Hi,
+                                    const MCSymbol *Lo,
+                                    unsigned Encoding) const {
+  // The least significant 3 bits specify the width of the encoding
+  if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
+    EmitLabelDifferenceAsULEB128(Hi, Lo);
+  else
+    EmitLabelDifference(Hi, Lo, GetSizeOfEncodedValue(Encoding));
+}
+
+void AsmPrinter::EmitCallSiteValue(uint64_t Value,
+                                   unsigned Encoding) const {
+  // The least significant 3 bits specify the width of the encoding
+  if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
+    EmitULEB128(Value);
+  else
+    OutStreamer->EmitIntValue(Value, GetSizeOfEncodedValue(Encoding));
+}
+
 //===----------------------------------------------------------------------===//
 // Dwarf Lowering Routines
 //===----------------------------------------------------------------------===//
index 2786f8d9f6a4031948540e609d5cb68fc4b8e42c..99e3687b36b8a22841d2f24e65d21935feb02570 100644 (file)
@@ -378,7 +378,8 @@ MCSymbol *EHStreamer::emitExceptionTable() {
   bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
   bool IsWasm = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Wasm;
   unsigned CallSiteEncoding =
-      IsSJLJ ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_uleb128;
+      IsSJLJ ? static_cast<unsigned>(dwarf::DW_EH_PE_udata4) :
+               Asm->getObjFileLowering().getCallSiteEncoding();
   bool HaveTTData = !TypeInfos.empty() || !FilterIds.empty();
 
   // Type infos.
@@ -523,24 +524,24 @@ MCSymbol *EHStreamer::emitExceptionTable() {
       // Offset of the call site relative to the start of the procedure.
       if (VerboseAsm)
         Asm->OutStreamer->AddComment(">> Call Site " + Twine(++Entry) + " <<");
-      Asm->EmitLabelDifferenceAsULEB128(BeginLabel, EHFuncBeginSym);
+      Asm->EmitCallSiteOffset(BeginLabel, EHFuncBeginSym, CallSiteEncoding);
       if (VerboseAsm)
         Asm->OutStreamer->AddComment(Twine("  Call between ") +
                                      BeginLabel->getName() + " and " +
                                      EndLabel->getName());
-      Asm->EmitLabelDifferenceAsULEB128(EndLabel, BeginLabel);
+      Asm->EmitCallSiteOffset(EndLabel, BeginLabel, CallSiteEncoding);
 
       // Offset of the landing pad relative to the start of the procedure.
       if (!S.LPad) {
         if (VerboseAsm)
           Asm->OutStreamer->AddComment("    has no landing pad");
-        Asm->EmitULEB128(0);
+        Asm->EmitCallSiteValue(0, CallSiteEncoding);
       } else {
         if (VerboseAsm)
           Asm->OutStreamer->AddComment(Twine("    jumps to ") +
                                        S.LPad->LandingPadLabel->getName());
-        Asm->EmitLabelDifferenceAsULEB128(S.LPad->LandingPadLabel,
-                                          EHFuncBeginSym);
+        Asm->EmitCallSiteOffset(S.LPad->LandingPadLabel, EHFuncBeginSym,
+                                CallSiteEncoding);
       }
 
       // Offset of the first associated action record, relative to the start of
index d8e6b3ef93a3471bc2f4658b5c7ce28b3e98b727..4c8f75b237aa8e15836fc31aa5f2caea677adbe1 100644 (file)
@@ -218,6 +218,7 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
       PersonalityEncoding = dwarf::DW_EH_PE_absptr;
       TTypeEncoding = dwarf::DW_EH_PE_absptr;
     }
+    CallSiteEncoding = dwarf::DW_EH_PE_udata4;
     break;
   case Triple::riscv32:
   case Triple::riscv64:
@@ -226,6 +227,7 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
                           dwarf::DW_EH_PE_sdata4;
     TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
                     dwarf::DW_EH_PE_sdata4;
+    CallSiteEncoding = dwarf::DW_EH_PE_udata4;
     break;
   case Triple::sparcv9:
     LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
index ee32d01572461edcf32587845e90a43dae9cfd58..17274e1c2c6eb8541b176f4639fae1c0c02ea870 100644 (file)
@@ -47,6 +47,7 @@ void TargetLoweringObjectFile::Initialize(MCContext &ctx,
 
   // Reset various EH DWARF encodings.
   PersonalityEncoding = LSDAEncoding = TTypeEncoding = dwarf::DW_EH_PE_absptr;
+  CallSiteEncoding = dwarf::DW_EH_PE_uleb128;
 }
 
 TargetLoweringObjectFile::~TargetLoweringObjectFile() {
index 67236d7da668eb7ebd0ecbddac61d968b17d838e..ecca81783e56c3e8e0575ede0d65ba7394303cd3 100644 (file)
@@ -53,14 +53,14 @@ try.cont:
 ; CHECK-NEXT: .byte 155 # @TType Encoding = indirect pcrel sdata4
 ; TODO: call site encoding should be DW_EH_PE_udata4
 ; CHECK: .Lttbaseref0:
-; CHECK-NEXT: .byte    1                       # Call site Encoding = uleb128
+; CHECK-NEXT: .byte    3                       # Call site Encoding = udata4
 ; CHECK-NEXT: .uleb128 .Lcst_end0-.Lcst_begin0
 ; CHECK-NEXT: cst_begin0:
-; CHECK-NEXT: .uleb128 .Ltmp0-.Lfunc_begin0   # >> Call Site 1 <<
-; CHECK-NEXT: .uleb128 .Ltmp1-.Ltmp0          #   Call between .Ltmp0 and .Ltmp1
-; CHECK-NEXT: .uleb128 .Ltmp2-.Lfunc_begin0   #     jumps to .Ltmp2
+; CHECK-NEXT: .word .Ltmp0-.Lfunc_begin0   # >> Call Site 1 <<
+; CHECK-NEXT: .word .Ltmp1-.Ltmp0          #   Call between .Ltmp0 and .Ltmp1
+; CHECK-NEXT: .word .Ltmp2-.Lfunc_begin0   #     jumps to .Ltmp2
 ; CHECK-NEXT: .byte    1                       #   On action: 1
-; CHECK-NEXT: .uleb128 .Ltmp1-.Lfunc_begin0   # >> Call Site 2 <<
-; CHECK-NEXT: .uleb128 .Lfunc_end0-.Ltmp1     #   Call between .Ltmp1 and .Lfunc_end0
-; CHECK-NEXT: .byte    0                       #     has no landing pad
+; CHECK-NEXT: .word .Ltmp1-.Lfunc_begin0   # >> Call Site 2 <<
+; CHECK-NEXT: .word .Lfunc_end0-.Ltmp1     #   Call between .Ltmp1 and .Lfunc_end0
+; CHECK-NEXT: .word    0                       #     has no landing pad
 ; CHECK-NEXT: .byte    0                       #   On action: cleanup