| author | |
| committer | |
| log | 8fc15f188c0deb1b0e2847297e535823eca1d2e8 |
| tree | 1dcda4337dc446f1d1c5e3bb478ea4b9678c383c |
| parent | 61919fe63d1eb7134a3c85fe0a4cf279744de3e9 |
| parent | e79ac14ef34d8ceea945de972b7f395b8f53621f |
| signature |
elf+zigobject: emit relocs for debug sections10 files changed, 470 insertions(+), 238 deletions(-)
src/arch/riscv64/Emit.zig+12-12| ... | @@ -56,17 +56,17 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -56,17 +56,17 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 56 | const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20); | 56 | const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20); |
| 57 | const lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I); | 57 | const lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I); |
| 58 | 58 | ||
| 59 | try atom_ptr.addReloc(elf_file, .{ | 59 | try atom_ptr.addReloc(elf_file.base.comp.gpa, .{ |
| 60 | .r_offset = start_offset, | 60 | .r_offset = start_offset, |
| 61 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type, | 61 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type, |
| 62 | .r_addend = 0, | 62 | .r_addend = 0, |
| 63 | }); | 63 | }, zo); |
| 64 | 64 | ||
| 65 | try atom_ptr.addReloc(elf_file, .{ | 65 | try atom_ptr.addReloc(elf_file.base.comp.gpa, .{ |
| 66 | .r_offset = start_offset + 4, | 66 | .r_offset = start_offset + 4, |
| 67 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | lo_r_type, | 67 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | lo_r_type, |
| 68 | .r_addend = 0, | 68 | .r_addend = 0, |
| 69 | }); | 69 | }, zo); |
| 70 | }, | 70 | }, |
| 71 | .load_tlv_reloc => |symbol| { | 71 | .load_tlv_reloc => |symbol| { |
| 72 | const elf_file = emit.bin_file.cast(.elf).?; | 72 | const elf_file = emit.bin_file.cast(.elf).?; |
| ... | @@ -76,23 +76,23 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -76,23 +76,23 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 76 | 76 | ||
| 77 | const R_RISCV = std.elf.R_RISCV; | 77 | const R_RISCV = std.elf.R_RISCV; |
| 78 | 78 | ||
| 79 | try atom_ptr.addReloc(elf_file, .{ | 79 | try atom_ptr.addReloc(elf_file.base.comp.gpa, .{ |
| 80 | .r_offset = start_offset, | 80 | .r_offset = start_offset, |
| 81 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_HI20), | 81 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_HI20), |
| 82 | .r_addend = 0, | 82 | .r_addend = 0, |
| 83 | }); | 83 | }, zo); |
| 84 | 84 | ||
| 85 | try atom_ptr.addReloc(elf_file, .{ | 85 | try atom_ptr.addReloc(elf_file.base.comp.gpa, .{ |
| 86 | .r_offset = start_offset + 4, | 86 | .r_offset = start_offset + 4, |
| 87 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_ADD), | 87 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_ADD), |
| 88 | .r_addend = 0, | 88 | .r_addend = 0, |
| 89 | }); | 89 | }, zo); |
| 90 | 90 | ||
| 91 | try atom_ptr.addReloc(elf_file, .{ | 91 | try atom_ptr.addReloc(elf_file.base.comp.gpa, .{ |
| 92 | .r_offset = start_offset + 8, | 92 | .r_offset = start_offset + 8, |
| 93 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_LO12_I), | 93 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_LO12_I), |
| 94 | .r_addend = 0, | 94 | .r_addend = 0, |
| 95 | }); | 95 | }, zo); |
| 96 | }, | 96 | }, |
| 97 | .call_extern_fn_reloc => |symbol| { | 97 | .call_extern_fn_reloc => |symbol| { |
| 98 | const elf_file = emit.bin_file.cast(.elf).?; | 98 | const elf_file = emit.bin_file.cast(.elf).?; |
| ... | @@ -101,11 +101,11 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -101,11 +101,11 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 101 | 101 | ||
| 102 | const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT); | 102 | const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT); |
| 103 | 103 | ||
| 104 | try atom_ptr.addReloc(elf_file, .{ | 104 | try atom_ptr.addReloc(elf_file.base.comp.gpa, .{ |
| 105 | .r_offset = start_offset, | 105 | .r_offset = start_offset, |
| 106 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type, | 106 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type, |
| 107 | .r_addend = 0, | 107 | .r_addend = 0, |
| 108 | }); | 108 | }, zo); |
| 109 | }, | 109 | }, |
| 110 | }; | 110 | }; |
| 111 | } | 111 | } |
src/arch/x86_64/Emit.zig+10-10| ... | @@ -48,11 +48,11 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -48,11 +48,11 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 48 | const zo = elf_file.zigObjectPtr().?; | 48 | const zo = elf_file.zigObjectPtr().?; |
| 49 | const atom_ptr = zo.symbol(emit.atom_index).atom(elf_file).?; | 49 | const atom_ptr = zo.symbol(emit.atom_index).atom(elf_file).?; |
| 50 | const r_type = @intFromEnum(std.elf.R_X86_64.PLT32); | 50 | const r_type = @intFromEnum(std.elf.R_X86_64.PLT32); |
| 51 | try atom_ptr.addReloc(elf_file, .{ | 51 | try atom_ptr.addReloc(elf_file.base.comp.gpa, .{ |
| 52 | .r_offset = end_offset - 4, | 52 | .r_offset = end_offset - 4, |
| 53 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 53 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 54 | .r_addend = lowered_relocs[0].off - 4, | 54 | .r_addend = lowered_relocs[0].off - 4, |
| 55 | }); | 55 | }, zo); |
| 56 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { | 56 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { |
| 57 | // Add relocation to the decl. | 57 | // Add relocation to the decl. |
| 58 | const zo = macho_file.getZigObject().?; | 58 | const zo = macho_file.getZigObject().?; |
| ... | @@ -95,22 +95,22 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -95,22 +95,22 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 95 | const zo = elf_file.zigObjectPtr().?; | 95 | const zo = elf_file.zigObjectPtr().?; |
| 96 | const atom = zo.symbol(emit.atom_index).atom(elf_file).?; | 96 | const atom = zo.symbol(emit.atom_index).atom(elf_file).?; |
| 97 | const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD); | 97 | const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD); |
| 98 | try atom.addReloc(elf_file, .{ | 98 | try atom.addReloc(elf_file.base.comp.gpa, .{ |
| 99 | .r_offset = end_offset - 4, | 99 | .r_offset = end_offset - 4, |
| 100 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 100 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 101 | .r_addend = lowered_relocs[0].off - 4, | 101 | .r_addend = lowered_relocs[0].off - 4, |
| 102 | }); | 102 | }, zo); |
| 103 | }, | 103 | }, |
| 104 | .linker_dtpoff => |sym_index| { | 104 | .linker_dtpoff => |sym_index| { |
| 105 | const elf_file = emit.lower.bin_file.cast(.elf).?; | 105 | const elf_file = emit.lower.bin_file.cast(.elf).?; |
| 106 | const zo = elf_file.zigObjectPtr().?; | 106 | const zo = elf_file.zigObjectPtr().?; |
| 107 | const atom = zo.symbol(emit.atom_index).atom(elf_file).?; | 107 | const atom = zo.symbol(emit.atom_index).atom(elf_file).?; |
| 108 | const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32); | 108 | const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32); |
| 109 | try atom.addReloc(elf_file, .{ | 109 | try atom.addReloc(elf_file.base.comp.gpa, .{ |
| 110 | .r_offset = end_offset - 4, | 110 | .r_offset = end_offset - 4, |
| 111 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 111 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 112 | .r_addend = lowered_relocs[0].off, | 112 | .r_addend = lowered_relocs[0].off, |
| 113 | }); | 113 | }, zo); |
| 114 | }, | 114 | }, |
| 115 | .linker_reloc => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| { | 115 | .linker_reloc => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| { |
| 116 | const zo = elf_file.zigObjectPtr().?; | 116 | const zo = elf_file.zigObjectPtr().?; |
| ... | @@ -121,21 +121,21 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -121,21 +121,21 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 121 | @intFromEnum(std.elf.R_X86_64.GOTPCREL) | 121 | @intFromEnum(std.elf.R_X86_64.GOTPCREL) |
| 122 | else | 122 | else |
| 123 | @intFromEnum(std.elf.R_X86_64.PC32); | 123 | @intFromEnum(std.elf.R_X86_64.PC32); |
| 124 | try atom.addReloc(elf_file, .{ | 124 | try atom.addReloc(elf_file.base.comp.gpa, .{ |
| 125 | .r_offset = end_offset - 4, | 125 | .r_offset = end_offset - 4, |
| 126 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 126 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 127 | .r_addend = lowered_relocs[0].off - 4, | 127 | .r_addend = lowered_relocs[0].off - 4, |
| 128 | }); | 128 | }, zo); |
| 129 | } else { | 129 | } else { |
| 130 | const r_type: u32 = if (sym.flags.is_tls) | 130 | const r_type: u32 = if (sym.flags.is_tls) |
| 131 | @intFromEnum(std.elf.R_X86_64.TPOFF32) | 131 | @intFromEnum(std.elf.R_X86_64.TPOFF32) |
| 132 | else | 132 | else |
| 133 | @intFromEnum(std.elf.R_X86_64.@"32"); | 133 | @intFromEnum(std.elf.R_X86_64.@"32"); |
| 134 | try atom.addReloc(elf_file, .{ | 134 | try atom.addReloc(elf_file.base.comp.gpa, .{ |
| 135 | .r_offset = end_offset - 4, | 135 | .r_offset = end_offset - 4, |
| 136 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 136 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 137 | .r_addend = lowered_relocs[0].off, | 137 | .r_addend = lowered_relocs[0].off, |
| 138 | }); | 138 | }, zo); |
| 139 | } | 139 | } |
| 140 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { | 140 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { |
| 141 | const zo = macho_file.getZigObject().?; | 141 | const zo = macho_file.getZigObject().?; |
src/link/Dwarf.zig+57-23| ... | @@ -201,7 +201,7 @@ const StringSection = struct { | ... | @@ -201,7 +201,7 @@ const StringSection = struct { |
| 201 | }; | 201 | }; |
| 202 | 202 | ||
| 203 | /// A linker section containing a sequence of `Unit`s. | 203 | /// A linker section containing a sequence of `Unit`s. |
| 204 | const Section = struct { | 204 | pub const Section = struct { |
| 205 | dirty: bool, | 205 | dirty: bool, |
| 206 | pad_to_ideal: bool, | 206 | pad_to_ideal: bool, |
| 207 | alignment: InternPool.Alignment, | 207 | alignment: InternPool.Alignment, |
| ... | @@ -287,7 +287,7 @@ const Section = struct { | ... | @@ -287,7 +287,7 @@ const Section = struct { |
| 287 | return sec.getUnit(unit).addEntry(sec, dwarf); | 287 | return sec.getUnit(unit).addEntry(sec, dwarf); |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | fn getUnit(sec: *Section, unit: Unit.Index) *Unit { | 290 | pub fn getUnit(sec: *Section, unit: Unit.Index) *Unit { |
| 291 | return &sec.units.items[@intFromEnum(unit)]; | 291 | return &sec.units.items[@intFromEnum(unit)]; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| ... | @@ -368,7 +368,7 @@ const Unit = struct { | ... | @@ -368,7 +368,7 @@ const Unit = struct { |
| 368 | none = std.math.maxInt(u32), | 368 | none = std.math.maxInt(u32), |
| 369 | _, | 369 | _, |
| 370 | 370 | ||
| 371 | fn unwrap(uio: Optional) ?Index { | 371 | pub fn unwrap(uio: Optional) ?Index { |
| 372 | return if (uio != .none) @enumFromInt(@intFromEnum(uio)) else null; | 372 | return if (uio != .none) @enumFromInt(@intFromEnum(uio)) else null; |
| 373 | } | 373 | } |
| 374 | }; | 374 | }; |
| ... | @@ -415,7 +415,7 @@ const Unit = struct { | ... | @@ -415,7 +415,7 @@ const Unit = struct { |
| 415 | return entry; | 415 | return entry; |
| 416 | } | 416 | } |
| 417 | 417 | ||
| 418 | fn getEntry(unit: *Unit, entry: Entry.Index) *Entry { | 418 | pub fn getEntry(unit: *Unit, entry: Entry.Index) *Entry { |
| 419 | return &unit.entries.items[@intFromEnum(entry)]; | 419 | return &unit.entries.items[@intFromEnum(entry)]; |
| 420 | } | 420 | } |
| 421 | 421 | ||
| ... | @@ -614,7 +614,7 @@ const Entry = struct { | ... | @@ -614,7 +614,7 @@ const Entry = struct { |
| 614 | none = std.math.maxInt(u32), | 614 | none = std.math.maxInt(u32), |
| 615 | _, | 615 | _, |
| 616 | 616 | ||
| 617 | fn unwrap(eio: Optional) ?Index { | 617 | pub fn unwrap(eio: Optional) ?Index { |
| 618 | return if (eio != .none) @enumFromInt(@intFromEnum(eio)) else null; | 618 | return if (eio != .none) @enumFromInt(@intFromEnum(eio)) else null; |
| 619 | } | 619 | } |
| 620 | }; | 620 | }; |
| ... | @@ -736,7 +736,7 @@ const Entry = struct { | ... | @@ -736,7 +736,7 @@ const Entry = struct { |
| 736 | } | 736 | } |
| 737 | } | 737 | } |
| 738 | 738 | ||
| 739 | fn assertNonEmpty(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) *Entry { | 739 | pub fn assertNonEmpty(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) *Entry { |
| 740 | if (entry.len > 0) return entry; | 740 | if (entry.len > 0) return entry; |
| 741 | if (std.debug.runtime_safety) { | 741 | if (std.debug.runtime_safety) { |
| 742 | log.err("missing {} from {s}", .{ | 742 | log.err("missing {} from {s}", .{ |
| ... | @@ -1958,11 +1958,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -1958,11 +1958,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 1958 | const loc = tree.tokenLocation(0, tree.nodes.items(.main_token)[decl_inst.data.declaration.src_node]); | 1958 | const loc = tree.tokenLocation(0, tree.nodes.items(.main_token)[decl_inst.data.declaration.src_node]); |
| 1959 | assert(loc.line == zcu.navSrcLine(nav_index)); | 1959 | assert(loc.line == zcu.navSrcLine(nav_index)); |
| 1960 | 1960 | ||
| 1961 | const unit = try dwarf.getUnit(file.mod); | ||
| 1962 | var wip_nav: WipNav = .{ | 1961 | var wip_nav: WipNav = .{ |
| 1963 | .dwarf = dwarf, | 1962 | .dwarf = dwarf, |
| 1964 | .pt = pt, | 1963 | .pt = pt, |
| 1965 | .unit = unit, | 1964 | .unit = try dwarf.getUnit(file.mod), |
| 1966 | .entry = undefined, | 1965 | .entry = undefined, |
| 1967 | .any_children = false, | 1966 | .any_children = false, |
| 1968 | .func = .none, | 1967 | .func = .none, |
| ... | @@ -1981,7 +1980,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -1981,7 +1980,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 1981 | switch (ip.indexToKey(nav_val.toIntern())) { | 1980 | switch (ip.indexToKey(nav_val.toIntern())) { |
| 1982 | .func => |func| { | 1981 | .func => |func| { |
| 1983 | if (nav_gop.found_existing) { | 1982 | if (nav_gop.found_existing) { |
| 1984 | const unit_ptr = dwarf.debug_info.section.getUnit(unit); | 1983 | const unit_ptr = dwarf.debug_info.section.getUnit(wip_nav.unit); |
| 1985 | const entry_ptr = unit_ptr.getEntry(nav_gop.value_ptr.*); | 1984 | const entry_ptr = unit_ptr.getEntry(nav_gop.value_ptr.*); |
| 1986 | if (entry_ptr.len >= AbbrevCode.decl_bytes) { | 1985 | if (entry_ptr.len >= AbbrevCode.decl_bytes) { |
| 1987 | var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined; | 1986 | var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined; |
| ... | @@ -2000,7 +1999,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -2000,7 +1999,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 2000 | } | 1999 | } |
| 2001 | } | 2000 | } |
| 2002 | entry_ptr.clear(); | 2001 | entry_ptr.clear(); |
| 2003 | } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | 2002 | } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); |
| 2004 | wip_nav.entry = nav_gop.value_ptr.*; | 2003 | wip_nav.entry = nav_gop.value_ptr.*; |
| 2005 | 2004 | ||
| 2006 | const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: { | 2005 | const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: { |
| ... | @@ -2074,8 +2073,14 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -2074,8 +2073,14 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 2074 | if (type_inst_info.inst != value_inst) break :decl_struct; | 2073 | if (type_inst_info.inst != value_inst) break :decl_struct; |
| 2075 | 2074 | ||
| 2076 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); | 2075 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); |
| 2077 | if (type_gop.found_existing) nav_gop.value_ptr.* = type_gop.value_ptr.* else { | 2076 | if (type_gop.found_existing) { |
| 2078 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | 2077 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); |
| 2078 | nav_gop.value_ptr.* = type_gop.value_ptr.*; | ||
| 2079 | } else { | ||
| 2080 | if (nav_gop.found_existing) | ||
| 2081 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() | ||
| 2082 | else | ||
| 2083 | nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); | ||
| 2079 | type_gop.value_ptr.* = nav_gop.value_ptr.*; | 2084 | type_gop.value_ptr.* = nav_gop.value_ptr.*; |
| 2080 | } | 2085 | } |
| 2081 | wip_nav.entry = nav_gop.value_ptr.*; | 2086 | wip_nav.entry = nav_gop.value_ptr.*; |
| ... | @@ -2139,7 +2144,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -2139,7 +2144,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 2139 | break :done; | 2144 | break :done; |
| 2140 | } | 2145 | } |
| 2141 | 2146 | ||
| 2142 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | 2147 | if (nav_gop.found_existing) |
| 2148 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() | ||
| 2149 | else | ||
| 2150 | nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); | ||
| 2143 | wip_nav.entry = nav_gop.value_ptr.*; | 2151 | wip_nav.entry = nav_gop.value_ptr.*; |
| 2144 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | 2152 | const diw = wip_nav.debug_info.writer(dwarf.gpa); |
| 2145 | try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias)); | 2153 | try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias)); |
| ... | @@ -2190,8 +2198,14 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -2190,8 +2198,14 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 2190 | if (type_inst_info.inst != value_inst) break :decl_enum; | 2198 | if (type_inst_info.inst != value_inst) break :decl_enum; |
| 2191 | 2199 | ||
| 2192 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); | 2200 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); |
| 2193 | if (type_gop.found_existing) nav_gop.value_ptr.* = type_gop.value_ptr.* else { | 2201 | if (type_gop.found_existing) { |
| 2194 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | 2202 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); |
| 2203 | nav_gop.value_ptr.* = type_gop.value_ptr.*; | ||
| 2204 | } else { | ||
| 2205 | if (nav_gop.found_existing) | ||
| 2206 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() | ||
| 2207 | else | ||
| 2208 | nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); | ||
| 2195 | type_gop.value_ptr.* = nav_gop.value_ptr.*; | 2209 | type_gop.value_ptr.* = nav_gop.value_ptr.*; |
| 2196 | } | 2210 | } |
| 2197 | wip_nav.entry = nav_gop.value_ptr.*; | 2211 | wip_nav.entry = nav_gop.value_ptr.*; |
| ... | @@ -2215,7 +2229,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -2215,7 +2229,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 2215 | break :done; | 2229 | break :done; |
| 2216 | } | 2230 | } |
| 2217 | 2231 | ||
| 2218 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | 2232 | if (nav_gop.found_existing) |
| 2233 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() | ||
| 2234 | else | ||
| 2235 | nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); | ||
| 2219 | wip_nav.entry = nav_gop.value_ptr.*; | 2236 | wip_nav.entry = nav_gop.value_ptr.*; |
| 2220 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | 2237 | const diw = wip_nav.debug_info.writer(dwarf.gpa); |
| 2221 | try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias)); | 2238 | try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias)); |
| ... | @@ -2264,8 +2281,14 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -2264,8 +2281,14 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 2264 | if (type_inst_info.inst != value_inst) break :decl_union; | 2281 | if (type_inst_info.inst != value_inst) break :decl_union; |
| 2265 | 2282 | ||
| 2266 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); | 2283 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); |
| 2267 | if (type_gop.found_existing) nav_gop.value_ptr.* = type_gop.value_ptr.* else { | 2284 | if (type_gop.found_existing) { |
| 2268 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | 2285 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); |
| 2286 | nav_gop.value_ptr.* = type_gop.value_ptr.*; | ||
| 2287 | } else { | ||
| 2288 | if (nav_gop.found_existing) | ||
| 2289 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() | ||
| 2290 | else | ||
| 2291 | nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); | ||
| 2269 | type_gop.value_ptr.* = nav_gop.value_ptr.*; | 2292 | type_gop.value_ptr.* = nav_gop.value_ptr.*; |
| 2270 | } | 2293 | } |
| 2271 | wip_nav.entry = nav_gop.value_ptr.*; | 2294 | wip_nav.entry = nav_gop.value_ptr.*; |
| ... | @@ -2328,7 +2351,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -2328,7 +2351,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 2328 | break :done; | 2351 | break :done; |
| 2329 | } | 2352 | } |
| 2330 | 2353 | ||
| 2331 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | 2354 | if (nav_gop.found_existing) |
| 2355 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() | ||
| 2356 | else | ||
| 2357 | nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); | ||
| 2332 | wip_nav.entry = nav_gop.value_ptr.*; | 2358 | wip_nav.entry = nav_gop.value_ptr.*; |
| 2333 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | 2359 | const diw = wip_nav.debug_info.writer(dwarf.gpa); |
| 2334 | try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias)); | 2360 | try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias)); |
| ... | @@ -2377,8 +2403,14 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -2377,8 +2403,14 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 2377 | if (type_inst_info.inst != value_inst) break :decl_opaque; | 2403 | if (type_inst_info.inst != value_inst) break :decl_opaque; |
| 2378 | 2404 | ||
| 2379 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); | 2405 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); |
| 2380 | if (type_gop.found_existing) nav_gop.value_ptr.* = type_gop.value_ptr.* else { | 2406 | if (type_gop.found_existing) { |
| 2381 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | 2407 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); |
| 2408 | nav_gop.value_ptr.* = type_gop.value_ptr.*; | ||
| 2409 | } else { | ||
| 2410 | if (nav_gop.found_existing) | ||
| 2411 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() | ||
| 2412 | else | ||
| 2413 | nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); | ||
| 2382 | type_gop.value_ptr.* = nav_gop.value_ptr.*; | 2414 | type_gop.value_ptr.* = nav_gop.value_ptr.*; |
| 2383 | } | 2415 | } |
| 2384 | wip_nav.entry = nav_gop.value_ptr.*; | 2416 | wip_nav.entry = nav_gop.value_ptr.*; |
| ... | @@ -2394,7 +2426,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -2394,7 +2426,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 2394 | break :done; | 2426 | break :done; |
| 2395 | } | 2427 | } |
| 2396 | 2428 | ||
| 2397 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit); | 2429 | if (nav_gop.found_existing) |
| 2430 | dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() | ||
| 2431 | else | ||
| 2432 | nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); | ||
| 2398 | wip_nav.entry = nav_gop.value_ptr.*; | 2433 | wip_nav.entry = nav_gop.value_ptr.*; |
| 2399 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | 2434 | const diw = wip_nav.debug_info.writer(dwarf.gpa); |
| 2400 | try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias)); | 2435 | try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias)); |
| ... | @@ -2412,7 +2447,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool | ... | @@ -2412,7 +2447,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 2412 | }, | 2447 | }, |
| 2413 | } | 2448 | } |
| 2414 | try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items); | 2449 | try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items); |
| 2415 | try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.items); | ||
| 2416 | try wip_nav.flush(); | 2450 | try wip_nav.flush(); |
| 2417 | } | 2451 | } |
| 2418 | 2452 |
src/link/Elf.zig+84-110| ... | @@ -585,7 +585,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -585,7 +585,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 585 | const ptr_size = self.ptrWidthBytes(); | 585 | const ptr_size = self.ptrWidthBytes(); |
| 586 | const target = self.base.comp.root_mod.resolved_target.result; | 586 | const target = self.base.comp.root_mod.resolved_target.result; |
| 587 | const ptr_bit_width = target.ptrBitWidth(); | 587 | const ptr_bit_width = target.ptrBitWidth(); |
| 588 | const zig_object = self.zigObjectPtr().?; | 588 | const zo = self.zigObjectPtr().?; |
| 589 | 589 | ||
| 590 | const fillSection = struct { | 590 | const fillSection = struct { |
| 591 | fn fillSection(elf_file: *Elf, shdr: *elf.Elf64_Shdr, size: u64, phndx: ?u16) !void { | 591 | fn fillSection(elf_file: *Elf, shdr: *elf.Elf64_Shdr, size: u64, phndx: ?u16) !void { |
| ... | @@ -766,7 +766,27 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -766,7 +766,27 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 766 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{}); | 766 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{}); |
| 767 | } | 767 | } |
| 768 | 768 | ||
| 769 | if (zig_object.dwarf) |*dwarf| { | 769 | if (zo.dwarf) |*dwarf| { |
| 770 | const addSectionSymbol = struct { | ||
| 771 | fn addSectionSymbol( | ||
| 772 | zig_object: *ZigObject, | ||
| 773 | alloc: Allocator, | ||
| 774 | name: [:0]const u8, | ||
| 775 | alignment: Atom.Alignment, | ||
| 776 | shndx: u32, | ||
| 777 | ) !Symbol.Index { | ||
| 778 | const name_off = try zig_object.addString(alloc, name); | ||
| 779 | const index = try zig_object.newSymbolWithAtom(alloc, name_off); | ||
| 780 | const sym = zig_object.symbol(index); | ||
| 781 | const esym = &zig_object.symtab.items(.elf_sym)[sym.esym_index]; | ||
| 782 | esym.st_info |= elf.STT_SECTION; | ||
| 783 | const atom_ptr = zig_object.atom(sym.ref.index).?; | ||
| 784 | atom_ptr.alignment = alignment; | ||
| 785 | atom_ptr.output_section_index = shndx; | ||
| 786 | return index; | ||
| 787 | } | ||
| 788 | }.addSectionSymbol; | ||
| 789 | |||
| 770 | if (self.debug_str_section_index == null) { | 790 | if (self.debug_str_section_index == null) { |
| 771 | self.debug_str_section_index = try self.addSection(.{ | 791 | self.debug_str_section_index = try self.addSection(.{ |
| 772 | .name = try self.insertShString(".debug_str"), | 792 | .name = try self.insertShString(".debug_str"), |
| ... | @@ -775,7 +795,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -775,7 +795,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 775 | .type = elf.SHT_PROGBITS, | 795 | .type = elf.SHT_PROGBITS, |
| 776 | .addralign = 1, | 796 | .addralign = 1, |
| 777 | }); | 797 | }); |
| 778 | zig_object.debug_str_section_dirty = true; | 798 | zo.debug_str_section_dirty = true; |
| 799 | zo.debug_str_index = try addSectionSymbol(zo, gpa, ".debug_str", .@"1", self.debug_str_section_index.?); | ||
| 779 | try self.output_sections.putNoClobber(gpa, self.debug_str_section_index.?, .{}); | 800 | try self.output_sections.putNoClobber(gpa, self.debug_str_section_index.?, .{}); |
| 780 | } | 801 | } |
| 781 | 802 | ||
| ... | @@ -785,7 +806,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -785,7 +806,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 785 | .type = elf.SHT_PROGBITS, | 806 | .type = elf.SHT_PROGBITS, |
| 786 | .addralign = 1, | 807 | .addralign = 1, |
| 787 | }); | 808 | }); |
| 788 | zig_object.debug_info_section_dirty = true; | 809 | zo.debug_info_section_dirty = true; |
| 810 | zo.debug_info_index = try addSectionSymbol(zo, gpa, ".debug_info", .@"1", self.debug_info_section_index.?); | ||
| 789 | try self.output_sections.putNoClobber(gpa, self.debug_info_section_index.?, .{}); | 811 | try self.output_sections.putNoClobber(gpa, self.debug_info_section_index.?, .{}); |
| 790 | } | 812 | } |
| 791 | 813 | ||
| ... | @@ -795,7 +817,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -795,7 +817,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 795 | .type = elf.SHT_PROGBITS, | 817 | .type = elf.SHT_PROGBITS, |
| 796 | .addralign = 1, | 818 | .addralign = 1, |
| 797 | }); | 819 | }); |
| 798 | zig_object.debug_abbrev_section_dirty = true; | 820 | zo.debug_abbrev_section_dirty = true; |
| 821 | zo.debug_abbrev_index = try addSectionSymbol(zo, gpa, ".debug_abbrev", .@"1", self.debug_abbrev_section_index.?); | ||
| 799 | try self.output_sections.putNoClobber(gpa, self.debug_abbrev_section_index.?, .{}); | 822 | try self.output_sections.putNoClobber(gpa, self.debug_abbrev_section_index.?, .{}); |
| 800 | } | 823 | } |
| 801 | 824 | ||
| ... | @@ -805,7 +828,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -805,7 +828,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 805 | .type = elf.SHT_PROGBITS, | 828 | .type = elf.SHT_PROGBITS, |
| 806 | .addralign = 16, | 829 | .addralign = 16, |
| 807 | }); | 830 | }); |
| 808 | zig_object.debug_aranges_section_dirty = true; | 831 | zo.debug_aranges_section_dirty = true; |
| 832 | zo.debug_aranges_index = try addSectionSymbol(zo, gpa, ".debug_aranges", .@"16", self.debug_aranges_section_index.?); | ||
| 809 | try self.output_sections.putNoClobber(gpa, self.debug_aranges_section_index.?, .{}); | 833 | try self.output_sections.putNoClobber(gpa, self.debug_aranges_section_index.?, .{}); |
| 810 | } | 834 | } |
| 811 | 835 | ||
| ... | @@ -815,7 +839,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -815,7 +839,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 815 | .type = elf.SHT_PROGBITS, | 839 | .type = elf.SHT_PROGBITS, |
| 816 | .addralign = 1, | 840 | .addralign = 1, |
| 817 | }); | 841 | }); |
| 818 | zig_object.debug_line_section_dirty = true; | 842 | zo.debug_line_section_dirty = true; |
| 843 | zo.debug_line_index = try addSectionSymbol(zo, gpa, ".debug_line", .@"1", self.debug_line_section_index.?); | ||
| 819 | try self.output_sections.putNoClobber(gpa, self.debug_line_section_index.?, .{}); | 844 | try self.output_sections.putNoClobber(gpa, self.debug_line_section_index.?, .{}); |
| 820 | } | 845 | } |
| 821 | 846 | ||
| ... | @@ -827,7 +852,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -827,7 +852,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 827 | .type = elf.SHT_PROGBITS, | 852 | .type = elf.SHT_PROGBITS, |
| 828 | .addralign = 1, | 853 | .addralign = 1, |
| 829 | }); | 854 | }); |
| 830 | zig_object.debug_line_str_section_dirty = true; | 855 | zo.debug_line_str_section_dirty = true; |
| 856 | zo.debug_line_str_index = try addSectionSymbol(zo, gpa, ".debug_line_str", .@"1", self.debug_line_str_section_index.?); | ||
| 831 | try self.output_sections.putNoClobber(gpa, self.debug_line_str_section_index.?, .{}); | 857 | try self.output_sections.putNoClobber(gpa, self.debug_line_str_section_index.?, .{}); |
| 832 | } | 858 | } |
| 833 | 859 | ||
| ... | @@ -837,7 +863,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -837,7 +863,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 837 | .type = elf.SHT_PROGBITS, | 863 | .type = elf.SHT_PROGBITS, |
| 838 | .addralign = 1, | 864 | .addralign = 1, |
| 839 | }); | 865 | }); |
| 840 | zig_object.debug_loclists_section_dirty = true; | 866 | zo.debug_loclists_section_dirty = true; |
| 867 | zo.debug_loclists_index = try addSectionSymbol(zo, gpa, ".debug_loclists", .@"1", self.debug_loclists_section_index.?); | ||
| 841 | try self.output_sections.putNoClobber(gpa, self.debug_loclists_section_index.?, .{}); | 868 | try self.output_sections.putNoClobber(gpa, self.debug_loclists_section_index.?, .{}); |
| 842 | } | 869 | } |
| 843 | 870 | ||
| ... | @@ -847,7 +874,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -847,7 +874,8 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 847 | .type = elf.SHT_PROGBITS, | 874 | .type = elf.SHT_PROGBITS, |
| 848 | .addralign = 1, | 875 | .addralign = 1, |
| 849 | }); | 876 | }); |
| 850 | zig_object.debug_rnglists_section_dirty = true; | 877 | zo.debug_rnglists_section_dirty = true; |
| 878 | zo.debug_rnglists_index = try addSectionSymbol(zo, gpa, ".debug_rnglists", .@"1", self.debug_rnglists_section_index.?); | ||
| 851 | try self.output_sections.putNoClobber(gpa, self.debug_rnglists_section_index.?, .{}); | 879 | try self.output_sections.putNoClobber(gpa, self.debug_rnglists_section_index.?, .{}); |
| 852 | } | 880 | } |
| 853 | 881 | ||
| ... | @@ -1254,7 +1282,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod | ... | @@ -1254,7 +1282,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod |
| 1254 | try self.addCommentString(); | 1282 | try self.addCommentString(); |
| 1255 | try self.finalizeMergeSections(); | 1283 | try self.finalizeMergeSections(); |
| 1256 | try self.initOutputSections(); | 1284 | try self.initOutputSections(); |
| 1257 | try self.initMergeSections(); | ||
| 1258 | if (self.linkerDefinedPtr()) |obj| { | 1285 | if (self.linkerDefinedPtr()) |obj| { |
| 1259 | try obj.initStartStopSymbols(self); | 1286 | try obj.initStartStopSymbols(self); |
| 1260 | } | 1287 | } |
| ... | @@ -1317,8 +1344,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod | ... | @@ -1317,8 +1344,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod |
| 1317 | try self.base.file.?.pwriteAll(code, file_offset); | 1344 | try self.base.file.?.pwriteAll(code, file_offset); |
| 1318 | } | 1345 | } |
| 1319 | 1346 | ||
| 1320 | if (zo.dwarf) |*dwarf| try dwarf.resolveRelocs(); | ||
| 1321 | |||
| 1322 | if (has_reloc_errors) return error.FlushFailure; | 1347 | if (has_reloc_errors) return error.FlushFailure; |
| 1323 | } | 1348 | } |
| 1324 | 1349 | ||
| ... | @@ -2652,15 +2677,6 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s | ... | @@ -2652,15 +2677,6 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s |
| 2652 | } | 2677 | } |
| 2653 | } | 2678 | } |
| 2654 | 2679 | ||
| 2655 | fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void { | ||
| 2656 | const target = self.base.comp.root_mod.resolved_target.result; | ||
| 2657 | const target_endian = target.cpu.arch.endian(); | ||
| 2658 | switch (self.ptr_width) { | ||
| 2659 | .p32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(addr)), target_endian), | ||
| 2660 | .p64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), addr, target_endian), | ||
| 2661 | } | ||
| 2662 | } | ||
| 2663 | |||
| 2664 | pub fn writeShdrTable(self: *Elf) !void { | 2680 | pub fn writeShdrTable(self: *Elf) !void { |
| 2665 | const gpa = self.base.comp.gpa; | 2681 | const gpa = self.base.comp.gpa; |
| 2666 | const target = self.base.comp.root_mod.resolved_target.result; | 2682 | const target = self.base.comp.root_mod.resolved_target.result; |
| ... | @@ -3031,17 +3047,17 @@ pub fn finalizeMergeSections(self: *Elf) !void { | ... | @@ -3031,17 +3047,17 @@ pub fn finalizeMergeSections(self: *Elf) !void { |
| 3031 | } | 3047 | } |
| 3032 | 3048 | ||
| 3033 | pub fn updateMergeSectionSizes(self: *Elf) !void { | 3049 | pub fn updateMergeSectionSizes(self: *Elf) !void { |
| 3050 | for (self.merge_sections.items) |*msec| { | ||
| 3051 | msec.updateSize(); | ||
| 3052 | } | ||
| 3034 | for (self.merge_sections.items) |*msec| { | 3053 | for (self.merge_sections.items) |*msec| { |
| 3035 | const shdr = &self.shdrs.items[msec.output_section_index]; | 3054 | const shdr = &self.shdrs.items[msec.output_section_index]; |
| 3036 | for (msec.finalized_subsections.items) |msub_index| { | 3055 | const offset = msec.alignment.forward(shdr.sh_size); |
| 3037 | const msub = msec.mergeSubsection(msub_index); | 3056 | const padding = offset - shdr.sh_size; |
| 3038 | assert(msub.alive); | 3057 | msec.value = @intCast(offset); |
| 3039 | const offset = msub.alignment.forward(shdr.sh_size); | 3058 | shdr.sh_size += padding + msec.size; |
| 3040 | const padding = offset - shdr.sh_size; | 3059 | shdr.sh_addralign = @max(shdr.sh_addralign, msec.alignment.toByteUnits() orelse 1); |
| 3041 | msub.value = @intCast(offset); | 3060 | shdr.sh_entsize = if (shdr.sh_entsize == 0) msec.entsize else @min(shdr.sh_entsize, msec.entsize); |
| 3042 | shdr.sh_size += padding + msub.size; | ||
| 3043 | shdr.sh_addralign = @max(shdr.sh_addralign, msub.alignment.toByteUnits() orelse 1); | ||
| 3044 | } | ||
| 3045 | } | 3061 | } |
| 3046 | } | 3062 | } |
| 3047 | 3063 | ||
| ... | @@ -3052,7 +3068,8 @@ pub fn writeMergeSections(self: *Elf) !void { | ... | @@ -3052,7 +3068,8 @@ pub fn writeMergeSections(self: *Elf) !void { |
| 3052 | 3068 | ||
| 3053 | for (self.merge_sections.items) |*msec| { | 3069 | for (self.merge_sections.items) |*msec| { |
| 3054 | const shdr = self.shdrs.items[msec.output_section_index]; | 3070 | const shdr = self.shdrs.items[msec.output_section_index]; |
| 3055 | const size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | 3071 | const fileoff = math.cast(usize, msec.value + shdr.sh_offset) orelse return error.Overflow; |
| 3072 | const size = math.cast(usize, msec.size) orelse return error.Overflow; | ||
| 3056 | try buffer.ensureTotalCapacity(size); | 3073 | try buffer.ensureTotalCapacity(size); |
| 3057 | buffer.appendNTimesAssumeCapacity(0, size); | 3074 | buffer.appendNTimesAssumeCapacity(0, size); |
| 3058 | 3075 | ||
| ... | @@ -3064,7 +3081,7 @@ pub fn writeMergeSections(self: *Elf) !void { | ... | @@ -3064,7 +3081,7 @@ pub fn writeMergeSections(self: *Elf) !void { |
| 3064 | @memcpy(buffer.items[off..][0..string.len], string); | 3081 | @memcpy(buffer.items[off..][0..string.len], string); |
| 3065 | } | 3082 | } |
| 3066 | 3083 | ||
| 3067 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); | 3084 | try self.base.file.?.pwriteAll(buffer.items, fileoff); |
| 3068 | buffer.clearRetainingCapacity(); | 3085 | buffer.clearRetainingCapacity(); |
| 3069 | } | 3086 | } |
| 3070 | } | 3087 | } |
| ... | @@ -3073,26 +3090,9 @@ fn initOutputSections(self: *Elf) !void { | ... | @@ -3073,26 +3090,9 @@ fn initOutputSections(self: *Elf) !void { |
| 3073 | for (self.objects.items) |index| { | 3090 | for (self.objects.items) |index| { |
| 3074 | try self.file(index).?.object.initOutputSections(self); | 3091 | try self.file(index).?.object.initOutputSections(self); |
| 3075 | } | 3092 | } |
| 3076 | } | ||
| 3077 | |||
| 3078 | pub fn initMergeSections(self: *Elf) !void { | ||
| 3079 | for (self.merge_sections.items) |*msec| { | 3093 | for (self.merge_sections.items) |*msec| { |
| 3080 | if (msec.finalized_subsections.items.len == 0) continue; | 3094 | if (msec.finalized_subsections.items.len == 0) continue; |
| 3081 | const name = msec.name(self); | 3095 | try msec.initOutputSection(self); |
| 3082 | const shndx = self.sectionByName(name) orelse try self.addSection(.{ | ||
| 3083 | .name = msec.name_offset, | ||
| 3084 | .type = msec.type, | ||
| 3085 | .flags = msec.flags, | ||
| 3086 | }); | ||
| 3087 | msec.output_section_index = shndx; | ||
| 3088 | |||
| 3089 | var entsize = msec.mergeSubsection(msec.finalized_subsections.items[0]).entsize; | ||
| 3090 | for (msec.finalized_subsections.items) |msub_index| { | ||
| 3091 | const msub = msec.mergeSubsection(msub_index); | ||
| 3092 | entsize = @min(entsize, msub.entsize); | ||
| 3093 | } | ||
| 3094 | const shdr = &self.shdrs.items[shndx]; | ||
| 3095 | shdr.sh_entsize = entsize; | ||
| 3096 | } | 3096 | } |
| 3097 | } | 3097 | } |
| 3098 | 3098 | ||
| ... | @@ -4184,26 +4184,21 @@ pub fn allocateNonAllocSections(self: *Elf) !void { | ... | @@ -4184,26 +4184,21 @@ pub fn allocateNonAllocSections(self: *Elf) !void { |
| 4184 | shdr.sh_offset, | 4184 | shdr.sh_offset, |
| 4185 | new_offset, | 4185 | new_offset, |
| 4186 | }); | 4186 | }); |
| 4187 | const zig_object = self.zigObjectPtr().?; | 4187 | const zo = self.zigObjectPtr().?; |
| 4188 | const existing_size = blk: { | 4188 | const existing_size = for ([_]Symbol.Index{ |
| 4189 | if (shndx == self.debug_info_section_index.?) | 4189 | zo.debug_info_index.?, |
| 4190 | break :blk zig_object.debug_info_section_zig_size; | 4190 | zo.debug_abbrev_index.?, |
| 4191 | if (shndx == self.debug_abbrev_section_index.?) | 4191 | zo.debug_aranges_index.?, |
| 4192 | break :blk zig_object.debug_abbrev_section_zig_size; | 4192 | zo.debug_str_index.?, |
| 4193 | if (shndx == self.debug_str_section_index.?) | 4193 | zo.debug_line_index.?, |
| 4194 | break :blk zig_object.debug_str_section_zig_size; | 4194 | zo.debug_line_str_index.?, |
| 4195 | if (shndx == self.debug_aranges_section_index.?) | 4195 | zo.debug_loclists_index.?, |
| 4196 | break :blk zig_object.debug_aranges_section_zig_size; | 4196 | zo.debug_rnglists_index.?, |
| 4197 | if (shndx == self.debug_line_section_index.?) | 4197 | }) |sym_index| { |
| 4198 | break :blk zig_object.debug_line_section_zig_size; | 4198 | const sym = zo.symbol(sym_index); |
| 4199 | if (shndx == self.debug_line_str_section_index.?) | 4199 | const atom_ptr = sym.atom(self).?; |
| 4200 | break :blk zig_object.debug_line_str_section_zig_size; | 4200 | if (atom_ptr.output_section_index == shndx) break atom_ptr.size; |
| 4201 | if (shndx == self.debug_loclists_section_index.?) | 4201 | } else 0; |
| 4202 | break :blk zig_object.debug_loclists_section_zig_size; | ||
| 4203 | if (shndx == self.debug_rnglists_section_index.?) | ||
| 4204 | break :blk zig_object.debug_rnglists_section_zig_size; | ||
| 4205 | unreachable; | ||
| 4206 | }; | ||
| 4207 | const amt = try self.base.file.?.copyRangeAll( | 4202 | const amt = try self.base.file.?.copyRangeAll( |
| 4208 | shdr.sh_offset, | 4203 | shdr.sh_offset, |
| 4209 | self.base.file.?, | 4204 | self.base.file.?, |
| ... | @@ -4299,24 +4294,21 @@ fn writeAtoms(self: *Elf) !void { | ... | @@ -4299,24 +4294,21 @@ fn writeAtoms(self: *Elf) !void { |
| 4299 | 4294 | ||
| 4300 | // TODO really, really handle debug section separately | 4295 | // TODO really, really handle debug section separately |
| 4301 | const base_offset = if (self.isDebugSection(@intCast(shndx))) blk: { | 4296 | const base_offset = if (self.isDebugSection(@intCast(shndx))) blk: { |
| 4302 | const zig_object = self.zigObjectPtr().?; | 4297 | const zo = self.zigObjectPtr().?; |
| 4303 | if (shndx == self.debug_info_section_index.?) | 4298 | break :blk for ([_]Symbol.Index{ |
| 4304 | break :blk zig_object.debug_info_section_zig_size; | 4299 | zo.debug_info_index.?, |
| 4305 | if (shndx == self.debug_abbrev_section_index.?) | 4300 | zo.debug_abbrev_index.?, |
| 4306 | break :blk zig_object.debug_abbrev_section_zig_size; | 4301 | zo.debug_aranges_index.?, |
| 4307 | if (shndx == self.debug_str_section_index.?) | 4302 | zo.debug_str_index.?, |
| 4308 | break :blk zig_object.debug_str_section_zig_size; | 4303 | zo.debug_line_index.?, |
| 4309 | if (shndx == self.debug_aranges_section_index.?) | 4304 | zo.debug_line_str_index.?, |
| 4310 | break :blk zig_object.debug_aranges_section_zig_size; | 4305 | zo.debug_loclists_index.?, |
| 4311 | if (shndx == self.debug_line_section_index.?) | 4306 | zo.debug_rnglists_index.?, |
| 4312 | break :blk zig_object.debug_line_section_zig_size; | 4307 | }) |sym_index| { |
| 4313 | if (shndx == self.debug_line_str_section_index.?) | 4308 | const sym = zo.symbol(sym_index); |
| 4314 | break :blk zig_object.debug_line_str_section_zig_size; | 4309 | const atom_ptr = sym.atom(self).?; |
| 4315 | if (shndx == self.debug_loclists_section_index.?) | 4310 | if (atom_ptr.output_section_index == shndx) break atom_ptr.size; |
| 4316 | break :blk zig_object.debug_loclists_section_zig_size; | 4311 | } else 0; |
| 4317 | if (shndx == self.debug_rnglists_section_index.?) | ||
| 4318 | break :blk zig_object.debug_rnglists_section_zig_size; | ||
| 4319 | unreachable; | ||
| 4320 | } else 0; | 4312 | } else 0; |
| 4321 | const sh_offset = shdr.sh_offset + base_offset; | 4313 | const sh_offset = shdr.sh_offset + base_offset; |
| 4322 | const sh_size = math.cast(usize, shdr.sh_size - base_offset) orelse return error.Overflow; | 4314 | const sh_size = math.cast(usize, shdr.sh_size - base_offset) orelse return error.Overflow; |
| ... | @@ -4410,7 +4402,6 @@ pub fn updateSymtabSize(self: *Elf) !void { | ... | @@ -4410,7 +4402,6 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4410 | if (self.eh_frame_section_index) |_| { | 4402 | if (self.eh_frame_section_index) |_| { |
| 4411 | nlocals += 1; | 4403 | nlocals += 1; |
| 4412 | } | 4404 | } |
| 4413 | nlocals += @intCast(self.merge_sections.items.len); | ||
| 4414 | 4405 | ||
| 4415 | if (self.requiresThunks()) for (self.thunks.items) |*th| { | 4406 | if (self.requiresThunks()) for (self.thunks.items) |*th| { |
| 4416 | th.output_symtab_ctx.ilocal = nlocals + 1; | 4407 | th.output_symtab_ctx.ilocal = nlocals + 1; |
| ... | @@ -4734,30 +4725,12 @@ fn writeSectionSymbols(self: *Elf) void { | ... | @@ -4734,30 +4725,12 @@ fn writeSectionSymbols(self: *Elf) void { |
| 4734 | }; | 4725 | }; |
| 4735 | ilocal += 1; | 4726 | ilocal += 1; |
| 4736 | } | 4727 | } |
| 4737 | |||
| 4738 | for (self.merge_sections.items) |msec| { | ||
| 4739 | const shdr = self.shdrs.items[msec.output_section_index]; | ||
| 4740 | const out_sym = &self.symtab.items[ilocal]; | ||
| 4741 | out_sym.* = .{ | ||
| 4742 | .st_name = 0, | ||
| 4743 | .st_value = shdr.sh_addr, | ||
| 4744 | .st_info = elf.STT_SECTION, | ||
| 4745 | .st_shndx = @intCast(msec.output_section_index), | ||
| 4746 | .st_size = 0, | ||
| 4747 | .st_other = 0, | ||
| 4748 | }; | ||
| 4749 | ilocal += 1; | ||
| 4750 | } | ||
| 4751 | } | 4728 | } |
| 4752 | 4729 | ||
| 4753 | pub fn sectionSymbolOutputSymtabIndex(self: Elf, shndx: u32) u32 { | 4730 | pub fn sectionSymbolOutputSymtabIndex(self: Elf, shndx: u32) u32 { |
| 4754 | if (self.eh_frame_section_index) |index| { | 4731 | if (self.eh_frame_section_index) |index| { |
| 4755 | if (index == shndx) return @intCast(self.output_sections.keys().len + 1); | 4732 | if (index == shndx) return @intCast(self.output_sections.keys().len + 1); |
| 4756 | } | 4733 | } |
| 4757 | const base: usize = if (self.eh_frame_section_index == null) 0 else 1; | ||
| 4758 | for (self.merge_sections.items, 0..) |msec, index| { | ||
| 4759 | if (msec.output_section_index == shndx) return @intCast(self.output_sections.keys().len + 1 + index + base); | ||
| 4760 | } | ||
| 4761 | return @intCast(self.output_sections.getIndex(shndx).? + 1); | 4734 | return @intCast(self.output_sections.getIndex(shndx).? + 1); |
| 4762 | } | 4735 | } |
| 4763 | 4736 | ||
| ... | @@ -5520,10 +5493,11 @@ fn formatShdr( | ... | @@ -5520,10 +5493,11 @@ fn formatShdr( |
| 5520 | _ = options; | 5493 | _ = options; |
| 5521 | _ = unused_fmt_string; | 5494 | _ = unused_fmt_string; |
| 5522 | const shdr = ctx.shdr; | 5495 | const shdr = ctx.shdr; |
| 5523 | try writer.print("{s} : @{x} ({x}) : align({x}) : size({x}) : flags({})", .{ | 5496 | try writer.print("{s} : @{x} ({x}) : align({x}) : size({x}) : entsize({x}) : flags({})", .{ |
| 5524 | ctx.elf_file.getShString(shdr.sh_name), shdr.sh_offset, | 5497 | ctx.elf_file.getShString(shdr.sh_name), shdr.sh_offset, |
| 5525 | shdr.sh_addr, shdr.sh_addralign, | 5498 | shdr.sh_addr, shdr.sh_addralign, |
| 5526 | shdr.sh_size, fmtShdrFlags(shdr.sh_flags), | 5499 | shdr.sh_size, shdr.sh_entsize, |
| 5500 | fmtShdrFlags(shdr.sh_flags), | ||
| 5527 | }); | 5501 | }); |
| 5528 | } | 5502 | } |
| 5529 | 5503 |
src/link/Elf/Atom.zig+12-14| ... | @@ -302,7 +302,7 @@ pub fn free(self: *Atom, elf_file: *Elf) void { | ... | @@ -302,7 +302,7 @@ pub fn free(self: *Atom, elf_file: *Elf) void { |
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | // TODO create relocs free list | 304 | // TODO create relocs free list |
| 305 | self.freeRelocs(elf_file); | 305 | self.freeRelocs(zo); |
| 306 | // TODO figure out how to free input section mappind in ZigModule | 306 | // TODO figure out how to free input section mappind in ZigModule |
| 307 | // const zig_object = elf_file.zigObjectPtr().? | 307 | // const zig_object = elf_file.zigObjectPtr().? |
| 308 | // assert(zig_object.atoms.swapRemove(self.atom_index)); | 308 | // assert(zig_object.atoms.swapRemove(self.atom_index)); |
| ... | @@ -377,21 +377,19 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void { | ... | @@ -377,21 +377,19 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void { |
| 377 | } | 377 | } |
| 378 | } | 378 | } |
| 379 | 379 | ||
| 380 | pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void { | 380 | pub fn addReloc(self: Atom, alloc: Allocator, reloc: elf.Elf64_Rela, zo: *ZigObject) !void { |
| 381 | const comp = elf_file.base.comp; | 381 | const rels = &zo.relocs.items[self.relocs_section_index]; |
| 382 | const gpa = comp.gpa; | 382 | try rels.ensureUnusedCapacity(alloc, 1); |
| 383 | const file_ptr = self.file(elf_file).?; | 383 | self.addRelocAssumeCapacity(reloc, zo); |
| 384 | assert(file_ptr == .zig_object); | ||
| 385 | const zig_object = file_ptr.zig_object; | ||
| 386 | const rels = &zig_object.relocs.items[self.relocs_section_index]; | ||
| 387 | try rels.append(gpa, reloc); | ||
| 388 | } | 384 | } |
| 389 | 385 | ||
| 390 | pub fn freeRelocs(self: Atom, elf_file: *Elf) void { | 386 | pub fn addRelocAssumeCapacity(self: Atom, reloc: elf.Elf64_Rela, zo: *ZigObject) void { |
| 391 | const file_ptr = self.file(elf_file).?; | 387 | const rels = &zo.relocs.items[self.relocs_section_index]; |
| 392 | assert(file_ptr == .zig_object); | 388 | rels.appendAssumeCapacity(reloc); |
| 393 | const zig_object = file_ptr.zig_object; | 389 | } |
| 394 | zig_object.relocs.items[self.relocs_section_index].clearRetainingCapacity(); | 390 | |
| 391 | pub fn freeRelocs(self: Atom, zo: *ZigObject) void { | ||
| 392 | zo.relocs.items[self.relocs_section_index].clearRetainingCapacity(); | ||
| 395 | } | 393 | } |
| 396 | 394 | ||
| 397 | pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool { | 395 | pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool { |
src/link/Elf/ZigObject.zig+159-47| ... | @@ -50,16 +50,14 @@ debug_line_str_section_dirty: bool = false, | ... | @@ -50,16 +50,14 @@ debug_line_str_section_dirty: bool = false, |
| 50 | debug_loclists_section_dirty: bool = false, | 50 | debug_loclists_section_dirty: bool = false, |
| 51 | debug_rnglists_section_dirty: bool = false, | 51 | debug_rnglists_section_dirty: bool = false, |
| 52 | 52 | ||
| 53 | /// Size contribution of Zig's metadata to each debug section. | 53 | debug_info_index: ?Symbol.Index = null, |
| 54 | /// Used to track start of metadata from input object files. | 54 | debug_abbrev_index: ?Symbol.Index = null, |
| 55 | debug_info_section_zig_size: u64 = 0, | 55 | debug_aranges_index: ?Symbol.Index = null, |
| 56 | debug_abbrev_section_zig_size: u64 = 0, | 56 | debug_str_index: ?Symbol.Index = null, |
| 57 | debug_str_section_zig_size: u64 = 0, | 57 | debug_line_index: ?Symbol.Index = null, |
| 58 | debug_aranges_section_zig_size: u64 = 0, | 58 | debug_line_str_index: ?Symbol.Index = null, |
| 59 | debug_line_section_zig_size: u64 = 0, | 59 | debug_loclists_index: ?Symbol.Index = null, |
| 60 | debug_line_str_section_zig_size: u64 = 0, | 60 | debug_rnglists_index: ?Symbol.Index = null, |
| 61 | debug_loclists_section_zig_size: u64 = 0, | ||
| 62 | debug_rnglists_section_zig_size: u64 = 0, | ||
| 63 | 61 | ||
| 64 | pub const global_symbol_bit: u32 = 0x80000000; | 62 | pub const global_symbol_bit: u32 = 0x80000000; |
| 65 | pub const symbol_mask: u32 = 0x7fffffff; | 63 | pub const symbol_mask: u32 = 0x7fffffff; |
| ... | @@ -171,13 +169,154 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi | ... | @@ -171,13 +169,154 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi |
| 171 | if (self.dwarf) |*dwarf| { | 169 | if (self.dwarf) |*dwarf| { |
| 172 | const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid }; | 170 | const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid }; |
| 173 | try dwarf.flushModule(pt); | 171 | try dwarf.flushModule(pt); |
| 172 | try dwarf.resolveRelocs(); | ||
| 173 | |||
| 174 | const gpa = elf_file.base.comp.gpa; | ||
| 175 | const cpu_arch = elf_file.getTarget().cpu.arch; | ||
| 176 | |||
| 177 | // TODO invert this logic so that we manage the output section with the atom, not the | ||
| 178 | // other way around | ||
| 179 | for ([_]u32{ | ||
| 180 | self.debug_info_index.?, | ||
| 181 | self.debug_abbrev_index.?, | ||
| 182 | self.debug_str_index.?, | ||
| 183 | self.debug_aranges_index.?, | ||
| 184 | self.debug_line_index.?, | ||
| 185 | self.debug_line_str_index.?, | ||
| 186 | self.debug_loclists_index.?, | ||
| 187 | self.debug_rnglists_index.?, | ||
| 188 | }, [_]*Dwarf.Section{ | ||
| 189 | &dwarf.debug_info.section, | ||
| 190 | &dwarf.debug_abbrev.section, | ||
| 191 | &dwarf.debug_str.section, | ||
| 192 | &dwarf.debug_aranges.section, | ||
| 193 | &dwarf.debug_line.section, | ||
| 194 | &dwarf.debug_line_str.section, | ||
| 195 | &dwarf.debug_loclists.section, | ||
| 196 | &dwarf.debug_rnglists.section, | ||
| 197 | }) |sym_index, sect| { | ||
| 198 | const sym = self.symbol(sym_index); | ||
| 199 | const atom_ptr = self.atom(sym.ref.index).?; | ||
| 200 | if (!atom_ptr.alive) continue; | ||
| 201 | const shndx = sym.outputShndx(elf_file).?; | ||
| 202 | const shdr = elf_file.shdrs.items[shndx]; | ||
| 203 | const esym = &self.symtab.items(.elf_sym)[sym.esym_index]; | ||
| 204 | esym.st_size = shdr.sh_size; | ||
| 205 | atom_ptr.size = shdr.sh_size; | ||
| 206 | atom_ptr.alignment = Atom.Alignment.fromNonzeroByteUnits(shdr.sh_addralign); | ||
| 207 | |||
| 208 | log.debug("parsing relocs in {s}", .{sym.name(elf_file)}); | ||
| 209 | |||
| 210 | const relocs = &self.relocs.items[atom_ptr.relocsShndx().?]; | ||
| 211 | for (sect.units.items) |*unit| { | ||
| 212 | try relocs.ensureUnusedCapacity(gpa, unit.cross_section_relocs.items.len); | ||
| 213 | for (unit.cross_section_relocs.items) |reloc| { | ||
| 214 | const target_sym_index = switch (reloc.target_sec) { | ||
| 215 | .debug_abbrev => self.debug_abbrev_index.?, | ||
| 216 | .debug_info => self.debug_info_index.?, | ||
| 217 | .debug_line => self.debug_line_index.?, | ||
| 218 | .debug_line_str => self.debug_line_str_index.?, | ||
| 219 | .debug_loclists => self.debug_loclists_index.?, | ||
| 220 | .debug_rnglists => self.debug_rnglists_index.?, | ||
| 221 | .debug_str => self.debug_str_index.?, | ||
| 222 | }; | ||
| 223 | const target_sec = switch (reloc.target_sec) { | ||
| 224 | inline else => |target_sec| &@field(dwarf, @tagName(target_sec)).section, | ||
| 225 | }; | ||
| 226 | const target_unit = target_sec.getUnit(reloc.target_unit); | ||
| 227 | const r_offset = unit.off + reloc.source_off; | ||
| 228 | const r_addend: i64 = @intCast(target_unit.off + reloc.target_off + (if (reloc.target_entry.unwrap()) |target_entry| | ||
| 229 | target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sect, dwarf).off | ||
| 230 | else | ||
| 231 | 0)); | ||
| 232 | const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch); | ||
| 233 | log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{ | ||
| 234 | self.symbol(target_sym_index).name(elf_file), | ||
| 235 | r_offset, | ||
| 236 | r_addend, | ||
| 237 | relocation.fmtRelocType(r_type, cpu_arch), | ||
| 238 | }); | ||
| 239 | atom_ptr.addRelocAssumeCapacity(.{ | ||
| 240 | .r_offset = r_offset, | ||
| 241 | .r_addend = r_addend, | ||
| 242 | .r_info = (@as(u64, @intCast(target_sym_index)) << 32) | r_type, | ||
| 243 | }, self); | ||
| 244 | } | ||
| 245 | |||
| 246 | for (unit.entries.items) |*entry| { | ||
| 247 | const entry_off = unit.off + unit.header_len + entry.off; | ||
| 248 | |||
| 249 | try relocs.ensureUnusedCapacity(gpa, entry.cross_section_relocs.items.len); | ||
| 250 | for (entry.cross_section_relocs.items) |reloc| { | ||
| 251 | const target_sym_index = switch (reloc.target_sec) { | ||
| 252 | .debug_abbrev => self.debug_abbrev_index.?, | ||
| 253 | .debug_info => self.debug_info_index.?, | ||
| 254 | .debug_line => self.debug_line_index.?, | ||
| 255 | .debug_line_str => self.debug_line_str_index.?, | ||
| 256 | .debug_loclists => self.debug_loclists_index.?, | ||
| 257 | .debug_rnglists => self.debug_rnglists_index.?, | ||
| 258 | .debug_str => self.debug_str_index.?, | ||
| 259 | }; | ||
| 260 | const target_sec = switch (reloc.target_sec) { | ||
| 261 | inline else => |target_sec| &@field(dwarf, @tagName(target_sec)).section, | ||
| 262 | }; | ||
| 263 | const target_unit = target_sec.getUnit(reloc.target_unit); | ||
| 264 | const r_offset = entry_off + reloc.source_off; | ||
| 265 | const r_addend: i64 = @intCast(target_unit.off + reloc.target_off + (if (reloc.target_entry.unwrap()) |target_entry| | ||
| 266 | target_unit.header_len + target_unit.getEntry(target_entry).assertNonEmpty(unit, sect, dwarf).off | ||
| 267 | else | ||
| 268 | 0)); | ||
| 269 | const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch); | ||
| 270 | log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{ | ||
| 271 | self.symbol(target_sym_index).name(elf_file), | ||
| 272 | r_offset, | ||
| 273 | r_addend, | ||
| 274 | relocation.fmtRelocType(r_type, cpu_arch), | ||
| 275 | }); | ||
| 276 | atom_ptr.addRelocAssumeCapacity(.{ | ||
| 277 | .r_offset = r_offset, | ||
| 278 | .r_addend = r_addend, | ||
| 279 | .r_info = (@as(u64, @intCast(target_sym_index)) << 32) | r_type, | ||
| 280 | }, self); | ||
| 281 | } | ||
| 282 | |||
| 283 | try relocs.ensureUnusedCapacity(gpa, entry.external_relocs.items.len); | ||
| 284 | for (entry.external_relocs.items) |reloc| { | ||
| 285 | const target_sym = self.symbol(reloc.target_sym); | ||
| 286 | const r_offset = entry_off + reloc.source_off; | ||
| 287 | const r_addend: i64 = @intCast(reloc.target_off); | ||
| 288 | const r_type = relocation.dwarf.externalRelocType(target_sym.*, dwarf.address_size, cpu_arch); | ||
| 289 | log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{ | ||
| 290 | target_sym.name(elf_file), | ||
| 291 | r_offset, | ||
| 292 | r_addend, | ||
| 293 | relocation.fmtRelocType(r_type, cpu_arch), | ||
| 294 | }); | ||
| 295 | atom_ptr.addRelocAssumeCapacity(.{ | ||
| 296 | .r_offset = r_offset, | ||
| 297 | .r_addend = r_addend, | ||
| 298 | .r_info = (@as(u64, @intCast(reloc.target_sym)) << 32) | r_type, | ||
| 299 | }, self); | ||
| 300 | } | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | if (elf_file.base.isRelocatable() and relocs.items.len > 0) { | ||
| 305 | const gop = try elf_file.output_rela_sections.getOrPut(gpa, shndx); | ||
| 306 | if (!gop.found_existing) { | ||
| 307 | const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)}); | ||
| 308 | defer gpa.free(rela_sect_name); | ||
| 309 | const rela_sh_name = try elf_file.insertShString(rela_sect_name); | ||
| 310 | const rela_shndx = try elf_file.addRelaShdr(rela_sh_name, shndx); | ||
| 311 | gop.value_ptr.* = .{ .shndx = rela_shndx }; | ||
| 312 | } | ||
| 313 | } | ||
| 314 | } | ||
| 174 | 315 | ||
| 175 | self.debug_abbrev_section_dirty = false; | 316 | self.debug_abbrev_section_dirty = false; |
| 176 | self.debug_aranges_section_dirty = false; | 317 | self.debug_aranges_section_dirty = false; |
| 177 | self.debug_rnglists_section_dirty = false; | 318 | self.debug_rnglists_section_dirty = false; |
| 178 | self.debug_str_section_dirty = false; | 319 | self.debug_str_section_dirty = false; |
| 179 | |||
| 180 | self.saveDebugSectionsSizes(elf_file); | ||
| 181 | } | 320 | } |
| 182 | 321 | ||
| 183 | // The point of flushModule() is to commit changes, so in theory, nothing should | 322 | // The point of flushModule() is to commit changes, so in theory, nothing should |
| ... | @@ -190,33 +329,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi | ... | @@ -190,33 +329,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi |
| 190 | assert(!self.debug_str_section_dirty); | 329 | assert(!self.debug_str_section_dirty); |
| 191 | } | 330 | } |
| 192 | 331 | ||
| 193 | fn saveDebugSectionsSizes(self: *ZigObject, elf_file: *Elf) void { | ||
| 194 | if (elf_file.debug_info_section_index) |shndx| { | ||
| 195 | self.debug_info_section_zig_size = elf_file.shdrs.items[shndx].sh_size; | ||
| 196 | } | ||
| 197 | if (elf_file.debug_abbrev_section_index) |shndx| { | ||
| 198 | self.debug_abbrev_section_zig_size = elf_file.shdrs.items[shndx].sh_size; | ||
| 199 | } | ||
| 200 | if (elf_file.debug_str_section_index) |shndx| { | ||
| 201 | self.debug_str_section_zig_size = elf_file.shdrs.items[shndx].sh_size; | ||
| 202 | } | ||
| 203 | if (elf_file.debug_aranges_section_index) |shndx| { | ||
| 204 | self.debug_aranges_section_zig_size = elf_file.shdrs.items[shndx].sh_size; | ||
| 205 | } | ||
| 206 | if (elf_file.debug_line_section_index) |shndx| { | ||
| 207 | self.debug_line_section_zig_size = elf_file.shdrs.items[shndx].sh_size; | ||
| 208 | } | ||
| 209 | if (elf_file.debug_line_str_section_index) |shndx| { | ||
| 210 | self.debug_line_str_section_zig_size = elf_file.shdrs.items[shndx].sh_size; | ||
| 211 | } | ||
| 212 | if (elf_file.debug_loclists_section_index) |shndx| { | ||
| 213 | self.debug_loclists_section_zig_size = elf_file.shdrs.items[shndx].sh_size; | ||
| 214 | } | ||
| 215 | if (elf_file.debug_rnglists_section_index) |shndx| { | ||
| 216 | self.debug_rnglists_section_zig_size = elf_file.shdrs.items[shndx].sh_size; | ||
| 217 | } | ||
| 218 | } | ||
| 219 | |||
| 220 | fn newSymbol(self: *ZigObject, allocator: Allocator, name_off: u32, st_bind: u4) !Symbol.Index { | 332 | fn newSymbol(self: *ZigObject, allocator: Allocator, name_off: u32, st_bind: u4) !Symbol.Index { |
| 221 | try self.symtab.ensureUnusedCapacity(allocator, 1); | 333 | try self.symtab.ensureUnusedCapacity(allocator, 1); |
| 222 | try self.symbols.ensureUnusedCapacity(allocator, 1); | 334 | try self.symbols.ensureUnusedCapacity(allocator, 1); |
| ... | @@ -278,7 +390,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Atom.Index { | ... | @@ -278,7 +390,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Atom.Index { |
| 278 | return index; | 390 | return index; |
| 279 | } | 391 | } |
| 280 | 392 | ||
| 281 | fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Symbol.Index { | 393 | pub fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Symbol.Index { |
| 282 | const atom_index = try self.newAtom(allocator, name_off); | 394 | const atom_index = try self.newAtom(allocator, name_off); |
| 283 | const sym_index = try self.newLocalSymbol(allocator, name_off); | 395 | const sym_index = try self.newLocalSymbol(allocator, name_off); |
| 284 | const sym = self.symbol(sym_index); | 396 | const sym = self.symbol(sym_index); |
| ... | @@ -642,11 +754,11 @@ pub fn getNavVAddr( | ... | @@ -642,11 +754,11 @@ pub fn getNavVAddr( |
| 642 | const vaddr = this_sym.address(.{}, elf_file); | 754 | const vaddr = this_sym.address(.{}, elf_file); |
| 643 | const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?; | 755 | const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?; |
| 644 | const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); | 756 | const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); |
| 645 | try parent_atom.addReloc(elf_file, .{ | 757 | try parent_atom.addReloc(elf_file.base.comp.gpa, .{ |
| 646 | .r_offset = reloc_info.offset, | 758 | .r_offset = reloc_info.offset, |
| 647 | .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type, | 759 | .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type, |
| 648 | .r_addend = reloc_info.addend, | 760 | .r_addend = reloc_info.addend, |
| 649 | }); | 761 | }, self); |
| 650 | return @intCast(vaddr); | 762 | return @intCast(vaddr); |
| 651 | } | 763 | } |
| 652 | 764 | ||
| ... | @@ -661,11 +773,11 @@ pub fn getUavVAddr( | ... | @@ -661,11 +773,11 @@ pub fn getUavVAddr( |
| 661 | const vaddr = sym.address(.{}, elf_file); | 773 | const vaddr = sym.address(.{}, elf_file); |
| 662 | const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?; | 774 | const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?; |
| 663 | const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); | 775 | const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); |
| 664 | try parent_atom.addReloc(elf_file, .{ | 776 | try parent_atom.addReloc(elf_file.base.comp.gpa, .{ |
| 665 | .r_offset = reloc_info.offset, | 777 | .r_offset = reloc_info.offset, |
| 666 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, | 778 | .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, |
| 667 | .r_addend = reloc_info.addend, | 779 | .r_addend = reloc_info.addend, |
| 668 | }); | 780 | }, self); |
| 669 | return @intCast(vaddr); | 781 | return @intCast(vaddr); |
| 670 | } | 782 | } |
| 671 | 783 | ||
| ... | @@ -1012,7 +1124,7 @@ pub fn updateFunc( | ... | @@ -1012,7 +1124,7 @@ pub fn updateFunc( |
| 1012 | log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav }); | 1124 | log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav }); |
| 1013 | 1125 | ||
| 1014 | const sym_index = try self.getOrCreateMetadataForNav(elf_file, func.owner_nav); | 1126 | const sym_index = try self.getOrCreateMetadataForNav(elf_file, func.owner_nav); |
| 1015 | self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); | 1127 | self.symbol(sym_index).atom(elf_file).?.freeRelocs(self); |
| 1016 | 1128 | ||
| 1017 | var code_buffer = std.ArrayList(u8).init(gpa); | 1129 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1018 | defer code_buffer.deinit(); | 1130 | defer code_buffer.deinit(); |
| ... | @@ -1140,7 +1252,7 @@ pub fn updateNav( | ... | @@ -1140,7 +1252,7 @@ pub fn updateNav( |
| 1140 | 1252 | ||
| 1141 | if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) { | 1253 | if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) { |
| 1142 | const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index); | 1254 | const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index); |
| 1143 | self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); | 1255 | self.symbol(sym_index).atom(elf_file).?.freeRelocs(self); |
| 1144 | 1256 | ||
| 1145 | var code_buffer = std.ArrayList(u8).init(zcu.gpa); | 1257 | var code_buffer = std.ArrayList(u8).init(zcu.gpa); |
| 1146 | defer code_buffer.deinit(); | 1258 | defer code_buffer.deinit(); |
| ... | @@ -1529,7 +1641,7 @@ pub fn asFile(self: *ZigObject) File { | ... | @@ -1529,7 +1641,7 @@ pub fn asFile(self: *ZigObject) File { |
| 1529 | return .{ .zig_object = self }; | 1641 | return .{ .zig_object = self }; |
| 1530 | } | 1642 | } |
| 1531 | 1643 | ||
| 1532 | fn addString(self: *ZigObject, allocator: Allocator, string: []const u8) !u32 { | 1644 | pub fn addString(self: *ZigObject, allocator: Allocator, string: []const u8) !u32 { |
| 1533 | return self.strtab.insert(allocator, string); | 1645 | return self.strtab.insert(allocator, string); |
| 1534 | } | 1646 | } |
| 1535 | 1647 |
src/link/Elf/merge_section.zig+32-2| ... | @@ -1,4 +1,8 @@ | ... | @@ -1,4 +1,8 @@ |
| 1 | pub const MergeSection = struct { | 1 | pub const MergeSection = struct { |
| 2 | value: u64 = 0, | ||
| 3 | size: u64 = 0, | ||
| 4 | alignment: Atom.Alignment = .@"1", | ||
| 5 | entsize: u32 = 0, | ||
| 2 | name_offset: u32 = 0, | 6 | name_offset: u32 = 0, |
| 3 | type: u32 = 0, | 7 | type: u32 = 0, |
| 4 | flags: u64 = 0, | 8 | flags: u64 = 0, |
| ... | @@ -26,7 +30,7 @@ pub const MergeSection = struct { | ... | @@ -26,7 +30,7 @@ pub const MergeSection = struct { |
| 26 | 30 | ||
| 27 | pub fn address(msec: MergeSection, elf_file: *Elf) i64 { | 31 | pub fn address(msec: MergeSection, elf_file: *Elf) i64 { |
| 28 | const shdr = elf_file.shdrs.items[msec.output_section_index]; | 32 | const shdr = elf_file.shdrs.items[msec.output_section_index]; |
| 29 | return @intCast(shdr.sh_addr); | 33 | return @intCast(shdr.sh_addr + msec.value); |
| 30 | } | 34 | } |
| 31 | 35 | ||
| 32 | const InsertResult = struct { | 36 | const InsertResult = struct { |
| ... | @@ -90,6 +94,29 @@ pub const MergeSection = struct { | ... | @@ -90,6 +94,29 @@ pub const MergeSection = struct { |
| 90 | std.mem.sort(MergeSubsection.Index, msec.finalized_subsections.items, msec, sortFn); | 94 | std.mem.sort(MergeSubsection.Index, msec.finalized_subsections.items, msec, sortFn); |
| 91 | } | 95 | } |
| 92 | 96 | ||
| 97 | pub fn updateSize(msec: *MergeSection) void { | ||
| 98 | for (msec.finalized_subsections.items) |msub_index| { | ||
| 99 | const msub = msec.mergeSubsection(msub_index); | ||
| 100 | assert(msub.alive); | ||
| 101 | const offset = msub.alignment.forward(msec.size); | ||
| 102 | const padding = offset - msec.size; | ||
| 103 | msub.value = @intCast(offset); | ||
| 104 | msec.size += padding + msub.size; | ||
| 105 | msec.alignment = msec.alignment.max(msub.alignment); | ||
| 106 | msec.entsize = if (msec.entsize == 0) msub.entsize else @min(msec.entsize, msub.entsize); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | pub fn initOutputSection(msec: *MergeSection, elf_file: *Elf) !void { | ||
| 111 | const shndx = elf_file.sectionByName(msec.name(elf_file)) orelse try elf_file.addSection(.{ | ||
| 112 | .name = msec.name_offset, | ||
| 113 | .type = msec.type, | ||
| 114 | .flags = msec.flags, | ||
| 115 | }); | ||
| 116 | try elf_file.output_sections.put(elf_file.base.comp.gpa, shndx, .{}); | ||
| 117 | msec.output_section_index = shndx; | ||
| 118 | } | ||
| 119 | |||
| 93 | pub fn addMergeSubsection(msec: *MergeSection, allocator: Allocator) !MergeSubsection.Index { | 120 | pub fn addMergeSubsection(msec: *MergeSection, allocator: Allocator) !MergeSubsection.Index { |
| 94 | const index: MergeSubsection.Index = @intCast(msec.subsections.items.len); | 121 | const index: MergeSubsection.Index = @intCast(msec.subsections.items.len); |
| 95 | const msub = try msec.subsections.addOne(allocator); | 122 | const msub = try msec.subsections.addOne(allocator); |
| ... | @@ -163,9 +190,12 @@ pub const MergeSection = struct { | ... | @@ -163,9 +190,12 @@ pub const MergeSection = struct { |
| 163 | _ = unused_fmt_string; | 190 | _ = unused_fmt_string; |
| 164 | const msec = ctx.msec; | 191 | const msec = ctx.msec; |
| 165 | const elf_file = ctx.elf_file; | 192 | const elf_file = ctx.elf_file; |
| 166 | try writer.print("{s} : @{x} : type({x}) : flags({x})\n", .{ | 193 | try writer.print("{s} : @{x} : size({x}) : align({x}) : entsize({x}) : type({x}) : flags({x})\n", .{ |
| 167 | msec.name(elf_file), | 194 | msec.name(elf_file), |
| 168 | msec.address(elf_file), | 195 | msec.address(elf_file), |
| 196 | msec.size, | ||
| 197 | msec.alignment.toByteUnits() orelse 0, | ||
| 198 | msec.entsize, | ||
| 169 | msec.type, | 199 | msec.type, |
| 170 | msec.flags, | 200 | msec.flags, |
| 171 | }); | 201 | }); |
src/link/Elf/relocatable.zig+26-20| ... | @@ -42,7 +42,11 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]co | ... | @@ -42,7 +42,11 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]co |
| 42 | try elf_file.finalizeMergeSections(); | 42 | try elf_file.finalizeMergeSections(); |
| 43 | zig_object.claimUnresolvedObject(elf_file); | 43 | zig_object.claimUnresolvedObject(elf_file); |
| 44 | 44 | ||
| 45 | try elf_file.initMergeSections(); | 45 | for (elf_file.merge_sections.items) |*msec| { |
| 46 | if (msec.finalized_subsections.items.len == 0) continue; | ||
| 47 | try msec.initOutputSection(elf_file); | ||
| 48 | } | ||
| 49 | |||
| 46 | try elf_file.initSymtab(); | 50 | try elf_file.initSymtab(); |
| 47 | try elf_file.initShStrtab(); | 51 | try elf_file.initShStrtab(); |
| 48 | try elf_file.sortShdrs(); | 52 | try elf_file.sortShdrs(); |
| ... | @@ -198,7 +202,6 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]const | ... | @@ -198,7 +202,6 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]const |
| 198 | claimUnresolved(elf_file); | 202 | claimUnresolved(elf_file); |
| 199 | 203 | ||
| 200 | try initSections(elf_file); | 204 | try initSections(elf_file); |
| 201 | try elf_file.initMergeSections(); | ||
| 202 | try elf_file.sortShdrs(); | 205 | try elf_file.sortShdrs(); |
| 203 | if (elf_file.zigObjectPtr()) |zig_object| { | 206 | if (elf_file.zigObjectPtr()) |zig_object| { |
| 204 | try zig_object.addAtomsToRelaSections(elf_file); | 207 | try zig_object.addAtomsToRelaSections(elf_file); |
| ... | @@ -294,6 +297,11 @@ fn initSections(elf_file: *Elf) !void { | ... | @@ -294,6 +297,11 @@ fn initSections(elf_file: *Elf) !void { |
| 294 | try object.initRelaSections(elf_file); | 297 | try object.initRelaSections(elf_file); |
| 295 | } | 298 | } |
| 296 | 299 | ||
| 300 | for (elf_file.merge_sections.items) |*msec| { | ||
| 301 | if (msec.finalized_subsections.items.len == 0) continue; | ||
| 302 | try msec.initOutputSection(elf_file); | ||
| 303 | } | ||
| 304 | |||
| 297 | const needs_eh_frame = for (elf_file.objects.items) |index| { | 305 | const needs_eh_frame = for (elf_file.objects.items) |index| { |
| 298 | if (elf_file.file(index).?.object.cies.items.len > 0) break true; | 306 | if (elf_file.file(index).?.object.cies.items.len > 0) break true; |
| 299 | } else false; | 307 | } else false; |
| ... | @@ -423,24 +431,21 @@ fn writeAtoms(elf_file: *Elf) !void { | ... | @@ -423,24 +431,21 @@ fn writeAtoms(elf_file: *Elf) !void { |
| 423 | 431 | ||
| 424 | // TODO really, really handle debug section separately | 432 | // TODO really, really handle debug section separately |
| 425 | const base_offset = if (elf_file.isDebugSection(@intCast(shndx))) blk: { | 433 | const base_offset = if (elf_file.isDebugSection(@intCast(shndx))) blk: { |
| 426 | const zig_object = elf_file.zigObjectPtr().?; | 434 | const zo = elf_file.zigObjectPtr().?; |
| 427 | if (shndx == elf_file.debug_info_section_index.?) | 435 | break :blk for ([_]Symbol.Index{ |
| 428 | break :blk zig_object.debug_info_section_zig_size; | 436 | zo.debug_info_index.?, |
| 429 | if (shndx == elf_file.debug_abbrev_section_index.?) | 437 | zo.debug_abbrev_index.?, |
| 430 | break :blk zig_object.debug_abbrev_section_zig_size; | 438 | zo.debug_aranges_index.?, |
| 431 | if (shndx == elf_file.debug_str_section_index.?) | 439 | zo.debug_str_index.?, |
| 432 | break :blk zig_object.debug_str_section_zig_size; | 440 | zo.debug_line_index.?, |
| 433 | if (shndx == elf_file.debug_aranges_section_index.?) | 441 | zo.debug_line_str_index.?, |
| 434 | break :blk zig_object.debug_aranges_section_zig_size; | 442 | zo.debug_loclists_index.?, |
| 435 | if (shndx == elf_file.debug_line_section_index.?) | 443 | zo.debug_rnglists_index.?, |
| 436 | break :blk zig_object.debug_line_section_zig_size; | 444 | }) |sym_index| { |
| 437 | if (shndx == elf_file.debug_line_str_section_index.?) | 445 | const sym = zo.symbol(sym_index); |
| 438 | break :blk zig_object.debug_line_str_section_zig_size; | 446 | const atom_ptr = sym.atom(elf_file).?; |
| 439 | if (shndx == elf_file.debug_loclists_section_index.?) | 447 | if (atom_ptr.output_section_index == shndx) break atom_ptr.size; |
| 440 | break :blk zig_object.debug_loclists_section_zig_size; | 448 | } else 0; |
| 441 | if (shndx == elf_file.debug_rnglists_section_index.?) | ||
| 442 | break :blk zig_object.debug_rnglists_section_zig_size; | ||
| 443 | unreachable; | ||
| 444 | } else 0; | 449 | } else 0; |
| 445 | const sh_offset = shdr.sh_offset + base_offset; | 450 | const sh_offset = shdr.sh_offset + base_offset; |
| 446 | const sh_size = math.cast(usize, shdr.sh_size - base_offset) orelse return error.Overflow; | 451 | const sh_size = math.cast(usize, shdr.sh_size - base_offset) orelse return error.Overflow; |
| ... | @@ -586,3 +591,4 @@ const Compilation = @import("../../Compilation.zig"); | ... | @@ -586,3 +591,4 @@ const Compilation = @import("../../Compilation.zig"); |
| 586 | const Elf = @import("../Elf.zig"); | 591 | const Elf = @import("../Elf.zig"); |
| 587 | const File = @import("file.zig").File; | 592 | const File = @import("file.zig").File; |
| 588 | const Object = @import("Object.zig"); | 593 | const Object = @import("Object.zig"); |
| 594 | const Symbol = @import("Symbol.zig"); |
src/link/Elf/relocation.zig+40| ... | @@ -91,6 +91,44 @@ pub fn encode(comptime kind: Kind, cpu_arch: std.Target.Cpu.Arch) u32 { | ... | @@ -91,6 +91,44 @@ pub fn encode(comptime kind: Kind, cpu_arch: std.Target.Cpu.Arch) u32 { |
| 91 | }; | 91 | }; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | pub const dwarf = struct { | ||
| 95 | pub fn crossSectionRelocType(format: DW.Format, cpu_arch: std.Target.Cpu.Arch) u32 { | ||
| 96 | return switch (cpu_arch) { | ||
| 97 | .x86_64 => @intFromEnum(switch (format) { | ||
| 98 | .@"32" => elf.R_X86_64.@"32", | ||
| 99 | .@"64" => .@"64", | ||
| 100 | }), | ||
| 101 | .riscv64 => @intFromEnum(switch (format) { | ||
| 102 | .@"32" => elf.R_RISCV.@"32", | ||
| 103 | .@"64" => .@"64", | ||
| 104 | }), | ||
| 105 | else => @panic("TODO unhandled cpu arch"), | ||
| 106 | }; | ||
| 107 | } | ||
| 108 | |||
| 109 | pub fn externalRelocType( | ||
| 110 | target: Symbol, | ||
| 111 | address_size: Dwarf.AddressSize, | ||
| 112 | cpu_arch: std.Target.Cpu.Arch, | ||
| 113 | ) u32 { | ||
| 114 | return switch (cpu_arch) { | ||
| 115 | .x86_64 => @intFromEnum(switch (address_size) { | ||
| 116 | .@"32" => if (target.flags.is_tls) elf.R_X86_64.DTPOFF32 else .@"32", | ||
| 117 | .@"64" => if (target.flags.is_tls) elf.R_X86_64.DTPOFF64 else .@"64", | ||
| 118 | else => unreachable, | ||
| 119 | }), | ||
| 120 | .riscv64 => @intFromEnum(switch (address_size) { | ||
| 121 | .@"32" => elf.R_RISCV.@"32", | ||
| 122 | .@"64" => elf.R_RISCV.@"64", | ||
| 123 | else => unreachable, | ||
| 124 | }), | ||
| 125 | else => @panic("TODO unhandled cpu arch"), | ||
| 126 | }; | ||
| 127 | } | ||
| 128 | |||
| 129 | const DW = std.dwarf; | ||
| 130 | }; | ||
| 131 | |||
| 94 | const FormatRelocTypeCtx = struct { | 132 | const FormatRelocTypeCtx = struct { |
| 95 | r_type: u32, | 133 | r_type: u32, |
| 96 | cpu_arch: std.Target.Cpu.Arch, | 134 | cpu_arch: std.Target.Cpu.Arch, |
| ... | @@ -124,4 +162,6 @@ const assert = std.debug.assert; | ... | @@ -124,4 +162,6 @@ const assert = std.debug.assert; |
| 124 | const elf = std.elf; | 162 | const elf = std.elf; |
| 125 | const std = @import("std"); | 163 | const std = @import("std"); |
| 126 | 164 | ||
| 165 | const Dwarf = @import("../Dwarf.zig"); | ||
| 127 | const Elf = @import("../Elf.zig"); | 166 | const Elf = @import("../Elf.zig"); |
| 167 | const Symbol = @import("Symbol.zig"); |
test/src/Debugger.zig+38| ... | @@ -695,6 +695,44 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { | ... | @@ -695,6 +695,44 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { |
| 695 | \\1 breakpoints deleted; 0 breakpoint locations disabled. | 695 | \\1 breakpoints deleted; 0 breakpoint locations disabled. |
| 696 | }, | 696 | }, |
| 697 | ); | 697 | ); |
| 698 | db.addLldbTest( | ||
| 699 | "link_object", | ||
| 700 | target, | ||
| 701 | &.{ | ||
| 702 | .{ | ||
| 703 | .path = "main.zig", | ||
| 704 | .source = | ||
| 705 | \\extern fn fabsf(f32) f32; | ||
| 706 | \\pub fn main() void { | ||
| 707 | \\ var x: f32 = -1234.5; | ||
| 708 | \\ x = fabsf(x); | ||
| 709 | \\ _ = &x; | ||
| 710 | \\} | ||
| 711 | , | ||
| 712 | }, | ||
| 713 | }, | ||
| 714 | \\breakpoint set --file main.zig --source-pattern-regexp 'x = fabsf\(x\);' | ||
| 715 | \\process launch | ||
| 716 | \\frame variable x | ||
| 717 | \\breakpoint delete --force 1 | ||
| 718 | \\ | ||
| 719 | \\breakpoint set --file main.zig --source-pattern-regexp '_ = &x;' | ||
| 720 | \\process continue | ||
| 721 | \\frame variable x | ||
| 722 | \\breakpoint delete --force 2 | ||
| 723 | , | ||
| 724 | &.{ | ||
| 725 | \\(lldb) frame variable x | ||
| 726 | \\(f32) x = -1234.5 | ||
| 727 | \\(lldb) breakpoint delete --force 1 | ||
| 728 | \\1 breakpoints deleted; 0 breakpoint locations disabled. | ||
| 729 | , | ||
| 730 | \\(lldb) frame variable x | ||
| 731 | \\(f32) x = 1234.5 | ||
| 732 | \\(lldb) breakpoint delete --force 2 | ||
| 733 | \\1 breakpoints deleted; 0 breakpoint locations disabled. | ||
| 734 | }, | ||
| 735 | ); | ||
| 698 | } | 736 | } |
| 699 | 737 | ||
| 700 | const File = struct { import: ?[]const u8 = null, path: []const u8, source: []const u8 }; | 738 | const File = struct { import: ?[]const u8 = null, path: []const u8, source: []const u8 }; |