| ... | ... | @@ -424,13 +424,13 @@ fn glibcVerFromSO(so_path: [:0]const u8) !std.builtin.Version { |
| 424 | 424 | error.BadPathName => unreachable, // Windows only |
| 425 | 425 | error.UnsupportedReparsePointType => unreachable, // Windows only |
| 426 | 426 | }; |
| 427 | | return glibcVerFromLinkName(link_name); |
| 427 | return glibcVerFromLinkName(link_name, "libc-"); |
| 428 | 428 | } |
| 429 | 429 | |
| 430 | | fn glibcVerFromLinkName(link_name: []const u8) !std.builtin.Version { |
| 430 | fn glibcVerFromLinkName(link_name: []const u8, prefix: []const u8) !std.builtin.Version { |
| 431 | 431 | // example: "libc-2.3.4.so" |
| 432 | 432 | // example: "libc-2.27.so" |
| 433 | | const prefix = "libc-"; |
| 433 | // example: "ld-2.33.so" |
| 434 | 434 | const suffix = ".so"; |
| 435 | 435 | if (!mem.startsWith(u8, link_name, prefix) or !mem.endsWith(u8, link_name, suffix)) { |
| 436 | 436 | return error.UnrecognizedGnuLibCFileName; |
| ... | ... | @@ -590,7 +590,9 @@ pub fn abiAndDynamicLinkerFromFile( |
| 590 | 590 | } |
| 591 | 591 | } |
| 592 | 592 | |
| 593 | | if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and cross_target.glibc_version == null) { |
| 593 | if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and |
| 594 | cross_target.glibc_version == null) |
| 595 | { |
| 594 | 596 | if (rpath_offset) |rpoff| { |
| 595 | 597 | const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx); |
| 596 | 598 | |
| ... | ... | @@ -706,6 +708,7 @@ pub fn abiAndDynamicLinkerFromFile( |
| 706 | 708 | }; |
| 707 | 709 | result.target.os.version_range.linux.glibc = glibcVerFromLinkName( |
| 708 | 710 | link_name, |
| 711 | "libc-", |
| 709 | 712 | ) catch |err| switch (err) { |
| 710 | 713 | error.UnrecognizedGnuLibCFileName, |
| 711 | 714 | error.InvalidGnuLibCVersion, |
| ... | ... | @@ -714,6 +717,36 @@ pub fn abiAndDynamicLinkerFromFile( |
| 714 | 717 | break; |
| 715 | 718 | } |
| 716 | 719 | } |
| 720 | } else if (result.dynamic_linker.get()) |dl_path| glibc_ver: { |
| 721 | // There is no DT_RUNPATH but we can try to see if the information is |
| 722 | // present in the symlink data for the dynamic linker path. |
| 723 | var link_buf: [std.os.PATH_MAX]u8 = undefined; |
| 724 | const link_name = std.os.readlink(dl_path, &link_buf) catch |err| switch (err) { |
| 725 | error.NameTooLong => unreachable, |
| 726 | error.InvalidUtf8 => unreachable, // Windows only |
| 727 | error.BadPathName => unreachable, // Windows only |
| 728 | error.UnsupportedReparsePointType => unreachable, // Windows only |
| 729 | |
| 730 | error.AccessDenied, |
| 731 | error.FileNotFound, |
| 732 | error.NotLink, |
| 733 | error.NotDir, |
| 734 | => break :glibc_ver, |
| 735 | |
| 736 | error.SystemResources, |
| 737 | error.FileSystem, |
| 738 | error.SymLinkLoop, |
| 739 | error.Unexpected, |
| 740 | => |e| return e, |
| 741 | }; |
| 742 | result.target.os.version_range.linux.glibc = glibcVerFromLinkName( |
| 743 | fs.path.basename(link_name), |
| 744 | "ld-", |
| 745 | ) catch |err| switch (err) { |
| 746 | error.UnrecognizedGnuLibCFileName, |
| 747 | error.InvalidGnuLibCVersion, |
| 748 | => break :glibc_ver, |
| 749 | }; |
| 717 | 750 | } |
| 718 | 751 | } |
| 719 | 752 | |