authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-08-24 22:42:57+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-09-05 06:16:26+02:00
log27c72c555a3e5cb170703e3820a1f0ce25fc3e2d
tree8cda60311cb55b359c1a614ce773d35b678246f3
parent1773a88ab1a0dca05e6f8a19f873efec9ecfa858
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

glibc: Fix an edge case leading to duplicate stub symbols.

Closes #20376. Closes #21076.

1 files changed, 31 insertions(+), 0 deletions(-)

src/glibc.zig+31
...@@ -854,6 +854,23 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi...@@ -854,6 +854,23 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
854 var opt_symbol_name: ?[]const u8 = null;854 var opt_symbol_name: ?[]const u8 = null;
855 var versions_buffer: [32]u8 = undefined;855 var versions_buffer: [32]u8 = undefined;
856 var versions_len: usize = undefined;856 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
857 while (sym_i < fn_inclusions_len) : (sym_i += 1) {874 while (sym_i < fn_inclusions_len) : (sym_i += 1) {
858 const sym_name = opt_symbol_name orelse n: {875 const sym_name = opt_symbol_name orelse n: {
859 const name = mem.sliceTo(metadata.inclusions[inc_i..], 0);876 const name = mem.sliceTo(metadata.inclusions[inc_i..], 0);
...@@ -907,6 +924,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi...@@ -907,6 +924,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
907 }924 }
908 }925 }
909 }926 }
927
928 versions_written.clearRetainingCapacity();
929 try versions_written.ensureTotalCapacity(versions_len);
930
910 {931 {
911 var ver_buf_i: u8 = 0;932 var ver_buf_i: u8 = 0;
912 while (ver_buf_i < versions_len) : (ver_buf_i += 1) {933 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...@@ -917,6 +938,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
917 // _Exit_2_2_5:938 // _Exit_2_2_5:
918 const ver_index = versions_buffer[ver_buf_i];939 const ver_index = versions_buffer[ver_buf_i];
919 const ver = metadata.all_versions[ver_index];940 const ver = metadata.all_versions[ver_index];
941
942 if (versions_written.getOrPutAssumeCapacity(ver).found_existing) continue;
943
920 // Default symbol version definition vs normal symbol version definition944 // Default symbol version definition vs normal symbol version definition
921 const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;945 const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
922 const at_sign_str: []const u8 = if (want_default) "@@" else "@";946 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...@@ -1066,6 +1090,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
1066 }1090 }
1067 }1091 }
1068 }1092 }
1093
1094 versions_written.clearRetainingCapacity();
1095 try versions_written.ensureTotalCapacity(versions_len);
1096
1069 {1097 {
1070 var ver_buf_i: u8 = 0;1098 var ver_buf_i: u8 = 0;
1071 while (ver_buf_i < versions_len) : (ver_buf_i += 1) {1099 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...@@ -1077,6 +1105,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
1077 // environ_2_2_5:1105 // environ_2_2_5:
1078 const ver_index = versions_buffer[ver_buf_i];1106 const ver_index = versions_buffer[ver_buf_i];
1079 const ver = metadata.all_versions[ver_index];1107 const ver = metadata.all_versions[ver_index];
1108
1109 if (versions_written.getOrPutAssumeCapacity(ver).found_existing) continue;
1110
1080 // Default symbol version definition vs normal symbol version definition1111 // Default symbol version definition vs normal symbol version definition
1081 const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;1112 const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
1082 const at_sign_str: []const u8 = if (want_default) "@@" else "@";1113 const at_sign_str: []const u8 = if (want_default) "@@" else "@";