[llvm-commits] [llvm] r98924 - in /llvm/trunk: lib/MC/MCAssembler.cpp test/MC/MachO/reloc.s

Daniel Dunbar daniel at zuster.org
Thu Mar 18 20:18:12 PDT 2010


Author: ddunbar
Date: Thu Mar 18 22:18:12 2010
New Revision: 98924

URL: http://llvm.org/viewvc/llvm-project?rev=98924&view=rev
Log:
MC/Mach-O: Factor out isScatteredFixupFullyResolvedSimple predicate, and fix some corner cases.

Modified:
    llvm/trunk/lib/MC/MCAssembler.cpp
    llvm/trunk/test/MC/MachO/reloc.s

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=98924&r1=98923&r2=98924&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Thu Mar 18 22:18:12 2010
@@ -1010,6 +1010,44 @@
 MCAssembler::~MCAssembler() {
 }
 
+static bool isScatteredFixupFullyResolvedSimple(const MCAssembler &Asm,
+                                                const MCAsmFixup &Fixup,
+                                                const MCDataFragment *DF,
+                                                const MCValue Target,
+                                                const MCSection *BaseSection) {
+  // The effective fixup address is
+  //     addr(atom(A)) + offset(A)
+  //   - addr(atom(B)) - offset(B)
+  //   - addr(<base symbol>) + <fixup offset from base symbol>
+  // and the offsets are not relocatable, so the fixup is fully resolved when
+  //  addr(atom(A)) - addr(atom(B)) - addr(<base symbol>)) == 0.
+  //
+  // The simple (Darwin, except on x86_64) way of dealing with this was to
+  // assume that any reference to a temporary symbol *must* be a temporary
+  // symbol in the same atom, unless the sections differ. Therefore, any PCrel
+  // relocation to a temporary symbol (in the same section) is fully
+  // resolved. This also works in conjunction with absolutized .set, which
+  // requires the compiler to use .set to absolutize the differences between
+  // symbols which the compiler knows to be assembly time constants, so we don't
+  // need to worry about consider symbol differences fully resolved.
+
+  // Non-relative fixups are only resolved if constant.
+  if (!BaseSection)
+    return Target.isAbsolute();
+
+  // Otherwise, relative fixups are only resolved if not a difference and the
+  // target is a temporary in the same section.
+  if (Target.isAbsolute() || Target.getSymB())
+    return false;
+
+  const MCSymbol *A = &Target.getSymA()->getSymbol();
+  if (!A->isTemporary() || !A->isInSection() ||
+      &A->getSection() != BaseSection)
+    return false;
+
+  return true;
+}
+
 bool MCAssembler::isSymbolLinkerVisible(const MCSymbolData *SD) const {
   // Non-temporary labels should always be visible to the linker.
   if (!SD->getSymbol().isTemporary())
@@ -1036,34 +1074,33 @@
 
   Value = Target.getConstant();
 
-  // FIXME: This "resolved" check isn't quite right. The assumption is that if
-  // we have a PCrel access to a temporary, then that temporary is in the same
-  // atom, and so the value is resolved. We need explicit atom's to implement
-  // this more precisely.
   bool IsResolved = true, IsPCRel = isFixupKindPCRel(Fixup.Kind);
   if (const MCSymbolRefExpr *A = Target.getSymA()) {
     if (A->getSymbol().isDefined())
       Value += getSymbolData(A->getSymbol()).getAddress();
     else
       IsResolved = false;
-
-    // With scattered symbols, we assume anything that isn't a PCrel temporary
-    // access can have an arbitrary value.
-    if (getBackend().hasScatteredSymbols() &&
-        (!IsPCRel || !A->getSymbol().isTemporary()))
-      IsResolved = false;
   }
   if (const MCSymbolRefExpr *B = Target.getSymB()) {
     if (B->getSymbol().isDefined())
       Value -= getSymbolData(B->getSymbol()).getAddress();
     else
       IsResolved = false;
+  }
 
-    // With scattered symbols, we assume anything that isn't a PCrel temporary
-    // access can have an arbitrary value.
-    if (getBackend().hasScatteredSymbols() &&
-        (!IsPCRel || !B->getSymbol().isTemporary()))
-      IsResolved = false;
+  // If we are using scattered symbols, determine whether this value is actually
+  // resolved; scattering may cause atoms to move.
+  if (IsResolved && getBackend().hasScatteredSymbols()) {
+    if (getBackend().hasReliableSymbolDifference()) {
+      llvm_report_error("FIXME: Not yet implemented");
+    } else {
+      const MCSection *BaseSection = 0;
+      if (IsPCRel)
+        BaseSection = &DF->getParent()->getSection();
+
+      IsResolved = isScatteredFixupFullyResolvedSimple(*this, Fixup, DF, Target,
+                                                       BaseSection);
+    }
   }
 
   if (IsPCRel)

Modified: llvm/trunk/test/MC/MachO/reloc.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/reloc.s?rev=98924&r1=98923&r2=98924&view=diff
==============================================================================
--- llvm/trunk/test/MC/MachO/reloc.s (original)
+++ llvm/trunk/test/MC/MachO/reloc.s Thu Mar 18 22:18:12 2010
@@ -10,7 +10,7 @@
 
 local_a:
         .long 0
-local_a_elt:      
+local_a_elt:
         .long 0
 local_b:
         .long local_b - local_c + 245
@@ -27,9 +27,20 @@
         .const
 
         .long
-bar:    
+bar:
         .long local_a_elt - bar + 33
 
+L0:
+        .long L0
+        .long L1
+
+        .text
+_f0:
+L1:
+        jmp L0
+        jmp L1
+        ret
+
 // CHECK: ('cputype', 7)
 // CHECK: ('cpusubtype', 3)
 // CHECK: ('filetype', 1)
@@ -42,9 +53,9 @@
 // CHECK:   ('size', 260)
 // CHECK:   ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:   ('vm_addr', 0)
-// CHECK:   ('vm_size', 47)
+// CHECK:   ('vm_size', 63)
 // CHECK:   ('file_offset', 392)
-// CHECK:   ('file_size', 47)
+// CHECK:   ('file_size', 63)
 // CHECK:   ('maxprot', 7)
 // CHECK:   ('initprot', 7)
 // CHECK:   ('num_sections', 3)
@@ -54,26 +65,29 @@
 // CHECK:    (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:     ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:     ('address', 0)
-// CHECK:     ('size', 0)
+// CHECK:     ('size', 8)
 // CHECK:     ('offset', 392)
 // CHECK:     ('alignment', 0)
-// CHECK:     ('reloc_offset', 0)
-// CHECK:     ('num_reloc', 0)
-// CHECK:     ('flags', 0x80000000)
+// CHECK:     ('reloc_offset', 456)
+// CHECK:     ('num_reloc', 1)
+// CHECK:     ('flags', 0x80000400)
 // CHECK:     ('reserved1', 0)
 // CHECK:     ('reserved2', 0)
 // CHECK:    ),
 // CHECK:   ('_relocations', [
+// CHECK:     # Relocation 0
+// CHECK:     (('word-0', 0x1),
+// CHECK:      ('word-1', 0x5000003)),
 // CHECK:   ])
-// CHECK:   ('_section_data', '')
+// CHECK:   ('_section_data', '\xe92\x00\x00\x00\xeb\xf9\xc3')
 // CHECK:     # Section 1
 // CHECK:    (('section_name', '__data\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:     ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
-// CHECK:     ('address', 0)
+// CHECK:     ('address', 8)
 // CHECK:     ('size', 43)
-// CHECK:     ('offset', 392)
+// CHECK:     ('offset', 400)
 // CHECK:     ('alignment', 0)
-// CHECK:     ('reloc_offset', 440)
+// CHECK:     ('reloc_offset', 464)
 // CHECK:     ('num_reloc', 9)
 // CHECK:     ('flags', 0x0)
 // CHECK:     ('reserved1', 0)
@@ -82,72 +96,78 @@
 // CHECK:   ('_relocations', [
 // CHECK:     # Relocation 0
 // CHECK:     (('word-0', 0x8000002a),
-// CHECK:      ('word-1', 0x10)),
+// CHECK:      ('word-1', 0x18)),
 // CHECK:     # Relocation 1
 // CHECK:     (('word-0', 0x90000028),
-// CHECK:      ('word-1', 0x10)),
+// CHECK:      ('word-1', 0x18)),
 // CHECK:     # Relocation 2
 // CHECK:     (('word-0', 0xa0000024),
-// CHECK:      ('word-1', 0x10)),
+// CHECK:      ('word-1', 0x18)),
 // CHECK:     # Relocation 3
 // CHECK:     (('word-0', 0xa0000020),
-// CHECK:      ('word-1', 0x10)),
+// CHECK:      ('word-1', 0x18)),
 // CHECK:     # Relocation 4
 // CHECK:     (('word-0', 0xa4000014),
-// CHECK:      ('word-1', 0x14)),
+// CHECK:      ('word-1', 0x1c)),
 // CHECK:     # Relocation 5
 // CHECK:     (('word-0', 0xa1000000),
-// CHECK:      ('word-1', 0x1c)),
+// CHECK:      ('word-1', 0x24)),
 // CHECK:     # Relocation 6
 // CHECK:     (('word-0', 0x8),
 // CHECK:      ('word-1', 0x4000002)),
 // CHECK:     # Relocation 7
 // CHECK:     (('word-0', 0x4),
-// CHECK:      ('word-1', 0xc000006)),
+// CHECK:      ('word-1', 0xc000007)),
 // CHECK:     # Relocation 8
 // CHECK:     (('word-0', 0x0),
-// CHECK:      ('word-1', 0xc000006)),
+// CHECK:      ('word-1', 0xc000007)),
 // CHECK:   ])
-// CHECK:   ('_section_data', '\x00\x00\x00\x00\x04\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x1a\x00\x00\x00$\x00i')
+// CHECK:   ('_section_data', '\x00\x00\x00\x00\x04\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00"\x00\x00\x00,\x00q')
 // CHECK:     # Section 2
 // CHECK:    (('section_name', '__const\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:     ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
-// CHECK:     ('address', 43)
-// CHECK:     ('size', 4)
-// CHECK:     ('offset', 435)
+// CHECK:     ('address', 51)
+// CHECK:     ('size', 12)
+// CHECK:     ('offset', 443)
 // CHECK:     ('alignment', 0)
-// CHECK:     ('reloc_offset', 512)
-// CHECK:     ('num_reloc', 2)
+// CHECK:     ('reloc_offset', 536)
+// CHECK:     ('num_reloc', 4)
 // CHECK:     ('flags', 0x0)
 // CHECK:     ('reserved1', 0)
 // CHECK:     ('reserved2', 0)
 // CHECK:    ),
 // CHECK:   ('_relocations', [
 // CHECK:     # Relocation 0
-// CHECK:     (('word-0', 0xa4000000),
-// CHECK:      ('word-1', 0x10)),
+// CHECK:     (('word-0', 0x8),
+// CHECK:      ('word-1', 0x4000001)),
 // CHECK:     # Relocation 1
+// CHECK:     (('word-0', 0x4),
+// CHECK:      ('word-1', 0x4000003)),
+// CHECK:     # Relocation 2
+// CHECK:     (('word-0', 0xa4000000),
+// CHECK:      ('word-1', 0x18)),
+// CHECK:     # Relocation 3
 // CHECK:     (('word-0', 0xa1000000),
-// CHECK:      ('word-1', 0x2b)),
+// CHECK:      ('word-1', 0x33)),
 // CHECK:   ])
-// CHECK:   ('_section_data', '\x06\x00\x00\x00')
+// CHECK:   ('_section_data', '\x06\x00\x00\x007\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:   ])
 // CHECK:  ),
 // CHECK:   # Load Command 1
 // CHECK:  (('command', 2)
 // CHECK:   ('size', 24)
-// CHECK:   ('symoff', 528)
-// CHECK:   ('nsyms', 7)
-// CHECK:   ('stroff', 612)
-// CHECK:   ('strsize', 60)
-// CHECK:   ('_string_data', '\x00undef\x00local_a_ext\x00local_a\x00local_a_elt\x00local_b\x00local_c\x00bar\x00\x00')
+// CHECK:   ('symoff', 568)
+// CHECK:   ('nsyms', 8)
+// CHECK:   ('stroff', 664)
+// CHECK:   ('strsize', 64)
+// CHECK:   ('_string_data', '\x00undef\x00local_a_ext\x00local_a\x00local_a_elt\x00local_b\x00local_c\x00bar\x00_f0\x00\x00')
 // CHECK:   ('_symbols', [
 // CHECK:     # Symbol 0
 // CHECK:    (('n_strx', 19)
 // CHECK:     ('n_type', 0xe)
 // CHECK:     ('n_sect', 2)
 // CHECK:     ('n_desc', 0)
-// CHECK:     ('n_value', 12)
+// CHECK:     ('n_value', 20)
 // CHECK:     ('_string', 'local_a')
 // CHECK:    ),
 // CHECK:     # Symbol 1
@@ -155,7 +175,7 @@
 // CHECK:     ('n_type', 0xe)
 // CHECK:     ('n_sect', 2)
 // CHECK:     ('n_desc', 0)
-// CHECK:     ('n_value', 16)
+// CHECK:     ('n_value', 24)
 // CHECK:     ('_string', 'local_a_elt')
 // CHECK:    ),
 // CHECK:     # Symbol 2
@@ -163,7 +183,7 @@
 // CHECK:     ('n_type', 0xe)
 // CHECK:     ('n_sect', 2)
 // CHECK:     ('n_desc', 0)
-// CHECK:     ('n_value', 20)
+// CHECK:     ('n_value', 28)
 // CHECK:     ('_string', 'local_b')
 // CHECK:    ),
 // CHECK:     # Symbol 3
@@ -171,7 +191,7 @@
 // CHECK:     ('n_type', 0xe)
 // CHECK:     ('n_sect', 2)
 // CHECK:     ('n_desc', 0)
-// CHECK:     ('n_value', 28)
+// CHECK:     ('n_value', 36)
 // CHECK:     ('_string', 'local_c')
 // CHECK:    ),
 // CHECK:     # Symbol 4
@@ -179,18 +199,26 @@
 // CHECK:     ('n_type', 0xe)
 // CHECK:     ('n_sect', 3)
 // CHECK:     ('n_desc', 0)
-// CHECK:     ('n_value', 43)
+// CHECK:     ('n_value', 51)
 // CHECK:     ('_string', 'bar')
 // CHECK:    ),
 // CHECK:     # Symbol 5
+// CHECK:    (('n_strx', 59)
+// CHECK:     ('n_type', 0xe)
+// CHECK:     ('n_sect', 1)
+// CHECK:     ('n_desc', 0)
+// CHECK:     ('n_value', 0)
+// CHECK:     ('_string', '_f0')
+// CHECK:    ),
+// CHECK:     # Symbol 6
 // CHECK:    (('n_strx', 7)
 // CHECK:     ('n_type', 0xf)
 // CHECK:     ('n_sect', 2)
 // CHECK:     ('n_desc', 0)
-// CHECK:     ('n_value', 8)
+// CHECK:     ('n_value', 16)
 // CHECK:     ('_string', 'local_a_ext')
 // CHECK:    ),
-// CHECK:     # Symbol 6
+// CHECK:     # Symbol 7
 // CHECK:    (('n_strx', 1)
 // CHECK:     ('n_type', 0x1)
 // CHECK:     ('n_sect', 0)
@@ -204,10 +232,10 @@
 // CHECK:  (('command', 11)
 // CHECK:   ('size', 80)
 // CHECK:   ('ilocalsym', 0)
-// CHECK:   ('nlocalsym', 5)
-// CHECK:   ('iextdefsym', 5)
+// CHECK:   ('nlocalsym', 6)
+// CHECK:   ('iextdefsym', 6)
 // CHECK:   ('nextdefsym', 1)
-// CHECK:   ('iundefsym', 6)
+// CHECK:   ('iundefsym', 7)
 // CHECK:   ('nundefsym', 1)
 // CHECK:   ('tocoff', 0)
 // CHECK:   ('ntoc', 0)





More information about the llvm-commits mailing list