| ... | @@ -528,7 +528,7 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 { | ... | @@ -528,7 +528,7 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 { |
| 528 | return start; | 528 | return start; |
| 529 | } | 529 | } |
| 530 | | 530 | |
| 531 | pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { | 531 | pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64, min_alignment: u64) !void { |
| 532 | const slice = self.sections.slice(); | 532 | const slice = self.sections.slice(); |
| 533 | const shdr = &slice.items(.shdr)[shdr_index]; | 533 | const shdr = &slice.items(.shdr)[shdr_index]; |
| 534 | assert(shdr.sh_flags & elf.SHF_ALLOC != 0); | 534 | assert(shdr.sh_flags & elf.SHF_ALLOC != 0); |
| ... | @@ -547,8 +547,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { | ... | @@ -547,8 +547,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { |
| 547 | const existing_size = shdr.sh_size; | 547 | const existing_size = shdr.sh_size; |
| 548 | shdr.sh_size = 0; | 548 | shdr.sh_size = 0; |
| 549 | // Must move the entire section. | 549 | // Must move the entire section. |
| 550 | const alignment = if (maybe_phdr) |phdr| phdr.p_align else shdr.sh_addralign; | 550 | const new_offset = try self.findFreeSpace(needed_size, min_alignment); |
| 551 | const new_offset = try self.findFreeSpace(needed_size, alignment); | | |
| 552 | | 551 | |
| 553 | log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{ | 552 | log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{ |
| 554 | self.getShString(shdr.sh_name), | 553 | self.getShString(shdr.sh_name), |
| ... | @@ -588,7 +587,7 @@ pub fn growNonAllocSection( | ... | @@ -588,7 +587,7 @@ pub fn growNonAllocSection( |
| 588 | self: *Elf, | 587 | self: *Elf, |
| 589 | shdr_index: u32, | 588 | shdr_index: u32, |
| 590 | needed_size: u64, | 589 | needed_size: u64, |
| 591 | min_alignment: u32, | 590 | min_alignment: u64, |
| 592 | requires_file_copy: bool, | 591 | requires_file_copy: bool, |
| 593 | ) !void { | 592 | ) !void { |
| 594 | const shdr = &self.sections.items(.shdr)[shdr_index]; | 593 | const shdr = &self.sections.items(.shdr)[shdr_index]; |
| ... | @@ -728,9 +727,9 @@ pub fn allocateChunk(self: *Elf, shndx: u32, size: u64, alignment: Atom.Alignmen | ... | @@ -728,9 +727,9 @@ pub fn allocateChunk(self: *Elf, shndx: u32, size: u64, alignment: Atom.Alignmen |
| 728 | if (expand_section) { | 727 | if (expand_section) { |
| 729 | const needed_size = res.value + size; | 728 | const needed_size = res.value + size; |
| 730 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) | 729 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) |
| 731 | try self.growAllocSection(shndx, needed_size) | 730 | try self.growAllocSection(shndx, needed_size, alignment.toByteUnits().?) |
| 732 | else | 731 | else |
| 733 | try self.growNonAllocSection(shndx, needed_size, @intCast(alignment.toByteUnits().?), true); | 732 | try self.growNonAllocSection(shndx, needed_size, alignment.toByteUnits().?, true); |
| 734 | } | 733 | } |
| 735 | | 734 | |
| 736 | return res; | 735 | return res; |
| ... | @@ -1831,8 +1830,8 @@ pub fn initOutputSection(self: *Elf, args: struct { | ... | @@ -1831,8 +1830,8 @@ pub fn initOutputSection(self: *Elf, args: struct { |
| 1831 | break :blk args.name; | 1830 | break :blk args.name; |
| 1832 | }; | 1831 | }; |
| 1833 | const @"type" = tt: { | 1832 | const @"type" = tt: { |
| 1834 | if (self.getTarget().cpu.arch == .x86_64 and | 1833 | if (self.getTarget().cpu.arch == .x86_64 and args.type == elf.SHT_X86_64_UNWIND) |
| 1835 | args.type == elf.SHT_X86_64_UNWIND) break :tt elf.SHT_PROGBITS; | 1834 | break :tt elf.SHT_PROGBITS; |
| 1836 | switch (args.type) { | 1835 | switch (args.type) { |
| 1837 | elf.SHT_NULL => unreachable, | 1836 | elf.SHT_NULL => unreachable, |
| 1838 | elf.SHT_PROGBITS => { | 1837 | elf.SHT_PROGBITS => { |
| ... | @@ -2896,21 +2895,28 @@ fn initSyntheticSections(self: *Elf) !void { | ... | @@ -2896,21 +2895,28 @@ fn initSyntheticSections(self: *Elf) !void { |
| 2896 | const target = self.getTarget(); | 2895 | const target = self.getTarget(); |
| 2897 | const ptr_size = self.ptrWidthBytes(); | 2896 | const ptr_size = self.ptrWidthBytes(); |
| 2898 | | 2897 | |
| 2899 | const needs_eh_frame = for (self.objects.items) |index| { | 2898 | const needs_eh_frame = if (self.zigObjectPtr()) |zo| |
| | 2899 | zo.eh_frame_index != null |
| | 2900 | else for (self.objects.items) |index| { |
| 2900 | if (self.file(index).?.object.cies.items.len > 0) break true; | 2901 | if (self.file(index).?.object.cies.items.len > 0) break true; |
| 2901 | } else false; | 2902 | } else false; |
| 2902 | if (needs_eh_frame) { | 2903 | if (needs_eh_frame) { |
| 2903 | if (self.eh_frame_section_index == null) { | 2904 | if (self.eh_frame_section_index == null) { |
| 2904 | self.eh_frame_section_index = try self.addSection(.{ | 2905 | self.eh_frame_section_index = blk: { |
| 2905 | .name = try self.insertShString(".eh_frame"), | 2906 | if (self.zigObjectPtr()) |zo| { |
| 2906 | .type = if (target.cpu.arch == .x86_64) | 2907 | if (zo.eh_frame_index) |idx| break :blk zo.symbol(idx).atom(self).?.output_section_index; |
| 2907 | elf.SHT_X86_64_UNWIND | 2908 | } |
| 2908 | else | 2909 | break :blk try self.addSection(.{ |
| 2909 | elf.SHT_PROGBITS, | 2910 | .name = try self.insertShString(".eh_frame"), |
| 2910 | .flags = elf.SHF_ALLOC, | 2911 | .type = if (target.cpu.arch == .x86_64) |
| 2911 | .addralign = ptr_size, | 2912 | elf.SHT_X86_64_UNWIND |
| 2912 | .offset = std.math.maxInt(u64), | 2913 | else |
| 2913 | }); | 2914 | elf.SHT_PROGBITS, |
| | 2915 | .flags = elf.SHF_ALLOC, |
| | 2916 | .addralign = ptr_size, |
| | 2917 | .offset = std.math.maxInt(u64), |
| | 2918 | }); |
| | 2919 | }; |
| 2914 | } | 2920 | } |
| 2915 | if (comp.link_eh_frame_hdr) { | 2921 | if (comp.link_eh_frame_hdr) { |
| 2916 | self.eh_frame_hdr_section_index = try self.addSection(.{ | 2922 | self.eh_frame_hdr_section_index = try self.addSection(.{ |