| ... | ... | @@ -168,7 +168,7 @@ pub fn parseNameOrOrdinal(allocator: Allocator, reader: *std.Io.Reader) !NameOrO |
| 168 | 168 | } |
| 169 | 169 | |
| 170 | 170 | pub const CoffOptions = struct { |
| 171 | | target: std.coff.MachineType = .X64, |
| 171 | target: std.coff.IMAGE.FILE.MACHINE = .AMD64, |
| 172 | 172 | /// If true, zeroes will be written to all timestamp fields |
| 173 | 173 | reproducible: bool = true, |
| 174 | 174 | /// If true, the MEM_WRITE flag will not be set in the .rsrc section header |
| ... | ... | @@ -210,19 +210,19 @@ pub fn writeCoff(allocator: Allocator, writer: *std.Io.Writer, resources: []cons |
| 210 | 210 | const lengths = resource_tree.dataLengths(); |
| 211 | 211 | const byte_size_of_relocation = 10; |
| 212 | 212 | const relocations_len: u32 = @intCast(byte_size_of_relocation * resources.len); |
| 213 | | const pointer_to_rsrc01_data = @sizeOf(std.coff.CoffHeader) + (@sizeOf(std.coff.SectionHeader) * 2); |
| 213 | const pointer_to_rsrc01_data = @sizeOf(std.coff.Header) + (@sizeOf(std.coff.SectionHeader) * 2); |
| 214 | 214 | const pointer_to_relocations = pointer_to_rsrc01_data + lengths.rsrc01; |
| 215 | 215 | const pointer_to_rsrc02_data = pointer_to_relocations + relocations_len; |
| 216 | 216 | const pointer_to_symbol_table = pointer_to_rsrc02_data + lengths.rsrc02; |
| 217 | 217 | |
| 218 | 218 | const timestamp: i64 = if (options.reproducible) 0 else std.time.timestamp(); |
| 219 | 219 | const size_of_optional_header = 0; |
| 220 | | const machine_type: std.coff.MachineType = options.target; |
| 221 | | const flags = std.coff.CoffHeaderFlags{ |
| 222 | | .@"32BIT_MACHINE" = 1, |
| 220 | const machine_type: std.coff.IMAGE.FILE.MACHINE = options.target; |
| 221 | const flags = std.coff.Header.Flags{ |
| 222 | .@"32BIT_MACHINE" = true, |
| 223 | 223 | }; |
| 224 | 224 | const number_of_symbols = 5 + @as(u32, @intCast(resources.len)) + @intFromBool(options.define_external_symbol != null); |
| 225 | | const coff_header = std.coff.CoffHeader{ |
| 225 | const coff_header = std.coff.Header{ |
| 226 | 226 | .machine = machine_type, |
| 227 | 227 | .number_of_sections = 2, |
| 228 | 228 | .time_date_stamp = @as(u32, @truncate(@as(u64, @bitCast(timestamp)))), |
| ... | ... | @@ -245,9 +245,9 @@ pub fn writeCoff(allocator: Allocator, writer: *std.Io.Writer, resources: []cons |
| 245 | 245 | .number_of_relocations = @intCast(resources.len), |
| 246 | 246 | .number_of_linenumbers = 0, |
| 247 | 247 | .flags = .{ |
| 248 | | .CNT_INITIALIZED_DATA = 1, |
| 249 | | .MEM_WRITE = @intFromBool(!options.read_only), |
| 250 | | .MEM_READ = 1, |
| 248 | .CNT_INITIALIZED_DATA = true, |
| 249 | .MEM_WRITE = !options.read_only, |
| 250 | .MEM_READ = true, |
| 251 | 251 | }, |
| 252 | 252 | }; |
| 253 | 253 | try writer.writeStruct(rsrc01_header, .little); |
| ... | ... | @@ -263,9 +263,9 @@ pub fn writeCoff(allocator: Allocator, writer: *std.Io.Writer, resources: []cons |
| 263 | 263 | .number_of_relocations = 0, |
| 264 | 264 | .number_of_linenumbers = 0, |
| 265 | 265 | .flags = .{ |
| 266 | | .CNT_INITIALIZED_DATA = 1, |
| 267 | | .MEM_WRITE = @intFromBool(!options.read_only), |
| 268 | | .MEM_READ = 1, |
| 266 | .CNT_INITIALIZED_DATA = true, |
| 267 | .MEM_WRITE = !options.read_only, |
| 268 | .MEM_READ = true, |
| 269 | 269 | }, |
| 270 | 270 | }; |
| 271 | 271 | try writer.writeStruct(rsrc02_header, .little); |
| ... | ... | @@ -1005,9 +1005,9 @@ pub const supported_targets = struct { |
| 1005 | 1005 | x86_64, |
| 1006 | 1006 | aarch64, |
| 1007 | 1007 | |
| 1008 | | pub fn toCoffMachineType(arch: Arch) std.coff.MachineType { |
| 1008 | pub fn toCoffMachineType(arch: Arch) std.coff.IMAGE.FILE.MACHINE { |
| 1009 | 1009 | return switch (arch) { |
| 1010 | | .x64, .amd64, .x86_64 => .X64, |
| 1010 | .x64, .amd64, .x86_64 => .AMD64, |
| 1011 | 1011 | .x86, .i386 => .I386, |
| 1012 | 1012 | .arm, .armnt => .ARMNT, |
| 1013 | 1013 | .arm64, .aarch64 => .ARM64, |
| ... | ... | @@ -1079,26 +1079,26 @@ pub const supported_targets = struct { |
| 1079 | 1079 | }; |
| 1080 | 1080 | |
| 1081 | 1081 | // https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#type-indicators |
| 1082 | | pub fn rvaRelocationTypeIndicator(target: std.coff.MachineType) ?u16 { |
| 1082 | pub fn rvaRelocationTypeIndicator(target: std.coff.IMAGE.FILE.MACHINE) ?u16 { |
| 1083 | 1083 | return switch (target) { |
| 1084 | | .X64 => 0x3, // IMAGE_REL_AMD64_ADDR32NB |
| 1085 | | .I386 => 0x7, // IMAGE_REL_I386_DIR32NB |
| 1086 | | .ARMNT => 0x2, // IMAGE_REL_ARM_ADDR32NB |
| 1087 | | .ARM64, .ARM64EC, .ARM64X => 0x2, // IMAGE_REL_ARM64_ADDR32NB |
| 1088 | | .IA64 => 0x10, // IMAGE_REL_IA64_DIR32NB |
| 1084 | .AMD64 => @intFromEnum(std.coff.IMAGE.REL.AMD64.ADDR32NB), |
| 1085 | .I386 => @intFromEnum(std.coff.IMAGE.REL.I386.DIR32NB), |
| 1086 | .ARMNT => @intFromEnum(std.coff.IMAGE.REL.ARM.ADDR32NB), |
| 1087 | .ARM64, .ARM64EC, .ARM64X => @intFromEnum(std.coff.IMAGE.REL.ARM64.ADDR32NB), |
| 1088 | .IA64 => @intFromEnum(std.coff.IMAGE.REL.IA64.DIR32NB), |
| 1089 | 1089 | .EBC => 0x1, // This is what cvtres.exe writes for this target, unsure where it comes from |
| 1090 | 1090 | else => null, |
| 1091 | 1091 | }; |
| 1092 | 1092 | } |
| 1093 | 1093 | |
| 1094 | | pub fn isSupported(target: std.coff.MachineType) bool { |
| 1094 | pub fn isSupported(target: std.coff.IMAGE.FILE.MACHINE) bool { |
| 1095 | 1095 | return rvaRelocationTypeIndicator(target) != null; |
| 1096 | 1096 | } |
| 1097 | 1097 | |
| 1098 | 1098 | comptime { |
| 1099 | 1099 | // Enforce two things: |
| 1100 | 1100 | // 1. Arch enum field names are all lowercase (necessary for how fromStringIgnoreCase is implemented) |
| 1101 | | // 2. All enum fields in Arch have an associated RVA relocation type when converted to a coff.MachineType |
| 1101 | // 2. All enum fields in Arch have an associated RVA relocation type when converted to a coff.IMAGE.FILE.MACHINE |
| 1102 | 1102 | for (@typeInfo(Arch).@"enum".fields) |enum_field| { |
| 1103 | 1103 | const all_lower = all_lower: for (enum_field.name) |c| { |
| 1104 | 1104 | if (std.ascii.isUpper(c)) break :all_lower false; |