| author | |
| committer | |
| log | 2ef3e30e2d04f16510d0953e6d266a97bcb4eb49 |
| tree | 2d4fd8e6fd36449939b254f99408370b3884cc86 |
| parent | 5cb51c10debd3e9542e35e22648bca2a8b59259e |
5 files changed, 61 insertions(+), 25 deletions(-)
src/link/Elf.zig+13-11| ... | ... | @@ -3388,34 +3388,36 @@ fn shdrRank(self: *Elf, shndx: u32) u8 { |
| 3388 | 3388 | elf.SHT_PREINIT_ARRAY, |
| 3389 | 3389 | elf.SHT_INIT_ARRAY, |
| 3390 | 3390 | elf.SHT_FINI_ARRAY, |
| 3391 | => return 0xf2, | |
| 3391 | => return 0xf1, | |
| 3392 | 3392 | |
| 3393 | elf.SHT_DYNAMIC => return 0xf3, | |
| 3393 | elf.SHT_DYNAMIC => return 0xf2, | |
| 3394 | 3394 | |
| 3395 | 3395 | elf.SHT_RELA, elf.SHT_GROUP => return 0xf, |
| 3396 | 3396 | |
| 3397 | 3397 | elf.SHT_PROGBITS => if (flags & elf.SHF_ALLOC != 0) { |
| 3398 | 3398 | if (flags & elf.SHF_EXECINSTR != 0) { |
| 3399 | return 0xf1; | |
| 3399 | return 0xf0; | |
| 3400 | 3400 | } else if (flags & elf.SHF_WRITE != 0) { |
| 3401 | return if (flags & elf.SHF_TLS != 0) 0xf4 else 0xf6; | |
| 3401 | return if (flags & elf.SHF_TLS != 0) 0xf3 else 0xf5; | |
| 3402 | 3402 | } else if (mem.eql(u8, name, ".interp")) { |
| 3403 | 3403 | return 1; |
| 3404 | } else if (mem.startsWith(u8, name, ".eh_frame")) { | |
| 3405 | return 0xe1; | |
| 3404 | 3406 | } else { |
| 3405 | return 0xf0; | |
| 3407 | return 0xe0; | |
| 3406 | 3408 | } |
| 3407 | 3409 | } else { |
| 3408 | 3410 | if (mem.startsWith(u8, name, ".debug")) { |
| 3409 | return 0xf8; | |
| 3411 | return 0xf7; | |
| 3410 | 3412 | } else { |
| 3411 | return 0xf9; | |
| 3413 | return 0xf8; | |
| 3412 | 3414 | } |
| 3413 | 3415 | }, |
| 3414 | elf.SHT_X86_64_UNWIND => return 0xf0, | |
| 3416 | elf.SHT_X86_64_UNWIND => return 0xe1, | |
| 3415 | 3417 | |
| 3416 | elf.SHT_NOBITS => return if (flags & elf.SHF_TLS != 0) 0xf5 else 0xf7, | |
| 3417 | elf.SHT_SYMTAB => return 0xfa, | |
| 3418 | elf.SHT_STRTAB => return if (mem.eql(u8, name, ".dynstr")) 0x4 else 0xfb, | |
| 3418 | elf.SHT_NOBITS => return if (flags & elf.SHF_TLS != 0) 0xf4 else 0xf6, | |
| 3419 | elf.SHT_SYMTAB => return 0xf9, | |
| 3420 | elf.SHT_STRTAB => return if (mem.eql(u8, name, ".dynstr")) 0x4 else 0xfa, | |
| 3419 | 3421 | else => return 0xff, |
| 3420 | 3422 | } |
| 3421 | 3423 | } |
src/link/Elf/Object.zig+19-9| ... | ... | @@ -391,15 +391,24 @@ fn parseEhFrame(self: *Object, allocator: Allocator, handle: std.fs.File, shndx: |
| 391 | 391 | .input_section_index = shndx, |
| 392 | 392 | .file_index = self.index, |
| 393 | 393 | }), |
| 394 | .fde => try self.fdes.append(allocator, .{ | |
| 395 | .offset = data_start + rec.offset, | |
| 396 | .size = rec.size, | |
| 397 | .cie_index = undefined, | |
| 398 | .rel_index = rel_start + @as(u32, @intCast(rel_range.start)), | |
| 399 | .rel_num = @as(u32, @intCast(rel_range.len)), | |
| 400 | .input_section_index = shndx, | |
| 401 | .file_index = self.index, | |
| 402 | }), | |
| 394 | .fde => { | |
| 395 | if (rel_range.len == 0) { | |
| 396 | // No relocs for an FDE means we cannot associate this FDE to an Atom | |
| 397 | // so we skip it. According to mold source code | |
| 398 | // (https://github.com/rui314/mold/blob/a3e69502b0eaf1126d6093e8ea5e6fdb95219811/src/input-files.cc#L525-L528) | |
| 399 | // this can happen for object files built with -r flag by the linker. | |
| 400 | continue; | |
| 401 | } | |
| 402 | try self.fdes.append(allocator, .{ | |
| 403 | .offset = data_start + rec.offset, | |
| 404 | .size = rec.size, | |
| 405 | .cie_index = undefined, | |
| 406 | .rel_index = rel_start + @as(u32, @intCast(rel_range.start)), | |
| 407 | .rel_num = @as(u32, @intCast(rel_range.len)), | |
| 408 | .input_section_index = shndx, | |
| 409 | .file_index = self.index, | |
| 410 | }); | |
| 411 | }, | |
| 403 | 412 | } |
| 404 | 413 | } |
| 405 | 414 | |
| ... | ... | @@ -1106,6 +1115,7 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void { |
| 1106 | 1115 | for (self.atoms_indexes.items) |atom_index| { |
| 1107 | 1116 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 1108 | 1117 | if (!atom_ptr.alive) continue; |
| 1118 | if (atom_ptr.output_section_index == elf_file.eh_frame_section_index) continue; | |
| 1109 | 1119 | const shndx = blk: { |
| 1110 | 1120 | const shndx = atom_ptr.relocsShndx() orelse continue; |
| 1111 | 1121 | const shdr = self.shdrs.items[shndx]; |
src/link/Elf/ZigObject.zig+1| ... | ... | @@ -808,6 +808,7 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void { |
| 808 | 808 | for (self.atoms_indexes.items) |atom_index| { |
| 809 | 809 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 810 | 810 | if (!atom_ptr.alive) continue; |
| 811 | if (atom_ptr.output_section_index == elf_file.eh_frame_section_index) continue; | |
| 811 | 812 | const rela_shndx = atom_ptr.relocsShndx() orelse continue; |
| 812 | 813 | // TODO this check will become obsolete when we rework our relocs mechanism at the ZigObject level |
| 813 | 814 | if (self.relocs.items[rela_shndx].items.len == 0) continue; |
src/link/Elf/eh_frame.zig+26-4| ... | ... | @@ -288,6 +288,13 @@ pub fn calcEhFrameHdrSize(elf_file: *Elf) usize { |
| 288 | 288 | |
| 289 | 289 | pub fn calcEhFrameRelocs(elf_file: *Elf) usize { |
| 290 | 290 | var count: usize = 0; |
| 291 | if (elf_file.zigObjectPtr()) |zo| zo: { | |
| 292 | const sym_index = zo.eh_frame_index orelse break :zo; | |
| 293 | const sym = zo.symbol(sym_index); | |
| 294 | const atom_ptr = zo.atom(sym.ref.index).?; | |
| 295 | if (!atom_ptr.alive) break :zo; | |
| 296 | count += atom_ptr.relocs(elf_file).len; | |
| 297 | } | |
| 291 | 298 | for (elf_file.objects.items) |index| { |
| 292 | 299 | const object = elf_file.file(index).?.object; |
| 293 | 300 | for (object.cies.items) |cie| { |
| ... | ... | @@ -416,9 +423,9 @@ pub fn writeEhFrameRelocatable(elf_file: *Elf, writer: anytype) !void { |
| 416 | 423 | } |
| 417 | 424 | } |
| 418 | 425 | |
| 419 | fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela) elf.Elf64_Rela { | |
| 426 | fn emitReloc(elf_file: *Elf, base_offset: u64, sym: *const Symbol, rel: elf.Elf64_Rela) elf.Elf64_Rela { | |
| 420 | 427 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 421 | const r_offset = rec.address(elf_file) + rel.r_offset - rec.offset; | |
| 428 | const r_offset = base_offset + rel.r_offset; | |
| 422 | 429 | const r_type = rel.r_type(); |
| 423 | 430 | var r_addend = rel.r_addend; |
| 424 | 431 | var r_sym: u32 = 0; |
| ... | ... | @@ -452,6 +459,19 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void { |
| 452 | 459 | elf_file.sections.items(.shdr)[elf_file.eh_frame_section_index.?].sh_addr, |
| 453 | 460 | }); |
| 454 | 461 | |
| 462 | if (elf_file.zigObjectPtr()) |zo| zo: { | |
| 463 | const sym_index = zo.eh_frame_index orelse break :zo; | |
| 464 | const sym = zo.symbol(sym_index); | |
| 465 | const atom_ptr = zo.atom(sym.ref.index).?; | |
| 466 | if (!atom_ptr.alive) break :zo; | |
| 467 | for (atom_ptr.relocs(elf_file)) |rel| { | |
| 468 | const ref = zo.resolveSymbol(rel.r_sym(), elf_file); | |
| 469 | const target = elf_file.symbol(ref).?; | |
| 470 | const out_rel = emitReloc(elf_file, 0, target, rel); | |
| 471 | try writer.writeStruct(out_rel); | |
| 472 | } | |
| 473 | } | |
| 474 | ||
| 455 | 475 | for (elf_file.objects.items) |index| { |
| 456 | 476 | const object = elf_file.file(index).?.object; |
| 457 | 477 | |
| ... | ... | @@ -460,7 +480,8 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void { |
| 460 | 480 | for (cie.relocs(elf_file)) |rel| { |
| 461 | 481 | const ref = object.resolveSymbol(rel.r_sym(), elf_file); |
| 462 | 482 | const sym = elf_file.symbol(ref).?; |
| 463 | const out_rel = emitReloc(elf_file, cie, sym, rel); | |
| 483 | const offset = cie.address(elf_file) - cie.offset; | |
| 484 | const out_rel = emitReloc(elf_file, offset, sym, rel); | |
| 464 | 485 | try writer.writeStruct(out_rel); |
| 465 | 486 | } |
| 466 | 487 | } |
| ... | ... | @@ -470,7 +491,8 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void { |
| 470 | 491 | for (fde.relocs(elf_file)) |rel| { |
| 471 | 492 | const ref = object.resolveSymbol(rel.r_sym(), elf_file); |
| 472 | 493 | const sym = elf_file.symbol(ref).?; |
| 473 | const out_rel = emitReloc(elf_file, fde, sym, rel); | |
| 494 | const offset = fde.address(elf_file) - fde.offset; | |
| 495 | const out_rel = emitReloc(elf_file, offset, sym, rel); | |
| 474 | 496 | try writer.writeStruct(out_rel); |
| 475 | 497 | } |
| 476 | 498 | } |
src/link/Elf/relocatable.zig+2-1| ... | ... | @@ -424,8 +424,9 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 424 | 424 | const gpa = elf_file.base.comp.gpa; |
| 425 | 425 | const slice = elf_file.sections.slice(); |
| 426 | 426 | |
| 427 | for (slice.items(.shdr), slice.items(.atom_list)) |shdr, atom_list| { | |
| 427 | for (slice.items(.shdr), slice.items(.atom_list), 0..) |shdr, atom_list, shndx| { | |
| 428 | 428 | if (shdr.sh_type != elf.SHT_RELA) continue; |
| 429 | if (@as(u32, @intCast(shndx)) == elf_file.eh_frame_rela_section_index) continue; | |
| 429 | 430 | if (atom_list.items.len == 0) continue; |
| 430 | 431 | |
| 431 | 432 | const num_relocs = math.cast(usize, @divExact(shdr.sh_size, shdr.sh_entsize)) orelse |