Commit ba5e64ff6b

Jacob Young <jacobly0@users.noreply.github.com>
2025-02-07 02:57:58
x86_64: fix backend assertion failures
Fixes the backend portion of #22798
1 parent a8af36a
Changed files (3)
src
src/arch/x86_64/CodeGen.zig
@@ -63262,17 +63262,27 @@ fn genSetReg(
             });
         },
         .lea_symbol => |sym_off| switch (self.bin_file.tag) {
-            .elf, .macho => try self.asmRegisterMemory(
-                .{ ._, .lea },
-                dst_reg.to64(),
-                .{
-                    .base = .{ .reloc = sym_off.sym_index },
-                    .mod = .{ .rm = .{
-                        .size = .qword,
-                        .disp = sym_off.off,
-                    } },
-                },
-            ),
+            .elf, .macho => {
+                try self.asmRegisterMemory(
+                    .{ ._, .lea },
+                    dst_reg.to64(),
+                    .{
+                        .base = .{ .reloc = sym_off.sym_index },
+                        .mod = .{ .rm = .{ .size = .qword } },
+                    },
+                );
+                if (sym_off.off != 0) try self.asmRegisterMemory(
+                    .{ ._, .lea },
+                    dst_reg.to64(),
+                    .{
+                        .base = .{ .reg = dst_reg.to64() },
+                        .mod = .{ .rm = .{
+                            .size = .qword,
+                            .disp = sym_off.off,
+                        } },
+                    },
+                );
+            },
             else => return self.fail("TODO emit symbol sequence on {s}", .{
                 @tagName(self.bin_file.tag),
             }),
src/link/Elf/ZigObject.zig
@@ -360,7 +360,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
                     const target_unit = sect.getUnit(reloc.target_unit);
                     const r_offset = unit.off + reloc.source_off;
                     const r_addend: i64 = @intCast(target_unit.off + reloc.target_off + (if (reloc.target_entry.unwrap()) |target_entry|
-                        target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sect, dwarf).off
+                        target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(target_unit, sect, dwarf).off
                     else
                         0));
                     const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
@@ -388,7 +388,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
                     const target_unit = target_sec.getUnit(reloc.target_unit);
                     const r_offset = unit.off + reloc.source_off;
                     const r_addend: i64 = @intCast(target_unit.off + reloc.target_off + (if (reloc.target_entry.unwrap()) |target_entry|
-                        target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sect, dwarf).off
+                        target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(target_unit, sect, dwarf).off
                     else
                         0));
                     const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
@@ -422,7 +422,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
                         const target_unit = sect.getUnit(reloc.target_unit);
                         const r_offset = entry_off + reloc.source_off;
                         const r_addend: i64 = @intCast(target_unit.off + reloc.target_off + (if (reloc.target_entry.unwrap()) |target_entry|
-                            target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sect, dwarf).off
+                            target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(target_unit, sect, dwarf).off
                         else
                             0));
                         const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
@@ -450,7 +450,7 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
                         const target_unit = target_sec.getUnit(reloc.target_unit);
                         const r_offset = entry_off + reloc.source_off;
                         const r_addend: i64 = @intCast(target_unit.off + reloc.target_off + (if (reloc.target_entry.unwrap()) |target_entry|
-                            target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sect, dwarf).off
+                            target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(target_unit, sect, dwarf).off
                         else
                             0));
                         const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
src/link/Dwarf.zig
@@ -735,7 +735,7 @@ const Unit = struct {
             try dwarf.resolveReloc(
                 unit_off + reloc.source_off,
                 target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry|
-                    target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off
+                    target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(target_unit, sec, dwarf).off
                 else
                     0) + reloc.target_off,
                 dwarf.sectionOffsetBytes(),
@@ -749,7 +749,7 @@ const Unit = struct {
             try dwarf.resolveReloc(
                 unit_off + reloc.source_off,
                 target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry|
-                    target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off
+                    target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(target_unit, sec, dwarf).off
                 else
                     0) + reloc.target_off,
                 dwarf.sectionOffsetBytes(),
@@ -1000,7 +1000,7 @@ const Entry = struct {
             try dwarf.resolveReloc(
                 entry_off + reloc.source_off,
                 target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry|
-                    target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off
+                    target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(target_unit, sec, dwarf).off
                 else
                     0) + reloc.target_off,
                 dwarf.sectionOffsetBytes(),
@@ -1014,7 +1014,7 @@ const Entry = struct {
             try dwarf.resolveReloc(
                 entry_off + reloc.source_off,
                 target_unit.off + (if (reloc.target_entry.unwrap()) |target_entry|
-                    target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sec, dwarf).off
+                    target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(target_unit, sec, dwarf).off
                 else
                     0) + reloc.target_off,
                 dwarf.sectionOffsetBytes(),
@@ -1850,7 +1850,7 @@ pub const WipNav = struct {
         const ty = value.typeOf(zcu);
         if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null);
         if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());
-        if (ip.isFunctionType(ty.toIntern())) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav);
+        if (ip.isFunctionType(ty.toIntern()) and !value.isUndef(zcu)) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav);
         const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern());
         const unit: Unit.Index = .main;
         if (gop.found_existing) return .{ unit, gop.value_ptr.* };