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