diff --git a/libpkg/pkg_elf.c b/libpkg/pkg_elf.c index 98dd14df1e..ee943410bb 100644 --- a/libpkg/pkg_elf.c +++ b/libpkg/pkg_elf.c @@ -606,6 +606,71 @@ aeabi_parse_arm_attributes(void *data, size_t length) #undef MOVE } +static const char * +elf_parse_arch(os_type_t ostype, Elf *elf, GElf_Ehdr *ehdr) +{ + switch (ehdr->e_machine) { + case EM_386: + return ("i386"); + case EM_X86_64: + switch (ostype) { + case OS_FREEBSD: + return ("amd64"); + case OS_DRAGONFLY: + return ("x86:64"); + default: + return ("x86_64"); + } + case EM_AARCH64: + return ("aarch64"); + case EM_ARM: + /* Only support EABI */ + if ((ehdr->e_flags & EF_ARM_EABIMASK) == 0) { + return (NULL); + } + + size_t shstrndx; + elf_getshdrstrndx(elf, &shstrndx); + + GElf_Shdr shdr; + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != &shdr) { + break; + } + const char *sh_name = elf_strptr(elf, shstrndx, shdr.sh_name); + if (sh_name == NULL) { + continue; + } + if (STREQ(".ARM.attributes", sh_name)) { + Elf_Data *data = elf_getdata(scn, NULL); + return (aeabi_parse_arm_attributes(data->d_buf, data->d_size)); + } + } + break; + case EM_PPC: + return ("powerpc"); + case EM_PPC64: + switch (ehdr->e_ident[EI_DATA]) { + case ELFDATA2MSB: + return ("powerpc64"); + case ELFDATA2LSB: + return ("powerpc64le"); + } + break; + case EM_RISCV: + switch (ehdr->e_ident[EI_CLASS]) { + case ELFCLASS32: + return ("riscv32"); + case ELFCLASS64: + return ("riscv64"); + } + break; + } + + return (NULL); +} + static bool elf_note_analyse(Elf_Data *data, GElf_Ehdr *elfhdr, struct os_info *oi) { @@ -731,10 +796,8 @@ pkg_get_myarch_elfparse(int fd, struct os_info *oi) Elf_Data *data; Elf_Scn *scn = NULL; int ret = EPKG_OK; - const char *arch,*abi, *endian_corres_str, *wordsize_corres_str, *fpu; char *dest = oi->abi; size_t sz = sizeof(oi->abi); - size_t dsz; if (elf_version(EV_CURRENT) == EV_NONE) { pkg_emit_error("ELF library initialization failed: %s", @@ -777,20 +840,15 @@ pkg_get_myarch_elfparse(int fd, struct os_info *oi) goto cleanup; } - snprintf(dest, sz, "%s:%s", oi->name, oi->version); - - wordsize_corres_str = elf_corres_to_string(wordsize_corres, - (int)elfhdr.e_ident[EI_CLASS]); - - if (oi->ostype == OS_FREEBSD && elfhdr.e_machine == EM_X86_64) - oi->arch = xstrdup("amd64"); - else if (oi->ostype == OS_DRAGONFLY && elfhdr.e_machine == EM_X86_64) - oi->arch = xstrdup("x86:64"); - else - oi->arch = xstrdup(elf_corres_to_string(mach_corres, (int) elfhdr.e_machine)); + const char *arch = elf_parse_arch(oi->ostype, elf, &elfhdr); + if (arch == NULL) { + ret = EPKG_FATAL; + pkg_emit_error("failed to determine the architecture"); + goto cleanup; + } + oi->arch = xstrdup(arch); - dsz = strlen(dest); - snprintf(dest + dsz, sz - dsz, ":%s", oi->arch); + snprintf(dest, sz, "%s:%s:%s", oi->name, oi->version, oi->arch); cleanup: if (elf != NULL) diff --git a/libpkg/private/elf_tables.h b/libpkg/private/elf_tables.h index 970fce23cf..dbe8ebab94 100644 --- a/libpkg/private/elf_tables.h +++ b/libpkg/private/elf_tables.h @@ -50,26 +50,6 @@ static const struct _elf_corres wordsize_corres[] = { { -1, NULL}, }; -static const struct _elf_corres endian_corres[] = { - { ELFDATA2MSB, "eb" }, - { ELFDATA2LSB, "el" }, - { -1, NULL} -}; - -static const struct _elf_corres os_corres[] = { - { ELFOSABI_FREEBSD, "freebsd" }, - { -1, NULL } -}; - -#ifndef EF_MIPS_ABI -#define EF_MIPS_ABI 0x0000F000 -#endif -#ifndef EF_ARM_VFP_FLOAT -#define EF_ARM_VFP_FLOAT 0x00000400 -#endif -#define E_MIPS_ABI_O32 0x00001000 -#define E_MIPS_ABI_N32 0x00000020 - #define NT_VERSION 1 #define NT_ARCH 2 #define NT_GNU_ABI_TAG 1 diff --git a/tests/Makefile.autosetup b/tests/Makefile.autosetup index 69d462559f..4f8739eb8e 100644 --- a/tests/Makefile.autosetup +++ b/tests/Makefile.autosetup @@ -68,13 +68,24 @@ TESTS_SH= \ frontend/triggers.sh # -# Those files simple binaries obtained from +# These files are mostly simple binaries obtained from # int main(void) { return 0; } # +# The freebsd-*.bin files are copies of /usr/bin/uname from official +# 14.1 release artifacts for the given architecture. + TESTS_SHELL_BINS= \ frontend/dfly.bin \ - frontend/fbsd.bin \ + frontend/freebsd-aarch64.bin \ + frontend/freebsd-amd64.bin \ + frontend/freebsd-armv6.bin \ + frontend/freebsd-armv7.bin \ + frontend/freebsd-i386.bin \ + frontend/freebsd-powerpc.bin \ + frontend/freebsd-powerpc64.bin \ + frontend/freebsd-powerpc64le.bin \ + frontend/freebsd-riscv64.bin \ frontend/linux.bin \ frontend/macos.bin \ frontend/macos106.bin \ diff --git a/tests/frontend/abi.sh b/tests/frontend/abi.sh index 0634fc1102..85464bb731 100644 --- a/tests/frontend/abi.sh +++ b/tests/frontend/abi.sh @@ -59,15 +59,96 @@ override_body() { elfparse_body() { # ELF parsing now works across platforms - _expected="FreeBSD:13:amd64\n" + + _expected="FreeBSD:14:aarch64\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-aarch64.bin config abi + + _expected="freebsd:14:aarch64:64\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-aarch64.bin config altabi + + _expected="FreeBSD:14:amd64\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-amd64.bin config abi + + _expected="freebsd:14:x86:64\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-amd64.bin config altabi + + _expected="FreeBSD:13:armv6\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-armv6.bin config abi + + _expected="freebsd:13:armv6:32:el:eabi:hardfp\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-armv6.bin config altabi + + _expected="FreeBSD:14:armv7\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-armv7.bin config abi + + _expected="freebsd:14:armv7:32:el:eabi:hardfp\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-armv7.bin config altabi + + _expected="FreeBSD:14:i386\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-i386.bin config abi + + _expected="freebsd:14:x86:32\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-i386.bin config altabi + + _expected="FreeBSD:14:powerpc\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-powerpc.bin config abi + + _expected="freebsd:14:powerpc:32:eb\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-powerpc.bin config altabi + + _expected="FreeBSD:14:powerpc64\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-powerpc64.bin config abi + + _expected="freebsd:14:powerpc:64:eb\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-powerpc64.bin config altabi + + _expected="FreeBSD:14:powerpc64le\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-powerpc64le.bin config abi + + _expected="freebsd:14:powerpc:64:el\n" + atf_check \ + -o inline:"${_expected}" \ + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-powerpc64le.bin config altabi + + _expected="FreeBSD:14:riscv64\n" atf_check \ -o inline:"${_expected}" \ - pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/fbsd.bin config abi + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-riscv64.bin config abi - _expected="freebsd:13:x86:64\n" + _expected="freebsd:14:riscv:64:hf\n" atf_check \ -o inline:"${_expected}" \ - pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/fbsd.bin config altabi + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=$(atf_get_srcdir)/freebsd-riscv64.bin config altabi _expected="dragonfly:5.10:x86:64\n" atf_check \ diff --git a/tests/frontend/fbsd.binin b/tests/frontend/fbsd.binin deleted file mode 100755 index d78231f870..0000000000 Binary files a/tests/frontend/fbsd.binin and /dev/null differ diff --git a/tests/frontend/freebsd-aarch64.binin b/tests/frontend/freebsd-aarch64.binin new file mode 100755 index 0000000000..eff6bd6aab Binary files /dev/null and b/tests/frontend/freebsd-aarch64.binin differ diff --git a/tests/frontend/freebsd-amd64.binin b/tests/frontend/freebsd-amd64.binin new file mode 100755 index 0000000000..be7292602c Binary files /dev/null and b/tests/frontend/freebsd-amd64.binin differ diff --git a/tests/frontend/freebsd-armv6.binin b/tests/frontend/freebsd-armv6.binin new file mode 100755 index 0000000000..84c7c2292e Binary files /dev/null and b/tests/frontend/freebsd-armv6.binin differ diff --git a/tests/frontend/freebsd-armv7.binin b/tests/frontend/freebsd-armv7.binin new file mode 100755 index 0000000000..36285adc55 Binary files /dev/null and b/tests/frontend/freebsd-armv7.binin differ diff --git a/tests/frontend/freebsd-i386.binin b/tests/frontend/freebsd-i386.binin new file mode 100755 index 0000000000..5ce965482a Binary files /dev/null and b/tests/frontend/freebsd-i386.binin differ diff --git a/tests/frontend/freebsd-powerpc.binin b/tests/frontend/freebsd-powerpc.binin new file mode 100755 index 0000000000..64e0c2b8a4 Binary files /dev/null and b/tests/frontend/freebsd-powerpc.binin differ diff --git a/tests/frontend/freebsd-powerpc64.binin b/tests/frontend/freebsd-powerpc64.binin new file mode 100755 index 0000000000..67f7651f5a Binary files /dev/null and b/tests/frontend/freebsd-powerpc64.binin differ diff --git a/tests/frontend/freebsd-powerpc64le.binin b/tests/frontend/freebsd-powerpc64le.binin new file mode 100755 index 0000000000..2772f857ac Binary files /dev/null and b/tests/frontend/freebsd-powerpc64le.binin differ diff --git a/tests/frontend/freebsd-riscv64.binin b/tests/frontend/freebsd-riscv64.binin new file mode 100755 index 0000000000..765c60017b Binary files /dev/null and b/tests/frontend/freebsd-riscv64.binin differ