mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 01:15:14 +00:00
elf: allocate .data in ZigObject similarly to .eh_frame
This commit is contained in:
parent
37a1f0e7f2
commit
0b92404ddf
@ -59,8 +59,6 @@ phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{},
|
||||
phdr_zig_load_re_index: ?u16 = null,
|
||||
/// The index into the program headers of a PT_LOAD program header with Read flag
|
||||
phdr_zig_load_ro_index: ?u16 = null,
|
||||
/// The index into the program headers of a PT_LOAD program header with Write flag
|
||||
phdr_zig_load_rw_index: ?u16 = null,
|
||||
|
||||
/// Special program headers
|
||||
/// PT_PHDR
|
||||
@ -126,7 +124,6 @@ comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
|
||||
/// .rela.* sections are only used when emitting a relocatable object file.
|
||||
zig_text_section_index: ?u32 = null,
|
||||
zig_data_rel_ro_section_index: ?u32 = null,
|
||||
zig_data_section_index: ?u32 = null,
|
||||
|
||||
debug_info_section_index: ?u32 = null,
|
||||
debug_abbrev_section_index: ?u32 = null,
|
||||
@ -3491,7 +3488,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
|
||||
&self.verneed_section_index,
|
||||
&self.zig_text_section_index,
|
||||
&self.zig_data_rel_ro_section_index,
|
||||
&self.zig_data_section_index,
|
||||
&self.debug_info_section_index,
|
||||
&self.debug_abbrev_section_index,
|
||||
&self.debug_str_section_index,
|
||||
@ -3589,12 +3585,16 @@ fn updateSectionSizes(self: *Elf) !void {
|
||||
for (slice.items(.shdr), slice.items(.atom_list), 0..) |*shdr, atom_list, shndx| {
|
||||
if (atom_list.items.len == 0) continue;
|
||||
if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;
|
||||
if (self.zigObjectPtr()) |zo| {
|
||||
if (zo.bss_index) |sym_index| {
|
||||
const atom_ptr = zo.symbol(sym_index).atom(self).?;
|
||||
if (shndx == atom_ptr.output_section_index) {
|
||||
shdr.sh_size = atom_ptr.size;
|
||||
}
|
||||
if (self.zigObjectPtr()) |zo| blk: {
|
||||
const sym_index = for ([_]?Symbol.Index{
|
||||
zo.data_index,
|
||||
zo.bss_index,
|
||||
}) |maybe_idx| {
|
||||
if (maybe_idx) |idx| break idx;
|
||||
} else break :blk;
|
||||
const atom_ptr = zo.symbol(sym_index).atom(self).?;
|
||||
if (shndx == atom_ptr.output_section_index) {
|
||||
shdr.sh_size = atom_ptr.size;
|
||||
}
|
||||
}
|
||||
for (atom_list.items) |ref| {
|
||||
@ -3929,10 +3929,16 @@ pub fn allocateAllocSections(self: *Elf) !void {
|
||||
}
|
||||
new_offset = alignment.@"align"(shndx, shdr.sh_addralign, new_offset);
|
||||
|
||||
if (shndx == self.eh_frame_section_index) eh_frame: {
|
||||
const zo = self.zigObjectPtr() orelse break :eh_frame;
|
||||
const sym = zo.symbol(zo.eh_frame_index orelse break :eh_frame);
|
||||
const existing_size = sym.atom(self).?.size;
|
||||
if (self.zigObjectPtr()) |zo| blk: {
|
||||
const existing_size = for ([_]?Symbol.Index{
|
||||
zo.data_index,
|
||||
zo.eh_frame_index,
|
||||
}) |maybe_sym_index| {
|
||||
const sect_sym_index = maybe_sym_index orelse continue;
|
||||
const sect_atom_ptr = zo.symbol(sect_sym_index).atom(self).?;
|
||||
if (sect_atom_ptr.output_section_index != shndx) continue;
|
||||
break sect_atom_ptr.size;
|
||||
} else break :blk;
|
||||
log.debug("moving {s} from 0x{x} to 0x{x}", .{
|
||||
self.getShString(shdr.sh_name),
|
||||
shdr.sh_offset,
|
||||
@ -4096,10 +4102,17 @@ fn writeAtoms(self: *Elf) !void {
|
||||
if (atom_ptr.output_section_index == shndx) break :base_offset atom_ptr.size;
|
||||
}
|
||||
break :base_offset 0;
|
||||
} else if (@as(u32, @intCast(shndx)) == self.eh_frame_section_index) base_offset: {
|
||||
const zo = self.zigObjectPtr() orelse break :base_offset 0;
|
||||
const sym = zo.symbol(zo.eh_frame_index orelse break :base_offset 0);
|
||||
break :base_offset sym.atom(self).?.size;
|
||||
} else if (self.zigObjectPtr()) |zo| base_offset: {
|
||||
const sym_index = for ([_]?Symbol.Index{
|
||||
zo.data_index,
|
||||
zo.eh_frame_index,
|
||||
}) |maybe_idx| {
|
||||
if (maybe_idx) |idx| break idx;
|
||||
} else break :base_offset 0;
|
||||
const sym = zo.symbol(sym_index);
|
||||
const atom_ptr = sym.atom(self).?;
|
||||
if (atom_ptr.output_section_index == @as(u32, @intCast(shndx))) break :base_offset atom_ptr.size;
|
||||
break :base_offset 0;
|
||||
} else 0;
|
||||
const sh_offset = shdr.sh_offset + base_offset;
|
||||
const sh_size = math.cast(usize, shdr.sh_size - base_offset) orelse return error.Overflow;
|
||||
@ -4806,7 +4819,6 @@ pub fn isZigSection(self: Elf, shndx: u32) bool {
|
||||
inline for (&[_]?u32{
|
||||
self.zig_text_section_index,
|
||||
self.zig_data_rel_ro_section_index,
|
||||
self.zig_data_section_index,
|
||||
}) |index| {
|
||||
if (index == shndx) return true;
|
||||
}
|
||||
@ -5507,7 +5519,7 @@ fn requiresThunks(self: Elf) bool {
|
||||
/// so that we reserve enough space for the program header table up-front.
|
||||
/// Bump these numbers when adding or deleting a Zig specific pre-allocated segment, or adding
|
||||
/// more special-purpose program headers.
|
||||
pub const number_of_zig_segments = 4;
|
||||
pub const number_of_zig_segments = 2;
|
||||
const max_number_of_object_segments = 9;
|
||||
const max_number_of_special_phdrs = 5;
|
||||
|
||||
|
||||
@ -61,6 +61,7 @@ debug_loclists_index: ?Symbol.Index = null,
|
||||
debug_rnglists_index: ?Symbol.Index = null,
|
||||
eh_frame_index: ?Symbol.Index = null,
|
||||
bss_index: ?Symbol.Index = null,
|
||||
data_index: ?Symbol.Index = null,
|
||||
|
||||
pub const global_symbol_bit: u32 = 0x80000000;
|
||||
pub const symbol_mask: u32 = 0x7fffffff;
|
||||
@ -104,7 +105,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
}
|
||||
}.fillSection;
|
||||
|
||||
comptime assert(Elf.number_of_zig_segments == 4);
|
||||
comptime assert(Elf.number_of_zig_segments == 2);
|
||||
|
||||
if (!elf_file.base.isRelocatable()) {
|
||||
if (elf_file.phdr_zig_load_re_index == null) {
|
||||
@ -135,21 +136,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
.flags = elf.PF_R | elf.PF_W,
|
||||
});
|
||||
}
|
||||
|
||||
if (elf_file.phdr_zig_load_rw_index == null) {
|
||||
const alignment = elf_file.page_size;
|
||||
const filesz: u64 = 1024;
|
||||
const off = try elf_file.findFreeSpace(filesz, alignment);
|
||||
elf_file.phdr_zig_load_rw_index = try elf_file.addPhdr(.{
|
||||
.type = elf.PT_LOAD,
|
||||
.offset = off,
|
||||
.filesz = filesz,
|
||||
.addr = if (ptr_size >= 4) 0x10000000 else 0xc000,
|
||||
.memsz = filesz,
|
||||
.@"align" = alignment,
|
||||
.flags = elf.PF_R | elf.PF_W,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (elf_file.zig_text_section_index == null) {
|
||||
@ -194,27 +180,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
}
|
||||
}
|
||||
|
||||
if (elf_file.zig_data_section_index == null) {
|
||||
elf_file.zig_data_section_index = try elf_file.addSection(.{
|
||||
.name = try elf_file.insertShString(".data.zig"),
|
||||
.type = elf.SHT_PROGBITS,
|
||||
.addralign = ptr_size,
|
||||
.flags = elf.SHF_ALLOC | elf.SHF_WRITE,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_data_section_index.?];
|
||||
const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_data_section_index.?];
|
||||
try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index);
|
||||
if (elf_file.base.isRelocatable()) {
|
||||
_ = try elf_file.addRelaShdr(
|
||||
try elf_file.insertShString(".rela.data.zig"),
|
||||
elf_file.zig_data_section_index.?,
|
||||
);
|
||||
} else {
|
||||
phndx.* = elf_file.phdr_zig_load_rw_index.?;
|
||||
}
|
||||
}
|
||||
|
||||
switch (comp.config.debug_format) {
|
||||
.strip => {},
|
||||
.dwarf => |v| {
|
||||
@ -1246,6 +1211,8 @@ fn getNavShdrIndex(
|
||||
sym_index: Symbol.Index,
|
||||
code: []const u8,
|
||||
) error{OutOfMemory}!u32 {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const ptr_size = elf_file.ptrWidthBytes();
|
||||
const ip = &zcu.intern_pool;
|
||||
const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
|
||||
const nav_val = zcu.navValue(nav_index);
|
||||
@ -1276,7 +1243,19 @@ fn getNavShdrIndex(
|
||||
if (is_const) return elf_file.zig_data_rel_ro_section_index.?;
|
||||
if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
|
||||
return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
|
||||
.Debug, .ReleaseSafe => elf_file.zig_data_section_index.?,
|
||||
.Debug, .ReleaseSafe => {
|
||||
if (self.data_index) |symbol_index|
|
||||
return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
|
||||
const osec = try elf_file.addSection(.{
|
||||
.name = try elf_file.insertShString(".data"),
|
||||
.type = elf.SHT_PROGBITS,
|
||||
.addralign = ptr_size,
|
||||
.flags = elf.SHF_ALLOC | elf.SHF_WRITE,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
self.data_index = try self.addSectionSymbol(gpa, ".data", .@"1", osec);
|
||||
return osec;
|
||||
},
|
||||
.ReleaseFast, .ReleaseSmall => {
|
||||
if (self.bss_index) |symbol_index|
|
||||
return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
|
||||
@ -1286,7 +1265,7 @@ fn getNavShdrIndex(
|
||||
.name = try elf_file.insertShString(".bss"),
|
||||
.addralign = 1,
|
||||
});
|
||||
self.bss_index = try self.addSectionSymbol(elf_file.base.comp.gpa, ".bss", .@"1", osec);
|
||||
self.bss_index = try self.addSectionSymbol(gpa, ".bss", .@"1", osec);
|
||||
return osec;
|
||||
},
|
||||
};
|
||||
@ -1302,10 +1281,20 @@ fn getNavShdrIndex(
|
||||
.name = try elf_file.insertShString(".bss"),
|
||||
.addralign = 1,
|
||||
});
|
||||
self.bss_index = try self.addSectionSymbol(elf_file.base.comp.gpa, ".bss", .@"1", osec);
|
||||
self.bss_index = try self.addSectionSymbol(gpa, ".bss", .@"1", osec);
|
||||
return osec;
|
||||
}
|
||||
return elf_file.zig_data_section_index.?;
|
||||
if (self.data_index) |symbol_index|
|
||||
return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
|
||||
const osec = try elf_file.addSection(.{
|
||||
.name = try elf_file.insertShString(".data"),
|
||||
.type = elf.SHT_PROGBITS,
|
||||
.addralign = ptr_size,
|
||||
.flags = elf.SHF_ALLOC | elf.SHF_WRITE,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
self.data_index = try self.addSectionSymbol(gpa, ".data", .@"1", osec);
|
||||
return osec;
|
||||
}
|
||||
|
||||
fn updateNavCode(
|
||||
@ -2014,6 +2003,16 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {
|
||||
}
|
||||
shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits().?);
|
||||
|
||||
const sect_atom_ptr = for ([_]?Symbol.Index{self.data_index}) |maybe_sym_index| {
|
||||
const sect_sym_index = maybe_sym_index orelse continue;
|
||||
const sect_atom_ptr = self.symbol(sect_sym_index).atom(elf_file).?;
|
||||
if (sect_atom_ptr.output_section_index == atom_ptr.output_section_index) break sect_atom_ptr;
|
||||
} else null;
|
||||
if (sect_atom_ptr) |sap| {
|
||||
sap.size = shdr.sh_size;
|
||||
sap.alignment = Atom.Alignment.fromNonzeroByteUnits(shdr.sh_addralign);
|
||||
}
|
||||
|
||||
// This function can also reallocate an atom.
|
||||
// In this case we need to "unplug" it from its previous location before
|
||||
// plugging it in to its new location.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user