authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-10 22:39:31+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-15 18:49:47+02:00
log95aeb09b9b36874645eae648324e21cb2f89337a
tree786f636601c44f89edfc7b92bd739e8b7f33d73e
parent714e0c47612e375ac7148bc177ac7bc543c80243

zld: populate sections from the top rather than from bottom


2 files changed, 32 insertions(+), 19 deletions(-)

src/link/MachO/Object.zig+1
...@@ -502,6 +502,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {...@@ -502,6 +502,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
502502
503 // Is there any padding between symbols within the section?503 // Is there any padding between symbols within the section?
504 const is_splittable = self.header.?.flags & macho.MH_SUBSECTIONS_VIA_SYMBOLS != 0;504 const is_splittable = self.header.?.flags & macho.MH_SUBSECTIONS_VIA_SYMBOLS != 0;
505 // const is_splittable = false;
505506
506 next: {507 next: {
507 if (is_splittable) blocks: {508 if (is_splittable) blocks: {
src/link/MachO/Zld.zig+31-19
...@@ -1046,22 +1046,28 @@ fn allocateTextBlocks(self: *Zld) !void {...@@ -1046,22 +1046,28 @@ fn allocateTextBlocks(self: *Zld) !void {
1046 const match = entry.key_ptr.*;1046 const match = entry.key_ptr.*;
1047 var block: *TextBlock = entry.value_ptr.*;1047 var block: *TextBlock = entry.value_ptr.*;
10481048
1049 // Find the first block
1050 while (block.prev) |prev| {
1051 block = prev;
1052 }
1053
1049 const seg = self.load_commands.items[match.seg].Segment;1054 const seg = self.load_commands.items[match.seg].Segment;
1050 const sect = seg.sections.items[match.sect];1055 const sect = seg.sections.items[match.sect];
1051 var base_addr: u64 = sect.addr + sect.size;
10521056
1053 log.debug(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) });1057 var base_addr: u64 = sect.addr;
1054 log.debug(" {}", .{sect});1058
1059 log.warn(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) });
1060 log.warn(" {}", .{sect});
10551061
1056 while (true) {1062 while (true) {
1057 const block_alignment = try math.powi(u32, 2, block.alignment);1063 const block_alignment = try math.powi(u32, 2, block.alignment);
1058 base_addr = mem.alignBackwardGeneric(u64, base_addr - block.size, block_alignment);1064 base_addr = mem.alignForwardGeneric(u64, base_addr, block_alignment);
10591065
1060 const sym = self.locals.items[block.local_sym_index];1066 const sym = self.locals.items[block.local_sym_index];
1061 assert(sym.payload == .regular);1067 assert(sym.payload == .regular);
1062 sym.payload.regular.address = base_addr;1068 sym.payload.regular.address = base_addr;
10631069
1064 log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{1070 log.warn(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
1065 sym.name,1071 sym.name,
1066 base_addr,1072 base_addr,
1067 base_addr + block.size,1073 base_addr + block.size,
...@@ -1087,8 +1093,10 @@ fn allocateTextBlocks(self: *Zld) !void {...@@ -1087,8 +1093,10 @@ fn allocateTextBlocks(self: *Zld) !void {
1087 }1093 }
1088 }1094 }
10891095
1090 if (block.prev) |prev| {1096 base_addr += block.size;
1091 block = prev;1097
1098 if (block.next) |next| {
1099 block = next;
1092 } else break;1100 } else break;
1093 }1101 }
1094 }1102 }
...@@ -1102,12 +1110,16 @@ fn writeTextBlocks(self: *Zld) !void {...@@ -1102,12 +1110,16 @@ fn writeTextBlocks(self: *Zld) !void {
1102 const match = entry.key_ptr.*;1110 const match = entry.key_ptr.*;
1103 var block: *TextBlock = entry.value_ptr.*;1111 var block: *TextBlock = entry.value_ptr.*;
11041112
1113 while (block.prev) |prev| {
1114 block = prev;
1115 }
1116
1105 const seg = self.load_commands.items[match.seg].Segment;1117 const seg = self.load_commands.items[match.seg].Segment;
1106 const sect = seg.sections.items[match.sect];1118 const sect = seg.sections.items[match.sect];
1107 const sect_type = sectionType(sect);1119 const sect_type = sectionType(sect);
11081120
1109 log.debug(" for section {s},{s}", .{ segmentName(sect), sectionName(sect) });1121 log.warn(" for section {s},{s}", .{ segmentName(sect), sectionName(sect) });
1110 log.debug(" {}", .{sect});1122 log.warn(" {}", .{sect});
11111123
1112 var code = try self.allocator.alloc(u8, sect.size);1124 var code = try self.allocator.alloc(u8, sect.size);
1113 defer self.allocator.free(code);1125 defer self.allocator.free(code);
...@@ -1115,15 +1127,14 @@ fn writeTextBlocks(self: *Zld) !void {...@@ -1115,15 +1127,14 @@ fn writeTextBlocks(self: *Zld) !void {
1115 if (sect_type == macho.S_ZEROFILL or sect_type == macho.S_THREAD_LOCAL_ZEROFILL) {1127 if (sect_type == macho.S_ZEROFILL or sect_type == macho.S_THREAD_LOCAL_ZEROFILL) {
1116 mem.set(u8, code, 0);1128 mem.set(u8, code, 0);
1117 } else {1129 } else {
1118 var base_off: u64 = sect.size;1130 var base_off: u64 = 0;
11191131
1120 while (true) {1132 while (true) {
1121 const block_alignment = try math.powi(u32, 2, block.alignment);1133 const block_alignment = try math.powi(u32, 2, block.alignment);
1122 const unaligned_base_off = base_off - block.size;1134 const aligned_base_off = mem.alignForwardGeneric(u64, base_off, block_alignment);
1123 const aligned_base_off = mem.alignBackwardGeneric(u64, unaligned_base_off, block_alignment);
11241135
1125 const sym = self.locals.items[block.local_sym_index];1136 const sym = self.locals.items[block.local_sym_index];
1126 log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{1137 log.warn(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
1127 sym.name,1138 sym.name,
1128 aligned_base_off,1139 aligned_base_off,
1129 aligned_base_off + block.size,1140 aligned_base_off + block.size,
...@@ -1135,16 +1146,17 @@ fn writeTextBlocks(self: *Zld) !void {...@@ -1135,16 +1146,17 @@ fn writeTextBlocks(self: *Zld) !void {
1135 mem.copy(u8, code[aligned_base_off..][0..block.size], block.code);1146 mem.copy(u8, code[aligned_base_off..][0..block.size], block.code);
11361147
1137 // TODO NOP for machine code instead of just zeroing out1148 // TODO NOP for machine code instead of just zeroing out
1138 const padding_off = aligned_base_off + block.size;1149 const padding_len = aligned_base_off - base_off;
1139 const padding_len = unaligned_base_off - aligned_base_off;1150 mem.set(u8, code[base_off..][0..padding_len], 0);
1140 mem.set(u8, code[padding_off..][0..padding_len], 0);
11411151
1142 base_off = aligned_base_off;1152 base_off = aligned_base_off + block.size;
11431153
1144 if (block.prev) |prev| {1154 if (block.next) |next| {
1145 block = prev;1155 block = next;
1146 } else break;1156 } else break;
1147 }1157 }
1158
1159 mem.set(u8, code[base_off..], 0);
1148 }1160 }
11491161
1150 try self.file.?.pwriteAll(code, sect.offset);1162 try self.file.?.pwriteAll(code, sect.offset);