diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h --- a/lld/MachO/SyntheticSections.h +++ b/lld/MachO/SyntheticSections.h @@ -382,9 +382,12 @@ uint64_t getRawSize() const override { return size; } void writeTo(uint8_t *buf) const override; + static constexpr size_t EMPTY_STRING_INDEX = 1; + private: // ld64 emits string tables which start with a space and a zero byte. We // match its behavior here since some tools depend on it. + // Consequently, the empty string will be at index 1, not zero. std::vector strings{" "}; size_t size = 2; }; @@ -396,7 +399,7 @@ struct StabsEntry { uint8_t type = 0; - uint32_t strx = 0; + uint32_t strx = StringTableSection::EMPTY_STRING_INDEX; uint8_t sect = 0; uint16_t desc = 0; uint64_t value = 0; diff --git a/lld/test/MachO/stabs.s b/lld/test/MachO/stabs.s --- a/lld/test/MachO/stabs.s +++ b/lld/test/MachO/stabs.s @@ -10,23 +10,23 @@ # RUN: llvm-ar rcsU %t/foo.a %t/foo.o # RUN: %lld -lSystem %t/test.o %t/foo.o %t/no-debug.o -o %t/test -# RUN: (llvm-objdump --section-headers %t/test; llvm-nm -pa %t/test) | \ +# RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ # RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.o ## Check that we emit the right modtime even when the object file is in an ## archive. # RUN: %lld -lSystem %t/test.o %t/foo.a %t/no-debug.o -o %t/test -# RUN: (llvm-objdump --section-headers %t/test; llvm-nm -pa %t/test) | \ +# RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ # RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\) ## Check that we emit absolute paths to the object files in our OSO entries ## even if our inputs are relative paths. # RUN: cd %t && %lld -lSystem test.o foo.o no-debug.o -o test -# RUN: (llvm-objdump --section-headers %t/test; llvm-nm -pa %t/test) | \ +# RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ # RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.o # RUN: cd %t && %lld -lSystem test.o foo.a no-debug.o -o %t/test -# RUN: (llvm-objdump --section-headers %t/test; llvm-nm -pa %t/test) | \ +# RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ # RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\) # CHECK: Sections: @@ -37,46 +37,48 @@ # CHECK-NEXT: [[#COMM_ID:]] __common # CHECK-NEXT: [[#MORE_TEXT_ID:]] more_text -# CHECK: 0000000000000000 - 00 0000 SO /tmp/test.cpp -# CHECK-NEXT: 0000000000000010 - 03 0001 OSO [[DIR]]/test.o -# CHECK-NEXT: [[#%x, STATIC:]] - 0[[#MORE_DATA_ID + 1]] 0000 STSYM _static_var -# CHECK-NEXT: [[#%x, MAIN:]] - 0[[#TEXT_ID + 1]] 0000 FUN _main -# CHECK-NEXT: 0000000000000006 - 00 0000 FUN -# CHECK-NEXT: [[#%x, BAR:]] - 0[[#TEXT_ID + 1]] 0000 FUN _bar -# CHECK-NEXT: 0000000000000000 - 00 0000 FUN -# CHECK-NEXT: [[#%x, BAR2:]] - 0[[#TEXT_ID + 1]] 0000 FUN _bar2 -# CHECK-NEXT: 0000000000000001 - 00 0000 FUN -# CHECK-NEXT: [[#%x, BAZ:]] - 0[[#TEXT_ID + 1]] 0000 FUN _baz -# CHECK-NEXT: 0000000000000000 - 00 0000 FUN -# CHECK-NEXT: [[#%x, BAZ2:]] - 0[[#TEXT_ID + 1]] 0000 FUN _baz -# CHECK-NEXT: 0000000000000002 - 00 0000 FUN -# CHECK-NEXT: [[#%x, QUX:]] - 0[[#TEXT_ID + 1]] 0000 FUN _qux -# CHECK-NEXT: 0000000000000003 - 00 0000 FUN -# CHECK-NEXT: [[#%x, QUUX:]] - 0[[#TEXT_ID + 1]] 0000 FUN _quux -# CHECK-NEXT: 0000000000000004 - 00 0000 FUN -# CHECK-NEXT: [[#%x, GLOB:]] - 0[[#DATA_ID + 1]] 0000 GSYM _global_var -# CHECK-NEXT: [[#%x, ZERO:]] - 0[[#COMM_ID + 1]] 0000 GSYM _zero -# CHECK-NEXT: [[#%x, FUN:]] - 0[[#MORE_TEXT_ID + 1]] 0000 FUN _fun -# CHECK-NEXT: 0000000000000001 - 00 0000 FUN -# CHECK-NEXT: 0000000000000000 - 01 0000 SO -# CHECK-NEXT: 0000000000000000 - 00 0000 SO /foo.cpp -# CHECK-NEXT: 0000000000000020 - 03 0001 OSO [[FOO_PATH]] -# CHECK-NEXT: [[#%x, FOO:]] - 0[[#TEXT_ID + 1]] 0000 FUN _foo -# CHECK-NEXT: 0000000000000001 - 00 0000 FUN -# CHECK-NEXT: 0000000000000000 - 01 0000 SO -# CHECK-DAG: [[#STATIC]] s _static_var -# CHECK-DAG: [[#MAIN]] T _main -# CHECK-DAG: {{[0-9af]+}} A _abs -# CHECK-DAG: [[#BAR]] T _bar -# CHECK-DAG: [[#BAR2]] T _bar2 -# CHECK-DAG: [[#BAZ]] T _baz -# CHECK-DAG: [[#BAZ2]] T _baz2 -# CHECK-DAG: [[#FUN]] S _fun -# CHECK-DAG: [[#GLOB]] D _global_var -# CHECK-DAG: [[#ZERO]] S _zero -# CHECK-DAG: [[#FOO]] T _foo -# CHECK-DAG: {{[0-9af]+}} T _no_debug -# CHECK-DAG: {{0+}} A __mh_execute_header +# CHECK: (N_SO ) 00 0000 0000000000000000 '/tmp/test.cpp' +# CHECK-NEXT: (N_OSO ) 03 0001 0000000000000010 '[[DIR]]/test.o' +# CHECK-NEXT: (N_STSYM ) [[#%.2d,MORE_DATA_ID + 1]] 0000 [[#%.16x,STATIC:]] '_static_var' +# CHECK-NEXT: (N_FUN ) [[#%.2d,TEXT_ID + 1]] 0000 [[#%.16x,MAIN:]] '_main' +# CHECK-NEXT: (N_FUN ) 00 0000 0000000000000006{{$}} +# CHECK-NEXT: (N_FUN ) [[#%.2d,TEXT_ID + 1]] 0000 [[#%.16x,BAR:]] '_bar' +# CHECK-NEXT: (N_FUN ) 00 0000 0000000000000000{{$}} +# CHECK-NEXT: (N_FUN ) [[#%.2d,TEXT_ID + 1]] 0000 [[#%.16x,BAR2:]] '_bar2' +# CHECK-NEXT: (N_FUN ) 00 0000 0000000000000001{{$}} +# CHECK-NEXT: (N_FUN ) [[#%.2d,TEXT_ID + 1]] 0000 [[#%.16x,BAZ:]] '_baz' +# CHECK-NEXT: (N_FUN ) 00 0000 0000000000000000{{$}} +# CHECK-NEXT: (N_FUN ) [[#%.2d,TEXT_ID + 1]] 0000 [[#%.16x,BAZ2:]] '_baz2' +# CHECK-NEXT: (N_FUN ) 00 0000 0000000000000002{{$}} +# CHECK-NEXT: (N_FUN ) [[#%.2d,TEXT_ID + 1]] 0000 [[#%.16x,QUX:]] '_qux' +# CHECK-NEXT: (N_FUN ) 00 0000 0000000000000003{{$}} +# CHECK-NEXT: (N_FUN ) [[#%.2d,TEXT_ID + 1]] 0000 [[#%.16x,QUUX:]] '_quux' +# CHECK-NEXT: (N_FUN ) 00 0000 0000000000000004{{$}} +# CHECK-NEXT: (N_GSYM ) [[#%.2d,DATA_ID + 1]] 0000 [[#%.16x,GLOB:]] '_global_var' +# CHECK-NEXT: (N_GSYM ) [[#%.2d,COMM_ID + 1]] 0000 [[#%.16x,ZERO:]] '_zero' +# CHECK-NEXT: (N_FUN ) [[#%.2d,MORE_TEXT_ID + 1]] 0000 [[#%.16x,FUN:]] '_fun' +# CHECK-NEXT: (N_FUN ) 00 0000 0000000000000001{{$}} +# CHECK-NEXT: (N_SO ) 01 0000 0000000000000000{{$}} +# CHECK-NEXT: (N_SO ) 00 0000 0000000000000000 '/foo.cpp' +# CHECK-NEXT: (N_OSO ) 03 0001 0000000000000020 '[[FOO_PATH]]' +# CHECK-NEXT: (N_FUN ) [[#%.2d,TEXT_ID + 1]] 0000 [[#%.16x,FOO:]] '_foo' +# CHECK-NEXT: (N_FUN ) 00 0000 0000000000000001{{$}} +# CHECK-NEXT: (N_SO ) 01 0000 0000000000000000{{$}} +# CHECK-DAG: ( SECT ) [[#%.2d,MORE_DATA_ID + 1]] 0000 [[#STATIC]] '_static_var' +# CHECK-DAG: ( SECT EXT) [[#%.2d,TEXT_ID + 1]] 0000 [[#MAIN]] '_main' +# CHECK-DAG: ( ABS EXT) 00 0000 {{[0-9af]+}} '_abs' +# CHECK-DAG: ( SECT EXT) [[#%.2d,TEXT_ID + 1]] 0000 [[#FOO]] '_foo' +# CHECK-DAG: ( SECT EXT) [[#%.2d,TEXT_ID + 1]] 0000 [[#BAR]] '_bar' +# CHECK-DAG: ( SECT EXT) [[#%.2d,TEXT_ID + 1]] 0000 [[#BAR2]] '_bar2' +# CHECK-DAG: ( SECT EXT) [[#%.2d,TEXT_ID + 1]] 0000 [[#BAZ]] '_baz' +# CHECK-DAG: ( SECT EXT) [[#%.2d,TEXT_ID + 1]] 0000 [[#BAZ2]] '_baz2' +# CHECK-DAG: ( SECT EXT) [[#%.2d,TEXT_ID + 1]] 0000 [[#QUX]] '_qux' +# CHECK-DAG: ( SECT EXT) [[#%.2d,TEXT_ID + 1]] 0000 [[#QUUX]] '_quux' +# CHECK-DAG: ( SECT EXT) [[#%.2d,DATA_ID + 1]] 0000 [[#GLOB]] '_global_var' +# CHECK-DAG: ( SECT EXT) [[#%.2d,COMM_ID + 1]] 0000 [[#ZERO]] '_zero' +# CHECK-DAG: ( SECT EXT) [[#%.2d,MORE_TEXT_ID + 1]] 0000 [[#FUN]] '_fun' +# CHECK-DAG: ( SECT EXT) [[#%.2d,TEXT_ID + 1]] 0000 {{[0-9a-f]+}} '_no_debug' +# CHECK-DAG: ( {{.*}}) {{[0-9]+}} 0000 {{[0-9a-f]+}} '__mh_execute_header' # CHECK-EMPTY: ## Check that we don't attempt to emit rebase opcodes for the debug sections