Skip to content

Commit 27c72c5

Browse files
committed
glibc: Fix an edge case leading to duplicate stub symbols.
Closes #20376. Closes #21076.
1 parent 1773a88 commit 27c72c5

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
@@ -854,6 +854,23 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
854854
var opt_symbol_name: ?[]const u8 = null;
855855
var versions_buffer: [32]u8 = undefined;
856856
var versions_len: usize = undefined;
857+
858+
// There can be situations where there are multiple inclusions for the same symbol with
859+
// partially overlapping versions, due to different target lists. For example:
860+
//
861+
// lgammal:
862+
// library: libm.so
863+
// versions: 2.4 2.23
864+
// targets: ... powerpc64-linux-gnu s390x-linux-gnu
865+
// lgammal:
866+
// library: libm.so
867+
// versions: 2.2 2.23
868+
// targets: sparc64-linux-gnu s390x-linux-gnu
869+
//
870+
// If we don't handle this, we end up writing the default `lgammal` symbol for version 2.33
871+
// twice, which causes a "duplicate symbol" assembler error.
872+
var versions_written = std.AutoArrayHashMap(Version, void).init(arena);
873+
857874
while (sym_i < fn_inclusions_len) : (sym_i += 1) {
858875
const sym_name = opt_symbol_name orelse n: {
859876
const name = mem.sliceTo(metadata.inclusions[inc_i..], 0);
@@ -907,6 +924,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
907924
}
908925
}
909926
}
927+
928+
versions_written.clearRetainingCapacity();
929+
try versions_written.ensureTotalCapacity(versions_len);
930+
910931
{
911932
var ver_buf_i: u8 = 0;
912933
while (ver_buf_i < versions_len) : (ver_buf_i += 1) {
@@ -917,6 +938,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
917938
// _Exit_2_2_5:
918939
const ver_index = versions_buffer[ver_buf_i];
919940
const ver = metadata.all_versions[ver_index];
941+
942+
if (versions_written.getOrPutAssumeCapacity(ver).found_existing) continue;
943+
920944
// Default symbol version definition vs normal symbol version definition
921945
const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
922946
const at_sign_str: []const u8 = if (want_default) "@@" else "@";
@@ -1066,6 +1090,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
10661090
}
10671091
}
10681092
}
1093+
1094+
versions_written.clearRetainingCapacity();
1095+
try versions_written.ensureTotalCapacity(versions_len);
1096+
10691097
{
10701098
var ver_buf_i: u8 = 0;
10711099
while (ver_buf_i < versions_len) : (ver_buf_i += 1) {
@@ -1077,6 +1105,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
10771105
// environ_2_2_5:
10781106
const ver_index = versions_buffer[ver_buf_i];
10791107
const ver = metadata.all_versions[ver_index];
1108+
1109+
if (versions_written.getOrPutAssumeCapacity(ver).found_existing) continue;
1110+
10801111
// Default symbol version definition vs normal symbol version definition
10811112
const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
10821113
const at_sign_str: []const u8 = if (want_default) "@@" else "@";

0 commit comments

Comments
 (0)