mirror of
https://github.com/ziglang/zig.git
synced 2024-11-17 01:23:54 +00:00
elf: enable static-lib flush path
This commit is contained in:
parent
d2c4597eb5
commit
481ee1b598
@ -85,15 +85,19 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
@tagName(emit.lower.bin_file.tag),
|
||||
}),
|
||||
.linker_reloc => |data| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
const is_obj = emit.lower.bin_file.options.effectiveOutputMode() == .Obj;
|
||||
const is_obj_or_static_lib = switch (emit.lower.bin_file.options.output_mode) {
|
||||
.Exe => false,
|
||||
.Obj => true,
|
||||
.Lib => emit.lower.bin_file.options.link_mode == .Static,
|
||||
};
|
||||
const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
|
||||
const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index);
|
||||
const sym = elf_file.symbol(sym_index);
|
||||
if (sym.flags.needs_zig_got and !is_obj) {
|
||||
if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
|
||||
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
|
||||
}
|
||||
if (emit.lower.bin_file.options.pic) {
|
||||
const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj)
|
||||
const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
|
||||
link.File.Elf.R_X86_64_ZIG_GOTPCREL
|
||||
else if (sym.flags.needs_got)
|
||||
std.elf.R_X86_64_GOTPCREL
|
||||
@ -105,7 +109,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.r_addend = -4,
|
||||
});
|
||||
} else {
|
||||
const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj)
|
||||
const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
|
||||
link.File.Elf.R_X86_64_ZIG_GOT32
|
||||
else if (sym.flags.needs_got)
|
||||
std.elf.R_X86_64_GOT32
|
||||
|
@ -327,7 +327,11 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
||||
}
|
||||
}.needsZigGot;
|
||||
|
||||
const is_obj = lower.bin_file.options.effectiveOutputMode() == .Obj;
|
||||
const is_obj_or_static_lib = switch (lower.bin_file.options.output_mode) {
|
||||
.Exe => false,
|
||||
.Obj => true,
|
||||
.Lib => lower.bin_file.options.link_mode == .Static,
|
||||
};
|
||||
var emit_prefix = prefix;
|
||||
var emit_mnemonic = mnemonic;
|
||||
var emit_ops_storage: [4]Operand = undefined;
|
||||
@ -347,7 +351,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
||||
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
|
||||
},
|
||||
.mov => {
|
||||
if (is_obj and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
|
||||
if (is_obj_or_static_lib and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
|
||||
},
|
||||
else => unreachable,
|
||||
@ -360,7 +364,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
||||
break :op .{ .imm = Immediate.s(0) };
|
||||
},
|
||||
.mov => {
|
||||
if (is_obj and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
|
||||
if (is_obj_or_static_lib and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||
.base = .{ .reg = .ds },
|
||||
}) };
|
||||
|
@ -498,7 +498,7 @@ pub fn initMetadata(self: *Elf) !void {
|
||||
|
||||
const fillSection = struct {
|
||||
fn fillSection(elf_file: *Elf, shdr: *elf.Elf64_Shdr, size: u64, phndx: ?u16) void {
|
||||
if (elf_file.isObject()) {
|
||||
if (elf_file.isRelocatable()) {
|
||||
const off = elf_file.findFreeSpace(size, shdr.sh_addralign);
|
||||
shdr.sh_offset = off;
|
||||
shdr.sh_size = size;
|
||||
@ -513,7 +513,7 @@ pub fn initMetadata(self: *Elf) !void {
|
||||
|
||||
comptime assert(number_of_zig_segments == 5);
|
||||
|
||||
if (!self.isObject()) {
|
||||
if (!self.isRelocatable()) {
|
||||
if (self.phdr_zig_load_re_index == null) {
|
||||
const filesz = self.base.options.program_code_size_hint;
|
||||
const off = self.findFreeSpace(filesz, self.page_size);
|
||||
@ -597,7 +597,7 @@ pub fn initMetadata(self: *Elf) !void {
|
||||
});
|
||||
const shdr = &self.shdrs.items[self.zig_text_section_index.?];
|
||||
fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index);
|
||||
if (self.isObject()) {
|
||||
if (self.isRelocatable()) {
|
||||
try zig_object.addSectionSymbol(self.zig_text_section_index.?, self);
|
||||
self.zig_text_rela_section_index = try self.addRelaShdr(
|
||||
".rela.text.zig",
|
||||
@ -613,7 +613,7 @@ pub fn initMetadata(self: *Elf) !void {
|
||||
try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});
|
||||
}
|
||||
|
||||
if (self.zig_got_section_index == null and !self.isObject()) {
|
||||
if (self.zig_got_section_index == null and !self.isRelocatable()) {
|
||||
self.zig_got_section_index = try self.addSection(.{
|
||||
.name = ".got.zig",
|
||||
.type = elf.SHT_PROGBITS,
|
||||
@ -644,7 +644,7 @@ pub fn initMetadata(self: *Elf) !void {
|
||||
});
|
||||
const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?];
|
||||
fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index);
|
||||
if (self.isObject()) {
|
||||
if (self.isRelocatable()) {
|
||||
try zig_object.addSectionSymbol(self.zig_data_rel_ro_section_index.?, self);
|
||||
self.zig_data_rel_ro_rela_section_index = try self.addRelaShdr(
|
||||
".rela.data.rel.ro.zig",
|
||||
@ -670,7 +670,7 @@ pub fn initMetadata(self: *Elf) !void {
|
||||
});
|
||||
const shdr = &self.shdrs.items[self.zig_data_section_index.?];
|
||||
fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index);
|
||||
if (self.isObject()) {
|
||||
if (self.isRelocatable()) {
|
||||
try zig_object.addSectionSymbol(self.zig_data_section_index.?, self);
|
||||
self.zig_data_rela_section_index = try self.addRelaShdr(
|
||||
".rela.data.zig",
|
||||
@ -904,10 +904,6 @@ pub fn flush(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) link
|
||||
if (use_lld) {
|
||||
return self.linkWithLLD(comp, prog_node);
|
||||
}
|
||||
if (self.base.options.output_mode == .Lib and self.isStatic()) {
|
||||
// TODO writing static library files
|
||||
return error.TODOImplementWritingLibFiles;
|
||||
}
|
||||
try self.flushModule(comp, prog_node);
|
||||
}
|
||||
|
||||
@ -943,7 +939,12 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
} else null;
|
||||
const gc_sections = self.base.options.gc_sections orelse false;
|
||||
|
||||
if (self.isObject() and self.zig_object_index == null) {
|
||||
if (self.isRelocatable() and self.zig_object_index == null) {
|
||||
if (self.isStaticLib()) {
|
||||
var err = try self.addErrorWithNotes(0);
|
||||
try err.addMsg(self, "fatal linker error: emitting static libs unimplemented", .{});
|
||||
return;
|
||||
}
|
||||
// TODO this will become -r route I guess. For now, just copy the object file.
|
||||
assert(self.base.file == null); // TODO uncomment once we implement -r
|
||||
const the_object_path = blk: {
|
||||
@ -1389,6 +1390,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
}
|
||||
|
||||
if (self.zigObjectPtr()) |zig_object| try zig_object.flushModule(self);
|
||||
if (self.isStaticLib()) return self.flushStaticLib(comp);
|
||||
|
||||
// Dedup shared objects
|
||||
{
|
||||
@ -1424,9 +1426,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
self.resolveSymbols();
|
||||
self.markEhFrameAtomsDead();
|
||||
|
||||
if (self.isObject()) {
|
||||
return self.flushObject(comp);
|
||||
}
|
||||
if (self.isObject()) return self.flushObject(comp);
|
||||
|
||||
try self.convertCommonSymbols();
|
||||
self.markImportsExports();
|
||||
@ -1511,7 +1511,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
try self.writeAtoms();
|
||||
try self.writeSyntheticSections();
|
||||
|
||||
if (self.entry_index == null and self.base.options.effectiveOutputMode() == .Exe) {
|
||||
if (self.entry_index == null and self.isExe()) {
|
||||
log.debug("flushing. no_entry_point_found = true", .{});
|
||||
self.error_flags.no_entry_point_found = true;
|
||||
} else {
|
||||
@ -1521,6 +1521,12 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void {
|
||||
_ = comp;
|
||||
var err = try self.addErrorWithNotes(0);
|
||||
try err.addMsg(self, "fatal linker error: emitting static libs unimplemented", .{});
|
||||
}
|
||||
|
||||
pub fn flushObject(self: *Elf, comp: *Compilation) link.File.FlushError!void {
|
||||
_ = comp;
|
||||
self.claimUnresolvedObject();
|
||||
@ -2822,7 +2828,7 @@ fn writeHeader(self: *Elf) !void {
|
||||
|
||||
assert(index == 16);
|
||||
|
||||
const elf_type: elf.ET = switch (self.base.options.effectiveOutputMode()) {
|
||||
const elf_type: elf.ET = switch (self.base.options.output_mode) {
|
||||
.Exe => if (self.base.options.pie) .DYN else .EXEC,
|
||||
.Obj => .REL,
|
||||
.Lib => switch (self.base.options.link_mode) {
|
||||
@ -3147,11 +3153,11 @@ fn initSections(self: *Elf) !void {
|
||||
};
|
||||
const ptr_size = self.ptrWidthBytes();
|
||||
|
||||
for (self.objects.items) |index| {
|
||||
if (!self.isStaticLib()) for (self.objects.items) |index| {
|
||||
try self.file(index).?.object.initOutputSections(self);
|
||||
}
|
||||
};
|
||||
|
||||
const needs_eh_frame = for (self.objects.items) |index| {
|
||||
const needs_eh_frame = if (self.isStaticLib()) false else for (self.objects.items) |index| {
|
||||
if (self.file(index).?.object.cies.items.len > 0) break true;
|
||||
} else false;
|
||||
if (needs_eh_frame) {
|
||||
@ -4954,15 +4960,23 @@ pub fn isStatic(self: Elf) bool {
|
||||
}
|
||||
|
||||
pub fn isObject(self: Elf) bool {
|
||||
return self.base.options.effectiveOutputMode() == .Obj;
|
||||
return self.base.options.output_mode == .Obj;
|
||||
}
|
||||
|
||||
pub fn isExe(self: Elf) bool {
|
||||
return self.base.options.effectiveOutputMode() == .Exe;
|
||||
return self.base.options.output_mode == .Exe;
|
||||
}
|
||||
|
||||
pub fn isStaticLib(self: Elf) bool {
|
||||
return self.base.options.output_mode == .Lib and self.isStatic();
|
||||
}
|
||||
|
||||
pub fn isRelocatable(self: Elf) bool {
|
||||
return self.isObject() or self.isStaticLib();
|
||||
}
|
||||
|
||||
pub fn isDynLib(self: Elf) bool {
|
||||
return self.base.options.effectiveOutputMode() == .Lib and self.base.options.link_mode == .Dynamic;
|
||||
return self.base.options.output_mode == .Lib and !self.isStatic();
|
||||
}
|
||||
|
||||
pub fn isZigSection(self: Elf, shndx: u16) bool {
|
||||
|
@ -605,7 +605,8 @@ fn dynAbsRelocAction(symbol: *const Symbol, elf_file: *Elf) RelocAction {
|
||||
}
|
||||
|
||||
fn outputType(elf_file: *Elf) u2 {
|
||||
return switch (elf_file.base.options.effectiveOutputMode()) {
|
||||
assert(!elf_file.isRelocatable());
|
||||
return switch (elf_file.base.options.output_mode) {
|
||||
.Obj => unreachable,
|
||||
.Lib => 0,
|
||||
.Exe => if (elf_file.base.options.pie) 1 else 2,
|
||||
|
@ -287,7 +287,7 @@ pub fn addAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index {
|
||||
}
|
||||
|
||||
pub fn addSectionSymbol(self: *ZigObject, shndx: u16, elf_file: *Elf) !void {
|
||||
assert(elf_file.isObject());
|
||||
assert(elf_file.isRelocatable());
|
||||
const gpa = elf_file.base.allocator;
|
||||
const symbol_index = try elf_file.addSymbol();
|
||||
try self.local_symbols.append(gpa, symbol_index);
|
||||
@ -886,7 +886,7 @@ fn updateDeclCode(
|
||||
sym.value = atom_ptr.value;
|
||||
esym.st_value = atom_ptr.value;
|
||||
|
||||
if (!elf_file.isObject()) {
|
||||
if (!elf_file.isRelocatable()) {
|
||||
log.debug(" (writing new offset table entry)", .{});
|
||||
assert(sym.flags.has_zig_got);
|
||||
const extra = sym.extra(elf_file).?;
|
||||
@ -904,7 +904,7 @@ fn updateDeclCode(
|
||||
sym.flags.needs_zig_got = true;
|
||||
esym.st_value = atom_ptr.value;
|
||||
|
||||
if (!elf_file.isObject()) {
|
||||
if (!elf_file.isRelocatable()) {
|
||||
const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
|
||||
try elf_file.zig_got.writeOne(elf_file, gop.index);
|
||||
}
|
||||
@ -1160,7 +1160,7 @@ fn updateLazySymbol(
|
||||
local_sym.flags.needs_zig_got = true;
|
||||
local_esym.st_value = atom_ptr.value;
|
||||
|
||||
if (!elf_file.isObject()) {
|
||||
if (!elf_file.isRelocatable()) {
|
||||
const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file);
|
||||
try elf_file.zig_got.writeOne(elf_file, gop.index);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user