| ... | ... | @@ -17,6 +17,7 @@ relocs: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, |
| 17 | 17 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 18 | 18 | atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 19 | 19 | atoms_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 20 | section_chunks: std.ArrayListUnmanaged(SectionChunk) = .{}, |
| 20 | 21 | |
| 21 | 22 | comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup) = .{}, |
| 22 | 23 | comdat_group_data: std.ArrayListUnmanaged(u32) = .{}, |
| ... | ... | @@ -58,6 +59,10 @@ pub fn deinit(self: *Object, allocator: Allocator) void { |
| 58 | 59 | self.atoms.deinit(allocator); |
| 59 | 60 | self.atoms_indexes.deinit(allocator); |
| 60 | 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 | 66 | self.comdat_groups.deinit(allocator); |
| 62 | 67 | self.comdat_group_data.deinit(allocator); |
| 63 | 68 | self.relocs.deinit(allocator); |
| ... | ... | @@ -933,11 +938,26 @@ pub fn initOutputSections(self: *Object, elf_file: *Elf) !void { |
| 933 | 938 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 934 | 939 | if (!atom_ptr.alive) continue; |
| 935 | 940 | const shdr = atom_ptr.inputShdr(elf_file); |
| 936 | | _ = try elf_file.initOutputSection(.{ |
| 941 | const osec = try elf_file.initOutputSection(.{ |
| 937 | 942 | .name = self.getString(shdr.sh_name), |
| 938 | 943 | .flags = shdr.sh_flags, |
| 939 | 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 | 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 | 1473 | pub fn fmtCies(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatCies) { |
| 1431 | 1474 | return .{ .data = .{ |
| 1432 | 1475 | .object = self, |
| ... | ... | @@ -1528,6 +1571,75 @@ const InArchive = struct { |
| 1528 | 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 | 1643 | const Object = @This(); |
| 1532 | 1644 | |
| 1533 | 1645 | const std = @import("std"); |