diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 72937cd628..f5f9a073e5 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1461,7 +1461,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { } } - if (self.base.isDynLib()) { + if (self.isEffectivelyDynLib()) { if (self.soname) |name| { try argv.append("-soname"); try argv.append(name); @@ -1517,7 +1517,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { if (self.base.isStatic()) { try argv.append("-static"); - } else if (self.base.isDynLib() or (target.os.tag == .haiku and self.base.isExe())) { + } else if (self.isEffectivelyDynLib()) { try argv.append("-shared"); } @@ -1997,7 +1997,7 @@ fn markImportsExports(self: *Elf) void { } if (file_ptr.index() == file_index) { global.flags.@"export" = true; - if (elf_file.base.isDynLib() and vis != .PROTECTED) { + if (elf_file.isEffectivelyDynLib() and vis != .PROTECTED) { global.flags.import = true; } } @@ -2005,7 +2005,7 @@ fn markImportsExports(self: *Elf) void { } }.mark; - if (!self.base.isDynLib()) { + if (!self.isEffectivelyDynLib()) { for (self.shared_objects.items) |index| { for (self.file(index).?.globals()) |global_index| { const global = self.symbol(global_index); @@ -3117,7 +3117,7 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { } } - if (self.getTarget().cpu.arch == .riscv64 and self.base.isDynLib()) { + if (self.getTarget().cpu.arch == .riscv64 and self.isEffectivelyDynLib()) { self.global_pointer_index = try linker_defined.addGlobal("__global_pointer$", self); } @@ -3423,7 +3423,7 @@ fn initSyntheticSections(self: *Elf) !void { }); } - if (self.base.isDynLib() or self.shared_objects.items.len > 0 or comp.config.pie) { + if (self.isEffectivelyDynLib() or self.shared_objects.items.len > 0 or comp.config.pie) { self.dynstrtab_section_index = try self.addSection(.{ .name = ".dynstr", .flags = elf.SHF_ALLOC, @@ -3660,7 +3660,7 @@ fn setDynamicSection(self: *Elf, rpaths: []const []const u8) !void { try self.dynamic.addNeeded(shared_object, self); } - if (self.base.isDynLib()) { + if (self.isEffectivelyDynLib()) { if (self.soname) |soname| { try self.dynamic.setSoname(soname, self); } @@ -5249,6 +5249,16 @@ const CsuObjects = struct { } }; +/// If a target compiles other output modes as dynamic libraries, +/// this function returns true for those too. +pub fn isEffectivelyDynLib(self: Elf) bool { + if (self.base.isDynLib()) return true; + return switch (self.getTarget().os.tag) { + .haiku => self.base.isExe(), + else => false, + }; +} + pub fn isZigSection(self: Elf, shndx: u32) bool { inline for (&[_]?u32{ self.zig_text_section_index, diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 3db1182696..b5ceeb24b8 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -1054,7 +1054,7 @@ const x86_64 = struct { it: *RelocsIterator, ) !void { const is_static = elf_file.base.isStatic(); - const is_dyn_lib = elf_file.base.isDynLib(); + const is_dyn_lib = elf_file.isEffectivelyDynLib(); const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type()); const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow; @@ -1599,7 +1599,7 @@ const aarch64 = struct { _ = it; const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type()); - const is_dyn_lib = elf_file.base.isDynLib(); + const is_dyn_lib = elf_file.isEffectivelyDynLib(); switch (r_type) { .ABS64 => { diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index cc135f2f97..d483540aa6 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -568,7 +568,7 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void { } const is_import = blk: { - if (!elf_file.base.isDynLib()) break :blk false; + if (!elf_file.isEffectivelyDynLib()) break :blk false; const vis = @as(elf.STV, @enumFromInt(esym.st_other)); if (vis == .HIDDEN) break :blk false; break :blk true; diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 6aede441c8..8b8dc9bd81 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -367,7 +367,7 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void { } const is_import = blk: { - if (!elf_file.base.isDynLib()) break :blk false; + if (!elf_file.isEffectivelyDynLib()) break :blk false; const vis = @as(elf.STV, @enumFromInt(esym.st_other)); if (vis == .HIDDEN) break :blk false; break :blk true; diff --git a/src/link/Elf/synthetic_sections.zig b/src/link/Elf/synthetic_sections.zig index 0e7cb90545..2ef7d49540 100644 --- a/src/link/Elf/synthetic_sections.zig +++ b/src/link/Elf/synthetic_sections.zig @@ -89,7 +89,7 @@ pub const DynamicSection = struct { if (elf_file.verneed_section_index != null) nentries += 2; // VERNEED if (dt.getFlags(elf_file) != null) nentries += 1; // FLAGS if (dt.getFlags1(elf_file) != null) nentries += 1; // FLAGS_1 - if (!elf_file.base.isDynLib()) nentries += 1; // DEBUG + if (!elf_file.isEffectivelyDynLib()) nentries += 1; // DEBUG nentries += 1; // NULL return nentries * @sizeOf(elf.Elf64_Dyn); } @@ -216,7 +216,7 @@ pub const DynamicSection = struct { } // DEBUG - if (!elf_file.base.isDynLib()) try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_DEBUG, .d_val = 0 }); + if (!elf_file.isEffectivelyDynLib()) try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_DEBUG, .d_val = 0 }); // NULL try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NULL, .d_val = 0 }); @@ -256,7 +256,7 @@ pub const ZigGotSection = struct { entry.* = sym_index; const symbol = elf_file.symbol(sym_index); symbol.flags.has_zig_got = true; - if (elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) { + if (elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) { zig_got.flags.needs_rela = true; } if (symbol.extra(elf_file)) |extra| { @@ -495,7 +495,7 @@ pub const GotSection = struct { const symbol = elf_file.symbol(sym_index); symbol.flags.has_got = true; if (symbol.flags.import or symbol.isIFunc(elf_file) or - ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.isAbs(elf_file))) + ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.isAbs(elf_file))) { got.flags.needs_rela = true; } @@ -528,7 +528,7 @@ pub const GotSection = struct { entry.symbol_index = sym_index; const symbol = elf_file.symbol(sym_index); symbol.flags.has_tlsgd = true; - if (symbol.flags.import or elf_file.base.isDynLib()) got.flags.needs_rela = true; + if (symbol.flags.import or elf_file.isEffectivelyDynLib()) got.flags.needs_rela = true; if (symbol.extra(elf_file)) |extra| { var new_extra = extra; new_extra.tlsgd = index; @@ -545,7 +545,7 @@ pub const GotSection = struct { entry.symbol_index = sym_index; const symbol = elf_file.symbol(sym_index); symbol.flags.has_gottp = true; - if (symbol.flags.import or elf_file.base.isDynLib()) got.flags.needs_rela = true; + if (symbol.flags.import or elf_file.isEffectivelyDynLib()) got.flags.needs_rela = true; if (symbol.extra(elf_file)) |extra| { var new_extra = extra; new_extra.gottp = index; @@ -580,7 +580,7 @@ pub const GotSection = struct { pub fn write(got: GotSection, elf_file: *Elf, writer: anytype) !void { const comp = elf_file.base.comp; - const is_dyn_lib = elf_file.base.isDynLib(); + const is_dyn_lib = elf_file.isEffectivelyDynLib(); const apply_relocs = true; // TODO add user option for this for (got.entries.items) |entry| { @@ -595,7 +595,7 @@ pub const GotSection = struct { if (symbol.?.flags.import) break :blk 0; if (symbol.?.isIFunc(elf_file)) break :blk if (apply_relocs) value else 0; - if ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and + if ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.?.isAbs(elf_file)) { break :blk if (apply_relocs) value else 0; @@ -653,7 +653,7 @@ pub const GotSection = struct { pub fn addRela(got: GotSection, elf_file: *Elf) !void { const comp = elf_file.base.comp; const gpa = comp.gpa; - const is_dyn_lib = elf_file.base.isDynLib(); + const is_dyn_lib = elf_file.isEffectivelyDynLib(); const cpu_arch = elf_file.getTarget().cpu.arch; try elf_file.rela_dyn.ensureUnusedCapacity(gpa, got.numRela(elf_file)); @@ -683,7 +683,7 @@ pub const GotSection = struct { }); continue; } - if ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and + if ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.?.isAbs(elf_file)) { elf_file.addRelaDynAssumeCapacity(.{ @@ -758,7 +758,7 @@ pub const GotSection = struct { pub fn numRela(got: GotSection, elf_file: *Elf) usize { const comp = elf_file.base.comp; - const is_dyn_lib = elf_file.base.isDynLib(); + const is_dyn_lib = elf_file.isEffectivelyDynLib(); var num: usize = 0; for (got.entries.items) |entry| { const symbol = switch (entry.tag) { @@ -767,7 +767,7 @@ pub const GotSection = struct { }; switch (entry.tag) { .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or - ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and + ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.?.isAbs(elf_file))) { num += 1;