| ... | ... | @@ -49,6 +49,7 @@ shndx: struct { |
| 49 | 49 | debug_info: Section.Index, |
| 50 | 50 | debug_line: Section.Index, |
| 51 | 51 | debug_line_str: Section.Index, |
| 52 | debug_rnglists: Section.Index, |
| 52 | 53 | debug_str: Section.Index, |
| 53 | 54 | debug_str_offsets: Section.Index, |
| 54 | 55 | // These sections are created only as needed, and are initially `.UNDEF`. |
| ... | ... | @@ -212,6 +213,8 @@ dwarf_units: std.ArrayList(struct { |
| 212 | 213 | debug_info_header_first_node_reloc: NodeReloc.Index, |
| 213 | 214 | debug_line_header_first_target_reloc: NodeReloc.Index, |
| 214 | 215 | debug_line_header_first_node_reloc: NodeReloc.Index, |
| 216 | debug_rnglists_first_target_reloc: NodeReloc.Index, |
| 217 | debug_rnglists_symbol_relocs: std.array_hash_map.Auto(SymbolReloc.Index, void), |
| 215 | 218 | }), |
| 216 | 219 | dwarf_values: std.ArrayList(struct { |
| 217 | 220 | debug_info_first_target_reloc: NodeReloc.Index, |
| ... | ... | @@ -304,6 +307,7 @@ const Node = union(enum) { |
| 304 | 307 | unit_debug_info_header: Dwarf.Unit.Index, |
| 305 | 308 | unit_debug_line: Dwarf.Unit.Index, |
| 306 | 309 | unit_debug_line_header: Dwarf.Unit.Index, |
| 310 | unit_debug_rnglists: Dwarf.Unit.Index, |
| 307 | 311 | |
| 308 | 312 | value_debug_info: link.ConstPool.Index, |
| 309 | 313 | global_debug_info: Dwarf.Global.Index, |
| ... | ... | @@ -1808,9 +1812,14 @@ const NodeReloc = struct { |
| 1808 | 1812 | .none => { |
| 1809 | 1813 | const first_target_reloc = switch (elf.getNode(reloc.target)) { |
| 1810 | 1814 | else => unreachable, |
| 1815 | .debug_shared => |ss| &elf.dwarf_shared.getPtr(ss).first_target_reloc, |
| 1811 | 1816 | .unit_frame_cie => |ui| &elf.dwarf_units.items[@backingInt(ui)].frame_cie_first_target_reloc, |
| 1812 | 1817 | .unit_debug_info_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_target_reloc, |
| 1813 | 1818 | .unit_debug_line_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_target_reloc, |
| 1819 | .unit_debug_rnglists => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_rnglists_first_target_reloc, |
| 1820 | .value_debug_info => |vi| &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_target_reloc, |
| 1821 | .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc, |
| 1822 | .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc, |
| 1814 | 1823 | }; |
| 1815 | 1824 | first_target_reloc.* = reloc.next; |
| 1816 | 1825 | }, |
| ... | ... | @@ -3258,6 +3267,7 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId { |
| 3258 | 3267 | .unit_debug_info_header, |
| 3259 | 3268 | .unit_debug_line, |
| 3260 | 3269 | .unit_debug_line_header, |
| 3270 | .unit_debug_rnglists, |
| 3261 | 3271 | .value_debug_info, |
| 3262 | 3272 | .global_debug_info, |
| 3263 | 3273 | .func_frame_fde, |
| ... | ... | @@ -3276,8 +3286,8 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId { |
| 3276 | 3286 | pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) link.Error!link.File.SymbolId { |
| 3277 | 3287 | const diags = &elf.base.comp.link_diags; |
| 3278 | 3288 | return elf.lazySymbolInner(lazy) catch |err| switch (err) { |
| 3279 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3280 | 3289 | else => |e| return e, |
| 3290 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3281 | 3291 | }; |
| 3282 | 3292 | } |
| 3283 | 3293 | fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.SymbolId { |
| ... | ... | @@ -3331,8 +3341,8 @@ pub const ExternSymbolOpts = struct { |
| 3331 | 3341 | pub fn externSymbol(elf: *Elf, opts: ExternSymbolOpts) link.Error!link.File.SymbolId { |
| 3332 | 3342 | const diags = &elf.base.comp.link_diags; |
| 3333 | 3343 | return (elf.externSymbolInner(opts) catch |err| switch (err) { |
| 3334 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3335 | 3344 | else => |e| return e, |
| 3345 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3336 | 3346 | }).toTypeErased(); |
| 3337 | 3347 | } |
| 3338 | 3348 | fn externSymbolInner(elf: *Elf, opts: ExternSymbolOpts) Error!Symbol.Id { |
| ... | ... | @@ -3372,15 +3382,15 @@ pub fn addReloc( |
| 3372 | 3382 | const node: MappedFile.Node.Index = Node.fromAtom(atom); |
| 3373 | 3383 | const diags = &elf.base.comp.link_diags; |
| 3374 | 3384 | elf.ensureUnusedRelocCapacity(node, 1) catch |err| switch (err) { |
| 3375 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3376 | 3385 | else => |e| return e, |
| 3386 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3377 | 3387 | }; |
| 3378 | 3388 | elf.addRelocAssumeCapacity(node, offset, .fromTypeErased(target), addend, @"type") catch |err| switch (err) { |
| 3389 | else => |e| return e, |
| 3379 | 3390 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3380 | 3391 | error.UnknownRelocation => unreachable, // codegen bug |
| 3381 | 3392 | error.NonStaticRelocation => unreachable, // codegen bug |
| 3382 | 3393 | error.UnimplementedRelocation => unreachable, // codegen bug (asking Elf2 for a relocation it does not support) |
| 3383 | | else => |e| return e, |
| 3384 | 3394 | }; |
| 3385 | 3395 | } |
| 3386 | 3396 | pub fn addNodeReloc( |
| ... | ... | @@ -3393,12 +3403,12 @@ pub fn addNodeReloc( |
| 3393 | 3403 | ) link.Error!void { |
| 3394 | 3404 | const diags = &elf.base.comp.link_diags; |
| 3395 | 3405 | elf.ensureUnusedRelocCapacity(node, 1) catch |err| switch (err) { |
| 3396 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3397 | 3406 | else => |e| return e, |
| 3407 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3398 | 3408 | }; |
| 3399 | 3409 | elf.addNodeRelocAssumeCapacity(node, offset, target, addend, @"type") catch |err| switch (err) { |
| 3400 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3401 | 3410 | else => |e| return e, |
| 3411 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3402 | 3412 | }; |
| 3403 | 3413 | } |
| 3404 | 3414 | pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.File.SymbolId { |
| ... | ... | @@ -3416,8 +3426,8 @@ pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.Fil |
| 3416 | 3426 | }); |
| 3417 | 3427 | } |
| 3418 | 3428 | const nmi = elf.navMapIndex(zcu, nav_index) catch |err| switch (err) { |
| 3419 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3420 | 3429 | else => |e| return e, |
| 3430 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3421 | 3431 | }; |
| 3422 | 3432 | const s: Symbol.Id = .local(nmi.symbol(elf)); |
| 3423 | 3433 | return s.toTypeErased(); |
| ... | ... | @@ -3429,8 +3439,8 @@ pub fn uavSymbol( |
| 3429 | 3439 | ) link.Error!link.File.SymbolId { |
| 3430 | 3440 | const diags = &elf.base.comp.link_diags; |
| 3431 | 3441 | const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) { |
| 3432 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3433 | 3442 | else => |e| return e, |
| 3443 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3434 | 3444 | }; |
| 3435 | 3445 | const s: Symbol.Id = .local(umi.symbol(elf)); |
| 3436 | 3446 | return s.toTypeErased(); |
| ... | ... | @@ -3470,8 +3480,8 @@ pub fn lowerUav( |
| 3470 | 3480 | _ = pt; |
| 3471 | 3481 | const diags = &elf.base.comp.link_diags; |
| 3472 | 3482 | const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) { |
| 3473 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3474 | 3483 | else => |e| return e, |
| 3484 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 3475 | 3485 | }; |
| 3476 | 3486 | const s: Symbol.Id = .local(umi.symbol(elf)); |
| 3477 | 3487 | return s.toTypeErased(); |
| ... | ... | @@ -3705,6 +3715,7 @@ fn create( |
| 3705 | 3715 | .debug_info = .UNDEF, |
| 3706 | 3716 | .debug_line = .UNDEF, |
| 3707 | 3717 | .debug_line_str = .UNDEF, |
| 3718 | .debug_rnglists = .UNDEF, |
| 3708 | 3719 | .debug_str = .UNDEF, |
| 3709 | 3720 | .debug_str_offsets = .UNDEF, |
| 3710 | 3721 | .init_array = .UNDEF, |
| ... | ... | @@ -3819,6 +3830,7 @@ pub fn deinit(elf: *Elf) void { |
| 3819 | 3830 | elf.changed_symtab_index.deinit(gpa); |
| 3820 | 3831 | |
| 3821 | 3832 | elf.dwarf.deinit(); |
| 3833 | for (elf.dwarf_units.items) |*dwarf_unit| dwarf_unit.debug_rnglists_symbol_relocs.deinit(gpa); |
| 3822 | 3834 | elf.dwarf_units.deinit(gpa); |
| 3823 | 3835 | elf.dwarf_values.deinit(gpa); |
| 3824 | 3836 | elf.dwarf_globals.deinit(gpa); |
| ... | ... | @@ -3900,6 +3912,7 @@ fn initHeaders( |
| 3900 | 3912 | shnum += 1; // .debug_info |
| 3901 | 3913 | shnum += 1; // .debug_line |
| 3902 | 3914 | shnum += 1; // .debug_line_str |
| 3915 | shnum += 1; // .debug_rnglists |
| 3903 | 3916 | shnum += 1; // .debug_str |
| 3904 | 3917 | shnum += 1; // .debug_str_offsets |
| 3905 | 3918 | }, |
| ... | ... | @@ -4744,22 +4757,22 @@ fn initHeaders( |
| 4744 | 4757 | elf.plt_first_symbol_reloc = @fromBackingInt(@intCast(elf.symbol_relocs.items.len)); |
| 4745 | 4758 | try elf.ensureUnusedRelocCapacity(plt_ni, 3); |
| 4746 | 4759 | elf.addRelocAssumeCapacity(plt_ni, 0, got_plt_sym, 0, .{ .LARCH = .PCALA_HI20 }) catch |err| switch (err) { |
| 4760 | else => |e| return e, |
| 4747 | 4761 | error.UnknownRelocation => unreachable, |
| 4748 | 4762 | error.NonStaticRelocation => unreachable, |
| 4749 | 4763 | error.UnimplementedRelocation => unreachable, |
| 4750 | | else => |e| return e, |
| 4751 | 4764 | }; |
| 4752 | 4765 | elf.addRelocAssumeCapacity(plt_ni, 8, got_plt_sym, 0, .{ .LARCH = .PCALA_LO12 }) catch |err| switch (err) { |
| 4766 | else => |e| return e, |
| 4753 | 4767 | error.UnknownRelocation => unreachable, |
| 4754 | 4768 | error.NonStaticRelocation => unreachable, |
| 4755 | 4769 | error.UnimplementedRelocation => unreachable, |
| 4756 | | else => |e| return e, |
| 4757 | 4770 | }; |
| 4758 | 4771 | elf.addRelocAssumeCapacity(plt_ni, 16, got_plt_sym, 0, .{ .LARCH = .PCALA_LO12 }) catch |err| switch (err) { |
| 4772 | else => |e| return e, |
| 4759 | 4773 | error.UnknownRelocation => unreachable, |
| 4760 | 4774 | error.NonStaticRelocation => unreachable, |
| 4761 | 4775 | error.UnimplementedRelocation => unreachable, |
| 4762 | | else => |e| return e, |
| 4763 | 4776 | }; |
| 4764 | 4777 | }, |
| 4765 | 4778 | .SPARCV9 => {}, |
| ... | ... | @@ -5008,6 +5021,10 @@ fn initHeaders( |
| 5008 | 5021 | .name = ".debug_line_str", |
| 5009 | 5022 | .flags = .{ .MERGE = true, .STRINGS = true }, |
| 5010 | 5023 | }); |
| 5024 | elf.shndx.debug_rnglists = try elf.addSection(elf.ni.elf, .{ |
| 5025 | .name = ".debug_rnglists", |
| 5026 | .node_align = elf.mf.flags.block_size, |
| 5027 | }); |
| 5011 | 5028 | elf.shndx.debug_str = try elf.addSection(elf.ni.elf, .{ |
| 5012 | 5029 | .name = ".debug_str", |
| 5013 | 5030 | .flags = .{ .MERGE = true, .STRINGS = true }, |
| ... | ... | @@ -5118,6 +5135,7 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index { |
| 5118 | 5135 | .unit_frame, |
| 5119 | 5136 | .unit_debug_info, |
| 5120 | 5137 | .unit_debug_line, |
| 5138 | .unit_debug_rnglists, |
| 5121 | 5139 | => elf.getNode(ni.parent(&elf.mf).unwrap().?).section, |
| 5122 | 5140 | .unit_frame_cie, |
| 5123 | 5141 | .unit_debug_info_header, |
| ... | ... | @@ -5157,6 +5175,7 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { |
| 5157 | 5175 | .unit_debug_info_header, |
| 5158 | 5176 | .unit_debug_line, |
| 5159 | 5177 | .unit_debug_line_header, |
| 5178 | .unit_debug_rnglists, |
| 5160 | 5179 | .value_debug_info, |
| 5161 | 5180 | .global_debug_info, |
| 5162 | 5181 | .func_frame_fde, |
| ... | ... | @@ -5190,6 +5209,7 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { |
| 5190 | 5209 | .unit_frame_cie, |
| 5191 | 5210 | .unit_debug_info_header, |
| 5192 | 5211 | .unit_debug_line_header, |
| 5212 | .unit_debug_rnglists, |
| 5193 | 5213 | .value_debug_info, |
| 5194 | 5214 | .global_debug_info, |
| 5195 | 5215 | .func_frame_fde, |
| ... | ... | @@ -5210,7 +5230,12 @@ fn getNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 { |
| 5210 | 5230 | /// Asserts that `ni` must be a node which supports relocations (see `Elf.Node`). Does not support |
| 5211 | 5231 | /// the special-case sections '.plt', '.dynamic', and '.eh_frame_hdr'. |
| 5212 | 5232 | fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { |
| 5213 | | const symbol_relocs: ?*SymbolReloc.Index, const node_relocs: ?*NodeReloc.Index, const got_relocs: ?*GotReloc.Index = switch (elf.getNode(ni)) { |
| 5233 | const opts: struct { |
| 5234 | ignore_node: MappedFile.Node.Index.Optional = .none, |
| 5235 | first_symbol_reloc: ?*SymbolReloc.Index = null, |
| 5236 | first_node_reloc: ?*NodeReloc.Index = null, |
| 5237 | first_got_reloc: ?*GotReloc.Index = null, |
| 5238 | } = switch (elf.getNode(ni)) { |
| 5214 | 5239 | .archive, |
| 5215 | 5240 | .archive_header, |
| 5216 | 5241 | .archive_input_member, |
| ... | ... | @@ -5231,65 +5256,55 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { |
| 5231 | 5256 | .section_manual_size, |
| 5232 | 5257 | => unreachable, // cannot contain relocs (.plt, .dynamic, and .eh_frame_hdr unsupported) |
| 5233 | 5258 | .input_section => |isi| .{ |
| 5234 | | &elf.input_sections.items[@backingInt(isi)].first_symbol_reloc, |
| 5235 | | null, |
| 5236 | | &elf.input_sections.items[@backingInt(isi)].first_got_reloc, |
| 5259 | .first_symbol_reloc = &elf.input_sections.items[@backingInt(isi)].first_symbol_reloc, |
| 5260 | .first_got_reloc = &elf.input_sections.items[@backingInt(isi)].first_got_reloc, |
| 5237 | 5261 | }, |
| 5238 | 5262 | .nav => |nmi| .{ |
| 5239 | | &elf.navs.values()[@backingInt(nmi)].first_symbol_reloc, |
| 5240 | | null, |
| 5241 | | &elf.navs.values()[@backingInt(nmi)].first_got_reloc, |
| 5263 | .first_symbol_reloc = &elf.navs.values()[@backingInt(nmi)].first_symbol_reloc, |
| 5264 | .first_got_reloc = &elf.navs.values()[@backingInt(nmi)].first_got_reloc, |
| 5242 | 5265 | }, |
| 5243 | 5266 | .uav => |umi| .{ |
| 5244 | | &elf.uavs.values()[@backingInt(umi)].first_symbol_reloc, |
| 5245 | | null, |
| 5246 | | null, |
| 5267 | .first_symbol_reloc = &elf.uavs.values()[@backingInt(umi)].first_symbol_reloc, |
| 5247 | 5268 | }, |
| 5248 | 5269 | inline .lazy_code, .lazy_const_data => |lmi| .{ |
| 5249 | | &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_symbol_reloc, |
| 5250 | | null, |
| 5251 | | &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_got_reloc, |
| 5270 | .first_symbol_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_symbol_reloc, |
| 5271 | .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_got_reloc, |
| 5252 | 5272 | }, |
| 5253 | 5273 | .unit_debug_info_header => |ui| .{ |
| 5254 | | null, |
| 5255 | | &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_node_reloc, |
| 5256 | | null, |
| 5274 | .first_node_reloc = &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_node_reloc, |
| 5257 | 5275 | }, |
| 5258 | 5276 | .unit_debug_line_header => |ui| .{ |
| 5259 | | null, |
| 5260 | | &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_node_reloc, |
| 5261 | | null, |
| 5277 | .first_node_reloc = &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_node_reloc, |
| 5262 | 5278 | }, |
| 5279 | .unit_debug_rnglists => unreachable, // unsupported |
| 5263 | 5280 | .value_debug_info => |vi| .{ |
| 5264 | | &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_symbol_reloc, |
| 5265 | | &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_node_reloc, |
| 5266 | | null, |
| 5281 | .first_symbol_reloc = &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_symbol_reloc, |
| 5282 | .first_node_reloc = &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_node_reloc, |
| 5267 | 5283 | }, |
| 5268 | 5284 | .global_debug_info => |gi| .{ |
| 5269 | | &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_symbol_reloc, |
| 5270 | | &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_node_reloc, |
| 5271 | | null, |
| 5285 | .first_symbol_reloc = &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_symbol_reloc, |
| 5286 | .first_node_reloc = &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_node_reloc, |
| 5272 | 5287 | }, |
| 5273 | 5288 | .func_frame_fde => |fi| .{ |
| 5274 | | &elf.dwarf_funcs.items[@backingInt(fi)].frame_fde_first_symbol_reloc, |
| 5275 | | &elf.dwarf_funcs.items[@backingInt(fi)].frame_fde_first_node_reloc, |
| 5276 | | null, |
| 5289 | .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].frame_fde_first_symbol_reloc, |
| 5290 | .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].frame_fde_first_node_reloc, |
| 5277 | 5291 | }, |
| 5278 | 5292 | .func_debug_info => |fi| .{ |
| 5279 | | &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_symbol_reloc, |
| 5280 | | &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_node_reloc, |
| 5281 | | null, |
| 5293 | .ignore_node = fi.get(&elf.dwarf).debug_line_ni, |
| 5294 | .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_symbol_reloc, |
| 5295 | .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_node_reloc, |
| 5282 | 5296 | }, |
| 5283 | 5297 | .func_debug_line => |fi| .{ |
| 5284 | | &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_symbol_reloc, |
| 5285 | | &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_node_reloc, |
| 5286 | | null, |
| 5298 | .ignore_node = fi.get(&elf.dwarf).debug_info_ni, |
| 5299 | .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_symbol_reloc, |
| 5300 | .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_node_reloc, |
| 5287 | 5301 | }, |
| 5288 | 5302 | }; |
| 5289 | 5303 | |
| 5290 | | if (symbol_relocs) |ptr| { |
| 5304 | if (opts.first_symbol_reloc) |ptr| { |
| 5291 | 5305 | if (ptr.* != .none) { |
| 5292 | 5306 | for (elf.symbol_relocs.items[@backingInt(ptr.*)..], @backingInt(ptr.*)..) |*reloc, index| { |
| 5307 | if (reloc.node.toOptional() == opts.ignore_node) continue; |
| 5293 | 5308 | if (reloc.node != ni) break; |
| 5294 | 5309 | reloc.delete(elf, @fromBackingInt(@intCast(index))); |
| 5295 | 5310 | } |
| ... | ... | @@ -5297,9 +5312,10 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { |
| 5297 | 5312 | ptr.* = @fromBackingInt(@intCast(elf.symbol_relocs.items.len)); |
| 5298 | 5313 | } |
| 5299 | 5314 | |
| 5300 | | if (node_relocs) |ptr| { |
| 5315 | if (opts.first_node_reloc) |ptr| { |
| 5301 | 5316 | if (ptr.* != .none) { |
| 5302 | 5317 | for (elf.node_relocs.items[@backingInt(ptr.*)..]) |*reloc| { |
| 5318 | if (reloc.node.toOptional() == opts.ignore_node) continue; |
| 5303 | 5319 | if (reloc.node != ni) break; |
| 5304 | 5320 | reloc.delete(elf); |
| 5305 | 5321 | } |
| ... | ... | @@ -5307,9 +5323,10 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { |
| 5307 | 5323 | ptr.* = @fromBackingInt(@intCast(elf.node_relocs.items.len)); |
| 5308 | 5324 | } |
| 5309 | 5325 | |
| 5310 | | if (got_relocs) |ptr| { |
| 5326 | if (opts.first_got_reloc) |ptr| { |
| 5311 | 5327 | if (ptr.* != .none) { |
| 5312 | 5328 | for (elf.got_relocs.items[@backingInt(ptr.*)..]) |*reloc| { |
| 5329 | if (reloc.node == opts.ignore_node) continue; |
| 5313 | 5330 | if (reloc.node != ni.toOptional()) break; |
| 5314 | 5331 | reloc.delete(elf); |
| 5315 | 5332 | } |
| ... | ... | @@ -5324,12 +5341,16 @@ fn flushMovedNodeRelocs( |
| 5324 | 5341 | elf: *Elf, |
| 5325 | 5342 | node: MappedFile.Node.Index, |
| 5326 | 5343 | node_vaddr: u64, |
| 5327 | | first_symbol_reloc: SymbolReloc.Index, |
| 5328 | | first_node_reloc: NodeReloc.Index, |
| 5329 | | first_got_reloc: GotReloc.Index, |
| 5344 | opts: struct { |
| 5345 | ignore_node: MappedFile.Node.Index.Optional = .none, |
| 5346 | first_symbol_reloc: SymbolReloc.Index = .none, |
| 5347 | first_node_reloc: NodeReloc.Index = .none, |
| 5348 | first_got_reloc: GotReloc.Index = .none, |
| 5349 | }, |
| 5330 | 5350 | ) void { |
| 5331 | | if (first_symbol_reloc != .none) { |
| 5332 | | for (elf.symbol_relocs.items[@backingInt(first_symbol_reloc)..]) |*reloc| { |
| 5351 | if (opts.first_symbol_reloc != .none) { |
| 5352 | for (elf.symbol_relocs.items[@backingInt(opts.first_symbol_reloc)..]) |*reloc| { |
| 5353 | if (reloc.node.toOptional() == opts.ignore_node) continue; |
| 5333 | 5354 | if (reloc.node != node) break; |
| 5334 | 5355 | if (reloc.rela_index.unwrap()) |rela_index| { |
| 5335 | 5356 | // The node has moved, so the offset of the relocation within the section might have |
| ... | ... | @@ -5345,8 +5366,9 @@ fn flushMovedNodeRelocs( |
| 5345 | 5366 | } |
| 5346 | 5367 | } |
| 5347 | 5368 | |
| 5348 | | if (first_node_reloc != .none) { |
| 5349 | | for (elf.node_relocs.items[@backingInt(first_node_reloc)..]) |*reloc| { |
| 5369 | if (opts.first_node_reloc != .none) { |
| 5370 | for (elf.node_relocs.items[@backingInt(opts.first_node_reloc)..]) |*reloc| { |
| 5371 | if (reloc.node.toOptional() == opts.ignore_node) continue; |
| 5350 | 5372 | if (reloc.node != node) break; |
| 5351 | 5373 | if (reloc.rela_index.unwrap()) |rela_index| { |
| 5352 | 5374 | assert(elf.ehdrType() == .REL); |
| ... | ... | @@ -5360,8 +5382,9 @@ fn flushMovedNodeRelocs( |
| 5360 | 5382 | } |
| 5361 | 5383 | } |
| 5362 | 5384 | |
| 5363 | | if (first_got_reloc != .none) { |
| 5364 | | for (elf.got_relocs.items[@backingInt(first_got_reloc)..]) |*reloc| { |
| 5385 | if (opts.first_got_reloc != .none) { |
| 5386 | for (elf.got_relocs.items[@backingInt(opts.first_got_reloc)..]) |*reloc| { |
| 5387 | if (reloc.node == opts.ignore_node) continue; |
| 5365 | 5388 | if (reloc.node != node.toOptional()) break; |
| 5366 | 5389 | reloc.apply(elf); |
| 5367 | 5390 | } |
| ... | ... | @@ -5814,6 +5837,7 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node |
| 5814 | 5837 | })) |shndx| { |
| 5815 | 5838 | break :section shndx; |
| 5816 | 5839 | } else |err| switch (err) { |
| 5840 | else => |e| return e, |
| 5817 | 5841 | error.StripSection, |
| 5818 | 5842 | error.TlsSectionUnavailable, |
| 5819 | 5843 | error.UnsupportedSectionFlags, |
| ... | ... | @@ -5821,7 +5845,6 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node |
| 5821 | 5845 | error.SectionFlagsConflict, |
| 5822 | 5846 | => {}, // fall back to default behavior below |
| 5823 | 5847 | |
| 5824 | | else => |e| return e, |
| 5825 | 5848 | } |
| 5826 | 5849 | } |
| 5827 | 5850 | if (elf.base.comp.config.any_non_single_threaded and nav.resolved.?.@"threadlocal") { |
| ... | ... | @@ -6074,8 +6097,8 @@ fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (Load |
| 6074 | 6097 | strtab.clearRetainingCapacity(); |
| 6075 | 6098 | try strtab.ensureTotalCapacityPrecise(size); |
| 6076 | 6099 | r.streamExact(&strtab.writer, size) catch |err| switch (err) { |
| 6077 | | error.WriteFailed => return error.OutOfMemory, |
| 6078 | 6100 | else => |e| return e, |
| 6101 | error.WriteFailed => return error.OutOfMemory, |
| 6079 | 6102 | }; |
| 6080 | 6103 | continue; |
| 6081 | 6104 | } |
| ... | ... | @@ -6106,8 +6129,8 @@ fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (Load |
| 6106 | 6129 | } |
| 6107 | 6130 | try fr.seekTo(std.mem.alignForward(u64, offset + size, 2)); |
| 6108 | 6131 | } else |err| switch (err) { |
| 6109 | | error.EndOfStream => if (!fr.atEnd()) return error.EndOfStream, |
| 6110 | 6132 | else => |e| return e, |
| 6133 | error.EndOfStream => if (!fr.atEnd()) return error.EndOfStream, |
| 6111 | 6134 | } |
| 6112 | 6135 | } |
| 6113 | 6136 | fn fmtMemberString(member: ?[]const u8) std.fmt.Alt(?[]const u8, memberStringEscape) { |
| ... | ... | @@ -6273,6 +6296,7 @@ fn loadObject( |
| 6273 | 6296 | .flags = section.shdr.flags.shf, |
| 6274 | 6297 | .entsize = section.shdr.entsize, |
| 6275 | 6298 | }) catch |err| switch (err) { |
| 6299 | else => |e| return e, |
| 6276 | 6300 | error.StripSection => continue, |
| 6277 | 6301 | error.TlsSectionUnavailable => return diags.failParse( |
| 6278 | 6302 | path, |
| ... | ... | @@ -6303,7 +6327,6 @@ fn loadObject( |
| 6303 | 6327 | "flags of section '{s}' conflict with other inputs", |
| 6304 | 6328 | .{name}, |
| 6305 | 6329 | ), |
| 6306 | | else => |e| return e, |
| 6307 | 6330 | }; |
| 6308 | 6331 | if (section.shdr.flags.shf.COMPRESSED) { |
| 6309 | 6332 | // SHF_COMPRESSED is only allowed on non-alloc sections. |
| ... | ... | @@ -6585,6 +6608,7 @@ fn loadObject( |
| 6585 | 6608 | rel.addend, |
| 6586 | 6609 | rt, |
| 6587 | 6610 | ) catch |err| switch (err) { |
| 6611 | else => |e| return e, |
| 6588 | 6612 | error.UnknownRelocation => diags.addParseError( |
| 6589 | 6613 | path, |
| 6590 | 6614 | "unknown relocation type '{f}'", |
| ... | ... | @@ -6600,7 +6624,6 @@ fn loadObject( |
| 6600 | 6624 | "TODO(Elf2): unimplemented relocation type '{f}'", |
| 6601 | 6625 | .{rt.fmt(elf)}, |
| 6602 | 6626 | ), |
| 6603 | | else => |e| return e, |
| 6604 | 6627 | }; |
| 6605 | 6628 | } |
| 6606 | 6629 | }, |
| ... | ... | @@ -6997,7 +7020,7 @@ pub fn prelink(elf: *Elf, prog_node: std.Progress.Node) link.Error!void { |
| 6997 | 7020 | fn prelinkInner(elf: *Elf) Error!void { |
| 6998 | 7021 | const comp = elf.base.comp; |
| 6999 | 7022 | const gpa = comp.gpa; |
| 7000 | | if (comp.zcu) |zcu| self_hosted_codegen: { |
| 7023 | if (comp.zcu) |_| self_hosted_codegen: { |
| 7001 | 7024 | if (comp.config.use_llvm) break :self_hosted_codegen; |
| 7002 | 7025 | |
| 7003 | 7026 | // We're using self-hosted codegen---add an input representing the Zig "object". |
| ... | ... | @@ -7019,15 +7042,32 @@ fn prelinkInner(elf: *Elf) Error!void { |
| 7019 | 7042 | .extra = .{ .file_symbol = zcu_file_symbol }, |
| 7020 | 7043 | }; |
| 7021 | 7044 | elf.input_pending_index += 1; |
| 7045 | } |
| 7046 | } |
| 7047 | |
| 7048 | pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void { |
| 7049 | elf.zcuFilesReadyInner(zcu) catch |err| switch (err) { |
| 7050 | else => |e| return e, |
| 7051 | error.MappedFileIo => return elf.base.comp.link_diags.fail( |
| 7052 | "failed to write output file: {t}", |
| 7053 | .{elf.mf.io_err.?}, |
| 7054 | ), |
| 7055 | }; |
| 7056 | } |
| 7057 | fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void { |
| 7058 | const gpa = zcu.gpa; |
| 7022 | 7059 | |
| 7060 | if (elf.dwarf.units.count() == 0) { |
| 7023 | 7061 | try elf.dwarf.initUnits(zcu); |
| 7024 | | try elf.nodes.ensureUnusedCapacity(gpa, 4 + 4 + (4 + 4) * elf.dwarf.units.count()); |
| 7062 | try elf.nodes.ensureUnusedCapacity(gpa, 4 + 5 + 5 * elf.dwarf.units.count()); |
| 7025 | 7063 | try elf.dwarf_units.appendNTimes(gpa, .{ |
| 7026 | 7064 | .frame_cie_first_target_reloc = .none, |
| 7027 | 7065 | .debug_info_header_first_target_reloc = .none, |
| 7028 | 7066 | .debug_info_header_first_node_reloc = .none, |
| 7029 | 7067 | .debug_line_header_first_target_reloc = .none, |
| 7030 | 7068 | .debug_line_header_first_node_reloc = .none, |
| 7069 | .debug_rnglists_first_target_reloc = .none, |
| 7070 | .debug_rnglists_symbol_relocs = .empty, |
| 7031 | 7071 | }, elf.dwarf.units.count()); |
| 7032 | 7072 | |
| 7033 | 7073 | elf.dwarf.debug_abbrev.ni = |
| ... | ... | @@ -7046,11 +7086,12 @@ fn prelinkInner(elf: *Elf) Error!void { |
| 7046 | 7086 | .wrap(try elf.shndx.debug_str_offsets.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{})); |
| 7047 | 7087 | elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_str_offsets }); |
| 7048 | 7088 | |
| 7049 | | for ([4]Section.Index{ |
| 7089 | for ([5]Section.Index{ |
| 7050 | 7090 | elf.shndx.eh_frame, |
| 7051 | 7091 | elf.shndx.debug_frame, |
| 7052 | 7092 | elf.shndx.debug_info, |
| 7053 | 7093 | elf.shndx.debug_line, |
| 7094 | elf.shndx.debug_rnglists, |
| 7054 | 7095 | }) |debug_shndx| { |
| 7055 | 7096 | if (debug_shndx == .UNDEF) continue; |
| 7056 | 7097 | const debug_ni = debug_shndx.get(elf).ni; |
| ... | ... | @@ -7085,7 +7126,6 @@ fn prelinkInner(elf: *Elf) Error!void { |
| 7085 | 7126 | const debug_info_ni = |
| 7086 | 7127 | try debug_info_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ |
| 7087 | 7128 | .alignment = elf.mf.flags.block_size, |
| 7088 | | .next_moved = true, |
| 7089 | 7129 | .enable_next_moved = true, |
| 7090 | 7130 | }); |
| 7091 | 7131 | unit.debug_info_ni = .wrap(debug_info_ni); |
| ... | ... | @@ -7105,7 +7145,6 @@ fn prelinkInner(elf: *Elf) Error!void { |
| 7105 | 7145 | const debug_line_ni = |
| 7106 | 7146 | try debug_line_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ |
| 7107 | 7147 | .alignment = elf.mf.flags.block_size, |
| 7108 | | .next_moved = true, |
| 7109 | 7148 | .enable_next_moved = true, |
| 7110 | 7149 | }); |
| 7111 | 7150 | unit.debug_line_ni = .wrap(debug_line_ni); |
| ... | ... | @@ -7113,43 +7152,72 @@ fn prelinkInner(elf: *Elf) Error!void { |
| 7113 | 7152 | |
| 7114 | 7153 | unit.debug_line_header_ni = |
| 7115 | 7154 | .wrap(try debug_line_ni.addOnlyHeaderChild(&elf.mf, gpa, .{ |
| 7116 | | .next_moved = true, |
| 7155 | // Idle tasks are going to try to keep this up to date before we are able to |
| 7156 | // write out the full header, so just reserve space for them to do so. |
| 7157 | .size = elf.dwarf.unitLengthSize(), |
| 7117 | 7158 | .enable_next_moved = true, |
| 7118 | 7159 | })); |
| 7119 | 7160 | elf.nodes.appendAssumeCapacity(.{ .unit_debug_line_header = ui }); |
| 7120 | 7161 | }, |
| 7121 | 7162 | } |
| 7163 | switch (elf.shndx.debug_rnglists) { |
| 7164 | .UNDEF => {}, |
| 7165 | else => |debug_rnglists_shndx| { |
| 7166 | unit.debug_rnglists_ni = |
| 7167 | .wrap(try debug_rnglists_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ |
| 7168 | .next_moved = true, |
| 7169 | .enable_next_moved = true, |
| 7170 | })); |
| 7171 | elf.nodes.appendAssumeCapacity(.{ .unit_debug_rnglists = ui }); |
| 7172 | }, |
| 7173 | } |
| 7122 | 7174 | } |
| 7123 | 7175 | |
| 7124 | | for (0.., elf.dwarf.units.values()) |unit_index, *unit| { |
| 7125 | | const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index)); |
| 7126 | | if (elf.shndx.debug_info != .UNDEF) { |
| 7127 | | var header_nw: MappedFile.Node.Writer = undefined; |
| 7128 | | const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?; |
| 7129 | | debug_info_header_ni.writer(&elf.mf, gpa, &header_nw); |
| 7130 | | defer header_nw.deinit(); |
| 7131 | | elf.resetNodeRelocs(debug_info_header_ni); |
| 7132 | | elf.dwarf.genDebugInfoHeader(&header_nw, ui, zcu) catch |err| switch (err) { |
| 7133 | | error.WriteFailed => return header_nw.err.?, |
| 7176 | for (elf.dwarf.units.keys(), elf.dwarf.units.values()) |mod, *unit| { |
| 7177 | var drh_nw: MappedFile.Node.Writer = undefined; |
| 7178 | unit.debug_rnglists_ni.unwrap().?.writer(&elf.mf, gpa, &drh_nw); |
| 7179 | defer drh_nw.deinit(); |
| 7180 | const debug_rnglists_offsets_table_offset = |
| 7181 | elf.dwarf.genDebugRnglistsHeader(unit, &drh_nw) catch |err| switch (err) { |
| 7134 | 7182 | else => |e| return e, |
| 7183 | error.WriteFailed => return drh_nw.err.?, |
| 7135 | 7184 | }; |
| 7136 | | } |
| 7137 | | if (elf.shndx.debug_line != .UNDEF) { |
| 7138 | | var header_nw: MappedFile.Node.Writer = undefined; |
| 7139 | | const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?; |
| 7140 | | debug_line_header_ni.writer(&elf.mf, gpa, &header_nw); |
| 7141 | | defer header_nw.deinit(); |
| 7142 | | elf.resetNodeRelocs(debug_line_header_ni); |
| 7143 | | elf.dwarf.genDebugLineHeader(&header_nw.interface) catch |err| switch (err) { |
| 7144 | | error.WriteFailed => return header_nw.err.?, |
| 7145 | | }; |
| 7146 | | } |
| 7185 | |
| 7186 | var dih_nw: MappedFile.Node.Writer = undefined; |
| 7187 | const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?; |
| 7188 | debug_info_header_ni.writer(&elf.mf, gpa, &dih_nw); |
| 7189 | defer dih_nw.deinit(); |
| 7190 | elf.resetNodeRelocs(debug_info_header_ni); |
| 7191 | elf.dwarf.genDebugInfoHeader( |
| 7192 | mod, |
| 7193 | unit, |
| 7194 | &dih_nw, |
| 7195 | debug_rnglists_offsets_table_offset, |
| 7196 | zcu, |
| 7197 | ) catch |err| switch (err) { |
| 7198 | else => |e| return e, |
| 7199 | error.WriteFailed => return dih_nw.err.?, |
| 7200 | }; |
| 7147 | 7201 | } |
| 7148 | 7202 | } |
| 7149 | 7203 | } |
| 7150 | 7204 | |
| 7151 | | pub fn zcuFilesReady(elf: *Elf) link.Error!void { |
| 7152 | | _ = elf; // TODO jacobly |
| 7205 | fn flushFiles(elf: *Elf) Error!void { |
| 7206 | const gpa = elf.base.comp.gpa; |
| 7207 | if (elf.shndx.debug_line != .UNDEF) for (elf.dwarf.units.keys(), elf.dwarf.units.values()) |mod, *unit| { |
| 7208 | if (!unit.cleanFilesChanged()) continue; |
| 7209 | const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?; |
| 7210 | try debug_line_header_ni.moved(gpa, &elf.mf); |
| 7211 | try debug_line_header_ni.nextMoved(gpa, &elf.mf); |
| 7212 | var dlh_nw: MappedFile.Node.Writer = undefined; |
| 7213 | debug_line_header_ni.writer(&elf.mf, gpa, &dlh_nw); |
| 7214 | defer dlh_nw.deinit(); |
| 7215 | elf.resetNodeRelocs(debug_line_header_ni); |
| 7216 | elf.dwarf.genDebugLineHeader(mod, unit, &dlh_nw, elf.base.comp.zcu.?) catch |err| switch (err) { |
| 7217 | else => |e| return e, |
| 7218 | error.WriteFailed => return dlh_nw.err.?, |
| 7219 | }; |
| 7220 | }; |
| 7153 | 7221 | } |
| 7154 | 7222 | |
| 7155 | 7223 | fn prepareDynamic(elf: *Elf) Error!void { |
| ... | ... | @@ -7952,6 +8020,10 @@ fn addNodeRelocAssumeCapacity( |
| 7952 | 8020 | .unit_frame_cie => |ui| &elf.dwarf_units.items[@backingInt(ui)].frame_cie_first_target_reloc, |
| 7953 | 8021 | .unit_debug_info_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_target_reloc, |
| 7954 | 8022 | .unit_debug_line_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_target_reloc, |
| 8023 | .unit_debug_rnglists => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_rnglists_first_target_reloc, |
| 8024 | .value_debug_info => |vi| &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_target_reloc, |
| 8025 | .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc, |
| 8026 | .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc, |
| 7955 | 8027 | }; |
| 7956 | 8028 | const next = first_target_reloc.*; |
| 7957 | 8029 | const ri: NodeReloc.Index = @fromBackingInt(@intCast(elf.node_relocs.items.len)); |
| ... | ... | @@ -8052,6 +8124,7 @@ fn addGotRelocAssumeCapacity( |
| 8052 | 8124 | .unit_debug_info_header, |
| 8053 | 8125 | .unit_debug_line, |
| 8054 | 8126 | .unit_debug_line_header, |
| 8127 | .unit_debug_rnglists, |
| 8055 | 8128 | .value_debug_info, |
| 8056 | 8129 | .global_debug_info, |
| 8057 | 8130 | .func_frame_fde, |
| ... | ... | @@ -8331,10 +8404,12 @@ fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) Error!bool { |
| 8331 | 8404 | } |
| 8332 | 8405 | |
| 8333 | 8406 | pub fn updateNav(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.Error!void { |
| 8334 | | const diags = &elf.base.comp.link_diags; |
| 8335 | 8407 | elf.updateNavInner(pt, nav_index) catch |err| switch (err) { |
| 8336 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 8337 | 8408 | else => |e| return e, |
| 8409 | error.MappedFileIo => return elf.base.comp.link_diags.fail( |
| 8410 | "failed to write output file: {t}", |
| 8411 | .{elf.mf.io_err.?}, |
| 8412 | ), |
| 8338 | 8413 | }; |
| 8339 | 8414 | } |
| 8340 | 8415 | fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void { |
| ... | ... | @@ -8365,8 +8440,8 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) |
| 8365 | 8440 | &nw.interface, |
| 8366 | 8441 | .{ .atom_index = Node.toAtom(ni) }, |
| 8367 | 8442 | ) catch |err| switch (err) { |
| 8368 | | error.WriteFailed => return nw.err.?, |
| 8369 | 8443 | else => |e| return e, |
| 8444 | error.WriteFailed => return nw.err.?, |
| 8370 | 8445 | }; |
| 8371 | 8446 | switch (elf.symPtr(nmi.symbol(elf).index())) { |
| 8372 | 8447 | inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)), |
| ... | ... | @@ -8383,10 +8458,12 @@ pub fn updateFunc( |
| 8383 | 8458 | func_index: InternPool.Index, |
| 8384 | 8459 | mir: *const codegen.AnyMir, |
| 8385 | 8460 | ) link.Error!void { |
| 8386 | | const diags = &elf.base.comp.link_diags; |
| 8387 | 8461 | elf.updateFuncInner(pt, func_index, mir) catch |err| switch (err) { |
| 8388 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 8389 | 8462 | else => |e| return e, |
| 8463 | error.MappedFileIo => return elf.base.comp.link_diags.fail( |
| 8464 | "failed to write output file: {t}", |
| 8465 | .{elf.mf.io_err.?}, |
| 8466 | ), |
| 8390 | 8467 | }; |
| 8391 | 8468 | } |
| 8392 | 8469 | fn updateFuncInner( |
| ... | ... | @@ -8403,7 +8480,8 @@ fn updateFuncInner( |
| 8403 | 8480 | |
| 8404 | 8481 | const nmi = try elf.navMapIndex(zcu, func.owner_nav); |
| 8405 | 8482 | log.debug("updateFunc({f}) = {d}", .{ nav.fqn.fmt(ip), nmi.symbol(elf) }); |
| 8406 | | const ni = nmi.symbol(elf).index().ptr(elf).node.unwrap().?; |
| 8483 | const lsi = nmi.symbol(elf); |
| 8484 | const ni = lsi.index().ptr(elf).node.unwrap().?; |
| 8407 | 8485 | |
| 8408 | 8486 | // Ensure the NAV is marked as moved so that once we're done, `flushMoved` will eventually be |
| 8409 | 8487 | // called to apply the NAV's new relocations. |
| ... | ... | @@ -8421,7 +8499,7 @@ fn updateFuncInner( |
| 8421 | 8499 | if (mod.strip and mod.unwind_tables == .none) break :debug_output .{ .none, undefined }; |
| 8422 | 8500 | |
| 8423 | 8501 | try elf.nodes.ensureUnusedCapacity(gpa, 5); |
| 8424 | | const dwarf_func_index = try dwarf.getFunc(func.owner_nav); |
| 8502 | const dwarf_fi = try dwarf.getFunc(func.owner_nav); |
| 8425 | 8503 | try elf.dwarf_funcs.appendNTimes(gpa, .{ |
| 8426 | 8504 | .frame_fde_first_symbol_reloc = .none, |
| 8427 | 8505 | .frame_fde_first_node_reloc = .none, |
| ... | ... | @@ -8430,14 +8508,14 @@ fn updateFuncInner( |
| 8430 | 8508 | .debug_info_first_node_reloc = .none, |
| 8431 | 8509 | .debug_line_first_symbol_reloc = .none, |
| 8432 | 8510 | .debug_line_first_node_reloc = .none, |
| 8433 | | }, @backingInt(dwarf_func_index) + 1 -| elf.dwarf_funcs.items.len); |
| 8511 | }, @backingInt(dwarf_fi) + 1 -| elf.dwarf_funcs.items.len); |
| 8434 | 8512 | |
| 8435 | 8513 | const wip_nav = &debug_output_buf.wip_nav; |
| 8436 | 8514 | wip_nav.* = .{ |
| 8437 | 8515 | .dwarf = dwarf, |
| 8438 | 8516 | .unit = dwarf.getUnit(mod), |
| 8439 | | .func = dwarf_func_index, |
| 8440 | | .func_si = Symbol.Id.local(nmi.symbol(elf)).toTypeErased(), |
| 8517 | .func = dwarf_fi, |
| 8518 | .func_si = Symbol.Id.local(lsi).toTypeErased(), |
| 8441 | 8519 | .cfi = .{ |
| 8442 | 8520 | .loc = 0, |
| 8443 | 8521 | .cfa = dwarf.frame.header.initial_instructions[0].def_cfa, |
| ... | ... | @@ -8462,7 +8540,6 @@ fn updateFuncInner( |
| 8462 | 8540 | .eh_frame => elf.shndx.eh_frame, |
| 8463 | 8541 | }.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{ |
| 8464 | 8542 | .alignment = frame_align.max(elf.mf.flags.block_size), |
| 8465 | | .next_moved = true, |
| 8466 | 8543 | .enable_next_moved = true, |
| 8467 | 8544 | }); |
| 8468 | 8545 | unit.frame_ni = .wrap(frame_ni); |
| ... | ... | @@ -8487,7 +8564,7 @@ fn updateFuncInner( |
| 8487 | 8564 | error.WriteFailed => return cie_nw.err.?, |
| 8488 | 8565 | }; |
| 8489 | 8566 | }; |
| 8490 | | const dwarf_func = dwarf_func_index.get(dwarf); |
| 8567 | const dwarf_func = dwarf_fi.get(dwarf); |
| 8491 | 8568 | const fde_ni = if (dwarf_func.fde_ni.unwrap()) |fde_ni| fde_ni: { |
| 8492 | 8569 | try fde_ni.moved(gpa, &elf.mf); |
| 8493 | 8570 | try fde_ni.nextMoved(gpa, &elf.mf); |
| ... | ... | @@ -8510,24 +8587,34 @@ fn updateFuncInner( |
| 8510 | 8587 | debug.pt = pt; |
| 8511 | 8588 | debug.any_children = false; |
| 8512 | 8589 | debug.blocks = .empty; |
| 8513 | | const debug_info_ni = dwarf_func.debug_info_ni.unwrap() orelse debug_info_ni: { |
| 8590 | const debug_info_ni = if (dwarf_func.debug_info_ni.unwrap()) |debug_info_ni| debug_info_ni: { |
| 8591 | try debug_info_ni.moved(gpa, &elf.mf); |
| 8592 | try debug_info_ni.nextMoved(gpa, &elf.mf); |
| 8593 | break :debug_info_ni debug_info_ni; |
| 8594 | } else debug_info_ni: { |
| 8514 | 8595 | const debug_info_ni = |
| 8515 | 8596 | try unit.debug_info_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{ |
| 8597 | .moved = true, |
| 8516 | 8598 | .next_moved = true, |
| 8517 | 8599 | .enable_next_moved = true, |
| 8518 | 8600 | }); |
| 8519 | 8601 | dwarf_func.debug_info_ni = .wrap(debug_info_ni); |
| 8520 | | elf.nodes.appendAssumeCapacity(.{ .func_debug_info = dwarf_func_index }); |
| 8602 | elf.nodes.appendAssumeCapacity(.{ .func_debug_info = dwarf_fi }); |
| 8521 | 8603 | break :debug_info_ni debug_info_ni; |
| 8522 | 8604 | }; |
| 8523 | 8605 | debug_info_ni.writer(&elf.mf, gpa, &debug.info_writer); |
| 8524 | | const debug_line_ni = dwarf_func.debug_line_ni.unwrap() orelse debug_line_ni: { |
| 8606 | const debug_line_ni = if (dwarf_func.debug_line_ni.unwrap()) |debug_line_ni| debug_line_ni: { |
| 8607 | try debug_line_ni.moved(gpa, &elf.mf); |
| 8608 | try debug_line_ni.nextMoved(gpa, &elf.mf); |
| 8609 | break :debug_line_ni debug_line_ni; |
| 8610 | } else debug_line_ni: { |
| 8525 | 8611 | const debug_line_ni = |
| 8526 | 8612 | try unit.debug_line_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{ |
| 8613 | .moved = true, |
| 8527 | 8614 | .next_moved = true, |
| 8528 | 8615 | .enable_next_moved = true, |
| 8529 | 8616 | }); |
| 8530 | | elf.nodes.appendAssumeCapacity(.{ .func_debug_line = dwarf_func_index }); |
| 8617 | elf.nodes.appendAssumeCapacity(.{ .func_debug_line = dwarf_fi }); |
| 8531 | 8618 | break :debug_line_ni debug_line_ni; |
| 8532 | 8619 | }; |
| 8533 | 8620 | debug_line_ni.writer(&elf.mf, gpa, &debug.line_writer); |
| ... | ... | @@ -8549,7 +8636,8 @@ fn updateFuncInner( |
| 8549 | 8636 | elf.resetNodeRelocs(dwarf_func.fde_ni.unwrap().?); |
| 8550 | 8637 | try debug.wip_nav.genDebugFrameHeader(); |
| 8551 | 8638 | elf.resetNodeRelocs(dwarf_func.debug_info_ni.unwrap().?); |
| 8552 | | try debug.startDebugInfo(); |
| 8639 | elf.resetNodeRelocs(dwarf_func.debug_line_ni.unwrap().?); |
| 8640 | try debug.startFunc(); |
| 8553 | 8641 | }, |
| 8554 | 8642 | .none => {}, |
| 8555 | 8643 | } |
| ... | ... | @@ -8563,10 +8651,8 @@ fn updateFuncInner( |
| 8563 | 8651 | &nw.interface, |
| 8564 | 8652 | debug_output, |
| 8565 | 8653 | ) catch |err| switch (err) { |
| 8566 | | error.WriteFailed => { |
| 8567 | | if (nw.err) |e| return e; |
| 8568 | | }, |
| 8569 | 8654 | else => |e| return e, |
| 8655 | error.WriteFailed => if (nw.err) |e| return e, |
| 8570 | 8656 | }; |
| 8571 | 8657 | const func_length = nw.interface.end; |
| 8572 | 8658 | switch (elf.symPtr(nmi.symbol(elf).index())) { |
| ... | ... | @@ -8591,19 +8677,44 @@ fn updateFuncInner( |
| 8591 | 8677 | } |
| 8592 | 8678 | }, |
| 8593 | 8679 | .dwarf2 => |debug| { |
| 8594 | | try debug.finishFunc(); |
| 8595 | | for ([2]Section.Index{ |
| 8680 | try debug.finishFunc(func_length); |
| 8681 | for ([3]Section.Index{ |
| 8596 | 8682 | elf.shndx.debug_info, |
| 8597 | 8683 | elf.shndx.debug_line, |
| 8684 | elf.shndx.debug_rnglists, |
| 8598 | 8685 | }) |debug_shndx| try debug_shndx.get(elf).ni.trimStart(&elf.mf, gpa); |
| 8686 | const unit = debug.wip_nav.unit.get(debug.wip_nav.dwarf); |
| 8599 | 8687 | { |
| 8600 | | const debug_info_ni = |
| 8601 | | debug.wip_nav.unit.get(debug.wip_nav.dwarf).debug_info_ni.unwrap().?; |
| 8688 | const debug_info_ni = unit.debug_info_ni.unwrap().?; |
| 8602 | 8689 | const last_offset, const last_size = |
| 8603 | 8690 | debug_info_ni.last(&elf.mf).unwrap().?.location(&elf.mf).resolve(&elf.mf); |
| 8604 | 8691 | try debug_info_ni.ensureMinimumSize(&elf.mf, gpa, last_offset + last_size + |
| 8605 | 8692 | comptime Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) * 2); |
| 8606 | 8693 | } |
| 8694 | { |
| 8695 | var dr_nw: MappedFile.Node.Writer = undefined; |
| 8696 | unit.debug_rnglists_ni.unwrap().?.writer(&elf.mf, gpa, &dr_nw); |
| 8697 | defer dr_nw.deinit(); |
| 8698 | const first_symbol_reloc = elf.symbol_relocs.items.len; |
| 8699 | debug.wip_nav.dwarf.genDebugRnglists( |
| 8700 | unit, |
| 8701 | &dr_nw, |
| 8702 | debug.wip_nav.func_si, |
| 8703 | func_length, |
| 8704 | ) catch |err| switch (err) { |
| 8705 | else => |e| return e, |
| 8706 | error.WriteFailed => return dr_nw.err.?, |
| 8707 | }; |
| 8708 | const symbol_relocs = &elf.dwarf_units.items[@backingInt(debug.wip_nav.unit)] |
| 8709 | .debug_rnglists_symbol_relocs; |
| 8710 | try symbol_relocs.ensureUnusedCapacity(gpa, elf.symbol_relocs.items.len - |
| 8711 | first_symbol_reloc); |
| 8712 | for (first_symbol_reloc..elf.symbol_relocs.items.len) |symbol_ri| |
| 8713 | symbol_relocs.putAssumeCapacityNoClobber( |
| 8714 | @fromBackingInt(@intCast(symbol_ri)), |
| 8715 | {}, |
| 8716 | ); |
| 8717 | } |
| 8607 | 8718 | continue :debug_output .{ .eh_frame = &debug.wip_nav }; |
| 8608 | 8719 | }, |
| 8609 | 8720 | .none => {}, |
| ... | ... | @@ -8615,13 +8726,15 @@ fn updateFuncInner( |
| 8615 | 8726 | } |
| 8616 | 8727 | |
| 8617 | 8728 | pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void { |
| 8618 | | const diags = &elf.base.comp.link_diags; |
| 8619 | 8729 | elf.genLazy(pt, .{ |
| 8620 | 8730 | .kind = .const_data, |
| 8621 | 8731 | .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return), |
| 8622 | 8732 | }) catch |err| switch (err) { |
| 8623 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 8624 | 8733 | else => |e| return e, |
| 8734 | error.MappedFileIo => return elf.base.comp.link_diags.fail( |
| 8735 | "failed to write output file: {t}", |
| 8736 | .{elf.mf.io_err.?}, |
| 8737 | ), |
| 8625 | 8738 | }; |
| 8626 | 8739 | } |
| 8627 | 8740 | |
| ... | ... | @@ -8632,8 +8745,11 @@ pub fn flush( |
| 8632 | 8745 | prog_node: std.Progress.Node, |
| 8633 | 8746 | ) link.Error!void { |
| 8634 | 8747 | elf.flushInner(arena, tid, prog_node) catch |err| switch (err) { |
| 8635 | | error.MappedFileIo => return elf.base.comp.link_diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 8636 | 8748 | else => |e| return e, |
| 8749 | error.MappedFileIo => return elf.base.comp.link_diags.fail( |
| 8750 | "failed to write output file: {t}", |
| 8751 | .{elf.mf.io_err.?}, |
| 8752 | ), |
| 8637 | 8753 | }; |
| 8638 | 8754 | } |
| 8639 | 8755 | fn flushInner( |
| ... | ... | @@ -8649,6 +8765,8 @@ fn flushInner( |
| 8649 | 8765 | const sub_prog_node = prog_node.start("ELF Flush", 0); |
| 8650 | 8766 | defer sub_prog_node.end(); |
| 8651 | 8767 | |
| 8768 | try elf.flushFiles(); |
| 8769 | |
| 8652 | 8770 | if (comp.config.output_mode == .Exe) { |
| 8653 | 8771 | var any_undef = false; |
| 8654 | 8772 | for (elf.globals.strong_undef.keys()) |name| { |
| ... | ... | @@ -8714,7 +8832,7 @@ fn flushInner( |
| 8714 | 8832 | |
| 8715 | 8833 | if (elf.options.enable_link_snapshots) |
| 8716 | 8834 | elf.dumpStderr(tid) catch |err| |
| 8717 | | return comp.link_diags.fail("dumping link snapshot failed: {t}", .{err}); |
| 8835 | return diags.fail("dumping link snapshot failed: {t}", .{err}); |
| 8718 | 8836 | } |
| 8719 | 8837 | |
| 8720 | 8838 | pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { |
| ... | ... | @@ -8737,8 +8855,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { |
| 8737 | 8855 | const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(ii.node(elf))); |
| 8738 | 8856 | defer sub_prog_node.end(); |
| 8739 | 8857 | elf.flushInput(ii) catch |err| switch (err) { |
| 8740 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 8741 | 8858 | else => |e| return e, |
| 8859 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 8742 | 8860 | }; |
| 8743 | 8861 | break :task; |
| 8744 | 8862 | } |
| ... | ... | @@ -8748,8 +8866,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { |
| 8748 | 8866 | const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(isi.node(elf))); |
| 8749 | 8867 | defer sub_prog_node.end(); |
| 8750 | 8868 | elf.flushInputSection(isi) catch |err| switch (err) { |
| 8751 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 8752 | 8869 | else => |e| return e, |
| 8870 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 8753 | 8871 | }; |
| 8754 | 8872 | break :task; |
| 8755 | 8873 | } |
| ... | ... | @@ -8907,11 +9025,12 @@ fn idleProgNode( |
| 8907 | 9025 | .unit_debug_info_header, |
| 8908 | 9026 | .unit_debug_line, |
| 8909 | 9027 | .unit_debug_line_header, |
| 9028 | .unit_debug_rnglists, |
| 8910 | 9029 | => |ui, tag| std.mem.print(&name, "{s} info for {s}", .{ |
| 8911 | 9030 | switch (tag) { |
| 8912 | 9031 | else => unreachable, |
| 8913 | 9032 | .unit_frame, .unit_frame_cie => "unwind", |
| 8914 | | .unit_debug_info, .unit_debug_info_header => "debug", |
| 9033 | .unit_debug_info, .unit_debug_info_header, .unit_debug_rnglists => "debug", |
| 8915 | 9034 | .unit_debug_line, .unit_debug_line_header => "line", |
| 8916 | 9035 | }, |
| 8917 | 9036 | ui.mod(&elf.dwarf).fully_qualified_name, |
| ... | ... | @@ -8996,8 +9115,8 @@ fn genUav( |
| 8996 | 9115 | &nw.interface, |
| 8997 | 9116 | .{ .atom_index = Node.toAtom(ni) }, |
| 8998 | 9117 | ) catch |err| switch (err) { |
| 8999 | | error.WriteFailed => return nw.err.?, |
| 9000 | 9118 | else => |e| return e, |
| 9119 | error.WriteFailed => return nw.err.?, |
| 9001 | 9120 | }; |
| 9002 | 9121 | switch (elf.symPtr(umi.symbol(elf).index())) { |
| 9003 | 9122 | inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)), |
| ... | ... | @@ -9032,8 +9151,8 @@ fn genLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void { |
| 9032 | 9151 | .none, |
| 9033 | 9152 | .{ .atom_index = Node.toAtom(ni) }, |
| 9034 | 9153 | ) catch |err| switch (err) { |
| 9035 | | error.WriteFailed => return nw.err.?, |
| 9036 | 9154 | else => |e| return e, |
| 9155 | error.WriteFailed => return nw.err.?, |
| 9037 | 9156 | }; |
| 9038 | 9157 | switch (elf.symPtr(lmr.symbol(elf).index())) { |
| 9039 | 9158 | inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)), |
| ... | ... | @@ -9241,14 +9360,18 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9241 | 9360 | reloc.apply(elf); |
| 9242 | 9361 | } |
| 9243 | 9362 | } else if (shndx == elf.shndx.plt) { |
| 9244 | | elf.flushMovedNodeRelocs(ni, addr, elf.plt_first_symbol_reloc, .none, .none); |
| 9363 | elf.flushMovedNodeRelocs(ni, addr, .{ |
| 9364 | .first_symbol_reloc = elf.plt_first_symbol_reloc, |
| 9365 | }); |
| 9245 | 9366 | elf.flushMovedPltSection(.plt, old_addr, addr); |
| 9246 | 9367 | } else if (shndx == elf.shndx.got_plt) { |
| 9247 | 9368 | elf.flushMovedPltSection(.got_plt, old_addr, addr); |
| 9248 | 9369 | } else if (shndx == elf.shndx.plt_sec) { |
| 9249 | 9370 | elf.flushMovedPltSection(.plt_sec, old_addr, addr); |
| 9250 | 9371 | } else if (shndx == elf.shndx.eh_frame_hdr) { |
| 9251 | | elf.flushMovedNodeRelocs(ni, addr, elf.eh_frame_hdr_first_symbol_reloc, .none, .none); |
| 9372 | elf.flushMovedNodeRelocs(ni, addr, .{ |
| 9373 | .first_symbol_reloc = elf.eh_frame_hdr_first_symbol_reloc, |
| 9374 | }); |
| 9252 | 9375 | } |
| 9253 | 9376 | }, |
| 9254 | 9377 | .input_section => |isi| { |
| ... | ... | @@ -9295,13 +9418,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9295 | 9418 | } |
| 9296 | 9419 | } |
| 9297 | 9420 | |
| 9298 | | elf.flushMovedNodeRelocs( |
| 9299 | | ni, |
| 9300 | | new_section_addr, |
| 9301 | | isi.ptrConst(elf).first_symbol_reloc, |
| 9302 | | .none, |
| 9303 | | isi.ptrConst(elf).first_got_reloc, |
| 9304 | | ); |
| 9421 | elf.flushMovedNodeRelocs(ni, new_section_addr, .{ |
| 9422 | .first_symbol_reloc = isi.ptrConst(elf).first_symbol_reloc, |
| 9423 | .first_got_reloc = isi.ptrConst(elf).first_got_reloc, |
| 9424 | }); |
| 9305 | 9425 | }, |
| 9306 | 9426 | .copied_global => |global_name| { |
| 9307 | 9427 | const copied_global = elf.copied_globals.getPtr(global_name) orelse { |
| ... | ... | @@ -9327,13 +9447,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9327 | 9447 | name = elf.globalByName(name).?.next_in_node; |
| 9328 | 9448 | } |
| 9329 | 9449 | } |
| 9330 | | elf.flushMovedNodeRelocs( |
| 9331 | | ni, |
| 9332 | | new_addr, |
| 9333 | | mi.firstSymbolReloc(elf), |
| 9334 | | .none, |
| 9335 | | mi.firstGotReloc(elf), |
| 9336 | | ); |
| 9450 | elf.flushMovedNodeRelocs(ni, new_addr, .{ |
| 9451 | .first_symbol_reloc = mi.firstSymbolReloc(elf), |
| 9452 | .first_got_reloc = mi.firstGotReloc(elf), |
| 9453 | }); |
| 9337 | 9454 | }, |
| 9338 | 9455 | .debug_shared => |ss| { |
| 9339 | 9456 | var target_ri = elf.dwarf_shared.getPtr(ss).first_target_reloc; |
| ... | ... | @@ -9364,13 +9481,9 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9364 | 9481 | target_reloc.apply(elf); |
| 9365 | 9482 | target_ri = target_reloc.next; |
| 9366 | 9483 | } |
| 9367 | | elf.flushMovedNodeRelocs( |
| 9368 | | ni, |
| 9369 | | elf.computeNodeVAddr(ni), |
| 9370 | | .none, |
| 9371 | | dwarf_unit.debug_info_header_first_node_reloc, |
| 9372 | | .none, |
| 9373 | | ); |
| 9484 | elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{ |
| 9485 | .first_node_reloc = dwarf_unit.debug_info_header_first_node_reloc, |
| 9486 | }); |
| 9374 | 9487 | }, |
| 9375 | 9488 | .unit_debug_line_header => |ui| { |
| 9376 | 9489 | const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)]; |
| ... | ... | @@ -9381,13 +9494,32 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9381 | 9494 | target_reloc.apply(elf); |
| 9382 | 9495 | target_ri = target_reloc.next; |
| 9383 | 9496 | } |
| 9384 | | elf.flushMovedNodeRelocs( |
| 9385 | | ni, |
| 9386 | | elf.computeNodeVAddr(ni), |
| 9387 | | .none, |
| 9388 | | dwarf_unit.debug_line_header_first_node_reloc, |
| 9389 | | .none, |
| 9390 | | ); |
| 9497 | elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{ |
| 9498 | .first_node_reloc = dwarf_unit.debug_line_header_first_node_reloc, |
| 9499 | }); |
| 9500 | }, |
| 9501 | .unit_debug_rnglists => |ui| { |
| 9502 | const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)]; |
| 9503 | var target_ri = dwarf_unit.debug_rnglists_first_target_reloc; |
| 9504 | while (target_ri != .none) { |
| 9505 | const target_reloc = target_ri.get(elf); |
| 9506 | assert(target_reloc.target == ni); |
| 9507 | target_reloc.apply(elf); |
| 9508 | target_ri = target_reloc.next; |
| 9509 | } |
| 9510 | const node_vaddr = elf.computeNodeVAddr(ni); |
| 9511 | for (dwarf_unit.debug_rnglists_symbol_relocs.keys()) |symbol_ri| { |
| 9512 | const symbol_reloc = symbol_ri.get(elf); |
| 9513 | assert(symbol_reloc.node == ni); |
| 9514 | if (symbol_reloc.rela_index.unwrap()) |rela_index| { |
| 9515 | // The node has moved, so the offset of the relocation within the section might have |
| 9516 | // changed, so update the `offset` field of the `ElfN.Rela` entry. |
| 9517 | symbol_reloc.relaSection(elf).relaSetOffset(elf, rela_index, node_vaddr + symbol_reloc.offset); |
| 9518 | } |
| 9519 | if (elf.ehdrType() != .REL) { |
| 9520 | symbol_reloc.apply(elf); |
| 9521 | } |
| 9522 | } |
| 9391 | 9523 | }, |
| 9392 | 9524 | .value_debug_info => |vi| { |
| 9393 | 9525 | const dwarf_value = &elf.dwarf_values.items[@backingInt(vi)]; |
| ... | ... | @@ -9398,13 +9530,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9398 | 9530 | target_reloc.apply(elf); |
| 9399 | 9531 | target_ri = target_reloc.next; |
| 9400 | 9532 | } |
| 9401 | | elf.flushMovedNodeRelocs( |
| 9402 | | ni, |
| 9403 | | elf.computeNodeVAddr(ni), |
| 9404 | | dwarf_value.debug_info_first_symbol_reloc, |
| 9405 | | dwarf_value.debug_info_first_node_reloc, |
| 9406 | | .none, |
| 9407 | | ); |
| 9533 | elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{ |
| 9534 | .first_symbol_reloc = dwarf_value.debug_info_first_symbol_reloc, |
| 9535 | .first_node_reloc = dwarf_value.debug_info_first_node_reloc, |
| 9536 | }); |
| 9408 | 9537 | }, |
| 9409 | 9538 | .global_debug_info => |vi| { |
| 9410 | 9539 | const dwarf_global = &elf.dwarf_globals.items[@backingInt(vi)]; |
| ... | ... | @@ -9415,13 +9544,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9415 | 9544 | target_reloc.apply(elf); |
| 9416 | 9545 | target_ri = target_reloc.next; |
| 9417 | 9546 | } |
| 9418 | | elf.flushMovedNodeRelocs( |
| 9419 | | ni, |
| 9420 | | elf.computeNodeVAddr(ni), |
| 9421 | | dwarf_global.debug_info_first_symbol_reloc, |
| 9422 | | dwarf_global.debug_info_first_node_reloc, |
| 9423 | | .none, |
| 9424 | | ); |
| 9547 | elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{ |
| 9548 | .first_symbol_reloc = dwarf_global.debug_info_first_symbol_reloc, |
| 9549 | .first_node_reloc = dwarf_global.debug_info_first_node_reloc, |
| 9550 | }); |
| 9425 | 9551 | }, |
| 9426 | 9552 | .func_frame_fde => |fi| { |
| 9427 | 9553 | const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)]; |
| ... | ... | @@ -9433,13 +9559,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9433 | 9559 | elf.dwarf.updateEhFrameFde(ni.slice(&elf.mf), offset); |
| 9434 | 9560 | }, |
| 9435 | 9561 | } |
| 9436 | | elf.flushMovedNodeRelocs( |
| 9437 | | ni, |
| 9438 | | elf.computeNodeVAddr(ni), |
| 9439 | | dwarf_func.frame_fde_first_symbol_reloc, |
| 9440 | | dwarf_func.frame_fde_first_node_reloc, |
| 9441 | | .none, |
| 9442 | | ); |
| 9562 | elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{ |
| 9563 | .first_symbol_reloc = dwarf_func.frame_fde_first_symbol_reloc, |
| 9564 | .first_node_reloc = dwarf_func.frame_fde_first_node_reloc, |
| 9565 | }); |
| 9443 | 9566 | }, |
| 9444 | 9567 | .func_debug_info => |fi| { |
| 9445 | 9568 | const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)]; |
| ... | ... | @@ -9450,23 +9573,19 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 9450 | 9573 | target_reloc.apply(elf); |
| 9451 | 9574 | target_ri = target_reloc.next; |
| 9452 | 9575 | } |
| 9453 | | elf.flushMovedNodeRelocs( |
| 9454 | | ni, |
| 9455 | | elf.computeNodeVAddr(ni), |
| 9456 | | dwarf_func.debug_info_first_symbol_reloc, |
| 9457 | | dwarf_func.debug_info_first_node_reloc, |
| 9458 | | .none, |
| 9459 | | ); |
| 9576 | elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{ |
| 9577 | .ignore_node = fi.get(&elf.dwarf).debug_line_ni, |
| 9578 | .first_symbol_reloc = dwarf_func.debug_info_first_symbol_reloc, |
| 9579 | .first_node_reloc = dwarf_func.debug_info_first_node_reloc, |
| 9580 | }); |
| 9460 | 9581 | }, |
| 9461 | 9582 | .func_debug_line => |fi| { |
| 9462 | 9583 | const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)]; |
| 9463 | | elf.flushMovedNodeRelocs( |
| 9464 | | ni, |
| 9465 | | elf.computeNodeVAddr(ni), |
| 9466 | | dwarf_func.debug_line_first_symbol_reloc, |
| 9467 | | dwarf_func.debug_line_first_node_reloc, |
| 9468 | | .none, |
| 9469 | | ); |
| 9584 | elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{ |
| 9585 | .ignore_node = fi.get(&elf.dwarf).debug_info_ni, |
| 9586 | .first_symbol_reloc = dwarf_func.debug_line_first_symbol_reloc, |
| 9587 | .first_node_reloc = dwarf_func.debug_line_first_node_reloc, |
| 9588 | }); |
| 9470 | 9589 | }, |
| 9471 | 9590 | } |
| 9472 | 9591 | try ni.childrenMoved(elf.base.comp.gpa, &elf.mf); |
| ... | ... | @@ -9712,6 +9831,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo |
| 9712 | 9831 | .unit_debug_info_header, |
| 9713 | 9832 | .unit_debug_line, |
| 9714 | 9833 | .unit_debug_line_header, |
| 9834 | .unit_debug_rnglists, |
| 9715 | 9835 | .value_debug_info, |
| 9716 | 9836 | .global_debug_info, |
| 9717 | 9837 | .func_frame_fde, |
| ... | ... | @@ -9774,6 +9894,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error! |
| 9774 | 9894 | .unit_frame_cie, |
| 9775 | 9895 | .unit_debug_info_header, |
| 9776 | 9896 | .unit_debug_line_header, |
| 9897 | .unit_debug_rnglists, |
| 9777 | 9898 | .value_debug_info, |
| 9778 | 9899 | .global_debug_info, |
| 9779 | 9900 | .func_frame_fde, |
| ... | ... | @@ -9788,15 +9909,15 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error! |
| 9788 | 9909 | break :slice parent_slice[@intCast(offset)..@intCast(next_offset)]; |
| 9789 | 9910 | } else slice: switch (tag) { |
| 9790 | 9911 | else => unreachable, |
| 9791 | | .unit_padding => { |
| 9792 | | const frame_slice = parent_ni.slicePadding(&elf.mf); |
| 9912 | .unit_padding, .unit_debug_rnglists => { |
| 9913 | const parent_slice = parent_ni.slicePadding(&elf.mf); |
| 9793 | 9914 | switch (elf.getNode(parent_ni).section.debugFrameFormat(elf) orelse .debug_frame) { |
| 9794 | 9915 | .eh_frame => { |
| 9795 | | const end = frame_slice.len - 4; |
| 9796 | | std.mem.writeInt(u32, frame_slice[end..][0..4], 0, elf.dwarf.endian); |
| 9797 | | break :slice frame_slice[@intCast(offset)..end]; |
| 9916 | const end = parent_slice.len - 4; |
| 9917 | std.mem.writeInt(u32, parent_slice[end..][0..4], 0, elf.dwarf.endian); |
| 9918 | break :slice parent_slice[@intCast(offset)..end]; |
| 9798 | 9919 | }, |
| 9799 | | .debug_frame => break :slice frame_slice[@intCast(offset)..], |
| 9920 | .debug_frame => break :slice parent_slice[@intCast(offset)..], |
| 9800 | 9921 | } |
| 9801 | 9922 | }, |
| 9802 | 9923 | .unit_frame_cie, .func_frame_fde => { |
| ... | ... | @@ -9840,36 +9961,64 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error! |
| 9840 | 9961 | break :debug_end @intCast(parent_next_offset); |
| 9841 | 9962 | } else debug_slice.len]); |
| 9842 | 9963 | fw.end = @intCast(offset + size); |
| 9843 | | for (0..2) |_| fw.writeUleb128(@backingInt(Dwarf.AbbrevCode.null)) catch |
| 9844 | | unreachable; // ensured by `updateFunc` |
| 9845 | | elf.dwarf.updateUnitLength(fw.buffer, fw.end); |
| 9964 | switch (tag) { |
| 9965 | else => unreachable, |
| 9966 | .unit_debug_info_header, |
| 9967 | .value_debug_info, |
| 9968 | .global_debug_info, |
| 9969 | .func_debug_info, |
| 9970 | => for (0..2) |_| fw.writeUleb128(@backingInt(Dwarf.AbbrevCode.null)) catch unreachable, |
| 9971 | .unit_debug_line_header, .func_debug_line => {}, |
| 9972 | } |
| 9973 | const unit_padding_offset = fw.end; |
| 9846 | 9974 | const unit_padding = fw.unusedCapacitySlice(); |
| 9847 | 9975 | elf.dwarf.genUnitPadding(&fw) catch |err| switch (err) { |
| 9848 | 9976 | error.WriteFailed => { |
| 9849 | | comptime assert(Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) == 1); |
| 9850 | | @memset(fw.buffer, @backingInt(Dwarf.AbbrevCode.null)); |
| 9977 | fw.end = unit_padding_offset; |
| 9978 | elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len); |
| 9979 | switch (tag) { |
| 9980 | else => unreachable, |
| 9981 | .unit_debug_info_header, .value_debug_info, .global_debug_info, .func_debug_info => { |
| 9982 | comptime assert(Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) == 1); |
| 9983 | @memset(fw.unusedCapacitySlice(), @backingInt(Dwarf.AbbrevCode.null)); |
| 9984 | }, |
| 9985 | .unit_debug_line_header, .func_debug_line => Dwarf.genDebugLinePadding(&fw, fw.unusedCapacityLen()) catch |
| 9986 | unreachable, |
| 9987 | } |
| 9988 | return; |
| 9851 | 9989 | }, |
| 9852 | 9990 | }; |
| 9991 | elf.dwarf.updateUnitLength(fw.buffer, unit_padding_offset); |
| 9853 | 9992 | elf.dwarf.updateUnitLength(unit_padding, unit_padding.len); |
| 9854 | 9993 | return; |
| 9855 | 9994 | }, |
| 9856 | 9995 | }; |
| 9996 | var fw: Io.Writer = .fixed(slice[@intCast(size)..]); |
| 9857 | 9997 | switch (tag) { |
| 9858 | 9998 | else => unreachable, |
| 9859 | 9999 | .unit_padding => elf.dwarf.updateUnitLength(slice, slice.len), |
| 9860 | 10000 | .unit_frame_cie, .func_frame_fde => { |
| 9861 | 10001 | elf.dwarf.updateUnitLength(slice, slice.len); |
| 9862 | | @memset(slice[@intCast(size)..], std.dwarf.CFA.nop); |
| 10002 | @memset(fw.buffer, std.dwarf.CFA.nop); |
| 9863 | 10003 | }, |
| 9864 | 10004 | .unit_debug_info_header, |
| 9865 | | .unit_debug_line_header, |
| 9866 | 10005 | .value_debug_info, |
| 9867 | 10006 | .global_debug_info, |
| 9868 | 10007 | .func_debug_info, |
| 10008 | => elf.dwarf.genDebugInfoPadding(&fw, fw.buffer.len) catch unreachable, |
| 10009 | .unit_debug_line_header, |
| 9869 | 10010 | .func_debug_line, |
| 9870 | | => { |
| 9871 | | var fw: Io.Writer = .fixed(slice[@intCast(size)..]); |
| 9872 | | elf.dwarf.genDebugInfoPadding(&fw, fw.unusedCapacityLen()) catch unreachable; |
| 10011 | => Dwarf.genDebugLinePadding(&fw, fw.buffer.len) catch unreachable, |
| 10012 | .unit_debug_rnglists => { |
| 10013 | elf.dwarf.genUnitPadding(&fw) catch |err| switch (err) { |
| 10014 | error.WriteFailed => { |
| 10015 | elf.dwarf.updateUnitLength(slice, slice.len); |
| 10016 | @memset(fw.buffer, std.dwarf.RLE.end_of_list); |
| 10017 | return; |
| 10018 | }, |
| 10019 | }; |
| 10020 | elf.dwarf.updateUnitLength(slice, size); |
| 10021 | elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len); |
| 9873 | 10022 | }, |
| 9874 | 10023 | } |
| 9875 | 10024 | }, |
| ... | ... | @@ -10229,11 +10378,10 @@ pub fn updateExports( |
| 10229 | 10378 | pt: Zcu.PerThread, |
| 10230 | 10379 | export_indices: []const Zcu.Export.Index, |
| 10231 | 10380 | ) link.Error!void { |
| 10232 | | const diags = &elf.base.comp.link_diags; |
| 10233 | 10381 | for (export_indices) |export_index| { |
| 10234 | 10382 | elf.updateExportInner(pt, export_index) catch |err| switch (err) { |
| 10235 | 10383 | else => |e| return e, |
| 10236 | | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 10384 | error.MappedFileIo => return elf.base.comp.link_diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 10237 | 10385 | }; |
| 10238 | 10386 | } |
| 10239 | 10387 | } |
| ... | ... | @@ -10377,7 +10525,7 @@ pub fn printNode( |
| 10377 | 10525 | const ip = &zcu.intern_pool; |
| 10378 | 10526 | const nav = ip.getNav(nmi.navIndex(elf)); |
| 10379 | 10527 | try w.print("({f}, {f})", .{ |
| 10380 | | Type.fromInterned(ip.typeOf(nav.resolved.?.value)).fmt(.{ .zcu = zcu, .tid = tid }), |
| 10528 | Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }), |
| 10381 | 10529 | nav.fqn.fmt(ip), |
| 10382 | 10530 | }); |
| 10383 | 10531 | }, |
| ... | ... | @@ -10402,9 +10550,8 @@ pub fn printNode( |
| 10402 | 10550 | .unit_debug_info_header, |
| 10403 | 10551 | .unit_debug_line, |
| 10404 | 10552 | .unit_debug_line_header, |
| 10405 | | => |ui| try w.print("({s})", .{ |
| 10406 | | ui.mod(&elf.dwarf).fully_qualified_name, |
| 10407 | | }), |
| 10553 | .unit_debug_rnglists, |
| 10554 | => |ui| try w.print("({s})", .{ui.mod(&elf.dwarf).fully_qualified_name}), |
| 10408 | 10555 | .value_debug_info => |cpi| try w.print("({f})", .{ |
| 10409 | 10556 | Value.fromInterned(cpi.val(&elf.dwarf.const_pool)) |
| 10410 | 10557 | .fmtValue(.{ .zcu = elf.base.comp.zcu.?, .tid = tid }), |
| ... | ... | @@ -10414,7 +10561,7 @@ pub fn printNode( |
| 10414 | 10561 | const ip = &zcu.intern_pool; |
| 10415 | 10562 | const nav = ip.getNav(gi.nav(&elf.dwarf)); |
| 10416 | 10563 | try w.print("({f}, {f})", .{ |
| 10417 | | Type.fromInterned(ip.typeOf(nav.resolved.?.value)).fmt(.{ .zcu = zcu, .tid = tid }), |
| 10564 | Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }), |
| 10418 | 10565 | nav.fqn.fmt(ip), |
| 10419 | 10566 | }); |
| 10420 | 10567 | }, |
| ... | ... | @@ -10423,7 +10570,7 @@ pub fn printNode( |
| 10423 | 10570 | const ip = &zcu.intern_pool; |
| 10424 | 10571 | const nav = ip.getNav(fi.nav(&elf.dwarf)); |
| 10425 | 10572 | try w.print("({f}, {f})", .{ |
| 10426 | | Type.fromInterned(ip.typeOf(nav.resolved.?.value)).fmt(.{ .zcu = zcu, .tid = tid }), |
| 10573 | Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }), |
| 10427 | 10574 | nav.fqn.fmt(ip), |
| 10428 | 10575 | }); |
| 10429 | 10576 | }, |