From 693ce239c666825233853e94f06ae776aa8f63b8 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sat, 11 Nov 2023 14:16:36 +0100 Subject: [PATCH] Explore linux behaviour when grabbing stack. --- .github/workflows/main.yml | 1 + lib/std/os/linux/linux.c3 | 200 ++++++++++++++++++ lib/std/os/macos/darwin.c3 | 9 +- lib/std/os/subprocess.c3 | 7 + resources/linux_stack.c3 | 14 ++ src/compiler/linker.c | 8 + src/compiler/llvm_codegen_module.c | 1 + .../concurrency/atomic_load_store_debug.c3t | 135 ++++++------ test/test_suite/debug_symbols/constants.c3t | 33 +-- .../debug_symbols/constants_mingw.c3t | 34 ++- 10 files changed, 336 insertions(+), 106 deletions(-) create mode 100644 lib/std/os/linux/linux.c3 create mode 100644 resources/linux_stack.c3 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a8c4196ad..d43a42868 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -264,6 +264,7 @@ jobs: ../build/c3c compile-run examples/load_world.c3 ../build/c3c compile-run examples/process.c3 ../build/c3c compile-run examples/ls.c3 + ../build/c3c compile-run linux_stack.c3 - name: Compile run unit tests run: | diff --git a/lib/std/os/linux/linux.c3 b/lib/std/os/linux/linux.c3 new file mode 100644 index 000000000..318a963dc --- /dev/null +++ b/lib/std/os/linux/linux.c3 @@ -0,0 +1,200 @@ +module std::os::linux @if(env::LINUX); +import libc; +import std::os::posix; +import std::io; +import std::collections::list; + +extern fn isz readlink(ZString path, char* buf, usz bufsize); + +def BacktraceList = List(); + +const PT_PHDR = 6; +const EI_NIDENT = 16; +def Elf32_Half = ushort; +def Elf32_Word = uint; +def Elf32_Addr = uint; +def Elf32_Off = uint; + +struct Elf32_Ehdr +{ + char[EI_NIDENT] e_ident; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} + +struct Elf32_Phdr +{ + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} + +def Elf64_Addr = ulong; +def Elf64_Half = ushort; +def Elf64_Off = ulong; +def Elf64_Word = uint; +def Elf64_Sword = int; +def Elf64_Sxword = long; +def Elf64_Lword = ulong; +def Elf64_Xword = ulong; + +struct Elf64_Ehdr +{ + char[EI_NIDENT] e_ident; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} + +struct Elf64_Phdr +{ + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; + Elf64_Xword p_memsz; + Elf64_Xword p_align; +} + +extern fn CInt dladdr(void* addr, Linux_Dl_info* info); + +struct Linux_Dl_info +{ + ZString dli_fname; /* Pathname of shared object */ + void* dli_fbase; /* Base address of shared object */ + ZString dli_sname; /* Name of nearest symbol */ + void* dli_saddr; /* Address of nearest symbol */ +} + +fn ulong! elf_module_image_base(String path) @local +{ + File file = file::open(path, "rb")!; + defer (void)file.close(); + char[4] buffer; + io::read_all(&file, &buffer)!; + if (buffer != char[4]{ 0x7f, 'E', 'L', 'F'}) return BacktraceFault.IMAGE_NOT_FOUND?; + bool is_64 = file.read_byte()! == 2; + bool is_little_endian = file.read_byte()! == 1; + // Actually, not supported. + if (!is_little_endian) return BacktraceFault.IMAGE_NOT_FOUND?; + file.seek(0)!; + if (is_64) + { + Elf64_Ehdr file_header; + io::read_any(&file, &file_header)!; + if (file_header.e_ehsize != Elf64_Ehdr.sizeof) return BacktraceFault.IMAGE_NOT_FOUND?; + for (isz i = 0; i < file_header.e_phnum; i++) + { + Elf64_Phdr header; + file.seek((usz)file_header.e_phoff + (usz)file_header.e_phentsize * i)!; + io::read_any(&file, &header)!; + if (header.p_type == PT_PHDR) return header.p_vaddr - header.p_offset; + } + return 0; + } + Elf32_Ehdr file_header; + io::read_any(&file, &file_header)!; + if (file_header.e_ehsize != Elf32_Ehdr.sizeof) return BacktraceFault.IMAGE_NOT_FOUND?; + for (isz i = 0; i < file_header.e_phnum; i++) + { + Elf32_Phdr header; + file.seek(file_header.e_phoff + (usz)file_header.e_phentsize * i)!; + io::read_any(&file, &header)!; + if (header.p_type == PT_PHDR) return (ulong)header.p_vaddr - header.p_offset; + } + return 0; +} + +fn Backtrace! backtrace_load_element(void* addr, Allocator* allocator = mem::heap()) @local +{ + @pool(allocator) + { + if (!addr) return backtrace::BACKTRACE_UNKNOWN; + char[] buf = mem::temp_array(char, 1024); + Linux_Dl_info info; + if (dladdr(addr, &info) == 0) return backtrace::BACKTRACE_UNKNOWN; + void* obj_address = addr - (uptr)info.dli_fbase + (uptr)elf_module_image_base(info.dli_fname.str_view())!; + ZString obj_path = info.dli_fname; + String s = process::execute_stdout_to_buffer(buf, { "addr2line", "-p", "-i", "-C", "-f", "-e", obj_path.str_view(), string::tformat("0x%x", obj_address) })!; + io::printfn("Result: [%s]", s); + String[] parts = s.tsplit(" at "); + if (parts.len != 2) + { + return { + .function = info.dli_sname ? info.dli_sname.copy(allocator) : "???".copy(allocator), + .object_file = info.dli_fname.copy(allocator), + .offset = (uptr)addr, + .file = "".copy(allocator), + .line = 0 + }; + } + uint line = 0; + String source = ""; + if (!parts[1].contains("?") && parts[1].contains(":")) + { + usz index = parts[1].rindex_of_char(':')!; + source = parts[1][:index]; + line = parts[1][index + 1..].to_uint()!; + } + return { + .function = parts[0].copy(allocator), + .object_file = info.dli_fname.copy(allocator), + .file = source.copy(allocator), + .line = line, + .allocator = allocator + }; + }; +} + +fn BacktraceList! backtrace_load(Allocator* allocator) +{ + void*[256] bt_buffer; + CInt size = posix::backtrace(&bt_buffer, 256); + BacktraceList list; + list.init_new(size, allocator); + defer catch + { + foreach (trace : list) + { + trace.free(); + } + list.free(); + } + @pool(allocator) + { + for (usz i = 1; i < size; i++) + { + Backtrace trace = backtrace_load_element(bt_buffer[i], allocator)!; + list.append(trace); + } + }; + return list; +} diff --git a/lib/std/os/macos/darwin.c3 b/lib/std/os/macos/darwin.c3 index 28b164a08..d8f6fb302 100644 --- a/lib/std/os/macos/darwin.c3 +++ b/lib/std/os/macos/darwin.c3 @@ -101,15 +101,12 @@ fn Backtrace! backtrace_load_element(String execpath, void* buffer, void* load_a { if (buffer) { - SubProcess process = process::create({ "atos", - "-o", execpath, "-arch", env::AARCH64 ? "arm64" : "x86_64", "-l", + char* buf = tmalloc(1024); + String s = process::execute_stdout_to_buffer(buf[:1024], + { "atos", "-o", execpath, "-arch", env::AARCH64 ? "arm64" : "x86_64", "-l", string::tformat("%p", load_address), string::tformat("%p", buffer), "-fullPath" })!; - process.join()!; - char* buf = tmalloc(1024); - usz len = process.read_stdout(buf, 1024)!; - String s = (String)buf[:len - 1]; String[] parts = s.tsplit(" "); if (parts.len == 4) { diff --git a/lib/std/os/subprocess.c3 b/lib/std/os/subprocess.c3 index 0305a6856..aac929d76 100644 --- a/lib/std/os/subprocess.c3 +++ b/lib/std/os/subprocess.c3 @@ -269,6 +269,13 @@ fn ZString* tcopy_env(String[] environment) @local @inline @if(env::POSIX) return copy; } +fn String! execute_stdout_to_buffer(char[] buffer, String[] command_line, SubProcessOptions options = {}, String[] environment = {}) +{ + SubProcess process = process::create(command_line, options, environment)!; + process.join()!; + usz len = process.read_stdout(buffer.ptr, buffer.len)!; + return (String)buffer[:len - 1]; +} /** * @require !environment || !options.inherit_environment diff --git a/resources/linux_stack.c3 b/resources/linux_stack.c3 new file mode 100644 index 000000000..fcf56d883 --- /dev/null +++ b/resources/linux_stack.c3 @@ -0,0 +1,14 @@ +module test; +import std::io; +import std::collections::map; +import std::os; + +fn void! main() +{ + int x = 2; + BacktraceList list = linux::backtrace_load(mem::heap())!; + foreach (Backtrace trace : list) + { + io::printfn(">%s", trace); + } +} \ No newline at end of file diff --git a/src/compiler/linker.c b/src/compiler/linker.c index 8e487f82c..572789b21 100644 --- a/src/compiler/linker.c +++ b/src/compiler/linker.c @@ -386,9 +386,17 @@ static void linker_setup_linux(const char ***args_ref, LinkerType linker_type) { if (linker_type == LINKER_CC) { + if (active_target.debug_info == DEBUG_INFO_FULL) + { + add_arg("-rdynamic"); + } add_arg("-pthread"); return; } + if (active_target.debug_info == DEBUG_INFO_FULL) + { + add_arg("-export-dynamic"); + } if (is_no_pie(platform_target.reloc_model)) add_arg("-no-pie"); if (is_pie(platform_target.reloc_model)) add_arg("-pie"); if (platform_target.arch == ARCH_TYPE_X86_64) add_arg("--eh-frame-hdr"); diff --git a/src/compiler/llvm_codegen_module.c b/src/compiler/llvm_codegen_module.c index 44cc3e233..af98fd6a2 100644 --- a/src/compiler/llvm_codegen_module.c +++ b/src/compiler/llvm_codegen_module.c @@ -152,6 +152,7 @@ void gencontext_begin_module(GenContext *c) { llvm_set_module_flag(c, LLVMModuleFlagBehaviorWarning, "Dwarf Version", 4, type_uint); llvm_set_module_flag(c, LLVMModuleFlagBehaviorWarning, "Debug Info Version", 3, type_uint); + llvm_set_module_flag(c, LLVMModuleFlagBehaviorWarning, "frame-pointer", 2, type_uint); } llvm_set_module_flag(c, LLVMModuleFlagBehaviorError, "uwtable", 2, type_uint); diff --git a/test/test_suite/concurrency/atomic_load_store_debug.c3t b/test/test_suite/concurrency/atomic_load_store_debug.c3t index 2d84859e4..9f8f2a779 100644 --- a/test/test_suite/concurrency/atomic_load_store_debug.c3t +++ b/test/test_suite/concurrency/atomic_load_store_debug.c3t @@ -22,43 +22,44 @@ fn void main() /* #expect: test.ll %.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] } %"any*" = type { ptr, i64 } + @"$ct.test.Ghh" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 12, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 @.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1 @"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 -define void @test.main() #0 !dbg !5 { +define void @test.main() #0 !dbg !6 { entry: %a = alloca i32, align 4 %x = alloca i32, align 4 %y = alloca i32, align 4 %varargslots = alloca [1 x %"any*"], align 16 %retparam = alloca i64, align 8 - call void @llvm.dbg.declare(metadata ptr %a, metadata !9, metadata !DIExpression()), !dbg !11 - store i32 111, ptr %a, align 4, !dbg !12 - call void @llvm.dbg.declare(metadata ptr %x, metadata !13, metadata !DIExpression()), !dbg !14 - %0 = load atomic i32, ptr %a seq_cst, align 4, !dbg !15 - store i32 %0, ptr %x, align 4, !dbg !15 - call void @llvm.dbg.declare(metadata ptr %y, metadata !18, metadata !DIExpression()), !dbg !19 - %1 = load atomic volatile i32, ptr %a monotonic, align 4, !dbg !20 - store i32 %1, ptr %y, align 4, !dbg !20 - %2 = load i32, ptr %x, align 4, !dbg !22 - %add = add i32 123, %2, !dbg !23 - store atomic i32 %add, ptr %a seq_cst, align 4, !dbg !24 - %3 = load i32, ptr %y, align 4, !dbg !26 - %add1 = add i32 33, %3, !dbg !27 - store atomic volatile i32 %add1, ptr %a monotonic, align 4, !dbg !28 - %4 = insertvalue %"any*" undef, ptr %a, 0, !dbg !30 - %5 = insertvalue %"any*" %4, i64 ptrtoint (ptr @"$ct.int" to i64), 1, !dbg !30 - %6 = getelementptr inbounds [1 x %"any*"], ptr %varargslots, i64 0, i64 0, !dbg !30 - store %"any*" %5, ptr %6, align 16, !dbg !30 - %7 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1), !dbg !31 - ret void, !dbg !31 + call void @llvm.dbg.declare(metadata ptr %a, metadata !10, metadata !DIExpression()), !dbg !12 + store i32 111, ptr %a, align 4, !dbg !13 + call void @llvm.dbg.declare(metadata ptr %x, metadata !14, metadata !DIExpression()), !dbg !15 + %0 = load atomic i32, ptr %a seq_cst, align 4, !dbg !16 + store i32 %0, ptr %x, align 4, !dbg !16 + call void @llvm.dbg.declare(metadata ptr %y, metadata !19, metadata !DIExpression()), !dbg !20 + %1 = load atomic volatile i32, ptr %a monotonic, align 4, !dbg !21 + store i32 %1, ptr %y, align 4, !dbg !21 + %2 = load i32, ptr %x, align 4, !dbg !23 + %add = add i32 123, %2, !dbg !24 + store atomic i32 %add, ptr %a seq_cst, align 4, !dbg !25 + %3 = load i32, ptr %y, align 4, !dbg !27 + %add1 = add i32 33, %3, !dbg !28 + store atomic volatile i32 %add1, ptr %a monotonic, align 4, !dbg !29 + %4 = insertvalue %"any*" undef, ptr %a, 0, !dbg !31 + %5 = insertvalue %"any*" %4, i64 ptrtoint (ptr @"$ct.int" to i64), 1, !dbg !31 + %6 = getelementptr inbounds [1 x %"any*"], ptr %varargslots, i64 0, i64 0, !dbg !31 + store %"any*" %5, ptr %6, align 16, !dbg !31 + %7 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1), !dbg !32 + ret void, !dbg !32 } -define i32 @main(i32 %0, ptr %1) #0 !dbg !32 { +define i32 @main(i32 %0, ptr %1) #0 !dbg !33 { entry: - call void @test.main(), !dbg !38 - ret i32 0, !dbg !41 + call void @test.main(), !dbg !39 + ret i32 0, !dbg !42 } declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 @@ -68,47 +69,49 @@ declare i64 @std.io.printfn(ptr, ptr, i64, ptr, i64) #0 declare i1 @llvm.expect.i1(i1, i1) #2 -!llvm.module.flags = !{!0, !1, !2} -!llvm.dbg.cu = !{!3} +!llvm.module.flags = !{!0, !1, !2, !3} +!llvm.dbg.cu = !{!4} + !0 = !{i32 2, !"Dwarf Version", i32 4} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = !{i32 1, !"uwtable", i32 2} -!3 = distinct !DICompileUnit(language: DW_LANG_C11, file: !4, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) -!4 = !DIFile(filename: "atomic_load_store_debug.c3" -!5 = distinct !DISubprogram(name: "main", linkageName: "test.main", scope: !4, file: !4, line: 10, type: !6, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !3, retainedNodes: !8) -!6 = !DISubroutineType(types: !7) -!7 = !{null} -!8 = !{} -!9 = !DILocalVariable(name: "a", scope: !5, file: !4, line: 12, type: !10, align: 4) -!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!11 = !DILocation(line: 12, column: 6, scope: !5) -!12 = !DILocation(line: 12, column: 10, scope: !5) -!13 = !DILocalVariable(name: "x", scope: !5, file: !4, line: 13, type: !10, align: 4) -!14 = !DILocation(line: 13, column: 6, scope: !5) -!15 = !DILocation(line: -!16 = distinct !DILexicalBlock(scope: !5, file: !17, -!17 = !DIFile(filename: "mem.c3", -!18 = !DILocalVariable(name: "y", scope: !5, file: !4, line: 14, type: !10, align: 4) -!19 = !DILocation(line: 14, column: 6, scope: !5) -!20 = !DILocation(line: -!21 = distinct !DILexicalBlock(scope: !5, file: !17, -!22 = !DILocation(line: 15, column: 25, scope: !5) -!23 = !DILocation(line: 15, column: 19, scope: !5) -!24 = !DILocation(line: -!25 = distinct !DILexicalBlock(scope: !5, file: !17, -!26 = !DILocation(line: 16, column: 24, scope: !5) -!27 = !DILocation(line: 16, column: 19, scope: !5) -!28 = !DILocation(line: -!29 = distinct !DILexicalBlock(scope: !5, file: !17, line: -!30 = !DILocation(line: 17, column: 20, scope: !5) -!31 = !DILocation(line: 17, column: 6, scope: !5) -!32 = distinct !DISubprogram(name: "_$main", linkageName: "main", scope: !4, file: !4, line: 10, type: !33, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !3, retainedNodes: !8) -!33 = !DISubroutineType(types: !34) -!34 = !{!10, !10, !35} -!35 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char**", baseType: !36, size: 64, align: 64, dwarfAddressSpace: 0) -!36 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char*", baseType: !37, size: 64, align: 64, dwarfAddressSpace: 0) -!37 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char) -!38 = !DILocation(line: 18, column: 2, scope: !39) -!39 = distinct !DILexicalBlock(scope: !32, file: !40, line: 18, column: 2) -!40 = !DIFile(filename: "main_stub.c3", -!41 = !DILocation(line: 19, column: 9, scope: !39) +!2 = !{i32 2, !"frame-pointer", i32 2} +!3 = !{i32 1, !"uwtable", i32 2} +!4 = distinct !DICompileUnit(language: DW_LANG_C11, file: !5, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!5 = !DIFile(filename: "atomic_load_store_debug.c3" +!6 = distinct !DISubprogram(name: "main", linkageName: "test.main", scope: !5, file: !5, line: 10, type: !7, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !4, retainedNodes: !9) +!7 = !DISubroutineType(types: !8) +!8 = !{null} +!9 = !{} +!10 = !DILocalVariable(name: "a", scope: !6, file: !5, line: 12, type: !11, align: 4) +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DILocation(line: 12, column: 6, scope: !6) +!13 = !DILocation(line: 12, column: 10, scope: !6) +!14 = !DILocalVariable(name: "x", scope: !6, file: !5, line: 13, type: !11, align: 4) +!15 = !DILocation(line: 13, column: 6, scope: !6) +!16 = !DILocation(line: 195, column: 23, scope: !17) +!17 = distinct !DILexicalBlock(scope: !6, file: !18, line: 195, column: 9) +!18 = !DIFile(filename: "mem.c3", directory: "/Users/lerno/Projects/c3c/lib/std/core") +!19 = !DILocalVariable(name: "y", scope: !6, file: !5, line: 14, type: !11, align: 4) +!20 = !DILocation(line: 14, column: 6, scope: !6) +!21 = !DILocation(line: 195, column: 23, scope: !22) +!22 = distinct !DILexicalBlock(scope: !6, file: !18, line: 195, column: 9) +!23 = !DILocation(line: 15, column: 25, scope: !6) +!24 = !DILocation(line: 15, column: 19, scope: !6) +!25 = !DILocation(line: 210, column: 20, scope: !26) +!26 = distinct !DILexicalBlock(scope: !6, file: !18, line: 210, column: 2) +!27 = !DILocation(line: 16, column: 24, scope: !6) +!28 = !DILocation(line: 16, column: 19, scope: !6) +!29 = !DILocation(line: 210, column: 20, scope: !30) +!30 = distinct !DILexicalBlock(scope: !6, file: !18, line: 210, column: 2) +!31 = !DILocation(line: 17, column: 20, scope: !6) +!32 = !DILocation(line: 17, column: 6, scope: !6) +!33 = distinct !DISubprogram(name: "_$main", linkageName: "main", scope: !5, file: !5, line: 10, type: !34, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !4, retainedNodes: !9) +!34 = !DISubroutineType(types: !35) +!35 = !{!11, !11, !36} +!36 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char**", baseType: !37, size: 64, align: 64, dwarfAddressSpace: 0) +!37 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char*", baseType: !38, size: 64, align: 64, dwarfAddressSpace: 0) +!38 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char) +!39 = !DILocation(line: 18, column: 2, scope: !40) +!40 = distinct !DILexicalBlock(scope: !33, file: !41, line: 18, column: 2) +!41 = !DIFile(filename: "main_stub.c3" +!42 = !DILocation(line: 19, column: 9, scope: !40) diff --git a/test/test_suite/debug_symbols/constants.c3t b/test/test_suite/debug_symbols/constants.c3t index 4b96c8a80..f4dbb41c1 100644 --- a/test/test_suite/debug_symbols/constants.c3t +++ b/test/test_suite/debug_symbols/constants.c3t @@ -11,21 +11,22 @@ const FOO @private = ~(uint)(0); @constants.BB = local_unnamed_addr constant i8 -56, align 1 @constants.CC = protected unnamed_addr constant i32 -1, align 4 @constants.FOO = protected unnamed_addr constant i32 -1, align 4 -!llvm.module.flags = !{!0, !1, !2} -!llvm.dbg.cu = !{!3} +!llvm.module.flags = !{!0, !1, !2, !3} +!llvm.dbg.cu = !{!4} !0 = !{i32 2, !"Dwarf Version", i32 4} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = !{i32 1, !"uwtable", i32 2} -!3 = distinct !DICompileUnit(language: DW_LANG_C11, file: !4, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !5, splitDebugInlining: false) -!4 = !DIFile(filename: "constants.c3", -!5 = !{!6, !9, !11, !14} -!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) -!7 = distinct !DIGlobalVariable(name: "AA", linkageName: "constants.AA", scope: !4 -!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char) -!9 = !DIGlobalVariableExpression(var: !10, expr: !DIExpression()) -!10 = distinct !DIGlobalVariable(name: "BB", linkageName: "constants.BB", scope: !4, file: !4, line: 2 -!11 = !DIGlobalVariableExpression(var: !12, expr: !DIExpression()) -!12 = distinct !DIGlobalVariable(name: "CC", linkageName: "constants.CC", scope: !4, file: !4, line: 3 -!13 = !DIBasicType(name: "uint", size: 32, encoding: DW_ATE_unsigned) -!14 = !DIGlobalVariableExpression(var: !15, expr: !DIExpression()) -!15 = distinct !DIGlobalVariable(name: "FOO", linkageName: "constants.FOO", scope: !4, file: !4, line: +!2 = !{i32 2, !"frame-pointer", i32 2} +!3 = !{i32 1, !"uwtable", i32 2} +!4 = distinct !DICompileUnit(language: DW_LANG_C11, file: !5, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !6, splitDebugInlining: false) +!5 = !DIFile(filename: "constants.c3", +!6 = !{!7, !10, !12, !15} +!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression()) +!8 = distinct !DIGlobalVariable(name: "AA", linkageName: "constants.AA", scope: !5 +!9 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char) +!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) +!11 = distinct !DIGlobalVariable(name: "BB", linkageName: "constants.BB", scope: !5, file: !5, line: 2 +!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression()) +!13 = distinct !DIGlobalVariable(name: "CC", linkageName: "constants.CC", scope: !5, file: !5, line: 3 +!14 = !DIBasicType(name: "uint", size: 32, encoding: DW_ATE_unsigned) +!15 = !DIGlobalVariableExpression(var: !16, expr: !DIExpression()) +!16 = distinct !DIGlobalVariable(name: "FOO", linkageName: "constants.FOO", scope: !5, file: !5, line: 4, type: !14, isLocal: true, isDefinition: true, align: 4) diff --git a/test/test_suite/debug_symbols/constants_mingw.c3t b/test/test_suite/debug_symbols/constants_mingw.c3t index ef27a55fe..2c3e46216 100644 --- a/test/test_suite/debug_symbols/constants_mingw.c3t +++ b/test/test_suite/debug_symbols/constants_mingw.c3t @@ -12,27 +12,25 @@ const FOO @private = ~(uint)(0); source_filename = "constants_mingw" target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64: target triple = "x86_64-w64-windows-gnu" - @constants_mingw.AA = protected unnamed_addr constant i8 1, align 1 @constants_mingw.BB = local_unnamed_addr constant i8 -56, align 1 @constants_mingw.CC = protected unnamed_addr constant i32 -1, align 4 @constants_mingw.FOO = protected unnamed_addr constant i32 -1, align 4 - -!llvm.module.flags = !{!0, !1, !2} -!llvm.dbg.cu = !{!3} - +!llvm.module.flags = !{!0, !1, !2, !3} +!llvm.dbg.cu = !{!4} !0 = !{i32 2, !"Dwarf Version", i32 4} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = !{i32 1, !"uwtable", i32 2} -!3 = distinct !DICompileUnit(language: DW_LANG_C11, file: !4, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !5, splitDebugInlining: false) -!5 = !{!6, !9, !11, !14} -!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) -!7 = distinct !DIGlobalVariable(name: "AA", linkageName: "constants_mingw.AA", scope: !4, file: !4, line: 1, type: !8, isLocal: true, isDefinition: true, align: 1) -!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char) -!9 = !DIGlobalVariableExpression(var: !10, expr: !DIExpression()) -!10 = distinct !DIGlobalVariable(name: "BB", linkageName: "constants_mingw.BB", scope: !4, file: !4, line: 2, type: !8, isLocal: false, isDefinition: true, align: 1) -!11 = !DIGlobalVariableExpression(var: !12, expr: !DIExpression()) -!12 = distinct !DIGlobalVariable(name: "CC", linkageName: "constants_mingw.CC", scope: !4, file: !4, line: 3, type: !13, isLocal: true, isDefinition: true, align: 4) -!13 = !DIBasicType(name: "uint", size: 32, encoding: DW_ATE_unsigned) -!14 = !DIGlobalVariableExpression(var: !15, expr: !DIExpression()) -!15 = distinct !DIGlobalVariable(name: "FOO", linkageName: "constants_mingw.FOO", scope: !4, file: !4, line: 4, type: !13, isLocal: true, isDefinition: true, align: 4) +!2 = !{i32 2, !"frame-pointer", i32 2} +!3 = !{i32 1, !"uwtable", i32 2} +!4 = distinct !DICompileUnit(language: DW_LANG_C11, file: !5, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !6, splitDebugInlining: false) +!6 = !{!7, !10, !12, !15} +!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression()) +!8 = distinct !DIGlobalVariable(name: "AA", linkageName: "constants_mingw.AA", scope: !5, file: !5, line: 1, type: !9, isLocal: true, isDefinition: true, align: 1) +!9 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char) +!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) +!11 = distinct !DIGlobalVariable(name: "BB", linkageName: "constants_mingw.BB", scope: !5, file: !5, line: 2, type: !9, isLocal: false, isDefinition: true, align: 1) +!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression()) +!13 = distinct !DIGlobalVariable(name: "CC", linkageName: "constants_mingw.CC", scope: !5, file: !5, line: 3, type: !14, isLocal: true, isDefinition: true, align: 4) +!14 = !DIBasicType(name: "uint", size: 32, encoding: DW_ATE_unsigned) +!15 = !DIGlobalVariableExpression(var: !16, expr: !DIExpression()) +!16 = distinct !DIGlobalVariable(name: "FOO", linkageName: "constants_mingw.FOO", scope: !5, file: !5, line: 4, type: !14, isLocal: true, isDefinition: true, align: 4) \ No newline at end of file