| author | |
| committer | |
| log | eeec50d2515c5a3b65cab697ba3e28d89cc3b14c |
| tree | ec0b7769fa070c189aa605c00015ec943997b6b1 |
| parent | fca92fd7c0a2e1431338ef62440751870563a0e3 |
5 files changed, 64 insertions(+), 61 deletions(-)
src/link/Elf.zig+18-26| ... | ... | @@ -621,7 +621,6 @@ pub fn growNonAllocSection( |
| 621 | 621 | try self.base.file.?.setEndPos(shdr.sh_offset + needed_size); |
| 622 | 622 | } |
| 623 | 623 | shdr.sh_size = needed_size; |
| 624 | ||
| 625 | 624 | self.markDirty(shdr_index); |
| 626 | 625 | } |
| 627 | 626 | |
| ... | ... | @@ -2895,28 +2894,25 @@ fn initSyntheticSections(self: *Elf) !void { |
| 2895 | 2894 | const target = self.getTarget(); |
| 2896 | 2895 | const ptr_size = self.ptrWidthBytes(); |
| 2897 | 2896 | |
| 2898 | const needs_eh_frame = if (self.zigObjectPtr()) |zo| | |
| 2899 | zo.eh_frame_index != null | |
| 2900 | else for (self.objects.items) |index| { | |
| 2901 | if (self.file(index).?.object.cies.items.len > 0) break true; | |
| 2902 | } else false; | |
| 2897 | const needs_eh_frame = blk: { | |
| 2898 | if (self.zigObjectPtr()) |zo| | |
| 2899 | if (zo.eh_frame_index != null) break :blk true; | |
| 2900 | break :blk for (self.objects.items) |index| { | |
| 2901 | if (self.file(index).?.object.cies.items.len > 0) break true; | |
| 2902 | } else false; | |
| 2903 | }; | |
| 2903 | 2904 | if (needs_eh_frame) { |
| 2904 | 2905 | if (self.eh_frame_section_index == null) { |
| 2905 | self.eh_frame_section_index = blk: { | |
| 2906 | if (self.zigObjectPtr()) |zo| { | |
| 2907 | if (zo.eh_frame_index) |idx| break :blk zo.symbol(idx).atom(self).?.output_section_index; | |
| 2908 | } | |
| 2909 | break :blk try self.addSection(.{ | |
| 2910 | .name = try self.insertShString(".eh_frame"), | |
| 2911 | .type = if (target.cpu.arch == .x86_64) | |
| 2912 | elf.SHT_X86_64_UNWIND | |
| 2913 | else | |
| 2914 | elf.SHT_PROGBITS, | |
| 2915 | .flags = elf.SHF_ALLOC, | |
| 2916 | .addralign = ptr_size, | |
| 2917 | .offset = std.math.maxInt(u64), | |
| 2918 | }); | |
| 2919 | }; | |
| 2906 | self.eh_frame_section_index = self.sectionByName(".eh_frame") orelse try self.addSection(.{ | |
| 2907 | .name = try self.insertShString(".eh_frame"), | |
| 2908 | .type = if (target.cpu.arch == .x86_64) | |
| 2909 | elf.SHT_X86_64_UNWIND | |
| 2910 | else | |
| 2911 | elf.SHT_PROGBITS, | |
| 2912 | .flags = elf.SHF_ALLOC, | |
| 2913 | .addralign = ptr_size, | |
| 2914 | .offset = std.math.maxInt(u64), | |
| 2915 | }); | |
| 2920 | 2916 | } |
| 2921 | 2917 | if (comp.link_eh_frame_hdr) { |
| 2922 | 2918 | self.eh_frame_hdr_section_index = try self.addSection(.{ |
| ... | ... | @@ -3591,11 +3587,7 @@ fn updateSectionSizes(self: *Elf) !void { |
| 3591 | 3587 | |
| 3592 | 3588 | const shdrs = slice.items(.shdr); |
| 3593 | 3589 | if (self.eh_frame_section_index) |index| { |
| 3594 | shdrs[index].sh_size = existing_size: { | |
| 3595 | const zo = self.zigObjectPtr() orelse break :existing_size 0; | |
| 3596 | const sym = zo.symbol(zo.eh_frame_index orelse break :existing_size 0); | |
| 3597 | break :existing_size sym.atom(self).?.size; | |
| 3598 | } + try eh_frame.calcEhFrameSize(self); | |
| 3590 | shdrs[index].sh_size = try eh_frame.calcEhFrameSize(self); | |
| 3599 | 3591 | } |
| 3600 | 3592 | |
| 3601 | 3593 | if (self.eh_frame_hdr_section_index) |index| { |
src/link/Elf/Object.zig+1| ... | ... | @@ -1096,6 +1096,7 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void { |
| 1096 | 1096 | for (self.atoms_indexes.items) |atom_index| { |
| 1097 | 1097 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 1098 | 1098 | if (!atom_ptr.alive) continue; |
| 1099 | if (atom_ptr.output_section_index == elf_file.eh_frame_section_index) continue; | |
| 1099 | 1100 | const shndx = atom_ptr.relocsShndx() orelse continue; |
| 1100 | 1101 | const shdr = self.shdrs.items[shndx]; |
| 1101 | 1102 | const out_shndx = try elf_file.initOutputSection(.{ |
src/link/Elf/ZigObject.zig+12| ... | ... | @@ -111,6 +111,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 111 | 111 | }); |
| 112 | 112 | self.debug_str_section_dirty = true; |
| 113 | 113 | self.debug_str_index = try self.addSectionSymbol(gpa, ".debug_str", .@"1", osec); |
| 114 | elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_str_index.?).ref; | |
| 114 | 115 | } |
| 115 | 116 | |
| 116 | 117 | if (self.debug_info_index == null) { |
| ... | ... | @@ -121,6 +122,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 121 | 122 | }); |
| 122 | 123 | self.debug_info_section_dirty = true; |
| 123 | 124 | self.debug_info_index = try self.addSectionSymbol(gpa, ".debug_info", .@"1", osec); |
| 125 | elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_info_index.?).ref; | |
| 124 | 126 | } |
| 125 | 127 | |
| 126 | 128 | if (self.debug_abbrev_index == null) { |
| ... | ... | @@ -131,6 +133,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 131 | 133 | }); |
| 132 | 134 | self.debug_abbrev_section_dirty = true; |
| 133 | 135 | self.debug_abbrev_index = try self.addSectionSymbol(gpa, ".debug_abbrev", .@"1", osec); |
| 136 | elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_abbrev_index.?).ref; | |
| 134 | 137 | } |
| 135 | 138 | |
| 136 | 139 | if (self.debug_aranges_index == null) { |
| ... | ... | @@ -141,6 +144,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 141 | 144 | }); |
| 142 | 145 | self.debug_aranges_section_dirty = true; |
| 143 | 146 | self.debug_aranges_index = try self.addSectionSymbol(gpa, ".debug_aranges", .@"16", osec); |
| 147 | elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_aranges_index.?).ref; | |
| 144 | 148 | } |
| 145 | 149 | |
| 146 | 150 | if (self.debug_line_index == null) { |
| ... | ... | @@ -151,6 +155,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 151 | 155 | }); |
| 152 | 156 | self.debug_line_section_dirty = true; |
| 153 | 157 | self.debug_line_index = try self.addSectionSymbol(gpa, ".debug_line", .@"1", osec); |
| 158 | elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_line_index.?).ref; | |
| 154 | 159 | } |
| 155 | 160 | |
| 156 | 161 | if (self.debug_line_str_index == null) { |
| ... | ... | @@ -163,6 +168,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 163 | 168 | }); |
| 164 | 169 | self.debug_line_str_section_dirty = true; |
| 165 | 170 | self.debug_line_str_index = try self.addSectionSymbol(gpa, ".debug_line_str", .@"1", osec); |
| 171 | elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_line_str_index.?).ref; | |
| 166 | 172 | } |
| 167 | 173 | |
| 168 | 174 | if (self.debug_loclists_index == null) { |
| ... | ... | @@ -173,6 +179,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 173 | 179 | }); |
| 174 | 180 | self.debug_loclists_section_dirty = true; |
| 175 | 181 | self.debug_loclists_index = try self.addSectionSymbol(gpa, ".debug_loclists", .@"1", osec); |
| 182 | elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_loclists_index.?).ref; | |
| 176 | 183 | } |
| 177 | 184 | |
| 178 | 185 | if (self.debug_rnglists_index == null) { |
| ... | ... | @@ -183,6 +190,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 183 | 190 | }); |
| 184 | 191 | self.debug_rnglists_section_dirty = true; |
| 185 | 192 | self.debug_rnglists_index = try self.addSectionSymbol(gpa, ".debug_rnglists", .@"1", osec); |
| 193 | elf_file.sections.items(.last_atom)[osec] = self.symbol(self.debug_rnglists_index.?).ref; | |
| 186 | 194 | } |
| 187 | 195 | |
| 188 | 196 | if (self.eh_frame_index == null) { |
| ... | ... | @@ -197,6 +205,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 197 | 205 | }); |
| 198 | 206 | self.eh_frame_section_dirty = true; |
| 199 | 207 | self.eh_frame_index = try self.addSectionSymbol(gpa, ".eh_frame", Atom.Alignment.fromNonzeroByteUnits(ptr_size), osec); |
| 208 | elf_file.sections.items(.last_atom)[osec] = self.symbol(self.eh_frame_index.?).ref; | |
| 200 | 209 | } |
| 201 | 210 | |
| 202 | 211 | try dwarf.initMetadata(); |
| ... | ... | @@ -1116,6 +1125,9 @@ pub fn getOrCreateMetadataForNav( |
| 1116 | 1125 | return gop.value_ptr.symbol_index; |
| 1117 | 1126 | } |
| 1118 | 1127 | |
| 1128 | // FIXME: we always create an atom to basically store size and alignment, however, this is only true for | |
| 1129 | // sections that have a single atom like the debug sections. It would be a better solution to decouple this | |
| 1130 | // concept from the atom, maybe. | |
| 1119 | 1131 | fn addSectionSymbol( |
| 1120 | 1132 | self: *ZigObject, |
| 1121 | 1133 | allocator: Allocator, |
src/link/Elf/eh_frame.zig+10-8| ... | ... | @@ -233,7 +233,10 @@ pub fn calcEhFrameSize(elf_file: *Elf) !usize { |
| 233 | 233 | const comp = elf_file.base.comp; |
| 234 | 234 | const gpa = comp.gpa; |
| 235 | 235 | |
| 236 | var offset: usize = 0; | |
| 236 | var offset: usize = if (elf_file.zigObjectPtr()) |zo| blk: { | |
| 237 | const sym = zo.symbol(zo.eh_frame_index orelse break :blk 0); | |
| 238 | break :blk sym.atom(elf_file).?.size; | |
| 239 | } else 0; | |
| 237 | 240 | |
| 238 | 241 | var cies = std.ArrayList(Cie).init(gpa); |
| 239 | 242 | defer cies.deinit(); |
| ... | ... | @@ -423,9 +426,8 @@ pub fn writeEhFrameRelocatable(elf_file: *Elf, writer: anytype) !void { |
| 423 | 426 | } |
| 424 | 427 | } |
| 425 | 428 | |
| 426 | fn emitReloc(elf_file: *Elf, base_offset: u64, sym: *const Symbol, rel: elf.Elf64_Rela) elf.Elf64_Rela { | |
| 429 | fn emitReloc(elf_file: *Elf, r_offset: u64, sym: *const Symbol, rel: elf.Elf64_Rela) elf.Elf64_Rela { | |
| 427 | 430 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 428 | const r_offset = base_offset + rel.r_offset; | |
| 429 | 431 | const r_type = rel.r_type(); |
| 430 | 432 | var r_addend = rel.r_addend; |
| 431 | 433 | var r_sym: u32 = 0; |
| ... | ... | @@ -467,7 +469,7 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void { |
| 467 | 469 | for (atom_ptr.relocs(elf_file)) |rel| { |
| 468 | 470 | const ref = zo.resolveSymbol(rel.r_sym(), elf_file); |
| 469 | 471 | const target = elf_file.symbol(ref).?; |
| 470 | const out_rel = emitReloc(elf_file, 0, target, rel); | |
| 472 | const out_rel = emitReloc(elf_file, rel.r_offset, target, rel); | |
| 471 | 473 | try writer.writeStruct(out_rel); |
| 472 | 474 | } |
| 473 | 475 | } |
| ... | ... | @@ -480,8 +482,8 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void { |
| 480 | 482 | for (cie.relocs(elf_file)) |rel| { |
| 481 | 483 | const ref = object.resolveSymbol(rel.r_sym(), elf_file); |
| 482 | 484 | const sym = elf_file.symbol(ref).?; |
| 483 | const offset = cie.address(elf_file) - cie.offset; | |
| 484 | const out_rel = emitReloc(elf_file, offset, sym, rel); | |
| 485 | const r_offset = cie.address(elf_file) + rel.r_offset - cie.offset; | |
| 486 | const out_rel = emitReloc(elf_file, r_offset, sym, rel); | |
| 485 | 487 | try writer.writeStruct(out_rel); |
| 486 | 488 | } |
| 487 | 489 | } |
| ... | ... | @@ -491,8 +493,8 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void { |
| 491 | 493 | for (fde.relocs(elf_file)) |rel| { |
| 492 | 494 | const ref = object.resolveSymbol(rel.r_sym(), elf_file); |
| 493 | 495 | const sym = elf_file.symbol(ref).?; |
| 494 | const offset = fde.address(elf_file) - fde.offset; | |
| 495 | const out_rel = emitReloc(elf_file, offset, sym, rel); | |
| 496 | const r_offset = fde.address(elf_file) + rel.r_offset - fde.offset; | |
| 497 | const out_rel = emitReloc(elf_file, r_offset, sym, rel); | |
| 496 | 498 | try writer.writeStruct(out_rel); |
| 497 | 499 | } |
| 498 | 500 | } |
src/link/Elf/relocatable.zig+23-27| ... | ... | @@ -302,30 +302,29 @@ fn initSections(elf_file: *Elf) !void { |
| 302 | 302 | try msec.initOutputSection(elf_file); |
| 303 | 303 | } |
| 304 | 304 | |
| 305 | const needs_eh_frame = if (elf_file.zigObjectPtr()) |zo| | |
| 306 | zo.eh_frame_index != null | |
| 307 | else for (elf_file.objects.items) |index| { | |
| 308 | if (elf_file.file(index).?.object.cies.items.len > 0) break true; | |
| 309 | } else false; | |
| 305 | const needs_eh_frame = blk: { | |
| 306 | if (elf_file.zigObjectPtr()) |zo| | |
| 307 | if (zo.eh_frame_index != null) break :blk true; | |
| 308 | break :blk for (elf_file.objects.items) |index| { | |
| 309 | if (elf_file.file(index).?.object.cies.items.len > 0) break true; | |
| 310 | } else false; | |
| 311 | }; | |
| 310 | 312 | if (needs_eh_frame) { |
| 311 | 313 | if (elf_file.eh_frame_section_index == null) { |
| 312 | elf_file.eh_frame_section_index = blk: { | |
| 313 | if (elf_file.zigObjectPtr()) |zo| { | |
| 314 | if (zo.eh_frame_index) |idx| break :blk zo.symbol(idx).atom(elf_file).?.output_section_index; | |
| 315 | } | |
| 316 | break :blk try elf_file.addSection(.{ | |
| 317 | .name = try elf_file.insertShString(".eh_frame"), | |
| 318 | .type = if (elf_file.getTarget().cpu.arch == .x86_64) | |
| 319 | elf.SHT_X86_64_UNWIND | |
| 320 | else | |
| 321 | elf.SHT_PROGBITS, | |
| 322 | .flags = elf.SHF_ALLOC, | |
| 323 | .addralign = elf_file.ptrWidthBytes(), | |
| 324 | .offset = std.math.maxInt(u64), | |
| 325 | }); | |
| 326 | }; | |
| 314 | elf_file.eh_frame_section_index = elf_file.sectionByName(".eh_frame") orelse | |
| 315 | try elf_file.addSection(.{ | |
| 316 | .name = try elf_file.insertShString(".eh_frame"), | |
| 317 | .type = if (elf_file.getTarget().cpu.arch == .x86_64) | |
| 318 | elf.SHT_X86_64_UNWIND | |
| 319 | else | |
| 320 | elf.SHT_PROGBITS, | |
| 321 | .flags = elf.SHF_ALLOC, | |
| 322 | .addralign = elf_file.ptrWidthBytes(), | |
| 323 | .offset = std.math.maxInt(u64), | |
| 324 | }); | |
| 327 | 325 | } |
| 328 | elf_file.eh_frame_rela_section_index = try elf_file.addRelaShdr( | |
| 326 | elf_file.eh_frame_rela_section_index = elf_file.sectionByName(".rela.eh_frame") orelse | |
| 327 | try elf_file.addRelaShdr( | |
| 329 | 328 | try elf_file.insertShString(".rela.eh_frame"), |
| 330 | 329 | elf_file.eh_frame_section_index.?, |
| 331 | 330 | ); |
| ... | ... | @@ -367,6 +366,7 @@ fn updateSectionSizes(elf_file: *Elf) !void { |
| 367 | 366 | for (slice.items(.shdr), 0..) |*shdr, shndx| { |
| 368 | 367 | const atom_list = slice.items(.atom_list)[shndx]; |
| 369 | 368 | if (shdr.sh_type != elf.SHT_RELA) continue; |
| 369 | if (@as(u32, @intCast(shndx)) == elf_file.eh_frame_section_index) continue; | |
| 370 | 370 | for (atom_list.items) |ref| { |
| 371 | 371 | const atom_ptr = elf_file.atom(ref) orelse continue; |
| 372 | 372 | if (!atom_ptr.alive) continue; |
| ... | ... | @@ -378,11 +378,7 @@ fn updateSectionSizes(elf_file: *Elf) !void { |
| 378 | 378 | } |
| 379 | 379 | |
| 380 | 380 | if (elf_file.eh_frame_section_index) |index| { |
| 381 | slice.items(.shdr)[index].sh_size = existing_size: { | |
| 382 | const zo = elf_file.zigObjectPtr() orelse break :existing_size 0; | |
| 383 | const sym = zo.symbol(zo.eh_frame_index orelse break :existing_size 0); | |
| 384 | break :existing_size sym.atom(elf_file).?.size; | |
| 385 | } + try eh_frame.calcEhFrameSize(elf_file); | |
| 381 | slice.items(.shdr)[index].sh_size = try eh_frame.calcEhFrameSize(elf_file); | |
| 386 | 382 | } |
| 387 | 383 | if (elf_file.eh_frame_rela_section_index) |index| { |
| 388 | 384 | const shdr = &slice.items(.shdr)[index]; |
| ... | ... | @@ -464,8 +460,8 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 464 | 460 | |
| 465 | 461 | for (slice.items(.shdr), slice.items(.atom_list), 0..) |shdr, atom_list, shndx| { |
| 466 | 462 | if (shdr.sh_type != elf.SHT_RELA) continue; |
| 467 | if (@as(u32, @intCast(shndx)) == elf_file.eh_frame_rela_section_index) continue; | |
| 468 | 463 | if (atom_list.items.len == 0) continue; |
| 464 | if (@as(u32, @intCast(shndx)) == elf_file.eh_frame_section_index) continue; | |
| 469 | 465 | |
| 470 | 466 | const num_relocs = math.cast(usize, @divExact(shdr.sh_size, shdr.sh_entsize)) orelse |
| 471 | 467 | return error.Overflow; |