mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Merge pull request #25898 from jacobly0/elfv2-progress
Elf2: more progress
This commit is contained in:
commit
a9568ed296
8 changed files with 838 additions and 247 deletions
|
|
@ -2282,10 +2282,6 @@ pub const Discarding = struct {
|
||||||
|
|
||||||
pub fn sendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!usize {
|
pub fn sendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!usize {
|
||||||
if (File.Handle == void) return error.Unimplemented;
|
if (File.Handle == void) return error.Unimplemented;
|
||||||
switch (builtin.zig_backend) {
|
|
||||||
else => {},
|
|
||||||
.stage2_aarch64 => return error.Unimplemented,
|
|
||||||
}
|
|
||||||
const d: *Discarding = @alignCast(@fieldParentPtr("writer", w));
|
const d: *Discarding = @alignCast(@fieldParentPtr("writer", w));
|
||||||
d.count += w.end;
|
d.count += w.end;
|
||||||
w.end = 0;
|
w.end = 0;
|
||||||
|
|
|
||||||
|
|
@ -427,7 +427,6 @@ const noop_impl = builtin.single_threaded or switch (builtin.os.tag) {
|
||||||
.wasi, .freestanding => true,
|
.wasi, .freestanding => true,
|
||||||
else => false,
|
else => false,
|
||||||
} or switch (builtin.zig_backend) {
|
} or switch (builtin.zig_backend) {
|
||||||
.stage2_aarch64 => true,
|
|
||||||
else => false,
|
else => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -739,10 +739,7 @@ pub const Writer = struct {
|
||||||
return .{
|
return .{
|
||||||
.vtable = &.{
|
.vtable = &.{
|
||||||
.drain = drain,
|
.drain = drain,
|
||||||
.sendFile = switch (builtin.zig_backend) {
|
.sendFile = sendFile,
|
||||||
else => sendFile,
|
|
||||||
.stage2_aarch64 => Io.Writer.unimplementedSendFile,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
.buffer = buffer,
|
.buffer = buffer,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9569,11 +9569,15 @@ pub const Value = struct {
|
||||||
.zr
|
.zr
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
if (part_ra != .zr) {
|
const part_lock: RegLock = switch (part_ra) {
|
||||||
const live_vi = isel.live_registers.getPtr(part_ra);
|
else => isel.lockReg(part_ra),
|
||||||
assert(live_vi.* == .free);
|
.zr => .empty,
|
||||||
live_vi.* = .allocating;
|
};
|
||||||
}
|
defer switch (opts.expected_live_registers.get(part_ra)) {
|
||||||
|
_ => {},
|
||||||
|
.allocating => unreachable,
|
||||||
|
.free => part_lock.unlock(isel),
|
||||||
|
};
|
||||||
if (opts.wrap) |int_info| switch (int_info.bits) {
|
if (opts.wrap) |int_info| switch (int_info.bits) {
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
1...7, 9...15, 17...31 => |bits| try isel.emit(switch (int_info.signedness) {
|
1...7, 9...15, 17...31 => |bits| try isel.emit(switch (int_info.signedness) {
|
||||||
|
|
@ -9604,15 +9608,6 @@ pub const Value = struct {
|
||||||
64 => {},
|
64 => {},
|
||||||
};
|
};
|
||||||
try isel.loadReg(part_ra, part_size, part_vi.signedness(isel), base_ra, opts.offset);
|
try isel.loadReg(part_ra, part_size, part_vi.signedness(isel), base_ra, opts.offset);
|
||||||
if (part_ra != .zr) {
|
|
||||||
const live_vi = isel.live_registers.getPtr(part_ra);
|
|
||||||
assert(live_vi.* == .allocating);
|
|
||||||
switch (opts.expected_live_registers.get(part_ra)) {
|
|
||||||
_ => {},
|
|
||||||
.allocating => unreachable,
|
|
||||||
.free => live_vi.* = .free,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var used = false;
|
var used = false;
|
||||||
|
|
|
||||||
|
|
@ -881,7 +881,7 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
|
||||||
end_offset - 4,
|
end_offset - 4,
|
||||||
@enumFromInt(reloc.target.index),
|
@enumFromInt(reloc.target.index),
|
||||||
reloc.off - 4,
|
reloc.off - 4,
|
||||||
.{ .X86_64 = .PC32 },
|
.{ .X86_64 = .PLT32 },
|
||||||
) else if (emit.bin_file.cast(.macho)) |macho_file| {
|
) else if (emit.bin_file.cast(.macho)) |macho_file| {
|
||||||
const zo = macho_file.getZigObject().?;
|
const zo = macho_file.getZigObject().?;
|
||||||
const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;
|
const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;
|
||||||
|
|
@ -916,7 +916,13 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
|
||||||
.r_info = @as(u64, reloc.target.index) << 32 | @intFromEnum(r_type),
|
.r_info = @as(u64, reloc.target.index) << 32 | @intFromEnum(r_type),
|
||||||
.r_addend = reloc.off - 4,
|
.r_addend = reloc.off - 4,
|
||||||
}, zo);
|
}, zo);
|
||||||
} else return emit.fail("TODO implement {s} reloc for {s}", .{
|
} else if (emit.bin_file.cast(.elf2)) |elf| try elf.addReloc(
|
||||||
|
@enumFromInt(emit.atom_index),
|
||||||
|
end_offset - 4,
|
||||||
|
@enumFromInt(reloc.target.index),
|
||||||
|
reloc.off - 4,
|
||||||
|
.{ .X86_64 = if (emit.pic) .TLSLD else unreachable },
|
||||||
|
) else return emit.fail("TODO implement {s} reloc for {s}", .{
|
||||||
@tagName(reloc.target.type), @tagName(emit.bin_file.tag),
|
@tagName(reloc.target.type), @tagName(emit.bin_file.tag),
|
||||||
}),
|
}),
|
||||||
.tlv => if (emit.bin_file.cast(.elf)) |elf_file| {
|
.tlv => if (emit.bin_file.cast(.elf)) |elf_file| {
|
||||||
|
|
@ -933,7 +939,7 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
|
||||||
end_offset - 4,
|
end_offset - 4,
|
||||||
@enumFromInt(reloc.target.index),
|
@enumFromInt(reloc.target.index),
|
||||||
reloc.off,
|
reloc.off,
|
||||||
.{ .X86_64 = .TPOFF32 },
|
.{ .X86_64 = if (emit.pic) .DTPOFF32 else .TPOFF32 },
|
||||||
) else if (emit.bin_file.cast(.macho)) |macho_file| {
|
) else if (emit.bin_file.cast(.macho)) |macho_file| {
|
||||||
const zo = macho_file.getZigObject().?;
|
const zo = macho_file.getZigObject().?;
|
||||||
const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;
|
const atom = zo.symbols.items[emit.atom_index].getAtom(macho_file).?;
|
||||||
|
|
|
||||||
15
src/link.zig
15
src/link.zig
|
|
@ -1069,7 +1069,7 @@ pub const File = struct {
|
||||||
errdefer archive.file.close();
|
errdefer archive.file.close();
|
||||||
loadInput(base, .{ .archive = archive }) catch |err| switch (err) {
|
loadInput(base, .{ .archive = archive }) catch |err| switch (err) {
|
||||||
error.BadMagic, error.UnexpectedEndOfFile => {
|
error.BadMagic, error.UnexpectedEndOfFile => {
|
||||||
if (base.tag != .elf) return err;
|
if (base.tag != .elf and base.tag != .elf2) return err;
|
||||||
try loadGnuLdScript(base, path, query, archive.file);
|
try loadGnuLdScript(base, path, query, archive.file);
|
||||||
archive.file.close();
|
archive.file.close();
|
||||||
return;
|
return;
|
||||||
|
|
@ -1091,7 +1091,7 @@ pub const File = struct {
|
||||||
errdefer dso.file.close();
|
errdefer dso.file.close();
|
||||||
loadInput(base, .{ .dso = dso }) catch |err| switch (err) {
|
loadInput(base, .{ .dso = dso }) catch |err| switch (err) {
|
||||||
error.BadMagic, error.UnexpectedEndOfFile => {
|
error.BadMagic, error.UnexpectedEndOfFile => {
|
||||||
if (base.tag != .elf) return err;
|
if (base.tag != .elf and base.tag != .elf2) return err;
|
||||||
try loadGnuLdScript(base, path, query, dso.file);
|
try loadGnuLdScript(base, path, query, dso.file);
|
||||||
dso.file.close();
|
dso.file.close();
|
||||||
return;
|
return;
|
||||||
|
|
@ -1101,8 +1101,9 @@ pub const File = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn loadGnuLdScript(base: *File, path: Path, parent_query: UnresolvedInput.Query, file: fs.File) anyerror!void {
|
fn loadGnuLdScript(base: *File, path: Path, parent_query: UnresolvedInput.Query, file: fs.File) anyerror!void {
|
||||||
const diags = &base.comp.link_diags;
|
const comp = base.comp;
|
||||||
const gpa = base.comp.gpa;
|
const diags = &comp.link_diags;
|
||||||
|
const gpa = comp.gpa;
|
||||||
const stat = try file.stat();
|
const stat = try file.stat();
|
||||||
const size = std.math.cast(u32, stat.size) orelse return error.FileTooBig;
|
const size = std.math.cast(u32, stat.size) orelse return error.FileTooBig;
|
||||||
const buf = try gpa.alloc(u8, size);
|
const buf = try gpa.alloc(u8, size);
|
||||||
|
|
@ -1124,7 +1125,11 @@ pub const File = struct {
|
||||||
@panic("TODO");
|
@panic("TODO");
|
||||||
} else {
|
} else {
|
||||||
if (fs.path.isAbsolute(arg.path)) {
|
if (fs.path.isAbsolute(arg.path)) {
|
||||||
const new_path = Path.initCwd(try gpa.dupe(u8, arg.path));
|
const new_path = Path.initCwd(path: {
|
||||||
|
comp.mutex.lock();
|
||||||
|
defer comp.mutex.unlock();
|
||||||
|
break :path try comp.arena.dupe(u8, arg.path);
|
||||||
|
});
|
||||||
switch (Compilation.classifyFileExt(arg.path)) {
|
switch (Compilation.classifyFileExt(arg.path)) {
|
||||||
.shared_library => try openLoadDso(base, new_path, query),
|
.shared_library => try openLoadDso(base, new_path, query),
|
||||||
.object => try openLoadObject(base, new_path),
|
.object => try openLoadObject(base, new_path),
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -213,7 +213,7 @@ pub const Node = extern struct {
|
||||||
defer node_moved.* = false;
|
defer node_moved.* = false;
|
||||||
return node_moved.*;
|
return node_moved.*;
|
||||||
}
|
}
|
||||||
fn movedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void {
|
pub fn movedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void {
|
||||||
if (ni.hasMoved(mf)) return;
|
if (ni.hasMoved(mf)) return;
|
||||||
const node = ni.get(mf);
|
const node = ni.get(mf);
|
||||||
node.flags.moved = true;
|
node.flags.moved = true;
|
||||||
|
|
@ -234,7 +234,7 @@ pub const Node = extern struct {
|
||||||
defer node_resized.* = false;
|
defer node_resized.* = false;
|
||||||
return node_resized.*;
|
return node_resized.*;
|
||||||
}
|
}
|
||||||
fn resizedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void {
|
pub fn resizedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void {
|
||||||
const node = ni.get(mf);
|
const node = ni.get(mf);
|
||||||
if (node.flags.resized) return;
|
if (node.flags.resized) return;
|
||||||
node.flags.resized = true;
|
node.flags.resized = true;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue