Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
libpkg: fix regressions in ELF arch parsing
Isaac Freund committed 1 year ago
commit 76df8dc73a4d418ba6228149facf6f2400b295fd
parent d5eb29f
14 files changed +171 -41
modified 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)
modified 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
modified 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 \
modified 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 \
deleted tests/frontend/fbsd.binin
added tests/frontend/freebsd-aarch64.binin
added tests/frontend/freebsd-amd64.binin
added tests/frontend/freebsd-armv6.binin
added tests/frontend/freebsd-armv7.binin
added tests/frontend/freebsd-i386.binin
added tests/frontend/freebsd-powerpc.binin
added tests/frontend/freebsd-powerpc64.binin
added tests/frontend/freebsd-powerpc64le.binin
added tests/frontend/freebsd-riscv64.binin