diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index 194be6e4713..e073eb5a0d4 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -612,9 +612,16 @@ public: } } } else { - if (Modifier == MCSymbolRefExpr::VK_GOT) + if (Modifier == MCSymbolRefExpr::VK_GOT) { Type = RIT_X86_64_GOT; - else if (Modifier != MCSymbolRefExpr::VK_None) + } else if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) { + // GOTPCREL is allowed as a modifier on non-PCrel instructions, in + // which case all we do is set the PCrel bit in the relocation entry; + // this is used with exception handling, for example. The source is + // required to include any necessary offset directly. + Type = RIT_X86_64_GOT; + IsPCRel = 1; + } else if (Modifier != MCSymbolRefExpr::VK_None) llvm_report_error("unsupported symbol modifier in relocation"); else Type = RIT_X86_64_Unsigned; diff --git a/test/MC/MachO/darwin-x86_64-reloc.s b/test/MC/MachO/darwin-x86_64-reloc.s index 6b325b085ec..d5e75d12145 100644 --- a/test/MC/MachO/darwin-x86_64-reloc.s +++ b/test/MC/MachO/darwin-x86_64-reloc.s @@ -38,25 +38,29 @@ L_pc: L1: .quad L1 - _prev + .data +.long _foobar@GOTPCREL+4 +.long _foo@GOTPCREL+4 + // CHECK: ('cputype', 16777223) // CHECK: ('cpusubtype', 3) // CHECK: ('filetype', 1) // CHECK: ('num_load_commands', 1) -// CHECK: ('load_commands_size', 256) +// CHECK: ('load_commands_size', 336) // CHECK: ('flag', 0) // CHECK: ('reserved', 0) // CHECK: ('load_commands', [ // CHECK: # Load Command 0 // CHECK: (('command', 25) -// CHECK: ('size', 152) +// CHECK: ('size', 232) // 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', 181) -// CHECK: ('file_offset', 288) -// CHECK: ('file_size', 181) +// CHECK: ('vm_size', 189) +// CHECK: ('file_offset', 368) +// CHECK: ('file_size', 189) // CHECK: ('maxprot', 7) // CHECK: ('initprot', 7) -// CHECK: ('num_sections', 1) +// CHECK: ('num_sections', 2) // CHECK: ('flags', 0) // CHECK: ('sections', [ // CHECK: # Section 0 @@ -64,9 +68,9 @@ L1: // CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') // CHECK: ('address', 0) // CHECK: ('size', 181) -// CHECK: ('offset', 288) +// CHECK: ('offset', 368) // CHECK: ('alignment', 0) -// CHECK: ('reloc_offset', 472) +// CHECK: ('reloc_offset', 560) // CHECK: ('num_reloc', 27) // CHECK: ('flags', 0x80000400) // CHECK: ('reserved1', 0) @@ -157,19 +161,42 @@ L1: // CHECK: ('word-1', 0x2d000000)), // CHECK: ]) // CHECK: ('_section_data', '\xc3\xe8\x00\x00\x00\x00\xe8\x04\x00\x00\x00H\x8b\x05\x00\x00\x00\x00\xff5\x00\x00\x00\x00\x8b\x05\x00\x00\x00\x00\x8b\x05\x04\x00\x00\x00\xc6\x05\xff\xff\xff\xff\x12\xc7\x05\xfc\xff\xff\xffxV4\x12\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x8d\x05,\x00\x00\x00H\x8d\x05\x14\x00\x00\x00\x83\x05\x13\x00\x00\x00\x06f\x81\x05\x12\x00\x00\x00\xf4\x01\x81\x05\x10\x00\x00\x00\xf4\x01\x00\x00\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90,\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\xe4\xff\xff\xff\xff\xff\xff\xff\xd4\xff\xff\xff\xff\xff\xff\xff,\x00\x00\x00\x00\x00\x00\x00') +// 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', 181) +// CHECK: ('size', 8) +// CHECK: ('offset', 549) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 776) +// CHECK: ('num_reloc', 2) +// CHECK: ('flags', 0x0) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ('reserved3', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: # Relocation 0 +// CHECK: (('word-0', 0x4), +// CHECK: ('word-1', 0x4d000000)), +// CHECK: # Relocation 1 +// CHECK: (('word-0', 0x0), +// CHECK: ('word-1', 0x4d000004)), +// CHECK: ]) +// CHECK: ('_section_data', '\x04\x00\x00\x00\x04\x00\x00\x00') // CHECK: ]) // CHECK: ), // CHECK: # Load Command 1 // CHECK: (('command', 2) // CHECK: ('size', 24) -// CHECK: ('symoff', 688) -// CHECK: ('nsyms', 4) -// CHECK: ('stroff', 752) -// CHECK: ('strsize', 24) -// CHECK: ('_string_data', '\x00_foo\x00_baz\x00_bar\x00_prev\x00\x00\x00') +// 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: ('_symbols', [ // CHECK: # Symbol 0 -// CHECK: (('n_strx', 1) +// CHECK: (('n_strx', 9) // CHECK: ('n_type', 0xe) // CHECK: ('n_sect', 1) // CHECK: ('n_desc', 0) @@ -177,7 +204,7 @@ L1: // CHECK: ('_string', '_foo') // CHECK: ), // CHECK: # Symbol 1 -// CHECK: (('n_strx', 6) +// CHECK: (('n_strx', 14) // CHECK: ('n_type', 0xe) // CHECK: ('n_sect', 1) // CHECK: ('n_desc', 0) @@ -185,7 +212,7 @@ L1: // CHECK: ('_string', '_baz') // CHECK: ), // CHECK: # Symbol 2 -// CHECK: (('n_strx', 11) +// CHECK: (('n_strx', 19) // CHECK: ('n_type', 0xe) // CHECK: ('n_sect', 1) // CHECK: ('n_desc', 0) @@ -193,13 +220,21 @@ L1: // CHECK: ('_string', '_bar') // CHECK: ), // CHECK: # Symbol 3 -// CHECK: (('n_strx', 16) +// CHECK: (('n_strx', 24) // CHECK: ('n_type', 0xe) // CHECK: ('n_sect', 1) // CHECK: ('n_desc', 0) // CHECK: ('n_value', 129) // CHECK: ('_string', '_prev') // CHECK: ), +// CHECK: # Symbol 4 +// CHECK: (('n_strx', 1) +// CHECK: ('n_type', 0x1) +// CHECK: ('n_sect', 0) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 0) +// CHECK: ('_string', '_foobar') +// CHECK: ), // CHECK: ]) // CHECK: ), // CHECK: # Load Command 2 @@ -210,7 +245,7 @@ L1: // CHECK: ('iextdefsym', 4) // CHECK: ('nextdefsym', 0) // CHECK: ('iundefsym', 4) -// CHECK: ('nundefsym', 0) +// CHECK: ('nundefsym', 1) // CHECK: ('tocoff', 0) // CHECK: ('ntoc', 0) // CHECK: ('modtaboff', 0)