[lld] r213585 - [mach-o] add support for old x86 __eh_frame sections

Nick Kledzik kledzik at apple.com
Mon Jul 21 15:06:57 PDT 2014


Author: kledzik
Date: Mon Jul 21 17:06:57 2014
New Revision: 213585

URL: http://llvm.org/viewvc/llvm-project?rev=213585&view=rev
Log:
[mach-o] add support for old x86 __eh_frame sections

Over time the symbols and relocations have changed for dwarf unwind info
in the __eh_frame section.  Add test cases for older and new style.

Added:
    lld/trunk/test/mach-o/parse-eh-frame-x86-anon.yaml
    lld/trunk/test/mach-o/parse-eh-frame-x86-labeled.yaml
Modified:
    lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp

Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp?rev=213585&r1=213584&r2=213585&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp Mon Jul 21 17:06:57 2014
@@ -83,6 +83,7 @@ private:
     funcRel32,             /// ex: movl _foo-L1(%eax), %eax
     pointer32,             /// ex: .long _foo
     delta32,               /// ex: .long _foo - .
+    negDelta32,            /// ex: .long . - _foo
 
     // Kinds introduced by Passes:
     lazyPointer,           /// Location contains a lazy pointer.
@@ -120,6 +121,7 @@ const Registry::KindStrings ArchHandler_
   LLD_KIND_STRING_ENTRY(funcRel32),
   LLD_KIND_STRING_ENTRY(pointer32),
   LLD_KIND_STRING_ENTRY(delta32),
+  LLD_KIND_STRING_ENTRY(negDelta32),
   LLD_KIND_STRING_ENTRY(lazyPointer),
   LLD_KIND_STRING_ENTRY(lazyImmediateLocation),
   LLD_KIND_STRING_END
@@ -302,22 +304,28 @@ ArchHandler_x86::getPairReferenceInfo(co
     ec = atomFromAddr(0, fromAddress, &fromTarget, &offsetInFrom);
     if (ec)
       return ec;
-    if (fromTarget != inAtom)
-      return make_dynamic_error_code(Twine("SECTDIFF relocation where "
-                                           "subtrahend label is not in atom"));
-    *kind = ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) ? funcRel32
-                                                                     : delta32;
-    if (*kind == funcRel32) {
-      // SECTDIFF relocations are used in i386 codegen where the function
-      // prolog does a CALL to the next instruction which POPs the return
-      // address into EBX which becomes the pic-base register.  The POP
-      // instruction is label the used for the subtrahend in expressions.
-      // The funcRel32 kind represents the 32-bit delta to some symbol from
-      // the start of the function (atom) containing the funcRel32.
-      uint32_t ta = fromAddress + value - toAddress;
-      *addend = ta - offsetInFrom;
+    if (fromTarget != inAtom) {
+      if (*target != inAtom) 
+        return make_dynamic_error_code(Twine("SECTDIFF relocation where "
+                                             "neither target is in atom"));
+      *kind = negDelta32;
+      *addend = toAddress - value - fromAddress;
+      *target = fromTarget;
     } else {
-      *addend = fromAddress + value - toAddress;
+      if ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) {
+        // SECTDIFF relocations are used in i386 codegen where the function
+        // prolog does a CALL to the next instruction which POPs the return
+        // address into EBX which becomes the pic-base register.  The POP
+        // instruction is label the used for the subtrahend in expressions.
+        // The funcRel32 kind represents the 32-bit delta to some symbol from
+        // the start of the function (atom) containing the funcRel32.
+        *kind = funcRel32;
+        uint32_t ta = fromAddress + value - toAddress;
+        *addend = ta - offsetInFrom;
+      } else {
+        *kind = delta32;
+        *addend = fromAddress + value - toAddress;
+      }
     }
     return std::error_code();
     break;
@@ -379,6 +387,9 @@ void ArchHandler_x86::applyFixupFinal(co
   case delta32:
     write32(*loc32, _swap, targetAddress - fixupAddress + ref.addend());
     break;
+  case negDelta32:
+    write32(*loc32, _swap, fixupAddress - targetAddress + ref.addend());
+    break;
   case lazyPointer:
   case lazyImmediateLocation:
     // do nothing
@@ -420,6 +431,9 @@ void ArchHandler_x86::applyFixupRelocata
   case delta32:
     write32(*loc32, _swap, targetAddress - fixupAddress + ref.addend());
     break;
+  case negDelta32:
+    write32(*loc32, _swap, fixupAddress - targetAddress + ref.addend());
+    break;
   case lazyPointer:
   case lazyImmediateLocation:
     // do nothing
@@ -507,17 +521,24 @@ void ArchHandler_x86::appendSectionReloc
     }
     break;
   case funcRel32:
-      appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
-                GENERIC_RELOC_SECTDIFF |  rScattered    | rLength4);
-      appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) - ref.addend(),
-                GENERIC_RELOC_PAIR     |  rScattered    | rLength4);
+    appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
+              GENERIC_RELOC_SECTDIFF |  rScattered    | rLength4);
+    appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) - ref.addend(),
+              GENERIC_RELOC_PAIR     |  rScattered    | rLength4);
     break;
   case delta32:
-      appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
-                GENERIC_RELOC_SECTDIFF |  rScattered    | rLength4);
-      appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) +
-                                                             ref.offsetInAtom(),
-                GENERIC_RELOC_PAIR     |  rScattered    | rLength4);
+    appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
+              GENERIC_RELOC_SECTDIFF |  rScattered    | rLength4);
+    appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) +
+                                                           ref.offsetInAtom(),
+              GENERIC_RELOC_PAIR     |  rScattered    | rLength4);
+    break;
+  case negDelta32:
+    appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) +
+                                                           ref.offsetInAtom(),
+              GENERIC_RELOC_SECTDIFF |  rScattered    | rLength4);
+    appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
+              GENERIC_RELOC_PAIR     |  rScattered    | rLength4);
     break;
   case lazyPointer:
   case lazyImmediateLocation:

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=213585&r1=213584&r2=213585&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Mon Jul 21 17:06:57 2014
@@ -62,6 +62,7 @@ const MachORelocatableSectionToAtomType
   ENTRY("__TEXT", "__const",          S_REGULAR,          typeConstant),
   ENTRY("__TEXT", "__const_coal",     S_COALESCED,        typeConstant),
   ENTRY("__TEXT", "__eh_frame",       S_COALESCED,        typeCFI),
+  ENTRY("__TEXT", "__eh_frame",       S_REGULAR,          typeCFI),
   ENTRY("__TEXT", "__literal4",       S_4BYTE_LITERALS,   typeLiteral4),
   ENTRY("__TEXT", "__literal8",       S_8BYTE_LITERALS,   typeLiteral8),
   ENTRY("__TEXT", "__literal16",      S_16BYTE_LITERALS,  typeLiteral16),
@@ -149,7 +150,7 @@ void sectionParseInfo(DefinedAtom::Conte
                                                             atomizeUTF8),
     ENTRY(typeUTF16String,       1, scopeLinkageUnit,     mergeByContent, 
                                                             atomizeUTF16),
-    ENTRY(typeCFI,               1, scopeTranslationUnit, mergeNo, 
+    ENTRY(typeCFI,               4, scopeTranslationUnit, mergeNo,
                                                             atomizeCFI),
     ENTRY(typeLiteral4,          4, scopeLinkageUnit,     mergeByContent, 
                                                             atomizeFixedSize),
@@ -165,8 +166,6 @@ void sectionParseInfo(DefinedAtom::Conte
                                                             atomizePointerSize),
     ENTRY(typeCompactUnwindInfo, 4, scopeTranslationUnit, mergeNo, 
                                                             atomizeCU),
-    ENTRY(typeCFI,               4, scopeTranslationUnit, mergeNo, 
-                                                            atomizeFixedSize),
     ENTRY(typeGOT,               4, scopeLinkageUnit,     mergeByContent, 
                                                             atomizePointerSize),
     ENTRY(typeUnknown,           1, scopeGlobal,          mergeNo, 

Added: lld/trunk/test/mach-o/parse-eh-frame-x86-anon.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-eh-frame-x86-anon.yaml?rev=213585&view=auto
==============================================================================
--- lld/trunk/test/mach-o/parse-eh-frame-x86-anon.yaml (added)
+++ lld/trunk/test/mach-o/parse-eh-frame-x86-anon.yaml Mon Jul 21 17:06:57 2014
@@ -0,0 +1,129 @@
+# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t  | FileCheck %s
+#
+# Test parsing of new __eh_frame (dwarf unwind) section that has no .eh labels
+# and no relocations.
+#
+
+--- !mach-o
+arch:            x86
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+OS:              unknown
+sections:        
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x89, 0xE5, 0x56, 0x83, 0xEC, 0x14, 0xE8, 
+                       0x00, 0x00, 0x00, 0x00, 0x5E, 0xC7, 0x04, 0x24, 
+                       0x04, 0x00, 0x00, 0x00, 0xE8, 0xE7, 0xFF, 0xFF, 
+                       0xFF, 0xC7, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x8B, 
+                       0x8E, 0x38, 0x00, 0x00, 0x00, 0x89, 0x4C, 0x24, 
+                       0x04, 0x89, 0x04, 0x24, 0xC7, 0x44, 0x24, 0x08, 
+                       0x00, 0x00, 0x00, 0x00, 0xE8, 0xC7, 0xFF, 0xFF, 
+                       0xFF, 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x08, 0xE8, 
+                       0xBC, 0xFF, 0xFF, 0xFF ]
+    relocations:     
+      - offset:          0x00000040
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          true
+        extern:          false
+        symbol:          1
+      - offset:          0x00000035
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          4
+      - offset:          0x00000021
+        scattered:       true
+        type:            GENERIC_RELOC_LOCAL_SECTDIFF
+        length:          2
+        pc-rel:          false
+        value:           0x00000044
+      - offset:          0x00000000
+        scattered:       true
+        type:            GENERIC_RELOC_PAIR
+        length:          2
+        pc-rel:          false
+        value:           0x0000000C
+      - offset:          0x00000015
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          3
+  - segment:         __IMPORT
+    section:         __pointers
+    type:            S_NON_LAZY_SYMBOL_POINTERS
+    attributes:      [  ]
+    address:         0x0000000000000044
+    content:         [ 0x00, 0x00, 0x00, 0x00 ]
+    indirect-syms:   [ 5 ]
+  - segment:         __TEXT
+    section:         __eh_frame
+    type:            S_REGULAR
+    attributes:      [  ]
+    alignment:       2
+    address:         0x0000000000000048
+    content:         [ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x01, 0x7A, 0x52, 0x00, 0x01, 0x7C, 0x08, 0x01, 
+                       0x10, 0x0C, 0x05, 0x04, 0x88, 0x01, 0x00, 0x00, 
+                       0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 
+                       0x98, 0xFF, 0xFF, 0xFF, 0x39, 0x00, 0x00, 0x00, 
+                       0x00, 0x41, 0x0E, 0x08, 0x84, 0x02, 0x42, 0x0D, 
+                       0x04, 0x44, 0x86, 0x03, 0x18, 0x00, 0x00, 0x00, 
+                       0x38, 0x00, 0x00, 0x00, 0xB5, 0xFF, 0xFF, 0xFF, 
+                       0x0B, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0E, 0x08, 
+                       0x84, 0x02, 0x42, 0x0D, 0x04, 0x00, 0x00, 0x00 ]
+global-symbols:  
+  - name:            __Z3barv
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000039
+  - name:            __Z3foov
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+undefined-symbols: 
+  - name:            __ZTIi
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+  - name:            ___cxa_allocate_exception
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+  - name:            ___cxa_throw
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+...
+
+# CHECK: defined-atoms:   
+# FIXME:   - ref-name:        [[CIE:L[L0-9]+]]
+# CHECK:     type:            unwind-cfi
+# CHECK:     content:          
+# CHECK:   - type:            unwind-cfi
+# CHECK:     content:         
+# FIXME:     references:      
+# FIXME:       - kind:            negDelta32
+# FIXME:         offset:          4
+# FIXME:         target:          [[CIE]]
+# FIXME:       - kind:            delta32
+# FIXME:         offset:          8
+# FIXME:         target:          __Z3foov
+# CHECK:   - type:            unwind-cfi
+# CHECK:     content:          
+# FIXME:     references:      
+# FIXME:       - kind:            negDelta32
+# FIXME:         offset:          4
+# FIXME:         target:          [[CIE]]
+# FIXME:       - kind:            delta32
+# FIXME:         offset:          8
+# FIXME:         target:          __Z3barv
+

Added: lld/trunk/test/mach-o/parse-eh-frame-x86-labeled.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-eh-frame-x86-labeled.yaml?rev=213585&view=auto
==============================================================================
--- lld/trunk/test/mach-o/parse-eh-frame-x86-labeled.yaml (added)
+++ lld/trunk/test/mach-o/parse-eh-frame-x86-labeled.yaml Mon Jul 21 17:06:57 2014
@@ -0,0 +1,193 @@
+# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t  | FileCheck %s
+#
+# Test parsing of old __eh_frame (dwarf unwind) section that has .eh labels
+# and relocations.
+#
+
+--- !mach-o
+arch:            x86
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+OS:              unknown
+sections:        
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x89, 0xE5, 0x56, 0x83, 0xEC, 0x14, 0xE8, 
+                       0x00, 0x00, 0x00, 0x00, 0x5E, 0xC7, 0x04, 0x24, 
+                       0x04, 0x00, 0x00, 0x00, 0xE8, 0xE7, 0xFF, 0xFF, 
+                       0xFF, 0xC7, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x8B, 
+                       0x8E, 0x38, 0x00, 0x00, 0x00, 0x89, 0x4C, 0x24, 
+                       0x04, 0x89, 0x04, 0x24, 0xC7, 0x44, 0x24, 0x08, 
+                       0x00, 0x00, 0x00, 0x00, 0xE8, 0xC7, 0xFF, 0xFF, 
+                       0xFF, 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x08, 0xE8, 
+                       0xBC, 0xFF, 0xFF, 0xFF ]
+    relocations:     
+      - offset:          0x00000040
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          true
+        extern:          false
+        symbol:          1
+      - offset:          0x00000035
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          7
+      - offset:          0x00000021
+        scattered:       true
+        type:            GENERIC_RELOC_LOCAL_SECTDIFF
+        length:          2
+        pc-rel:          false
+        value:           0x00000044
+      - offset:          0x00000000
+        scattered:       true
+        type:            GENERIC_RELOC_PAIR
+        length:          2
+        pc-rel:          false
+        value:           0x0000000C
+      - offset:          0x00000015
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          6
+  - segment:         __IMPORT
+    section:         __pointers
+    type:            S_NON_LAZY_SYMBOL_POINTERS
+    attributes:      [  ]
+    address:         0x0000000000000044
+    content:         [ 0x00, 0x00, 0x00, 0x00 ]
+    indirect-syms:   [ 5 ]
+  - segment:         __TEXT
+    section:         __eh_frame
+    type:            S_REGULAR
+    attributes:      [  ]
+    alignment:       2
+    address:         0x0000000000000048
+    content:         [ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x01, 0x7A, 0x52, 0x00, 0x01, 0x7C, 0x08, 0x01, 
+                       0x10, 0x0C, 0x05, 0x04, 0x88, 0x01, 0x00, 0x00, 
+                       0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 
+                       0x98, 0xFF, 0xFF, 0xFF, 0x39, 0x00, 0x00, 0x00, 
+                       0x00, 0x41, 0x0E, 0x08, 0x84, 0x02, 0x42, 0x0D, 
+                       0x04, 0x44, 0x86, 0x03, 0x18, 0x00, 0x00, 0x00, 
+                       0x38, 0x00, 0x00, 0x00, 0xB5, 0xFF, 0xFF, 0xFF, 
+                       0x0B, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0E, 0x08, 
+                       0x84, 0x02, 0x42, 0x0D, 0x04, 0x00, 0x00, 0x00 ]
+    relocations:     
+      - offset:          0x0000001C
+        scattered:       true
+        type:            GENERIC_RELOC_LOCAL_SECTDIFF
+        length:          2
+        pc-rel:          false
+        value:           0x00000064
+      - offset:          0x00000000
+        scattered:       true
+        type:            GENERIC_RELOC_PAIR
+        length:          2
+        pc-rel:          false
+        value:           0x00000048
+      - offset:          0x00000020
+        scattered:       true
+        type:            GENERIC_RELOC_SECTDIFF
+        length:          2
+        pc-rel:          false
+        value:           0x00000000
+      - offset:          0x00000000
+        scattered:       true
+        type:            GENERIC_RELOC_PAIR
+        length:          2
+        pc-rel:          false
+        value:           0x00000068
+      - offset:          0x00000038
+        scattered:       true
+        type:            GENERIC_RELOC_LOCAL_SECTDIFF
+        length:          2
+        pc-rel:          false
+        value:           0x00000080
+      - offset:          0x00000000
+        scattered:       true
+        type:            GENERIC_RELOC_PAIR
+        length:          2
+        pc-rel:          false
+        value:           0x00000048
+      - offset:          0x0000003C
+        scattered:       true
+        type:            GENERIC_RELOC_SECTDIFF
+        length:          2
+        pc-rel:          false
+        value:           0x00000039
+      - offset:          0x00000000
+        scattered:       true
+        type:            GENERIC_RELOC_PAIR
+        length:          2
+        pc-rel:          false
+        value:           0x00000084
+local-symbols:   
+  - name:            EH_frame0
+    type:            N_SECT
+    sect:            3
+    value:           0x0000000000000048
+global-symbols:  
+  - name:            __Z3barv
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000039
+  - name:            __Z3barv.eh
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            3
+    value:           0x000000000000007C
+  - name:            __Z3foov
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+  - name:            __Z3foov.eh
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            3
+    value:           0x0000000000000060
+undefined-symbols: 
+  - name:            __ZTIi
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+  - name:            ___cxa_allocate_exception
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+  - name:            ___cxa_throw
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+...
+
+# CHECK: defined-atoms:   
+# CHECK:   - ref-name:        [[CIE:L[L0-9]+]]
+# CHECK:     type:            unwind-cfi
+# CHECK:     content:          
+# CHECK:   - type:            unwind-cfi
+# CHECK:     content:         
+# CHECK:     references:      
+# CHECK:       - kind:            negDelta32
+# CHECK:         offset:          4
+# CHECK:         target:          [[CIE]]
+# CHECK:       - kind:            delta32
+# CHECK:         offset:          8
+# CHECK:         target:          __Z3foov
+# CHECK:   - type:            unwind-cfi
+# CHECK:     content:          
+# CHECK:     references:      
+# CHECK:       - kind:            negDelta32
+# CHECK:         offset:          4
+# CHECK:         target:          [[CIE]]
+# CHECK:       - kind:            delta32
+# CHECK:         offset:          8
+# CHECK:         target:          __Z3barv
+





More information about the llvm-commits mailing list