| ... | ... | @@ -1003,7 +1003,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1003 | 1003 | |
| 1004 | 1004 | const target_endian = self.base.options.target.cpu.arch.endian(); |
| 1005 | 1005 | const foreign_endian = target_endian != builtin.cpu.arch.endian(); |
| 1006 | | _ = foreign_endian; |
| 1007 | 1006 | |
| 1008 | 1007 | if (self.dwarf) |*dw| { |
| 1009 | 1008 | try dw.flushModule(module); |
| ... | ... | @@ -1044,212 +1043,212 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1044 | 1043 | } |
| 1045 | 1044 | } |
| 1046 | 1045 | |
| 1047 | | // try self.writeSymbols(); |
| 1046 | try self.writeSymbols(); |
| 1048 | 1047 | |
| 1049 | 1048 | if (build_options.enable_logging) { |
| 1050 | 1049 | state_log.debug("{}", .{self.dumpState()}); |
| 1051 | 1050 | } |
| 1052 | 1051 | |
| 1053 | | // if (self.dwarf) |*dw| { |
| 1054 | | // if (self.debug_abbrev_section_dirty) { |
| 1055 | | // try dw.writeDbgAbbrev(); |
| 1056 | | // if (!self.shdr_table_dirty) { |
| 1057 | | // // Then it won't get written with the others and we need to do it. |
| 1058 | | // try self.writeSectHeader(self.debug_abbrev_section_index.?); |
| 1059 | | // } |
| 1060 | | // self.debug_abbrev_section_dirty = false; |
| 1061 | | // } |
| 1062 | | |
| 1063 | | // if (self.debug_info_header_dirty) { |
| 1064 | | // // Currently only one compilation unit is supported, so the address range is simply |
| 1065 | | // // identical to the main program header virtual address and memory size. |
| 1066 | | // const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?]; |
| 1067 | | // const low_pc = text_phdr.p_vaddr; |
| 1068 | | // const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; |
| 1069 | | // try dw.writeDbgInfoHeader(module, low_pc, high_pc); |
| 1070 | | // self.debug_info_header_dirty = false; |
| 1071 | | // } |
| 1072 | | |
| 1073 | | // if (self.debug_aranges_section_dirty) { |
| 1074 | | // // Currently only one compilation unit is supported, so the address range is simply |
| 1075 | | // // identical to the main program header virtual address and memory size. |
| 1076 | | // const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?]; |
| 1077 | | // try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz); |
| 1078 | | // if (!self.shdr_table_dirty) { |
| 1079 | | // // Then it won't get written with the others and we need to do it. |
| 1080 | | // try self.writeSectHeader(self.debug_aranges_section_index.?); |
| 1081 | | // } |
| 1082 | | // self.debug_aranges_section_dirty = false; |
| 1083 | | // } |
| 1084 | | |
| 1085 | | // if (self.debug_line_header_dirty) { |
| 1086 | | // try dw.writeDbgLineHeader(); |
| 1087 | | // self.debug_line_header_dirty = false; |
| 1088 | | // } |
| 1089 | | // } |
| 1090 | | |
| 1091 | | // if (self.phdr_table_dirty) { |
| 1092 | | // const phsize: u64 = switch (self.ptr_width) { |
| 1093 | | // .p32 => @sizeOf(elf.Elf32_Phdr), |
| 1094 | | // .p64 => @sizeOf(elf.Elf64_Phdr), |
| 1095 | | // }; |
| 1096 | | |
| 1097 | | // const phdr_table_index = self.phdr_table_index.?; |
| 1098 | | // const phdr_table = &self.program_headers.items[phdr_table_index]; |
| 1099 | | // const phdr_table_load = &self.program_headers.items[self.phdr_table_load_index.?]; |
| 1100 | | |
| 1101 | | // const allocated_size = self.allocatedSize(phdr_table.p_offset); |
| 1102 | | // const needed_size = self.program_headers.items.len * phsize; |
| 1103 | | |
| 1104 | | // if (needed_size > allocated_size) { |
| 1105 | | // phdr_table.p_offset = 0; // free the space |
| 1106 | | // phdr_table.p_offset = self.findFreeSpace(needed_size, @as(u32, @intCast(phdr_table.p_align))); |
| 1107 | | // } |
| 1108 | | |
| 1109 | | // phdr_table_load.p_offset = mem.alignBackward(u64, phdr_table.p_offset, phdr_table_load.p_align); |
| 1110 | | // const load_align_offset = phdr_table.p_offset - phdr_table_load.p_offset; |
| 1111 | | // phdr_table_load.p_filesz = load_align_offset + needed_size; |
| 1112 | | // phdr_table_load.p_memsz = load_align_offset + needed_size; |
| 1113 | | |
| 1114 | | // phdr_table.p_filesz = needed_size; |
| 1115 | | // phdr_table.p_vaddr = phdr_table_load.p_vaddr + load_align_offset; |
| 1116 | | // phdr_table.p_paddr = phdr_table_load.p_paddr + load_align_offset; |
| 1117 | | // phdr_table.p_memsz = needed_size; |
| 1118 | | |
| 1119 | | // switch (self.ptr_width) { |
| 1120 | | // .p32 => { |
| 1121 | | // const buf = try gpa.alloc(elf.Elf32_Phdr, self.program_headers.items.len); |
| 1122 | | // defer gpa.free(buf); |
| 1123 | | |
| 1124 | | // for (buf, 0..) |*phdr, i| { |
| 1125 | | // phdr.* = progHeaderTo32(self.program_headers.items[i]); |
| 1126 | | // if (foreign_endian) { |
| 1127 | | // mem.byteSwapAllFields(elf.Elf32_Phdr, phdr); |
| 1128 | | // } |
| 1129 | | // } |
| 1130 | | // try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); |
| 1131 | | // }, |
| 1132 | | // .p64 => { |
| 1133 | | // const buf = try gpa.alloc(elf.Elf64_Phdr, self.program_headers.items.len); |
| 1134 | | // defer gpa.free(buf); |
| 1135 | | |
| 1136 | | // for (buf, 0..) |*phdr, i| { |
| 1137 | | // phdr.* = self.program_headers.items[i]; |
| 1138 | | // if (foreign_endian) { |
| 1139 | | // mem.byteSwapAllFields(elf.Elf64_Phdr, phdr); |
| 1140 | | // } |
| 1141 | | // } |
| 1142 | | // try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); |
| 1143 | | // }, |
| 1144 | | // } |
| 1145 | | |
| 1146 | | // // We don't actually care if the phdr load section overlaps, only the phdr section matters. |
| 1147 | | // phdr_table_load.p_offset = 0; |
| 1148 | | // phdr_table_load.p_filesz = 0; |
| 1149 | | |
| 1150 | | // self.phdr_table_dirty = false; |
| 1151 | | // } |
| 1152 | | |
| 1153 | | // { |
| 1154 | | // const shdr_index = self.shstrtab_section_index.?; |
| 1155 | | // if (self.shstrtab_dirty or self.shstrtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) { |
| 1156 | | // try self.growNonAllocSection(shdr_index, self.shstrtab.buffer.items.len, 1, false); |
| 1157 | | // const shstrtab_sect = self.sections.items(.shdr)[shdr_index]; |
| 1158 | | // try self.base.file.?.pwriteAll(self.shstrtab.buffer.items, shstrtab_sect.sh_offset); |
| 1159 | | // self.shstrtab_dirty = false; |
| 1160 | | // } |
| 1161 | | // } |
| 1162 | | |
| 1163 | | // { |
| 1164 | | // const shdr_index = self.strtab_section_index.?; |
| 1165 | | // if (self.strtab_dirty or self.strtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) { |
| 1166 | | // try self.growNonAllocSection(shdr_index, self.strtab.buffer.items.len, 1, false); |
| 1167 | | // const strtab_sect = self.sections.items(.shdr)[shdr_index]; |
| 1168 | | // try self.base.file.?.pwriteAll(self.strtab.buffer.items, strtab_sect.sh_offset); |
| 1169 | | // self.strtab_dirty = false; |
| 1170 | | // } |
| 1171 | | // } |
| 1172 | | |
| 1173 | | // if (self.dwarf) |dwarf| { |
| 1174 | | // const shdr_index = self.debug_str_section_index.?; |
| 1175 | | // if (self.debug_strtab_dirty or dwarf.strtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) { |
| 1176 | | // try self.growNonAllocSection(shdr_index, dwarf.strtab.buffer.items.len, 1, false); |
| 1177 | | // const debug_strtab_sect = self.sections.items(.shdr)[shdr_index]; |
| 1178 | | // try self.base.file.?.pwriteAll(dwarf.strtab.buffer.items, debug_strtab_sect.sh_offset); |
| 1179 | | // self.debug_strtab_dirty = false; |
| 1180 | | // } |
| 1181 | | // } |
| 1182 | | |
| 1183 | | // if (self.shdr_table_dirty) { |
| 1184 | | // const shsize: u64 = switch (self.ptr_width) { |
| 1185 | | // .p32 => @sizeOf(elf.Elf32_Shdr), |
| 1186 | | // .p64 => @sizeOf(elf.Elf64_Shdr), |
| 1187 | | // }; |
| 1188 | | // const shalign: u16 = switch (self.ptr_width) { |
| 1189 | | // .p32 => @alignOf(elf.Elf32_Shdr), |
| 1190 | | // .p64 => @alignOf(elf.Elf64_Shdr), |
| 1191 | | // }; |
| 1192 | | // const allocated_size = self.allocatedSize(self.shdr_table_offset.?); |
| 1193 | | // const needed_size = self.sections.slice().len * shsize; |
| 1194 | | |
| 1195 | | // if (needed_size > allocated_size) { |
| 1196 | | // self.shdr_table_offset = null; // free the space |
| 1197 | | // self.shdr_table_offset = self.findFreeSpace(needed_size, shalign); |
| 1198 | | // } |
| 1199 | | |
| 1200 | | // switch (self.ptr_width) { |
| 1201 | | // .p32 => { |
| 1202 | | // const slice = self.sections.slice(); |
| 1203 | | // const buf = try gpa.alloc(elf.Elf32_Shdr, slice.len); |
| 1204 | | // defer gpa.free(buf); |
| 1205 | | |
| 1206 | | // for (buf, 0..) |*shdr, i| { |
| 1207 | | // shdr.* = sectHeaderTo32(slice.items(.shdr)[i]); |
| 1208 | | // log.debug("writing section {?s}: {}", .{ self.shstrtab.get(shdr.sh_name), shdr.* }); |
| 1209 | | // if (foreign_endian) { |
| 1210 | | // mem.byteSwapAllFields(elf.Elf32_Shdr, shdr); |
| 1211 | | // } |
| 1212 | | // } |
| 1213 | | // try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 1214 | | // }, |
| 1215 | | // .p64 => { |
| 1216 | | // const slice = self.sections.slice(); |
| 1217 | | // const buf = try gpa.alloc(elf.Elf64_Shdr, slice.len); |
| 1218 | | // defer gpa.free(buf); |
| 1219 | | |
| 1220 | | // for (buf, 0..) |*shdr, i| { |
| 1221 | | // shdr.* = slice.items(.shdr)[i]; |
| 1222 | | // log.debug("writing section {?s}: {}", .{ self.shstrtab.get(shdr.sh_name), shdr.* }); |
| 1223 | | // if (foreign_endian) { |
| 1224 | | // mem.byteSwapAllFields(elf.Elf64_Shdr, shdr); |
| 1225 | | // } |
| 1226 | | // } |
| 1227 | | // try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 1228 | | // }, |
| 1229 | | // } |
| 1230 | | // self.shdr_table_dirty = false; |
| 1231 | | // } |
| 1232 | | // if (self.entry_addr == null and self.base.options.effectiveOutputMode() == .Exe) { |
| 1233 | | // log.debug("flushing. no_entry_point_found = true", .{}); |
| 1234 | | // self.error_flags.no_entry_point_found = true; |
| 1235 | | // } else { |
| 1236 | | // log.debug("flushing. no_entry_point_found = false", .{}); |
| 1237 | | // self.error_flags.no_entry_point_found = false; |
| 1238 | | // try self.writeElfHeader(); |
| 1239 | | // } |
| 1240 | | |
| 1241 | | // // The point of flush() is to commit changes, so in theory, nothing should |
| 1242 | | // // be dirty after this. However, it is possible for some things to remain |
| 1243 | | // // dirty because they fail to be written in the event of compile errors, |
| 1244 | | // // such as debug_line_header_dirty and debug_info_header_dirty. |
| 1245 | | // assert(!self.debug_abbrev_section_dirty); |
| 1246 | | // assert(!self.debug_aranges_section_dirty); |
| 1247 | | // assert(!self.phdr_table_dirty); |
| 1248 | | // assert(!self.shdr_table_dirty); |
| 1249 | | // assert(!self.shstrtab_dirty); |
| 1250 | | // assert(!self.strtab_dirty); |
| 1251 | | // assert(!self.debug_strtab_dirty); |
| 1252 | | // assert(!self.got_table_count_dirty); |
| 1052 | if (self.dwarf) |*dw| { |
| 1053 | if (self.debug_abbrev_section_dirty) { |
| 1054 | try dw.writeDbgAbbrev(); |
| 1055 | if (!self.shdr_table_dirty) { |
| 1056 | // Then it won't get written with the others and we need to do it. |
| 1057 | try self.writeSectHeader(self.debug_abbrev_section_index.?); |
| 1058 | } |
| 1059 | self.debug_abbrev_section_dirty = false; |
| 1060 | } |
| 1061 | |
| 1062 | if (self.debug_info_header_dirty) { |
| 1063 | // Currently only one compilation unit is supported, so the address range is simply |
| 1064 | // identical to the main program header virtual address and memory size. |
| 1065 | const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?]; |
| 1066 | const low_pc = text_phdr.p_vaddr; |
| 1067 | const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; |
| 1068 | try dw.writeDbgInfoHeader(module, low_pc, high_pc); |
| 1069 | self.debug_info_header_dirty = false; |
| 1070 | } |
| 1071 | |
| 1072 | if (self.debug_aranges_section_dirty) { |
| 1073 | // Currently only one compilation unit is supported, so the address range is simply |
| 1074 | // identical to the main program header virtual address and memory size. |
| 1075 | const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?]; |
| 1076 | try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz); |
| 1077 | if (!self.shdr_table_dirty) { |
| 1078 | // Then it won't get written with the others and we need to do it. |
| 1079 | try self.writeSectHeader(self.debug_aranges_section_index.?); |
| 1080 | } |
| 1081 | self.debug_aranges_section_dirty = false; |
| 1082 | } |
| 1083 | |
| 1084 | if (self.debug_line_header_dirty) { |
| 1085 | try dw.writeDbgLineHeader(); |
| 1086 | self.debug_line_header_dirty = false; |
| 1087 | } |
| 1088 | } |
| 1089 | |
| 1090 | if (self.phdr_table_dirty) { |
| 1091 | const phsize: u64 = switch (self.ptr_width) { |
| 1092 | .p32 => @sizeOf(elf.Elf32_Phdr), |
| 1093 | .p64 => @sizeOf(elf.Elf64_Phdr), |
| 1094 | }; |
| 1095 | |
| 1096 | const phdr_table_index = self.phdr_table_index.?; |
| 1097 | const phdr_table = &self.program_headers.items[phdr_table_index]; |
| 1098 | const phdr_table_load = &self.program_headers.items[self.phdr_table_load_index.?]; |
| 1099 | |
| 1100 | const allocated_size = self.allocatedSize(phdr_table.p_offset); |
| 1101 | const needed_size = self.program_headers.items.len * phsize; |
| 1102 | |
| 1103 | if (needed_size > allocated_size) { |
| 1104 | phdr_table.p_offset = 0; // free the space |
| 1105 | phdr_table.p_offset = self.findFreeSpace(needed_size, @as(u32, @intCast(phdr_table.p_align))); |
| 1106 | } |
| 1107 | |
| 1108 | phdr_table_load.p_offset = mem.alignBackward(u64, phdr_table.p_offset, phdr_table_load.p_align); |
| 1109 | const load_align_offset = phdr_table.p_offset - phdr_table_load.p_offset; |
| 1110 | phdr_table_load.p_filesz = load_align_offset + needed_size; |
| 1111 | phdr_table_load.p_memsz = load_align_offset + needed_size; |
| 1112 | |
| 1113 | phdr_table.p_filesz = needed_size; |
| 1114 | phdr_table.p_vaddr = phdr_table_load.p_vaddr + load_align_offset; |
| 1115 | phdr_table.p_paddr = phdr_table_load.p_paddr + load_align_offset; |
| 1116 | phdr_table.p_memsz = needed_size; |
| 1117 | |
| 1118 | switch (self.ptr_width) { |
| 1119 | .p32 => { |
| 1120 | const buf = try gpa.alloc(elf.Elf32_Phdr, self.program_headers.items.len); |
| 1121 | defer gpa.free(buf); |
| 1122 | |
| 1123 | for (buf, 0..) |*phdr, i| { |
| 1124 | phdr.* = progHeaderTo32(self.program_headers.items[i]); |
| 1125 | if (foreign_endian) { |
| 1126 | mem.byteSwapAllFields(elf.Elf32_Phdr, phdr); |
| 1127 | } |
| 1128 | } |
| 1129 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); |
| 1130 | }, |
| 1131 | .p64 => { |
| 1132 | const buf = try gpa.alloc(elf.Elf64_Phdr, self.program_headers.items.len); |
| 1133 | defer gpa.free(buf); |
| 1134 | |
| 1135 | for (buf, 0..) |*phdr, i| { |
| 1136 | phdr.* = self.program_headers.items[i]; |
| 1137 | if (foreign_endian) { |
| 1138 | mem.byteSwapAllFields(elf.Elf64_Phdr, phdr); |
| 1139 | } |
| 1140 | } |
| 1141 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); |
| 1142 | }, |
| 1143 | } |
| 1144 | |
| 1145 | // We don't actually care if the phdr load section overlaps, only the phdr section matters. |
| 1146 | phdr_table_load.p_offset = 0; |
| 1147 | phdr_table_load.p_filesz = 0; |
| 1148 | |
| 1149 | self.phdr_table_dirty = false; |
| 1150 | } |
| 1151 | |
| 1152 | { |
| 1153 | const shdr_index = self.shstrtab_section_index.?; |
| 1154 | if (self.shstrtab_dirty or self.shstrtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) { |
| 1155 | try self.growNonAllocSection(shdr_index, self.shstrtab.buffer.items.len, 1, false); |
| 1156 | const shstrtab_sect = self.sections.items(.shdr)[shdr_index]; |
| 1157 | try self.base.file.?.pwriteAll(self.shstrtab.buffer.items, shstrtab_sect.sh_offset); |
| 1158 | self.shstrtab_dirty = false; |
| 1159 | } |
| 1160 | } |
| 1161 | |
| 1162 | { |
| 1163 | const shdr_index = self.strtab_section_index.?; |
| 1164 | if (self.strtab_dirty or self.strtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) { |
| 1165 | try self.growNonAllocSection(shdr_index, self.strtab.buffer.items.len, 1, false); |
| 1166 | const strtab_sect = self.sections.items(.shdr)[shdr_index]; |
| 1167 | try self.base.file.?.pwriteAll(self.strtab.buffer.items, strtab_sect.sh_offset); |
| 1168 | self.strtab_dirty = false; |
| 1169 | } |
| 1170 | } |
| 1171 | |
| 1172 | if (self.dwarf) |dwarf| { |
| 1173 | const shdr_index = self.debug_str_section_index.?; |
| 1174 | if (self.debug_strtab_dirty or dwarf.strtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) { |
| 1175 | try self.growNonAllocSection(shdr_index, dwarf.strtab.buffer.items.len, 1, false); |
| 1176 | const debug_strtab_sect = self.sections.items(.shdr)[shdr_index]; |
| 1177 | try self.base.file.?.pwriteAll(dwarf.strtab.buffer.items, debug_strtab_sect.sh_offset); |
| 1178 | self.debug_strtab_dirty = false; |
| 1179 | } |
| 1180 | } |
| 1181 | |
| 1182 | if (self.shdr_table_dirty) { |
| 1183 | const shsize: u64 = switch (self.ptr_width) { |
| 1184 | .p32 => @sizeOf(elf.Elf32_Shdr), |
| 1185 | .p64 => @sizeOf(elf.Elf64_Shdr), |
| 1186 | }; |
| 1187 | const shalign: u16 = switch (self.ptr_width) { |
| 1188 | .p32 => @alignOf(elf.Elf32_Shdr), |
| 1189 | .p64 => @alignOf(elf.Elf64_Shdr), |
| 1190 | }; |
| 1191 | const allocated_size = self.allocatedSize(self.shdr_table_offset.?); |
| 1192 | const needed_size = self.sections.slice().len * shsize; |
| 1193 | |
| 1194 | if (needed_size > allocated_size) { |
| 1195 | self.shdr_table_offset = null; // free the space |
| 1196 | self.shdr_table_offset = self.findFreeSpace(needed_size, shalign); |
| 1197 | } |
| 1198 | |
| 1199 | switch (self.ptr_width) { |
| 1200 | .p32 => { |
| 1201 | const slice = self.sections.slice(); |
| 1202 | const buf = try gpa.alloc(elf.Elf32_Shdr, slice.len); |
| 1203 | defer gpa.free(buf); |
| 1204 | |
| 1205 | for (buf, 0..) |*shdr, i| { |
| 1206 | shdr.* = sectHeaderTo32(slice.items(.shdr)[i]); |
| 1207 | log.debug("writing section {?s}: {}", .{ self.shstrtab.get(shdr.sh_name), shdr.* }); |
| 1208 | if (foreign_endian) { |
| 1209 | mem.byteSwapAllFields(elf.Elf32_Shdr, shdr); |
| 1210 | } |
| 1211 | } |
| 1212 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 1213 | }, |
| 1214 | .p64 => { |
| 1215 | const slice = self.sections.slice(); |
| 1216 | const buf = try gpa.alloc(elf.Elf64_Shdr, slice.len); |
| 1217 | defer gpa.free(buf); |
| 1218 | |
| 1219 | for (buf, 0..) |*shdr, i| { |
| 1220 | shdr.* = slice.items(.shdr)[i]; |
| 1221 | log.debug("writing section {?s}: {}", .{ self.shstrtab.get(shdr.sh_name), shdr.* }); |
| 1222 | if (foreign_endian) { |
| 1223 | mem.byteSwapAllFields(elf.Elf64_Shdr, shdr); |
| 1224 | } |
| 1225 | } |
| 1226 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 1227 | }, |
| 1228 | } |
| 1229 | self.shdr_table_dirty = false; |
| 1230 | } |
| 1231 | if (self.entry_addr == null and self.base.options.effectiveOutputMode() == .Exe) { |
| 1232 | log.debug("flushing. no_entry_point_found = true", .{}); |
| 1233 | self.error_flags.no_entry_point_found = true; |
| 1234 | } else { |
| 1235 | log.debug("flushing. no_entry_point_found = false", .{}); |
| 1236 | self.error_flags.no_entry_point_found = false; |
| 1237 | try self.writeElfHeader(); |
| 1238 | } |
| 1239 | |
| 1240 | // The point of flush() is to commit changes, so in theory, nothing should |
| 1241 | // be dirty after this. However, it is possible for some things to remain |
| 1242 | // dirty because they fail to be written in the event of compile errors, |
| 1243 | // such as debug_line_header_dirty and debug_info_header_dirty. |
| 1244 | assert(!self.debug_abbrev_section_dirty); |
| 1245 | assert(!self.debug_aranges_section_dirty); |
| 1246 | assert(!self.phdr_table_dirty); |
| 1247 | assert(!self.shdr_table_dirty); |
| 1248 | assert(!self.shstrtab_dirty); |
| 1249 | assert(!self.strtab_dirty); |
| 1250 | assert(!self.debug_strtab_dirty); |
| 1251 | assert(!self.got_table_count_dirty); |
| 1253 | 1252 | } |
| 1254 | 1253 | |
| 1255 | 1254 | fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| ... | ... | @@ -2795,12 +2794,13 @@ fn writeSymbols(self: *Elf) !void { |
| 2795 | 2794 | .p32 => @alignOf(elf.Elf32_Sym), |
| 2796 | 2795 | .p64 => @alignOf(elf.Elf64_Sym), |
| 2797 | 2796 | }; |
| 2797 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; |
| 2798 | 2798 | |
| 2799 | 2799 | const shdr = &self.sections.items(.shdr)[self.symtab_section_index.?]; |
| 2800 | | shdr.sh_info = @intCast(self.locals.items.len); |
| 2800 | shdr.sh_info = @intCast(zig_module.locals().len); |
| 2801 | 2801 | self.markDirty(self.symtab_section_index.?, null); |
| 2802 | 2802 | |
| 2803 | | const nsyms = self.locals.items.len + self.globals.items.len; |
| 2803 | const nsyms = zig_module.locals().len + zig_module.globals().len; |
| 2804 | 2804 | const needed_size = nsyms * sym_size; |
| 2805 | 2805 | try self.growNonAllocSection(self.symtab_section_index.?, needed_size, sym_align, true); |
| 2806 | 2806 | |
| ... | ... | @@ -2811,15 +2811,17 @@ fn writeSymbols(self: *Elf) !void { |
| 2811 | 2811 | const buf = try gpa.alloc(elf.Elf32_Sym, nsyms); |
| 2812 | 2812 | defer gpa.free(buf); |
| 2813 | 2813 | |
| 2814 | | for (buf[0..self.locals.items.len], self.locals.items) |*sym, local| { |
| 2815 | | elf32SymFromSym(local, sym); |
| 2814 | for (buf[0..zig_module.locals().len], zig_module.locals()) |*sym, local_index| { |
| 2815 | const local = self.symbol(local_index); |
| 2816 | elf32SymFromSym(local.sourceSymbol(self).*, sym); |
| 2816 | 2817 | if (foreign_endian) { |
| 2817 | 2818 | mem.byteSwapAllFields(elf.Elf32_Sym, sym); |
| 2818 | 2819 | } |
| 2819 | 2820 | } |
| 2820 | 2821 | |
| 2821 | | for (buf[self.locals.items.len..], self.globals.items) |*sym, glob| { |
| 2822 | | elf32SymFromSym(self.symbol(glob).*, sym); |
| 2822 | for (buf[zig_module.locals().len..], zig_module.globals()) |*sym, global_index| { |
| 2823 | const global = self.symbol(global_index); |
| 2824 | elf32SymFromSym(global.sourceSymbol(self).*, sym); |
| 2823 | 2825 | if (foreign_endian) { |
| 2824 | 2826 | mem.byteSwapAllFields(elf.Elf32_Sym, sym); |
| 2825 | 2827 | } |
| ... | ... | @@ -2829,15 +2831,17 @@ fn writeSymbols(self: *Elf) !void { |
| 2829 | 2831 | .p64 => { |
| 2830 | 2832 | const buf = try gpa.alloc(elf.Elf64_Sym, nsyms); |
| 2831 | 2833 | defer gpa.free(buf); |
| 2832 | | for (buf[0..self.locals.items.len], self.locals.items) |*sym, local| { |
| 2833 | | sym.* = local; |
| 2834 | for (buf[0..zig_module.locals().len], zig_module.locals()) |*sym, local_index| { |
| 2835 | const local = self.symbol(local_index); |
| 2836 | sym.* = local.sourceSymbol(self).*; |
| 2834 | 2837 | if (foreign_endian) { |
| 2835 | 2838 | mem.byteSwapAllFields(elf.Elf64_Sym, sym); |
| 2836 | 2839 | } |
| 2837 | 2840 | } |
| 2838 | 2841 | |
| 2839 | | for (buf[self.locals.items.len..], self.globals.items) |*sym, glob| { |
| 2840 | | sym.* = self.symbol(glob).*; |
| 2842 | for (buf[zig_module.locals().len..], zig_module.globals()) |*sym, global_index| { |
| 2843 | const global = self.symbol(global_index); |
| 2844 | sym.* = global.sourceSymbol(self).*; |
| 2841 | 2845 | if (foreign_endian) { |
| 2842 | 2846 | mem.byteSwapAllFields(elf.Elf64_Sym, sym); |
| 2843 | 2847 | } |