| author | |
| committer | |
| log | 44a6172edbf6c99f4ebfeabb530756ed2a40c3c2 |
| tree | fb158886b71bc3e1a19d09aea13b4e3d19b164ea |
| parent | 9f1f60fd4311b37493a5297ccaac167d0270f521 |
| parent | fa620ef710bbbf7f642fd1d6d24a188d02902988 |
| signature |
link.MachO: use accurate alignment attribute on pointers4 files changed, 79 insertions(+), 16 deletions(-)
lib/std/array_list.zig+63| ... | @@ -221,6 +221,30 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { | ... | @@ -221,6 +221,30 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 221 | mem.copy(T, self.items[old_len..], items); | 221 | mem.copy(T, self.items[old_len..], items); |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | /// Append an unaligned slice of items to the list. Allocates more | ||
| 225 | /// memory as necessary. Only call this function if calling | ||
| 226 | /// `appendSlice` instead would be a compile error. | ||
| 227 | pub fn appendUnalignedSlice(self: *Self, items: []align(1) const T) Allocator.Error!void { | ||
| 228 | try self.ensureUnusedCapacity(items.len); | ||
| 229 | self.appendUnalignedSliceAssumeCapacity(items); | ||
| 230 | } | ||
| 231 | |||
| 232 | /// Append the slice of items to the list, asserting the capacity is already | ||
| 233 | /// enough to store the new items. **Does not** invalidate pointers. | ||
| 234 | /// Only call this function if calling `appendSliceAssumeCapacity` instead | ||
| 235 | /// would be a compile error. | ||
| 236 | pub fn appendUnalignedSliceAssumeCapacity(self: *Self, items: []align(1) const T) void { | ||
| 237 | const old_len = self.items.len; | ||
| 238 | const new_len = old_len + items.len; | ||
| 239 | assert(new_len <= self.capacity); | ||
| 240 | self.items.len = new_len; | ||
| 241 | @memcpy( | ||
| 242 | @ptrCast([*]align(@alignOf(T)) u8, self.items.ptr + old_len), | ||
| 243 | @ptrCast([*]const u8, items.ptr), | ||
| 244 | items.len * @sizeOf(T), | ||
| 245 | ); | ||
| 246 | } | ||
| 247 | |||
| 224 | pub const Writer = if (T != u8) | 248 | pub const Writer = if (T != u8) |
| 225 | @compileError("The Writer interface is only defined for ArrayList(u8) " ++ | 249 | @compileError("The Writer interface is only defined for ArrayList(u8) " ++ |
| 226 | "but the given type is ArrayList(" ++ @typeName(T) ++ ")") | 250 | "but the given type is ArrayList(" ++ @typeName(T) ++ ")") |
| ... | @@ -592,6 +616,29 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ | ... | @@ -592,6 +616,29 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 592 | mem.copy(T, self.items[old_len..], items); | 616 | mem.copy(T, self.items[old_len..], items); |
| 593 | } | 617 | } |
| 594 | 618 | ||
| 619 | /// Append the slice of items to the list. Allocates more | ||
| 620 | /// memory as necessary. Only call this function if a call to `appendSlice` instead would | ||
| 621 | /// be a compile error. | ||
| 622 | pub fn appendUnalignedSlice(self: *Self, allocator: Allocator, items: []align(1) const T) Allocator.Error!void { | ||
| 623 | try self.ensureUnusedCapacity(allocator, items.len); | ||
| 624 | self.appendUnalignedSliceAssumeCapacity(items); | ||
| 625 | } | ||
| 626 | |||
| 627 | /// Append an unaligned slice of items to the list, asserting the capacity is enough | ||
| 628 | /// to store the new items. Only call this function if a call to `appendSliceAssumeCapacity` | ||
| 629 | /// instead would be a compile error. | ||
| 630 | pub fn appendUnalignedSliceAssumeCapacity(self: *Self, items: []align(1) const T) void { | ||
| 631 | const old_len = self.items.len; | ||
| 632 | const new_len = old_len + items.len; | ||
| 633 | assert(new_len <= self.capacity); | ||
| 634 | self.items.len = new_len; | ||
| 635 | @memcpy( | ||
| 636 | @ptrCast([*]align(@alignOf(T)) u8, self.items.ptr + old_len), | ||
| 637 | @ptrCast([*]const u8, items.ptr), | ||
| 638 | items.len * @sizeOf(T), | ||
| 639 | ); | ||
| 640 | } | ||
| 641 | |||
| 595 | pub const WriterContext = struct { | 642 | pub const WriterContext = struct { |
| 596 | self: *Self, | 643 | self: *Self, |
| 597 | allocator: Allocator, | 644 | allocator: Allocator, |
| ... | @@ -899,6 +946,14 @@ test "std.ArrayList/ArrayListUnmanaged.basic" { | ... | @@ -899,6 +946,14 @@ test "std.ArrayList/ArrayListUnmanaged.basic" { |
| 899 | try testing.expect(list.pop() == 1); | 946 | try testing.expect(list.pop() == 1); |
| 900 | try testing.expect(list.items.len == 9); | 947 | try testing.expect(list.items.len == 9); |
| 901 | 948 | ||
| 949 | var unaligned: [3]i32 align(1) = [_]i32{ 4, 5, 6 }; | ||
| 950 | list.appendUnalignedSlice(&unaligned) catch unreachable; | ||
| 951 | try testing.expect(list.items.len == 12); | ||
| 952 | try testing.expect(list.pop() == 6); | ||
| 953 | try testing.expect(list.pop() == 5); | ||
| 954 | try testing.expect(list.pop() == 4); | ||
| 955 | try testing.expect(list.items.len == 9); | ||
| 956 | |||
| 902 | list.appendSlice(&[_]i32{}) catch unreachable; | 957 | list.appendSlice(&[_]i32{}) catch unreachable; |
| 903 | try testing.expect(list.items.len == 9); | 958 | try testing.expect(list.items.len == 9); |
| 904 | 959 | ||
| ... | @@ -941,6 +996,14 @@ test "std.ArrayList/ArrayListUnmanaged.basic" { | ... | @@ -941,6 +996,14 @@ test "std.ArrayList/ArrayListUnmanaged.basic" { |
| 941 | try testing.expect(list.pop() == 1); | 996 | try testing.expect(list.pop() == 1); |
| 942 | try testing.expect(list.items.len == 9); | 997 | try testing.expect(list.items.len == 9); |
| 943 | 998 | ||
| 999 | var unaligned: [3]i32 align(1) = [_]i32{ 4, 5, 6 }; | ||
| 1000 | list.appendUnalignedSlice(a, &unaligned) catch unreachable; | ||
| 1001 | try testing.expect(list.items.len == 12); | ||
| 1002 | try testing.expect(list.pop() == 6); | ||
| 1003 | try testing.expect(list.pop() == 5); | ||
| 1004 | try testing.expect(list.pop() == 4); | ||
| 1005 | try testing.expect(list.items.len == 9); | ||
| 1006 | |||
| 944 | list.appendSlice(a, &[_]i32{}) catch unreachable; | 1007 | list.appendSlice(a, &[_]i32{}) catch unreachable; |
| 945 | try testing.expect(list.items.len == 9); | 1008 | try testing.expect(list.items.len == 9); |
| 946 | 1009 |
src/link/MachO.zig+3-3| ... | @@ -5315,10 +5315,10 @@ fn writeFunctionStarts(self: *MachO, ncmds: *u32, lc_writer: anytype) !void { | ... | @@ -5315,10 +5315,10 @@ fn writeFunctionStarts(self: *MachO, ncmds: *u32, lc_writer: anytype) !void { |
| 5315 | } | 5315 | } |
| 5316 | 5316 | ||
| 5317 | fn filterDataInCode( | 5317 | fn filterDataInCode( |
| 5318 | dices: []const macho.data_in_code_entry, | 5318 | dices: []align(1) const macho.data_in_code_entry, |
| 5319 | start_addr: u64, | 5319 | start_addr: u64, |
| 5320 | end_addr: u64, | 5320 | end_addr: u64, |
| 5321 | ) []const macho.data_in_code_entry { | 5321 | ) []align(1) const macho.data_in_code_entry { |
| 5322 | const Predicate = struct { | 5322 | const Predicate = struct { |
| 5323 | addr: u64, | 5323 | addr: u64, |
| 5324 | 5324 | ||
| ... | @@ -5825,7 +5825,7 @@ pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc { | ... | @@ -5825,7 +5825,7 @@ pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc { |
| 5825 | return global; | 5825 | return global; |
| 5826 | } | 5826 | } |
| 5827 | 5827 | ||
| 5828 | pub fn findFirst(comptime T: type, haystack: []const T, start: usize, predicate: anytype) usize { | 5828 | pub fn findFirst(comptime T: type, haystack: []align(1) const T, start: usize, predicate: anytype) usize { |
| 5829 | if (!@hasDecl(@TypeOf(predicate), "predicate")) | 5829 | if (!@hasDecl(@TypeOf(predicate), "predicate")) |
| 5830 | @compileError("Predicate is required to define fn predicate(@This(), T) bool"); | 5830 | @compileError("Predicate is required to define fn predicate(@This(), T) bool"); |
| 5831 | 5831 |
src/link/MachO/Atom.zig+1-1| ... | @@ -218,7 +218,7 @@ const RelocContext = struct { | ... | @@ -218,7 +218,7 @@ const RelocContext = struct { |
| 218 | base_offset: i32 = 0, | 218 | base_offset: i32 = 0, |
| 219 | }; | 219 | }; |
| 220 | 220 | ||
| 221 | pub fn parseRelocs(self: *Atom, relocs: []const macho.relocation_info, context: RelocContext) !void { | 221 | pub fn parseRelocs(self: *Atom, relocs: []align(1) const macho.relocation_info, context: RelocContext) !void { |
| 222 | const tracy = trace(@src()); | 222 | const tracy = trace(@src()); |
| 223 | defer tracy.end(); | 223 | defer tracy.end(); |
| 224 | 224 |
src/link/MachO/Object.zig+12-12| ... | @@ -24,7 +24,7 @@ mtime: u64, | ... | @@ -24,7 +24,7 @@ mtime: u64, |
| 24 | contents: []align(@alignOf(u64)) const u8, | 24 | contents: []align(@alignOf(u64)) const u8, |
| 25 | 25 | ||
| 26 | header: macho.mach_header_64 = undefined, | 26 | header: macho.mach_header_64 = undefined, |
| 27 | in_symtab: []const macho.nlist_64 = undefined, | 27 | in_symtab: []align(1) const macho.nlist_64 = undefined, |
| 28 | in_strtab: []const u8 = undefined, | 28 | in_strtab: []const u8 = undefined, |
| 29 | 29 | ||
| 30 | symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 30 | symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| ... | @@ -100,12 +100,12 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) | ... | @@ -100,12 +100,12 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) |
| 100 | .SYMTAB => { | 100 | .SYMTAB => { |
| 101 | const symtab = cmd.cast(macho.symtab_command).?; | 101 | const symtab = cmd.cast(macho.symtab_command).?; |
| 102 | // Sadly, SYMTAB may be at an unaligned offset within the object file. | 102 | // Sadly, SYMTAB may be at an unaligned offset within the object file. |
| 103 | self.in_symtab = @alignCast(@alignOf(macho.nlist_64), @ptrCast( | 103 | self.in_symtab = @ptrCast( |
| 104 | [*]align(1) const macho.nlist_64, | 104 | [*]align(1) const macho.nlist_64, |
| 105 | self.contents.ptr + symtab.symoff, | 105 | self.contents.ptr + symtab.symoff, |
| 106 | ))[0..symtab.nsyms]; | 106 | )[0..symtab.nsyms]; |
| 107 | self.in_strtab = self.contents[symtab.stroff..][0..symtab.strsize]; | 107 | self.in_strtab = self.contents[symtab.stroff..][0..symtab.strsize]; |
| 108 | try self.symtab.appendSlice(allocator, self.in_symtab); | 108 | try self.symtab.appendUnalignedSlice(allocator, self.in_symtab); |
| 109 | }, | 109 | }, |
| 110 | else => {}, | 110 | else => {}, |
| 111 | } | 111 | } |
| ... | @@ -197,10 +197,10 @@ fn filterSymbolsByAddress( | ... | @@ -197,10 +197,10 @@ fn filterSymbolsByAddress( |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | fn filterRelocs( | 199 | fn filterRelocs( |
| 200 | relocs: []const macho.relocation_info, | 200 | relocs: []align(1) const macho.relocation_info, |
| 201 | start_addr: u64, | 201 | start_addr: u64, |
| 202 | end_addr: u64, | 202 | end_addr: u64, |
| 203 | ) []const macho.relocation_info { | 203 | ) []align(1) const macho.relocation_info { |
| 204 | const Predicate = struct { | 204 | const Predicate = struct { |
| 205 | addr: u64, | 205 | addr: u64, |
| 206 | 206 | ||
| ... | @@ -303,10 +303,10 @@ pub fn splitIntoAtomsOneShot(self: *Object, macho_file: *MachO, object_id: u32) | ... | @@ -303,10 +303,10 @@ pub fn splitIntoAtomsOneShot(self: *Object, macho_file: *MachO, object_id: u32) |
| 303 | const code: ?[]const u8 = if (!sect.isZerofill()) try self.getSectionContents(sect) else null; | 303 | const code: ?[]const u8 = if (!sect.isZerofill()) try self.getSectionContents(sect) else null; |
| 304 | 304 | ||
| 305 | // Read section's list of relocations | 305 | // Read section's list of relocations |
| 306 | const relocs = @alignCast(@alignOf(macho.relocation_info), @ptrCast( | 306 | const relocs = @ptrCast( |
| 307 | [*]align(1) const macho.relocation_info, | 307 | [*]align(1) const macho.relocation_info, |
| 308 | self.contents.ptr + sect.reloff, | 308 | self.contents.ptr + sect.reloff, |
| 309 | ))[0..sect.nreloc]; | 309 | )[0..sect.nreloc]; |
| 310 | 310 | ||
| 311 | // Symbols within this section only. | 311 | // Symbols within this section only. |
| 312 | const filtered_syms = filterSymbolsByAddress( | 312 | const filtered_syms = filterSymbolsByAddress( |
| ... | @@ -473,7 +473,7 @@ fn createAtomFromSubsection( | ... | @@ -473,7 +473,7 @@ fn createAtomFromSubsection( |
| 473 | size: u64, | 473 | size: u64, |
| 474 | alignment: u32, | 474 | alignment: u32, |
| 475 | code: ?[]const u8, | 475 | code: ?[]const u8, |
| 476 | relocs: []const macho.relocation_info, | 476 | relocs: []align(1) const macho.relocation_info, |
| 477 | indexes: []const SymbolAtIndex, | 477 | indexes: []const SymbolAtIndex, |
| 478 | match: u8, | 478 | match: u8, |
| 479 | sect: macho.section_64, | 479 | sect: macho.section_64, |
| ... | @@ -539,7 +539,7 @@ pub fn getSourceSection(self: Object, index: u16) macho.section_64 { | ... | @@ -539,7 +539,7 @@ pub fn getSourceSection(self: Object, index: u16) macho.section_64 { |
| 539 | return self.sections.items[index]; | 539 | return self.sections.items[index]; |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | pub fn parseDataInCode(self: Object) ?[]const macho.data_in_code_entry { | 542 | pub fn parseDataInCode(self: Object) ?[]align(1) const macho.data_in_code_entry { |
| 543 | var it = LoadCommandIterator{ | 543 | var it = LoadCommandIterator{ |
| 544 | .ncmds = self.header.ncmds, | 544 | .ncmds = self.header.ncmds, |
| 545 | .buffer = self.contents[@sizeOf(macho.mach_header_64)..][0..self.header.sizeofcmds], | 545 | .buffer = self.contents[@sizeOf(macho.mach_header_64)..][0..self.header.sizeofcmds], |
| ... | @@ -549,10 +549,10 @@ pub fn parseDataInCode(self: Object) ?[]const macho.data_in_code_entry { | ... | @@ -549,10 +549,10 @@ pub fn parseDataInCode(self: Object) ?[]const macho.data_in_code_entry { |
| 549 | .DATA_IN_CODE => { | 549 | .DATA_IN_CODE => { |
| 550 | const dice = cmd.cast(macho.linkedit_data_command).?; | 550 | const dice = cmd.cast(macho.linkedit_data_command).?; |
| 551 | const ndice = @divExact(dice.datasize, @sizeOf(macho.data_in_code_entry)); | 551 | const ndice = @divExact(dice.datasize, @sizeOf(macho.data_in_code_entry)); |
| 552 | return @alignCast(@alignOf(macho.data_in_code_entry), @ptrCast( | 552 | return @ptrCast( |
| 553 | [*]align(1) const macho.data_in_code_entry, | 553 | [*]align(1) const macho.data_in_code_entry, |
| 554 | self.contents.ptr + dice.dataoff, | 554 | self.contents.ptr + dice.dataoff, |
| 555 | ))[0..ndice]; | 555 | )[0..ndice]; |
| 556 | }, | 556 | }, |
| 557 | else => {}, | 557 | else => {}, |
| 558 | } | 558 | } |