mirror of
https://github.com/ziglang/zig.git
synced 2024-12-04 19:09:32 +00:00
link.MachO: use accurate alignment attribute on pointers
Also adds a new method to ArrayList: appendUnalignedSlice
This commit is contained in:
parent
cc56400e62
commit
fa620ef710
@ -221,6 +221,30 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
|
||||
mem.copy(T, self.items[old_len..], items);
|
||||
}
|
||||
|
||||
/// Append an unaligned slice of items to the list. Allocates more
|
||||
/// memory as necessary. Only call this function if calling
|
||||
/// `appendSlice` instead would be a compile error.
|
||||
pub fn appendUnalignedSlice(self: *Self, items: []align(1) const T) Allocator.Error!void {
|
||||
try self.ensureUnusedCapacity(items.len);
|
||||
self.appendUnalignedSliceAssumeCapacity(items);
|
||||
}
|
||||
|
||||
/// Append the slice of items to the list, asserting the capacity is already
|
||||
/// enough to store the new items. **Does not** invalidate pointers.
|
||||
/// Only call this function if calling `appendSliceAssumeCapacity` instead
|
||||
/// would be a compile error.
|
||||
pub fn appendUnalignedSliceAssumeCapacity(self: *Self, items: []align(1) const T) void {
|
||||
const old_len = self.items.len;
|
||||
const new_len = old_len + items.len;
|
||||
assert(new_len <= self.capacity);
|
||||
self.items.len = new_len;
|
||||
@memcpy(
|
||||
@ptrCast([*]align(@alignOf(T)) u8, self.items.ptr + old_len),
|
||||
@ptrCast([*]const u8, items.ptr),
|
||||
items.len * @sizeOf(T),
|
||||
);
|
||||
}
|
||||
|
||||
pub const Writer = if (T != u8)
|
||||
@compileError("The Writer interface is only defined for ArrayList(u8) " ++
|
||||
"but the given type is ArrayList(" ++ @typeName(T) ++ ")")
|
||||
@ -592,6 +616,29 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
|
||||
mem.copy(T, self.items[old_len..], items);
|
||||
}
|
||||
|
||||
/// Append the slice of items to the list. Allocates more
|
||||
/// memory as necessary. Only call this function if a call to `appendSlice` instead would
|
||||
/// be a compile error.
|
||||
pub fn appendUnalignedSlice(self: *Self, allocator: Allocator, items: []align(1) const T) Allocator.Error!void {
|
||||
try self.ensureUnusedCapacity(allocator, items.len);
|
||||
self.appendUnalignedSliceAssumeCapacity(items);
|
||||
}
|
||||
|
||||
/// Append an unaligned slice of items to the list, asserting the capacity is enough
|
||||
/// to store the new items. Only call this function if a call to `appendSliceAssumeCapacity`
|
||||
/// instead would be a compile error.
|
||||
pub fn appendUnalignedSliceAssumeCapacity(self: *Self, items: []align(1) const T) void {
|
||||
const old_len = self.items.len;
|
||||
const new_len = old_len + items.len;
|
||||
assert(new_len <= self.capacity);
|
||||
self.items.len = new_len;
|
||||
@memcpy(
|
||||
@ptrCast([*]align(@alignOf(T)) u8, self.items.ptr + old_len),
|
||||
@ptrCast([*]const u8, items.ptr),
|
||||
items.len * @sizeOf(T),
|
||||
);
|
||||
}
|
||||
|
||||
pub const WriterContext = struct {
|
||||
self: *Self,
|
||||
allocator: Allocator,
|
||||
@ -899,6 +946,14 @@ test "std.ArrayList/ArrayListUnmanaged.basic" {
|
||||
try testing.expect(list.pop() == 1);
|
||||
try testing.expect(list.items.len == 9);
|
||||
|
||||
var unaligned: [3]i32 align(1) = [_]i32{ 4, 5, 6 };
|
||||
list.appendUnalignedSlice(&unaligned) catch unreachable;
|
||||
try testing.expect(list.items.len == 12);
|
||||
try testing.expect(list.pop() == 6);
|
||||
try testing.expect(list.pop() == 5);
|
||||
try testing.expect(list.pop() == 4);
|
||||
try testing.expect(list.items.len == 9);
|
||||
|
||||
list.appendSlice(&[_]i32{}) catch unreachable;
|
||||
try testing.expect(list.items.len == 9);
|
||||
|
||||
@ -941,6 +996,14 @@ test "std.ArrayList/ArrayListUnmanaged.basic" {
|
||||
try testing.expect(list.pop() == 1);
|
||||
try testing.expect(list.items.len == 9);
|
||||
|
||||
var unaligned: [3]i32 align(1) = [_]i32{ 4, 5, 6 };
|
||||
list.appendUnalignedSlice(a, &unaligned) catch unreachable;
|
||||
try testing.expect(list.items.len == 12);
|
||||
try testing.expect(list.pop() == 6);
|
||||
try testing.expect(list.pop() == 5);
|
||||
try testing.expect(list.pop() == 4);
|
||||
try testing.expect(list.items.len == 9);
|
||||
|
||||
list.appendSlice(a, &[_]i32{}) catch unreachable;
|
||||
try testing.expect(list.items.len == 9);
|
||||
|
||||
|
@ -5315,10 +5315,10 @@ fn writeFunctionStarts(self: *MachO, ncmds: *u32, lc_writer: anytype) !void {
|
||||
}
|
||||
|
||||
fn filterDataInCode(
|
||||
dices: []const macho.data_in_code_entry,
|
||||
dices: []align(1) const macho.data_in_code_entry,
|
||||
start_addr: u64,
|
||||
end_addr: u64,
|
||||
) []const macho.data_in_code_entry {
|
||||
) []align(1) const macho.data_in_code_entry {
|
||||
const Predicate = struct {
|
||||
addr: u64,
|
||||
|
||||
@ -5825,7 +5825,7 @@ pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc {
|
||||
return global;
|
||||
}
|
||||
|
||||
pub fn findFirst(comptime T: type, haystack: []const T, start: usize, predicate: anytype) usize {
|
||||
pub fn findFirst(comptime T: type, haystack: []align(1) const T, start: usize, predicate: anytype) usize {
|
||||
if (!@hasDecl(@TypeOf(predicate), "predicate"))
|
||||
@compileError("Predicate is required to define fn predicate(@This(), T) bool");
|
||||
|
||||
|
@ -218,7 +218,7 @@ const RelocContext = struct {
|
||||
base_offset: i32 = 0,
|
||||
};
|
||||
|
||||
pub fn parseRelocs(self: *Atom, relocs: []const macho.relocation_info, context: RelocContext) !void {
|
||||
pub fn parseRelocs(self: *Atom, relocs: []align(1) const macho.relocation_info, context: RelocContext) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
|
@ -24,7 +24,7 @@ mtime: u64,
|
||||
contents: []align(@alignOf(u64)) const u8,
|
||||
|
||||
header: macho.mach_header_64 = undefined,
|
||||
in_symtab: []const macho.nlist_64 = undefined,
|
||||
in_symtab: []align(1) const macho.nlist_64 = undefined,
|
||||
in_strtab: []const u8 = undefined,
|
||||
|
||||
symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{},
|
||||
@ -99,12 +99,13 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch)
|
||||
},
|
||||
.SYMTAB => {
|
||||
const symtab = cmd.cast(macho.symtab_command).?;
|
||||
// Sadly, SYMTAB may be at an unaligned offset within the object file.
|
||||
self.in_symtab = @ptrCast(
|
||||
[*]const macho.nlist_64,
|
||||
@alignCast(@alignOf(macho.nlist_64), &self.contents[symtab.symoff]),
|
||||
[*]align(1) const macho.nlist_64,
|
||||
self.contents.ptr + symtab.symoff,
|
||||
)[0..symtab.nsyms];
|
||||
self.in_strtab = self.contents[symtab.stroff..][0..symtab.strsize];
|
||||
try self.symtab.appendSlice(allocator, self.in_symtab);
|
||||
try self.symtab.appendUnalignedSlice(allocator, self.in_symtab);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
@ -196,10 +197,10 @@ fn filterSymbolsByAddress(
|
||||
}
|
||||
|
||||
fn filterRelocs(
|
||||
relocs: []const macho.relocation_info,
|
||||
relocs: []align(1) const macho.relocation_info,
|
||||
start_addr: u64,
|
||||
end_addr: u64,
|
||||
) []const macho.relocation_info {
|
||||
) []align(1) const macho.relocation_info {
|
||||
const Predicate = struct {
|
||||
addr: u64,
|
||||
|
||||
@ -303,8 +304,8 @@ pub fn splitIntoAtomsOneShot(self: *Object, macho_file: *MachO, object_id: u32)
|
||||
|
||||
// Read section's list of relocations
|
||||
const relocs = @ptrCast(
|
||||
[*]const macho.relocation_info,
|
||||
@alignCast(@alignOf(macho.relocation_info), &self.contents[sect.reloff]),
|
||||
[*]align(1) const macho.relocation_info,
|
||||
self.contents.ptr + sect.reloff,
|
||||
)[0..sect.nreloc];
|
||||
|
||||
// Symbols within this section only.
|
||||
@ -472,7 +473,7 @@ fn createAtomFromSubsection(
|
||||
size: u64,
|
||||
alignment: u32,
|
||||
code: ?[]const u8,
|
||||
relocs: []const macho.relocation_info,
|
||||
relocs: []align(1) const macho.relocation_info,
|
||||
indexes: []const SymbolAtIndex,
|
||||
match: u8,
|
||||
sect: macho.section_64,
|
||||
@ -538,7 +539,7 @@ pub fn getSourceSection(self: Object, index: u16) macho.section_64 {
|
||||
return self.sections.items[index];
|
||||
}
|
||||
|
||||
pub fn parseDataInCode(self: Object) ?[]const macho.data_in_code_entry {
|
||||
pub fn parseDataInCode(self: Object) ?[]align(1) const macho.data_in_code_entry {
|
||||
var it = LoadCommandIterator{
|
||||
.ncmds = self.header.ncmds,
|
||||
.buffer = self.contents[@sizeOf(macho.mach_header_64)..][0..self.header.sizeofcmds],
|
||||
@ -549,8 +550,8 @@ pub fn parseDataInCode(self: Object) ?[]const macho.data_in_code_entry {
|
||||
const dice = cmd.cast(macho.linkedit_data_command).?;
|
||||
const ndice = @divExact(dice.datasize, @sizeOf(macho.data_in_code_entry));
|
||||
return @ptrCast(
|
||||
[*]const macho.data_in_code_entry,
|
||||
@alignCast(@alignOf(macho.data_in_code_entry), &self.contents[dice.dataoff]),
|
||||
[*]align(1) const macho.data_in_code_entry,
|
||||
self.contents.ptr + dice.dataoff,
|
||||
)[0..ndice];
|
||||
},
|
||||
else => {},
|
||||
|
Loading…
Reference in New Issue
Block a user