[llvm-dev] LLD invalid x86_64 Reference Kind

Rui Ueyama via llvm-dev llvm-dev at lists.llvm.org
Mon Aug 28 09:58:31 PDT 2017


On Sun, Aug 27, 2017 at 1:24 AM, Andrew Kelley <superjoe30 at gmail.com> wrote:

> This is release_50 branch. The LLVM IR file pasted at the bottom of this
> email causes LLD to hit unreachable. And this fixes it for me:
>
> diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
> b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
> index aee9959ca6b..efe23abb914 100644
> --- a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
> +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
> @@ -621,7 +621,7 @@ void ArchHandler_x86_64::applyFixupFinal(
>      // Fall into llvm_unreachable().
>      break;
>    }
> -  llvm_unreachable("invalid x86_64 Reference Kind");
> +  return;
>  }
>
>  void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref,
>
> Without this "fix":
> $ ~/local/llvm5/bin/clang -c test.ll
> $ ~/local/llvm5/bin/lld -flavor darwin -o test test.o -arch x86_64 -lSystem
> warning: -sdk_version is required when emitting min version load command.
> Setting sdk version to match provided min version
> invalid x86_64 Reference Kind
> UNREACHABLE executed at /Users/andy/Downloads/llvm-
> project/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp:624!
> 0  lld 0x0000000101730af5 llvm::sys::PrintStackTrace(llvm::raw_ostream&)
> + 37
> Stack dump:
> 0. Program arguments: /Users/andy/local/llvm5/bin/lld -flavor darwin -o
> test test.o -arch x86_64 -lSystem
> Abort trap: 6
>
> I understand that this is:
> 1. Not a satisfying fix to the underlying problem
> 2. The MACHO code in LLD is bit rotting right now and nobody cares about it
>

It seems both points were unfortunately true.

Even though I do not fully understand the issue, I can say that this fix is
not satisfactory as it just converts an llvm_unreachable for a
(theoretically) fully-covered switch to a return so that it won't raise a
runtime error instead of reporting that something's wrong. That may be
useful as a temporary workaround for your local repository, but I doubt we
really want to check this in to the main repository of lld because it is in
theory obviously incorrect thing to do.

That brings us to the point the second point that mach-o lld is not
maintained well. Virtually no active development has been made in the past
few years while there's maintenance cost associated with it, and it looks
like if you seriously attempt to try to use it, you are likely to hit some
issue. Perhaps we should start discussing to deprecate it if no one wants
to revive its development.


> Can we have it as a workaround until anyone is ready to take
> responsibility for this codebase?
>
> This makes all the Zig behavior tests pass on MacOS.
>
>
> test.ll:
> ; ModuleID = 'test'
> source_filename = "test"
> target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-apple-darwin-unknown"
>
> %"[]u8" = type { i8*, i64 }
>
> @__zig_panic_implementation_provided = internal unnamed_addr constant i1
> true, align 1
> @assert.1 = internal unnamed_addr constant void (i1)* @assert, align 8
> @is_test = internal unnamed_addr constant i1 false, align 1
> @0 = internal unnamed_addr constant i8* getelementptr inbounds ([24 x i8],
> [24 x i8]* @1, i64 0, i64 0), align 8
> @1 = internal unnamed_addr constant [24 x i8] c"reached unreachable code",
> align 16
> @2 = internal unnamed_addr constant { i8*, i64 } { i8* getelementptr
> inbounds ([24 x i8], [24 x i8]* @1, i64 0, i64 0), i64 24 }, align 8
> @3 = internal unnamed_addr constant i8* getelementptr inbounds ([17 x i8],
> [17 x i8]* @4, i64 0, i64 0), align 8
> @4 = internal unnamed_addr constant [17 x i8] c"assertion failure", align
> 16
> @5 = internal unnamed_addr constant { i8*, i64 } { i8* getelementptr
> inbounds ([17 x i8], [17 x i8]* @4, i64 0, i64 0), i64 17 }, align 8
>
> ; Function Attrs: nobuiltin nounwind sspstrong
> define internal fastcc void @assert(i1) unnamed_addr #0 !dbg !25 {
> Entry:
>   %ok = alloca i1, align 1
>   store i1 %0, i1* %ok
>   call void @llvm.dbg.declare(metadata i1* %ok, metadata !31, metadata
> !32), !dbg !33
>   %1 = load i1, i1* %ok, !dbg !34
>   %2 = icmp eq i1 %1, false, !dbg !37
>   br i1 %2, label %Then, label %Else, !dbg !37
>
> Then:                                             ; preds = %Entry
>   %3 = load i8*, i8** getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }*
> @2, i32 0, i32 0), !dbg !38
>   %4 = load i64, i64* getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }*
> @2, i32 0, i32 1), !dbg !38
>   call coldcc void @__zig_panic(i8* %3, i64 %4), !dbg !38
>   unreachable, !dbg !38
>
> Else:                                             ; preds = %Entry
>   br label %EndIf2, !dbg !41
>
> EndIf2:                                           ; preds = %Else
>   ret void, !dbg !42
> }
>
> ; Function Attrs: nobuiltin nounwind sspstrong
> define i32 @main(i32, i8** nonnull) #0 !dbg !43 {
> Entry:
>   %argc = alloca i32, align 4
>   %argv = alloca i8**, align 8
>   store i32 %0, i32* %argc
>   call void @llvm.dbg.declare(metadata i32* %argc, metadata !51, metadata
> !32), !dbg !54
>   store i8** %1, i8*** %argv
>   call void @llvm.dbg.declare(metadata i8*** %argv, metadata !52, metadata
> !32), !dbg !55
>   call fastcc void @nonConstSwitch(i3 2), !dbg !56
>   ret i32 0, !dbg !59
> }
>
> ; Function Attrs: cold nobuiltin noreturn nounwind
> define linkonce coldcc void @__zig_panic(i8* nonnull readonly, i64) #1
> !dbg !60 {
> Entry:
>   %2 = alloca %"[]u8", align 8
>   %message_ptr = alloca i8*, align 8
>   %message_len = alloca i64, align 8
>   store i8* %0, i8** %message_ptr
>   call void @llvm.dbg.declare(metadata i8** %message_ptr, metadata !67,
> metadata !32), !dbg !70
>   store i64 %1, i64* %message_len
>   call void @llvm.dbg.declare(metadata i64* %message_len, metadata !68,
> metadata !32), !dbg !71
>   %3 = load i64, i64* %message_len, !dbg !72
>   %4 = load i8*, i8** %message_ptr, !dbg !76
>   %5 = getelementptr inbounds %"[]u8", %"[]u8"* %2, i32 0, i32 0, !dbg !76
>   %6 = getelementptr inbounds i8, i8* %4, i64 0, !dbg !76
>   store i8* %6, i8** %5, !dbg !76
>   %7 = getelementptr inbounds %"[]u8", %"[]u8"* %2, i32 0, i32 1, !dbg !76
>   %8 = sub nsw i64 %3, 0, !dbg !76
>   store i64 %8, i64* %7, !dbg !76
>   call fastcc void @panic(%"[]u8"* byval %2), !dbg !77
>   unreachable, !dbg !77
> }
>
> ; Function Attrs: nobuiltin nounwind sspstrong
> define internal fastcc void @nonConstSwitch(i3) unnamed_addr #0 !dbg !78 {
> Entry:
>   %foo = alloca i3, align 1
>   %val = alloca i32, align 4
>   store i3 %0, i3* %foo
>   call void @llvm.dbg.declare(metadata i3* %foo, metadata !82, metadata
> !32), !dbg !87
>   %1 = load i3, i3* %foo, !dbg !88
>   switch i3 %1, label %SwitchElse [
>     i3 0, label %SwitchProng
>     i3 1, label %SwitchProng1
>     i3 2, label %SwitchProng2
>     i3 3, label %SwitchProng3
>   ], !dbg !88
>
> SwitchProng:                                      ; preds = %Entry
>   br label %SwitchEnd, !dbg !88
>
> SwitchProng1:                                     ; preds = %Entry
>   br label %SwitchEnd, !dbg !88
>
> SwitchProng2:                                     ; preds = %Entry
>   br label %SwitchEnd, !dbg !88
>
> SwitchProng3:                                     ; preds = %Entry
>   br label %SwitchEnd, !dbg !88
>
> SwitchElse:                                       ; preds = %Entry
>   %2 = load i8*, i8** getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }*
> @2, i32 0, i32 0), !dbg !88
>   %3 = load i64, i64* getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }*
> @2, i32 0, i32 1), !dbg !88
>   call coldcc void @__zig_panic(i8* %2, i64 %3), !dbg !88
>   unreachable, !dbg !88
>
> SwitchEnd:                                        ; preds = %SwitchProng3,
> %SwitchProng2, %SwitchProng1, %SwitchProng
>   %4 = phi i32 [ 1, %SwitchProng ], [ 2, %SwitchProng1 ], [ 3,
> %SwitchProng2 ], [ 4, %SwitchProng3 ], !dbg !88
>   store i32 %4, i32* %val, !dbg !89
>   call void @llvm.dbg.declare(metadata i32* %val, metadata !83, metadata
> !32), !dbg !89
>   %5 = load i32, i32* %val, !dbg !90
>   %6 = icmp eq i32 %5, 3, !dbg !92
>   call fastcc void @assert(i1 %6), !dbg !93
>   ret void, !dbg !94
> }
>
> ; Function Attrs: nobuiltin noreturn nounwind sspstrong
> define internal fastcc void @panic(%"[]u8"* byval nonnull readonly)
> unnamed_addr #2 !dbg !95 {
> Entry:
>   call void @llvm.dbg.declare(metadata %"[]u8"* %0, metadata !104,
> metadata !32), !dbg !105
>   br label %WhileCond, !dbg !106
>
> WhileCond:                                        ; preds = %WhileCond,
> %Entry
>   br label %WhileCond, !dbg !106
> }
>
> ; Function Attrs: nounwind readnone speculatable
> declare void @llvm.dbg.declare(metadata, metadata, metadata) #3
>
> ; Function Attrs: nounwind
> declare void @llvm.stackprotector(i8*, i8**) #4
>
> attributes #0 = { nobuiltin nounwind sspstrong
> "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
> "stack-protector-buffer-size"="4" }
> attributes #1 = { cold nobuiltin noreturn nounwind
> "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" }
> attributes #2 = { nobuiltin noreturn nounwind sspstrong
> "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
> "stack-protector-buffer-size"="4" }
> attributes #3 = { nounwind readnone speculatable }
> attributes #4 = { nounwind }
>
> !llvm.module.flags = !{!0}
> !llvm.dbg.cu = !{!1}
>
> !0 = !{i32 2, !"Debug Info Version", i32 3}
> !1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer:
> "zig 0.0.0", isOptimized: false, runtimeVersion: 0, emissionKind:
> FullDebug, enums: !3, globals: !19)
> !2 = !DIFile(filename: "test", directory: ".")
> !3 = !{!4, !12}
> !4 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "Foo", scope:
> !5, file: !5, line: 17, baseType: !6, size: 8, align: 8, elements: !7)
> !5 = !DIFile(filename: "test.zig", directory: "/Users/andy/dev/zig/build")
> !6 = !DIBasicType(name: "u3", size: 8, encoding: DW_ATE_unsigned)
> !7 = !{!8, !9, !10, !11}
> !8 = !DIEnumerator(name: "A", value: 0)
> !9 = !DIEnumerator(name: "B", value: 1)
> !10 = !DIEnumerator(name: "C", value: 2)
> !11 = !DIEnumerator(name: "D", value: 3)
> !12 = !DICompositeType(tag: DW_TAG_enumeration_type, name:
> "GlobalLinkage", scope: !13, file: !13, line: 138, baseType: !6, size: 8,
> align: 8, elements: !14)
> !13 = !DIFile(filename: "builtin.zig", directory:
> "/Users/andy/dev/zig/build/zig-cache")
> !14 = !{!15, !16, !17, !18}
> !15 = !DIEnumerator(name: "Internal", value: 0)
> !16 = !DIEnumerator(name: "Strong", value: 1)
> !17 = !DIEnumerator(name: "Weak", value: 2)
> !18 = !DIEnumerator(name: "LinkOnce", value: 3)
> !19 = !{!20, !23}
> !20 = !DIGlobalVariableExpression(var: !21)
> !21 = distinct !DIGlobalVariable(name: "__zig_panic_implementation_provided",
> linkageName: "__zig_panic_implementation_provided", scope: !13, file:
> !13, line: 201, type: !22, isLocal: true, isDefinition: true)
> !22 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean)
> !23 = !DIGlobalVariableExpression(var: !24)
> !24 = distinct !DIGlobalVariable(name: "is_test", linkageName: "is_test",
> scope: !13, file: !13, line: 194, type: !22, isLocal: true, isDefinition:
> true)
> !25 = distinct !DISubprogram(name: "assert", scope: !26, file: !26, line:
> 14, type: !27, isLocal: true, isDefinition: true, scopeLine: 14,
> isOptimized: false, unit: !1, variables: !30)
> !26 = !DIFile(filename: "debug.zig", directory: "/Users/andy/dev/zig/build/
> lib/zig/std")
> !27 = !DISubroutineType(types: !28)
> !28 = !{!29, !22}
> !29 = !DIBasicType(name: "void", encoding: DW_ATE_unsigned)
> !30 = !{!31}
> !31 = !DILocalVariable(name: "ok", arg: 1, scope: !25, file: !26, line:
> 14, type: !22)
> !32 = !DIExpression()
> !33 = !DILocation(line: 14, column: 15, scope: !25)
> !34 = !DILocation(line: 15, column: 10, scope: !35)
> !35 = distinct !DILexicalBlock(scope: !36, file: !26, line: 14, column: 25)
> !36 = distinct !DILexicalBlock(scope: !25, file: !26, line: 14, column: 15)
> !37 = !DILocation(line: 15, column: 9, scope: !35)
> !38 = !DILocation(line: 21, column: 13, scope: !39)
> !39 = distinct !DILexicalBlock(scope: !40, file: !26, line: 20, column: 16)
> !40 = distinct !DILexicalBlock(scope: !35, file: !26, line: 15, column: 14)
> !41 = !DILocation(line: 15, column: 5, scope: !35)
> !42 = !DILocation(line: 15, column: 5, scope: !36)
> !43 = distinct !DISubprogram(name: "main", scope: !5, file: !5, line: 4,
> type: !44, isLocal: false, isDefinition: true, scopeLine: 4, isOptimized:
> false, unit: !1, variables: !50)
> !44 = !DISubroutineType(types: !45)
> !45 = !{!46, !46, !47}
> !46 = !DIBasicType(name: "c_int", size: 32, encoding: DW_ATE_signed)
> !47 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&&u8", baseType:
> !48, size: 64, align: 64)
> !48 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&u8", baseType: !49,
> size: 64, align: 64)
> !49 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned_char)
> !50 = !{!51, !52}
> !51 = !DILocalVariable(name: "argc", arg: 1, scope: !43, file: !5, line:
> 4, type: !46)
> !52 = !DILocalVariable(name: "argv", arg: 2, scope: !53, file: !5, line:
> 4, type: !47)
> !53 = distinct !DILexicalBlock(scope: !43, file: !5, line: 4, column: 16)
> !54 = !DILocation(line: 4, column: 16, scope: !43)
> !55 = !DILocation(line: 4, column: 29, scope: !53)
> !56 = !DILocation(line: 5, column: 19, scope: !57)
> !57 = distinct !DILexicalBlock(scope: !58, file: !5, line: 4, column: 50)
> !58 = distinct !DILexicalBlock(scope: !53, file: !5, line: 4, column: 29)
> !59 = !DILocation(line: 6, column: 5, scope: !57)
> !60 = distinct !DISubprogram(name: "__zig_panic", scope: !61, file: !61,
> line: 7, type: !62, isLocal: false, isDefinition: true, scopeLine: 7,
> isOptimized: false, unit: !1, variables: !66)
> !61 = !DIFile(filename: "zigrt.zig", directory: "/Users/andy/dev/zig/build/
> lib/zig/std/special")
> !62 = !DISubroutineType(types: !63)
> !63 = !{!29, !64, !65}
> !64 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&const u8",
> baseType: !49, size: 64, align: 64)
> !65 = !DIBasicType(name: "usize", size: 64, encoding: DW_ATE_unsigned)
> !66 = !{!67, !68}
> !67 = !DILocalVariable(name: "message_ptr", arg: 1, scope: !60, file: !61,
> line: 7, type: !64)
> !68 = !DILocalVariable(name: "message_len", arg: 2, scope: !69, file: !61,
> line: 7, type: !65)
> !69 = distinct !DILexicalBlock(scope: !60, file: !61, line: 7, column: 30)
> !70 = !DILocation(line: 7, column: 30, scope: !60)
> !71 = !DILocation(line: 7, column: 54, scope: !69)
> !72 = !DILocation(line: 12, column: 48, scope: !73)
> !73 = distinct !DILexicalBlock(scope: !74, file: !61, line: 11, column: 54)
> !74 = distinct !DILexicalBlock(scope: !75, file: !61, line: 7, column: 86)
> !75 = distinct !DILexicalBlock(scope: !69, file: !61, line: 7, column: 54)
> !76 = !DILocation(line: 12, column: 43, scope: !73)
> !77 = !DILocation(line: 12, column: 31, scope: !73)
> !78 = distinct !DISubprogram(name: "nonConstSwitch", scope: !5, file: !5,
> line: 8, type: !79, isLocal: true, isDefinition: true, scopeLine: 8,
> isOptimized: false, unit: !1, variables: !81)
> !79 = !DISubroutineType(types: !80)
> !80 = !{!29, !4}
> !81 = !{!82, !83}
> !82 = !DILocalVariable(name: "foo", arg: 1, scope: !78, file: !5, line: 8,
> type: !4)
> !83 = !DILocalVariable(name: "val", scope: !84, file: !5, line: 9, type:
> !86)
> !84 = distinct !DILexicalBlock(scope: !85, file: !5, line: 8, column: 29)
> !85 = distinct !DILexicalBlock(scope: !78, file: !5, line: 8, column: 19)
> !86 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed)
> !87 = !DILocation(line: 8, column: 19, scope: !78)
> !88 = !DILocation(line: 9, column: 17, scope: !84)
> !89 = !DILocation(line: 9, column: 5, scope: !84)
> !90 = !DILocation(line: 15, column: 12, scope: !91)
> !91 = distinct !DILexicalBlock(scope: !84, file: !5, line: 9, column: 5)
> !92 = !DILocation(line: 15, column: 16, scope: !91)
> !93 = !DILocation(line: 15, column: 11, scope: !91)
> !94 = !DILocation(line: 8, column: 29, scope: !85)
> !95 = distinct !DISubprogram(name: "panic", scope: !5, file: !5, line: 1,
> type: !96, isLocal: true, isDefinition: true, scopeLine: 1, isOptimized:
> false, unit: !1, variables: !103)
> !96 = !DISubroutineType(types: !97)
> !97 = !{!29, !98}
> !98 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&const []const u8",
> baseType: !99, size: 64, align: 64)
> !99 = !DICompositeType(tag: DW_TAG_structure_type, name: "[]u8", size:
> 128, align: 128, elements: !100)
> !100 = !{!101, !102}
> !101 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !99,
> baseType: !48, size: 64, align: 64)
> !102 = !DIDerivedType(tag: DW_TAG_member, name: "len", scope: !99,
> baseType: !65, size: 64, align: 64, offset: 64)
> !103 = !{!104}
> !104 = !DILocalVariable(name: "msg", arg: 1, scope: !95, file: !5, line:
> 1, type: !99)
> !105 = !DILocation(line: 1, column: 14, scope: !95)
> !106 = !DILocation(line: 1, column: 45, scope: !107)
> !107 = distinct !DILexicalBlock(scope: !108, file: !5, line: 1, column: 43)
> !108 = distinct !DILexicalBlock(scope: !95, file: !5, line: 1, column: 14)
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170828/300398e3/attachment-0001.html>


More information about the llvm-dev mailing list