authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-01 16:52:52+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-04 09:09:01+01:00
logabf6c20cb93f9b9b9b3ef0d935bd1e12063f4c36
treef8814a3fe4808816ed1660b8b534ce2b6c023c4c
parentb1136a695f5cc463bafd6727ff5bb60d618d8ce9

elf: rename .rodata to .data.rel.ro and remove allocateAllocSection helper


2 files changed, 161 insertions(+), 125 deletions(-)

src/link/Elf.zig+156-120
...@@ -104,7 +104,7 @@ zig_got: ZigGotSection = .{},...@@ -104,7 +104,7 @@ zig_got: ZigGotSection = .{},
104104
105/// Tracked section headers with incremental updates to Zig object105/// Tracked section headers with incremental updates to Zig object
106zig_text_section_index: ?u16 = null,106zig_text_section_index: ?u16 = null,
107zig_rodata_section_index: ?u16 = null,107zig_data_rel_ro_section_index: ?u16 = null,
108zig_data_section_index: ?u16 = null,108zig_data_section_index: ?u16 = null,
109zig_bss_section_index: ?u16 = null,109zig_bss_section_index: ?u16 = null,
110zig_got_section_index: ?u16 = null,110zig_got_section_index: ?u16 = null,
...@@ -484,40 +484,6 @@ fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) u64 {...@@ -484,40 +484,6 @@ fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) u64 {
484 return start;484 return start;
485}485}
486486
487const AllocateAllocSectionOpts = struct {
488 name: [:0]const u8,
489 phdr_index: u16,
490 alignment: u64 = 1,
491 flags: u64 = elf.SHF_ALLOC,
492 type: u32 = elf.SHT_PROGBITS,
493};
494
495pub fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{OutOfMemory}!u16 {
496 const gpa = self.base.allocator;
497 const phdr = &self.phdrs.items[opts.phdr_index];
498 const index = try self.addSection(.{
499 .name = opts.name,
500 .type = opts.type,
501 .flags = opts.flags,
502 .addralign = opts.alignment,
503 .offset = std.math.maxInt(u64),
504 });
505 const shdr = &self.shdrs.items[index];
506 try self.phdr_to_shdr_table.putNoClobber(gpa, index, opts.phdr_index);
507 log.debug("allocating '{s}' in phdr({d}) from 0x{x} to 0x{x} (0x{x} - 0x{x})", .{
508 opts.name,
509 opts.phdr_index,
510 phdr.p_offset,
511 phdr.p_offset + phdr.p_filesz,
512 phdr.p_vaddr,
513 phdr.p_vaddr + phdr.p_memsz,
514 });
515 shdr.sh_addr = phdr.p_vaddr;
516 shdr.sh_offset = phdr.p_offset;
517 shdr.sh_size = phdr.p_memsz;
518 return index;
519}
520
521const AllocateNonAllocSectionOpts = struct {487const AllocateNonAllocSectionOpts = struct {
522 name: [:0]const u8,488 name: [:0]const u8,
523 size: u64,489 size: u64,
...@@ -557,123 +523,193 @@ pub fn initMetadata(self: *Elf) !void {...@@ -557,123 +523,193 @@ pub fn initMetadata(self: *Elf) !void {
557523
558 comptime assert(number_of_zig_segments == 5);524 comptime assert(number_of_zig_segments == 5);
559525
560 if (self.phdr_zig_load_re_index == null) {526 if (!self.isObject()) {
561 const filesz = self.base.options.program_code_size_hint;527 if (self.phdr_zig_load_re_index == null) {
562 const off = self.findFreeSpace(filesz, self.page_size);528 const filesz = self.base.options.program_code_size_hint;
563 self.phdr_zig_load_re_index = try self.addPhdr(.{529 const off = self.findFreeSpace(filesz, self.page_size);
564 .type = elf.PT_LOAD,530 self.phdr_zig_load_re_index = try self.addPhdr(.{
565 .offset = off,531 .type = elf.PT_LOAD,
566 .filesz = filesz,532 .offset = off,
567 .addr = if (ptr_bit_width >= 32) 0x8000000 else 0x8000,533 .filesz = filesz,
568 .memsz = filesz,534 .addr = if (ptr_bit_width >= 32) 0x8000000 else 0x8000,
569 .@"align" = self.page_size,535 .memsz = filesz,
570 .flags = elf.PF_X | elf.PF_R | elf.PF_W,536 .@"align" = self.page_size,
571 });537 .flags = elf.PF_X | elf.PF_R | elf.PF_W,
572 }538 });
539 }
573540
574 if (self.phdr_zig_got_index == null) {541 if (self.phdr_zig_got_index == null) {
575 // We really only need ptr alignment but since we are using PROGBITS, linux requires542 // We really only need ptr alignment but since we are using PROGBITS, linux requires
576 // page align.543 // page align.
577 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);544 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
578 const filesz = @as(u64, ptr_size) * self.base.options.symbol_count_hint;545 const filesz = @as(u64, ptr_size) * self.base.options.symbol_count_hint;
579 const off = self.findFreeSpace(filesz, alignment);546 const off = self.findFreeSpace(filesz, alignment);
580 self.phdr_zig_got_index = try self.addPhdr(.{547 self.phdr_zig_got_index = try self.addPhdr(.{
581 .type = elf.PT_LOAD,548 .type = elf.PT_LOAD,
582 .offset = off,549 .offset = off,
583 .filesz = filesz,550 .filesz = filesz,
584 .addr = if (ptr_bit_width >= 32) 0x4000000 else 0x4000,551 .addr = if (ptr_bit_width >= 32) 0x4000000 else 0x4000,
585 .memsz = filesz,552 .memsz = filesz,
586 .@"align" = alignment,553 .@"align" = alignment,
587 .flags = elf.PF_R | elf.PF_W,554 .flags = elf.PF_R | elf.PF_W,
588 });555 });
589 }556 }
590557
591 if (self.phdr_zig_load_ro_index == null) {558 if (self.phdr_zig_load_ro_index == null) {
592 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);559 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
593 const filesz: u64 = 1024;560 const filesz: u64 = 1024;
594 const off = self.findFreeSpace(filesz, alignment);561 const off = self.findFreeSpace(filesz, alignment);
595 self.phdr_zig_load_ro_index = try self.addPhdr(.{562 self.phdr_zig_load_ro_index = try self.addPhdr(.{
596 .type = elf.PT_LOAD,563 .type = elf.PT_LOAD,
597 .offset = off,564 .offset = off,
598 .filesz = filesz,565 .filesz = filesz,
599 .addr = if (ptr_bit_width >= 32) 0xc000000 else 0xa000,566 .addr = if (ptr_bit_width >= 32) 0xc000000 else 0xa000,
600 .memsz = filesz,567 .memsz = filesz,
601 .@"align" = alignment,568 .@"align" = alignment,
602 .flags = elf.PF_R | elf.PF_W,569 .flags = elf.PF_R | elf.PF_W,
603 });570 });
604 }571 }
605572
606 if (self.phdr_zig_load_rw_index == null) {573 if (self.phdr_zig_load_rw_index == null) {
607 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);574 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
608 const filesz: u64 = 1024;575 const filesz: u64 = 1024;
609 const off = self.findFreeSpace(filesz, alignment);576 const off = self.findFreeSpace(filesz, alignment);
610 self.phdr_zig_load_rw_index = try self.addPhdr(.{577 self.phdr_zig_load_rw_index = try self.addPhdr(.{
611 .type = elf.PT_LOAD,578 .type = elf.PT_LOAD,
612 .offset = off,579 .offset = off,
613 .filesz = filesz,580 .filesz = filesz,
614 .addr = if (ptr_bit_width >= 32) 0x10000000 else 0xc000,581 .addr = if (ptr_bit_width >= 32) 0x10000000 else 0xc000,
615 .memsz = filesz,582 .memsz = filesz,
616 .@"align" = alignment,583 .@"align" = alignment,
617 .flags = elf.PF_R | elf.PF_W,584 .flags = elf.PF_R | elf.PF_W,
618 });585 });
619 }586 }
620587
621 if (self.phdr_zig_load_zerofill_index == null) {588 if (self.phdr_zig_load_zerofill_index == null) {
622 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);589 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
623 self.phdr_zig_load_zerofill_index = try self.addPhdr(.{590 self.phdr_zig_load_zerofill_index = try self.addPhdr(.{
624 .type = elf.PT_LOAD,591 .type = elf.PT_LOAD,
625 .addr = if (ptr_bit_width >= 32) 0x14000000 else 0xf000,592 .addr = if (ptr_bit_width >= 32) 0x14000000 else 0xf000,
626 .memsz = 1024,593 .memsz = 1024,
627 .@"align" = alignment,594 .@"align" = alignment,
628 .flags = elf.PF_R | elf.PF_W,595 .flags = elf.PF_R | elf.PF_W,
629 });596 });
597 }
630 }598 }
631599
632 if (self.zig_text_section_index == null) {600 if (self.zig_text_section_index == null) {
633 self.zig_text_section_index = try self.allocateAllocSection(.{601 self.zig_text_section_index = try self.addSection(.{
634 .name = ".zig.text",602 .name = ".zig.text",
635 .phdr_index = self.phdr_zig_load_re_index.?,603 .type = elf.SHT_PROGBITS,
636 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,604 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
605 .addralign = 1,
606 .offset = std.math.maxInt(u64),
637 });607 });
608 const shdr = &self.shdrs.items[self.zig_text_section_index.?];
609 if (self.phdr_zig_load_re_index) |phndx| {
610 const phdr = self.phdrs.items[phndx];
611 shdr.sh_addr = phdr.p_vaddr;
612 shdr.sh_offset = phdr.p_offset;
613 shdr.sh_size = phdr.p_memsz;
614 try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_text_section_index.?, phndx);
615 } else {
616 const size = self.base.options.program_code_size_hint;
617 const off = self.findFreeSpace(size, 1);
618 shdr.sh_offset = off;
619 shdr.sh_size = size;
620 }
638 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});621 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});
639 }622 }
640623
641 if (self.zig_got_section_index == null) {624 if (self.zig_got_section_index == null) {
642 self.zig_got_section_index = try self.allocateAllocSection(.{625 // TODO we don't actually need this section in a relocatable object file
626 self.zig_got_section_index = try self.addSection(.{
643 .name = ".zig.got",627 .name = ".zig.got",
644 .phdr_index = self.phdr_zig_got_index.?,628 .type = elf.SHT_PROGBITS,
645 .alignment = ptr_size,629 .addralign = ptr_size,
646 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,630 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
631 .offset = std.math.maxInt(u64),
647 });632 });
633 const shdr = &self.shdrs.items[self.zig_got_section_index.?];
634 if (self.phdr_zig_got_index) |phndx| {
635 const phdr = self.phdrs.items[phndx];
636 shdr.sh_addr = phdr.p_vaddr;
637 shdr.sh_offset = phdr.p_offset;
638 shdr.sh_size = phdr.p_memsz;
639 try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_got_section_index.?, phndx);
640 } else {
641 const size = @as(u64, ptr_size) * self.base.options.symbol_count_hint;
642 const off = self.findFreeSpace(size, ptr_size);
643 shdr.sh_offset = off;
644 shdr.sh_size = size;
645 }
648 }646 }
649647
650 if (self.zig_rodata_section_index == null) {648 if (self.zig_data_rel_ro_section_index == null) {
651 self.zig_rodata_section_index = try self.allocateAllocSection(.{649 self.zig_data_rel_ro_section_index = try self.addSection(.{
652 .name = ".zig.rodata",650 .name = ".zig.data.rel.ro",
653 .phdr_index = self.phdr_zig_load_ro_index.?,651 .type = elf.SHT_PROGBITS,
652 .addralign = 1,
654 .flags = elf.SHF_ALLOC | elf.SHF_WRITE, // TODO rename this section to .data.rel.ro653 .flags = elf.SHF_ALLOC | elf.SHF_WRITE, // TODO rename this section to .data.rel.ro
654 .offset = std.math.maxInt(u64),
655 });655 });
656 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_rodata_section_index.?, .{});656 const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?];
657 if (self.phdr_zig_load_ro_index) |phndx| {
658 const phdr = self.phdrs.items[phndx];
659 shdr.sh_addr = phdr.p_vaddr;
660 shdr.sh_offset = phdr.p_offset;
661 shdr.sh_size = phdr.p_memsz;
662 try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, phndx);
663 } else {
664 const size: u64 = 1024;
665 const off = self.findFreeSpace(size, 1);
666 shdr.sh_offset = off;
667 shdr.sh_size = size;
668 }
669 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, .{});
657 }670 }
658671
659 if (self.zig_data_section_index == null) {672 if (self.zig_data_section_index == null) {
660 self.zig_data_section_index = try self.allocateAllocSection(.{673 self.zig_data_section_index = try self.addSection(.{
661 .name = ".zig.data",674 .name = ".zig.data",
662 .phdr_index = self.phdr_zig_load_rw_index.?,675 .type = elf.SHT_PROGBITS,
663 .alignment = ptr_size,676 .addralign = ptr_size,
664 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,677 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
678 .offset = std.math.maxInt(u64),
665 });679 });
680 const shdr = &self.shdrs.items[self.zig_data_section_index.?];
681 if (self.phdr_zig_load_rw_index) |phndx| {
682 const phdr = self.phdrs.items[phndx];
683 shdr.sh_addr = phdr.p_vaddr;
684 shdr.sh_offset = phdr.p_offset;
685 shdr.sh_size = phdr.p_memsz;
686 try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_data_section_index.?, phndx);
687 } else {
688 const size: u64 = 1024;
689 const off = self.findFreeSpace(size, ptr_size);
690 shdr.sh_offset = off;
691 shdr.sh_size = size;
692 }
666 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_section_index.?, .{});693 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_section_index.?, .{});
667 }694 }
668695
669 if (self.zig_bss_section_index == null) {696 if (self.zig_bss_section_index == null) {
670 self.zig_bss_section_index = try self.allocateAllocSection(.{697 self.zig_bss_section_index = try self.addSection(.{
671 .name = ".zig.bss",698 .name = ".zig.bss",
672 .phdr_index = self.phdr_zig_load_zerofill_index.?,
673 .alignment = ptr_size,
674 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
675 .type = elf.SHT_NOBITS,699 .type = elf.SHT_NOBITS,
700 .addralign = ptr_size,
701 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
702 .offset = 0,
676 });703 });
704 const shdr = &self.shdrs.items[self.zig_bss_section_index.?];
705 if (self.phdr_zig_load_zerofill_index) |phndx| {
706 const phdr = self.phdrs.items[phndx];
707 shdr.sh_addr = phdr.p_vaddr;
708 shdr.sh_size = phdr.p_memsz;
709 try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_bss_section_index.?, phndx);
710 } else {
711 shdr.sh_size = 1024;
712 }
677 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{});713 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{});
678 }714 }
679715
...@@ -3628,7 +3664,7 @@ fn sortShdrs(self: *Elf) !void {...@@ -3628,7 +3664,7 @@ fn sortShdrs(self: *Elf) !void {
3628 &self.verneed_section_index,3664 &self.verneed_section_index,
3629 &self.zig_text_section_index,3665 &self.zig_text_section_index,
3630 &self.zig_got_section_index,3666 &self.zig_got_section_index,
3631 &self.zig_rodata_section_index,3667 &self.zig_data_rel_ro_section_index,
3632 &self.zig_data_section_index,3668 &self.zig_data_section_index,
3633 &self.zig_bss_section_index,3669 &self.zig_bss_section_index,
3634 &self.debug_str_section_index,3670 &self.debug_str_section_index,
...@@ -4856,7 +4892,7 @@ pub fn isDynLib(self: Elf) bool {...@@ -4856,7 +4892,7 @@ pub fn isDynLib(self: Elf) bool {
4856pub fn isZigSection(self: Elf, shndx: u16) bool {4892pub fn isZigSection(self: Elf, shndx: u16) bool {
4857 inline for (&[_]?u16{4893 inline for (&[_]?u16{
4858 self.zig_text_section_index,4894 self.zig_text_section_index,
4859 self.zig_rodata_section_index,4895 self.zig_data_rel_ro_section_index,
4860 self.zig_data_section_index,4896 self.zig_data_section_index,
4861 self.zig_bss_section_index,4897 self.zig_bss_section_index,
4862 self.zig_got_section_index,4898 self.zig_got_section_index,
src/link/Elf/ZigObject.zig+5-5
...@@ -510,7 +510,7 @@ pub fn lowerAnonDecl(...@@ -510,7 +510,7 @@ pub fn lowerAnonDecl(
510 name,510 name,
511 tv,511 tv,
512 decl_alignment,512 decl_alignment,
513 elf_file.zig_rodata_section_index.?,513 elf_file.zig_data_rel_ro_section_index.?,
514 src_loc,514 src_loc,
515 ) catch |err| switch (err) {515 ) catch |err| switch (err) {
516 error.OutOfMemory => return error.OutOfMemory,516 error.OutOfMemory => return error.OutOfMemory,
...@@ -622,7 +622,7 @@ fn getDeclShdrIndex(self: *ZigObject, elf_file: *Elf, decl_index: Module.Decl.In...@@ -622,7 +622,7 @@ fn getDeclShdrIndex(self: *ZigObject, elf_file: *Elf, decl_index: Module.Decl.In
622 .Fn => elf_file.zig_text_section_index.?,622 .Fn => elf_file.zig_text_section_index.?,
623 else => blk: {623 else => blk: {
624 if (decl.getOwnedVariable(mod)) |variable| {624 if (decl.getOwnedVariable(mod)) |variable| {
625 if (variable.is_const) break :blk elf_file.zig_rodata_section_index.?;625 if (variable.is_const) break :blk elf_file.zig_data_rel_ro_section_index.?;
626 if (variable.init.toValue().isUndefDeep(mod)) {626 if (variable.init.toValue().isUndefDeep(mod)) {
627 const mode = elf_file.base.options.optimize_mode;627 const mode = elf_file.base.options.optimize_mode;
628 if (mode == .Debug or mode == .ReleaseSafe) break :blk elf_file.zig_data_section_index.?;628 if (mode == .Debug or mode == .ReleaseSafe) break :blk elf_file.zig_data_section_index.?;
...@@ -636,7 +636,7 @@ fn getDeclShdrIndex(self: *ZigObject, elf_file: *Elf, decl_index: Module.Decl.In...@@ -636,7 +636,7 @@ fn getDeclShdrIndex(self: *ZigObject, elf_file: *Elf, decl_index: Module.Decl.In
636 if (is_all_zeroes) break :blk elf_file.zig_bss_section_index.?;636 if (is_all_zeroes) break :blk elf_file.zig_bss_section_index.?;
637 break :blk elf_file.zig_data_section_index.?;637 break :blk elf_file.zig_data_section_index.?;
638 }638 }
639 break :blk elf_file.zig_rodata_section_index.?;639 break :blk elf_file.zig_data_rel_ro_section_index.?;
640 },640 },
641 };641 };
642 return shdr_index;642 return shdr_index;
...@@ -937,7 +937,7 @@ fn updateLazySymbol(...@@ -937,7 +937,7 @@ fn updateLazySymbol(
937937
938 const output_section_index = switch (sym.kind) {938 const output_section_index = switch (sym.kind) {
939 .code => elf_file.zig_text_section_index.?,939 .code => elf_file.zig_text_section_index.?,
940 .const_data => elf_file.zig_rodata_section_index.?,940 .const_data => elf_file.zig_data_rel_ro_section_index.?,
941 };941 };
942 const local_sym = elf_file.symbol(symbol_index);942 const local_sym = elf_file.symbol(symbol_index);
943 const phdr_index = elf_file.phdr_to_shdr_table.get(output_section_index).?;943 const phdr_index = elf_file.phdr_to_shdr_table.get(output_section_index).?;
...@@ -991,7 +991,7 @@ pub fn lowerUnnamedConst(...@@ -991,7 +991,7 @@ pub fn lowerUnnamedConst(
991 name,991 name,
992 typed_value,992 typed_value,
993 typed_value.ty.abiAlignment(mod),993 typed_value.ty.abiAlignment(mod),
994 elf_file.zig_rodata_section_index.?,994 elf_file.zig_data_rel_ro_section_index.?,
995 decl.srcLoc(mod),995 decl.srcLoc(mod),
996 )) {996 )) {
997 .ok => |sym_index| sym_index,997 .ok => |sym_index| sym_index,