| ... | ... | @@ -40,7 +40,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]co |
| 40 | 40 | try zig_object.resolveSymbols(elf_file); |
| 41 | 41 | try elf_file.addCommentString(); |
| 42 | 42 | try elf_file.finalizeMergeSections(); |
| 43 | | zig_object.claimUnresolvedObject(elf_file); |
| 43 | zig_object.claimUnresolvedRelocatable(elf_file); |
| 44 | 44 | |
| 45 | 45 | for (elf_file.merge_sections.items) |*msec| { |
| 46 | 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 | 280 | |
| 281 | 281 | fn claimUnresolved(elf_file: *Elf) void { |
| 282 | 282 | if (elf_file.zigObjectPtr()) |zig_object| { |
| 283 | | zig_object.claimUnresolvedObject(elf_file); |
| 283 | zig_object.claimUnresolvedRelocatable(elf_file); |
| 284 | 284 | } |
| 285 | 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 | 349 | } |
| 350 | 350 | |
| 351 | 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 | 356 | const slice = elf_file.sections.slice(); |
| 353 | 357 | for (slice.items(.shdr), 0..) |*shdr, shndx| { |
| 354 | 358 | const atom_list = slice.items(.atom_list)[shndx]; |
| 355 | | if (shdr.sh_type != elf.SHT_RELA) { |
| 356 | | for (atom_list.items) |ref| { |
| 357 | | const atom_ptr = elf_file.atom(ref) orelse continue; |
| 358 | | if (!atom_ptr.alive) continue; |
| 359 | | const offset = atom_ptr.alignment.forward(shdr.sh_size); |
| 360 | | const padding = offset - shdr.sh_size; |
| 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; |
| 359 | if (shdr.sh_type != elf.SHT_RELA) continue; |
| 360 | for (atom_list.items) |ref| { |
| 361 | const atom_ptr = elf_file.atom(ref) orelse continue; |
| 362 | if (!atom_ptr.alive) continue; |
| 363 | const relocs = atom_ptr.relocs(elf_file); |
| 364 | shdr.sh_size += shdr.sh_entsize * relocs.len; |
| 374 | 365 | } |
| 366 | |
| 367 | if (shdr.sh_size == 0) shdr.sh_offset = 0; |
| 375 | 368 | } |
| 376 | 369 | |
| 377 | 370 | if (elf_file.eh_frame_section_index) |index| { |
| ... | ... | @@ -422,74 +415,8 @@ fn allocateAllocSections(elf_file: *Elf) !void { |
| 422 | 415 | } |
| 423 | 416 | |
| 424 | 417 | fn writeAtoms(elf_file: *Elf) !void { |
| 425 | | const gpa = elf_file.base.comp.gpa; |
| 426 | | const slice = elf_file.sections.slice(); |
| 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); |
| 418 | for (elf_file.objects.items) |index| { |
| 419 | try elf_file.file(index).?.object.writeAtomsRelocatable(elf_file); |
| 493 | 420 | } |
| 494 | 421 | } |
| 495 | 422 | |
| ... | ... | @@ -541,7 +468,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 541 | 468 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 542 | 469 | var buffer = try std.ArrayList(u8).initCapacity(gpa, @intCast(sh_size - existing_size)); |
| 543 | 470 | defer buffer.deinit(); |
| 544 | | try eh_frame.writeEhFrameObject(elf_file, buffer.writer()); |
| 471 | try eh_frame.writeEhFrameRelocatable(elf_file, buffer.writer()); |
| 545 | 472 | log.debug("writing .eh_frame from 0x{x} to 0x{x}", .{ |
| 546 | 473 | shdr.sh_offset + existing_size, |
| 547 | 474 | shdr.sh_offset + sh_size, |