mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Native Linux backtrace.
This commit is contained in:
committed by
Christoffer Lerno
parent
f39aa1a41e
commit
dc0aa35522
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@@ -264,6 +264,7 @@ jobs:
|
|||||||
../build/c3c compile-run examples/load_world.c3
|
../build/c3c compile-run examples/load_world.c3
|
||||||
../build/c3c compile-run examples/process.c3
|
../build/c3c compile-run examples/process.c3
|
||||||
../build/c3c compile-run examples/ls.c3
|
../build/c3c compile-run examples/ls.c3
|
||||||
|
../build/c3c compile-run linux_stack.c3
|
||||||
|
|
||||||
- name: Compile run unit tests
|
- name: Compile run unit tests
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -87,11 +87,11 @@ struct CallstackElement
|
|||||||
uint line;
|
uint line;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::DARWIN)
|
fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::DARWIN || env::LINUX)
|
||||||
{
|
{
|
||||||
@pool()
|
@pool()
|
||||||
{
|
{
|
||||||
BacktraceList! backtrace = darwin::backtrace_load(mem::temp());
|
BacktraceList! backtrace = backtrace::backtrace_load(mem::temp());
|
||||||
if (catch backtrace) return false;
|
if (catch backtrace) return false;
|
||||||
if (backtrace.len() <= backtraces_to_ignore) return false;
|
if (backtrace.len() <= backtraces_to_ignore) return false;
|
||||||
io::eprint("\nERROR: '");
|
io::eprint("\nERROR: '");
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ fn void Backtrace.free(&self)
|
|||||||
self.allocator.free(self.file);
|
self.allocator.free(self.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def backtrace_load = darwin::backtrace_load @if(env::DARWIN);
|
||||||
|
def backtrace_load = linux::backtrace_load @if(env::LINUX);
|
||||||
|
|
||||||
fn Backtrace* Backtrace.init(&self, uptr offset, String function, String object_file, String file = "", uint line = 0, Allocator* using = mem::heap())
|
fn Backtrace* Backtrace.init(&self, uptr offset, String function, String object_file, String file = "", uint line = 0, Allocator* using = mem::heap())
|
||||||
{
|
{
|
||||||
if (!using)
|
if (!using)
|
||||||
|
|||||||
199
lib/std/os/linux/linux.c3
Normal file
199
lib/std/os/linux/linux.c3
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
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(<Backtrace>);
|
||||||
|
|
||||||
|
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) })!;
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -101,15 +101,12 @@ fn Backtrace! backtrace_load_element(String execpath, void* buffer, void* load_a
|
|||||||
{
|
{
|
||||||
if (buffer)
|
if (buffer)
|
||||||
{
|
{
|
||||||
SubProcess process = process::create({ "atos",
|
char* buf = tmalloc(1024);
|
||||||
"-o", execpath, "-arch", env::AARCH64 ? "arm64" : "x86_64", "-l",
|
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", load_address),
|
||||||
string::tformat("%p", buffer),
|
string::tformat("%p", buffer),
|
||||||
"-fullPath" })!;
|
"-fullPath" })!;
|
||||||
process.join()!;
|
|
||||||
char* buf = tmalloc(1024);
|
|
||||||
usz len = process.read_stdout(buf, 1024)!;
|
|
||||||
String s = (String)buf[:len - 1];
|
|
||||||
String[] parts = s.tsplit(" ");
|
String[] parts = s.tsplit(" ");
|
||||||
if (parts.len == 4)
|
if (parts.len == 4)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -269,6 +269,13 @@ fn ZString* tcopy_env(String[] environment) @local @inline @if(env::POSIX)
|
|||||||
return copy;
|
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
|
* @require !environment || !options.inherit_environment
|
||||||
|
|||||||
10
resources/linux_stack.c3
Normal file
10
resources/linux_stack.c3
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
module test;
|
||||||
|
import std::io;
|
||||||
|
import std::collections::map;
|
||||||
|
import std::os;
|
||||||
|
|
||||||
|
fn void! main()
|
||||||
|
{
|
||||||
|
int x = 2;
|
||||||
|
builtin::print_backtrace("Hello", 0);
|
||||||
|
}
|
||||||
@@ -2367,6 +2367,7 @@ void codegen_setup_object_names(Module *module, const char **ir_filename, const
|
|||||||
void target_setup(BuildTarget *build_target);
|
void target_setup(BuildTarget *build_target);
|
||||||
int target_alloca_addr_space();
|
int target_alloca_addr_space();
|
||||||
bool os_is_apple(OsType os_type);
|
bool os_is_apple(OsType os_type);
|
||||||
|
bool os_supports_stacktrace(OsType os_type);
|
||||||
bool arch_is_wasm(ArchType type);
|
bool arch_is_wasm(ArchType type);
|
||||||
|
|
||||||
const char *macos_sysroot(void);
|
const char *macos_sysroot(void);
|
||||||
|
|||||||
@@ -386,9 +386,17 @@ static void linker_setup_linux(const char ***args_ref, LinkerType linker_type)
|
|||||||
{
|
{
|
||||||
if (linker_type == LINKER_CC)
|
if (linker_type == LINKER_CC)
|
||||||
{
|
{
|
||||||
|
if (active_target.debug_info == DEBUG_INFO_FULL)
|
||||||
|
{
|
||||||
|
add_arg("-rdynamic");
|
||||||
|
}
|
||||||
add_arg("-pthread");
|
add_arg("-pthread");
|
||||||
return;
|
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_no_pie(platform_target.reloc_model)) add_arg("-no-pie");
|
||||||
if (is_pie(platform_target.reloc_model)) add_arg("-pie");
|
if (is_pie(platform_target.reloc_model)) add_arg("-pie");
|
||||||
if (platform_target.arch == ARCH_TYPE_X86_64) add_arg("--eh-frame-hdr");
|
if (platform_target.arch == ARCH_TYPE_X86_64) add_arg("--eh-frame-hdr");
|
||||||
|
|||||||
@@ -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, "Dwarf Version", 4, type_uint);
|
||||||
llvm_set_module_flag(c, LLVMModuleFlagBehaviorWarning, "Debug Info Version", 3, 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);
|
llvm_set_module_flag(c, LLVMModuleFlagBehaviorError, "uwtable", 2, type_uint);
|
||||||
|
|
||||||
@@ -168,7 +169,7 @@ void gencontext_begin_module(GenContext *c)
|
|||||||
LLVMStructSetBody(c->debug.stack_type, types, 5, false);
|
LLVMStructSetBody(c->debug.stack_type, types, 5, false);
|
||||||
c->debug.current_stack_ptr = NULL;
|
c->debug.current_stack_ptr = NULL;
|
||||||
c->debug.enable_stacktrace = true;
|
c->debug.enable_stacktrace = true;
|
||||||
c->debug.emulated_stacktrace = !os_is_apple(platform_target.os);
|
c->debug.emulated_stacktrace = !os_supports_stacktrace(platform_target.os);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c->global_builder = LLVMCreateBuilder();
|
c->global_builder = LLVMCreateBuilder();
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ int target_alloca_addr_space()
|
|||||||
return platform_target.alloca_address_space;
|
return platform_target.alloca_address_space;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool os_supports_stacktrace(OsType os_type)
|
||||||
|
{
|
||||||
|
return os_type == OS_TYPE_LINUX || os_is_apple(os_type);
|
||||||
|
}
|
||||||
bool os_is_apple(OsType os_type)
|
bool os_is_apple(OsType os_type)
|
||||||
{
|
{
|
||||||
return os_type == OS_TYPE_TVOS || os_type == OS_TYPE_WATCHOS ||
|
return os_type == OS_TYPE_TVOS || os_type == OS_TYPE_WATCHOS ||
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#define COMPILER_VERSION "0.4.699"
|
#define COMPILER_VERSION "0.4.700"
|
||||||
|
|||||||
@@ -22,43 +22,44 @@ fn void main()
|
|||||||
/* #expect: test.ll
|
/* #expect: test.ll
|
||||||
%.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] }
|
%.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] }
|
||||||
%"any*" = type { ptr, 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
|
@"$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
|
@.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
|
@"$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:
|
entry:
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%x = alloca i32, align 4
|
%x = alloca i32, align 4
|
||||||
%y = alloca i32, align 4
|
%y = alloca i32, align 4
|
||||||
%varargslots = alloca [1 x %"any*"], align 16
|
%varargslots = alloca [1 x %"any*"], align 16
|
||||||
%retparam = alloca i64, align 8
|
%retparam = alloca i64, align 8
|
||||||
call void @llvm.dbg.declare(metadata ptr %a, metadata !9, metadata !DIExpression()), !dbg !11
|
call void @llvm.dbg.declare(metadata ptr %a, metadata !10, metadata !DIExpression()), !dbg !12
|
||||||
store i32 111, ptr %a, align 4, !dbg !12
|
store i32 111, ptr %a, align 4, !dbg !13
|
||||||
call void @llvm.dbg.declare(metadata ptr %x, metadata !13, metadata !DIExpression()), !dbg !14
|
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 !15
|
%0 = load atomic i32, ptr %a seq_cst, align 4, !dbg !16
|
||||||
store i32 %0, ptr %x, align 4, !dbg !15
|
store i32 %0, ptr %x, align 4, !dbg !16
|
||||||
call void @llvm.dbg.declare(metadata ptr %y, metadata !18, metadata !DIExpression()), !dbg !19
|
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 !20
|
%1 = load atomic volatile i32, ptr %a monotonic, align 4, !dbg !21
|
||||||
store i32 %1, ptr %y, align 4, !dbg !20
|
store i32 %1, ptr %y, align 4, !dbg !21
|
||||||
%2 = load i32, ptr %x, align 4, !dbg !22
|
%2 = load i32, ptr %x, align 4, !dbg !23
|
||||||
%add = add i32 123, %2, !dbg !23
|
%add = add i32 123, %2, !dbg !24
|
||||||
store atomic i32 %add, ptr %a seq_cst, align 4, !dbg !24
|
store atomic i32 %add, ptr %a seq_cst, align 4, !dbg !25
|
||||||
%3 = load i32, ptr %y, align 4, !dbg !26
|
%3 = load i32, ptr %y, align 4, !dbg !27
|
||||||
%add1 = add i32 33, %3, !dbg !27
|
%add1 = add i32 33, %3, !dbg !28
|
||||||
store atomic volatile i32 %add1, ptr %a monotonic, align 4, !dbg !28
|
store atomic volatile i32 %add1, ptr %a monotonic, align 4, !dbg !29
|
||||||
%4 = insertvalue %"any*" undef, ptr %a, 0, !dbg !30
|
%4 = insertvalue %"any*" undef, ptr %a, 0, !dbg !31
|
||||||
%5 = insertvalue %"any*" %4, i64 ptrtoint (ptr @"$ct.int" to i64), 1, !dbg !30
|
%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 !30
|
%6 = getelementptr inbounds [1 x %"any*"], ptr %varargslots, i64 0, i64 0, !dbg !31
|
||||||
store %"any*" %5, ptr %6, align 16, !dbg !30
|
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 !31
|
%7 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1), !dbg !32
|
||||||
ret void, !dbg !31
|
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:
|
entry:
|
||||||
call void @test.main(), !dbg !38
|
call void @test.main(), !dbg !39
|
||||||
ret i32 0, !dbg !41
|
ret i32 0, !dbg !42
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
|
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
|
declare i1 @llvm.expect.i1(i1, i1) #2
|
||||||
|
|
||||||
!llvm.module.flags = !{!0, !1, !2}
|
!llvm.module.flags = !{!0, !1, !2, !3}
|
||||||
!llvm.dbg.cu = !{!3}
|
!llvm.dbg.cu = !{!4}
|
||||||
|
|
||||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||||
!2 = !{i32 1, !"uwtable", i32 2}
|
!2 = !{i32 2, !"frame-pointer", i32 2}
|
||||||
!3 = distinct !DICompileUnit(language: DW_LANG_C11, file: !4, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false)
|
!3 = !{i32 1, !"uwtable", i32 2}
|
||||||
!4 = !DIFile(filename: "atomic_load_store_debug.c3"
|
!4 = distinct !DICompileUnit(language: DW_LANG_C11, file: !5, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false)
|
||||||
!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)
|
!5 = !DIFile(filename: "atomic_load_store_debug.c3"
|
||||||
!6 = !DISubroutineType(types: !7)
|
!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 = !{null}
|
!7 = !DISubroutineType(types: !8)
|
||||||
!8 = !{}
|
!8 = !{null}
|
||||||
!9 = !DILocalVariable(name: "a", scope: !5, file: !4, line: 12, type: !10, align: 4)
|
!9 = !{}
|
||||||
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
!10 = !DILocalVariable(name: "a", scope: !6, file: !5, line: 12, type: !11, align: 4)
|
||||||
!11 = !DILocation(line: 12, column: 6, scope: !5)
|
!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||||
!12 = !DILocation(line: 12, column: 10, scope: !5)
|
!12 = !DILocation(line: 12, column: 6, scope: !6)
|
||||||
!13 = !DILocalVariable(name: "x", scope: !5, file: !4, line: 13, type: !10, align: 4)
|
!13 = !DILocation(line: 12, column: 10, scope: !6)
|
||||||
!14 = !DILocation(line: 13, column: 6, scope: !5)
|
!14 = !DILocalVariable(name: "x", scope: !6, file: !5, line: 13, type: !11, align: 4)
|
||||||
!15 = !DILocation(line:
|
!15 = !DILocation(line: 13, column: 6, scope: !6)
|
||||||
!16 = distinct !DILexicalBlock(scope: !5, file: !17,
|
!16 = !DILocation(line: 195, column: 23, scope: !17)
|
||||||
!17 = !DIFile(filename: "mem.c3",
|
!17 = distinct !DILexicalBlock(scope: !6, file: !18, line: 195, column: 9)
|
||||||
!18 = !DILocalVariable(name: "y", scope: !5, file: !4, line: 14, type: !10, align: 4)
|
!18 = !DIFile(filename: "mem.c3"
|
||||||
!19 = !DILocation(line: 14, column: 6, scope: !5)
|
!19 = !DILocalVariable(name: "y", scope: !6, file: !5, line: 14, type: !11, align: 4)
|
||||||
!20 = !DILocation(line:
|
!20 = !DILocation(line: 14, column: 6, scope: !6)
|
||||||
!21 = distinct !DILexicalBlock(scope: !5, file: !17,
|
!21 = !DILocation(line: 195, column: 23, scope: !22)
|
||||||
!22 = !DILocation(line: 15, column: 25, scope: !5)
|
!22 = distinct !DILexicalBlock(scope: !6, file: !18, line: 195, column: 9)
|
||||||
!23 = !DILocation(line: 15, column: 19, scope: !5)
|
!23 = !DILocation(line: 15, column: 25, scope: !6)
|
||||||
!24 = !DILocation(line:
|
!24 = !DILocation(line: 15, column: 19, scope: !6)
|
||||||
!25 = distinct !DILexicalBlock(scope: !5, file: !17,
|
!25 = !DILocation(line: 210, column: 20, scope: !26)
|
||||||
!26 = !DILocation(line: 16, column: 24, scope: !5)
|
!26 = distinct !DILexicalBlock(scope: !6, file: !18, line: 210, column: 2)
|
||||||
!27 = !DILocation(line: 16, column: 19, scope: !5)
|
!27 = !DILocation(line: 16, column: 24, scope: !6)
|
||||||
!28 = !DILocation(line:
|
!28 = !DILocation(line: 16, column: 19, scope: !6)
|
||||||
!29 = distinct !DILexicalBlock(scope: !5, file: !17, line:
|
!29 = !DILocation(line: 210, column: 20, scope: !30)
|
||||||
!30 = !DILocation(line: 17, column: 20, scope: !5)
|
!30 = distinct !DILexicalBlock(scope: !6, file: !18, line: 210, column: 2)
|
||||||
!31 = !DILocation(line: 17, column: 6, scope: !5)
|
!31 = !DILocation(line: 17, column: 20, scope: !6)
|
||||||
!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)
|
!32 = !DILocation(line: 17, column: 6, scope: !6)
|
||||||
!33 = !DISubroutineType(types: !34)
|
!33 = distinct !DISubprogram(name: "_$main", linkageName: "main"
|
||||||
!34 = !{!10, !10, !35}
|
!34 = !DISubroutineType(types: !35)
|
||||||
!35 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char**", baseType: !36, size: 64, align: 64, dwarfAddressSpace: 0)
|
!35 = !{!11, !11, !36}
|
||||||
!36 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char*", baseType: !37, 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)
|
!37 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char*", baseType: !38, size: 64, align: 64, dwarfAddressSpace: 0)
|
||||||
!38 = !DILocation(line: 18, column: 2, scope: !39)
|
!38 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char)
|
||||||
!39 = distinct !DILexicalBlock(scope: !32, file: !40, line: 18, column: 2)
|
!39 = !DILocation(line: 18, column: 2, scope: !40)
|
||||||
!40 = !DIFile(filename: "main_stub.c3",
|
!40 = distinct !DILexicalBlock(scope: !33, file: !41, line: 18, column: 2)
|
||||||
!41 = !DILocation(line: 19, column: 9, scope: !39)
|
!41 = !DIFile(filename: "main_stub.c3"
|
||||||
|
!42 = !DILocation(line: 19, column: 9, scope: !40)
|
||||||
|
|||||||
@@ -11,21 +11,22 @@ const FOO @private = ~(uint)(0);
|
|||||||
@constants.BB = local_unnamed_addr constant i8 -56, align 1
|
@constants.BB = local_unnamed_addr constant i8 -56, align 1
|
||||||
@constants.CC = protected unnamed_addr constant i32 -1, align 4
|
@constants.CC = protected unnamed_addr constant i32 -1, align 4
|
||||||
@constants.FOO = 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.module.flags = !{!0, !1, !2, !3}
|
||||||
!llvm.dbg.cu = !{!3}
|
!llvm.dbg.cu = !{!4}
|
||||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||||
!2 = !{i32 1, !"uwtable", i32 2}
|
!2 = !{i32 2, !"frame-pointer", i32 2}
|
||||||
!3 = distinct !DICompileUnit(language: DW_LANG_C11, file: !4, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !5, splitDebugInlining: false)
|
!3 = !{i32 1, !"uwtable", i32 2}
|
||||||
!4 = !DIFile(filename: "constants.c3",
|
!4 = distinct !DICompileUnit(language: DW_LANG_C11, file: !5, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !6, splitDebugInlining: false)
|
||||||
!5 = !{!6, !9, !11, !14}
|
!5 = !DIFile(filename: "constants.c3",
|
||||||
!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
|
!6 = !{!7, !10, !12, !15}
|
||||||
!7 = distinct !DIGlobalVariable(name: "AA", linkageName: "constants.AA", scope: !4
|
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression())
|
||||||
!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char)
|
!8 = distinct !DIGlobalVariable(name: "AA", linkageName: "constants.AA", scope: !5
|
||||||
!9 = !DIGlobalVariableExpression(var: !10, expr: !DIExpression())
|
!9 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char)
|
||||||
!10 = distinct !DIGlobalVariable(name: "BB", linkageName: "constants.BB", scope: !4, file: !4, line: 2
|
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
|
||||||
!11 = !DIGlobalVariableExpression(var: !12, expr: !DIExpression())
|
!11 = distinct !DIGlobalVariable(name: "BB", linkageName: "constants.BB", scope: !5, file: !5, line: 2
|
||||||
!12 = distinct !DIGlobalVariable(name: "CC", linkageName: "constants.CC", scope: !4, file: !4, line: 3
|
!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression())
|
||||||
!13 = !DIBasicType(name: "uint", size: 32, encoding: DW_ATE_unsigned)
|
!13 = distinct !DIGlobalVariable(name: "CC", linkageName: "constants.CC", scope: !5, file: !5, line: 3
|
||||||
!14 = !DIGlobalVariableExpression(var: !15, expr: !DIExpression())
|
!14 = !DIBasicType(name: "uint", size: 32, encoding: DW_ATE_unsigned)
|
||||||
!15 = distinct !DIGlobalVariable(name: "FOO", linkageName: "constants.FOO", scope: !4, file: !4, line:
|
!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)
|
||||||
|
|||||||
@@ -12,27 +12,25 @@ const FOO @private = ~(uint)(0);
|
|||||||
source_filename = "constants_mingw"
|
source_filename = "constants_mingw"
|
||||||
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:
|
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:
|
||||||
target triple = "x86_64-w64-windows-gnu"
|
target triple = "x86_64-w64-windows-gnu"
|
||||||
|
|
||||||
@constants_mingw.AA = protected unnamed_addr constant i8 1, align 1
|
@constants_mingw.AA = protected unnamed_addr constant i8 1, align 1
|
||||||
@constants_mingw.BB = local_unnamed_addr constant i8 -56, 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.CC = protected unnamed_addr constant i32 -1, align 4
|
||||||
@constants_mingw.FOO = 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, !3}
|
||||||
!llvm.module.flags = !{!0, !1, !2}
|
!llvm.dbg.cu = !{!4}
|
||||||
!llvm.dbg.cu = !{!3}
|
|
||||||
|
|
||||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||||
!2 = !{i32 1, !"uwtable", i32 2}
|
!2 = !{i32 2, !"frame-pointer", i32 2}
|
||||||
!3 = distinct !DICompileUnit(language: DW_LANG_C11, file: !4, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !5, splitDebugInlining: false)
|
!3 = !{i32 1, !"uwtable", i32 2}
|
||||||
!5 = !{!6, !9, !11, !14}
|
!4 = distinct !DICompileUnit(language: DW_LANG_C11, file: !5, producer: "c3c", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !6, splitDebugInlining: false)
|
||||||
!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
|
!6 = !{!7, !10, !12, !15}
|
||||||
!7 = distinct !DIGlobalVariable(name: "AA", linkageName: "constants_mingw.AA", scope: !4, file: !4, line: 1, type: !8, isLocal: true, isDefinition: true, align: 1)
|
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression())
|
||||||
!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char)
|
!8 = distinct !DIGlobalVariable(name: "AA", linkageName: "constants_mingw.AA", scope: !5, file: !5, line: 1, type: !9, isLocal: true, isDefinition: true, align: 1)
|
||||||
!9 = !DIGlobalVariableExpression(var: !10, expr: !DIExpression())
|
!9 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char)
|
||||||
!10 = distinct !DIGlobalVariable(name: "BB", linkageName: "constants_mingw.BB", scope: !4, file: !4, line: 2, type: !8, isLocal: false, isDefinition: true, align: 1)
|
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
|
||||||
!11 = !DIGlobalVariableExpression(var: !12, 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 = distinct !DIGlobalVariable(name: "CC", linkageName: "constants_mingw.CC", scope: !4, file: !4, line: 3, type: !13, isLocal: true, isDefinition: true, align: 4)
|
!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression())
|
||||||
!13 = !DIBasicType(name: "uint", size: 32, encoding: DW_ATE_unsigned)
|
!13 = distinct !DIGlobalVariable(name: "CC", linkageName: "constants_mingw.CC", scope: !5, file: !5, line: 3, type: !14, isLocal: true, isDefinition: true, align: 4)
|
||||||
!14 = !DIGlobalVariableExpression(var: !15, expr: !DIExpression())
|
!14 = !DIBasicType(name: "uint", size: 32, encoding: DW_ATE_unsigned)
|
||||||
!15 = distinct !DIGlobalVariable(name: "FOO", linkageName: "constants_mingw.FOO", scope: !4, file: !4, line: 4, type: !13, isLocal: true, isDefinition: true, align: 4)
|
!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)
|
||||||
Reference in New Issue
Block a user