mirror of
https://github.com/ziglang/zig.git
synced 2026-01-05 04:53:17 +00:00
zld: correctly estimate TextBlock's alignment with
section's alignment serving as the maximum alignment that can be seen in this particular section. However, TextBlocks are still allowed to have at most that alignment.
This commit is contained in:
parent
95aeb09b9b
commit
9e051e365b
@ -413,6 +413,12 @@ const TextBlockParser = struct {
|
||||
const code = self.code[start_addr..end_addr];
|
||||
const size = code.len;
|
||||
|
||||
const max_align = self.section.@"align";
|
||||
const actual_align = if (senior_nlist.nlist.n_value > 0)
|
||||
math.min(@ctz(u64, senior_nlist.nlist.n_value), max_align)
|
||||
else
|
||||
max_align;
|
||||
|
||||
const alias_only_indices = if (aliases.items.len > 0) blk: {
|
||||
var out = std.ArrayList(u32).init(self.allocator);
|
||||
try out.ensureTotalCapacity(aliases.items.len);
|
||||
@ -435,7 +441,7 @@ const TextBlockParser = struct {
|
||||
block.aliases = alias_only_indices;
|
||||
block.code = try self.allocator.dupe(u8, code);
|
||||
block.size = size;
|
||||
block.alignment = self.section.@"align";
|
||||
block.alignment = actual_align;
|
||||
|
||||
const relocs = filterRelocs(self.relocs, start_addr, end_addr);
|
||||
if (relocs.len > 0) {
|
||||
@ -524,7 +530,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
|
||||
const reg = &sym.payload.regular;
|
||||
if (reg.file) |file| {
|
||||
if (file != self) {
|
||||
log.debug("deduping definition of {s} in {s}", .{ sym.name, self.name.? });
|
||||
log.warn("deduping definition of {s} in {s}", .{ sym.name, self.name.? });
|
||||
block.deinit();
|
||||
self.allocator.destroy(block);
|
||||
continue;
|
||||
|
||||
@ -320,15 +320,15 @@ pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArg
|
||||
self.allocateLinkeditSegment();
|
||||
try self.allocateTextBlocks();
|
||||
|
||||
var it = self.blocks.iterator();
|
||||
while (it.next()) |entry| {
|
||||
const seg = self.load_commands.items[entry.key_ptr.seg].Segment;
|
||||
const sect = seg.sections.items[entry.key_ptr.sect];
|
||||
// var it = self.blocks.iterator();
|
||||
// while (it.next()) |entry| {
|
||||
// const seg = self.load_commands.items[entry.key_ptr.seg].Segment;
|
||||
// const sect = seg.sections.items[entry.key_ptr.sect];
|
||||
|
||||
log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) });
|
||||
log.warn(" {}", .{sect});
|
||||
entry.value_ptr.*.print(self);
|
||||
}
|
||||
// log.warn("\n\n{s},{s} contents:", .{ segmentName(sect), sectionName(sect) });
|
||||
// log.warn(" {}", .{sect});
|
||||
// entry.value_ptr.*.print(self);
|
||||
// }
|
||||
|
||||
try self.flush();
|
||||
}
|
||||
@ -1056,8 +1056,8 @@ fn allocateTextBlocks(self: *Zld) !void {
|
||||
|
||||
var base_addr: u64 = sect.addr;
|
||||
|
||||
log.warn(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) });
|
||||
log.warn(" {}", .{sect});
|
||||
log.debug(" within section {s},{s}", .{ segmentName(sect), sectionName(sect) });
|
||||
log.debug(" {}", .{sect});
|
||||
|
||||
while (true) {
|
||||
const block_alignment = try math.powi(u32, 2, block.alignment);
|
||||
@ -1067,7 +1067,7 @@ fn allocateTextBlocks(self: *Zld) !void {
|
||||
assert(sym.payload == .regular);
|
||||
sym.payload.regular.address = base_addr;
|
||||
|
||||
log.warn(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
|
||||
log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
|
||||
sym.name,
|
||||
base_addr,
|
||||
base_addr + block.size,
|
||||
@ -1118,8 +1118,8 @@ fn writeTextBlocks(self: *Zld) !void {
|
||||
const sect = seg.sections.items[match.sect];
|
||||
const sect_type = sectionType(sect);
|
||||
|
||||
log.warn(" for section {s},{s}", .{ segmentName(sect), sectionName(sect) });
|
||||
log.warn(" {}", .{sect});
|
||||
log.debug(" for section {s},{s}", .{ segmentName(sect), sectionName(sect) });
|
||||
log.debug(" {}", .{sect});
|
||||
|
||||
var code = try self.allocator.alloc(u8, sect.size);
|
||||
defer self.allocator.free(code);
|
||||
@ -1134,7 +1134,7 @@ fn writeTextBlocks(self: *Zld) !void {
|
||||
const aligned_base_off = mem.alignForwardGeneric(u64, base_off, block_alignment);
|
||||
|
||||
const sym = self.locals.items[block.local_sym_index];
|
||||
log.warn(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
|
||||
log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
|
||||
sym.name,
|
||||
aligned_base_off,
|
||||
aligned_base_off + block.size,
|
||||
@ -1433,7 +1433,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void {
|
||||
fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {
|
||||
log.debug("resolving symbols in '{s}'", .{object.name});
|
||||
|
||||
for (object.symtab.items) |sym, sym_id| {
|
||||
for (object.symtab.items) |sym| {
|
||||
const sym_name = object.getString(sym.n_strx);
|
||||
|
||||
if (Symbol.isStab(sym)) {
|
||||
@ -2152,7 +2152,6 @@ fn writeRebaseInfoTable(self: *Zld) !void {
|
||||
if (match.seg == self.text_segment_cmd_index.?) continue; // __TEXT is non-writable
|
||||
|
||||
const seg = self.load_commands.items[match.seg].Segment;
|
||||
const sect = seg.sections.items[match.sect];
|
||||
|
||||
while (true) {
|
||||
const sym = self.locals.items[block.local_sym_index];
|
||||
|
||||
@ -110,6 +110,7 @@ pub const Relocation = struct {
|
||||
}
|
||||
|
||||
pub fn format(self: Branch, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
_ = self;
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
try std.fmt.format(writer, "Branch {{}}", .{});
|
||||
@ -179,7 +180,7 @@ pub const Relocation = struct {
|
||||
load,
|
||||
};
|
||||
|
||||
pub fn resolve(self: PageOff, base: Relocation, source_addr: u64, target_addr: u64) !void {
|
||||
pub fn resolve(self: PageOff, base: Relocation, _: u64, target_addr: u64) !void {
|
||||
switch (self.kind) {
|
||||
.page => {
|
||||
const actual_target_addr = if (self.addend) |addend| target_addr + addend else target_addr;
|
||||
@ -325,12 +326,13 @@ pub const Relocation = struct {
|
||||
};
|
||||
|
||||
pub const PointerToGot = struct {
|
||||
pub fn resolve(self: PointerToGot, base: Relocation, source_addr: u64, target_addr: u64) !void {
|
||||
pub fn resolve(_: PointerToGot, base: Relocation, source_addr: u64, target_addr: u64) !void {
|
||||
const result = try math.cast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr));
|
||||
mem.writeIntLittle(u32, base.block.code[base.offset..][0..4], @bitCast(u32, result));
|
||||
}
|
||||
|
||||
pub fn format(self: PointerToGot, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
_ = self;
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
try std.fmt.format(writer, "PointerToGot {{}}", .{});
|
||||
@ -342,6 +344,10 @@ pub const Relocation = struct {
|
||||
correction: i4,
|
||||
|
||||
pub fn resolve(self: Signed, base: Relocation, source_addr: u64, target_addr: u64) !void {
|
||||
_ = self;
|
||||
_ = base;
|
||||
_ = source_addr;
|
||||
_ = target_addr;
|
||||
// const target_addr = target_addr: {
|
||||
// if (signed.base.target == .section) {
|
||||
// const source_target = @intCast(i64, args.source_source_sect_addr.?) + @intCast(i64, signed.base.offset) + signed.addend + 4;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user