aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Enderby <enderby@apple.com>2010-05-07 21:44:23 +0000
committerKevin Enderby <enderby@apple.com>2010-05-07 21:44:23 +0000
commita6eeb6e226d7d86d04e34e3b6464f66e0a052f43 (patch)
tree8540510b67e4627e91cbb21b3bdc1653c6cb816b
parent62077af40e4122f20b47ef3e892d91bfbce4dc95 (diff)
Fix i386 relocations to Weak Definitions. The relocation entries should be
external and the item to be relocated should not have the address of the symbol added in. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103302 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/MC/MCMachOSymbolFlags.h44
-rw-r--r--lib/MC/MCMachOStreamer.cpp20
-rw-r--r--lib/MC/MachObjectWriter.cpp13
-rw-r--r--test/MC/MachO/reloc.s94
4 files changed, 113 insertions, 58 deletions
diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h
new file mode 100644
index 0000000000..c938c81f69
--- /dev/null
+++ b/include/llvm/MC/MCMachOSymbolFlags.h
@@ -0,0 +1,44 @@
+//===- MCMachOSymbolFlags.h - MachO Symbol Flags ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SymbolFlags used for the MachO target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCMACHOSYMBOLFLAGS_H
+#define LLVM_MC_MCMACHOSYMBOLFLAGS_H
+
+// These flags are mostly used in MCMachOStreamer.cpp but also needed in
+// MachObjectWriter.cpp to test for Weak Definitions of symbols to emit
+// the correct relocation information.
+
+namespace llvm {
+ /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest
+ /// 16 bits of the implementation defined flags.
+ enum SymbolFlags { // See <mach-o/nlist.h>.
+ SF_DescFlagsMask = 0xFFFF,
+
+ // Reference type flags.
+ SF_ReferenceTypeMask = 0x0007,
+ SF_ReferenceTypeUndefinedNonLazy = 0x0000,
+ SF_ReferenceTypeUndefinedLazy = 0x0001,
+ SF_ReferenceTypeDefined = 0x0002,
+ SF_ReferenceTypePrivateDefined = 0x0003,
+ SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
+ SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
+
+ // Other 'desc' flags.
+ SF_NoDeadStrip = 0x0020,
+ SF_WeakReference = 0x0040,
+ SF_WeakDefinition = 0x0080
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 5ca31943f1..aa8b1ca1de 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -16,6 +16,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCMachOSymbolFlags.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetAsmBackend.h"
@@ -25,25 +26,6 @@ using namespace llvm;
namespace {
class MCMachOStreamer : public MCStreamer {
- /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest
- /// 16 bits of the implementation defined flags.
- enum SymbolFlags { // See <mach-o/nlist.h>.
- SF_DescFlagsMask = 0xFFFF,
-
- // Reference type flags.
- SF_ReferenceTypeMask = 0x0007,
- SF_ReferenceTypeUndefinedNonLazy = 0x0000,
- SF_ReferenceTypeUndefinedLazy = 0x0001,
- SF_ReferenceTypeDefined = 0x0002,
- SF_ReferenceTypePrivateDefined = 0x0003,
- SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
- SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
-
- // Other 'desc' flags.
- SF_NoDeadStrip = 0x0020,
- SF_WeakReference = 0x0040,
- SF_WeakDefinition = 0x0080
- };
private:
MCAssembler Assembler;
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index bb8eb10a48..0dbb2c1c0e 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -16,6 +16,7 @@
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCMachOSymbolFlags.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MachO.h"
@@ -753,9 +754,19 @@ public:
const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
MCSymbolData *SD = &Asm.getSymbolData(*Symbol);
- if (Symbol->isUndefined()) {
+ // Both references to undefined symbols and references to Weak Definitions
+ // get external relocation entries. This is so the static and then the
+ // the dynamic linker can resolve them to the actual definition that will
+ // be used. And in the case of Weak Definitions a reference to one will
+ // not always be to the definition in the same object file.
+ if (Symbol->isUndefined() || (SD->getFlags() & SF_WeakDefinition)) {
IsExtern = 1;
Index = SD->getIndex();
+ // In the case of a Weak Definition the FixedValue needs to be set to
+ // to not have the address of the symbol. In the case of an undefined
+ // symbol you can't call getSymbolAddress().
+ if (SD->getFlags() & SF_WeakDefinition)
+ FixedValue -= Layout.getSymbolAddress(SD);
Value = 0;
} else {
// The index is the section ordinal (1-based).
diff --git a/test/MC/MachO/reloc.s b/test/MC/MachO/reloc.s
index 73a69c3cc5..d935fea5d2 100644
--- a/test/MC/MachO/reloc.s
+++ b/test/MC/MachO/reloc.s
@@ -44,6 +44,13 @@ L1:
.objc_class_name_A=0
.globl .objc_class_name_A
+ .text
+ .globl _f1
+ .weak_definition _f1
+_f1:
+ .data
+ .long _f1
+
// CHECK: ('cputype', 7)
// CHECK: ('cpusubtype', 3)
// CHECK: ('filetype', 1)
@@ -56,9 +63,9 @@ L1:
// 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', 63)
+// CHECK: ('vm_size', 67)
// CHECK: ('file_offset', 392)
-// CHECK: ('file_size', 63)
+// CHECK: ('file_size', 67)
// CHECK: ('maxprot', 7)
// CHECK: ('initprot', 7)
// CHECK: ('num_sections', 3)
@@ -71,7 +78,7 @@ L1:
// CHECK: ('size', 8)
// CHECK: ('offset', 392)
// CHECK: ('alignment', 0)
-// CHECK: ('reloc_offset', 456)
+// CHECK: ('reloc_offset', 460)
// CHECK: ('num_reloc', 1)
// CHECK: ('flags', 0x80000400)
// CHECK: ('reserved1', 0)
@@ -82,58 +89,61 @@ L1:
// CHECK: (('word-0', 0x1),
// CHECK: ('word-1', 0x5000003)),
// CHECK: ])
-// CHECK: ('_section_data', '\xe92\x00\x00\x00\xeb\xf9\xc3')
+// CHECK: ('_section_data', '\xe96\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', 8)
-// CHECK: ('size', 43)
+// CHECK: ('size', 47)
// CHECK: ('offset', 400)
// CHECK: ('alignment', 0)
-// CHECK: ('reloc_offset', 464)
-// CHECK: ('num_reloc', 9)
+// CHECK: ('reloc_offset', 468)
+// CHECK: ('num_reloc', 10)
// CHECK: ('flags', 0x0)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: # Relocation 0
+// CHECK: (('word-0', 0x2b),
+// CHECK: ('word-1', 0xc000007)),
+// CHECK: # Relocation 1
// CHECK: (('word-0', 0x8000002a),
// CHECK: ('word-1', 0x18)),
-// CHECK: # Relocation 1
+// CHECK: # Relocation 2
// CHECK: (('word-0', 0x90000028),
// CHECK: ('word-1', 0x18)),
-// CHECK: # Relocation 2
+// CHECK: # Relocation 3
// CHECK: (('word-0', 0xa0000024),
// CHECK: ('word-1', 0x18)),
-// CHECK: # Relocation 3
+// CHECK: # Relocation 4
// CHECK: (('word-0', 0xa0000020),
// CHECK: ('word-1', 0x18)),
-// CHECK: # Relocation 4
+// CHECK: # Relocation 5
// CHECK: (('word-0', 0xa4000014),
// CHECK: ('word-1', 0x1c)),
-// CHECK: # Relocation 5
+// CHECK: # Relocation 6
// CHECK: (('word-0', 0xa1000000),
// CHECK: ('word-1', 0x24)),
-// CHECK: # Relocation 6
+// CHECK: # Relocation 7
// CHECK: (('word-0', 0x8),
// CHECK: ('word-1', 0x4000002)),
-// CHECK: # Relocation 7
-// CHECK: (('word-0', 0x4),
-// CHECK: ('word-1', 0xc000008)),
// CHECK: # Relocation 8
+// CHECK: (('word-0', 0x4),
+// CHECK: ('word-1', 0xc000009)),
+// CHECK: # Relocation 9
// CHECK: (('word-0', 0x0),
-// CHECK: ('word-1', 0xc000008)),
+// CHECK: ('word-1', 0xc000009)),
// CHECK: ])
-// 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_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\x00\x00\x00\x00')
// 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', 51)
+// CHECK: ('address', 55)
// CHECK: ('size', 12)
-// CHECK: ('offset', 443)
+// CHECK: ('offset', 447)
// CHECK: ('alignment', 0)
-// CHECK: ('reloc_offset', 536)
+// CHECK: ('reloc_offset', 548)
// CHECK: ('num_reloc', 4)
// CHECK: ('flags', 0x0)
// CHECK: ('reserved1', 0)
@@ -151,22 +161,22 @@ L1:
// CHECK: ('word-1', 0x18)),
// CHECK: # Relocation 3
// CHECK: (('word-0', 0xa1000000),
-// CHECK: ('word-1', 0x33)),
+// CHECK: ('word-1', 0x37)),
// CHECK: ])
-// CHECK: ('_section_data', '\x06\x00\x00\x007\x00\x00\x00\x00\x00\x00\x00')
+// CHECK: ('_section_data', '\x02\x00\x00\x00;\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ])
// CHECK: ),
// CHECK: # Load Command 1
// CHECK: (('command', 2)
// CHECK: ('size', 24)
-// CHECK: ('symoff', 568)
-// CHECK: ('nsyms', 9)
-// CHECK: ('stroff', 676)
-// CHECK: ('strsize', 84)
-// CHECK: ('_string_data', '\x00undef\x00local_a_ext\x00.objc_class_name_A\x00local_a\x00local_a_elt\x00local_b\x00local_c\x00bar\x00_f0\x00\x00\x00')
+// CHECK: ('symoff', 580)
+// CHECK: ('nsyms', 10)
+// CHECK: ('stroff', 700)
+// CHECK: ('strsize', 88)
+// CHECK: ('_string_data', '\x00undef\x00local_a_ext\x00.objc_class_name_A\x00_f1\x00local_a\x00local_a_elt\x00local_b\x00local_c\x00bar\x00_f0\x00\x00\x00')
// CHECK: ('_symbols', [
// CHECK: # Symbol 0
-// CHECK: (('n_strx', 38)
+// CHECK: (('n_strx', 42)
// CHECK: ('n_type', 0xe)
// CHECK: ('n_sect', 2)
// CHECK: ('n_desc', 0)
@@ -174,7 +184,7 @@ L1:
// CHECK: ('_string', 'local_a')
// CHECK: ),
// CHECK: # Symbol 1
-// CHECK: (('n_strx', 46)
+// CHECK: (('n_strx', 50)
// CHECK: ('n_type', 0xe)
// CHECK: ('n_sect', 2)
// CHECK: ('n_desc', 0)
@@ -182,7 +192,7 @@ L1:
// CHECK: ('_string', 'local_a_elt')
// CHECK: ),
// CHECK: # Symbol 2
-// CHECK: (('n_strx', 58)
+// CHECK: (('n_strx', 62)
// CHECK: ('n_type', 0xe)
// CHECK: ('n_sect', 2)
// CHECK: ('n_desc', 0)
@@ -190,7 +200,7 @@ L1:
// CHECK: ('_string', 'local_b')
// CHECK: ),
// CHECK: # Symbol 3
-// CHECK: (('n_strx', 66)
+// CHECK: (('n_strx', 70)
// CHECK: ('n_type', 0xe)
// CHECK: ('n_sect', 2)
// CHECK: ('n_desc', 0)
@@ -198,15 +208,15 @@ L1:
// CHECK: ('_string', 'local_c')
// CHECK: ),
// CHECK: # Symbol 4
-// CHECK: (('n_strx', 74)
+// CHECK: (('n_strx', 78)
// CHECK: ('n_type', 0xe)
// CHECK: ('n_sect', 3)
// CHECK: ('n_desc', 0)
-// CHECK: ('n_value', 51)
+// CHECK: ('n_value', 55)
// CHECK: ('_string', 'bar')
// CHECK: ),
// CHECK: # Symbol 5
-// CHECK: (('n_strx', 78)
+// CHECK: (('n_strx', 82)
// CHECK: ('n_type', 0xe)
// CHECK: ('n_sect', 1)
// CHECK: ('n_desc', 0)
@@ -222,6 +232,14 @@ L1:
// CHECK: ('_string', '.objc_class_name_A')
// CHECK: ),
// CHECK: # Symbol 7
+// CHECK: (('n_strx', 38)
+// CHECK: ('n_type', 0xf)
+// CHECK: ('n_sect', 1)
+// CHECK: ('n_desc', 128)
+// CHECK: ('n_value', 8)
+// CHECK: ('_string', '_f1')
+// CHECK: ),
+// CHECK: # Symbol 8
// CHECK: (('n_strx', 7)
// CHECK: ('n_type', 0xf)
// CHECK: ('n_sect', 2)
@@ -229,7 +247,7 @@ L1:
// CHECK: ('n_value', 16)
// CHECK: ('_string', 'local_a_ext')
// CHECK: ),
-// CHECK: # Symbol 8
+// CHECK: # Symbol 9
// CHECK: (('n_strx', 1)
// CHECK: ('n_type', 0x1)
// CHECK: ('n_sect', 0)
@@ -245,8 +263,8 @@ L1:
// CHECK: ('ilocalsym', 0)
// CHECK: ('nlocalsym', 6)
// CHECK: ('iextdefsym', 6)
-// CHECK: ('nextdefsym', 2)
-// CHECK: ('iundefsym', 8)
+// CHECK: ('nextdefsym', 3)
+// CHECK: ('iundefsym', 9)
// CHECK: ('nundefsym', 1)
// CHECK: ('tocoff', 0)
// CHECK: ('ntoc', 0)