Skip to content

Commit aeba466

Browse files
committed
glibc: Fix an edge case leading to duplicate stub symbols.
Closes #20376. Closes #21076.
1 parent 8917a79 commit aeba466

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

src/glibc.zig

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,23 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
849849
var opt_symbol_name: ?[]const u8 = null;
850850
var versions_buffer: [32]u8 = undefined;
851851
var versions_len: usize = undefined;
852+
853+
// There can be situations where there are multiple inclusions for the same symbol with
854+
// overlapping versions. For example:
855+
//
856+
// lgammal:
857+
// library: libm.so
858+
// versions: 2.4 2.23
859+
// targets: ... s390x-linux-gnu ...
860+
// lgammal:
861+
// library: libm.so
862+
// versions: 2.2 2.23
863+
// targets: ... s390x-linux-gnu ...
864+
//
865+
// If we don't handle this, we end up writing the default `lgammal` symbol for version 2.33
866+
// twice, which causes a "duplicate symbol" assembler error.
867+
var versions_written = std.AutoArrayHashMap(Version, void).init(arena);
868+
852869
while (sym_i < fn_inclusions_len) : (sym_i += 1) {
853870
const sym_name = opt_symbol_name orelse n: {
854871
const name = mem.sliceTo(metadata.inclusions[inc_i..], 0);
@@ -902,6 +919,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
902919
}
903920
}
904921
}
922+
923+
versions_written.clearRetainingCapacity();
924+
try versions_written.ensureTotalCapacity(versions_len);
925+
905926
{
906927
var ver_buf_i: u8 = 0;
907928
while (ver_buf_i < versions_len) : (ver_buf_i += 1) {
@@ -912,6 +933,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
912933
// _Exit_2_2_5:
913934
const ver_index = versions_buffer[ver_buf_i];
914935
const ver = metadata.all_versions[ver_index];
936+
937+
if (versions_written.getOrPutAssumeCapacity(ver).found_existing) continue;
938+
915939
// Default symbol version definition vs normal symbol version definition
916940
const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
917941
const at_sign_str: []const u8 = if (want_default) "@@" else "@";
@@ -1061,6 +1085,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
10611085
}
10621086
}
10631087
}
1088+
1089+
versions_written.clearRetainingCapacity();
1090+
try versions_written.ensureTotalCapacity(versions_len);
1091+
10641092
{
10651093
var ver_buf_i: u8 = 0;
10661094
while (ver_buf_i < versions_len) : (ver_buf_i += 1) {
@@ -1072,6 +1100,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
10721100
// environ_2_2_5:
10731101
const ver_index = versions_buffer[ver_buf_i];
10741102
const ver = metadata.all_versions[ver_index];
1103+
1104+
if (versions_written.getOrPutAssumeCapacity(ver).found_existing) continue;
1105+
10751106
// Default symbol version definition vs normal symbol version definition
10761107
const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
10771108
const at_sign_str: []const u8 = if (want_default) "@@" else "@";

0 commit comments

Comments
 (0)