freebsd: Fix stub libraries containing versioned symbols that shouldn't be.

Closes #23911.
This commit is contained in:
Alex Rønne Petersen 2025-05-17 20:10:11 +02:00
parent a97e417ab1
commit cd1eea0964
No known key found for this signature in database

View File

@ -539,6 +539,14 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
const fn_inclusions_len = try inc_reader.readInt(u16, .little);
// Pick the default symbol version:
// - If there are no versions, don't emit it
// - Take the greatest one <= than the target one
// - If none of them is <= than the
// specified one don't pick any default version
var chosen_def_ver_index: usize = 255;
var chosen_unversioned_ver_index: usize = 255;
while (sym_i < fn_inclusions_len) : (sym_i += 1) {
const sym_name = opt_symbol_name orelse n: {
sym_name_buf.clearRetainingCapacity();
@ -547,17 +555,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
opt_symbol_name = sym_name_buf.items;
versions.unsetAll();
weak_linkages.unsetAll();
chosen_def_ver_index = 255;
chosen_unversioned_ver_index = 255;
break :n sym_name_buf.items;
};
// Pick the default symbol version:
// - If there are no versions, don't emit it
// - Take the greatest one <= than the target one
// - If none of them is <= than the
// specified one don't pick any default version
var chosen_def_ver_index: usize = 255;
var chosen_unversioned_ver_index: usize = 255;
{
const targets = try std.leb.readUleb128(u64, inc_reader);
var lib_index = try inc_reader.readByte();
@ -578,14 +580,19 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
const last = (byte & 0b1000_0000) != 0;
const ver_i = @as(u7, @truncate(byte));
if (ok_lib_and_target and ver_i <= target_ver_index) {
versions.set(ver_i);
if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
chosen_def_ver_index = ver_i;
if (is_unversioned) {
if (chosen_unversioned_ver_index == 255 or ver_i > chosen_unversioned_ver_index) {
chosen_unversioned_ver_index = ver_i;
}
} else {
if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
chosen_def_ver_index = ver_i;
}
versions.set(ver_i);
}
if (is_unversioned and (chosen_unversioned_ver_index == 255 or ver_i > chosen_unversioned_ver_index)) {
chosen_unversioned_ver_index = ver_i;
}
if (is_weak) weak_linkages.set(ver_i);
weak_linkages.setValue(ver_i, is_weak);
}
if (last) break;
}
@ -595,31 +602,31 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
} else continue;
}
if (chosen_unversioned_ver_index != 255) {
// Example:
// .balign 4
// .globl _Exit
// .type _Exit, %function
// _Exit: .long 0
try stubs_writer.print(
\\.balign {d}
\\.{s} {s}
\\.type {s}, %function
\\{s}: {s} 0
\\
, .{
target.ptrBitWidth() / 8,
if (weak_linkages.isSet(chosen_unversioned_ver_index)) "weak" else "globl",
sym_name,
sym_name,
sym_name,
wordDirective(target),
});
}
{
var versions_iter = versions.iterator(.{});
while (versions_iter.next()) |ver_index| {
if (chosen_unversioned_ver_index != 255 and ver_index == chosen_unversioned_ver_index) {
// Example:
// .balign 4
// .globl _Exit
// .type _Exit, %function
// _Exit: .long 0
try stubs_writer.print(
\\.balign {d}
\\.{s} {s}
\\.type {s}, %function
\\{s}: {s} 0
\\
, .{
target.ptrBitWidth() / 8,
if (weak_linkages.isSet(ver_index)) "weak" else "globl",
sym_name,
sym_name,
sym_name,
wordDirective(target),
});
}
// Example:
// .balign 4
// .globl _Exit_1_0
@ -627,10 +634,6 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
// .symver _Exit_1_0, _Exit@@FBSD_1.0, remove
// _Exit_1_0: .long 0
const ver = metadata.all_versions[ver_index];
// Default symbol version definition vs normal symbol version definition
const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
const at_sign_str: []const u8 = if (want_default) "@@" else "@";
const sym_plus_ver = try std.fmt.allocPrint(
arena,
"{s}_FBSD_{d}_{d}",
@ -651,7 +654,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
sym_plus_ver,
sym_plus_ver,
sym_name,
at_sign_str,
// Default symbol version definition vs normal symbol version definition
if (chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index) "@@" else "@",
ver.major,
ver.minor,
sym_plus_ver,
@ -688,6 +692,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
sym_i = 0;
opt_symbol_name = null;
while (sym_i < obj_inclusions_len) : (sym_i += 1) {
const sym_name = opt_symbol_name orelse n: {
sym_name_buf.clearRetainingCapacity();
@ -696,17 +701,12 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
opt_symbol_name = sym_name_buf.items;
versions.unsetAll();
weak_linkages.unsetAll();
chosen_def_ver_index = 255;
chosen_unversioned_ver_index = 255;
break :n sym_name_buf.items;
};
// Pick the default symbol version:
// - If there are no versions, don't emit it
// - Take the greatest one <= than the target one
// - If none of them is <= than the
// specified one don't pick any default version
var chosen_def_ver_index: usize = 255;
var chosen_unversioned_ver_index: usize = 255;
{
const targets = try std.leb.readUleb128(u64, inc_reader);
const size = try std.leb.readUleb128(u16, inc_reader);
@ -728,15 +728,20 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
const last = (byte & 0b1000_0000) != 0;
const ver_i = @as(u7, @truncate(byte));
if (ok_lib_and_target and ver_i <= target_ver_index) {
versions.set(ver_i);
if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
chosen_def_ver_index = ver_i;
}
if (is_unversioned and (chosen_unversioned_ver_index == 255 or ver_i > chosen_unversioned_ver_index)) {
chosen_unversioned_ver_index = ver_i;
if (is_unversioned) {
if (chosen_unversioned_ver_index == 255 or ver_i > chosen_unversioned_ver_index) {
chosen_unversioned_ver_index = ver_i;
}
} else {
if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
chosen_def_ver_index = ver_i;
}
versions.set(ver_i);
}
sizes[ver_i] = size;
if (is_weak) weak_linkages.set(ver_i);
weak_linkages.setValue(ver_i, is_weak);
}
if (last) break;
}
@ -746,35 +751,35 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
} else continue;
}
if (chosen_unversioned_ver_index != 255) {
// Example:
// .balign 4
// .globl malloc_conf
// .type malloc_conf, %object
// .size malloc_conf, 4
// malloc_conf: .fill 4, 1, 0
try stubs_writer.print(
\\.balign {d}
\\.{s} {s}
\\.type {s}, %object
\\.size {s}, {d}
\\{s}: {s} 0
\\
, .{
target.ptrBitWidth() / 8,
if (weak_linkages.isSet(chosen_unversioned_ver_index)) "weak" else "globl",
sym_name,
sym_name,
sym_name,
sizes[chosen_unversioned_ver_index],
sym_name,
wordDirective(target),
});
}
{
var versions_iter = versions.iterator(.{});
while (versions_iter.next()) |ver_index| {
if (chosen_unversioned_ver_index != 255 and ver_index == chosen_unversioned_ver_index) {
// Example:
// .balign 4
// .globl malloc_conf
// .type malloc_conf, %object
// .size malloc_conf, 4
// malloc_conf: .fill 4, 1, 0
try stubs_writer.print(
\\.balign {d}
\\.{s} {s}
\\.type {s}, %object
\\.size {s}, {d}
\\{s}: {s} 0
\\
, .{
target.ptrBitWidth() / 8,
if (weak_linkages.isSet(ver_index)) "weak" else "globl",
sym_name,
sym_name,
sym_name,
sizes[ver_index],
sym_name,
wordDirective(target),
});
}
// Example:
// .balign 4
// .globl malloc_conf_1_3
@ -783,10 +788,6 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
// .symver malloc_conf_1_3, malloc_conf@@FBSD_1.3
// malloc_conf_1_3: .fill 4, 1, 0
const ver = metadata.all_versions[ver_index];
// Default symbol version definition vs normal symbol version definition
const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
const at_sign_str: []const u8 = if (want_default) "@@" else "@";
const sym_plus_ver = try std.fmt.allocPrint(
arena,
"{s}_FBSD_{d}_{d}",
@ -810,7 +811,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
sizes[ver_index],
sym_plus_ver,
sym_name,
at_sign_str,
// Default symbol version definition vs normal symbol version definition
if (chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index) "@@" else "@",
ver.major,
ver.minor,
sym_plus_ver,
@ -826,6 +828,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
sym_i = 0;
opt_symbol_name = null;
while (sym_i < tls_inclusions_len) : (sym_i += 1) {
const sym_name = opt_symbol_name orelse n: {
sym_name_buf.clearRetainingCapacity();
@ -834,17 +837,12 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
opt_symbol_name = sym_name_buf.items;
versions.unsetAll();
weak_linkages.unsetAll();
chosen_def_ver_index = 255;
chosen_unversioned_ver_index = 255;
break :n sym_name_buf.items;
};
// Pick the default symbol version:
// - If there are no versions, don't emit it
// - Take the greatest one <= than the target one
// - If none of them is <= than the
// specified one don't pick any default version
var chosen_def_ver_index: usize = 255;
var chosen_unversioned_ver_index: usize = 255;
{
const targets = try std.leb.readUleb128(u64, inc_reader);
const size = try std.leb.readUleb128(u16, inc_reader);
@ -866,15 +864,20 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
const last = (byte & 0b1000_0000) != 0;
const ver_i = @as(u7, @truncate(byte));
if (ok_lib_and_target and ver_i <= target_ver_index) {
versions.set(ver_i);
if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
chosen_def_ver_index = ver_i;
}
if (is_unversioned and (chosen_unversioned_ver_index == 255 or ver_i > chosen_unversioned_ver_index)) {
chosen_unversioned_ver_index = ver_i;
if (is_unversioned) {
if (chosen_unversioned_ver_index == 255 or ver_i > chosen_unversioned_ver_index) {
chosen_unversioned_ver_index = ver_i;
}
} else {
if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
chosen_def_ver_index = ver_i;
}
versions.set(ver_i);
}
sizes[ver_i] = size;
if (is_weak) weak_linkages.set(ver_i);
weak_linkages.setValue(ver_i, is_weak);
}
if (last) break;
}
@ -884,35 +887,35 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
} else continue;
}
if (chosen_unversioned_ver_index != 255) {
// Example:
// .balign 4
// .globl _ThreadRuneLocale
// .type _ThreadRuneLocale, %object
// .size _ThreadRuneLocale, 4
// _ThreadRuneLocale: .fill 4, 1, 0
try stubs_writer.print(
\\.balign {d}
\\.{s} {s}
\\.type {s}, %tls_object
\\.size {s}, {d}
\\{s}: {s} 0
\\
, .{
target.ptrBitWidth() / 8,
if (weak_linkages.isSet(chosen_unversioned_ver_index)) "weak" else "globl",
sym_name,
sym_name,
sym_name,
sizes[chosen_unversioned_ver_index],
sym_name,
wordDirective(target),
});
}
{
var versions_iter = versions.iterator(.{});
while (versions_iter.next()) |ver_index| {
if (chosen_unversioned_ver_index != 255 and ver_index == chosen_unversioned_ver_index) {
// Example:
// .balign 4
// .globl _ThreadRuneLocale
// .type _ThreadRuneLocale, %object
// .size _ThreadRuneLocale, 4
// _ThreadRuneLocale: .fill 4, 1, 0
try stubs_writer.print(
\\.balign {d}
\\.{s} {s}
\\.type {s}, %tls_object
\\.size {s}, {d}
\\{s}: {s} 0
\\
, .{
target.ptrBitWidth() / 8,
if (weak_linkages.isSet(ver_index)) "weak" else "globl",
sym_name,
sym_name,
sym_name,
sizes[ver_index],
sym_name,
wordDirective(target),
});
}
// Example:
// .balign 4
// .globl _ThreadRuneLocale_1_3
@ -921,10 +924,6 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
// .symver _ThreadRuneLocale_1_3, _ThreadRuneLocale@@FBSD_1.3
// _ThreadRuneLocale_1_3: .fill 4, 1, 0
const ver = metadata.all_versions[ver_index];
// Default symbol version definition vs normal symbol version definition
const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
const at_sign_str: []const u8 = if (want_default) "@@" else "@";
const sym_plus_ver = try std.fmt.allocPrint(
arena,
"{s}_FBSD_{d}_{d}",
@ -948,7 +947,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
sizes[ver_index],
sym_plus_ver,
sym_name,
at_sign_str,
// Default symbol version definition vs normal symbol version definition
if (chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index) "@@" else "@",
ver.major,
ver.minor,
sym_plus_ver,