authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-09 12:24:49+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-09 12:24:49+01:00
logb1fcf0ed8f435b834f21a3d57c03f5c0333c6fd9
tree86327d5af555728ef5975d48330f889dda963a5c
parent0efc4711220d98d8c0178dfe9d64dc897c6dee70

elf: emit .rela.eh_frame section contents


2 files changed, 68 insertions(+), 5 deletions(-)

src/link/Elf.zig+12-5
......@@ -4245,11 +4245,10 @@ fn updateSectionSizesObject(self: *Elf) !void {
42454245
42464246 if (self.eh_frame_section_index) |index| {
42474247 self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self);
4248
4249 if (self.eh_frame_rela_section_index) |rela_index| {
4250 const shdr = &self.shdrs.items[rela_index];
4251 shdr.sh_size = eh_frame.calcEhFrameRelocs(self) * shdr.sh_entsize;
4252 }
4248 }
4249 if (self.eh_frame_rela_section_index) |index| {
4250 const shdr = &self.shdrs.items[index];
4251 shdr.sh_size = eh_frame.calcEhFrameRelocs(self) * shdr.sh_entsize;
42534252 }
42544253
42554254 try self.updateSymtabSize();
......@@ -5013,6 +5012,14 @@ fn writeSyntheticSectionsObject(self: *Elf) !void {
50135012 try eh_frame.writeEhFrame(self, buffer.writer());
50145013 try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
50155014 }
5015 if (self.eh_frame_rela_section_index) |shndx| {
5016 const shdr = self.shdrs.items[shndx];
5017 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
5018 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
5019 defer buffer.deinit();
5020 try eh_frame.writeEhFrameRelocs(self, buffer.writer());
5021 try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
5022 }
50165023
50175024 try self.writeSymtab();
50185025 try self.writeShStrtab();
src/link/Elf/eh_frame.zig+56
......@@ -373,6 +373,62 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
373373 try writer.writeInt(u32, 0, .little);
374374}
375375
376fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela) elf.Elf64_Rela {
377 const r_offset = rec.address(elf_file) + rel.r_offset - rec.offset;
378 const r_type = rel.r_type();
379 var r_addend = rel.r_addend;
380 var r_sym: u32 = 0;
381 switch (sym.type(elf_file)) {
382 elf.STT_SECTION => {
383 r_addend += @intCast(sym.value);
384 r_sym = elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx().?);
385 },
386 else => {
387 r_sym = sym.outputSymtabIndex(elf_file) orelse 0;
388 },
389 }
390
391 relocs_log.debug(" {s}: [{x} => {d}({s})] + {x}", .{
392 Atom.fmtRelocType(r_type),
393 r_offset,
394 r_sym,
395 sym.name(elf_file),
396 r_addend,
397 });
398
399 return .{
400 .r_offset = r_offset,
401 .r_addend = r_addend,
402 .r_info = (@as(u64, @intCast(r_sym)) << 32) | r_type,
403 };
404}
405
406pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {
407 relocs_log.debug("{x}: .eh_frame", .{elf_file.shdrs.items[elf_file.eh_frame_section_index.?].sh_addr});
408
409 for (elf_file.objects.items) |index| {
410 const object = elf_file.file(index).?.object;
411
412 for (object.cies.items) |cie| {
413 if (!cie.alive) continue;
414 for (cie.relocs(elf_file)) |rel| {
415 const sym = elf_file.symbol(object.symbols.items[rel.r_sym()]);
416 const out_rel = emitReloc(elf_file, cie, sym, rel);
417 try writer.writeStruct(out_rel);
418 }
419 }
420
421 for (object.fdes.items) |fde| {
422 if (!fde.alive) continue;
423 for (fde.relocs(elf_file)) |rel| {
424 const sym = elf_file.symbol(object.symbols.items[rel.r_sym()]);
425 const out_rel = emitReloc(elf_file, fde, sym, rel);
426 try writer.writeStruct(out_rel);
427 }
428 }
429 }
430}
431
376432pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
377433 try writer.writeByte(1); // version
378434 try writer.writeByte(EH_PE.pcrel | EH_PE.sdata4);