| ... | @@ -40,7 +40,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]co | ... | @@ -40,7 +40,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]co |
| 40 | try zig_object.resolveSymbols(elf_file); | 40 | try zig_object.resolveSymbols(elf_file); |
| 41 | try elf_file.addCommentString(); | 41 | try elf_file.addCommentString(); |
| 42 | try elf_file.finalizeMergeSections(); | 42 | try elf_file.finalizeMergeSections(); |
| 43 | zig_object.claimUnresolvedObject(elf_file); | 43 | zig_object.claimUnresolvedRelocatable(elf_file); |
| 44 | | 44 | |
| 45 | for (elf_file.merge_sections.items) |*msec| { | 45 | for (elf_file.merge_sections.items) |*msec| { |
| 46 | if (msec.finalized_subsections.items.len == 0) continue; | 46 | if (msec.finalized_subsections.items.len == 0) continue; |
| ... | @@ -280,10 +280,10 @@ fn parseArchive(elf_file: *Elf, path: []const u8) Elf.ParseError!void { | ... | @@ -280,10 +280,10 @@ fn parseArchive(elf_file: *Elf, path: []const u8) Elf.ParseError!void { |
| 280 | | 280 | |
| 281 | fn claimUnresolved(elf_file: *Elf) void { | 281 | fn claimUnresolved(elf_file: *Elf) void { |
| 282 | if (elf_file.zigObjectPtr()) |zig_object| { | 282 | if (elf_file.zigObjectPtr()) |zig_object| { |
| 283 | zig_object.claimUnresolvedObject(elf_file); | 283 | zig_object.claimUnresolvedRelocatable(elf_file); |
| 284 | } | 284 | } |
| 285 | for (elf_file.objects.items) |index| { | 285 | for (elf_file.objects.items) |index| { |
| 286 | elf_file.file(index).?.object.claimUnresolvedObject(elf_file); | 286 | elf_file.file(index).?.object.claimUnresolvedRelocatable(elf_file); |
| 287 | } | 287 | } |
| 288 | } | 288 | } |
| 289 | | 289 | |
| ... | @@ -349,29 +349,22 @@ fn initComdatGroups(elf_file: *Elf) !void { | ... | @@ -349,29 +349,22 @@ fn initComdatGroups(elf_file: *Elf) !void { |
| 349 | } | 349 | } |
| 350 | | 350 | |
| 351 | fn updateSectionSizes(elf_file: *Elf) !void { | 351 | fn updateSectionSizes(elf_file: *Elf) !void { |
| | 352 | for (elf_file.objects.items) |index| { |
| | 353 | try elf_file.file(index).?.object.allocateAtoms(elf_file); |
| | 354 | } |
| | 355 | |
| 352 | const slice = elf_file.sections.slice(); | 356 | const slice = elf_file.sections.slice(); |
| 353 | for (slice.items(.shdr), 0..) |*shdr, shndx| { | 357 | for (slice.items(.shdr), 0..) |*shdr, shndx| { |
| 354 | const atom_list = slice.items(.atom_list)[shndx]; | 358 | const atom_list = slice.items(.atom_list)[shndx]; |
| 355 | if (shdr.sh_type != elf.SHT_RELA) { | 359 | if (shdr.sh_type != elf.SHT_RELA) continue; |
| 356 | for (atom_list.items) |ref| { | 360 | for (atom_list.items) |ref| { |
| 357 | const atom_ptr = elf_file.atom(ref) orelse continue; | 361 | const atom_ptr = elf_file.atom(ref) orelse continue; |
| 358 | if (!atom_ptr.alive) continue; | 362 | if (!atom_ptr.alive) continue; |
| 359 | const offset = atom_ptr.alignment.forward(shdr.sh_size); | 363 | const relocs = atom_ptr.relocs(elf_file); |
| 360 | const padding = offset - shdr.sh_size; | 364 | shdr.sh_size += shdr.sh_entsize * relocs.len; |
| 361 | atom_ptr.value = @intCast(offset); | | |
| 362 | shdr.sh_size += padding + atom_ptr.size; | | |
| 363 | shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits() orelse 1); | | |
| 364 | } | | |
| 365 | } else { | | |
| 366 | for (atom_list.items) |ref| { | | |
| 367 | const atom_ptr = elf_file.atom(ref) orelse continue; | | |
| 368 | if (!atom_ptr.alive) continue; | | |
| 369 | const relocs = atom_ptr.relocs(elf_file); | | |
| 370 | shdr.sh_size += shdr.sh_entsize * relocs.len; | | |
| 371 | } | | |
| 372 | | | |
| 373 | if (shdr.sh_size == 0) shdr.sh_offset = 0; | | |
| 374 | } | 365 | } |
| | 366 | |
| | 367 | if (shdr.sh_size == 0) shdr.sh_offset = 0; |
| 375 | } | 368 | } |
| 376 | | 369 | |
| 377 | if (elf_file.eh_frame_section_index) |index| { | 370 | if (elf_file.eh_frame_section_index) |index| { |
| ... | @@ -422,74 +415,8 @@ fn allocateAllocSections(elf_file: *Elf) !void { | ... | @@ -422,74 +415,8 @@ fn allocateAllocSections(elf_file: *Elf) !void { |
| 422 | } | 415 | } |
| 423 | | 416 | |
| 424 | fn writeAtoms(elf_file: *Elf) !void { | 417 | fn writeAtoms(elf_file: *Elf) !void { |
| 425 | const gpa = elf_file.base.comp.gpa; | 418 | for (elf_file.objects.items) |index| { |
| 426 | const slice = elf_file.sections.slice(); | 419 | try elf_file.file(index).?.object.writeAtomsRelocatable(elf_file); |
| 427 | | | |
| 428 | // TODO iterate over `output_sections` directly | | |
| 429 | for (slice.items(.shdr), slice.items(.atom_list), 0..) |shdr, atom_list, shndx| { | | |
| 430 | if (shdr.sh_type == elf.SHT_NULL) continue; | | |
| 431 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | | |
| 432 | if (shdr.sh_type == elf.SHT_RELA) continue; | | |
| 433 | if (atom_list.items.len == 0) continue; | | |
| 434 | | | |
| 435 | log.debug("writing atoms in '{s}' section", .{elf_file.getShString(shdr.sh_name)}); | | |
| 436 | | | |
| 437 | // TODO really, really handle debug section separately | | |
| 438 | const base_offset = if (elf_file.zigObjectPtr()) |zo| blk: { | | |
| 439 | break :blk for ([_]?Symbol.Index{ | | |
| 440 | zo.debug_info_index, | | |
| 441 | zo.debug_abbrev_index, | | |
| 442 | zo.debug_aranges_index, | | |
| 443 | zo.debug_str_index, | | |
| 444 | zo.debug_line_index, | | |
| 445 | zo.debug_line_str_index, | | |
| 446 | zo.debug_loclists_index, | | |
| 447 | zo.debug_rnglists_index, | | |
| 448 | }) |maybe_sym_index| { | | |
| 449 | const sym_index = maybe_sym_index orelse continue; | | |
| 450 | const sym = zo.symbol(sym_index); | | |
| 451 | const atom_ptr = sym.atom(elf_file).?; | | |
| 452 | if (atom_ptr.output_section_index == shndx) break atom_ptr.size; | | |
| 453 | } else 0; | | |
| 454 | } else 0; | | |
| 455 | const sh_offset = shdr.sh_offset + base_offset; | | |
| 456 | const sh_size = math.cast(usize, shdr.sh_size - base_offset) orelse return error.Overflow; | | |
| 457 | | | |
| 458 | const buffer = try gpa.alloc(u8, sh_size); | | |
| 459 | defer gpa.free(buffer); | | |
| 460 | const padding_byte: u8 = if (shdr.sh_type == elf.SHT_PROGBITS and | | |
| 461 | shdr.sh_flags & elf.SHF_EXECINSTR != 0) | | |
| 462 | 0xcc // int3 | | |
| 463 | else | | |
| 464 | 0; | | |
| 465 | @memset(buffer, padding_byte); | | |
| 466 | | | |
| 467 | for (atom_list.items) |ref| { | | |
| 468 | const atom_ptr = elf_file.atom(ref).?; | | |
| 469 | assert(atom_ptr.alive); | | |
| 470 | | | |
| 471 | const offset = math.cast(usize, atom_ptr.value - @as(i64, @intCast(shdr.sh_addr - base_offset))) orelse | | |
| 472 | return error.Overflow; | | |
| 473 | const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow; | | |
| 474 | | | |
| 475 | log.debug("writing atom({}) from 0x{x} to 0x{x}", .{ | | |
| 476 | ref, | | |
| 477 | sh_offset + offset, | | |
| 478 | sh_offset + offset + size, | | |
| 479 | }); | | |
| 480 | | | |
| 481 | // TODO decompress directly into provided buffer | | |
| 482 | const out_code = buffer[offset..][0..size]; | | |
| 483 | const in_code = switch (atom_ptr.file(elf_file).?) { | | |
| 484 | .object => |x| try x.codeDecompressAlloc(elf_file, ref.index), | | |
| 485 | .zig_object => |x| try x.codeAlloc(elf_file, ref.index), | | |
| 486 | else => unreachable, | | |
| 487 | }; | | |
| 488 | defer gpa.free(in_code); | | |
| 489 | @memcpy(out_code, in_code); | | |
| 490 | } | | |
| 491 | | | |
| 492 | try elf_file.base.file.?.pwriteAll(buffer, sh_offset); | | |
| 493 | } | 420 | } |
| 494 | } | 421 | } |
| 495 | | 422 | |
| ... | @@ -541,7 +468,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { | ... | @@ -541,7 +468,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 541 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | 468 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 542 | var buffer = try std.ArrayList(u8).initCapacity(gpa, @intCast(sh_size - existing_size)); | 469 | var buffer = try std.ArrayList(u8).initCapacity(gpa, @intCast(sh_size - existing_size)); |
| 543 | defer buffer.deinit(); | 470 | defer buffer.deinit(); |
| 544 | try eh_frame.writeEhFrameObject(elf_file, buffer.writer()); | 471 | try eh_frame.writeEhFrameRelocatable(elf_file, buffer.writer()); |
| 545 | log.debug("writing .eh_frame from 0x{x} to 0x{x}", .{ | 472 | log.debug("writing .eh_frame from 0x{x} to 0x{x}", .{ |
| 546 | shdr.sh_offset + existing_size, | 473 | shdr.sh_offset + existing_size, |
| 547 | shdr.sh_offset + sh_size, | 474 | shdr.sh_offset + sh_size, |