| ... | @@ -17,6 +17,7 @@ relocs: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, | ... | @@ -17,6 +17,7 @@ relocs: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, |
| 17 | atoms: std.ArrayListUnmanaged(Atom) = .{}, | 17 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 18 | atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .{}, | 18 | atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 19 | atoms_extra: std.ArrayListUnmanaged(u32) = .{}, | 19 | atoms_extra: std.ArrayListUnmanaged(u32) = .{}, |
| | 20 | section_chunks: std.ArrayListUnmanaged(SectionChunk) = .{}, |
| 20 | | 21 | |
| 21 | comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup) = .{}, | 22 | comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup) = .{}, |
| 22 | comdat_group_data: std.ArrayListUnmanaged(u32) = .{}, | 23 | comdat_group_data: std.ArrayListUnmanaged(u32) = .{}, |
| ... | @@ -58,6 +59,10 @@ pub fn deinit(self: *Object, allocator: Allocator) void { | ... | @@ -58,6 +59,10 @@ pub fn deinit(self: *Object, allocator: Allocator) void { |
| 58 | self.atoms.deinit(allocator); | 59 | self.atoms.deinit(allocator); |
| 59 | self.atoms_indexes.deinit(allocator); | 60 | self.atoms_indexes.deinit(allocator); |
| 60 | self.atoms_extra.deinit(allocator); | 61 | self.atoms_extra.deinit(allocator); |
| | 62 | for (self.section_chunks.items) |*chunk| { |
| | 63 | chunk.deinit(allocator); |
| | 64 | } |
| | 65 | self.section_chunks.deinit(allocator); |
| 61 | self.comdat_groups.deinit(allocator); | 66 | self.comdat_groups.deinit(allocator); |
| 62 | self.comdat_group_data.deinit(allocator); | 67 | self.comdat_group_data.deinit(allocator); |
| 63 | self.relocs.deinit(allocator); | 68 | self.relocs.deinit(allocator); |
| ... | @@ -933,11 +938,26 @@ pub fn initOutputSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -933,11 +938,26 @@ pub fn initOutputSections(self: *Object, elf_file: *Elf) !void { |
| 933 | const atom_ptr = self.atom(atom_index) orelse continue; | 938 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 934 | if (!atom_ptr.alive) continue; | 939 | if (!atom_ptr.alive) continue; |
| 935 | const shdr = atom_ptr.inputShdr(elf_file); | 940 | const shdr = atom_ptr.inputShdr(elf_file); |
| 936 | _ = try elf_file.initOutputSection(.{ | 941 | const osec = try elf_file.initOutputSection(.{ |
| 937 | .name = self.getString(shdr.sh_name), | 942 | .name = self.getString(shdr.sh_name), |
| 938 | .flags = shdr.sh_flags, | 943 | .flags = shdr.sh_flags, |
| 939 | .type = shdr.sh_type, | 944 | .type = shdr.sh_type, |
| 940 | }); | 945 | }); |
| | 946 | const chunk = for (self.section_chunks.items) |*chunk| { |
| | 947 | if (chunk.output_section_index == osec) break chunk; |
| | 948 | } else blk: { |
| | 949 | const chunk = try self.section_chunks.addOne(elf_file.base.comp.gpa); |
| | 950 | chunk.* = .{ .output_section_index = osec }; |
| | 951 | break :blk chunk; |
| | 952 | }; |
| | 953 | try chunk.atoms.append(elf_file.base.comp.gpa, atom_index); |
| | 954 | } |
| | 955 | } |
| | 956 | |
| | 957 | pub fn allocateAtoms(self: *Object, elf_file: *Elf) !void { |
| | 958 | _ = elf_file; |
| | 959 | for (self.section_chunks.items) |*chunk| { |
| | 960 | chunk.updateSize(self); |
| 941 | } | 961 | } |
| 942 | } | 962 | } |
| 943 | | 963 | |
| ... | @@ -1427,6 +1447,29 @@ fn formatAtoms( | ... | @@ -1427,6 +1447,29 @@ fn formatAtoms( |
| 1427 | } | 1447 | } |
| 1428 | } | 1448 | } |
| 1429 | | 1449 | |
| | 1450 | pub fn fmtSectionChunks(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatSectionChunks) { |
| | 1451 | return .{ .data = .{ |
| | 1452 | .object = self, |
| | 1453 | .elf_file = elf_file, |
| | 1454 | } }; |
| | 1455 | } |
| | 1456 | |
| | 1457 | fn formatSectionChunks( |
| | 1458 | ctx: FormatContext, |
| | 1459 | comptime unused_fmt_string: []const u8, |
| | 1460 | options: std.fmt.FormatOptions, |
| | 1461 | writer: anytype, |
| | 1462 | ) !void { |
| | 1463 | _ = unused_fmt_string; |
| | 1464 | _ = options; |
| | 1465 | const object = ctx.object; |
| | 1466 | const elf_file = ctx.elf_file; |
| | 1467 | try writer.writeAll(" section chunks\n"); |
| | 1468 | for (object.section_chunks.items) |chunk| { |
| | 1469 | try writer.print(" {}\n", .{chunk.fmt(elf_file)}); |
| | 1470 | } |
| | 1471 | } |
| | 1472 | |
| 1430 | pub fn fmtCies(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatCies) { | 1473 | pub fn fmtCies(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatCies) { |
| 1431 | return .{ .data = .{ | 1474 | return .{ .data = .{ |
| 1432 | .object = self, | 1475 | .object = self, |
| ... | @@ -1528,6 +1571,75 @@ const InArchive = struct { | ... | @@ -1528,6 +1571,75 @@ const InArchive = struct { |
| 1528 | size: u32, | 1571 | size: u32, |
| 1529 | }; | 1572 | }; |
| 1530 | | 1573 | |
| | 1574 | const SectionChunk = struct { |
| | 1575 | value: i64 = 0, |
| | 1576 | size: u64 = 0, |
| | 1577 | alignment: Atom.Alignment = .@"1", |
| | 1578 | output_section_index: u32 = 0, |
| | 1579 | atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| | 1580 | |
| | 1581 | fn deinit(chunk: *SectionChunk, allocator: Allocator) void { |
| | 1582 | chunk.atoms.deinit(allocator); |
| | 1583 | } |
| | 1584 | |
| | 1585 | fn address(chunk: SectionChunk, elf_file: *Elf) i64 { |
| | 1586 | const shdr = elf_file.sections.items(.shdr)[chunk.output_section_index]; |
| | 1587 | return @as(i64, @intCast(shdr.sh_addr)) + chunk.value; |
| | 1588 | } |
| | 1589 | |
| | 1590 | fn updateSize(chunk: *SectionChunk, object: *Object) void { |
| | 1591 | for (chunk.atoms.items) |atom_index| { |
| | 1592 | const atom_ptr = object.atom(atom_index).?; |
| | 1593 | assert(atom_ptr.alive); |
| | 1594 | const offset = atom_ptr.alignment.forward(chunk.size); |
| | 1595 | const padding = offset - chunk.size; |
| | 1596 | atom_ptr.value = @intCast(offset); |
| | 1597 | chunk.size += padding + atom_ptr.size; |
| | 1598 | chunk.alignment = chunk.alignment.max(atom_ptr.alignment); |
| | 1599 | } |
| | 1600 | } |
| | 1601 | |
| | 1602 | pub fn format( |
| | 1603 | chunk: SectionChunk, |
| | 1604 | comptime unused_fmt_string: []const u8, |
| | 1605 | options: std.fmt.FormatOptions, |
| | 1606 | writer: anytype, |
| | 1607 | ) !void { |
| | 1608 | _ = chunk; |
| | 1609 | _ = unused_fmt_string; |
| | 1610 | _ = options; |
| | 1611 | _ = writer; |
| | 1612 | @compileError("do not format SectionChunk directly"); |
| | 1613 | } |
| | 1614 | |
| | 1615 | const FormatCtx = struct { SectionChunk, *Elf }; |
| | 1616 | |
| | 1617 | pub fn fmt(chunk: SectionChunk, elf_file: *Elf) std.fmt.Formatter(format2) { |
| | 1618 | return .{ .data = .{ chunk, elf_file } }; |
| | 1619 | } |
| | 1620 | |
| | 1621 | fn format2( |
| | 1622 | ctx: FormatCtx, |
| | 1623 | comptime unused_fmt_string: []const u8, |
| | 1624 | options: std.fmt.FormatOptions, |
| | 1625 | writer: anytype, |
| | 1626 | ) !void { |
| | 1627 | _ = unused_fmt_string; |
| | 1628 | _ = options; |
| | 1629 | const chunk, const elf_file = ctx; |
| | 1630 | try writer.print("chunk : @{x} : shdr({d}) : align({x}) : size({x})", .{ |
| | 1631 | chunk.address(elf_file), chunk.output_section_index, |
| | 1632 | chunk.alignment.toByteUnits() orelse 0, chunk.size, |
| | 1633 | }); |
| | 1634 | try writer.writeAll(" : atoms{ "); |
| | 1635 | for (chunk.atoms.items, 0..) |atom_index, i| { |
| | 1636 | try writer.print("{d}", .{atom_index}); |
| | 1637 | if (i < chunk.atoms.items.len - 1) try writer.writeAll(", "); |
| | 1638 | } |
| | 1639 | try writer.writeAll(" }"); |
| | 1640 | } |
| | 1641 | }; |
| | 1642 | |
| 1531 | const Object = @This(); | 1643 | const Object = @This(); |
| 1532 | | 1644 | |
| 1533 | const std = @import("std"); | 1645 | const std = @import("std"); |