| ... | @@ -60,12 +60,16 @@ globals_lookup: []i64 = undefined, | ... | @@ -60,12 +60,16 @@ globals_lookup: []i64 = undefined, |
| 60 | /// Can be undefined as set together with in_symtab. | 60 | /// Can be undefined as set together with in_symtab. |
| 61 | relocs_lookup: []RelocEntry = undefined, | 61 | relocs_lookup: []RelocEntry = undefined, |
| 62 | | 62 | |
| 63 | /// All relocations sorted and flatened. | 63 | /// All relocations sorted and flatened, sorted by address descending |
| | 64 | /// per section. |
| 64 | relocations: std.ArrayListUnmanaged(macho.relocation_info) = .{}, | 65 | relocations: std.ArrayListUnmanaged(macho.relocation_info) = .{}, |
| 65 | /// Beginning index to the relocations array for each input section | 66 | /// Beginning index to the relocations array for each input section |
| 66 | /// defined within this Object file. | 67 | /// defined within this Object file. |
| 67 | section_relocs_lookup: std.ArrayListUnmanaged(u32) = .{}, | 68 | section_relocs_lookup: std.ArrayListUnmanaged(u32) = .{}, |
| 68 | | 69 | |
| | 70 | /// Data-in-code records sorted by address. |
| | 71 | data_in_code: std.ArrayListUnmanaged(macho.data_in_code_entry) = .{}, |
| | 72 | |
| 69 | atoms: std.ArrayListUnmanaged(AtomIndex) = .{}, | 73 | atoms: std.ArrayListUnmanaged(AtomIndex) = .{}, |
| 70 | exec_atoms: std.ArrayListUnmanaged(AtomIndex) = .{}, | 74 | exec_atoms: std.ArrayListUnmanaged(AtomIndex) = .{}, |
| 71 | | 75 | |
| ... | @@ -108,6 +112,7 @@ pub fn deinit(self: *Object, gpa: Allocator) void { | ... | @@ -108,6 +112,7 @@ pub fn deinit(self: *Object, gpa: Allocator) void { |
| 108 | self.unwind_records_lookup.deinit(gpa); | 112 | self.unwind_records_lookup.deinit(gpa); |
| 109 | self.relocations.deinit(gpa); | 113 | self.relocations.deinit(gpa); |
| 110 | self.section_relocs_lookup.deinit(gpa); | 114 | self.section_relocs_lookup.deinit(gpa); |
| | 115 | self.data_in_code.deinit(gpa); |
| 111 | } | 116 | } |
| 112 | | 117 | |
| 113 | pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) !void { | 118 | pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) !void { |
| ... | @@ -365,6 +370,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u32) !void { | ... | @@ -365,6 +370,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u32) !void { |
| 365 | try self.splitRegularSections(zld, object_id); | 370 | try self.splitRegularSections(zld, object_id); |
| 366 | try self.parseEhFrameSection(zld, object_id); | 371 | try self.parseEhFrameSection(zld, object_id); |
| 367 | try self.parseUnwindInfo(zld, object_id); | 372 | try self.parseUnwindInfo(zld, object_id); |
| | 373 | try self.parseDataInCode(zld.gpa); |
| 368 | } | 374 | } |
| 369 | | 375 | |
| 370 | /// Splits input regular sections into Atoms. | 376 | /// Splits input regular sections into Atoms. |
| ... | @@ -870,24 +876,27 @@ pub fn getSourceSections(self: Object) []const macho.section_64 { | ... | @@ -870,24 +876,27 @@ pub fn getSourceSections(self: Object) []const macho.section_64 { |
| 870 | } else unreachable; | 876 | } else unreachable; |
| 871 | } | 877 | } |
| 872 | | 878 | |
| 873 | pub fn parseDataInCode(self: Object) ?[]const macho.data_in_code_entry { | 879 | pub fn parseDataInCode(self: *Object, gpa: Allocator) !void { |
| 874 | var it = LoadCommandIterator{ | 880 | var it = LoadCommandIterator{ |
| 875 | .ncmds = self.header.ncmds, | 881 | .ncmds = self.header.ncmds, |
| 876 | .buffer = self.contents[@sizeOf(macho.mach_header_64)..][0..self.header.sizeofcmds], | 882 | .buffer = self.contents[@sizeOf(macho.mach_header_64)..][0..self.header.sizeofcmds], |
| 877 | }; | 883 | }; |
| 878 | while (it.next()) |cmd| { | 884 | const cmd = while (it.next()) |cmd| { |
| 879 | switch (cmd.cmd()) { | 885 | switch (cmd.cmd()) { |
| 880 | .DATA_IN_CODE => { | 886 | .DATA_IN_CODE => break cmd.cast(macho.linkedit_data_command).?, |
| 881 | const dice = cmd.cast(macho.linkedit_data_command).?; | | |
| 882 | const ndice = @divExact(dice.datasize, @sizeOf(macho.data_in_code_entry)); | | |
| 883 | return @ptrCast( | | |
| 884 | [*]const macho.data_in_code_entry, | | |
| 885 | @alignCast(@alignOf(macho.data_in_code_entry), &self.contents[dice.dataoff]), | | |
| 886 | )[0..ndice]; | | |
| 887 | }, | | |
| 888 | else => {}, | 887 | else => {}, |
| 889 | } | 888 | } |
| 890 | } else return null; | 889 | } else return; |
| | 890 | const ndice = @divExact(cmd.datasize, @sizeOf(macho.data_in_code_entry)); |
| | 891 | const dice = @ptrCast([*]align(1) const macho.data_in_code_entry, self.contents.ptr + cmd.dataoff)[0..ndice]; |
| | 892 | try self.data_in_code.ensureTotalCapacityPrecise(gpa, dice.len); |
| | 893 | self.data_in_code.appendUnalignedSliceAssumeCapacity(dice); |
| | 894 | std.sort.sort(macho.data_in_code_entry, self.data_in_code.items, {}, diceLessThan); |
| | 895 | } |
| | 896 | |
| | 897 | fn diceLessThan(ctx: void, lhs: macho.data_in_code_entry, rhs: macho.data_in_code_entry) bool { |
| | 898 | _ = ctx; |
| | 899 | return lhs.offset < rhs.offset; |
| 891 | } | 900 | } |
| 892 | | 901 | |
| 893 | fn parseDysymtab(self: Object) ?macho.dysymtab_command { | 902 | fn parseDysymtab(self: Object) ?macho.dysymtab_command { |
| ... | @@ -1033,3 +1042,7 @@ pub fn getEhFrameRecordsIterator(self: Object) eh_frame.Iterator { | ... | @@ -1033,3 +1042,7 @@ pub fn getEhFrameRecordsIterator(self: Object) eh_frame.Iterator { |
| 1033 | const data = self.getSectionContents(sect); | 1042 | const data = self.getSectionContents(sect); |
| 1034 | return .{ .data = data }; | 1043 | return .{ .data = data }; |
| 1035 | } | 1044 | } |
| | 1045 | |
| | 1046 | pub fn hasDataInCode(self: Object) bool { |
| | 1047 | return self.data_in_code.items.len > 0; |
| | 1048 | } |