From e1d54b6d1adb4b8e851bd949ade8cdc5fb840a9b Mon Sep 17 00:00:00 2001 From: Patrick Wickenhaeuser <35903594+patrickwick@users.noreply.github.com> Date: Fri, 4 Oct 2024 12:38:35 +0200 Subject: [PATCH] 19009: zig objcopy: integrate --add-section, --set-section-alignment and --set-section-flags into std.Build.Step.ObjCopy --- lib/compiler/objcopy.zig | 31 +++++++------ lib/std/Build/Step/ObjCopy.zig | 80 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 16 deletions(-) diff --git a/lib/compiler/objcopy.zig b/lib/compiler/objcopy.zig index ab0c340ac3..e609e39b9b 100644 --- a/lib/compiler/objcopy.zig +++ b/lib/compiler/objcopy.zig @@ -40,9 +40,9 @@ fn cmdObjCopy( var only_keep_debug: bool = false; var compress_debug_sections: bool = false; var listen = false; - var add_section: ?AddSectionOptions = null; - var set_section_alignment: ?SetSectionAlignmentOptions = null; - var set_section_flags: ?SetSectionFlagsOptions = null; + var add_section: ?AddSection = null; + var set_section_alignment: ?SetSectionAlignment = null; + var set_section_flags: ?SetSectionFlags = null; while (i < args.len) : (i += 1) { const arg = args[i]; if (!mem.startsWith(u8, arg, "-")) { @@ -279,23 +279,22 @@ pub const EmitRawElfOptions = struct { ofmt: std.Target.ObjectFormat, only_section: ?[]const u8 = null, pad_to: ?u64 = null, - add_section: ?AddSectionOptions, - set_section_alignment: ?SetSectionAlignmentOptions, - set_section_flags: ?SetSectionFlagsOptions, + add_section: ?AddSection, + set_section_alignment: ?SetSectionAlignment, + set_section_flags: ?SetSectionFlags, }; -const AddSectionOptions = struct { +const AddSection = struct { section_name: []const u8, - // file to store in new section file_path: []const u8, }; -const SetSectionAlignmentOptions = struct { +const SetSectionAlignment = struct { section_name: []const u8, alignment: u32, }; -const SetSectionFlagsOptions = struct { +const SetSectionFlags = struct { section_name: []const u8, flags: SectionFlags, }; @@ -740,9 +739,9 @@ const StripElfOptions = struct { strip_debug: bool = false, only_keep_debug: bool = false, compress_debug: bool = false, - add_section: ?AddSectionOptions, - set_section_alignment: ?SetSectionAlignmentOptions, - set_section_flags: ?SetSectionFlagsOptions, + add_section: ?AddSection, + set_section_alignment: ?SetSectionAlignment, + set_section_flags: ?SetSectionFlags, }; fn stripElf( @@ -976,9 +975,9 @@ fn ElfFile(comptime is_64: bool) type { section_filter: Filter = .all, debuglink: ?DebugLink = null, compress_debug: bool = false, - add_section: ?AddSectionOptions = null, - set_section_alignment: ?SetSectionAlignmentOptions = null, - set_section_flags: ?SetSectionFlagsOptions = null, + add_section: ?AddSection = null, + set_section_alignment: ?SetSectionAlignment = null, + set_section_flags: ?SetSectionFlags = null, }; fn emit(self: *const Self, gpa: Allocator, out_file: File, in_file: File, options: EmitElfOptions) !void { var arena = std.heap.ArenaAllocator.init(gpa); diff --git a/lib/std/Build/Step/ObjCopy.zig b/lib/std/Build/Step/ObjCopy.zig index 6ed23d3fb4..8f0f62e222 100644 --- a/lib/std/Build/Step/ObjCopy.zig +++ b/lib/std/Build/Step/ObjCopy.zig @@ -26,6 +26,50 @@ pub const Strip = enum { debug_and_symbols, }; +pub const SectionFlags = packed struct { + /// add SHF_ALLOC + alloc: bool = false, + + /// if section is SHT_NOBITS, set SHT_PROGBITS, otherwise do nothing + contents: bool = false, + + /// if section is SHT_NOBITS, set SHT_PROGBITS, otherwise do nothing (same as contents) + load: bool = false, + + /// readonly: clear default SHF_WRITE flag + readonly: bool = false, + + /// add SHF_EXECINSTR + code: bool = false, + + /// add SHF_EXCLUDE + exclude: bool = false, + + /// add SHF_X86_64_LARGE. Fatal error if target is not x86_64 + large: bool = false, + + /// add SHF_MERGE + merge: bool = false, + + /// add SHF_STRINGS + strings: bool = false, +}; + +pub const AddSection = struct { + section_name: []const u8, + file_path: std.Build.LazyPath, +}; + +pub const SetSectionAlignment = struct { + section_name: []const u8, + alignment: u32, +}; + +pub const SetSectionFlags = struct { + section_name: []const u8, + flags: SectionFlags, +}; + step: Step, input_file: std.Build.LazyPath, basename: []const u8, @@ -38,6 +82,10 @@ pad_to: ?u64, strip: Strip, compress_debug: bool, +add_section: ?AddSection, +set_section_alignment: ?SetSectionAlignment, +set_section_flags: ?SetSectionFlags, + pub const Options = struct { basename: ?[]const u8 = null, format: ?RawFormat = null, @@ -51,6 +99,10 @@ pub const Options = struct { /// note: the `basename` is baked into the elf file to specify the link to the separate debug file. /// see https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html extract_to_separate_file: bool = false, + + add_section: ?AddSection = null, + set_section_alignment: ?SetSectionAlignment = null, + set_section_flags: ?SetSectionFlags = null, }; pub fn create( @@ -75,6 +127,9 @@ pub fn create( .pad_to = options.pad_to, .strip = options.strip, .compress_debug = options.compress_debug, + .add_section = options.add_section, + .set_section_alignment = options.set_section_alignment, + .set_section_flags = options.set_section_flags, }; input_file.addStepDependencies(&objcopy.step); return objcopy; @@ -155,6 +210,31 @@ fn make(step: *Step, options: Step.MakeOptions) !void { if (objcopy.output_file_debug != null) { try argv.appendSlice(&.{b.fmt("--extract-to={s}", .{full_dest_path_debug})}); } + if (objcopy.add_section) |section| { + try argv.append("--add-section"); + try argv.appendSlice(&.{b.fmt("{s}={s}", .{ section.section_name, section.file_path.getPath(b) })}); + } + if (objcopy.set_section_alignment) |set_align| { + try argv.append("--set-section-alignment"); + try argv.appendSlice(&.{b.fmt("{s}={d}", .{ set_align.section_name, set_align.alignment })}); + } + if (objcopy.set_section_flags) |set_flags| { + const f = set_flags.flags; + // trailing comma is allowed + try argv.append("--set-section-flags"); + try argv.appendSlice(&.{b.fmt("{s}={s}{s}{s}{s}{s}{s}{s}{s}{s}", .{ + set_flags.section_name, + if (f.alloc) "alloc," else "", + if (f.contents) "contents," else "", + if (f.load) "load," else "", + if (f.readonly) "readonly," else "", + if (f.code) "code," else "", + if (f.exclude) "exclude," else "", + if (f.large) "large," else "", + if (f.merge) "merge," else "", + if (f.strings) "strings," else "", + })}); + } try argv.appendSlice(&.{ full_src_path, full_dest_path });