authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-03 12:53:39+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-04-03 12:53:39+02:00
loga329450aa4107d376ebda753be8a5579dd600c69
tree5cdb727ea245f082d4e19c7b770932e4dcc04ff1
parenta31450375eaadfead340c28c32dd414160a99e65
parent72137824e5ee59798140aef1d2061adc1c8227b9
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #15160 from ziglang/link-cleanup

link: misc clean ups

4 files changed, 67 insertions(+), 79 deletions(-)

src/link/Coff.zig+6-13
......@@ -155,6 +155,7 @@ const LazySymbolTable = std.ArrayHashMapUnmanaged(
155155const LazySymbolMetadata = struct {
156156 atom: Atom.Index,
157157 section: u16,
158 alignment: u32,
158159};
159160
160161const DeclMetadata = struct {
......@@ -621,12 +622,7 @@ fn allocateAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignme
621622 try self.growSection(sect_id, needed_size);
622623 maybe_last_atom_index.* = atom_index;
623624 }
624
625 {
626 const atom_ptr = self.getAtomPtr(atom_index);
627 atom_ptr.size = new_atom_size;
628 atom_ptr.alignment = alignment;
629 }
625 self.getAtomPtr(atom_index).size = new_atom_size;
630626
631627 if (atom.prev_index) |prev_index| {
632628 const prev = self.getAtomPtr(prev_index);
......@@ -739,7 +735,6 @@ pub fn createAtom(self: *Coff) !Atom.Index {
739735 .sym_index = sym_index,
740736 .file = null,
741737 .size = 0,
742 .alignment = 0,
743738 .prev_index = null,
744739 .next_index = null,
745740 };
......@@ -751,11 +746,10 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !Atom.Index {
751746 const atom_index = try self.createAtom();
752747 const atom = self.getAtomPtr(atom_index);
753748 atom.size = @sizeOf(u64);
754 atom.alignment = @alignOf(u64);
755749
756750 const sym = atom.getSymbolPtr(self);
757751 sym.section_number = @intToEnum(coff.SectionNumber, self.got_section_index.? + 1);
758 sym.value = try self.allocateAtom(atom_index, atom.size, atom.alignment);
752 sym.value = try self.allocateAtom(atom_index, atom.size, @sizeOf(u64));
759753
760754 log.debug("allocated GOT atom at 0x{x}", .{sym.value});
761755
......@@ -1116,9 +1110,8 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
11161110
11171111 const required_alignment = tv.ty.abiAlignment(self.base.options.target);
11181112 const atom = self.getAtomPtr(atom_index);
1119 atom.alignment = required_alignment;
11201113 atom.size = @intCast(u32, code.len);
1121 atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, atom.alignment);
1114 atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, required_alignment);
11221115 errdefer self.freeAtom(atom_index);
11231116
11241117 try unnamed_consts.append(gpa, atom_index);
......@@ -1228,7 +1221,7 @@ fn updateLazySymbol(
12281221 },
12291222 };
12301223
1231 const required_alignment = atom.alignment;
1224 const required_alignment = lazy_metadata.alignment;
12321225 const code_len = @intCast(u32, code.len);
12331226 const symbol = atom.getSymbolPtr(self);
12341227 try self.setSymbolName(symbol, name);
......@@ -1271,8 +1264,8 @@ pub fn getOrCreateAtomForLazySymbol(
12711264 .code => self.text_section_index.?,
12721265 .const_data => self.rdata_section_index.?,
12731266 },
1267 .alignment = alignment,
12741268 };
1275 self.getAtomPtr(gop.value_ptr.atom).alignment = alignment;
12761269 }
12771270 return gop.value_ptr.atom;
12781271}
src/link/Coff/Atom.zig+1-4
......@@ -19,12 +19,9 @@ sym_index: u32,
1919/// null means symbol defined by Zig source.
2020file: ?u32,
2121
22/// Used size of the atom
22/// Size of the atom
2323size: u32,
2424
25/// Alignment of the atom
26alignment: u32,
27
2825/// Points to the previous and next neighbors, based on the `text_offset`.
2926/// This can be used to find, for example, the capacity of this `Atom`.
3027prev_index: ?Index,
src/link/MachO.zig+60-58
......@@ -242,6 +242,7 @@ const LazySymbolTable = std.ArrayHashMapUnmanaged(
242242const LazySymbolMetadata = struct {
243243 atom: Atom.Index,
244244 section: u8,
245 alignment: u32,
245246};
246247
247248const DeclMetadata = struct {
......@@ -1205,7 +1206,6 @@ pub fn createAtom(self: *MachO) !Atom.Index {
12051206 .sym_index = sym_index,
12061207 .file = null,
12071208 .size = 0,
1208 .alignment = 0,
12091209 .prev_index = null,
12101210 .next_index = null,
12111211 };
......@@ -1217,7 +1217,6 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index {
12171217 const atom_index = try self.createAtom();
12181218 const atom = self.getAtomPtr(atom_index);
12191219 atom.size = @sizeOf(u64);
1220 atom.alignment = @alignOf(u64);
12211220
12221221 const sym = atom.getSymbolPtr(self);
12231222 sym.n_type = macho.N_SECT;
......@@ -1259,7 +1258,6 @@ pub fn createDyldPrivateAtom(self: *MachO) !void {
12591258 const atom_index = try self.createAtom();
12601259 const atom = self.getAtomPtr(atom_index);
12611260 atom.size = @sizeOf(u64);
1262 atom.alignment = @alignOf(u64);
12631261
12641262 const sym = atom.getSymbolPtr(self);
12651263 sym.n_type = macho.N_SECT;
......@@ -1285,7 +1283,8 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void {
12851283 const atom_index = try self.createAtom();
12861284 const atom = self.getAtomPtr(atom_index);
12871285 atom.size = size;
1288 atom.alignment = switch (arch) {
1286
1287 const required_alignment: u32 = switch (arch) {
12891288 .x86_64 => 1,
12901289 .aarch64 => @alignOf(u32),
12911290 else => unreachable,
......@@ -1392,7 +1391,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void {
13921391 }
13931392 self.stub_helper_preamble_atom_index = atom_index;
13941393
1395 sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment);
1394 sym.n_value = try self.allocateAtom(atom_index, size, required_alignment);
13961395 log.debug("allocated stub preamble atom at 0x{x}", .{sym.n_value});
13971396 try self.writeAtom(atom_index, code);
13981397}
......@@ -1408,7 +1407,8 @@ pub fn createStubHelperAtom(self: *MachO) !Atom.Index {
14081407 const atom_index = try self.createAtom();
14091408 const atom = self.getAtomPtr(atom_index);
14101409 atom.size = size;
1411 atom.alignment = switch (arch) {
1410
1411 const required_alignment: u32 = switch (arch) {
14121412 .x86_64 => 1,
14131413 .aarch64 => @alignOf(u32),
14141414 else => unreachable,
......@@ -1470,7 +1470,7 @@ pub fn createStubHelperAtom(self: *MachO) !Atom.Index {
14701470 else => unreachable,
14711471 }
14721472
1473 sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment);
1473 sym.n_value = try self.allocateAtom(atom_index, size, required_alignment);
14741474 log.debug("allocated stub helper atom at 0x{x}", .{sym.n_value});
14751475 try self.writeAtom(atom_index, code);
14761476
......@@ -1481,7 +1481,6 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi
14811481 const atom_index = try self.createAtom();
14821482 const atom = self.getAtomPtr(atom_index);
14831483 atom.size = @sizeOf(u64);
1484 atom.alignment = @alignOf(u64);
14851484
14861485 const sym = atom.getSymbolPtr(self);
14871486 sym.n_type = macho.N_SECT;
......@@ -1523,7 +1522,8 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {
15231522 const atom_index = try self.createAtom();
15241523 const atom = self.getAtomPtr(atom_index);
15251524 atom.size = size;
1526 atom.alignment = switch (arch) {
1525
1526 const required_alignment: u32 = switch (arch) {
15271527 .x86_64 => 1,
15281528 .aarch64 => @alignOf(u32),
15291529 else => unreachable, // unhandled architecture type
......@@ -1587,7 +1587,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {
15871587 else => unreachable,
15881588 }
15891589
1590 sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment);
1590 sym.n_value = try self.allocateAtom(atom_index, size, required_alignment);
15911591 log.debug("allocated stub atom at 0x{x}", .{sym.n_value});
15921592 try self.writeAtom(atom_index, code);
15931593
......@@ -2217,7 +2217,6 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
22172217 const required_alignment = typed_value.ty.abiAlignment(self.base.options.target);
22182218 const atom = self.getAtomPtr(atom_index);
22192219 atom.size = code.len;
2220 atom.alignment = required_alignment;
22212220 // TODO: work out logic for disambiguating functions from function pointers
22222221 // const sect_id = self.getDeclOutputSection(decl_index);
22232222 const sect_id = self.data_const_section_index.?;
......@@ -2355,7 +2354,7 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy
23552354 },
23562355 };
23572356
2358 const required_alignment = atom.alignment;
2357 const required_alignment = lazy_metadata.alignment;
23592358 const symbol = atom.getSymbolPtr(self);
23602359 symbol.n_strx = name_str_index;
23612360 symbol.n_type = macho.N_SECT;
......@@ -2398,8 +2397,8 @@ pub fn getOrCreateAtomForLazySymbol(
23982397 .code => self.text_section_index.?,
23992398 .const_data => self.data_const_section_index.?,
24002399 },
2400 .alignment = alignment,
24012401 };
2402 self.getAtomPtr(gop.value_ptr.atom).alignment = alignment;
24032402 }
24042403 return gop.value_ptr.atom;
24052404}
......@@ -3054,7 +3053,51 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts
30543053 return section_id;
30553054}
30563055
3057fn moveSectionInVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void {
3056fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {
3057 const header = &self.sections.items(.header)[sect_id];
3058 const segment_index = self.sections.items(.segment_index)[sect_id];
3059 const segment = &self.segments.items[segment_index];
3060 const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id];
3061 const sect_capacity = self.allocatedSize(header.offset);
3062
3063 if (needed_size > sect_capacity) {
3064 const new_offset = self.findFreeSpace(needed_size, self.page_size);
3065 const current_size = if (maybe_last_atom_index) |last_atom_index| blk: {
3066 const last_atom = self.getAtom(last_atom_index);
3067 const sym = last_atom.getSymbol(self);
3068 break :blk (sym.n_value + last_atom.size) - segment.vmaddr;
3069 } else 0;
3070
3071 log.debug("moving {s},{s} from 0x{x} to 0x{x}", .{
3072 header.segName(),
3073 header.sectName(),
3074 header.offset,
3075 new_offset,
3076 });
3077
3078 const amt = try self.base.file.?.copyRangeAll(
3079 header.offset,
3080 self.base.file.?,
3081 new_offset,
3082 current_size,
3083 );
3084 if (amt != current_size) return error.InputOutput;
3085 header.offset = @intCast(u32, new_offset);
3086 segment.fileoff = new_offset;
3087 }
3088
3089 const sect_vm_capacity = self.allocatedVirtualSize(segment.vmaddr);
3090 if (needed_size > sect_vm_capacity) {
3091 self.markRelocsDirtyByAddress(segment.vmaddr + needed_size);
3092 try self.growSectionVirtualMemory(sect_id, needed_size);
3093 }
3094
3095 header.size = needed_size;
3096 segment.filesize = mem.alignForwardGeneric(u64, needed_size, self.page_size);
3097 segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size);
3098}
3099
3100fn growSectionVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void {
30583101 const header = &self.sections.items(.header)[sect_id];
30593102 const segment = self.getSegmentPtr(sect_id);
30603103 const increased_size = padToIdeal(needed_size);
......@@ -3173,45 +3216,9 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm
31733216 else
31743217 true;
31753218 if (expand_section) {
3176 const sect_capacity = self.allocatedSize(header.offset);
31773219 const needed_size = (vaddr + new_atom_size) - segment.vmaddr;
3178 if (needed_size > sect_capacity) {
3179 const new_offset = self.findFreeSpace(needed_size, self.page_size);
3180 const current_size = if (maybe_last_atom_index.*) |last_atom_index| blk: {
3181 const last_atom = self.getAtom(last_atom_index);
3182 const sym = last_atom.getSymbol(self);
3183 break :blk (sym.n_value + last_atom.size) - segment.vmaddr;
3184 } else 0;
3185
3186 log.debug("moving {s},{s} from 0x{x} to 0x{x}", .{
3187 header.segName(),
3188 header.sectName(),
3189 header.offset,
3190 new_offset,
3191 });
3192
3193 const amt = try self.base.file.?.copyRangeAll(
3194 header.offset,
3195 self.base.file.?,
3196 new_offset,
3197 current_size,
3198 );
3199 if (amt != current_size) return error.InputOutput;
3200 header.offset = @intCast(u32, new_offset);
3201 segment.fileoff = new_offset;
3202 }
3203
3204 const sect_vm_capacity = self.allocatedVirtualSize(segment.vmaddr);
3205 if (needed_size > sect_vm_capacity) {
3206 self.markRelocsDirtyByAddress(segment.vmaddr + needed_size);
3207 try self.moveSectionInVirtualMemory(sect_id, needed_size);
3208 }
3209
3210 header.size = needed_size;
3211 segment.filesize = mem.alignForwardGeneric(u64, needed_size, self.page_size);
3212 segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size);
3220 try self.growSection(sect_id, needed_size);
32133221 maybe_last_atom_index.* = atom_index;
3214
32153222 self.segment_table_dirty = true;
32163223 }
32173224
......@@ -3219,11 +3226,7 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm
32193226 if (header.@"align" < align_pow) {
32203227 header.@"align" = align_pow;
32213228 }
3222 {
3223 const atom_ptr = self.getAtomPtr(atom_index);
3224 atom_ptr.size = new_atom_size;
3225 atom_ptr.alignment = @intCast(u32, alignment);
3226 }
3229 self.getAtomPtr(atom_index).size = new_atom_size;
32273230
32283231 if (atom.prev_index) |prev_index| {
32293232 const prev = self.getAtomPtr(prev_index);
......@@ -4510,12 +4513,11 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index) void {
45104513 const atom = self.getAtom(atom_index);
45114514 const sym = atom.getSymbol(self);
45124515 const sym_name = atom.getName(self);
4513 log.debug(" ATOM(%{?d}, '{s}') @ {x} (sizeof({x}), alignof({x})) in object({?d}) in sect({d})", .{
4516 log.debug(" ATOM(%{?d}, '{s}') @ {x} sizeof({x}) in object({?d}) in sect({d})", .{
45144517 atom.getSymbolIndex(),
45154518 sym_name,
45164519 sym.n_value,
45174520 atom.size,
4518 atom.alignment,
45194521 atom.file,
45204522 sym.n_sect,
45214523 });
src/link/MachO/Atom.zig-4
......@@ -33,10 +33,6 @@ file: ?u32,
3333/// the atom since macho.nlist_64 lacks this information.
3434size: u64,
3535
36/// Alignment of this atom as a power of 2.
37/// For instance, alignment of 0 should be read as 2^0 = 1 byte aligned.
38alignment: u32,
39
4036/// Points to the previous and next neighbours
4137/// TODO use the same trick as with symbols: reserve index 0 as null atom
4238next_index: ?Index,