[lld] r237491 - [LLD] Make sure MachO FDEs read their augmentation data strings from the right

Lang Hames lhames at gmail.com
Fri May 15 17:08:02 PDT 2015


Author: lhames
Date: Fri May 15 19:08:02 2015
New Revision: 237491

URL: http://llvm.org/viewvc/llvm-project?rev=237491&view=rev
Log:
[LLD] Make sure MachO FDEs read their augmentation data strings from the right
CIE, not just the most recently encountered one.


Modified:
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
    lld/trunk/test/mach-o/parse-eh-frame-relocs-x86_64.yaml

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=237491&r1=237490&r2=237491&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Fri May 15 19:08:02 2015
@@ -647,13 +647,15 @@ static int64_t readSPtr(bool is64, bool
 
 /// --- Augmentation String Processing ---
 
-struct AugmentationDataInfo {
-  bool _present = false;
+struct CIEInfo {
+  bool _augmentationDataPresent = false;
   bool _mayHaveLSDA = false;
 };
 
+typedef llvm::DenseMap<const MachODefinedAtom*, CIEInfo> CIEInfoMap;
+
 static std::error_code processAugmentationString(const uint8_t *augStr,
-                                                 AugmentationDataInfo &adi,
+                                                 CIEInfo &cieInfo,
                                                  unsigned *len = nullptr) {
 
   if (augStr[0] == '\0') {
@@ -666,12 +668,12 @@ static std::error_code processAugmentati
     return make_dynamic_error_code("expected 'z' at start of augmentation "
                                    "string");
 
-  adi._present = true;
+  cieInfo._augmentationDataPresent = true;
   uint64_t idx = 1;
 
   while (augStr[idx] != '\0') {
     if (augStr[idx] == 'L') {
-      adi._mayHaveLSDA = true;
+      cieInfo._mayHaveLSDA = true;
       ++idx;
     } else
       ++idx;
@@ -684,10 +686,12 @@ static std::error_code processAugmentati
 
 static std::error_code processCIE(const NormalizedFile &normalizedFile,
                                   MachODefinedAtom *atom,
-                                  AugmentationDataInfo &adi) {
+                                  CIEInfoMap &cieInfos) {
   const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
-
   const uint8_t *frameData = atom->rawContent().data();
+
+  CIEInfo cieInfo;
+
   uint32_t size = read32(frameData, isBig);
   uint64_t cieIDField = size == 0xffffffffU
                           ? sizeof(uint32_t) + sizeof(uint64_t)
@@ -696,9 +700,11 @@ static std::error_code processCIE(const
   uint64_t augmentationStringField = versionField + sizeof(uint8_t);
 
   if (auto err = processAugmentationString(frameData + augmentationStringField,
-                                           adi))
+                                           cieInfo))
     return err;
 
+  cieInfos[atom] = std::move(cieInfo);
+
   return std::error_code();
 }
 
@@ -708,7 +714,7 @@ static std::error_code processFDE(const
                                   const Section *ehFrameSection,
                                   MachODefinedAtom *atom,
                                   uint64_t offset,
-                                  const AugmentationDataInfo &adi) {
+                                  const CIEInfoMap &cieInfos) {
 
   const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
   const bool is64 = MachOLinkingContext::is64Bit(normalizedFile.arch);
@@ -730,11 +736,16 @@ static std::error_code processFDE(const
   cieAddress -= cieDelta;
 
   Reference::Addend addend;
-  const Atom *cie =
+  const MachODefinedAtom *cie =
     findAtomCoveringAddress(normalizedFile, file, cieAddress, &addend);
   atom->addReference(cieFieldInFDE, handler.unwindRefToCIEKind(), cie,
                      addend, handler.kindArch());
 
+  assert(cie && cie->contentType() == DefinedAtom::typeCFI && !addend &&
+         "FDE's CIE field does not point at the start of a CIE.");
+
+  const CIEInfo &cieInfo = cieInfos.find(cie)->second;
+
   // Linker needs to fixup reference from the FDE to the function it's
   // describing. FIXME: there are actually different ways to do this, and the
   // particular method used is specified in the CIE's augmentation fields
@@ -752,7 +763,7 @@ static std::error_code processFDE(const
                      func, addend, handler.kindArch());
 
   // Handle the augmentation data if there is any.
-  if (adi._present) {
+  if (cieInfo._augmentationDataPresent) {
     // First process the augmentation data length field.
     uint64_t augmentationDataLengthFieldInFDE =
       rangeFieldInFDE + 2 * (is64 ? sizeof(uint64_t) : sizeof(uint32_t));
@@ -761,7 +772,7 @@ static std::error_code processFDE(const
       llvm::decodeULEB128(frameData + augmentationDataLengthFieldInFDE,
                           &lengthFieldSize);
 
-    if (adi._mayHaveLSDA && augmentationDataLength > 0) {
+    if (cieInfo._mayHaveLSDA && augmentationDataLength > 0) {
 
       // Look at the augmentation data field.
       uint64_t augmentationDataFieldInFDE =
@@ -800,7 +811,7 @@ std::error_code addEHFrameReferences(con
     return std::error_code();
 
   std::error_code ehFrameErr;
-  AugmentationDataInfo adi;
+  CIEInfoMap cieInfos;
 
   file.eachAtomInSection(*ehFrameSection,
                          [&](MachODefinedAtom *atom, uint64_t offset) -> void {
@@ -811,12 +822,11 @@ std::error_code addEHFrameReferences(con
       return;
 
     const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
-    if (ArchHandler::isDwarfCIE(isBig, atom)) {
-      adi = AugmentationDataInfo();
-      ehFrameErr = processCIE(normalizedFile, atom, adi);
-    } else
+    if (ArchHandler::isDwarfCIE(isBig, atom))
+      ehFrameErr = processCIE(normalizedFile, atom, cieInfos);
+    else
       ehFrameErr = processFDE(normalizedFile, file, handler, ehFrameSection,
-                              atom, offset, adi);
+                              atom, offset, cieInfos);
   });
 
   return ehFrameErr;

Modified: lld/trunk/test/mach-o/parse-eh-frame-relocs-x86_64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-eh-frame-relocs-x86_64.yaml?rev=237491&r1=237490&r2=237491&view=diff
==============================================================================
--- lld/trunk/test/mach-o/parse-eh-frame-relocs-x86_64.yaml (original)
+++ lld/trunk/test/mach-o/parse-eh-frame-relocs-x86_64.yaml Fri May 15 19:08:02 2015
@@ -1,83 +1,110 @@
 # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
 #
 # Test parsing of x86_64 __eh_frame (dwarf unwind) relocations.
-#
-#_catchMyException:
-# pushq   %rbp
-# movq    %rsp, %rbp
-# callq   _foo
-# popq    %rbp
-# retq
-# movq    %rax, %rdi
-# callq   ___cxa_begin_catch
-# popq    %rbp
-# jmp     ___cxa_end_catch
 
 --- !mach-o
 arch:            x86_64
 file-type:       MH_OBJECT
-flags:           [  ]
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+compat-version:  0.0
+current-version: 0.0
+has-UUID:        false
+OS:              unknown
 sections:
   - segment:         __TEXT
     section:         __text
     type:            S_REGULAR
     attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    alignment:       16
     address:         0x0000000000000000
-    content:         [0x55, 0x48, 0x89, 0xe5, 0xe8, 0x00, 0x00, 0x00,
-                      0x00, 0x5d, 0xc3, 0x48, 0x89, 0xc7, 0xe8, 0x00,
-                      0x00, 0x00, 0x00, 0x5d, 0xe9, 0x00, 0x00, 0x00,
-                      0x00, 0x00, 0x00, 0x00 ]
-    relocations:
-      - offset:          0x00000015
-        type:            X86_64_RELOC_BRANCH
-        length:          2
-        pc-rel:          true
-        extern:          true
-        symbol:          2
-      - offset:          0x0000000f
-        type:            X86_64_RELOC_BRANCH
-        length:          2
-        pc-rel:          true
-        extern:          true
-        symbol:          1
-      - offset:          0x00000005
-        type:            X86_64_RELOC_BRANCH
-        length:          2
-        pc-rel:          true
-        extern:          true
-        symbol:          0
+    content:         [ 0x55, 0x48, 0x89, 0xE5, 0xE8, 0x00, 0x00, 0x00,
+                       0x00, 0x5D, 0xC3, 0x48, 0x89, 0xC7, 0xE8, 0x00,
+                       0x00, 0x00, 0x00, 0x5D, 0xE9, 0x00, 0x00, 0x00,
+                       0x00, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00,
+                       0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x66, 0x2E,
+                       0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x55, 0x48, 0x89, 0xE5, 0xE8, 0x00, 0x00, 0x00,
+                       0x00, 0x5D, 0xC3, 0x48, 0x89, 0xC7, 0xE8, 0x00,
+                       0x00, 0x00, 0x00, 0x5D, 0xE9, 0x00, 0x00, 0x00,
+                       0x00 ]
   - segment:         __TEXT
     section:         __gcc_except_tab
     type:            S_REGULAR
     attributes:      [  ]
-    address:         0x000000000000001c
-    content:         [ 0x00, 0x00, 0x00, 0x00 ]
+    alignment:       4
+    address:         0x000000000000004C
+    content:         [ 0xFF, 0x9B, 0xA2, 0x80, 0x80, 0x00, 0x03, 0x1A,
+                       0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+                       0x0B, 0x00, 0x00, 0x00, 0x01, 0x09, 0x00, 0x00,
+                       0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0xFF, 0x9B, 0xA2, 0x80, 0x80, 0x00, 0x03, 0x1A,
+                       0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+                       0x0B, 0x00, 0x00, 0x00, 0x01, 0x09, 0x00, 0x00,
+                       0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 ]
   - segment:         __TEXT
     section:         __eh_frame
     type:            S_COALESCED
     attributes:      [  ]
-    address:         0x0000000000000020
-    content:         [ 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                       0x01, 0x7a, 0x50, 0x4c, 0x52, 0x00, 0x01, 0x78,
-                       0x10, 0x07, 0x9b, 0x04, 0x00, 0x00, 0x00, 0x10,
-                       0x10, 0x0c, 0x07, 0x08, 0x90, 0x01, 0x00, 0x00,
-                       0x2c, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
-                       0xB8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    alignment:       8
+    address:         0x0000000000000100
+    content:         [ 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x03, 0x7A, 0x50, 0x4C, 0x52, 0x00, 0x01, 0x78,
+                       0x10, 0x07, 0x9B, 0x04, 0x00, 0x00, 0x00, 0x10,
+                       0x10, 0x0C, 0x07, 0x08, 0x90, 0x01, 0x00, 0x00,
+                       0x2C, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+                       0xD8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                       0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x08, 0x13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                       0xFF, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D,
+                       0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x03, 0x7A, 0x52, 0x00, 0x01, 0x78, 0x10, 0x01,
+                       0x10, 0x0C, 0x07, 0x08, 0x90, 0x01, 0x00, 0x00,
+                       0x24, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
+                       0xB0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                       0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x00, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D,
+                       0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x2C, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
+                       0x98, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                       0x08, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-                       0xff, 0x41, 0x0e, 0x10, 0x86, 0x02, 0x43, 0x0d,
+                       0x08, 0xCB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                       0xFF, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D,
                        0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
-  - segment:         __DATA
-    section:         __data
-    type:            S_REGULAR
-    attributes:      [  ]
-    address:         0x0000000000000068
-    content:         [ 0x00, 0x00, 0x00, 0x00 ]
+    relocations:
+      - offset:          0x00000013
+        type:            X86_64_RELOC_GOT
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          8
 local-symbols:
-  - name:            _catchMyException
+  - name:            GCC_except_table0
+    type:            N_SECT
+    sect:            2
+    value:           0x000000000000004C
+  - name:            GCC_except_table2
+    type:            N_SECT
+    sect:            2
+    value:           0x0000000000000074
+global-symbols:
+  - name:            _catchMyException1
     type:            N_SECT
+    scope:           [ N_EXT ]
     sect:            1
     value:           0x0000000000000000
+  - name:            _catchMyException2
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000030
+  - name:            _bar
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000020
 undefined-symbols:
   - name:            _foo
     type:            N_UNDF
@@ -91,17 +118,59 @@ undefined-symbols:
     type:            N_UNDF
     scope:           [ N_EXT ]
     value:           0x0000000000000000
+  - name:            ___gxx_personality_v0
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+page-size:       0x00000000
 ...
 
+# Check that LSDA fields are fixed up correctly, even when there are multiple
+# CIEs involved.
+#
+# (1) Check that we can relocate an LSDA at all. Requires correct interpretation
+#     of augmentation data strings in CIEs and augmentation data fields of FDEs.
+#
 # CHECK:       - type:            unwind-cfi
 # CHECK-NOT:   - type:
 # CHECK:         references:
 # CHECK-NEXT:      - kind:            negDelta32
 # CHECK-NEXT:        offset:          4
-# CHECK-NEXT:        target:          L000
+# CHECK-NEXT:        target:          L002
 # CHECK-NEXT:      - kind:            unwindFDEToFunction
 # CHECK-NEXT:        offset:          8
-# CHECK-NEXT:        target:          _catchMyException
+# CHECK-NEXT:        target:          _catchMyException1
 # CHECK-NEXT:      - kind:            unwindFDEToFunction
 # CHECK-NEXT:        offset:          25
+# CHECK-NEXT:        target:          GCC_except_table0
+#
+# (2) Check that we have an intervening FDE with a different CIE.
+#     If the test fails here then test (3) probably isn't testing what it
+#     should, and this test-case should be updated.
+#
+# CHECK:       - type:            unwind-cfi
+# CHECK-NOT:   - type:
+# CHECK:         references:
+# CHECK-NEXT:      - kind:            negDelta32
+# CHECK-NEXT:        offset:          4
 # CHECK-NEXT:        target:          L001
+# CHECK-NEXT:      - kind:            unwindFDEToFunction
+# CHECK-NEXT:        offset:          8
+# CHECK-NEXT:        target:          _bar
+#
+# (3) Check that we can relocate the LSDA on a second FDE that references the
+#     original CIE from (1). Requires us to match this FDE up with the correct
+#     CIE.
+#
+# CHECK-NEXT:  - type:            unwind-cfi
+# CHECK-NOT:   - type:
+# CHECK:         references:
+# CHECK-NEXT:      - kind:            negDelta32
+# CHECK-NEXT:        offset:          4
+# CHECK-NEXT:        target:          L002
+# CHECK-NEXT:      - kind:            unwindFDEToFunction
+# CHECK-NEXT:        offset:          8
+# CHECK-NEXT:        target:          _catchMyException2
+# CHECK-NEXT:      - kind:            unwindFDEToFunction
+# CHECK-NEXT:        offset:          25
+# CHECK-NEXT:        target:          GCC_except_table2





More information about the llvm-commits mailing list