authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-07 13:12:26+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-07 13:31:31+01:00
logc7ed7c4690dfa297c15b94fe7acba77c52d89e68
treec2e8791aefee2e92333ccea7491033179f559c6c
parent3df53d1722da9e4fcc8606315c68ffb884a0dd5a

elf: generate section symbols when writing symtab


6 files changed, 106 insertions(+), 50 deletions(-)

src/link/Elf.zig+85-25
...@@ -597,7 +597,6 @@ pub fn initMetadata(self: *Elf) !void {...@@ -597,7 +597,6 @@ pub fn initMetadata(self: *Elf) !void {
597 const shdr = &self.shdrs.items[self.zig_text_section_index.?];597 const shdr = &self.shdrs.items[self.zig_text_section_index.?];
598 fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index);598 fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index);
599 if (self.isRelocatable()) {599 if (self.isRelocatable()) {
600 try zig_object.addSectionSymbol(self.zig_text_section_index.?, self);
601 self.zig_text_rela_section_index = try self.addRelaShdr(600 self.zig_text_rela_section_index = try self.addRelaShdr(
602 ".rela.text.zig",601 ".rela.text.zig",
603 self.zig_text_section_index.?,602 self.zig_text_section_index.?,
...@@ -609,6 +608,7 @@ pub fn initMetadata(self: *Elf) !void {...@@ -609,6 +608,7 @@ pub fn initMetadata(self: *Elf) !void {
609 self.phdr_zig_load_re_index.?,608 self.phdr_zig_load_re_index.?,
610 );609 );
611 }610 }
611 try self.output_sections.putNoClobber(gpa, self.zig_text_section_index.?, .{});
612 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});612 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});
613 }613 }
614614
...@@ -644,7 +644,6 @@ pub fn initMetadata(self: *Elf) !void {...@@ -644,7 +644,6 @@ pub fn initMetadata(self: *Elf) !void {
644 const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?];644 const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?];
645 fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index);645 fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index);
646 if (self.isRelocatable()) {646 if (self.isRelocatable()) {
647 try zig_object.addSectionSymbol(self.zig_data_rel_ro_section_index.?, self);
648 self.zig_data_rel_ro_rela_section_index = try self.addRelaShdr(647 self.zig_data_rel_ro_rela_section_index = try self.addRelaShdr(
649 ".rela.data.rel.ro.zig",648 ".rela.data.rel.ro.zig",
650 self.zig_data_rel_ro_section_index.?,649 self.zig_data_rel_ro_section_index.?,
...@@ -656,6 +655,7 @@ pub fn initMetadata(self: *Elf) !void {...@@ -656,6 +655,7 @@ pub fn initMetadata(self: *Elf) !void {
656 self.phdr_zig_load_ro_index.?,655 self.phdr_zig_load_ro_index.?,
657 );656 );
658 }657 }
658 try self.output_sections.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, .{});
659 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, .{});659 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, .{});
660 }660 }
661661
...@@ -670,7 +670,6 @@ pub fn initMetadata(self: *Elf) !void {...@@ -670,7 +670,6 @@ pub fn initMetadata(self: *Elf) !void {
670 const shdr = &self.shdrs.items[self.zig_data_section_index.?];670 const shdr = &self.shdrs.items[self.zig_data_section_index.?];
671 fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index);671 fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index);
672 if (self.isRelocatable()) {672 if (self.isRelocatable()) {
673 try zig_object.addSectionSymbol(self.zig_data_section_index.?, self);
674 self.zig_data_rela_section_index = try self.addRelaShdr(673 self.zig_data_rela_section_index = try self.addRelaShdr(
675 ".rela.data.zig",674 ".rela.data.zig",
676 self.zig_data_section_index.?,675 self.zig_data_section_index.?,
...@@ -682,6 +681,7 @@ pub fn initMetadata(self: *Elf) !void {...@@ -682,6 +681,7 @@ pub fn initMetadata(self: *Elf) !void {
682 self.phdr_zig_load_rw_index.?,681 self.phdr_zig_load_rw_index.?,
683 );682 );
684 }683 }
684 try self.output_sections.putNoClobber(gpa, self.zig_data_section_index.?, .{});
685 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_section_index.?, .{});685 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_section_index.?, .{});
686 }686 }
687687
...@@ -700,9 +700,9 @@ pub fn initMetadata(self: *Elf) !void {...@@ -700,9 +700,9 @@ pub fn initMetadata(self: *Elf) !void {
700 shdr.sh_size = phdr.p_memsz;700 shdr.sh_size = phdr.p_memsz;
701 try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_bss_section_index.?, phndx);701 try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_bss_section_index.?, phndx);
702 } else {702 } else {
703 try zig_object.addSectionSymbol(self.zig_bss_section_index.?, self);
704 shdr.sh_size = 1024;703 shdr.sh_size = 1024;
705 }704 }
705 try self.output_sections.putNoClobber(gpa, self.zig_bss_section_index.?, .{});
706 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{});706 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{});
707 }707 }
708708
...@@ -724,6 +724,7 @@ pub fn initMetadata(self: *Elf) !void {...@@ -724,6 +724,7 @@ pub fn initMetadata(self: *Elf) !void {
724 shdr.sh_offset = off;724 shdr.sh_offset = off;
725 shdr.sh_size = size;725 shdr.sh_size = size;
726 zig_object.debug_strtab_dirty = true;726 zig_object.debug_strtab_dirty = true;
727 try self.output_sections.putNoClobber(gpa, self.debug_str_section_index.?, .{});
727 }728 }
728729
729 if (self.debug_info_section_index == null) {730 if (self.debug_info_section_index == null) {
...@@ -739,6 +740,7 @@ pub fn initMetadata(self: *Elf) !void {...@@ -739,6 +740,7 @@ pub fn initMetadata(self: *Elf) !void {
739 shdr.sh_offset = off;740 shdr.sh_offset = off;
740 shdr.sh_size = size;741 shdr.sh_size = size;
741 zig_object.debug_info_header_dirty = true;742 zig_object.debug_info_header_dirty = true;
743 try self.output_sections.putNoClobber(gpa, self.debug_info_section_index.?, .{});
742 }744 }
743745
744 if (self.debug_abbrev_section_index == null) {746 if (self.debug_abbrev_section_index == null) {
...@@ -754,6 +756,7 @@ pub fn initMetadata(self: *Elf) !void {...@@ -754,6 +756,7 @@ pub fn initMetadata(self: *Elf) !void {
754 shdr.sh_offset = off;756 shdr.sh_offset = off;
755 shdr.sh_size = size;757 shdr.sh_size = size;
756 zig_object.debug_abbrev_section_dirty = true;758 zig_object.debug_abbrev_section_dirty = true;
759 try self.output_sections.putNoClobber(gpa, self.debug_abbrev_section_index.?, .{});
757 }760 }
758761
759 if (self.debug_aranges_section_index == null) {762 if (self.debug_aranges_section_index == null) {
...@@ -769,6 +772,7 @@ pub fn initMetadata(self: *Elf) !void {...@@ -769,6 +772,7 @@ pub fn initMetadata(self: *Elf) !void {
769 shdr.sh_offset = off;772 shdr.sh_offset = off;
770 shdr.sh_size = size;773 shdr.sh_size = size;
771 zig_object.debug_aranges_section_dirty = true;774 zig_object.debug_aranges_section_dirty = true;
775 try self.output_sections.putNoClobber(gpa, self.debug_aranges_section_index.?, .{});
772 }776 }
773777
774 if (self.debug_line_section_index == null) {778 if (self.debug_line_section_index == null) {
...@@ -784,6 +788,7 @@ pub fn initMetadata(self: *Elf) !void {...@@ -784,6 +788,7 @@ pub fn initMetadata(self: *Elf) !void {
784 shdr.sh_offset = off;788 shdr.sh_offset = off;
785 shdr.sh_size = size;789 shdr.sh_size = size;
786 zig_object.debug_line_header_dirty = true;790 zig_object.debug_line_header_dirty = true;
791 try self.output_sections.putNoClobber(gpa, self.debug_line_section_index.?, .{});
787 }792 }
788 }793 }
789}794}
...@@ -1510,14 +1515,14 @@ pub fn flushStaticLib(self: *Elf) link.File.FlushError!void {...@@ -1510,14 +1515,14 @@ pub fn flushStaticLib(self: *Elf) link.File.FlushError!void {
1510 try self.initShStrtab();1515 try self.initShStrtab();
1511 try self.sortShdrs();1516 try self.sortShdrs();
1512 zig_object.updateRelaSectionsSizes(self);1517 zig_object.updateRelaSectionsSizes(self);
1513 self.updateSymtabSizeObject(zig_object);1518 self.updateSymtabSizeZigObject(zig_object);
1514 self.updateShStrtabSize();1519 self.updateShStrtabSize();
15151520
1516 try self.allocateNonAllocSections();1521 try self.allocateNonAllocSections();
15171522
1518 try self.writeShdrTable();1523 try self.writeShdrTable();
1519 try zig_object.writeRelaSections(self);1524 try zig_object.writeRelaSections(self);
1520 try self.writeSymtabObject(zig_object);1525 try self.writeSymtabZigObject(zig_object);
1521 try self.writeShStrtab();1526 try self.writeShStrtab();
1522 try self.writeElfHeader();1527 try self.writeElfHeader();
1523 }1528 }
...@@ -3579,7 +3584,8 @@ fn sortInitFini(self: *Elf) !void {...@@ -3579,7 +3584,8 @@ fn sortInitFini(self: *Elf) !void {
35793584
3580 if (!is_init_fini and !is_ctor_dtor) continue;3585 if (!is_init_fini and !is_ctor_dtor) continue;
35813586
3582 const atom_list = self.output_sections.getPtr(@intCast(shndx)) orelse continue;3587 const atom_list = self.output_sections.getPtr(@intCast(shndx)).?;
3588 if (atom_list.items.len == 0) continue;
35833589
3584 var entries = std.ArrayList(Entry).init(gpa);3590 var entries = std.ArrayList(Entry).init(gpa);
3585 try entries.ensureTotalCapacityPrecise(atom_list.items.len);3591 try entries.ensureTotalCapacityPrecise(atom_list.items.len);
...@@ -3909,6 +3915,20 @@ fn sortShdrs(self: *Elf) !void {...@@ -3909,6 +3915,20 @@ fn sortShdrs(self: *Elf) !void {
3909 shdr.sh_info = backlinks[shdr.sh_info];3915 shdr.sh_info = backlinks[shdr.sh_info];
3910 }3916 }
39113917
3918 {
3919 var output_sections = try self.output_sections.clone(gpa);
3920 defer output_sections.deinit(gpa);
3921
3922 self.output_sections.clearRetainingCapacity();
3923
3924 var it = output_sections.iterator();
3925 while (it.next()) |entry| {
3926 const shndx = entry.key_ptr.*;
3927 const meta = entry.value_ptr.*;
3928 self.output_sections.putAssumeCapacityNoClobber(backlinks[shndx], meta);
3929 }
3930 }
3931
3912 {3932 {
3913 var last_atom_and_free_list_table = try self.last_atom_and_free_list_table.clone(gpa);3933 var last_atom_and_free_list_table = try self.last_atom_and_free_list_table.clone(gpa);
3914 defer last_atom_and_free_list_table.deinit(gpa);3934 defer last_atom_and_free_list_table.deinit(gpa);
...@@ -3962,7 +3982,6 @@ fn sortShdrs(self: *Elf) !void {...@@ -3962,7 +3982,6 @@ fn sortShdrs(self: *Elf) !void {
39623982
3963fn updateSectionSizes(self: *Elf) !void {3983fn updateSectionSizes(self: *Elf) !void {
3964 for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| {3984 for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| {
3965 if (atom_list.items.len == 0) continue;
3966 const shdr = &self.shdrs.items[shndx];3985 const shdr = &self.shdrs.items[shndx];
3967 for (atom_list.items) |atom_index| {3986 for (atom_list.items) |atom_index| {
3968 const atom_ptr = self.atom(atom_index) orelse continue;3987 const atom_ptr = self.atom(atom_index) orelse continue;
...@@ -4056,7 +4075,6 @@ fn updateSectionSizes(self: *Elf) !void {...@@ -4056,7 +4075,6 @@ fn updateSectionSizes(self: *Elf) !void {
40564075
4057fn updateSectionSizesObject(self: *Elf) !void {4076fn updateSectionSizesObject(self: *Elf) !void {
4058 for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| {4077 for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| {
4059 if (atom_list.items.len == 0) continue;
4060 const shdr = &self.shdrs.items[shndx];4078 const shdr = &self.shdrs.items[shndx];
4061 for (atom_list.items) |atom_index| {4079 for (atom_list.items) |atom_index| {
4062 const atom_ptr = self.atom(atom_index) orelse continue;4080 const atom_ptr = self.atom(atom_index) orelse continue;
...@@ -4317,7 +4335,6 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void {...@@ -4317,7 +4335,6 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void {
4317/// Allocates alloc sections when merging relocatable objects files together.4335/// Allocates alloc sections when merging relocatable objects files together.
4318fn allocateAllocSectionsObject(self: *Elf) !void {4336fn allocateAllocSectionsObject(self: *Elf) !void {
4319 _ = self;4337 _ = self;
4320 @panic("TODO");
4321}4338}
43224339
4323/// Allocates non-alloc sections (debug info, symtabs, etc.).4340/// Allocates non-alloc sections (debug info, symtabs, etc.).
...@@ -4444,6 +4461,7 @@ fn writeAtoms(self: *Elf) !void {...@@ -4444,6 +4461,7 @@ fn writeAtoms(self: *Elf) !void {
4444 if (shdr.sh_type == elf.SHT_NOBITS) continue;4461 if (shdr.sh_type == elf.SHT_NOBITS) continue;
44454462
4446 const atom_list = self.output_sections.get(@intCast(shndx)) orelse continue;4463 const atom_list = self.output_sections.get(@intCast(shndx)) orelse continue;
4464 if (atom_list.items.len == 0) continue;
44474465
4448 log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)});4466 log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)});
44494467
...@@ -4519,6 +4537,7 @@ fn writeAtomsObject(self: *Elf) !void {...@@ -4519,6 +4537,7 @@ fn writeAtomsObject(self: *Elf) !void {
4519 if (shdr.sh_type == elf.SHT_NOBITS) continue;4537 if (shdr.sh_type == elf.SHT_NOBITS) continue;
45204538
4521 const atom_list = self.output_sections.get(@intCast(shndx)) orelse continue;4539 const atom_list = self.output_sections.get(@intCast(shndx)) orelse continue;
4540 if (atom_list.items.len == 0) continue;
45224541
4523 log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)});4542 log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)});
45244543
...@@ -4617,6 +4636,11 @@ fn updateSymtabSize(self: *Elf) void {...@@ -4617,6 +4636,11 @@ fn updateSymtabSize(self: *Elf) void {
4617 sizes.add(file_ptr.linker_defined.output_symtab_size);4636 sizes.add(file_ptr.linker_defined.output_symtab_size);
4618 }4637 }
46194638
4639 // Section symbols
4640 for (self.output_sections.keys()) |_| {
4641 sizes.nlocals += 1;
4642 }
4643
4620 const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?];4644 const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?];
4621 symtab_shdr.sh_info = sizes.nlocals + 1;4645 symtab_shdr.sh_info = sizes.nlocals + 1;
4622 symtab_shdr.sh_link = self.strtab_section_index.?;4646 symtab_shdr.sh_link = self.strtab_section_index.?;
...@@ -4632,9 +4656,16 @@ fn updateSymtabSize(self: *Elf) void {...@@ -4632,9 +4656,16 @@ fn updateSymtabSize(self: *Elf) void {
4632 strtab.sh_size = sizes.strsize + 1;4656 strtab.sh_size = sizes.strsize + 1;
4633}4657}
46344658
4635fn updateSymtabSizeObject(self: *Elf, zig_object: *ZigObject) void {4659fn updateSymtabSizeZigObject(self: *Elf, zig_object: *ZigObject) void {
4660 var sizes = SymtabSize{};
4661
4636 zig_object.asFile().updateSymtabSize(self);4662 zig_object.asFile().updateSymtabSize(self);
4637 const sizes = zig_object.output_symtab_size;4663 sizes.add(zig_object.output_symtab_size);
4664
4665 // Section symbols
4666 for (self.output_sections.keys()) |_| {
4667 sizes.nlocals += 1;
4668 }
46384669
4639 const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?];4670 const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?];
4640 symtab_shdr.sh_info = sizes.nlocals + 1;4671 symtab_shdr.sh_info = sizes.nlocals + 1;
...@@ -4798,7 +4829,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void {...@@ -4798,7 +4829,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void {
4798 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);4829 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
4799 defer buffer.deinit();4830 defer buffer.deinit();
4800 try eh_frame.writeEhFrame(self, buffer.writer());4831 try eh_frame.writeEhFrame(self, buffer.writer());
4801 try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);4832 // try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
4802 }4833 }
48034834
4804 try self.writeSymtab();4835 try self.writeSymtab();
...@@ -4812,6 +4843,16 @@ fn writeShStrtab(self: *Elf) !void {...@@ -4812,6 +4843,16 @@ fn writeShStrtab(self: *Elf) !void {
4812 }4843 }
4813}4844}
48144845
4846const WriteSymtabCtx = struct {
4847 ilocal: usize,
4848 iglobal: usize,
4849
4850 fn incr(this: *@This(), ss: SymtabSize) void {
4851 this.ilocal += ss.nlocals;
4852 this.iglobal += ss.nglobals;
4853 }
4854};
4855
4815fn writeSymtab(self: *Elf) !void {4856fn writeSymtab(self: *Elf) !void {
4816 const gpa = self.base.allocator;4857 const gpa = self.base.allocator;
4817 const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];4858 const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];
...@@ -4828,20 +4869,13 @@ fn writeSymtab(self: *Elf) !void {...@@ -4828,20 +4869,13 @@ fn writeSymtab(self: *Elf) !void {
4828 const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow;4869 const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow;
4829 try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size);4870 try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size);
48304871
4831 const Ctx = struct {4872 var ctx: WriteSymtabCtx = .{
4832 ilocal: usize,
4833 iglobal: usize,
4834
4835 fn incr(this: *@This(), ss: SymtabSize) void {
4836 this.ilocal += ss.nlocals;
4837 this.iglobal += ss.nglobals;
4838 }
4839 };
4840 var ctx: Ctx = .{
4841 .ilocal = 1,4873 .ilocal = 1,
4842 .iglobal = symtab_shdr.sh_info,4874 .iglobal = symtab_shdr.sh_info,
4843 };4875 };
48444876
4877 ctx.incr(self.writeSectionSymbols(ctx));
4878
4845 if (self.zigObjectPtr()) |zig_object| {4879 if (self.zigObjectPtr()) |zig_object| {
4846 zig_object.asFile().writeSymtab(self, ctx);4880 zig_object.asFile().writeSymtab(self, ctx);
4847 ctx.incr(zig_object.output_symtab_size);4881 ctx.incr(zig_object.output_symtab_size);
...@@ -4915,7 +4949,7 @@ fn writeSymtab(self: *Elf) !void {...@@ -4915,7 +4949,7 @@ fn writeSymtab(self: *Elf) !void {
4915 try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);4949 try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);
4916}4950}
49174951
4918fn writeSymtabObject(self: *Elf, zig_object: *ZigObject) !void {4952fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void {
4919 const gpa = self.base.allocator;4953 const gpa = self.base.allocator;
4920 const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];4954 const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];
4921 const strtab_shdr = self.shdrs.items[self.strtab_section_index.?];4955 const strtab_shdr = self.shdrs.items[self.strtab_section_index.?];
...@@ -4931,7 +4965,15 @@ fn writeSymtabObject(self: *Elf, zig_object: *ZigObject) !void {...@@ -4931,7 +4965,15 @@ fn writeSymtabObject(self: *Elf, zig_object: *ZigObject) !void {
4931 const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow;4965 const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow;
4932 try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size);4966 try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size);
49334967
4934 zig_object.asFile().writeSymtab(self, .{ .ilocal = 1, .iglobal = symtab_shdr.sh_info });4968 var ctx: WriteSymtabCtx = .{
4969 .ilocal = 1,
4970 .iglobal = symtab_shdr.sh_info,
4971 };
4972
4973 ctx.incr(self.writeSectionSymbols(ctx));
4974
4975 zig_object.asFile().writeSymtab(self, ctx);
4976 ctx.incr(zig_object.output_symtab_size);
49354977
4936 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();4978 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
4937 switch (self.ptr_width) {4979 switch (self.ptr_width) {
...@@ -4963,6 +5005,24 @@ fn writeSymtabObject(self: *Elf, zig_object: *ZigObject) !void {...@@ -4963,6 +5005,24 @@ fn writeSymtabObject(self: *Elf, zig_object: *ZigObject) !void {
4963 try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);5005 try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset);
4964}5006}
49655007
5008fn writeSectionSymbols(self: *Elf, ctx: WriteSymtabCtx) SymtabSize {
5009 var ilocal = ctx.ilocal;
5010 for (self.output_sections.keys()) |shndx| {
5011 const shdr = self.shdrs.items[shndx];
5012 const out_sym = &self.symtab.items[ilocal];
5013 out_sym.* = .{
5014 .st_name = 0,
5015 .st_value = shdr.sh_addr,
5016 .st_info = elf.STT_SECTION,
5017 .st_shndx = @intCast(shndx),
5018 .st_size = 0,
5019 .st_other = 0,
5020 };
5021 ilocal += 1;
5022 }
5023 return .{ .nlocals = @intCast(ilocal - ctx.ilocal) };
5024}
5025
4966/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.5026/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.
4967fn ptrWidthBytes(self: Elf) u8 {5027fn ptrWidthBytes(self: Elf) u8 {
4968 return switch (self.ptr_width) {5028 return switch (self.ptr_width) {
src/link/Elf/Atom.zig+8-2
...@@ -60,6 +60,11 @@ pub fn inputShdr(self: Atom, elf_file: *Elf) Object.ElfShdr {...@@ -60,6 +60,11 @@ pub fn inputShdr(self: Atom, elf_file: *Elf) Object.ElfShdr {
60 };60 };
61}61}
6262
63pub fn relocsShndx(self: Atom) ?u32 {
64 if (self.relocs_section_index == 0) return null;
65 return self.relocs_section_index;
66}
67
63pub fn outputShndx(self: Atom) ?u16 {68pub fn outputShndx(self: Atom) ?u16 {
64 if (self.output_section_index == 0) return null;69 if (self.output_section_index == 0) return null;
65 return self.output_section_index;70 return self.output_section_index;
...@@ -280,9 +285,10 @@ pub fn free(self: *Atom, elf_file: *Elf) void {...@@ -280,9 +285,10 @@ pub fn free(self: *Atom, elf_file: *Elf) void {
280}285}
281286
282pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela {287pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela {
288 const shndx = self.relocsShndx() orelse return &[0]elf.Elf64_Rela{};
283 return switch (self.file(elf_file).?) {289 return switch (self.file(elf_file).?) {
284 .zig_object => |x| x.relocs.items[self.relocs_section_index].items,290 .zig_object => |x| x.relocs.items[shndx].items,
285 .object => |x| x.getRelocs(self.relocs_section_index),291 .object => |x| x.getRelocs(shndx),
286 else => unreachable,292 else => unreachable,
287 };293 };
288}294}
src/link/Elf/Object.zig+12-3
...@@ -211,6 +211,7 @@ fn addAtom(self: *Object, shdr: ElfShdr, shndx: u16, elf_file: *Elf) error{OutOf...@@ -211,6 +211,7 @@ fn addAtom(self: *Object, shdr: ElfShdr, shndx: u16, elf_file: *Elf) error{OutOf
211fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMemory}!u16 {211fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMemory}!u16 {
212 const name = blk: {212 const name = blk: {
213 const name = self.getString(shdr.sh_name);213 const name = self.getString(shdr.sh_name);
214 if (elf_file.isRelocatable()) break :blk name;
214 if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name;215 if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name;
215 const sh_name_prefixes: []const [:0]const u8 = &.{216 const sh_name_prefixes: []const [:0]const u8 = &.{
216 ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss",217 ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss",
...@@ -237,7 +238,10 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMem...@@ -237,7 +238,10 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMem
237 else => shdr.sh_type,238 else => shdr.sh_type,
238 };239 };
239 const flags = blk: {240 const flags = blk: {
240 const flags = shdr.sh_flags & ~@as(u64, elf.SHF_COMPRESSED | elf.SHF_GROUP | elf.SHF_GNU_RETAIN);241 var flags = shdr.sh_flags;
242 if (!elf_file.isRelocatable()) {
243 flags &= ~@as(u64, elf.SHF_COMPRESSED | elf.SHF_GROUP | elf.SHF_GNU_RETAIN);
244 }
241 break :blk switch (@"type") {245 break :blk switch (@"type") {
242 elf.SHT_INIT_ARRAY, elf.SHT_FINI_ARRAY => flags | elf.SHF_WRITE,246 elf.SHT_INIT_ARRAY, elf.SHT_FINI_ARRAY => flags | elf.SHF_WRITE,
243 else => flags,247 else => flags,
...@@ -655,8 +659,13 @@ pub fn allocateAtoms(self: Object, elf_file: *Elf) void {...@@ -655,8 +659,13 @@ pub fn allocateAtoms(self: Object, elf_file: *Elf) void {
655}659}
656660
657pub fn initRelaSections(self: Object, elf_file: *Elf) !void {661pub fn initRelaSections(self: Object, elf_file: *Elf) !void {
658 _ = self;662 for (self.atoms.items) |atom_index| {
659 _ = elf_file;663 const atom = elf_file.atom(atom_index) orelse continue;
664 if (!atom.flags.alive) continue;
665 const shndx = atom.relocsShndx() orelse continue;
666 const shdr = self.shdrs.items[shndx];
667 _ = try self.initOutputSection(elf_file, shdr);
668 }
660}669}
661670
662pub fn updateRelaSectionsSizes(self: Object, elf_file: *Elf) void {671pub fn updateRelaSectionsSizes(self: Object, elf_file: *Elf) void {
src/link/Elf/Symbol.zig-2
...@@ -219,8 +219,6 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {...@@ -219,8 +219,6 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
219 const st_shndx = blk: {219 const st_shndx = blk: {
220 if (symbol.flags.has_copy_rel) break :blk elf_file.copy_rel_section_index.?;220 if (symbol.flags.has_copy_rel) break :blk elf_file.copy_rel_section_index.?;
221 if (file_ptr == .shared_object or esym.st_shndx == elf.SHN_UNDEF) break :blk elf.SHN_UNDEF;221 if (file_ptr == .shared_object or esym.st_shndx == elf.SHN_UNDEF) break :blk elf.SHN_UNDEF;
222 // TODO I think this is wrong and obsolete
223 if (elf_file.isRelocatable() and st_type == elf.STT_SECTION) break :blk symbol.outputShndx().?;
224 if (symbol.atom(elf_file) == null and file_ptr != .linker_defined)222 if (symbol.atom(elf_file) == null and file_ptr != .linker_defined)
225 break :blk elf.SHN_ABS;223 break :blk elf.SHN_ABS;
226 break :blk symbol.outputShndx() orelse elf.SHN_UNDEF;224 break :blk symbol.outputShndx() orelse elf.SHN_UNDEF;
src/link/Elf/ZigObject.zig-16
...@@ -287,22 +287,6 @@ pub fn addAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index {...@@ -287,22 +287,6 @@ pub fn addAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index {
287 return symbol_index;287 return symbol_index;
288}288}
289289
290pub fn addSectionSymbol(self: *ZigObject, shndx: u16, elf_file: *Elf) !void {
291 assert(elf_file.isRelocatable());
292 const gpa = elf_file.base.allocator;
293 const symbol_index = try elf_file.addSymbol();
294 try self.local_symbols.append(gpa, symbol_index);
295 const symbol_ptr = elf_file.symbol(symbol_index);
296 symbol_ptr.file_index = self.index;
297 symbol_ptr.output_section_index = shndx;
298
299 const esym_index = try self.addLocalEsym(gpa);
300 const esym = &self.local_esyms.items(.elf_sym)[esym_index];
301 esym.st_info = elf.STT_SECTION;
302 esym.st_shndx = shndx;
303 symbol_ptr.esym_index = esym_index;
304}
305
306/// TODO actually create fake input shdrs and return that instead.290/// TODO actually create fake input shdrs and return that instead.
307pub fn inputShdr(self: ZigObject, atom_index: Atom.Index, elf_file: *Elf) Object.ElfShdr {291pub fn inputShdr(self: ZigObject, atom_index: Atom.Index, elf_file: *Elf) Object.ElfShdr {
308 _ = self;292 _ = self;
src/link/Elf/file.zig+1-2
...@@ -136,8 +136,7 @@ pub const File = union(enum) {...@@ -136,8 +136,7 @@ pub const File = union(enum) {
136 if (local.atom(elf_file)) |atom| if (!atom.flags.alive) continue;136 if (local.atom(elf_file)) |atom| if (!atom.flags.alive) continue;
137 const esym = local.elfSym(elf_file);137 const esym = local.elfSym(elf_file);
138 switch (esym.st_type()) {138 switch (esym.st_type()) {
139 elf.STT_SECTION => if (!elf_file.isRelocatable()) continue,139 elf.STT_SECTION, elf.STT_NOTYPE => continue,
140 elf.STT_NOTYPE => continue,
141 else => {},140 else => {},
142 }141 }
143 local.flags.output_symtab = true;142 local.flags.output_symtab = true;