| ... | ... | @@ -6,19 +6,18 @@ const Configuration = std.Build.Configuration; |
| 6 | 6 | |
| 7 | 7 | step: Step, |
| 8 | 8 | input_file: std.Build.LazyPath, |
| 9 | | basename: ?[]const u8, |
| 9 | basename: Configuration.OptionalString, |
| 10 | 10 | output_file: Configuration.GeneratedFileIndex, |
| 11 | | output_file_debug: Configuration.OptionalGeneratedFileIndex, |
| 11 | debug_file: ?DebugFile, |
| 12 | 12 | |
| 13 | 13 | format: ?Format, |
| 14 | | only_section: ?[]const u8, |
| 14 | only_section: Configuration.OptionalString, |
| 15 | 15 | pad_to: ?u64, |
| 16 | 16 | strip: Strip, |
| 17 | 17 | compress_debug: bool, |
| 18 | 18 | |
| 19 | | add_section: ?AddSection, |
| 20 | | set_section_alignment: ?SetSectionAlignment, |
| 21 | | set_section_flags: ?SetSectionFlags, |
| 19 | add_sections: std.ArrayList(AddSection) = .empty, |
| 20 | update_sections: std.ArrayList(Configuration.Step.ObjCopy.UpdateSection) = .empty, |
| 22 | 21 | |
| 23 | 22 | pub const base_tag: Step.Tag = .obj_copy; |
| 24 | 23 | |
| ... | ... | @@ -27,18 +26,13 @@ pub const Strip = Configuration.Step.ObjCopy.Strip; |
| 27 | 26 | pub const SectionFlags = Configuration.Step.ObjCopy.SectionFlags; |
| 28 | 27 | |
| 29 | 28 | pub const AddSection = struct { |
| 30 | | section_name: []const u8, |
| 29 | section_name: Configuration.String, |
| 31 | 30 | file_path: std.Build.LazyPath, |
| 32 | 31 | }; |
| 33 | 32 | |
| 34 | | pub const SetSectionAlignment = struct { |
| 35 | | section_name: []const u8, |
| 36 | | alignment: u32, |
| 37 | | }; |
| 38 | | |
| 39 | | pub const SetSectionFlags = struct { |
| 40 | | section_name: []const u8, |
| 41 | | flags: SectionFlags, |
| 33 | pub const DebugFile = struct { |
| 34 | basename: Configuration.OptionalString, |
| 35 | output_file: Configuration.GeneratedFileIndex, |
| 42 | 36 | }; |
| 43 | 37 | |
| 44 | 38 | pub const Options = struct { |
| ... | ... | @@ -53,50 +47,80 @@ pub const Options = struct { |
| 53 | 47 | /// Put the stripped out debug sections in a separate file. |
| 54 | 48 | /// note: the `basename` is baked into the elf file to specify the link to the separate debug file. |
| 55 | 49 | /// see https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html |
| 56 | | extract_to_separate_file: bool = false, |
| 50 | /// |
| 51 | /// Makes `getOutputSeparatedDebug` return non-null. |
| 52 | separate_debug_file: ?SeparateDebugFile = null, |
| 57 | 53 | |
| 58 | | add_section: ?AddSection = null, |
| 59 | | set_section_alignment: ?SetSectionAlignment = null, |
| 60 | | set_section_flags: ?SetSectionFlags = null, |
| 54 | pub const SeparateDebugFile = struct { |
| 55 | basename: ?[]const u8, |
| 56 | }; |
| 61 | 57 | }; |
| 62 | 58 | |
| 63 | | pub fn create( |
| 64 | | owner: *std.Build, |
| 65 | | input_file: std.Build.LazyPath, |
| 66 | | options: Options, |
| 67 | | ) *ObjCopy { |
| 59 | pub fn create(owner: *std.Build, input_file: std.Build.LazyPath, options: Options) *ObjCopy { |
| 68 | 60 | const graph = owner.graph; |
| 69 | | const obj_copy = graph.create(ObjCopy); |
| 70 | | obj_copy.* = .{ |
| 61 | const wc = &graph.wip_configuration; |
| 62 | const oc = graph.create(ObjCopy); |
| 63 | oc.* = .{ |
| 71 | 64 | .step = .init(.{ |
| 72 | 65 | .tag = base_tag, |
| 73 | 66 | .name = owner.fmt("objcopy {f}", .{input_file.fmt(graph)}), |
| 74 | 67 | .owner = owner, |
| 75 | 68 | }), |
| 76 | 69 | .input_file = input_file, |
| 77 | | .basename = options.basename, |
| 78 | | .output_file = graph.addGeneratedFile(&obj_copy.step), |
| 79 | | .output_file_debug = if (options.strip != .none and options.extract_to_separate_file) |
| 80 | | .init(graph.addGeneratedFile(&obj_copy.step)) |
| 81 | | else |
| 82 | | .none, |
| 70 | .basename = if (options.basename) |s| .init(wc.addString(s) catch @panic("OOM")) else .none, |
| 71 | .output_file = graph.addGeneratedFile(&oc.step), |
| 72 | .debug_file = if (options.separate_debug_file) |df| .{ |
| 73 | .basename = if (df.basename) |s| .init(wc.addString(s) catch @panic("OOM")) else .none, |
| 74 | .output_file = graph.addGeneratedFile(&oc.step), |
| 75 | } else null, |
| 83 | 76 | .format = options.format, |
| 84 | | .only_section = options.only_section, |
| 77 | .only_section = if (options.only_section) |s| .init(wc.addString(s) catch @panic("OOM")) else .none, |
| 85 | 78 | .pad_to = options.pad_to, |
| 86 | 79 | .strip = options.strip, |
| 87 | 80 | .compress_debug = options.compress_debug, |
| 88 | | .add_section = options.add_section, |
| 89 | | .set_section_alignment = options.set_section_alignment, |
| 90 | | .set_section_flags = options.set_section_flags, |
| 91 | 81 | }; |
| 92 | | input_file.addStepDependencies(&obj_copy.step); |
| 93 | | return obj_copy; |
| 82 | input_file.addStepDependencies(&oc.step); |
| 83 | return oc; |
| 84 | } |
| 85 | |
| 86 | pub const UpdateSectionOptions = struct { |
| 87 | alignment: ?std.mem.Alignment = null, |
| 88 | flags: SectionFlags = .default, |
| 89 | }; |
| 90 | |
| 91 | pub fn updateSection(oc: *ObjCopy, section_name: []const u8, options: UpdateSectionOptions) void { |
| 92 | const graph = oc.owner.graph; |
| 93 | const arena = graph.arena; |
| 94 | const wc = &graph.wip_configuration; |
| 95 | oc.update_sections.append(arena, .{ |
| 96 | .flags = .{ |
| 97 | .section_flags = options.flags, |
| 98 | .alignment = .init(options.alignment), |
| 99 | }, |
| 100 | .section_name = wc.addString(section_name) catch @panic("OOM"), |
| 101 | }) catch @panic("OOM"); |
| 102 | } |
| 103 | |
| 104 | pub const AddSectionOptions = struct { |
| 105 | file_path: std.Build.LazyPath, |
| 106 | }; |
| 107 | |
| 108 | pub fn addSection(oc: *ObjCopy, section_name: []const u8, options: AddSectionOptions) void { |
| 109 | const graph = oc.owner.graph; |
| 110 | const arena = graph.arena; |
| 111 | const wc = &graph.wip_configuration; |
| 112 | oc.add_sections.append(arena, .{ |
| 113 | .section_name = wc.addString(section_name) catch @panic("OOM"), |
| 114 | .file_path = options.file_path, |
| 115 | }) catch @panic("OOM"); |
| 116 | options.file_path.addStepDependencies(&oc.step); |
| 94 | 117 | } |
| 95 | 118 | |
| 96 | | pub fn getOutput(obj_copy: *const ObjCopy) std.Build.LazyPath { |
| 97 | | return .{ .generated = .{ .index = obj_copy.output_file } }; |
| 119 | pub fn getOutput(oc: *const ObjCopy) std.Build.LazyPath { |
| 120 | return .{ .generated = .{ .index = oc.output_file } }; |
| 98 | 121 | } |
| 99 | 122 | |
| 100 | | pub fn getOutputSeparatedDebug(obj_copy: *const ObjCopy) ?std.Build.LazyPath { |
| 101 | | return if (obj_copy.output_file_debug.unwrap()) |index| .{ .generated = .{ .index = index } } else null; |
| 123 | pub fn getOutputSeparatedDebug(oc: *const ObjCopy) ?std.Build.LazyPath { |
| 124 | const df = oc.debug_file orelse return null; |
| 125 | return .{ .generated = .{ .index = df.output_file } }; |
| 102 | 126 | } |