[lld] r213340 - [mach-o] Add support for x86 CALL instruction that uses a scattered relocation

Nick Kledzik kledzik at apple.com
Thu Jul 17 17:37:52 PDT 2014


Author: kledzik
Date: Thu Jul 17 19:37:52 2014
New Revision: 213340

URL: http://llvm.org/viewvc/llvm-project?rev=213340&view=rev
Log:
[mach-o] Add support for x86 CALL instruction that uses a scattered relocation

Modified:
    lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
    lld/trunk/test/mach-o/parse-relocs-x86.yaml

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=213340&r1=213339&r2=213340&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp Thu Jul 17 19:37:52 2014
@@ -202,6 +202,14 @@ ArchHandler_x86::getReferenceInfo(const
     targetAddress = fixupAddress + 4 + readS32(swap, fixupContent);
     return atomFromAddress(reloc.symbol, targetAddress, target, addend);
     break;
+  case GENERIC_RELOC_VANILLA | rScattered | rPcRel | rLength4:
+    // ex: call _foo+n (and _foo defined)
+    *kind = branch32;
+    targetAddress = fixupAddress + 4 + readS32(swap, fixupContent);
+    if (E ec = atomFromAddress(0, reloc.value, target, addend))
+      return ec;
+    *addend = targetAddress - reloc.value;
+    break;
   case GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength2:
     // ex: callw _foo (and _foo undefined)
     *kind = branch16;
@@ -215,6 +223,14 @@ ArchHandler_x86::getReferenceInfo(const
     targetAddress = fixupAddress + 2 + readS16(swap, fixupContent);
     return atomFromAddress(reloc.symbol, targetAddress, target, addend);
     break;
+  case GENERIC_RELOC_VANILLA | rScattered | rPcRel | rLength2:
+    // ex: callw _foo+n (and _foo defined)
+    *kind = branch16;
+    targetAddress = fixupAddress + 2 + readS16(swap, fixupContent);
+    if (E ec = atomFromAddress(0, reloc.value, target, addend))
+      return ec;
+    *addend = targetAddress - reloc.value;
+    break;
   case GENERIC_RELOC_VANILLA | rExtern | rLength4:
     // ex: movl	_foo, %eax   (and _foo undefined)
     // ex: .long _foo        (and _foo undefined)
@@ -370,12 +386,19 @@ void ArchHandler_x86::applyFixupRelocata
                                                uint64_t inAtomAddress) {
   int32_t *loc32 = reinterpret_cast<int32_t *>(location);
   int16_t *loc16 = reinterpret_cast<int16_t *>(location);
+  bool useExternalReloc = useExternalRelocationTo(*ref.target());
   switch (ref.kindValue()) {
   case branch32:
-    write32(*loc32, _swap, ref.addend() - (fixupAddress + 4));
+    if (useExternalReloc)
+      write32(*loc32, _swap, ref.addend() - (fixupAddress + 4));
+    else
+      write32(*loc32, _swap, (targetAddress - (fixupAddress+4)) + ref.addend());
     break;
   case branch16:
-    write16(*loc16, _swap, ref.addend() - (fixupAddress + 2));
+    if (useExternalReloc)
+      write16(*loc16, _swap, ref.addend() - (fixupAddress + 2));
+    else
+      write16(*loc16, _swap, (targetAddress - (fixupAddress+2)) + ref.addend());
     break;
   case pointer32:
   case abs32:
@@ -434,20 +457,30 @@ void ArchHandler_x86::appendSectionReloc
   bool useExternalReloc = useExternalRelocationTo(*ref.target());
   switch (ref.kindValue()) {
   case branch32:
-    if (useExternalReloc)
-      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()),  0,
-                GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength4);
-    else
-      appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
-                GENERIC_RELOC_VANILLA | rPcRel           | rLength4);
+    if (useExternalReloc) {
+      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
+                  GENERIC_RELOC_VANILLA | rExtern    | rPcRel | rLength4);
+    } else {
+      if (ref.addend() != 0)
+        appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
+                  GENERIC_RELOC_VANILLA | rScattered | rPcRel |  rLength4);
+      else
+        appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
+                  GENERIC_RELOC_VANILLA |              rPcRel | rLength4);
+    }
     break;
   case branch16:
-    if (useExternalReloc)
-      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()),  0,
-                GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength2);
-    else
-      appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
-                GENERIC_RELOC_VANILLA | rPcRel           | rLength2);
+    if (useExternalReloc) {
+      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
+                  GENERIC_RELOC_VANILLA | rExtern    | rPcRel | rLength2);
+    } else {
+      if (ref.addend() != 0)
+        appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
+                  GENERIC_RELOC_VANILLA | rScattered | rPcRel |  rLength2);
+      else
+        appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
+                  GENERIC_RELOC_VANILLA |              rPcRel | rLength2);
+    }
     break;
   case pointer32:
   case abs32:

Modified: lld/trunk/test/mach-o/parse-relocs-x86.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-relocs-x86.yaml?rev=213340&r1=213339&r2=213340&view=diff
==============================================================================
--- lld/trunk/test/mach-o/parse-relocs-x86.yaml (original)
+++ lld/trunk/test/mach-o/parse-relocs-x86.yaml Thu Jul 17 19:37:52 2014
@@ -12,16 +12,24 @@
 #_test:
 #  	call _undef
 #  	call _undef+2
+#  	call _foo
+#  	call _foo+2
 #   callw _undef
+#  	callw _foo
+#  	callw _foo+2
 #L1:
 #  	movl	_undef, %eax
 #   movl	_x, %eax
 #  	movl	_x-L1(%eax), %eax
 #  	movl	_x+4-L1(%eax), %eax
 #
+#_foo:
+#    ret
+#
 #  .data
 #_x: 
 #  .long _undef
+#  .long _foo
 #  .long _test - .
 #  .long _test+3 - .
 #
@@ -29,7 +37,7 @@
 --- !mach-o
 arch:            x86
 file-type:       MH_OBJECT
-flags:           [  ]
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
 OS:              unknown
 sections:        
   - segment:         __TEXT
@@ -38,74 +46,100 @@ sections:
     attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
     address:         0x0000000000000000
     content:         [ 0xE8, 0xFB, 0xFF, 0xFF, 0xFF, 0xE8, 0xF8, 0xFF, 
-                       0xFF, 0xFF, 0x66, 0xE8, 0xF2, 0xFF, 0xA1, 0x00, 
-                       0x00, 0x00, 0x00, 0xA1, 0x24, 0x00, 0x00, 0x00, 
-                       0x8B, 0x80, 0x16, 0x00, 0x00, 0x00, 0x8B, 0x80, 
-                       0x1A, 0x00, 0x00, 0x00 ]
+                       0xFF, 0xFF, 0xE8, 0x27, 0x00, 0x00, 0x00, 0xE8, 
+                       0x24, 0x00, 0x00, 0x00, 0x66, 0xE8, 0xE8, 0xFF, 
+                       0x66, 0xE8, 0x1A, 0x00, 0x66, 0xE8, 0x18, 0x00, 
+                       0xA1, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x37, 0x00, 
+                       0x00, 0x00, 0x8B, 0x80, 0x17, 0x00, 0x00, 0x00, 
+                       0x8B, 0x80, 0x1B, 0x00, 0x00, 0x00, 0xC3 ]
     relocations:     
-      - offset:          0x00000020
+      - offset:          0x00000032
         scattered:       true
         type:            GENERIC_RELOC_LOCAL_SECTDIFF
         length:          2
         pc-rel:          false
-        value:           0x00000024
+        value:           0x00000037
       - offset:          0x00000000
         scattered:       true
         type:            GENERIC_RELOC_PAIR
         length:          2
         pc-rel:          false
-        value:           0x0000000E
-      - offset:          0x0000001A
+        value:           0x00000020
+      - offset:          0x0000002C
         scattered:       true
         type:            GENERIC_RELOC_LOCAL_SECTDIFF
         length:          2
         pc-rel:          false
-        value:           0x00000024
+        value:           0x00000037
       - offset:          0x00000000
         scattered:       true
         type:            GENERIC_RELOC_PAIR
         length:          2
         pc-rel:          false
-        value:           0x0000000E
-      - offset:          0x00000014
+        value:           0x00000020
+      - offset:          0x00000026
         type:            GENERIC_RELOC_VANILLA
         length:          2
         pc-rel:          false
         extern:          false
         symbol:          2
-      - offset:          0x0000000F
+      - offset:          0x00000021
         type:            GENERIC_RELOC_VANILLA
         length:          2
         pc-rel:          false
         extern:          true
-        symbol:          2
-      - offset:          0x0000000C
+        symbol:          3
+      - offset:          0x0000001E
+        scattered:       true
+        type:            GENERIC_RELOC_VANILLA
+        length:          1
+        pc-rel:          true
+        value:           0x00000036
+      - offset:          0x0000001A
+        type:            GENERIC_RELOC_VANILLA
+        length:          1
+        pc-rel:          true
+        extern:          false
+        symbol:          1
+      - offset:          0x00000016
         type:            GENERIC_RELOC_VANILLA
         length:          1
         pc-rel:          true
         extern:          true
-        symbol:          2
+        symbol:          3
+      - offset:          0x00000010
+        scattered:       true
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          true
+        value:           0x00000036
+      - offset:          0x0000000B
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          true
+        extern:          false
+        symbol:          1
       - offset:          0x00000006
         type:            GENERIC_RELOC_VANILLA
         length:          2
         pc-rel:          true
         extern:          true
-        symbol:          2
+        symbol:          3
       - offset:          0x00000001
         type:            GENERIC_RELOC_VANILLA
         length:          2
         pc-rel:          true
         extern:          true
-        symbol:          2
+        symbol:          3
   - segment:         __DATA
     section:         __data
     type:            S_REGULAR
     attributes:      [  ]
-    address:         0x0000000000000024
-    content:         [ 0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xFF, 0xFF, 
-                       0xD7, 0xFF, 0xFF, 0xFF ]
+    address:         0x0000000000000037
+    content:         [ 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 
+                       0xC1, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF ]
     relocations:     
-      - offset:          0x00000008
+      - offset:          0x0000000C
         scattered:       true
         type:            GENERIC_RELOC_LOCAL_SECTDIFF
         length:          2
@@ -116,8 +150,8 @@ sections:
         type:            GENERIC_RELOC_PAIR
         length:          2
         pc-rel:          false
-        value:           0x0000002C
-      - offset:          0x00000004
+        value:           0x00000043
+      - offset:          0x00000008
         scattered:       true
         type:            GENERIC_RELOC_LOCAL_SECTDIFF
         length:          2
@@ -128,22 +162,32 @@ sections:
         type:            GENERIC_RELOC_PAIR
         length:          2
         pc-rel:          false
-        value:           0x00000028
+        value:           0x0000003F
+      - offset:          0x00000004
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          false
+        extern:          false
+        symbol:          1
       - offset:          0x00000000
         type:            GENERIC_RELOC_VANILLA
         length:          2
         pc-rel:          false
         extern:          true
-        symbol:          2
+        symbol:          3
 local-symbols:   
   - name:            _test
     type:            N_SECT
     sect:            1
     value:           0x0000000000000000
+  - name:            _foo
+    type:            N_SECT
+    sect:            1
+    value:           0x0000000000000036
   - name:            _x
     type:            N_SECT
     sect:            2
-    value:           0x0000000000000024
+    value:           0x0000000000000037
 undefined-symbols: 
   - name:            _undef
     type:            N_UNDF
@@ -158,12 +202,15 @@ undefined-symbols:
 # CHECK:       - kind:            pointer32
 # CHECK:         offset:          0
 # CHECK:         target:          _undef
-# CHECK:       - kind:            delta32
+# CHECK:       - kind:            pointer32
 # CHECK:         offset:          4
-# CHECK:         target:          _test
+# CHECK:         target:          _foo
 # CHECK:       - kind:            delta32
 # CHECK:         offset:          8
 # CHECK:         target:          _test
+# CHECK:       - kind:            delta32
+# CHECK:         offset:          12
+# CHECK:         target:          _test
 # CHECK:         addend:          3
 # CHECK:  - name:            _test
 # CHECK:    references:
@@ -175,21 +222,38 @@ undefined-symbols:
 # CHECK:        offset:          6
 # CHECK:        target:          _undef
 # CHECK:        addend:          2
+# CHECK:      - kind:            branch32
+# CHECK:        offset:          11
+# CHECK:        target:          _foo
+# CHECK-NOT:    addend:
+# CHECK:      - kind:            branch32
+# CHECK:        offset:          16
+# CHECK:        target:          _foo
+# CHECK:        addend:          2
 # CHECK:      - kind:            branch16
-# CHECK:        offset:          12
+# CHECK:        offset:          22
 # CHECK:        target:          _undef
+# CHECK-NOT:    addend:
+# CHECK:      - kind:            branch16
+# CHECK:        offset:          26
+# CHECK:        target:          _foo
+# CHECK-NOT:    addend:
+# CHECK:      - kind:            branch16
+# CHECK:        offset:          30
+# CHECK:        target:          _foo
+# CHECK:        addend:          2
 # CHECK:      - kind:            abs32
-# CHECK:        offset:          15
+# CHECK:        offset:          33
 # CHECK:        target:          _undef
 # CHECK:      - kind:            abs32
-# CHECK:        offset:          20
+# CHECK:        offset:          38
 # CHECK:        target:          _x
 # CHECK:      - kind:            funcRel32
-# CHECK:        offset:          26
+# CHECK:        offset:          44
 # CHECK:        target:          _x
-# CHECK:        addend:          -14
+# CHECK:        addend:          -32
 # CHECK:      - kind:            funcRel32
-# CHECK:        offset:          32
+# CHECK:        offset:          50
 # CHECK:        target:          _x
-# CHECK:        addend:          -10
+# CHECK:        addend:          -28
 





More information about the llvm-commits mailing list