mirror of
https://github.com/ziglang/zig.git
synced 2025-12-27 00:23:22 +00:00
macho: move initSection into MachO from Zld
This commit is contained in:
parent
180979ee41
commit
b2773cd712
@ -2739,6 +2739,34 @@ fn calcPagezeroSize(self: *MachO) u64 {
|
||||
return aligned_pagezero_vmsize;
|
||||
}
|
||||
|
||||
const InitSectionOpts = struct {
|
||||
flags: u32 = macho.S_REGULAR,
|
||||
reserved1: u32 = 0,
|
||||
reserved2: u32 = 0,
|
||||
};
|
||||
|
||||
pub fn initSection(
|
||||
gpa: Allocator,
|
||||
ctx: anytype,
|
||||
segname: []const u8,
|
||||
sectname: []const u8,
|
||||
opts: InitSectionOpts,
|
||||
) !u8 {
|
||||
log.debug("creating section '{s},{s}'", .{ segname, sectname });
|
||||
const index = @as(u8, @intCast(ctx.sections.slice().len));
|
||||
try ctx.sections.append(gpa, .{
|
||||
.segment_index = undefined, // Segments will be created automatically later down the pipeline
|
||||
.header = .{
|
||||
.sectname = makeStaticString(sectname),
|
||||
.segname = makeStaticString(segname),
|
||||
.flags = opts.flags,
|
||||
.reserved1 = opts.reserved1,
|
||||
.reserved2 = opts.reserved2,
|
||||
},
|
||||
});
|
||||
return index;
|
||||
}
|
||||
|
||||
fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts: struct {
|
||||
size: u64 = 0,
|
||||
alignment: u32 = 0,
|
||||
@ -2751,7 +2779,6 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts
|
||||
// In incremental context, we create one section per segment pairing. This way,
|
||||
// we can move the segment in raw file as we please.
|
||||
const segment_id = @as(u8, @intCast(self.segments.items.len));
|
||||
const section_id = @as(u8, @intCast(self.sections.slice().len));
|
||||
const vmaddr = blk: {
|
||||
const prev_segment = self.segments.items[segment_id - 1];
|
||||
break :blk mem.alignForward(u64, prev_segment.vmaddr + prev_segment.vmsize, page_size);
|
||||
@ -2782,23 +2809,18 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts
|
||||
.cmdsize = @sizeOf(macho.segment_command_64) + @sizeOf(macho.section_64),
|
||||
};
|
||||
|
||||
var section = macho.section_64{
|
||||
.sectname = makeStaticString(sectname),
|
||||
.segname = makeStaticString(segname),
|
||||
.addr = mem.alignForward(u64, vmaddr, opts.alignment),
|
||||
.offset = mem.alignForward(u32, @as(u32, @intCast(off)), opts.alignment),
|
||||
.size = opts.size,
|
||||
.@"align" = math.log2(opts.alignment),
|
||||
const sect_id = try initSection(gpa, self, sectname, segname, .{
|
||||
.flags = opts.flags,
|
||||
.reserved2 = opts.reserved2,
|
||||
};
|
||||
});
|
||||
const section = &self.sections.items(.header)[sect_id];
|
||||
section.addr = mem.alignForward(u64, vmaddr, opts.alignment);
|
||||
section.offset = mem.alignForward(u32, @as(u32, @intCast(off)), opts.alignment);
|
||||
section.size = opts.size;
|
||||
section.@"align" = math.log2(opts.alignment);
|
||||
assert(!section.isZerofill()); // TODO zerofill sections
|
||||
|
||||
try self.sections.append(gpa, .{
|
||||
.segment_index = segment_id,
|
||||
.header = section,
|
||||
});
|
||||
return section_id;
|
||||
return sect_id;
|
||||
}
|
||||
|
||||
fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {
|
||||
|
||||
@ -106,6 +106,7 @@ pub fn freeListEligible(self: Atom, macho_file: *MachO) bool {
|
||||
}
|
||||
|
||||
pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
|
||||
const gpa = zld.gpa;
|
||||
const segname = sect.segName();
|
||||
const sectname = sect.sectName();
|
||||
const res: ?u8 = blk: {
|
||||
@ -126,7 +127,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
|
||||
|
||||
if (sect.isCode()) {
|
||||
if (zld.text_section_index == null) {
|
||||
zld.text_section_index = try zld.initSection(
|
||||
zld.text_section_index = try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
"__TEXT",
|
||||
"__text",
|
||||
.{
|
||||
@ -148,7 +151,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
|
||||
macho.S_8BYTE_LITERALS,
|
||||
macho.S_16BYTE_LITERALS,
|
||||
=> {
|
||||
break :blk zld.getSectionByName("__TEXT", "__const") orelse try zld.initSection(
|
||||
break :blk zld.getSectionByName("__TEXT", "__const") orelse try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
"__TEXT",
|
||||
"__const",
|
||||
.{},
|
||||
@ -156,13 +161,17 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
|
||||
},
|
||||
macho.S_CSTRING_LITERALS => {
|
||||
if (mem.startsWith(u8, sectname, "__objc")) {
|
||||
break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection(
|
||||
break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
segname,
|
||||
sectname,
|
||||
.{},
|
||||
);
|
||||
}
|
||||
break :blk zld.getSectionByName("__TEXT", "__cstring") orelse try zld.initSection(
|
||||
break :blk zld.getSectionByName("__TEXT", "__cstring") orelse try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
"__TEXT",
|
||||
"__cstring",
|
||||
.{ .flags = macho.S_CSTRING_LITERALS },
|
||||
@ -171,7 +180,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
|
||||
macho.S_MOD_INIT_FUNC_POINTERS,
|
||||
macho.S_MOD_TERM_FUNC_POINTERS,
|
||||
=> {
|
||||
break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try zld.initSection(
|
||||
break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
"__DATA_CONST",
|
||||
sectname,
|
||||
.{ .flags = sect.flags },
|
||||
@ -184,14 +195,19 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
|
||||
macho.S_THREAD_LOCAL_REGULAR,
|
||||
macho.S_THREAD_LOCAL_ZEROFILL,
|
||||
=> {
|
||||
break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection(
|
||||
break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
segname,
|
||||
sectname,
|
||||
.{ .flags = sect.flags },
|
||||
);
|
||||
},
|
||||
macho.S_COALESCED => {
|
||||
break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection(
|
||||
break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
|
||||
segname,
|
||||
sectname,
|
||||
.{},
|
||||
@ -205,7 +221,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
|
||||
mem.eql(u8, sectname, "__gosymtab") or
|
||||
mem.eql(u8, sectname, "__gopclntab"))
|
||||
{
|
||||
break :blk zld.getSectionByName("__TEXT", sectname) orelse try zld.initSection(
|
||||
break :blk zld.getSectionByName("__TEXT", sectname) orelse try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
"__TEXT",
|
||||
sectname,
|
||||
.{},
|
||||
@ -218,20 +236,26 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
|
||||
mem.eql(u8, sectname, "__objc_classlist") or
|
||||
mem.eql(u8, sectname, "__objc_imageinfo"))
|
||||
{
|
||||
break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try zld.initSection(
|
||||
break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
"__DATA_CONST",
|
||||
sectname,
|
||||
.{},
|
||||
);
|
||||
} else if (mem.eql(u8, sectname, "__data")) {
|
||||
break :blk zld.getSectionByName("__DATA", "__data") orelse try zld.initSection(
|
||||
break :blk zld.getSectionByName("__DATA", "__data") orelse try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
"__DATA",
|
||||
"__data",
|
||||
.{},
|
||||
);
|
||||
}
|
||||
}
|
||||
break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection(
|
||||
break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection(
|
||||
gpa,
|
||||
zld,
|
||||
segname,
|
||||
sectname,
|
||||
.{},
|
||||
|
||||
@ -685,11 +685,12 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void {
|
||||
|
||||
log.debug("parsing __TEXT,__eh_frame section", .{});
|
||||
|
||||
const gpa = zld.gpa;
|
||||
|
||||
if (zld.getSectionByName("__TEXT", "__eh_frame") == null) {
|
||||
_ = try zld.initSection("__TEXT", "__eh_frame", .{});
|
||||
_ = try MachO.initSection(gpa, zld, "__TEXT", "__eh_frame", .{});
|
||||
}
|
||||
|
||||
const gpa = zld.gpa;
|
||||
const cpu_arch = zld.options.target.cpu.arch;
|
||||
try self.parseRelocs(gpa, sect_id);
|
||||
const relocs = self.getRelocs(sect_id);
|
||||
@ -779,6 +780,8 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void {
|
||||
}
|
||||
|
||||
fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void {
|
||||
const gpa = zld.gpa;
|
||||
const cpu_arch = zld.options.target.cpu.arch;
|
||||
const sect_id = self.unwind_info_sect_id orelse {
|
||||
// If it so happens that the object had `__eh_frame` section defined but no `__compact_unwind`,
|
||||
// we will try fully synthesising unwind info records to somewhat match Apple ld's
|
||||
@ -786,7 +789,7 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void {
|
||||
// we still create the output `__TEXT,__unwind_info` section.
|
||||
if (self.hasEhFrameRecords()) {
|
||||
if (zld.getSectionByName("__TEXT", "__unwind_info") == null) {
|
||||
_ = try zld.initSection("__TEXT", "__unwind_info", .{});
|
||||
_ = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{});
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -794,11 +797,8 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void {
|
||||
|
||||
log.debug("parsing unwind info in {s}", .{self.name});
|
||||
|
||||
const gpa = zld.gpa;
|
||||
const cpu_arch = zld.options.target.cpu.arch;
|
||||
|
||||
if (zld.getSectionByName("__TEXT", "__unwind_info") == null) {
|
||||
_ = try zld.initSection("__TEXT", "__unwind_info", .{});
|
||||
_ = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{});
|
||||
}
|
||||
|
||||
const unwind_records = self.getUnwindRecords();
|
||||
|
||||
@ -141,7 +141,7 @@ pub const Zld = struct {
|
||||
sym.n_type = macho.N_SECT;
|
||||
|
||||
const sect_id = self.getSectionByName("__DATA", "__data") orelse
|
||||
try self.initSection("__DATA", "__data", .{});
|
||||
try MachO.initSection(self.gpa, self, "__DATA", "__data", .{});
|
||||
sym.n_sect = sect_id + 1;
|
||||
self.dyld_private_atom_index = atom_index;
|
||||
|
||||
@ -165,7 +165,7 @@ pub const Zld = struct {
|
||||
const size = sym.n_value;
|
||||
const alignment = (sym.n_desc >> 8) & 0x0f;
|
||||
const sect_id = self.getSectionByName("__DATA", "__bss") orelse
|
||||
try self.initSection("__DATA", "__bss", .{ .flags = macho.S_ZEROFILL });
|
||||
try MachO.initSection(gpa, self, "__DATA", "__bss", .{ .flags = macho.S_ZEROFILL });
|
||||
|
||||
sym.* = .{
|
||||
.n_strx = sym.n_strx,
|
||||
@ -619,7 +619,7 @@ pub const Zld = struct {
|
||||
if (self.got_table.lookup.contains(target)) return;
|
||||
_ = try self.got_table.allocateEntry(self.gpa, target);
|
||||
if (self.got_section_index == null) {
|
||||
self.got_section_index = try self.initSection("__DATA_CONST", "__got", .{
|
||||
self.got_section_index = try MachO.initSection(self.gpa, self, "__DATA_CONST", "__got", .{
|
||||
.flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
|
||||
});
|
||||
}
|
||||
@ -629,7 +629,7 @@ pub const Zld = struct {
|
||||
if (self.tlv_ptr_table.lookup.contains(target)) return;
|
||||
_ = try self.tlv_ptr_table.allocateEntry(self.gpa, target);
|
||||
if (self.tlv_ptr_section_index == null) {
|
||||
self.tlv_ptr_section_index = try self.initSection("__DATA", "__thread_ptrs", .{
|
||||
self.tlv_ptr_section_index = try MachO.initSection(self.gpa, self, "__DATA", "__thread_ptrs", .{
|
||||
.flags = macho.S_THREAD_LOCAL_VARIABLE_POINTERS,
|
||||
});
|
||||
}
|
||||
@ -639,18 +639,18 @@ pub const Zld = struct {
|
||||
if (self.stubs_table.lookup.contains(target)) return;
|
||||
_ = try self.stubs_table.allocateEntry(self.gpa, target);
|
||||
if (self.stubs_section_index == null) {
|
||||
self.stubs_section_index = try self.initSection("__TEXT", "__stubs", .{
|
||||
self.stubs_section_index = try MachO.initSection(self.gpa, self, "__TEXT", "__stubs", .{
|
||||
.flags = macho.S_SYMBOL_STUBS |
|
||||
macho.S_ATTR_PURE_INSTRUCTIONS |
|
||||
macho.S_ATTR_SOME_INSTRUCTIONS,
|
||||
.reserved2 = stubs.stubSize(self.options.target.cpu.arch),
|
||||
});
|
||||
self.stub_helper_section_index = try self.initSection("__TEXT", "__stub_helper", .{
|
||||
self.stub_helper_section_index = try MachO.initSection(self.gpa, self, "__TEXT", "__stub_helper", .{
|
||||
.flags = macho.S_REGULAR |
|
||||
macho.S_ATTR_PURE_INSTRUCTIONS |
|
||||
macho.S_ATTR_SOME_INSTRUCTIONS,
|
||||
});
|
||||
self.la_symbol_ptr_section_index = try self.initSection("__DATA", "__la_symbol_ptr", .{
|
||||
self.la_symbol_ptr_section_index = try MachO.initSection(self.gpa, self, "__DATA", "__la_symbol_ptr", .{
|
||||
.flags = macho.S_LAZY_SYMBOL_POINTERS,
|
||||
});
|
||||
}
|
||||
@ -1152,34 +1152,6 @@ pub const Zld = struct {
|
||||
segment.vmsize = mem.alignForward(u64, segment.vmsize, page_size);
|
||||
}
|
||||
|
||||
const InitSectionOpts = struct {
|
||||
flags: u32 = macho.S_REGULAR,
|
||||
reserved1: u32 = 0,
|
||||
reserved2: u32 = 0,
|
||||
};
|
||||
|
||||
pub fn initSection(
|
||||
self: *Zld,
|
||||
segname: []const u8,
|
||||
sectname: []const u8,
|
||||
opts: InitSectionOpts,
|
||||
) !u8 {
|
||||
const gpa = self.gpa;
|
||||
log.debug("creating section '{s},{s}'", .{ segname, sectname });
|
||||
const index = @as(u8, @intCast(self.sections.slice().len));
|
||||
try self.sections.append(gpa, .{
|
||||
.segment_index = undefined, // Segments will be created automatically later down the pipeline
|
||||
.header = .{
|
||||
.sectname = makeStaticString(sectname),
|
||||
.segname = makeStaticString(segname),
|
||||
.flags = opts.flags,
|
||||
.reserved1 = opts.reserved1,
|
||||
.reserved2 = opts.reserved2,
|
||||
},
|
||||
});
|
||||
return index;
|
||||
}
|
||||
|
||||
fn writeSegmentHeaders(self: *Zld, writer: anytype) !void {
|
||||
for (self.segments.items, 0..) |seg, i| {
|
||||
const indexes = self.getSectionIndexes(@as(u8, @intCast(i)));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user