| ... | ... | @@ -26,6 +26,50 @@ pub const Strip = enum { |
| 26 | 26 | debug_and_symbols, |
| 27 | 27 | }; |
| 28 | 28 | |
| 29 | pub 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 | |
| 58 | pub const AddSection = struct { |
| 59 | section_name: []const u8, |
| 60 | file_path: std.Build.LazyPath, |
| 61 | }; |
| 62 | |
| 63 | pub const SetSectionAlignment = struct { |
| 64 | section_name: []const u8, |
| 65 | alignment: u32, |
| 66 | }; |
| 67 | |
| 68 | pub const SetSectionFlags = struct { |
| 69 | section_name: []const u8, |
| 70 | flags: SectionFlags, |
| 71 | }; |
| 72 | |
| 29 | 73 | step: Step, |
| 30 | 74 | input_file: std.Build.LazyPath, |
| 31 | 75 | basename: []const u8, |
| ... | ... | @@ -38,6 +82,10 @@ pad_to: ?u64, |
| 38 | 82 | strip: Strip, |
| 39 | 83 | compress_debug: bool, |
| 40 | 84 | |
| 85 | add_section: ?AddSection, |
| 86 | set_section_alignment: ?SetSectionAlignment, |
| 87 | set_section_flags: ?SetSectionFlags, |
| 88 | |
| 41 | 89 | pub const Options = struct { |
| 42 | 90 | basename: ?[]const u8 = null, |
| 43 | 91 | format: ?RawFormat = null, |
| ... | ... | @@ -51,6 +99,10 @@ pub const Options = struct { |
| 51 | 99 | /// note: the `basename` is baked into the elf file to specify the link to the separate debug file. |
| 52 | 100 | /// see https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html |
| 53 | 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 | }; |
| 55 | 107 | |
| 56 | 108 | pub fn create( |
| ... | ... | @@ -75,6 +127,9 @@ pub fn create( |
| 75 | 127 | .pad_to = options.pad_to, |
| 76 | 128 | .strip = options.strip, |
| 77 | 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 | 134 | input_file.addStepDependencies(&objcopy.step); |
| 80 | 135 | return objcopy; |
| ... | ... | @@ -155,6 +210,31 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 155 | 210 | if (objcopy.output_file_debug != null) { |
| 156 | 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 | } |
| 158 | 238 | |
| 159 | 239 | try argv.appendSlice(&.{ full_src_path, full_dest_path }); |
| 160 | 240 | |