| ... | @@ -23,6 +23,7 @@ const Compilation = @import("../Compilation.zig"); | ... | @@ -23,6 +23,7 @@ const Compilation = @import("../Compilation.zig"); |
| 23 | const Liveness = @import("../Liveness.zig"); | 23 | const Liveness = @import("../Liveness.zig"); |
| 24 | const LlvmObject = @import("../codegen/llvm.zig").Object; | 24 | const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 25 | const Module = @import("../Module.zig"); | 25 | const Module = @import("../Module.zig"); |
| | 26 | const Object = @import("Coff/Object.zig"); |
| 26 | const StringTable = @import("strtab.zig").StringTable; | 27 | const StringTable = @import("strtab.zig").StringTable; |
| 27 | const TypedValue = @import("../TypedValue.zig"); | 28 | const TypedValue = @import("../TypedValue.zig"); |
| 28 | | 29 | |
| ... | @@ -39,6 +40,8 @@ error_flags: link.File.ErrorFlags = .{}, | ... | @@ -39,6 +40,8 @@ error_flags: link.File.ErrorFlags = .{}, |
| 39 | ptr_width: PtrWidth, | 40 | ptr_width: PtrWidth, |
| 40 | page_size: u32, | 41 | page_size: u32, |
| 41 | | 42 | |
| | 43 | objects: std.ArrayListUnmanaged(Object) = .{}, |
| | 44 | |
| 42 | sections: std.MultiArrayList(Section) = .{}, | 45 | sections: std.MultiArrayList(Section) = .{}, |
| 43 | data_directories: [16]coff.ImageDataDirectory, | 46 | data_directories: [16]coff.ImageDataDirectory, |
| 44 | | 47 | |
| ... | @@ -185,6 +188,11 @@ pub fn deinit(self: *Coff) void { | ... | @@ -185,6 +188,11 @@ pub fn deinit(self: *Coff) void { |
| 185 | if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa); | 188 | if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa); |
| 186 | } | 189 | } |
| 187 | | 190 | |
| | 191 | for (self.objects.items) |*object| { |
| | 192 | object.deinit(gpa); |
| | 193 | } |
| | 194 | self.objects.deinit(gpa); |
| | 195 | |
| 188 | for (self.sections.items(.free_list)) |*free_list| { | 196 | for (self.sections.items(.free_list)) |*free_list| { |
| 189 | free_list.deinit(gpa); | 197 | free_list.deinit(gpa); |
| 190 | } | 198 | } |
| ... | @@ -211,15 +219,15 @@ fn populateMissingMetadata(self: *Coff) !void { | ... | @@ -211,15 +219,15 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 211 | | 219 | |
| 212 | if (self.text_section_index == null) { | 220 | if (self.text_section_index == null) { |
| 213 | self.text_section_index = @intCast(u16, self.sections.slice().len); | 221 | self.text_section_index = @intCast(u16, self.sections.slice().len); |
| 214 | const file_size = self.base.options.program_code_size_hint; | 222 | const file_size = @intCast(u32, self.base.options.program_code_size_hint); |
| 215 | const off = self.findFreeSpace(file_size, self.page_size); // TODO we are over-aligning in file; we should track both in file and in memory pointers | 223 | const off = self.findFreeSpace(file_size, self.page_size); // TODO we are over-aligning in file; we should track both in file and in memory pointers |
| 216 | log.debug("found .text free space 0x{x} to 0x{x}", .{ off, off + file_size }); | 224 | log.debug("found .text free space 0x{x} to 0x{x}", .{ off, off + file_size }); |
| 217 | var header = coff.SectionHeader{ | 225 | var header = coff.SectionHeader{ |
| 218 | .name = undefined, | 226 | .name = undefined, |
| 219 | .virtual_size = @intCast(u32, file_size), | 227 | .virtual_size = file_size, |
| 220 | .virtual_address = @intCast(u32, off), | 228 | .virtual_address = off, |
| 221 | .size_of_raw_data = @intCast(u32, file_size), | 229 | .size_of_raw_data = file_size, |
| 222 | .pointer_to_raw_data = @intCast(u32, off), | 230 | .pointer_to_raw_data = off, |
| 223 | .pointer_to_relocations = 0, | 231 | .pointer_to_relocations = 0, |
| 224 | .pointer_to_linenumbers = 0, | 232 | .pointer_to_linenumbers = 0, |
| 225 | .number_of_relocations = 0, | 233 | .number_of_relocations = 0, |
| ... | @@ -236,15 +244,15 @@ fn populateMissingMetadata(self: *Coff) !void { | ... | @@ -236,15 +244,15 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 236 | | 244 | |
| 237 | if (self.pdata_section_index == null) { | 245 | if (self.pdata_section_index == null) { |
| 238 | self.pdata_section_index = @intCast(u16, self.sections.slice().len); | 246 | self.pdata_section_index = @intCast(u16, self.sections.slice().len); |
| 239 | const file_size = self.base.options.symbol_count_hint; | 247 | const file_size = @intCast(u32, self.base.options.symbol_count_hint); |
| 240 | const off = self.findFreeSpace(file_size, self.page_size); | 248 | const off = self.findFreeSpace(file_size, self.page_size); |
| 241 | log.debug("found .pdata free space 0x{x} to 0x{x}", .{ off, off + file_size }); | 249 | log.debug("found .pdata free space 0x{x} to 0x{x}", .{ off, off + file_size }); |
| 242 | var header = coff.SectionHeader{ | 250 | var header = coff.SectionHeader{ |
| 243 | .name = undefined, | 251 | .name = undefined, |
| 244 | .virtual_size = @intCast(u32, file_size), | 252 | .virtual_size = file_size, |
| 245 | .virtual_address = @intCast(u32, off), | 253 | .virtual_address = off, |
| 246 | .size_of_raw_data = @intCast(u32, file_size), | 254 | .size_of_raw_data = file_size, |
| 247 | .pointer_to_raw_data = @intCast(u32, off), | 255 | .pointer_to_raw_data = off, |
| 248 | .pointer_to_relocations = 0, | 256 | .pointer_to_relocations = 0, |
| 249 | .pointer_to_linenumbers = 0, | 257 | .pointer_to_linenumbers = 0, |
| 250 | .number_of_relocations = 0, | 258 | .number_of_relocations = 0, |
| ... | @@ -260,15 +268,15 @@ fn populateMissingMetadata(self: *Coff) !void { | ... | @@ -260,15 +268,15 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 260 | | 268 | |
| 261 | if (self.rdata_section_index == null) { | 269 | if (self.rdata_section_index == null) { |
| 262 | self.rdata_section_index = @intCast(u16, self.sections.slice().len); | 270 | self.rdata_section_index = @intCast(u16, self.sections.slice().len); |
| 263 | const file_size = 1024; | 271 | const file_size: u32 = 1024; |
| 264 | const off = self.findFreeSpace(file_size, self.page_size); | 272 | const off = self.findFreeSpace(file_size, self.page_size); |
| 265 | log.debug("found .rdata free space 0x{x} to 0x{x}", .{ off, off + file_size }); | 273 | log.debug("found .rdata free space 0x{x} to 0x{x}", .{ off, off + file_size }); |
| 266 | var header = coff.SectionHeader{ | 274 | var header = coff.SectionHeader{ |
| 267 | .name = undefined, | 275 | .name = undefined, |
| 268 | .virtual_size = @intCast(u32, file_size), | 276 | .virtual_size = file_size, |
| 269 | .virtual_address = @intCast(u32, off), | 277 | .virtual_address = off, |
| 270 | .size_of_raw_data = @intCast(u32, file_size), | 278 | .size_of_raw_data = file_size, |
| 271 | .pointer_to_raw_data = @intCast(u32, off), | 279 | .pointer_to_raw_data = off, |
| 272 | .pointer_to_relocations = 0, | 280 | .pointer_to_relocations = 0, |
| 273 | .pointer_to_linenumbers = 0, | 281 | .pointer_to_linenumbers = 0, |
| 274 | .number_of_relocations = 0, | 282 | .number_of_relocations = 0, |
| ... | @@ -284,15 +292,15 @@ fn populateMissingMetadata(self: *Coff) !void { | ... | @@ -284,15 +292,15 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 284 | | 292 | |
| 285 | if (self.data_section_index == null) { | 293 | if (self.data_section_index == null) { |
| 286 | self.data_section_index = @intCast(u16, self.sections.slice().len); | 294 | self.data_section_index = @intCast(u16, self.sections.slice().len); |
| 287 | const file_size = 1024; | 295 | const file_size: u32 = 1024; |
| 288 | const off = self.findFreeSpace(file_size, self.page_size); | 296 | const off = self.findFreeSpace(file_size, self.page_size); |
| 289 | log.debug("found .data free space 0x{x} to 0x{x}", .{ off, off + file_size }); | 297 | log.debug("found .data free space 0x{x} to 0x{x}", .{ off, off + file_size }); |
| 290 | var header = coff.SectionHeader{ | 298 | var header = coff.SectionHeader{ |
| 291 | .name = undefined, | 299 | .name = undefined, |
| 292 | .virtual_size = @intCast(u32, file_size), | 300 | .virtual_size = file_size, |
| 293 | .virtual_address = @intCast(u32, off), | 301 | .virtual_address = off, |
| 294 | .size_of_raw_data = @intCast(u32, file_size), | 302 | .size_of_raw_data = file_size, |
| 295 | .pointer_to_raw_data = @intCast(u32, off), | 303 | .pointer_to_raw_data = off, |
| 296 | .pointer_to_relocations = 0, | 304 | .pointer_to_relocations = 0, |
| 297 | .pointer_to_linenumbers = 0, | 305 | .pointer_to_linenumbers = 0, |
| 298 | .number_of_relocations = 0, | 306 | .number_of_relocations = 0, |
| ... | @@ -309,7 +317,7 @@ fn populateMissingMetadata(self: *Coff) !void { | ... | @@ -309,7 +317,7 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 309 | | 317 | |
| 310 | if (self.strtab_offset == null) { | 318 | if (self.strtab_offset == null) { |
| 311 | try self.strtab.buffer.append(gpa, 0); | 319 | try self.strtab.buffer.append(gpa, 0); |
| 312 | self.strtab_offset = @intCast(u32, self.findFreeSpace(self.strtab.len(), 1)); | 320 | self.strtab_offset = self.findFreeSpace(@intCast(u32, self.strtab.len()), 1); |
| 313 | log.debug("found strtab free space 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + self.strtab.len() }); | 321 | log.debug("found strtab free space 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + self.strtab.len() }); |
| 314 | } | 322 | } |
| 315 | | 323 | |
| ... | @@ -334,7 +342,7 @@ pub fn allocateDeclIndexes(self: *Coff, decl_index: Module.Decl.Index) !void { | ... | @@ -334,7 +342,7 @@ pub fn allocateDeclIndexes(self: *Coff, decl_index: Module.Decl.Index) !void { |
| 334 | try self.decls.putNoClobber(gpa, decl_index, null); | 342 | try self.decls.putNoClobber(gpa, decl_index, null); |
| 335 | } | 343 | } |
| 336 | | 344 | |
| 337 | fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u64, alignment: u64, sect_id: u16) !u64 { | 345 | fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32, sect_id: u16) !u32 { |
| 338 | const tracy = trace(@src()); | 346 | const tracy = trace(@src()); |
| 339 | defer tracy.end(); | 347 | defer tracy.end(); |
| 340 | | 348 | |
| ... | @@ -362,10 +370,10 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u64, alignment: u64, se | ... | @@ -362,10 +370,10 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u64, alignment: u64, se |
| 362 | const sym = big_atom.getSymbol(self); | 370 | const sym = big_atom.getSymbol(self); |
| 363 | const capacity = big_atom.capacity(self); | 371 | const capacity = big_atom.capacity(self); |
| 364 | const ideal_capacity = if (header.isCode()) padToIdeal(capacity) else capacity; | 372 | const ideal_capacity = if (header.isCode()) padToIdeal(capacity) else capacity; |
| 365 | const ideal_capacity_end_vaddr = math.add(u64, sym.n_value, ideal_capacity) catch ideal_capacity; | 373 | const ideal_capacity_end_vaddr = math.add(u32, sym.value, ideal_capacity) catch ideal_capacity; |
| 366 | const capacity_end_vaddr = sym.n_value + capacity; | 374 | const capacity_end_vaddr = sym.value + capacity; |
| 367 | const new_start_vaddr_unaligned = capacity_end_vaddr - new_atom_ideal_capacity; | 375 | const new_start_vaddr_unaligned = capacity_end_vaddr - new_atom_ideal_capacity; |
| 368 | const new_start_vaddr = mem.alignBackwardGeneric(u64, new_start_vaddr_unaligned, alignment); | 376 | const new_start_vaddr = mem.alignBackwardGeneric(u32, new_start_vaddr_unaligned, alignment); |
| 369 | if (new_start_vaddr < ideal_capacity_end_vaddr) { | 377 | if (new_start_vaddr < ideal_capacity_end_vaddr) { |
| 370 | // Additional bookkeeping here to notice if this free list node | 378 | // Additional bookkeeping here to notice if this free list node |
| 371 | // should be deleted because the atom that it points to has grown to take up | 379 | // should be deleted because the atom that it points to has grown to take up |
| ... | @@ -392,23 +400,30 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u64, alignment: u64, se | ... | @@ -392,23 +400,30 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u64, alignment: u64, se |
| 392 | } else if (maybe_last_atom.*) |last| { | 400 | } else if (maybe_last_atom.*) |last| { |
| 393 | const last_symbol = last.getSymbol(self); | 401 | const last_symbol = last.getSymbol(self); |
| 394 | const ideal_capacity = if (header.isCode()) padToIdeal(last.size) else last.size; | 402 | const ideal_capacity = if (header.isCode()) padToIdeal(last.size) else last.size; |
| 395 | const ideal_capacity_end_vaddr = last_symbol.n_value + ideal_capacity; | 403 | const ideal_capacity_end_vaddr = last_symbol.value + ideal_capacity; |
| 396 | const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, alignment); | 404 | const new_start_vaddr = mem.alignForwardGeneric(u32, ideal_capacity_end_vaddr, alignment); |
| 397 | atom_placement = last; | 405 | atom_placement = last; |
| 398 | break :blk new_start_vaddr; | 406 | break :blk new_start_vaddr; |
| 399 | } else { | 407 | } else { |
| 400 | break :blk mem.alignForwardGeneric(u64, header.addr, alignment); | 408 | break :blk mem.alignForwardGeneric(u32, header.virtual_address, alignment); |
| 401 | } | 409 | } |
| 402 | }; | 410 | }; |
| 403 | | 411 | |
| 404 | const expand_section = atom_placement == null or atom_placement.?.next == null; | 412 | const expand_section = atom_placement == null or atom_placement.?.next == null; |
| 405 | if (expand_section) { | 413 | if (expand_section) { |
| 406 | @panic("TODO expand section in allocateAtom"); | 414 | const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); |
| | 415 | const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address; |
| | 416 | if (needed_size > sect_capacity) { |
| | 417 | @panic("TODO move section"); |
| | 418 | } |
| | 419 | maybe_last_atom.* = atom; |
| | 420 | header.virtual_size = needed_size; |
| | 421 | header.size_of_raw_data = needed_size; |
| 407 | } | 422 | } |
| 408 | | 423 | |
| 409 | if (header.getAlignment() < alignment) { | 424 | // if (header.getAlignment().? < alignment) { |
| 410 | header.setAlignment(alignment); | 425 | // header.setAlignment(alignment); |
| 411 | } | 426 | // } |
| 412 | atom.size = new_atom_size; | 427 | atom.size = new_atom_size; |
| 413 | atom.alignment = alignment; | 428 | atom.alignment = alignment; |
| 414 | | 429 | |
| ... | @@ -465,30 +480,39 @@ fn allocateSymbol(self: *Coff) !u32 { | ... | @@ -465,30 +480,39 @@ fn allocateSymbol(self: *Coff) !u32 { |
| 465 | pub fn allocateGotEntry(self: *Coff, target: SymbolWithLoc) !u32 { | 480 | pub fn allocateGotEntry(self: *Coff, target: SymbolWithLoc) !u32 { |
| 466 | const gpa = self.base.allocator; | 481 | const gpa = self.base.allocator; |
| 467 | try self.got_entries.ensureUnusedCapacity(gpa, 1); | 482 | try self.got_entries.ensureUnusedCapacity(gpa, 1); |
| 468 | if (self.got_entries_free_list.popOrNull()) |index| { | 483 | const index: u32 = blk: { |
| 469 | log.debug(" (reusing GOT entry index {d})", .{index}); | 484 | if (self.got_entries_free_list.popOrNull()) |index| { |
| 470 | if (self.got_entries.getIndex(target)) |existing| { | 485 | log.debug(" (reusing GOT entry index {d})", .{index}); |
| 471 | assert(existing == index); | 486 | if (self.got_entries.getIndex(target)) |existing| { |
| | 487 | assert(existing == index); |
| | 488 | } |
| | 489 | break :blk index; |
| | 490 | } else { |
| | 491 | log.debug(" (allocating GOT entry at index {d})", .{self.got_entries.keys().len}); |
| | 492 | const index = @intCast(u32, self.got_entries.keys().len); |
| | 493 | self.got_entries.putAssumeCapacityNoClobber(target, 0); |
| | 494 | break :blk index; |
| 472 | } | 495 | } |
| 473 | self.got_entries.keys()[index] = target; | 496 | }; |
| 474 | return index; | 497 | self.got_entries.keys()[index] = target; |
| 475 | } else { | 498 | return index; |
| 476 | log.debug(" (allocating GOT entry at index {d})", .{self.got_entries.keys().len}); | 499 | } |
| 477 | const index = @intCast(u32, self.got_entries.keys().len); | 500 | |
| 478 | try self.got_entries.putAssumeCapacityNoClobber(target, 0); | 501 | fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom { |
| 479 | return index; | 502 | _ = self; |
| 480 | } | 503 | _ = target; |
| | 504 | @panic("TODO createGotAtom"); |
| 481 | } | 505 | } |
| 482 | | 506 | |
| 483 | fn growAtom(self: *Coff, atom: *Atom, new_atom_size: u64, alignment: u64, sect_id: u16) !u64 { | 507 | fn growAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32, sect_id: u16) !u32 { |
| 484 | const sym = atom.getSymbol(self); | 508 | const sym = atom.getSymbol(self); |
| 485 | const align_ok = mem.alignBackwardGeneric(u64, sym.value, alignment) == sym.value; | 509 | const align_ok = mem.alignBackwardGeneric(u32, sym.value, alignment) == sym.value; |
| 486 | const need_realloc = !align_ok or new_atom_size > atom.capacity(self); | 510 | const need_realloc = !align_ok or new_atom_size > atom.capacity(self); |
| 487 | if (!need_realloc) return sym.value; | 511 | if (!need_realloc) return sym.value; |
| 488 | return self.allocateAtom(atom, new_atom_size, alignment, sect_id); | 512 | return self.allocateAtom(atom, new_atom_size, alignment, sect_id); |
| 489 | } | 513 | } |
| 490 | | 514 | |
| 491 | fn shrinkAtom(self: *Coff, atom: *Atom, new_block_size: u64, sect_id: u16) void { | 515 | fn shrinkAtom(self: *Coff, atom: *Atom, new_block_size: u32, sect_id: u16) void { |
| 492 | _ = self; | 516 | _ = self; |
| 493 | _ = atom; | 517 | _ = atom; |
| 494 | _ = new_block_size; | 518 | _ = new_block_size; |
| ... | @@ -497,6 +521,22 @@ fn shrinkAtom(self: *Coff, atom: *Atom, new_block_size: u64, sect_id: u16) void | ... | @@ -497,6 +521,22 @@ fn shrinkAtom(self: *Coff, atom: *Atom, new_block_size: u64, sect_id: u16) void |
| 497 | // capacity, insert a free list node for it. | 521 | // capacity, insert a free list node for it. |
| 498 | } | 522 | } |
| 499 | | 523 | |
| | 524 | fn writeAtom(self: *Coff, atom: *Atom, code: []const u8, sect_id: u16) !void { |
| | 525 | const section = self.sections.get(sect_id); |
| | 526 | const sym = atom.getSymbol(self); |
| | 527 | const file_offset = section.header.pointer_to_raw_data + sym.value - section.header.virtual_address; |
| | 528 | try self.resolveRelocs(atom, code); |
| | 529 | log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ atom.getName(self), file_offset }); |
| | 530 | try self.base.file.?.pwriteAll(code, file_offset); |
| | 531 | } |
| | 532 | |
| | 533 | fn resolveRelocs(self: *Coff, atom: *Atom, code: []const u8) !void { |
| | 534 | _ = self; |
| | 535 | _ = atom; |
| | 536 | _ = code; |
| | 537 | log.debug("TODO resolveRelocs", .{}); |
| | 538 | } |
| | 539 | |
| 500 | fn freeAtom(self: *Coff, atom: *Atom, sect_id: u16) void { | 540 | fn freeAtom(self: *Coff, atom: *Atom, sect_id: u16) void { |
| 501 | log.debug("freeAtom {*}", .{atom}); | 541 | log.debug("freeAtom {*}", .{atom}); |
| 502 | | 542 | |
| ... | @@ -583,8 +623,7 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live | ... | @@ -583,8 +623,7 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live |
| 583 | }, | 623 | }, |
| 584 | }; | 624 | }; |
| 585 | | 625 | |
| 586 | const sym = try self.updateDeclCode(decl_index, code); | 626 | try self.updateDeclCode(decl_index, code); |
| 587 | log.debug("updated decl code has sym {}", .{sym}); | | |
| 588 | | 627 | |
| 589 | // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated. | 628 | // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated. |
| 590 | const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{}; | 629 | const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{}; |
| ... | @@ -640,20 +679,104 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! | ... | @@ -640,20 +679,104 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! |
| 640 | }, | 679 | }, |
| 641 | }; | 680 | }; |
| 642 | | 681 | |
| 643 | const sym = try self.updateDeclCode(decl_index, code); | 682 | try self.updateDeclCode(decl_index, code); |
| 644 | log.debug("updated decl code for {}", .{sym}); | | |
| 645 | | 683 | |
| 646 | // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated. | 684 | // Since we updated the vaddr and the size, each corresponding export symbol also needs to be updated. |
| 647 | const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{}; | 685 | const decl_exports = module.decl_exports.get(decl_index) orelse &[0]*Module.Export{}; |
| 648 | return self.updateDeclExports(module, decl_index, decl_exports); | 686 | return self.updateDeclExports(module, decl_index, decl_exports); |
| 649 | } | 687 | } |
| 650 | | 688 | |
| 651 | fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8) !*coff.Symbol { | 689 | fn getDeclOutputSection(self: *Coff, decl: *Module.Decl) u16 { |
| 652 | _ = self; | 690 | const ty = decl.ty; |
| 653 | _ = decl_index; | 691 | const zig_ty = ty.zigTypeTag(); |
| 654 | _ = code; | 692 | const val = decl.val; |
| 655 | log.debug("TODO updateDeclCode", .{}); | 693 | const index: u16 = blk: { |
| 656 | return &self.locals.items[0]; | 694 | if (val.isUndefDeep()) { |
| | 695 | // TODO in release-fast and release-small, we should put undef in .bss |
| | 696 | break :blk self.data_section_index.?; |
| | 697 | } |
| | 698 | |
| | 699 | switch (zig_ty) { |
| | 700 | .Fn => break :blk self.text_section_index.?, |
| | 701 | else => { |
| | 702 | if (val.castTag(.variable)) |_| { |
| | 703 | break :blk self.data_section_index.?; |
| | 704 | } |
| | 705 | break :blk self.rdata_section_index.?; |
| | 706 | }, |
| | 707 | } |
| | 708 | }; |
| | 709 | return index; |
| | 710 | } |
| | 711 | |
| | 712 | fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8) !void { |
| | 713 | const gpa = self.base.allocator; |
| | 714 | const mod = self.base.options.module.?; |
| | 715 | const decl = mod.declPtr(decl_index); |
| | 716 | |
| | 717 | const decl_name = try decl.getFullyQualifiedName(mod); |
| | 718 | defer gpa.free(decl_name); |
| | 719 | |
| | 720 | log.debug("updateDeclCode {s}{*}", .{ decl_name, decl }); |
| | 721 | const required_alignment = decl.getAlignment(self.base.options.target); |
| | 722 | |
| | 723 | const decl_ptr = self.decls.getPtr(decl_index).?; |
| | 724 | if (decl_ptr.* == null) { |
| | 725 | decl_ptr.* = self.getDeclOutputSection(decl); |
| | 726 | } |
| | 727 | const sect_index = decl_ptr.*.?; |
| | 728 | |
| | 729 | const code_len = @intCast(u32, code.len); |
| | 730 | const atom = &decl.link.coff; |
| | 731 | assert(atom.sym_index != 0); // Caller forgot to allocateDeclIndexes() |
| | 732 | if (atom.size != 0) { |
| | 733 | const sym = atom.getSymbolPtr(self); |
| | 734 | const capacity = atom.capacity(self); |
| | 735 | const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment); |
| | 736 | |
| | 737 | if (need_realloc) { |
| | 738 | const vaddr = try self.growAtom(atom, code_len, required_alignment, sect_index); |
| | 739 | log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, sym.value, vaddr }); |
| | 740 | log.debug(" (required alignment 0x{x}", .{required_alignment}); |
| | 741 | |
| | 742 | if (vaddr != sym.value) { |
| | 743 | sym.value = vaddr; |
| | 744 | log.debug(" (updating GOT entry)", .{}); |
| | 745 | var buffer: [@sizeOf(u64)]u8 = undefined; |
| | 746 | const got_atom = self.getGotAtomForSymbol(.{ .sym_index = atom.sym_index, .file = null }).?; |
| | 747 | try self.writeAtom(got_atom, &buffer, self.pdata_section_index.?); |
| | 748 | } |
| | 749 | } else if (code_len < atom.size) { |
| | 750 | self.shrinkAtom(atom, code_len, sect_index); |
| | 751 | } |
| | 752 | atom.size = code_len; |
| | 753 | try self.setSymbolName(sym, decl_name); |
| | 754 | sym.section_number = @intToEnum(coff.SectionNumber, sect_index + 1); |
| | 755 | sym.@"type" = .{ .complex_type = .FUNCTION, .base_type = .NULL }; |
| | 756 | sym.storage_class = .NULL; |
| | 757 | } else { |
| | 758 | const sym = atom.getSymbolPtr(self); |
| | 759 | try self.setSymbolName(sym, decl_name); |
| | 760 | const vaddr = try self.allocateAtom(atom, code_len, required_alignment, sect_index); |
| | 761 | errdefer self.freeAtom(atom, sect_index); |
| | 762 | |
| | 763 | log.debug("allocated atom for {s} at 0x{x}", .{ decl_name, vaddr }); |
| | 764 | |
| | 765 | atom.size = code_len; |
| | 766 | sym.value = vaddr; |
| | 767 | sym.section_number = @intToEnum(coff.SectionNumber, sect_index + 1); |
| | 768 | sym.@"type" = .{ .complex_type = .FUNCTION, .base_type = .NULL }; |
| | 769 | sym.storage_class = .NULL; |
| | 770 | |
| | 771 | const got_target = SymbolWithLoc{ .sym_index = atom.sym_index, .file = null }; |
| | 772 | _ = try self.allocateGotEntry(got_target); |
| | 773 | const got_atom = try self.createGotAtom(got_target); |
| | 774 | |
| | 775 | var buffer: [@sizeOf(u64)]u8 = undefined; |
| | 776 | try self.writeAtom(got_atom, &buffer, self.pdata_section_index.?); |
| | 777 | } |
| | 778 | |
| | 779 | try self.writeAtom(atom, code, sect_index); |
| 657 | } | 780 | } |
| 658 | | 781 | |
| 659 | pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { | 782 | pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { |
| ... | @@ -701,40 +824,142 @@ pub fn updateDeclExports( | ... | @@ -701,40 +824,142 @@ pub fn updateDeclExports( |
| 701 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 824 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 702 | } | 825 | } |
| 703 | | 826 | |
| 704 | // Even in the case of LLVM, we need to notice certain exported symbols in order to | 827 | if (build_options.have_llvm) { |
| 705 | // detect the default subsystem. | 828 | // Even in the case of LLVM, we need to notice certain exported symbols in order to |
| | 829 | // detect the default subsystem. |
| | 830 | for (exports) |exp| { |
| | 831 | const exported_decl = module.declPtr(exp.exported_decl); |
| | 832 | if (exported_decl.getFunction() == null) continue; |
| | 833 | const winapi_cc = switch (self.base.options.target.cpu.arch) { |
| | 834 | .i386 => std.builtin.CallingConvention.Stdcall, |
| | 835 | else => std.builtin.CallingConvention.C, |
| | 836 | }; |
| | 837 | const decl_cc = exported_decl.ty.fnCallingConvention(); |
| | 838 | if (decl_cc == .C and mem.eql(u8, exp.options.name, "main") and |
| | 839 | self.base.options.link_libc) |
| | 840 | { |
| | 841 | module.stage1_flags.have_c_main = true; |
| | 842 | } else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) { |
| | 843 | if (mem.eql(u8, exp.options.name, "WinMain")) { |
| | 844 | module.stage1_flags.have_winmain = true; |
| | 845 | } else if (mem.eql(u8, exp.options.name, "wWinMain")) { |
| | 846 | module.stage1_flags.have_wwinmain = true; |
| | 847 | } else if (mem.eql(u8, exp.options.name, "WinMainCRTStartup")) { |
| | 848 | module.stage1_flags.have_winmain_crt_startup = true; |
| | 849 | } else if (mem.eql(u8, exp.options.name, "wWinMainCRTStartup")) { |
| | 850 | module.stage1_flags.have_wwinmain_crt_startup = true; |
| | 851 | } else if (mem.eql(u8, exp.options.name, "DllMainCRTStartup")) { |
| | 852 | module.stage1_flags.have_dllmain_crt_startup = true; |
| | 853 | } |
| | 854 | } |
| | 855 | } |
| | 856 | |
| | 857 | if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports); |
| | 858 | } |
| | 859 | |
| | 860 | const tracy = trace(@src()); |
| | 861 | defer tracy.end(); |
| | 862 | |
| | 863 | const gpa = self.base.allocator; |
| | 864 | |
| | 865 | const decl = module.declPtr(decl_index); |
| | 866 | const atom = &decl.link.coff; |
| | 867 | if (atom.sym_index == 0) return; |
| | 868 | const decl_sym = atom.getSymbol(self); |
| | 869 | |
| 706 | for (exports) |exp| { | 870 | for (exports) |exp| { |
| 707 | const exported_decl = module.declPtr(exp.exported_decl); | 871 | log.debug("adding new export '{s}'", .{exp.options.name}); |
| 708 | if (exported_decl.getFunction() == null) continue; | 872 | |
| 709 | const winapi_cc = switch (self.base.options.target.cpu.arch) { | 873 | if (exp.options.section) |section_name| { |
| 710 | .i386 => std.builtin.CallingConvention.Stdcall, | 874 | if (!mem.eql(u8, section_name, ".text")) { |
| 711 | else => std.builtin.CallingConvention.C, | 875 | try module.failed_exports.putNoClobber( |
| 712 | }; | 876 | module.gpa, |
| 713 | const decl_cc = exported_decl.ty.fnCallingConvention(); | 877 | exp, |
| 714 | if (decl_cc == .C and mem.eql(u8, exp.options.name, "main") and | 878 | try Module.ErrorMsg.create( |
| 715 | self.base.options.link_libc) | 879 | gpa, |
| 716 | { | 880 | decl.srcLoc(), |
| 717 | module.stage1_flags.have_c_main = true; | 881 | "Unimplemented: ExportOptions.section", |
| 718 | } else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) { | 882 | .{}, |
| 719 | if (mem.eql(u8, exp.options.name, "WinMain")) { | 883 | ), |
| 720 | module.stage1_flags.have_winmain = true; | 884 | ); |
| 721 | } else if (mem.eql(u8, exp.options.name, "wWinMain")) { | 885 | continue; |
| 722 | module.stage1_flags.have_wwinmain = true; | | |
| 723 | } else if (mem.eql(u8, exp.options.name, "WinMainCRTStartup")) { | | |
| 724 | module.stage1_flags.have_winmain_crt_startup = true; | | |
| 725 | } else if (mem.eql(u8, exp.options.name, "wWinMainCRTStartup")) { | | |
| 726 | module.stage1_flags.have_wwinmain_crt_startup = true; | | |
| 727 | } else if (mem.eql(u8, exp.options.name, "DllMainCRTStartup")) { | | |
| 728 | module.stage1_flags.have_dllmain_crt_startup = true; | | |
| 729 | } | 886 | } |
| 730 | } | 887 | } |
| | 888 | |
| | 889 | if (exp.options.linkage == .LinkOnce) { |
| | 890 | try module.failed_exports.putNoClobber( |
| | 891 | module.gpa, |
| | 892 | exp, |
| | 893 | try Module.ErrorMsg.create( |
| | 894 | gpa, |
| | 895 | decl.srcLoc(), |
| | 896 | "Unimplemented: GlobalLinkage.LinkOnce", |
| | 897 | .{}, |
| | 898 | ), |
| | 899 | ); |
| | 900 | continue; |
| | 901 | } |
| | 902 | |
| | 903 | const sym_index = exp.link.macho.sym_index orelse blk: { |
| | 904 | const sym_index = try self.allocateSymbol(); |
| | 905 | exp.link.coff.sym_index = sym_index; |
| | 906 | break :blk sym_index; |
| | 907 | }; |
| | 908 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| | 909 | const sym = self.getSymbolPtr(sym_loc); |
| | 910 | try self.setSymbolName(sym, exp.options.name); |
| | 911 | sym.value = decl_sym.value; |
| | 912 | sym.section_number = @intToEnum(coff.SectionNumber, self.text_section_index.? + 1); |
| | 913 | sym.@"type" = .{ .complex_type = .FUNCTION, .base_type = .NULL }; |
| | 914 | |
| | 915 | switch (exp.options.linkage) { |
| | 916 | .Strong => { |
| | 917 | sym.storage_class = .EXTERNAL; |
| | 918 | }, |
| | 919 | .Internal => @panic("TODO Internal"), |
| | 920 | .Weak => @panic("TODO WeakExternal"), |
| | 921 | else => unreachable, |
| | 922 | } |
| | 923 | |
| | 924 | self.resolveGlobalSymbol(sym_loc) catch |err| switch (err) { |
| | 925 | error.MultipleSymbolDefinitions => { |
| | 926 | const global = self.globals.get(exp.options.name).?; |
| | 927 | if (sym_loc.sym_index != global.sym_index and global.file != null) { |
| | 928 | _ = try module.failed_exports.put(module.gpa, exp, try Module.ErrorMsg.create( |
| | 929 | gpa, |
| | 930 | decl.srcLoc(), |
| | 931 | \\LinkError: symbol '{s}' defined multiple times |
| | 932 | \\ first definition in '{s}' |
| | 933 | , |
| | 934 | .{ exp.options.name, self.objects.items[global.file.?].name }, |
| | 935 | )); |
| | 936 | } |
| | 937 | }, |
| | 938 | else => |e| return e, |
| | 939 | }; |
| 731 | } | 940 | } |
| | 941 | } |
| 732 | | 942 | |
| 733 | if (build_options.have_llvm) { | 943 | fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void { |
| 734 | if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports); | 944 | const gpa = self.base.allocator; |
| | 945 | const sym = self.getSymbol(current); |
| | 946 | _ = sym; |
| | 947 | const sym_name = self.getSymbolName(current); |
| | 948 | |
| | 949 | const name = try gpa.dupe(u8, sym_name); |
| | 950 | const global_index = @intCast(u32, self.globals.values().len); |
| | 951 | _ = global_index; |
| | 952 | const gop = try self.globals.getOrPut(gpa, name); |
| | 953 | defer if (gop.found_existing) gpa.free(name); |
| | 954 | |
| | 955 | if (!gop.found_existing) { |
| | 956 | gop.value_ptr.* = current; |
| | 957 | // TODO undef + tentative |
| | 958 | return; |
| 735 | } | 959 | } |
| 736 | | 960 | |
| 737 | log.debug("TODO updateDeclExports", .{}); | 961 | log.debug("TODO finish resolveGlobalSymbols implementation", .{}); |
| | 962 | return error.MultipleSymbolDefinitions; |
| 738 | } | 963 | } |
| 739 | | 964 | |
| 740 | pub fn flush(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void { | 965 | pub fn flush(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| ... | @@ -805,7 +1030,7 @@ pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl: *Module.Decl) !v | ... | @@ -805,7 +1030,7 @@ pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl: *Module.Decl) !v |
| 805 | | 1030 | |
| 806 | fn writeStrtab(self: *Coff) !void { | 1031 | fn writeStrtab(self: *Coff) !void { |
| 807 | const allocated_size = self.allocatedSize(self.strtab_offset.?); | 1032 | const allocated_size = self.allocatedSize(self.strtab_offset.?); |
| 808 | const needed_size = self.strtab.len(); | 1033 | const needed_size = @intCast(u32, self.strtab.len()); |
| 809 | | 1034 | |
| 810 | if (needed_size > allocated_size) { | 1035 | if (needed_size > allocated_size) { |
| 811 | self.strtab_offset = null; | 1036 | self.strtab_offset = null; |
| ... | @@ -870,7 +1095,7 @@ fn writeHeader(self: *Coff) !void { | ... | @@ -870,7 +1095,7 @@ fn writeHeader(self: *Coff) !void { |
| 870 | .NX_COMPAT = 1, // We are compatible with Data Execution Prevention | 1095 | .NX_COMPAT = 1, // We are compatible with Data Execution Prevention |
| 871 | }; | 1096 | }; |
| 872 | const subsystem: coff.Subsystem = .WINDOWS_CUI; | 1097 | const subsystem: coff.Subsystem = .WINDOWS_CUI; |
| 873 | const size_of_headers: u32 = @intCast(u32, self.getSizeOfHeaders()); | 1098 | const size_of_headers: u32 = self.getSizeOfHeaders(); |
| 874 | const size_of_image_aligned: u32 = mem.alignForwardGeneric(u32, size_of_headers, self.page_size); | 1099 | const size_of_image_aligned: u32 = mem.alignForwardGeneric(u32, size_of_headers, self.page_size); |
| 875 | const size_of_headers_aligned: u32 = mem.alignForwardGeneric(u32, size_of_headers, default_file_alignment); | 1100 | const size_of_headers_aligned: u32 = mem.alignForwardGeneric(u32, size_of_headers, default_file_alignment); |
| 876 | const image_base = self.base.options.image_base_override orelse switch (self.base.options.output_mode) { | 1101 | const image_base = self.base.options.image_base_override orelse switch (self.base.options.output_mode) { |
| ... | @@ -968,7 +1193,7 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { | ... | @@ -968,7 +1193,7 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 968 | math.maxInt(@TypeOf(actual_size)); | 1193 | math.maxInt(@TypeOf(actual_size)); |
| 969 | } | 1194 | } |
| 970 | | 1195 | |
| 971 | fn detectAllocCollision(self: *Coff, start: u64, size: u64) ?u64 { | 1196 | fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 { |
| 972 | const headers_size = self.getSizeOfHeaders(); | 1197 | const headers_size = self.getSizeOfHeaders(); |
| 973 | if (start < headers_size) | 1198 | if (start < headers_size) |
| 974 | return headers_size; | 1199 | return headers_size; |
| ... | @@ -976,7 +1201,7 @@ fn detectAllocCollision(self: *Coff, start: u64, size: u64) ?u64 { | ... | @@ -976,7 +1201,7 @@ fn detectAllocCollision(self: *Coff, start: u64, size: u64) ?u64 { |
| 976 | const end = start + padToIdeal(size); | 1201 | const end = start + padToIdeal(size); |
| 977 | | 1202 | |
| 978 | if (self.strtab_offset) |off| { | 1203 | if (self.strtab_offset) |off| { |
| 979 | const increased_size = padToIdeal(self.strtab.len()); | 1204 | const increased_size = padToIdeal(@intCast(u32, self.strtab.len())); |
| 980 | const test_end = off + increased_size; | 1205 | const test_end = off + increased_size; |
| 981 | if (end > off and start < test_end) { | 1206 | if (end > off and start < test_end) { |
| 982 | return test_end; | 1207 | return test_end; |
| ... | @@ -994,10 +1219,10 @@ fn detectAllocCollision(self: *Coff, start: u64, size: u64) ?u64 { | ... | @@ -994,10 +1219,10 @@ fn detectAllocCollision(self: *Coff, start: u64, size: u64) ?u64 { |
| 994 | return null; | 1219 | return null; |
| 995 | } | 1220 | } |
| 996 | | 1221 | |
| 997 | pub fn allocatedSize(self: *Coff, start: u64) u64 { | 1222 | pub fn allocatedSize(self: *Coff, start: u32) u32 { |
| 998 | if (start == 0) | 1223 | if (start == 0) |
| 999 | return 0; | 1224 | return 0; |
| 1000 | var min_pos: u64 = std.math.maxInt(u64); | 1225 | var min_pos: u32 = std.math.maxInt(u32); |
| 1001 | if (self.strtab_offset) |off| { | 1226 | if (self.strtab_offset) |off| { |
| 1002 | if (off > start and off < min_pos) min_pos = off; | 1227 | if (off > start and off < min_pos) min_pos = off; |
| 1003 | } | 1228 | } |
| ... | @@ -1008,41 +1233,41 @@ pub fn allocatedSize(self: *Coff, start: u64) u64 { | ... | @@ -1008,41 +1233,41 @@ pub fn allocatedSize(self: *Coff, start: u64) u64 { |
| 1008 | return min_pos - start; | 1233 | return min_pos - start; |
| 1009 | } | 1234 | } |
| 1010 | | 1235 | |
| 1011 | pub fn findFreeSpace(self: *Coff, object_size: u64, min_alignment: u32) u64 { | 1236 | pub fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 { |
| 1012 | var start: u64 = 0; | 1237 | var start: u32 = 0; |
| 1013 | while (self.detectAllocCollision(start, object_size)) |item_end| { | 1238 | while (self.detectAllocCollision(start, object_size)) |item_end| { |
| 1014 | start = mem.alignForwardGeneric(u64, item_end, min_alignment); | 1239 | start = mem.alignForwardGeneric(u32, item_end, min_alignment); |
| 1015 | } | 1240 | } |
| 1016 | return start; | 1241 | return start; |
| 1017 | } | 1242 | } |
| 1018 | | 1243 | |
| 1019 | inline fn getSizeOfHeaders(self: Coff) usize { | 1244 | inline fn getSizeOfHeaders(self: Coff) u32 { |
| 1020 | const msdos_hdr_size = msdos_stub.len + 8; | 1245 | const msdos_hdr_size = msdos_stub.len + 8; |
| 1021 | return msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize() + | 1246 | return @intCast(u32, msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize() + |
| 1022 | self.getDataDirectoryHeadersSize() + self.getSectionHeadersSize(); | 1247 | self.getDataDirectoryHeadersSize() + self.getSectionHeadersSize()); |
| 1023 | } | 1248 | } |
| 1024 | | 1249 | |
| 1025 | inline fn getOptionalHeaderSize(self: Coff) usize { | 1250 | inline fn getOptionalHeaderSize(self: Coff) u32 { |
| 1026 | return switch (self.ptr_width) { | 1251 | return switch (self.ptr_width) { |
| 1027 | .p32 => @sizeOf(coff.OptionalHeaderPE32), | 1252 | .p32 => @intCast(u32, @sizeOf(coff.OptionalHeaderPE32)), |
| 1028 | .p64 => @sizeOf(coff.OptionalHeaderPE64), | 1253 | .p64 => @intCast(u32, @sizeOf(coff.OptionalHeaderPE64)), |
| 1029 | }; | 1254 | }; |
| 1030 | } | 1255 | } |
| 1031 | | 1256 | |
| 1032 | inline fn getDataDirectoryHeadersSize(self: Coff) usize { | 1257 | inline fn getDataDirectoryHeadersSize(self: Coff) u32 { |
| 1033 | return self.data_directories.len * @sizeOf(coff.ImageDataDirectory); | 1258 | return @intCast(u32, self.data_directories.len * @sizeOf(coff.ImageDataDirectory)); |
| 1034 | } | 1259 | } |
| 1035 | | 1260 | |
| 1036 | inline fn getSectionHeadersSize(self: Coff) usize { | 1261 | inline fn getSectionHeadersSize(self: Coff) u32 { |
| 1037 | return self.sections.slice().len * @sizeOf(coff.SectionHeader); | 1262 | return @intCast(u32, self.sections.slice().len * @sizeOf(coff.SectionHeader)); |
| 1038 | } | 1263 | } |
| 1039 | | 1264 | |
| 1040 | inline fn getDataDirectoryHeadersOffset(self: Coff) usize { | 1265 | inline fn getDataDirectoryHeadersOffset(self: Coff) u32 { |
| 1041 | const msdos_hdr_size = msdos_stub.len + 8; | 1266 | const msdos_hdr_size = msdos_stub.len + 8; |
| 1042 | return msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize(); | 1267 | return @intCast(u32, msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize()); |
| 1043 | } | 1268 | } |
| 1044 | | 1269 | |
| 1045 | inline fn getSectionHeadersOffset(self: Coff) usize { | 1270 | inline fn getSectionHeadersOffset(self: Coff) u32 { |
| 1046 | return self.getDataDirectoryHeadersOffset() + self.getDataDirectoryHeadersSize(); | 1271 | return self.getDataDirectoryHeadersOffset() + self.getDataDirectoryHeadersSize(); |
| 1047 | } | 1272 | } |
| 1048 | | 1273 | |
| ... | @@ -1086,7 +1311,7 @@ fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !v | ... | @@ -1086,7 +1311,7 @@ fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !v |
| 1086 | return; | 1311 | return; |
| 1087 | } | 1312 | } |
| 1088 | const offset = try self.strtab.insert(self.base.allocator, name); | 1313 | const offset = try self.strtab.insert(self.base.allocator, name); |
| 1089 | const name_offset = try fmt.bufPrint(&header.name, "/{d}", .{offset}); | 1314 | const name_offset = fmt.bufPrint(&header.name, "/{d}", .{offset}) catch unreachable; |
| 1090 | mem.set(u8, header.name[name_offset.len..], 0); | 1315 | mem.set(u8, header.name[name_offset.len..], 0); |
| 1091 | } | 1316 | } |
| 1092 | | 1317 | |
| ... | @@ -1097,6 +1322,6 @@ fn setSymbolName(self: *Coff, symbol: *coff.Symbol, name: []const u8) !void { | ... | @@ -1097,6 +1322,6 @@ fn setSymbolName(self: *Coff, symbol: *coff.Symbol, name: []const u8) !void { |
| 1097 | return; | 1322 | return; |
| 1098 | } | 1323 | } |
| 1099 | const offset = try self.strtab.insert(self.base.allocator, name); | 1324 | const offset = try self.strtab.insert(self.base.allocator, name); |
| 1100 | mem.copy(u8, symbol.name[0..4], 0); | 1325 | mem.set(u8, symbol.name[0..4], 0); |
| 1101 | _ = try fmt.bufPrint(symbol.name[4..], "{d}", .{offset}); | 1326 | _ = fmt.bufPrint(symbol.name[4..], "{d}", .{offset}) catch unreachable; |
| 1102 | } | 1327 | } |