authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-10-04 12:46:57+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-09 12:38:53-07:00
loge448fb960137e5aa83a1e7c2e6cbbf688f4fce05
tree1ffad6ca3fe35659df183971fdc9c2bc85d835ac
parentc92c72d08cfb102206594d723e29dd0616290d31

elf: change how we manage debug atoms in Dwarf linker


5 files changed, 97 insertions(+), 97 deletions(-)

src/link/Dwarf.zig+26-18
...@@ -389,14 +389,20 @@ pub const Section = struct {...@@ -389,14 +389,20 @@ pub const Section = struct {
389 if (dwarf.bin_file.cast(.elf)) |elf_file| {389 if (dwarf.bin_file.cast(.elf)) |elf_file| {
390 const zo = elf_file.zigObjectPtr().?;390 const zo = elf_file.zigObjectPtr().?;
391 const atom = zo.symbol(sec.index).atom(elf_file).?;391 const atom = zo.symbol(sec.index).atom(elf_file).?;
392 const shndx = atom.output_section_index;392 const old_size = atom.size;
393 const needed_size = len;393 atom.size = len;
394 const min_alignment = sec.alignment.toByteUnits().?;394 atom.alignment = sec.alignment;
395 try elf_file.growSection(shndx, needed_size, min_alignment);395 sec.len = len;
396 const shdr = elf_file.sections.items(.shdr)[shndx];396 if (old_size > 0) {
397 atom.size = needed_size;397 if (!atom.alignment.check(@intCast(atom.value)) or atom.size > atom.fileCapacity(elf_file)) {
398 atom.alignment = InternPool.Alignment.fromNonzeroByteUnits(shdr.sh_addralign);398 try zo.allocateAtom(atom, false, elf_file);
399 sec.len = needed_size;399 } else {
400 const shdr = &elf_file.sections.items(.shdr)[atom.output_section_index];
401 shdr.sh_size = (shdr.sh_size - old_size) + atom.size;
402 }
403 } else {
404 try zo.allocateAtom(atom, false, elf_file);
405 }
400 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {406 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
401 const header = if (macho_file.d_sym) |*d_sym| header: {407 const header = if (macho_file.d_sym) |*d_sym| header: {
402 try d_sym.growSection(@intCast(sec.index), len, true, macho_file);408 try d_sym.growSection(@intCast(sec.index), len, true, macho_file);
...@@ -417,11 +423,15 @@ pub const Section = struct {...@@ -417,11 +423,15 @@ pub const Section = struct {
417 if (dwarf.bin_file.cast(.elf)) |elf_file| {423 if (dwarf.bin_file.cast(.elf)) |elf_file| {
418 const zo = elf_file.zigObjectPtr().?;424 const zo = elf_file.zigObjectPtr().?;
419 const atom = zo.symbol(sec.index).atom(elf_file).?;425 const atom = zo.symbol(sec.index).atom(elf_file).?;
420 const shndx = atom.output_section_index;426 if (atom.prevAtom(elf_file)) |_| {
421 const shdr = &elf_file.sections.items(.shdr)[shndx];427 // FIXME:JK trimming/shrinking has to be reworked on ZigObject/Elf level
422 atom.size = sec.len;428 atom.value += len;
423 shdr.sh_offset += len;429 } else {
424 shdr.sh_size = sec.len;430 const shdr = &elf_file.sections.items(.shdr)[atom.output_section_index];
431 shdr.sh_offset += len;
432 atom.value = 0;
433 }
434 atom.size -= len;
425 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {435 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
426 const header = if (macho_file.d_sym) |*d_sym|436 const header = if (macho_file.d_sym) |*d_sym|
427 &d_sym.sections.items[sec.index]437 &d_sym.sections.items[sec.index]
...@@ -910,11 +920,9 @@ const Entry = struct {...@@ -910,11 +920,9 @@ const Entry = struct {
910 if (std.debug.runtime_safety) {920 if (std.debug.runtime_safety) {
911 log.err("missing {} from {s}", .{921 log.err("missing {} from {s}", .{
912 @as(Entry.Index, @enumFromInt(entry - unit.entries.items.ptr)),922 @as(Entry.Index, @enumFromInt(entry - unit.entries.items.ptr)),
913 std.mem.sliceTo(if (dwarf.bin_file.cast(.elf)) |elf_file| sh_name: {923 std.mem.sliceTo(if (dwarf.bin_file.cast(.elf)) |elf_file|
914 const zo = elf_file.zigObjectPtr().?;924 elf_file.zigObjectPtr().?.symbol(sec.index).name(elf_file)
915 const shndx = zo.symbol(sec.index).atom(elf_file).?.output_section_index;925 else if (dwarf.bin_file.cast(.macho)) |macho_file|
916 break :sh_name elf_file.shstrtab.items[elf_file.sections.items(.shdr)[shndx].sh_name..];
917 } else if (dwarf.bin_file.cast(.macho)) |macho_file|
918 if (macho_file.d_sym) |*d_sym|926 if (macho_file.d_sym) |*d_sym|
919 &d_sym.sections.items[sec.index].segname927 &d_sym.sections.items[sec.index].segname
920 else928 else
src/link/Elf.zig+23-30
...@@ -573,10 +573,10 @@ pub fn growSection(self: *Elf, shdr_index: u32, needed_size: u64, min_alignment:...@@ -573,10 +573,10 @@ pub fn growSection(self: *Elf, shdr_index: u32, needed_size: u64, min_alignment:
573 // Must move the entire section.573 // Must move the entire section.
574 const new_offset = try self.findFreeSpace(needed_size, min_alignment);574 const new_offset = try self.findFreeSpace(needed_size, min_alignment);
575575
576 log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{576 log.debug("moving '{s}' from 0x{x} to 0x{x}", .{
577 self.getShString(shdr.sh_name),577 self.getShString(shdr.sh_name),
578 shdr.sh_offset,
578 new_offset,579 new_offset,
579 new_offset + existing_size,
580 });580 });
581581
582 const amt = try self.base.file.?.copyRangeAll(582 const amt = try self.base.file.?.copyRangeAll(
...@@ -691,13 +691,6 @@ pub fn allocateChunk(self: *Elf, args: struct {...@@ -691,13 +691,6 @@ pub fn allocateChunk(self: *Elf, args: struct {
691 }691 }
692 };692 };
693693
694 log.debug("allocated chunk (size({x}),align({x})) at 0x{x} (file(0x{x}))", .{
695 args.size,
696 args.alignment.toByteUnits().?,
697 shdr.sh_addr + res.value,
698 shdr.sh_offset + res.value,
699 });
700
701 const expand_section = if (self.atom(res.placement)) |placement_atom|694 const expand_section = if (self.atom(res.placement)) |placement_atom|
702 placement_atom.nextAtom(self) == null695 placement_atom.nextAtom(self) == null
703 else696 else
...@@ -707,6 +700,18 @@ pub fn allocateChunk(self: *Elf, args: struct {...@@ -707,6 +700,18 @@ pub fn allocateChunk(self: *Elf, args: struct {
707 try self.growSection(args.shndx, needed_size, args.alignment.toByteUnits().?);700 try self.growSection(args.shndx, needed_size, args.alignment.toByteUnits().?);
708 }701 }
709702
703 log.debug("allocated chunk (size({x}),align({x})) in {s} at 0x{x} (file(0x{x}))", .{
704 args.size,
705 args.alignment.toByteUnits().?,
706 self.getShString(shdr.sh_name),
707 shdr.sh_addr + res.value,
708 shdr.sh_offset + res.value,
709 });
710 log.debug(" placement {}, {s}", .{
711 res.placement,
712 if (self.atom(res.placement)) |atom_ptr| atom_ptr.name(self) else "",
713 });
714
710 return res;715 return res;
711}716}
712717
...@@ -1796,6 +1801,7 @@ pub fn initOutputSection(self: *Elf, args: struct {...@@ -1796,6 +1801,7 @@ pub fn initOutputSection(self: *Elf, args: struct {
1796 .type = @"type",1801 .type = @"type",
1797 .flags = flags,1802 .flags = flags,
1798 .name = try self.insertShString(name),1803 .name = try self.insertShString(name),
1804 .offset = std.math.maxInt(u64),
1799 });1805 });
1800 return out_shndx;1806 return out_shndx;
1801}1807}
...@@ -3898,27 +3904,14 @@ pub fn allocateNonAllocSections(self: *Elf) !void {...@@ -3898,27 +3904,14 @@ pub fn allocateNonAllocSections(self: *Elf) !void {
3898 shdr.sh_size = 0;3904 shdr.sh_size = 0;
3899 const new_offset = try self.findFreeSpace(needed_size, shdr.sh_addralign);3905 const new_offset = try self.findFreeSpace(needed_size, shdr.sh_addralign);
39003906
3901 if (self.zigObjectPtr()) |zo| blk: {3907 log.debug("moving {s} from 0x{x} to 0x{x}", .{
3902 const existing_size = for ([_]?Symbol.Index{3908 self.getShString(shdr.sh_name),
3903 zo.debug_info_index,3909 shdr.sh_offset,
3904 zo.debug_abbrev_index,3910 new_offset,
3905 zo.debug_aranges_index,3911 });
3906 zo.debug_str_index,3912
3907 zo.debug_line_index,3913 if (shdr.sh_offset > 0) {
3908 zo.debug_line_str_index,3914 const existing_size = self.sectionSize(@intCast(shndx));
3909 zo.debug_loclists_index,
3910 zo.debug_rnglists_index,
3911 }) |maybe_sym_index| {
3912 const sym_index = maybe_sym_index orelse continue;
3913 const sym = zo.symbol(sym_index);
3914 const atom_ptr = sym.atom(self).?;
3915 if (atom_ptr.output_section_index == shndx) break atom_ptr.size;
3916 } else break :blk;
3917 log.debug("moving {s} from 0x{x} to 0x{x}", .{
3918 self.getShString(shdr.sh_name),
3919 shdr.sh_offset,
3920 new_offset,
3921 });
3922 const amt = try self.base.file.?.copyRangeAll(3915 const amt = try self.base.file.?.copyRangeAll(
3923 shdr.sh_offset,3916 shdr.sh_offset,
3924 self.base.file.?,3917 self.base.file.?,
src/link/Elf/Atom.zig+10-1
...@@ -118,10 +118,19 @@ pub fn capacity(self: Atom, elf_file: *Elf) u64 {...@@ -118,10 +118,19 @@ pub fn capacity(self: Atom, elf_file: *Elf) u64 {
118 return @intCast(next_addr - self.address(elf_file));118 return @intCast(next_addr - self.address(elf_file));
119}119}
120120
121pub fn fileCapacity(self: Atom, elf_file: *Elf) u64 {
122 const self_off = self.offset(elf_file);
123 const next_off = if (self.nextAtom(elf_file)) |next_atom|
124 next_atom.offset(elf_file)
125 else
126 self_off + elf_file.allocatedSize(self_off);
127 return @intCast(next_off - self_off);
128}
129
121pub fn freeListEligible(self: Atom, elf_file: *Elf) bool {130pub fn freeListEligible(self: Atom, elf_file: *Elf) bool {
122 // No need to keep a free list node for the last block.131 // No need to keep a free list node for the last block.
123 const next = self.nextAtom(elf_file) orelse return false;132 const next = self.nextAtom(elf_file) orelse return false;
124 const cap: u64 = @intCast(next.address(elf_file) - self.address(elf_file));133 const cap: u64 = @intCast(next.value - self.value);
125 const ideal_cap = Elf.padToIdeal(self.size);134 const ideal_cap = Elf.padToIdeal(self.size);
126 if (cap <= ideal_cap) return false;135 if (cap <= ideal_cap) return false;
127 const surplus = cap - ideal_cap;136 const surplus = cap - ideal_cap;
src/link/Elf/ZigObject.zig+30-30
...@@ -130,10 +130,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -130,10 +130,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
130 .entsize = 1,130 .entsize = 1,
131 .type = elf.SHT_PROGBITS,131 .type = elf.SHT_PROGBITS,
132 .addralign = 1,132 .addralign = 1,
133 .offset = std.math.maxInt(u64),
133 });134 });
134 self.debug_str_section_dirty = true;135 self.debug_str_section_dirty = true;
135 self.debug_str_index = try addSectionSymbolWithAtom(self, gpa, ".debug_str", .@"1", osec);136 self.debug_str_index = try addSectionSymbolWithAtom(self, gpa, ".debug_str", .@"1", osec);
136 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_str_index.?).ref;
137 }137 }
138138
139 if (self.debug_info_index == null) {139 if (self.debug_info_index == null) {
...@@ -141,10 +141,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -141,10 +141,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
141 .name = try elf_file.insertShString(".debug_info"),141 .name = try elf_file.insertShString(".debug_info"),
142 .type = elf.SHT_PROGBITS,142 .type = elf.SHT_PROGBITS,
143 .addralign = 1,143 .addralign = 1,
144 .offset = std.math.maxInt(u64),
144 });145 });
145 self.debug_info_section_dirty = true;146 self.debug_info_section_dirty = true;
146 self.debug_info_index = try addSectionSymbolWithAtom(self, gpa, ".debug_info", .@"1", osec);147 self.debug_info_index = try addSectionSymbolWithAtom(self, gpa, ".debug_info", .@"1", osec);
147 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_info_index.?).ref;
148 }148 }
149149
150 if (self.debug_abbrev_index == null) {150 if (self.debug_abbrev_index == null) {
...@@ -152,10 +152,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -152,10 +152,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
152 .name = try elf_file.insertShString(".debug_abbrev"),152 .name = try elf_file.insertShString(".debug_abbrev"),
153 .type = elf.SHT_PROGBITS,153 .type = elf.SHT_PROGBITS,
154 .addralign = 1,154 .addralign = 1,
155 .offset = std.math.maxInt(u64),
155 });156 });
156 self.debug_abbrev_section_dirty = true;157 self.debug_abbrev_section_dirty = true;
157 self.debug_abbrev_index = try addSectionSymbolWithAtom(self, gpa, ".debug_abbrev", .@"1", osec);158 self.debug_abbrev_index = try addSectionSymbolWithAtom(self, gpa, ".debug_abbrev", .@"1", osec);
158 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_abbrev_index.?).ref;
159 }159 }
160160
161 if (self.debug_aranges_index == null) {161 if (self.debug_aranges_index == null) {
...@@ -163,10 +163,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -163,10 +163,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
163 .name = try elf_file.insertShString(".debug_aranges"),163 .name = try elf_file.insertShString(".debug_aranges"),
164 .type = elf.SHT_PROGBITS,164 .type = elf.SHT_PROGBITS,
165 .addralign = 16,165 .addralign = 16,
166 .offset = std.math.maxInt(u64),
166 });167 });
167 self.debug_aranges_section_dirty = true;168 self.debug_aranges_section_dirty = true;
168 self.debug_aranges_index = try addSectionSymbolWithAtom(self, gpa, ".debug_aranges", .@"16", osec);169 self.debug_aranges_index = try addSectionSymbolWithAtom(self, gpa, ".debug_aranges", .@"16", osec);
169 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_aranges_index.?).ref;
170 }170 }
171171
172 if (self.debug_line_index == null) {172 if (self.debug_line_index == null) {
...@@ -174,10 +174,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -174,10 +174,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
174 .name = try elf_file.insertShString(".debug_line"),174 .name = try elf_file.insertShString(".debug_line"),
175 .type = elf.SHT_PROGBITS,175 .type = elf.SHT_PROGBITS,
176 .addralign = 1,176 .addralign = 1,
177 .offset = std.math.maxInt(u64),
177 });178 });
178 self.debug_line_section_dirty = true;179 self.debug_line_section_dirty = true;
179 self.debug_line_index = try addSectionSymbolWithAtom(self, gpa, ".debug_line", .@"1", osec);180 self.debug_line_index = try addSectionSymbolWithAtom(self, gpa, ".debug_line", .@"1", osec);
180 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_line_index.?).ref;
181 }181 }
182182
183 if (self.debug_line_str_index == null) {183 if (self.debug_line_str_index == null) {
...@@ -187,10 +187,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -187,10 +187,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
187 .entsize = 1,187 .entsize = 1,
188 .type = elf.SHT_PROGBITS,188 .type = elf.SHT_PROGBITS,
189 .addralign = 1,189 .addralign = 1,
190 .offset = std.math.maxInt(u64),
190 });191 });
191 self.debug_line_str_section_dirty = true;192 self.debug_line_str_section_dirty = true;
192 self.debug_line_str_index = try addSectionSymbolWithAtom(self, gpa, ".debug_line_str", .@"1", osec);193 self.debug_line_str_index = try addSectionSymbolWithAtom(self, gpa, ".debug_line_str", .@"1", osec);
193 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_line_str_index.?).ref;
194 }194 }
195195
196 if (self.debug_loclists_index == null) {196 if (self.debug_loclists_index == null) {
...@@ -198,10 +198,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -198,10 +198,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
198 .name = try elf_file.insertShString(".debug_loclists"),198 .name = try elf_file.insertShString(".debug_loclists"),
199 .type = elf.SHT_PROGBITS,199 .type = elf.SHT_PROGBITS,
200 .addralign = 1,200 .addralign = 1,
201 .offset = std.math.maxInt(u64),
201 });202 });
202 self.debug_loclists_section_dirty = true;203 self.debug_loclists_section_dirty = true;
203 self.debug_loclists_index = try addSectionSymbolWithAtom(self, gpa, ".debug_loclists", .@"1", osec);204 self.debug_loclists_index = try addSectionSymbolWithAtom(self, gpa, ".debug_loclists", .@"1", osec);
204 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_loclists_index.?).ref;
205 }205 }
206206
207 if (self.debug_rnglists_index == null) {207 if (self.debug_rnglists_index == null) {
...@@ -209,10 +209,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -209,10 +209,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
209 .name = try elf_file.insertShString(".debug_rnglists"),209 .name = try elf_file.insertShString(".debug_rnglists"),
210 .type = elf.SHT_PROGBITS,210 .type = elf.SHT_PROGBITS,
211 .addralign = 1,211 .addralign = 1,
212 .offset = std.math.maxInt(u64),
212 });213 });
213 self.debug_rnglists_section_dirty = true;214 self.debug_rnglists_section_dirty = true;
214 self.debug_rnglists_index = try addSectionSymbolWithAtom(self, gpa, ".debug_rnglists", .@"1", osec);215 self.debug_rnglists_index = try addSectionSymbolWithAtom(self, gpa, ".debug_rnglists", .@"1", osec);
215 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_rnglists_index.?).ref;
216 }216 }
217217
218 if (self.eh_frame_index == null) {218 if (self.eh_frame_index == null) {
...@@ -224,10 +224,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -224,10 +224,10 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
224 elf.SHT_PROGBITS,224 elf.SHT_PROGBITS,
225 .flags = elf.SHF_ALLOC,225 .flags = elf.SHF_ALLOC,
226 .addralign = ptr_size,226 .addralign = ptr_size,
227 .offset = std.math.maxInt(u64),
227 });228 });
228 self.eh_frame_section_dirty = true;229 self.eh_frame_section_dirty = true;
229 self.eh_frame_index = try addSectionSymbolWithAtom(self, gpa, ".eh_frame", Atom.Alignment.fromNonzeroByteUnits(ptr_size), osec);230 self.eh_frame_index = try addSectionSymbolWithAtom(self, gpa, ".eh_frame", Atom.Alignment.fromNonzeroByteUnits(ptr_size), osec);
230 elf_file.sections.items(.last_atom)[osec] = self.symbol(self.eh_frame_index.?).ref;
231 }231 }
232232
233 try dwarf.initMetadata();233 try dwarf.initMetadata();
...@@ -1318,7 +1318,7 @@ fn updateNavCode(...@@ -1318,7 +1318,7 @@ fn updateNavCode(
1318 const capacity = atom_ptr.capacity(elf_file);1318 const capacity = atom_ptr.capacity(elf_file);
1319 const need_realloc = code.len > capacity or !required_alignment.check(@intCast(atom_ptr.value));1319 const need_realloc = code.len > capacity or !required_alignment.check(@intCast(atom_ptr.value));
1320 if (need_realloc) {1320 if (need_realloc) {
1321 try self.growAtom(atom_ptr, elf_file);1321 try self.allocateAtom(atom_ptr, true, elf_file);
1322 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), old_vaddr, atom_ptr.value });1322 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), old_vaddr, atom_ptr.value });
1323 if (old_vaddr != atom_ptr.value) {1323 if (old_vaddr != atom_ptr.value) {
1324 sym.value = 0;1324 sym.value = 0;
...@@ -1328,7 +1328,7 @@ fn updateNavCode(...@@ -1328,7 +1328,7 @@ fn updateNavCode(
1328 // TODO shrink section size1328 // TODO shrink section size
1329 }1329 }
1330 } else {1330 } else {
1331 try self.allocateAtom(atom_ptr, elf_file);1331 try self.allocateAtom(atom_ptr, true, elf_file);
1332 errdefer self.freeNavMetadata(elf_file, sym_index);1332 errdefer self.freeNavMetadata(elf_file, sym_index);
1333 sym.value = 0;1333 sym.value = 0;
1334 esym.st_value = 0;1334 esym.st_value = 0;
...@@ -1403,7 +1403,7 @@ fn updateTlv(...@@ -1403,7 +1403,7 @@ fn updateTlv(
1403 const gop = try self.tls_variables.getOrPut(gpa, atom_ptr.atom_index);1403 const gop = try self.tls_variables.getOrPut(gpa, atom_ptr.atom_index);
1404 assert(!gop.found_existing); // TODO incremental updates1404 assert(!gop.found_existing); // TODO incremental updates
14051405
1406 try self.allocateAtom(atom_ptr, elf_file);1406 try self.allocateAtom(atom_ptr, true, elf_file);
1407 sym.value = 0;1407 sym.value = 0;
1408 esym.st_value = 0;1408 esym.st_value = 0;
14091409
...@@ -1729,7 +1729,7 @@ fn updateLazySymbol(...@@ -1729,7 +1729,7 @@ fn updateLazySymbol(
1729 atom_ptr.size = code.len;1729 atom_ptr.size = code.len;
1730 atom_ptr.output_section_index = output_section_index;1730 atom_ptr.output_section_index = output_section_index;
17311731
1732 try self.allocateAtom(atom_ptr, elf_file);1732 try self.allocateAtom(atom_ptr, true, elf_file);
1733 errdefer self.freeNavMetadata(elf_file, symbol_index);1733 errdefer self.freeNavMetadata(elf_file, symbol_index);
17341734
1735 local_sym.value = 0;1735 local_sym.value = 0;
...@@ -1784,7 +1784,7 @@ fn lowerConst(...@@ -1784,7 +1784,7 @@ fn lowerConst(
1784 atom_ptr.size = code.len;1784 atom_ptr.size = code.len;
1785 atom_ptr.output_section_index = output_section_index;1785 atom_ptr.output_section_index = output_section_index;
17861786
1787 try self.allocateAtom(atom_ptr, elf_file);1787 try self.allocateAtom(atom_ptr, true, elf_file);
1788 errdefer self.freeNavMetadata(elf_file, sym_index);1788 errdefer self.freeNavMetadata(elf_file, sym_index);
17891789
1790 try elf_file.base.file.?.pwriteAll(code, atom_ptr.offset(elf_file));1790 try elf_file.base.file.?.pwriteAll(code, atom_ptr.offset(elf_file));
...@@ -1981,17 +1981,27 @@ fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void {...@@ -1981,17 +1981,27 @@ fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void {
1981 }1981 }
1982}1982}
19831983
1984fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {1984pub fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, requires_padding: bool, elf_file: *Elf) !void {
1985 const slice = elf_file.sections.slice();
1986 const shdr = &slice.items(.shdr)[atom_ptr.output_section_index];
1987 const last_atom_ref = &slice.items(.last_atom)[atom_ptr.output_section_index];
1988
1989 // FIXME:JK this only works if this atom is the only atom in the output section
1990 // In every other case, we need to redo the prev/next links
1991 if (last_atom_ref.eql(atom_ptr.ref())) last_atom_ref.* = .{};
1992
1985 const alloc_res = try elf_file.allocateChunk(.{1993 const alloc_res = try elf_file.allocateChunk(.{
1986 .shndx = atom_ptr.output_section_index,1994 .shndx = atom_ptr.output_section_index,
1987 .size = atom_ptr.size,1995 .size = atom_ptr.size,
1988 .alignment = atom_ptr.alignment,1996 .alignment = atom_ptr.alignment,
1997 .requires_padding = requires_padding,
1989 });1998 });
1990 atom_ptr.value = @intCast(alloc_res.value);1999 atom_ptr.value = @intCast(alloc_res.value);
19912000 log.debug("allocated {s} at {x}\n placement {?}", .{
1992 const slice = elf_file.sections.slice();2001 atom_ptr.name(elf_file),
1993 const shdr = &slice.items(.shdr)[atom_ptr.output_section_index];2002 atom_ptr.offset(elf_file),
1994 const last_atom_ref = &slice.items(.last_atom)[atom_ptr.output_section_index];2003 alloc_res.placement,
2004 });
19952005
1996 const expand_section = if (elf_file.atom(alloc_res.placement)) |placement_atom|2006 const expand_section = if (elf_file.atom(alloc_res.placement)) |placement_atom|
1997 placement_atom.nextAtom(elf_file) == null2007 placement_atom.nextAtom(elf_file) == null
...@@ -2013,12 +2023,6 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {...@@ -2013,12 +2023,6 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {
2013 }2023 }
2014 shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits().?);2024 shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits().?);
20152025
2016 if (self.sectionSymbol(atom_ptr.output_section_index, elf_file)) |sym| {
2017 assert(sym.atom(elf_file) == null and sym.mergeSubsection(elf_file) == null);
2018 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
2019 esym.st_size += atom_ptr.size + Elf.padToIdeal(atom_ptr.size);
2020 }
2021
2022 // This function can also reallocate an atom.2026 // This function can also reallocate an atom.
2023 // In this case we need to "unplug" it from its previous location before2027 // In this case we need to "unplug" it from its previous location before
2024 // plugging it in to its new location.2028 // plugging it in to its new location.
...@@ -2037,12 +2041,8 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {...@@ -2037,12 +2041,8 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {
2037 atom_ptr.prev_atom_ref = .{ .index = 0, .file = 0 };2041 atom_ptr.prev_atom_ref = .{ .index = 0, .file = 0 };
2038 atom_ptr.next_atom_ref = .{ .index = 0, .file = 0 };2042 atom_ptr.next_atom_ref = .{ .index = 0, .file = 0 };
2039 }2043 }
2040}
20412044
2042fn growAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {2045 log.debug(" prev {?}, next {?}", .{ atom_ptr.prev_atom_ref, atom_ptr.next_atom_ref });
2043 if (!atom_ptr.alignment.check(@intCast(atom_ptr.value)) or atom_ptr.size > atom_ptr.capacity(elf_file)) {
2044 try self.allocateAtom(atom_ptr, elf_file);
2045 }
2046}2046}
20472047
2048pub fn resetShdrIndexes(self: *ZigObject, backlinks: anytype) void {2048pub fn resetShdrIndexes(self: *ZigObject, backlinks: anytype) void {
src/link/Elf/relocatable.zig+8-18
...@@ -394,24 +394,14 @@ fn allocateAllocSections(elf_file: *Elf) !void {...@@ -394,24 +394,14 @@ fn allocateAllocSections(elf_file: *Elf) !void {
394 shdr.sh_size = 0;394 shdr.sh_size = 0;
395 const new_offset = try elf_file.findFreeSpace(needed_size, shdr.sh_addralign);395 const new_offset = try elf_file.findFreeSpace(needed_size, shdr.sh_addralign);
396396
397 if (elf_file.zigObjectPtr()) |zo| blk: {397 log.debug("moving {s} from 0x{x} to 0x{x}", .{
398 const existing_size = for ([_]?Symbol.Index{398 elf_file.getShString(shdr.sh_name),
399 zo.text_index,399 shdr.sh_offset,
400 zo.rodata_index,400 new_offset,
401 zo.data_relro_index,401 });
402 zo.data_index,402
403 zo.tdata_index,403 if (shdr.sh_offset > 0) {
404 zo.eh_frame_index,404 const existing_size = elf_file.sectionSize(@intCast(shndx));
405 }) |maybe_sym_index| {
406 const sect_sym_index = maybe_sym_index orelse continue;
407 const sect_atom_ptr = zo.symbol(sect_sym_index).atom(elf_file).?;
408 if (sect_atom_ptr.output_section_index == shndx) break sect_atom_ptr.size;
409 } else break :blk;
410 log.debug("moving {s} from 0x{x} to 0x{x}", .{
411 elf_file.getShString(shdr.sh_name),
412 shdr.sh_offset,
413 new_offset,
414 });
415 const amt = try elf_file.base.file.?.copyRangeAll(405 const amt = try elf_file.base.file.?.copyRangeAll(
416 shdr.sh_offset,406 shdr.sh_offset,
417 elf_file.base.file.?,407 elf_file.base.file.?,