authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-04-08 10:24:48+02:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-04-08 13:24:08-04:00
log4cd92567e7392b0fe390562d7ea52f68357bb45a
treeca1e263ce01ae884a5f706f9b3cca4823c91d780
parentb98e3bee2ba69c55a8c890eaca5eafae9fc251a7

link/elf: propagate Haiku requirement of always passing -shared for images


5 files changed, 33 insertions(+), 23 deletions(-)

src/link/Elf.zig+17-7
...@@ -1461,7 +1461,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {...@@ -1461,7 +1461,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
1461 }1461 }
1462 }1462 }
14631463
1464 if (self.base.isDynLib()) {1464 if (self.isEffectivelyDynLib()) {
1465 if (self.soname) |name| {1465 if (self.soname) |name| {
1466 try argv.append("-soname");1466 try argv.append("-soname");
1467 try argv.append(name);1467 try argv.append(name);
...@@ -1517,7 +1517,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {...@@ -1517,7 +1517,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
15171517
1518 if (self.base.isStatic()) {1518 if (self.base.isStatic()) {
1519 try argv.append("-static");1519 try argv.append("-static");
1520 } else if (self.base.isDynLib() or (target.os.tag == .haiku and self.base.isExe())) {1520 } else if (self.isEffectivelyDynLib()) {
1521 try argv.append("-shared");1521 try argv.append("-shared");
1522 }1522 }
15231523
...@@ -1997,7 +1997,7 @@ fn markImportsExports(self: *Elf) void {...@@ -1997,7 +1997,7 @@ fn markImportsExports(self: *Elf) void {
1997 }1997 }
1998 if (file_ptr.index() == file_index) {1998 if (file_ptr.index() == file_index) {
1999 global.flags.@"export" = true;1999 global.flags.@"export" = true;
2000 if (elf_file.base.isDynLib() and vis != .PROTECTED) {2000 if (elf_file.isEffectivelyDynLib() and vis != .PROTECTED) {
2001 global.flags.import = true;2001 global.flags.import = true;
2002 }2002 }
2003 }2003 }
...@@ -2005,7 +2005,7 @@ fn markImportsExports(self: *Elf) void {...@@ -2005,7 +2005,7 @@ fn markImportsExports(self: *Elf) void {
2005 }2005 }
2006 }.mark;2006 }.mark;
20072007
2008 if (!self.base.isDynLib()) {2008 if (!self.isEffectivelyDynLib()) {
2009 for (self.shared_objects.items) |index| {2009 for (self.shared_objects.items) |index| {
2010 for (self.file(index).?.globals()) |global_index| {2010 for (self.file(index).?.globals()) |global_index| {
2011 const global = self.symbol(global_index);2011 const global = self.symbol(global_index);
...@@ -3117,7 +3117,7 @@ fn addLinkerDefinedSymbols(self: *Elf) !void {...@@ -3117,7 +3117,7 @@ fn addLinkerDefinedSymbols(self: *Elf) !void {
3117 }3117 }
3118 }3118 }
31193119
3120 if (self.getTarget().cpu.arch == .riscv64 and self.base.isDynLib()) {3120 if (self.getTarget().cpu.arch == .riscv64 and self.isEffectivelyDynLib()) {
3121 self.global_pointer_index = try linker_defined.addGlobal("__global_pointer$", self);3121 self.global_pointer_index = try linker_defined.addGlobal("__global_pointer$", self);
3122 }3122 }
31233123
...@@ -3423,7 +3423,7 @@ fn initSyntheticSections(self: *Elf) !void {...@@ -3423,7 +3423,7 @@ fn initSyntheticSections(self: *Elf) !void {
3423 });3423 });
3424 }3424 }
34253425
3426 if (self.base.isDynLib() or self.shared_objects.items.len > 0 or comp.config.pie) {3426 if (self.isEffectivelyDynLib() or self.shared_objects.items.len > 0 or comp.config.pie) {
3427 self.dynstrtab_section_index = try self.addSection(.{3427 self.dynstrtab_section_index = try self.addSection(.{
3428 .name = ".dynstr",3428 .name = ".dynstr",
3429 .flags = elf.SHF_ALLOC,3429 .flags = elf.SHF_ALLOC,
...@@ -3660,7 +3660,7 @@ fn setDynamicSection(self: *Elf, rpaths: []const []const u8) !void {...@@ -3660,7 +3660,7 @@ fn setDynamicSection(self: *Elf, rpaths: []const []const u8) !void {
3660 try self.dynamic.addNeeded(shared_object, self);3660 try self.dynamic.addNeeded(shared_object, self);
3661 }3661 }
36623662
3663 if (self.base.isDynLib()) {3663 if (self.isEffectivelyDynLib()) {
3664 if (self.soname) |soname| {3664 if (self.soname) |soname| {
3665 try self.dynamic.setSoname(soname, self);3665 try self.dynamic.setSoname(soname, self);
3666 }3666 }
...@@ -5249,6 +5249,16 @@ const CsuObjects = struct {...@@ -5249,6 +5249,16 @@ const CsuObjects = struct {
5249 }5249 }
5250};5250};
52515251
5252/// If a target compiles other output modes as dynamic libraries,
5253/// this function returns true for those too.
5254pub fn isEffectivelyDynLib(self: Elf) bool {
5255 if (self.base.isDynLib()) return true;
5256 return switch (self.getTarget().os.tag) {
5257 .haiku => self.base.isExe(),
5258 else => false,
5259 };
5260}
5261
5252pub fn isZigSection(self: Elf, shndx: u32) bool {5262pub fn isZigSection(self: Elf, shndx: u32) bool {
5253 inline for (&[_]?u32{5263 inline for (&[_]?u32{
5254 self.zig_text_section_index,5264 self.zig_text_section_index,
src/link/Elf/Atom.zig+2-2
...@@ -1054,7 +1054,7 @@ const x86_64 = struct {...@@ -1054,7 +1054,7 @@ const x86_64 = struct {
1054 it: *RelocsIterator,1054 it: *RelocsIterator,
1055 ) !void {1055 ) !void {
1056 const is_static = elf_file.base.isStatic();1056 const is_static = elf_file.base.isStatic();
1057 const is_dyn_lib = elf_file.base.isDynLib();1057 const is_dyn_lib = elf_file.isEffectivelyDynLib();
10581058
1059 const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());1059 const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
1060 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;1060 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
...@@ -1599,7 +1599,7 @@ const aarch64 = struct {...@@ -1599,7 +1599,7 @@ const aarch64 = struct {
1599 _ = it;1599 _ = it;
16001600
1601 const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());1601 const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());
1602 const is_dyn_lib = elf_file.base.isDynLib();1602 const is_dyn_lib = elf_file.isEffectivelyDynLib();
16031603
1604 switch (r_type) {1604 switch (r_type) {
1605 .ABS64 => {1605 .ABS64 => {
src/link/Elf/Object.zig+1-1
...@@ -568,7 +568,7 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void {...@@ -568,7 +568,7 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void {
568 }568 }
569569
570 const is_import = blk: {570 const is_import = blk: {
571 if (!elf_file.base.isDynLib()) break :blk false;571 if (!elf_file.isEffectivelyDynLib()) break :blk false;
572 const vis = @as(elf.STV, @enumFromInt(esym.st_other));572 const vis = @as(elf.STV, @enumFromInt(esym.st_other));
573 if (vis == .HIDDEN) break :blk false;573 if (vis == .HIDDEN) break :blk false;
574 break :blk true;574 break :blk true;
src/link/Elf/ZigObject.zig+1-1
...@@ -367,7 +367,7 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void {...@@ -367,7 +367,7 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void {
367 }367 }
368368
369 const is_import = blk: {369 const is_import = blk: {
370 if (!elf_file.base.isDynLib()) break :blk false;370 if (!elf_file.isEffectivelyDynLib()) break :blk false;
371 const vis = @as(elf.STV, @enumFromInt(esym.st_other));371 const vis = @as(elf.STV, @enumFromInt(esym.st_other));
372 if (vis == .HIDDEN) break :blk false;372 if (vis == .HIDDEN) break :blk false;
373 break :blk true;373 break :blk true;
src/link/Elf/synthetic_sections.zig+12-12
...@@ -89,7 +89,7 @@ pub const DynamicSection = struct {...@@ -89,7 +89,7 @@ pub const DynamicSection = struct {
89 if (elf_file.verneed_section_index != null) nentries += 2; // VERNEED89 if (elf_file.verneed_section_index != null) nentries += 2; // VERNEED
90 if (dt.getFlags(elf_file) != null) nentries += 1; // FLAGS90 if (dt.getFlags(elf_file) != null) nentries += 1; // FLAGS
91 if (dt.getFlags1(elf_file) != null) nentries += 1; // FLAGS_191 if (dt.getFlags1(elf_file) != null) nentries += 1; // FLAGS_1
92 if (!elf_file.base.isDynLib()) nentries += 1; // DEBUG92 if (!elf_file.isEffectivelyDynLib()) nentries += 1; // DEBUG
93 nentries += 1; // NULL93 nentries += 1; // NULL
94 return nentries * @sizeOf(elf.Elf64_Dyn);94 return nentries * @sizeOf(elf.Elf64_Dyn);
95 }95 }
...@@ -216,7 +216,7 @@ pub const DynamicSection = struct {...@@ -216,7 +216,7 @@ pub const DynamicSection = struct {
216 }216 }
217217
218 // DEBUG218 // DEBUG
219 if (!elf_file.base.isDynLib()) try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_DEBUG, .d_val = 0 });219 if (!elf_file.isEffectivelyDynLib()) try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_DEBUG, .d_val = 0 });
220220
221 // NULL221 // NULL
222 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NULL, .d_val = 0 });222 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NULL, .d_val = 0 });
...@@ -256,7 +256,7 @@ pub const ZigGotSection = struct {...@@ -256,7 +256,7 @@ pub const ZigGotSection = struct {
256 entry.* = sym_index;256 entry.* = sym_index;
257 const symbol = elf_file.symbol(sym_index);257 const symbol = elf_file.symbol(sym_index);
258 symbol.flags.has_zig_got = true;258 symbol.flags.has_zig_got = true;
259 if (elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) {259 if (elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) {
260 zig_got.flags.needs_rela = true;260 zig_got.flags.needs_rela = true;
261 }261 }
262 if (symbol.extra(elf_file)) |extra| {262 if (symbol.extra(elf_file)) |extra| {
...@@ -495,7 +495,7 @@ pub const GotSection = struct {...@@ -495,7 +495,7 @@ pub const GotSection = struct {
495 const symbol = elf_file.symbol(sym_index);495 const symbol = elf_file.symbol(sym_index);
496 symbol.flags.has_got = true;496 symbol.flags.has_got = true;
497 if (symbol.flags.import or symbol.isIFunc(elf_file) or497 if (symbol.flags.import or symbol.isIFunc(elf_file) or
498 ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.isAbs(elf_file)))498 ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.isAbs(elf_file)))
499 {499 {
500 got.flags.needs_rela = true;500 got.flags.needs_rela = true;
501 }501 }
...@@ -528,7 +528,7 @@ pub const GotSection = struct {...@@ -528,7 +528,7 @@ pub const GotSection = struct {
528 entry.symbol_index = sym_index;528 entry.symbol_index = sym_index;
529 const symbol = elf_file.symbol(sym_index);529 const symbol = elf_file.symbol(sym_index);
530 symbol.flags.has_tlsgd = true;530 symbol.flags.has_tlsgd = true;
531 if (symbol.flags.import or elf_file.base.isDynLib()) got.flags.needs_rela = true;531 if (symbol.flags.import or elf_file.isEffectivelyDynLib()) got.flags.needs_rela = true;
532 if (symbol.extra(elf_file)) |extra| {532 if (symbol.extra(elf_file)) |extra| {
533 var new_extra = extra;533 var new_extra = extra;
534 new_extra.tlsgd = index;534 new_extra.tlsgd = index;
...@@ -545,7 +545,7 @@ pub const GotSection = struct {...@@ -545,7 +545,7 @@ pub const GotSection = struct {
545 entry.symbol_index = sym_index;545 entry.symbol_index = sym_index;
546 const symbol = elf_file.symbol(sym_index);546 const symbol = elf_file.symbol(sym_index);
547 symbol.flags.has_gottp = true;547 symbol.flags.has_gottp = true;
548 if (symbol.flags.import or elf_file.base.isDynLib()) got.flags.needs_rela = true;548 if (symbol.flags.import or elf_file.isEffectivelyDynLib()) got.flags.needs_rela = true;
549 if (symbol.extra(elf_file)) |extra| {549 if (symbol.extra(elf_file)) |extra| {
550 var new_extra = extra;550 var new_extra = extra;
551 new_extra.gottp = index;551 new_extra.gottp = index;
...@@ -580,7 +580,7 @@ pub const GotSection = struct {...@@ -580,7 +580,7 @@ pub const GotSection = struct {
580580
581 pub fn write(got: GotSection, elf_file: *Elf, writer: anytype) !void {581 pub fn write(got: GotSection, elf_file: *Elf, writer: anytype) !void {
582 const comp = elf_file.base.comp;582 const comp = elf_file.base.comp;
583 const is_dyn_lib = elf_file.base.isDynLib();583 const is_dyn_lib = elf_file.isEffectivelyDynLib();
584 const apply_relocs = true; // TODO add user option for this584 const apply_relocs = true; // TODO add user option for this
585585
586 for (got.entries.items) |entry| {586 for (got.entries.items) |entry| {
...@@ -595,7 +595,7 @@ pub const GotSection = struct {...@@ -595,7 +595,7 @@ pub const GotSection = struct {
595 if (symbol.?.flags.import) break :blk 0;595 if (symbol.?.flags.import) break :blk 0;
596 if (symbol.?.isIFunc(elf_file))596 if (symbol.?.isIFunc(elf_file))
597 break :blk if (apply_relocs) value else 0;597 break :blk if (apply_relocs) value else 0;
598 if ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and598 if ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and
599 !symbol.?.isAbs(elf_file))599 !symbol.?.isAbs(elf_file))
600 {600 {
601 break :blk if (apply_relocs) value else 0;601 break :blk if (apply_relocs) value else 0;
...@@ -653,7 +653,7 @@ pub const GotSection = struct {...@@ -653,7 +653,7 @@ pub const GotSection = struct {
653 pub fn addRela(got: GotSection, elf_file: *Elf) !void {653 pub fn addRela(got: GotSection, elf_file: *Elf) !void {
654 const comp = elf_file.base.comp;654 const comp = elf_file.base.comp;
655 const gpa = comp.gpa;655 const gpa = comp.gpa;
656 const is_dyn_lib = elf_file.base.isDynLib();656 const is_dyn_lib = elf_file.isEffectivelyDynLib();
657 const cpu_arch = elf_file.getTarget().cpu.arch;657 const cpu_arch = elf_file.getTarget().cpu.arch;
658 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, got.numRela(elf_file));658 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, got.numRela(elf_file));
659659
...@@ -683,7 +683,7 @@ pub const GotSection = struct {...@@ -683,7 +683,7 @@ pub const GotSection = struct {
683 });683 });
684 continue;684 continue;
685 }685 }
686 if ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and686 if ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and
687 !symbol.?.isAbs(elf_file))687 !symbol.?.isAbs(elf_file))
688 {688 {
689 elf_file.addRelaDynAssumeCapacity(.{689 elf_file.addRelaDynAssumeCapacity(.{
...@@ -758,7 +758,7 @@ pub const GotSection = struct {...@@ -758,7 +758,7 @@ pub const GotSection = struct {
758758
759 pub fn numRela(got: GotSection, elf_file: *Elf) usize {759 pub fn numRela(got: GotSection, elf_file: *Elf) usize {
760 const comp = elf_file.base.comp;760 const comp = elf_file.base.comp;
761 const is_dyn_lib = elf_file.base.isDynLib();761 const is_dyn_lib = elf_file.isEffectivelyDynLib();
762 var num: usize = 0;762 var num: usize = 0;
763 for (got.entries.items) |entry| {763 for (got.entries.items) |entry| {
764 const symbol = switch (entry.tag) {764 const symbol = switch (entry.tag) {
...@@ -767,7 +767,7 @@ pub const GotSection = struct {...@@ -767,7 +767,7 @@ pub const GotSection = struct {
767 };767 };
768 switch (entry.tag) {768 switch (entry.tag) {
769 .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or769 .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or
770 ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and770 ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and
771 !symbol.?.isAbs(elf_file)))771 !symbol.?.isAbs(elf_file)))
772 {772 {
773 num += 1;773 num += 1;