authorgravatar for 35903594+patrickwick@users.noreply.github.comPatrick Wickenhaeuser <35903594+patrickwick@users.noreply.github.com> 2024-10-04 12:38:35+02:00
committergravatar for 35903594+patrickwick@users.noreply.github.comPatrick Wickenhaeuser <35903594+patrickwick@users.noreply.github.com> 2024-10-04 15:49:50+02:00
loge1d54b6d1adb4b8e851bd949ade8cdc5fb840a9b
tree0e1f04850070a2e970f87bf72d15b9b0c9c915d9
parent8f55efc1af9de1ae00aa07bfa6fbbcfeeca02eb4

19009: zig objcopy: integrate --add-section, --set-section-alignment and --set-section-flags into std.Build.Step.ObjCopy


2 files changed, 95 insertions(+), 16 deletions(-)

lib/compiler/objcopy.zig+15-16
...@@ -40,9 +40,9 @@ fn cmdObjCopy(...@@ -40,9 +40,9 @@ fn cmdObjCopy(
40 var only_keep_debug: bool = false;40 var only_keep_debug: bool = false;
41 var compress_debug_sections: bool = false;41 var compress_debug_sections: bool = false;
42 var listen = false;42 var listen = false;
43 var add_section: ?AddSectionOptions = null;43 var add_section: ?AddSection = null;
44 var set_section_alignment: ?SetSectionAlignmentOptions = null;44 var set_section_alignment: ?SetSectionAlignment = null;
45 var set_section_flags: ?SetSectionFlagsOptions = null;45 var set_section_flags: ?SetSectionFlags = null;
46 while (i < args.len) : (i += 1) {46 while (i < args.len) : (i += 1) {
47 const arg = args[i];47 const arg = args[i];
48 if (!mem.startsWith(u8, arg, "-")) {48 if (!mem.startsWith(u8, arg, "-")) {
...@@ -279,23 +279,22 @@ pub const EmitRawElfOptions = struct {...@@ -279,23 +279,22 @@ pub const EmitRawElfOptions = struct {
279 ofmt: std.Target.ObjectFormat,279 ofmt: std.Target.ObjectFormat,
280 only_section: ?[]const u8 = null,280 only_section: ?[]const u8 = null,
281 pad_to: ?u64 = null,281 pad_to: ?u64 = null,
282 add_section: ?AddSectionOptions,282 add_section: ?AddSection,
283 set_section_alignment: ?SetSectionAlignmentOptions,283 set_section_alignment: ?SetSectionAlignment,
284 set_section_flags: ?SetSectionFlagsOptions,284 set_section_flags: ?SetSectionFlags,
285};285};
286286
287const AddSectionOptions = struct {287const AddSection = struct {
288 section_name: []const u8,288 section_name: []const u8,
289 // file to store in new section
290 file_path: []const u8,289 file_path: []const u8,
291};290};
292291
293const SetSectionAlignmentOptions = struct {292const SetSectionAlignment = struct {
294 section_name: []const u8,293 section_name: []const u8,
295 alignment: u32,294 alignment: u32,
296};295};
297296
298const SetSectionFlagsOptions = struct {297const SetSectionFlags = struct {
299 section_name: []const u8,298 section_name: []const u8,
300 flags: SectionFlags,299 flags: SectionFlags,
301};300};
...@@ -740,9 +739,9 @@ const StripElfOptions = struct {...@@ -740,9 +739,9 @@ const StripElfOptions = struct {
740 strip_debug: bool = false,739 strip_debug: bool = false,
741 only_keep_debug: bool = false,740 only_keep_debug: bool = false,
742 compress_debug: bool = false,741 compress_debug: bool = false,
743 add_section: ?AddSectionOptions,742 add_section: ?AddSection,
744 set_section_alignment: ?SetSectionAlignmentOptions,743 set_section_alignment: ?SetSectionAlignment,
745 set_section_flags: ?SetSectionFlagsOptions,744 set_section_flags: ?SetSectionFlags,
746};745};
747746
748fn stripElf(747fn stripElf(
...@@ -976,9 +975,9 @@ fn ElfFile(comptime is_64: bool) type {...@@ -976,9 +975,9 @@ fn ElfFile(comptime is_64: bool) type {
976 section_filter: Filter = .all,975 section_filter: Filter = .all,
977 debuglink: ?DebugLink = null,976 debuglink: ?DebugLink = null,
978 compress_debug: bool = false,977 compress_debug: bool = false,
979 add_section: ?AddSectionOptions = null,978 add_section: ?AddSection = null,
980 set_section_alignment: ?SetSectionAlignmentOptions = null,979 set_section_alignment: ?SetSectionAlignment = null,
981 set_section_flags: ?SetSectionFlagsOptions = null,980 set_section_flags: ?SetSectionFlags = null,
982 };981 };
983 fn emit(self: *const Self, gpa: Allocator, out_file: File, in_file: File, options: EmitElfOptions) !void {982 fn emit(self: *const Self, gpa: Allocator, out_file: File, in_file: File, options: EmitElfOptions) !void {
984 var arena = std.heap.ArenaAllocator.init(gpa);983 var arena = std.heap.ArenaAllocator.init(gpa);
lib/std/Build/Step/ObjCopy.zig+80
...@@ -26,6 +26,50 @@ pub const Strip = enum {...@@ -26,6 +26,50 @@ pub const Strip = enum {
26 debug_and_symbols,26 debug_and_symbols,
27};27};
2828
29pub const SectionFlags = packed struct {
30 /// add SHF_ALLOC
31 alloc: bool = false,
32
33 /// if section is SHT_NOBITS, set SHT_PROGBITS, otherwise do nothing
34 contents: bool = false,
35
36 /// if section is SHT_NOBITS, set SHT_PROGBITS, otherwise do nothing (same as contents)
37 load: bool = false,
38
39 /// readonly: clear default SHF_WRITE flag
40 readonly: bool = false,
41
42 /// add SHF_EXECINSTR
43 code: bool = false,
44
45 /// add SHF_EXCLUDE
46 exclude: bool = false,
47
48 /// add SHF_X86_64_LARGE. Fatal error if target is not x86_64
49 large: bool = false,
50
51 /// add SHF_MERGE
52 merge: bool = false,
53
54 /// add SHF_STRINGS
55 strings: bool = false,
56};
57
58pub const AddSection = struct {
59 section_name: []const u8,
60 file_path: std.Build.LazyPath,
61};
62
63pub const SetSectionAlignment = struct {
64 section_name: []const u8,
65 alignment: u32,
66};
67
68pub const SetSectionFlags = struct {
69 section_name: []const u8,
70 flags: SectionFlags,
71};
72
29step: Step,73step: Step,
30input_file: std.Build.LazyPath,74input_file: std.Build.LazyPath,
31basename: []const u8,75basename: []const u8,
...@@ -38,6 +82,10 @@ pad_to: ?u64,...@@ -38,6 +82,10 @@ pad_to: ?u64,
38strip: Strip,82strip: Strip,
39compress_debug: bool,83compress_debug: bool,
4084
85add_section: ?AddSection,
86set_section_alignment: ?SetSectionAlignment,
87set_section_flags: ?SetSectionFlags,
88
41pub const Options = struct {89pub const Options = struct {
42 basename: ?[]const u8 = null,90 basename: ?[]const u8 = null,
43 format: ?RawFormat = null,91 format: ?RawFormat = null,
...@@ -51,6 +99,10 @@ pub const Options = struct {...@@ -51,6 +99,10 @@ pub const Options = struct {
51 /// note: the `basename` is baked into the elf file to specify the link to the separate debug file.99 /// note: the `basename` is baked into the elf file to specify the link to the separate debug file.
52 /// see https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html100 /// see https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
53 extract_to_separate_file: bool = false,101 extract_to_separate_file: bool = false,
102
103 add_section: ?AddSection = null,
104 set_section_alignment: ?SetSectionAlignment = null,
105 set_section_flags: ?SetSectionFlags = null,
54};106};
55107
56pub fn create(108pub fn create(
...@@ -75,6 +127,9 @@ pub fn create(...@@ -75,6 +127,9 @@ pub fn create(
75 .pad_to = options.pad_to,127 .pad_to = options.pad_to,
76 .strip = options.strip,128 .strip = options.strip,
77 .compress_debug = options.compress_debug,129 .compress_debug = options.compress_debug,
130 .add_section = options.add_section,
131 .set_section_alignment = options.set_section_alignment,
132 .set_section_flags = options.set_section_flags,
78 };133 };
79 input_file.addStepDependencies(&objcopy.step);134 input_file.addStepDependencies(&objcopy.step);
80 return objcopy;135 return objcopy;
...@@ -155,6 +210,31 @@ fn make(step: *Step, options: Step.MakeOptions) !void {...@@ -155,6 +210,31 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
155 if (objcopy.output_file_debug != null) {210 if (objcopy.output_file_debug != null) {
156 try argv.appendSlice(&.{b.fmt("--extract-to={s}", .{full_dest_path_debug})});211 try argv.appendSlice(&.{b.fmt("--extract-to={s}", .{full_dest_path_debug})});
157 }212 }
213 if (objcopy.add_section) |section| {
214 try argv.append("--add-section");
215 try argv.appendSlice(&.{b.fmt("{s}={s}", .{ section.section_name, section.file_path.getPath(b) })});
216 }
217 if (objcopy.set_section_alignment) |set_align| {
218 try argv.append("--set-section-alignment");
219 try argv.appendSlice(&.{b.fmt("{s}={d}", .{ set_align.section_name, set_align.alignment })});
220 }
221 if (objcopy.set_section_flags) |set_flags| {
222 const f = set_flags.flags;
223 // trailing comma is allowed
224 try argv.append("--set-section-flags");
225 try argv.appendSlice(&.{b.fmt("{s}={s}{s}{s}{s}{s}{s}{s}{s}{s}", .{
226 set_flags.section_name,
227 if (f.alloc) "alloc," else "",
228 if (f.contents) "contents," else "",
229 if (f.load) "load," else "",
230 if (f.readonly) "readonly," else "",
231 if (f.code) "code," else "",
232 if (f.exclude) "exclude," else "",
233 if (f.large) "large," else "",
234 if (f.merge) "merge," else "",
235 if (f.strings) "strings," else "",
236 })});
237 }
158238
159 try argv.appendSlice(&.{ full_src_path, full_dest_path });239 try argv.appendSlice(&.{ full_src_path, full_dest_path });
160240