diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index f3bc8edd84e..2e634b03edd 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -136,6 +136,9 @@ public: unsigned getStubSize() const { return Reserved2; } unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; } + bool hasAttribute(unsigned Value) const { + return (TypeAndAttributes & Value) != 0; + } /// ParseSectionSpecifier - Parse the section specifier indicated by "Spec". /// This is a string that can appear after a .section directive in a mach-o diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index a533ccfdc64..f4aef96e302 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -548,6 +548,17 @@ public: MCSymbolData &SD = Asm.getSymbolData(*Symbol); const MCSymbolData *Base = Asm.getAtom(Layout, &SD); + // Relocations inside debug sections always use local relocations when + // possible. This seems to be done because the debugger doesn't fully + // understand x86_64 relocation entries, and expects to find values that + // have already been fixed up. + if (Symbol->isDefined()) { + const MCSectionMachO &Section = static_cast( + Fragment->getParent()->getSection()); + if (Section.hasAttribute(MCSectionMachO::S_ATTR_DEBUG)) + Base = 0; + } + // x86_64 almost always uses external relocations, except when there is no // symbol to use as a base address (a local symbol with no preceeding // non-local symbol). diff --git a/test/MC/MachO/darwin-x86_64-reloc.s b/test/MC/MachO/darwin-x86_64-reloc.s index d5e75d12145..eefe2984430 100644 --- a/test/MC/MachO/darwin-x86_64-reloc.s +++ b/test/MC/MachO/darwin-x86_64-reloc.s @@ -42,25 +42,29 @@ L1: .long _foobar@GOTPCREL+4 .long _foo@GOTPCREL+4 + .section __DWARF,__debug_frame,regular,debug + .quad L1 + .quad _ext_foo + // CHECK: ('cputype', 16777223) // CHECK: ('cpusubtype', 3) // CHECK: ('filetype', 1) // CHECK: ('num_load_commands', 1) -// CHECK: ('load_commands_size', 336) +// CHECK: ('load_commands_size', 416) // CHECK: ('flag', 0) // CHECK: ('reserved', 0) // CHECK: ('load_commands', [ // CHECK: # Load Command 0 // CHECK: (('command', 25) -// CHECK: ('size', 232) +// CHECK: ('size', 312) // 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', 189) -// CHECK: ('file_offset', 368) -// CHECK: ('file_size', 189) +// CHECK: ('vm_size', 205) +// CHECK: ('file_offset', 448) +// CHECK: ('file_size', 205) // CHECK: ('maxprot', 7) // CHECK: ('initprot', 7) -// CHECK: ('num_sections', 2) +// CHECK: ('num_sections', 3) // CHECK: ('flags', 0) // CHECK: ('sections', [ // CHECK: # Section 0 @@ -68,9 +72,9 @@ L1: // CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') // CHECK: ('address', 0) // CHECK: ('size', 181) -// CHECK: ('offset', 368) +// CHECK: ('offset', 448) // CHECK: ('alignment', 0) -// CHECK: ('reloc_offset', 560) +// CHECK: ('reloc_offset', 656) // CHECK: ('num_reloc', 27) // CHECK: ('flags', 0x80000400) // CHECK: ('reserved1', 0) @@ -166,9 +170,9 @@ L1: // CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') // CHECK: ('address', 181) // CHECK: ('size', 8) -// CHECK: ('offset', 549) +// CHECK: ('offset', 629) // CHECK: ('alignment', 0) -// CHECK: ('reloc_offset', 776) +// CHECK: ('reloc_offset', 872) // CHECK: ('num_reloc', 2) // CHECK: ('flags', 0x0) // CHECK: ('reserved1', 0) @@ -181,22 +185,45 @@ L1: // CHECK: ('word-1', 0x4d000000)), // CHECK: # Relocation 1 // CHECK: (('word-0', 0x0), -// CHECK: ('word-1', 0x4d000004)), +// CHECK: ('word-1', 0x4d000005)), // CHECK: ]) // CHECK: ('_section_data', '\x04\x00\x00\x00\x04\x00\x00\x00') +// CHECK: # Section 2 +// CHECK: (('section_name', '__debug_frame\x00\x00\x00') +// CHECK: ('segment_name', '__DWARF\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('address', 189) +// CHECK: ('size', 16) +// CHECK: ('offset', 637) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 888) +// CHECK: ('num_reloc', 2) +// CHECK: ('flags', 0x2000000) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ('reserved3', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: # Relocation 0 +// CHECK: (('word-0', 0x8), +// CHECK: ('word-1', 0xe000004)), +// CHECK: # Relocation 1 +// CHECK: (('word-0', 0x0), +// CHECK: ('word-1', 0x6000001)), +// CHECK: ]) +// CHECK: ('_section_data', '\xad\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') // CHECK: ]) // CHECK: ), // CHECK: # Load Command 1 // CHECK: (('command', 2) // CHECK: ('size', 24) -// CHECK: ('symoff', 792) -// CHECK: ('nsyms', 5) -// CHECK: ('stroff', 872) -// CHECK: ('strsize', 32) -// CHECK: ('_string_data', '\x00_foobar\x00_foo\x00_baz\x00_bar\x00_prev\x00\x00\x00') +// CHECK: ('symoff', 904) +// CHECK: ('nsyms', 6) +// CHECK: ('stroff', 1000) +// CHECK: ('strsize', 40) +// CHECK: ('_string_data', '\x00_foobar\x00_ext_foo\x00_foo\x00_baz\x00_bar\x00_prev\x00\x00') // CHECK: ('_symbols', [ // CHECK: # Symbol 0 -// CHECK: (('n_strx', 9) +// CHECK: (('n_strx', 18) // CHECK: ('n_type', 0xe) // CHECK: ('n_sect', 1) // CHECK: ('n_desc', 0) @@ -204,7 +231,7 @@ L1: // CHECK: ('_string', '_foo') // CHECK: ), // CHECK: # Symbol 1 -// CHECK: (('n_strx', 14) +// CHECK: (('n_strx', 23) // CHECK: ('n_type', 0xe) // CHECK: ('n_sect', 1) // CHECK: ('n_desc', 0) @@ -212,7 +239,7 @@ L1: // CHECK: ('_string', '_baz') // CHECK: ), // CHECK: # Symbol 2 -// CHECK: (('n_strx', 19) +// CHECK: (('n_strx', 28) // CHECK: ('n_type', 0xe) // CHECK: ('n_sect', 1) // CHECK: ('n_desc', 0) @@ -220,7 +247,7 @@ L1: // CHECK: ('_string', '_bar') // CHECK: ), // CHECK: # Symbol 3 -// CHECK: (('n_strx', 24) +// CHECK: (('n_strx', 33) // CHECK: ('n_type', 0xe) // CHECK: ('n_sect', 1) // CHECK: ('n_desc', 0) @@ -228,6 +255,14 @@ L1: // CHECK: ('_string', '_prev') // CHECK: ), // CHECK: # Symbol 4 +// CHECK: (('n_strx', 9) +// CHECK: ('n_type', 0x1) +// CHECK: ('n_sect', 0) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 0) +// CHECK: ('_string', '_ext_foo') +// CHECK: ), +// CHECK: # Symbol 5 // CHECK: (('n_strx', 1) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) @@ -245,7 +280,7 @@ L1: // CHECK: ('iextdefsym', 4) // CHECK: ('nextdefsym', 0) // CHECK: ('iundefsym', 4) -// CHECK: ('nundefsym', 1) +// CHECK: ('nundefsym', 2) // CHECK: ('tocoff', 0) // CHECK: ('ntoc', 0) // CHECK: ('modtaboff', 0)