mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
link/elf: propagate Haiku requirement of always passing -shared for images
This commit is contained in:
parent
b98e3bee2b
commit
4cd92567e7
5 changed files with 33 additions and 23 deletions
|
|
@ -1461,7 +1461,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.base.isDynLib()) {
|
if (self.isEffectivelyDynLib()) {
|
||||||
if (self.soname) |name| {
|
if (self.soname) |name| {
|
||||||
try argv.append("-soname");
|
try argv.append("-soname");
|
||||||
try argv.append(name);
|
try argv.append(name);
|
||||||
|
|
@ -1517,7 +1517,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
|
||||||
|
|
||||||
if (self.base.isStatic()) {
|
if (self.base.isStatic()) {
|
||||||
try argv.append("-static");
|
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");
|
try argv.append("-shared");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1997,7 +1997,7 @@ fn markImportsExports(self: *Elf) void {
|
||||||
}
|
}
|
||||||
if (file_ptr.index() == file_index) {
|
if (file_ptr.index() == file_index) {
|
||||||
global.flags.@"export" = true;
|
global.flags.@"export" = true;
|
||||||
if (elf_file.base.isDynLib() and vis != .PROTECTED) {
|
if (elf_file.isEffectivelyDynLib() and vis != .PROTECTED) {
|
||||||
global.flags.import = true;
|
global.flags.import = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2005,7 +2005,7 @@ fn markImportsExports(self: *Elf) void {
|
||||||
}
|
}
|
||||||
}.mark;
|
}.mark;
|
||||||
|
|
||||||
if (!self.base.isDynLib()) {
|
if (!self.isEffectivelyDynLib()) {
|
||||||
for (self.shared_objects.items) |index| {
|
for (self.shared_objects.items) |index| {
|
||||||
for (self.file(index).?.globals()) |global_index| {
|
for (self.file(index).?.globals()) |global_index| {
|
||||||
const global = self.symbol(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);
|
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(.{
|
self.dynstrtab_section_index = try self.addSection(.{
|
||||||
.name = ".dynstr",
|
.name = ".dynstr",
|
||||||
.flags = elf.SHF_ALLOC,
|
.flags = elf.SHF_ALLOC,
|
||||||
|
|
@ -3660,7 +3660,7 @@ fn setDynamicSection(self: *Elf, rpaths: []const []const u8) !void {
|
||||||
try self.dynamic.addNeeded(shared_object, self);
|
try self.dynamic.addNeeded(shared_object, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.base.isDynLib()) {
|
if (self.isEffectivelyDynLib()) {
|
||||||
if (self.soname) |soname| {
|
if (self.soname) |soname| {
|
||||||
try self.dynamic.setSoname(soname, self);
|
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 {
|
pub fn isZigSection(self: Elf, shndx: u32) bool {
|
||||||
inline for (&[_]?u32{
|
inline for (&[_]?u32{
|
||||||
self.zig_text_section_index,
|
self.zig_text_section_index,
|
||||||
|
|
|
||||||
|
|
@ -1054,7 +1054,7 @@ const x86_64 = struct {
|
||||||
it: *RelocsIterator,
|
it: *RelocsIterator,
|
||||||
) !void {
|
) !void {
|
||||||
const is_static = elf_file.base.isStatic();
|
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_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
|
||||||
const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
|
const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
|
||||||
|
|
@ -1599,7 +1599,7 @@ const aarch64 = struct {
|
||||||
_ = it;
|
_ = it;
|
||||||
|
|
||||||
const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());
|
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) {
|
switch (r_type) {
|
||||||
.ABS64 => {
|
.ABS64 => {
|
||||||
|
|
|
||||||
|
|
@ -568,7 +568,7 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
const is_import = blk: {
|
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));
|
const vis = @as(elf.STV, @enumFromInt(esym.st_other));
|
||||||
if (vis == .HIDDEN) break :blk false;
|
if (vis == .HIDDEN) break :blk false;
|
||||||
break :blk true;
|
break :blk true;
|
||||||
|
|
|
||||||
|
|
@ -367,7 +367,7 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
const is_import = blk: {
|
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));
|
const vis = @as(elf.STV, @enumFromInt(esym.st_other));
|
||||||
if (vis == .HIDDEN) break :blk false;
|
if (vis == .HIDDEN) break :blk false;
|
||||||
break :blk true;
|
break :blk true;
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ pub const DynamicSection = struct {
|
||||||
if (elf_file.verneed_section_index != null) nentries += 2; // VERNEED
|
if (elf_file.verneed_section_index != null) nentries += 2; // VERNEED
|
||||||
if (dt.getFlags(elf_file) != null) nentries += 1; // FLAGS
|
if (dt.getFlags(elf_file) != null) nentries += 1; // FLAGS
|
||||||
if (dt.getFlags1(elf_file) != null) nentries += 1; // FLAGS_1
|
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
|
nentries += 1; // NULL
|
||||||
return nentries * @sizeOf(elf.Elf64_Dyn);
|
return nentries * @sizeOf(elf.Elf64_Dyn);
|
||||||
}
|
}
|
||||||
|
|
@ -216,7 +216,7 @@ pub const DynamicSection = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG
|
// 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
|
// NULL
|
||||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NULL, .d_val = 0 });
|
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;
|
entry.* = sym_index;
|
||||||
const symbol = elf_file.symbol(sym_index);
|
const symbol = elf_file.symbol(sym_index);
|
||||||
symbol.flags.has_zig_got = true;
|
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;
|
zig_got.flags.needs_rela = true;
|
||||||
}
|
}
|
||||||
if (symbol.extra(elf_file)) |extra| {
|
if (symbol.extra(elf_file)) |extra| {
|
||||||
|
|
@ -495,7 +495,7 @@ pub const GotSection = struct {
|
||||||
const symbol = elf_file.symbol(sym_index);
|
const symbol = elf_file.symbol(sym_index);
|
||||||
symbol.flags.has_got = true;
|
symbol.flags.has_got = true;
|
||||||
if (symbol.flags.import or symbol.isIFunc(elf_file) or
|
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;
|
got.flags.needs_rela = true;
|
||||||
}
|
}
|
||||||
|
|
@ -528,7 +528,7 @@ pub const GotSection = struct {
|
||||||
entry.symbol_index = sym_index;
|
entry.symbol_index = sym_index;
|
||||||
const symbol = elf_file.symbol(sym_index);
|
const symbol = elf_file.symbol(sym_index);
|
||||||
symbol.flags.has_tlsgd = true;
|
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| {
|
if (symbol.extra(elf_file)) |extra| {
|
||||||
var new_extra = extra;
|
var new_extra = extra;
|
||||||
new_extra.tlsgd = index;
|
new_extra.tlsgd = index;
|
||||||
|
|
@ -545,7 +545,7 @@ pub const GotSection = struct {
|
||||||
entry.symbol_index = sym_index;
|
entry.symbol_index = sym_index;
|
||||||
const symbol = elf_file.symbol(sym_index);
|
const symbol = elf_file.symbol(sym_index);
|
||||||
symbol.flags.has_gottp = true;
|
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| {
|
if (symbol.extra(elf_file)) |extra| {
|
||||||
var new_extra = extra;
|
var new_extra = extra;
|
||||||
new_extra.gottp = index;
|
new_extra.gottp = index;
|
||||||
|
|
@ -580,7 +580,7 @@ pub const GotSection = struct {
|
||||||
|
|
||||||
pub fn write(got: GotSection, elf_file: *Elf, writer: anytype) !void {
|
pub fn write(got: GotSection, elf_file: *Elf, writer: anytype) !void {
|
||||||
const comp = elf_file.base.comp;
|
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
|
const apply_relocs = true; // TODO add user option for this
|
||||||
|
|
||||||
for (got.entries.items) |entry| {
|
for (got.entries.items) |entry| {
|
||||||
|
|
@ -595,7 +595,7 @@ pub const GotSection = struct {
|
||||||
if (symbol.?.flags.import) break :blk 0;
|
if (symbol.?.flags.import) break :blk 0;
|
||||||
if (symbol.?.isIFunc(elf_file))
|
if (symbol.?.isIFunc(elf_file))
|
||||||
break :blk if (apply_relocs) value else 0;
|
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))
|
!symbol.?.isAbs(elf_file))
|
||||||
{
|
{
|
||||||
break :blk if (apply_relocs) value else 0;
|
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 {
|
pub fn addRela(got: GotSection, elf_file: *Elf) !void {
|
||||||
const comp = elf_file.base.comp;
|
const comp = elf_file.base.comp;
|
||||||
const gpa = comp.gpa;
|
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;
|
const cpu_arch = elf_file.getTarget().cpu.arch;
|
||||||
try elf_file.rela_dyn.ensureUnusedCapacity(gpa, got.numRela(elf_file));
|
try elf_file.rela_dyn.ensureUnusedCapacity(gpa, got.numRela(elf_file));
|
||||||
|
|
||||||
|
|
@ -683,7 +683,7 @@ pub const GotSection = struct {
|
||||||
});
|
});
|
||||||
continue;
|
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))
|
!symbol.?.isAbs(elf_file))
|
||||||
{
|
{
|
||||||
elf_file.addRelaDynAssumeCapacity(.{
|
elf_file.addRelaDynAssumeCapacity(.{
|
||||||
|
|
@ -758,7 +758,7 @@ pub const GotSection = struct {
|
||||||
|
|
||||||
pub fn numRela(got: GotSection, elf_file: *Elf) usize {
|
pub fn numRela(got: GotSection, elf_file: *Elf) usize {
|
||||||
const comp = elf_file.base.comp;
|
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;
|
var num: usize = 0;
|
||||||
for (got.entries.items) |entry| {
|
for (got.entries.items) |entry| {
|
||||||
const symbol = switch (entry.tag) {
|
const symbol = switch (entry.tag) {
|
||||||
|
|
@ -767,7 +767,7 @@ pub const GotSection = struct {
|
||||||
};
|
};
|
||||||
switch (entry.tag) {
|
switch (entry.tag) {
|
||||||
.got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or
|
.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)))
|
!symbol.?.isAbs(elf_file)))
|
||||||
{
|
{
|
||||||
num += 1;
|
num += 1;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue