authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-05-16 21:20:31+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-05-17 04:41:26+02:00
log0d35a7760e419166577b0c032f598dc76d379a39
treeff59120d5301940cff9cb286fb9ad42ec81252ad
parent76d525f74a33e20dfa4c9e84b27ce8ad84529cac
signature Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

freebsd: Fix selection of unversioned symbol inclusion.

We want the latest unversioned inclusion that fits the target version. This theoretically matters because it might have a different global vs weak linkage compared to an older inclusion.

1 files changed, 42 insertions(+), 55 deletions(-)

src/libs/freebsd.zig+42-55
...@@ -533,7 +533,6 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -533,7 +533,6 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
533 var opt_symbol_name: ?[]const u8 = null;533 var opt_symbol_name: ?[]const u8 = null;
534 var versions = try std.DynamicBitSetUnmanaged.initEmpty(arena, metadata.all_versions.len);534 var versions = try std.DynamicBitSetUnmanaged.initEmpty(arena, metadata.all_versions.len);
535 var weak_linkages = try std.DynamicBitSetUnmanaged.initEmpty(arena, metadata.all_versions.len);535 var weak_linkages = try std.DynamicBitSetUnmanaged.initEmpty(arena, metadata.all_versions.len);
536 var sym_unversioned = false;
537536
538 var inc_fbs = std.io.fixedBufferStream(metadata.inclusions);537 var inc_fbs = std.io.fixedBufferStream(metadata.inclusions);
539 var inc_reader = inc_fbs.reader();538 var inc_reader = inc_fbs.reader();
...@@ -548,11 +547,17 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -548,11 +547,17 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
548 opt_symbol_name = sym_name_buf.items;547 opt_symbol_name = sym_name_buf.items;
549 versions.unsetAll();548 versions.unsetAll();
550 weak_linkages.unsetAll();549 weak_linkages.unsetAll();
551 sym_unversioned = false;
552550
553 break :n sym_name_buf.items;551 break :n sym_name_buf.items;
554 };552 };
555553
554 // Pick the default symbol version:
555 // - If there are no versions, don't emit it
556 // - Take the greatest one <= than the target one
557 // - If none of them is <= than the
558 // specified one don't pick any default version
559 var chosen_def_ver_index: usize = 255;
560 var chosen_unversioned_ver_index: usize = 255;
556 {561 {
557 const targets = try std.leb.readUleb128(u64, inc_reader);562 const targets = try std.leb.readUleb128(u64, inc_reader);
558 var lib_index = try inc_reader.readByte();563 var lib_index = try inc_reader.readByte();
...@@ -574,7 +579,12 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -574,7 +579,12 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
574 const ver_i = @as(u7, @truncate(byte));579 const ver_i = @as(u7, @truncate(byte));
575 if (ok_lib_and_target and ver_i <= target_ver_index) {580 if (ok_lib_and_target and ver_i <= target_ver_index) {
576 versions.set(ver_i);581 versions.set(ver_i);
577 if (is_unversioned) sym_unversioned = true;582 if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
583 chosen_def_ver_index = ver_i;
584 }
585 if (is_unversioned and (chosen_unversioned_ver_index == 255 or ver_i > chosen_unversioned_ver_index)) {
586 chosen_unversioned_ver_index = ver_i;
587 }
578 if (is_weak) weak_linkages.set(ver_i);588 if (is_weak) weak_linkages.set(ver_i);
579 }589 }
580 if (last) break;590 if (last) break;
...@@ -585,25 +595,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -585,25 +595,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
585 } else continue;595 } else continue;
586 }596 }
587597
588 // Pick the default symbol version:
589 // - If there are no versions, don't emit it
590 // - Take the greatest one <= than the target one
591 // - If none of them is <= than the
592 // specified one don't pick any default version
593 var chosen_def_ver_index: usize = 255;
594 {
595 var versions_iter = versions.iterator(.{});
596 while (versions_iter.next()) |ver_i| {
597 if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
598 chosen_def_ver_index = ver_i;
599 }
600 }
601 }
602
603 {598 {
604 var versions_iter = versions.iterator(.{});599 var versions_iter = versions.iterator(.{});
605 while (versions_iter.next()) |ver_index| {600 while (versions_iter.next()) |ver_index| {
606 if (sym_unversioned) {601 if (chosen_unversioned_ver_index != 255 and ver_index == chosen_unversioned_ver_index) {
607 // Example:602 // Example:
608 // .balign 4603 // .balign 4
609 // .globl _Exit604 // .globl _Exit
...@@ -701,11 +696,17 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -701,11 +696,17 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
701 opt_symbol_name = sym_name_buf.items;696 opt_symbol_name = sym_name_buf.items;
702 versions.unsetAll();697 versions.unsetAll();
703 weak_linkages.unsetAll();698 weak_linkages.unsetAll();
704 sym_unversioned = false;
705699
706 break :n sym_name_buf.items;700 break :n sym_name_buf.items;
707 };701 };
708702
703 // Pick the default symbol version:
704 // - If there are no versions, don't emit it
705 // - Take the greatest one <= than the target one
706 // - If none of them is <= than the
707 // specified one don't pick any default version
708 var chosen_def_ver_index: usize = 255;
709 var chosen_unversioned_ver_index: usize = 255;
709 {710 {
710 const targets = try std.leb.readUleb128(u64, inc_reader);711 const targets = try std.leb.readUleb128(u64, inc_reader);
711 const size = try std.leb.readUleb128(u16, inc_reader);712 const size = try std.leb.readUleb128(u16, inc_reader);
...@@ -728,8 +729,13 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -728,8 +729,13 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
728 const ver_i = @as(u7, @truncate(byte));729 const ver_i = @as(u7, @truncate(byte));
729 if (ok_lib_and_target and ver_i <= target_ver_index) {730 if (ok_lib_and_target and ver_i <= target_ver_index) {
730 versions.set(ver_i);731 versions.set(ver_i);
732 if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
733 chosen_def_ver_index = ver_i;
734 }
735 if (is_unversioned and (chosen_unversioned_ver_index == 255 or ver_i > chosen_unversioned_ver_index)) {
736 chosen_unversioned_ver_index = ver_i;
737 }
731 sizes[ver_i] = size;738 sizes[ver_i] = size;
732 if (is_unversioned) sym_unversioned = true;
733 if (is_weak) weak_linkages.set(ver_i);739 if (is_weak) weak_linkages.set(ver_i);
734 }740 }
735 if (last) break;741 if (last) break;
...@@ -740,25 +746,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -740,25 +746,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
740 } else continue;746 } else continue;
741 }747 }
742748
743 // Pick the default symbol version:
744 // - If there are no versions, don't emit it
745 // - Take the greatest one <= than the target one
746 // - If none of them is <= than the
747 // specified one don't pick any default version
748 var chosen_def_ver_index: usize = 255;
749 {
750 var versions_iter = versions.iterator(.{});
751 while (versions_iter.next()) |ver_i| {
752 if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
753 chosen_def_ver_index = ver_i;
754 }
755 }
756 }
757
758 {749 {
759 var versions_iter = versions.iterator(.{});750 var versions_iter = versions.iterator(.{});
760 while (versions_iter.next()) |ver_index| {751 while (versions_iter.next()) |ver_index| {
761 if (sym_unversioned) {752 if (chosen_unversioned_ver_index != 255 and ver_index == chosen_unversioned_ver_index) {
762 // Example:753 // Example:
763 // .balign 4754 // .balign 4
764 // .globl malloc_conf755 // .globl malloc_conf
...@@ -843,11 +834,17 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -843,11 +834,17 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
843 opt_symbol_name = sym_name_buf.items;834 opt_symbol_name = sym_name_buf.items;
844 versions.unsetAll();835 versions.unsetAll();
845 weak_linkages.unsetAll();836 weak_linkages.unsetAll();
846 sym_unversioned = false;
847837
848 break :n sym_name_buf.items;838 break :n sym_name_buf.items;
849 };839 };
850840
841 // Pick the default symbol version:
842 // - If there are no versions, don't emit it
843 // - Take the greatest one <= than the target one
844 // - If none of them is <= than the
845 // specified one don't pick any default version
846 var chosen_def_ver_index: usize = 255;
847 var chosen_unversioned_ver_index: usize = 255;
851 {848 {
852 const targets = try std.leb.readUleb128(u64, inc_reader);849 const targets = try std.leb.readUleb128(u64, inc_reader);
853 const size = try std.leb.readUleb128(u16, inc_reader);850 const size = try std.leb.readUleb128(u16, inc_reader);
...@@ -870,8 +867,13 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -870,8 +867,13 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
870 const ver_i = @as(u7, @truncate(byte));867 const ver_i = @as(u7, @truncate(byte));
871 if (ok_lib_and_target and ver_i <= target_ver_index) {868 if (ok_lib_and_target and ver_i <= target_ver_index) {
872 versions.set(ver_i);869 versions.set(ver_i);
870 if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
871 chosen_def_ver_index = ver_i;
872 }
873 if (is_unversioned and (chosen_unversioned_ver_index == 255 or ver_i > chosen_unversioned_ver_index)) {
874 chosen_unversioned_ver_index = ver_i;
875 }
873 sizes[ver_i] = size;876 sizes[ver_i] = size;
874 if (is_unversioned) sym_unversioned = true;
875 if (is_weak) weak_linkages.set(ver_i);877 if (is_weak) weak_linkages.set(ver_i);
876 }878 }
877 if (last) break;879 if (last) break;
...@@ -882,25 +884,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -882,25 +884,10 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
882 } else continue;884 } else continue;
883 }885 }
884886
885 // Pick the default symbol version:
886 // - If there are no versions, don't emit it
887 // - Take the greatest one <= than the target one
888 // - If none of them is <= than the
889 // specified one don't pick any default version
890 var chosen_def_ver_index: usize = 255;
891 {
892 var versions_iter = versions.iterator(.{});
893 while (versions_iter.next()) |ver_i| {
894 if (chosen_def_ver_index == 255 or ver_i > chosen_def_ver_index) {
895 chosen_def_ver_index = ver_i;
896 }
897 }
898 }
899
900 {887 {
901 var versions_iter = versions.iterator(.{});888 var versions_iter = versions.iterator(.{});
902 while (versions_iter.next()) |ver_index| {889 while (versions_iter.next()) |ver_index| {
903 if (sym_unversioned) {890 if (chosen_unversioned_ver_index != 255 and ver_index == chosen_unversioned_ver_index) {
904 // Example:891 // Example:
905 // .balign 4892 // .balign 4
906 // .globl _ThreadRuneLocale893 // .globl _ThreadRuneLocale