diff --git a/lib/std/debug.zig b/lib/std/debug.zig index a6bc0fedf3..41270bcd82 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -280,14 +280,23 @@ pub const StackIterator = struct { }; } + // On some architectures such as x86 the frame pointer is the address where + // the previous fp is stored, while on some other architectures such as + // RISC-V it points to the "top" of the frame, just above where the previous + // fp and the return address are stored. + const fp_adjust_factor = if (builtin.arch == .riscv32 or builtin.arch == .riscv64) + 2 * @sizeOf(usize) + else + 0; + fn next(self: *StackIterator) ?usize { - if (self.fp == 0) return null; - self.fp = @intToPtr(*const usize, self.fp).*; - if (self.fp == 0) return null; + if (self.fp < fp_adjust_factor) return null; + self.fp = @intToPtr(*const usize, self.fp - fp_adjust_factor).*; + if (self.fp < fp_adjust_factor) return null; if (self.first_addr) |addr| { - while (self.fp != 0) : (self.fp = @intToPtr(*const usize, self.fp).*) { - const return_address = @intToPtr(*const usize, self.fp + @sizeOf(usize)).*; + while (self.fp >= fp_adjust_factor) : (self.fp = @intToPtr(*const usize, self.fp - fp_adjust_factor).*) { + const return_address = @intToPtr(*const usize, self.fp - fp_adjust_factor + @sizeOf(usize)).*; if (addr == return_address) { self.first_addr = null; return return_address; @@ -295,7 +304,7 @@ pub const StackIterator = struct { } } - const return_address = @intToPtr(*const usize, self.fp + @sizeOf(usize)).*; + const return_address = @intToPtr(*const usize, self.fp - fp_adjust_factor + @sizeOf(usize)).*; return return_address; } }; diff --git a/lib/std/elf.zig b/lib/std/elf.zig index 37635895fd..b3aea3e5c6 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -338,6 +338,7 @@ pub const Arch = enum { IA_64, x86_64, AArch64, + RiscV, }; pub const SectionHeader = struct { @@ -428,6 +429,7 @@ pub const Elf = struct { 0x32 => Arch.IA_64, 0x3E => Arch.x86_64, 0xb7 => Arch.AArch64, + 0xf3 => Arch.RiscV, else => return error.InvalidFormat, }; diff --git a/src/analyze.cpp b/src/analyze.cpp index a38766bc25..399966d041 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1787,6 +1787,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc if (!analyze_const_align(g, child_scope, fn_proto->align_expr, &fn_type_id.alignment)) { return g->builtin_types.entry_invalid; } + fn_entry->align_bytes = fn_type_id.alignment; } if (fn_proto->return_var_token != nullptr) { @@ -3327,7 +3328,9 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry); if (fn_proto->section_expr != nullptr) { - analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name); + if (!analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name)) { + fn_table_entry->type_entry = g->builtin_types.entry_invalid; + } } if (fn_table_entry->type_entry->id == ZigTypeIdInvalid) { diff --git a/test/stage1/behavior/align.zig b/test/stage1/behavior/align.zig index 266e5d3519..bb40270cda 100644 --- a/test/stage1/behavior/align.zig +++ b/test/stage1/behavior/align.zig @@ -328,3 +328,10 @@ test "align(@alignOf(T)) T does not force resolution of T" { _ = async S.doTheTest(); expect(S.ok); } + +test "align(N) on functions" { + expect((@ptrToInt(overaligned_fn) & (0x1000 - 1)) == 0); +} +fn overaligned_fn() align(0x1000) i32 { + return 42; +}