authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-06 23:20:49+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-06 23:43:26+02:00
log37e2958f8125b08d4acb9175bf0bd30cd9872961
tree2b1139a2817ed099b2b80386b7eb46796b3311fa
parenta2b5a464e65955f09e3034830ca275ae84ebddea

elf: write symbtab


1 files changed, 216 insertions(+), 212 deletions(-)

src/link/Elf.zig+216-212
......@@ -1003,7 +1003,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10031003
10041004 const target_endian = self.base.options.target.cpu.arch.endian();
10051005 const foreign_endian = target_endian != builtin.cpu.arch.endian();
1006 _ = foreign_endian;
10071006
10081007 if (self.dwarf) |*dw| {
10091008 try dw.flushModule(module);
......@@ -1044,212 +1043,212 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10441043 }
10451044 }
10461045
1047 // try self.writeSymbols();
1046 try self.writeSymbols();
10481047
10491048 if (build_options.enable_logging) {
10501049 state_log.debug("{}", .{self.dumpState()});
10511050 }
10521051
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);
12531252}
12541253
12551254fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
......@@ -2795,12 +2794,13 @@ fn writeSymbols(self: *Elf) !void {
27952794 .p32 => @alignOf(elf.Elf32_Sym),
27962795 .p64 => @alignOf(elf.Elf64_Sym),
27972796 };
2797 const zig_module = self.file(self.zig_module_index.?).?.zig_module;
27982798
27992799 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);
28012801 self.markDirty(self.symtab_section_index.?, null);
28022802
2803 const nsyms = self.locals.items.len + self.globals.items.len;
2803 const nsyms = zig_module.locals().len + zig_module.globals().len;
28042804 const needed_size = nsyms * sym_size;
28052805 try self.growNonAllocSection(self.symtab_section_index.?, needed_size, sym_align, true);
28062806
......@@ -2811,15 +2811,17 @@ fn writeSymbols(self: *Elf) !void {
28112811 const buf = try gpa.alloc(elf.Elf32_Sym, nsyms);
28122812 defer gpa.free(buf);
28132813
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);
28162817 if (foreign_endian) {
28172818 mem.byteSwapAllFields(elf.Elf32_Sym, sym);
28182819 }
28192820 }
28202821
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);
28232825 if (foreign_endian) {
28242826 mem.byteSwapAllFields(elf.Elf32_Sym, sym);
28252827 }
......@@ -2829,15 +2831,17 @@ fn writeSymbols(self: *Elf) !void {
28292831 .p64 => {
28302832 const buf = try gpa.alloc(elf.Elf64_Sym, nsyms);
28312833 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).*;
28342837 if (foreign_endian) {
28352838 mem.byteSwapAllFields(elf.Elf64_Sym, sym);
28362839 }
28372840 }
28382841
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).*;
28412845 if (foreign_endian) {
28422846 mem.byteSwapAllFields(elf.Elf64_Sym, sym);
28432847 }