diff --git a/usr.sbin/pkg/Makefile b/usr.sbin/pkg/Makefile index 6a6c1ddea8e7..6c44806ebdcd 100644 --- a/usr.sbin/pkg/Makefile +++ b/usr.sbin/pkg/Makefile @@ -8,7 +8,7 @@ CFLAGS+=-I${.CURDIR}/../../contrib/libucl/include .PATH: ${.CURDIR}/../../contrib/libucl/include DPADD= ${LIBARCHIVE} ${LIBELF} ${LIBFETCH} ${LIBUCL} ${LIBSBUF} ${LIBSSL} \ ${LIBCRYPTO} ${LIBM} -LDADD= -larchive -lelf -lfetch ${LDUCL} -lsbuf -lssl -lcrypto -lm +LDADD= -larchive -lfetch ${LDUCL} -lsbuf -lssl -lcrypto -lm USEPRIVATELIB= ucl .include diff --git a/usr.sbin/pkg/config.c b/usr.sbin/pkg/config.c index fded95e8cbed..3a1f18d2515d 100644 --- a/usr.sbin/pkg/config.c +++ b/usr.sbin/pkg/config.c @@ -31,9 +31,9 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include #include +#include +#include #include #include @@ -42,14 +42,12 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include #include #include -#include "elf_tables.h" #include "config.h" #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ @@ -135,349 +133,32 @@ static struct config_entry c[] = { }, }; -static const char * -elf_corres_to_string(struct _elf_corres *m, int e) -{ - int i; - - for (i = 0; m[i].string != NULL; i++) - if (m[i].elf_nb == e) - return (m[i].string); - - return ("unknown"); -} - -static const char * -aeabi_parse_arm_attributes(void *data, size_t length) -{ - uint32_t sect_len; - uint8_t *section = data; - -#define MOVE(len) do { \ - assert(length >= (len)); \ - section += (len); \ - length -= (len); \ -} while (0) - - if (length == 0 || *section != 'A') - return (NULL); - - MOVE(1); - - /* Read the section length */ - if (length < sizeof(sect_len)) - return (NULL); - - memcpy(§_len, section, sizeof(sect_len)); - - /* - * The section length should be no longer than the section it is within - */ - if (sect_len > length) - return (NULL); - - MOVE(sizeof(sect_len)); - - /* Skip the vendor name */ - while (length != 0) { - if (*section == '\0') - break; - MOVE(1); - } - if (length == 0) - return (NULL); - MOVE(1); - - while (length != 0) { - uint32_t tag_length; - - switch(*section) { - case 1: /* Tag_File */ - MOVE(1); - if (length < sizeof(tag_length)) - return (NULL); - memcpy(&tag_length, section, sizeof(tag_length)); - break; - case 2: /* Tag_Section */ - case 3: /* Tag_Symbol */ - default: - return (NULL); - } - /* At least space for the tag and size */ - if (tag_length <= 5) - return (NULL); - tag_length--; - /* Check the tag fits */ - if (tag_length > length) - return (NULL); - -#define MOVE_TAG(len) do { \ - assert(tag_length >= (len)); \ - MOVE(len); \ - tag_length -= (len); \ -} while(0) - - MOVE(sizeof(tag_length)); - tag_length -= sizeof(tag_length); - - while (tag_length != 0) { - uint8_t tag; - - assert(tag_length >= length); - - tag = *section; - MOVE_TAG(1); - - /* - * These tag values come from: - * - * Addenda to, and Errata in, the ABI for the - * ARM Architecture. Release 2.08, section 2.3. - */ - if (tag == 6) { /* == Tag_CPU_arch */ - uint8_t val; - - val = *section; - /* - * We don't support values that require - * more than one byte. - */ - if (val & (1 << 7)) - return (NULL); - - /* We have an ARMv4 or ARMv5 */ - if (val <= 5) - return ("arm"); - else /* We have an ARMv6+ */ - return ("armv6"); - } else if (tag == 4 || tag == 5 || tag == 32 || - tag == 65 || tag == 67) { - while (*section != '\0' && length != 0) - MOVE_TAG(1); - if (tag_length == 0) - return (NULL); - /* Skip the last byte */ - MOVE_TAG(1); - } else if ((tag >= 7 && tag <= 31) || tag == 34 || - tag == 36 || tag == 38 || tag == 42 || tag == 44 || - tag == 64 || tag == 66 || tag == 68 || tag == 70) { - /* Skip the uleb128 data */ - while (*section & (1 << 7) && length != 0) - MOVE_TAG(1); - if (tag_length == 0) - return (NULL); - /* Skip the last byte */ - MOVE_TAG(1); - } else - return (NULL); -#undef MOVE_TAG - } - - break; - } - return (NULL); -#undef MOVE -} - static int pkg_get_myabi(char *dest, size_t sz) { - Elf *elf; - Elf_Data *data; - Elf_Note note; - Elf_Scn *scn; - char *src, *osname; - const char *arch, *abi, *fpu, *endian_corres_str; - const char *wordsize_corres_str; - GElf_Ehdr elfhdr; - GElf_Shdr shdr; - int fd, i, ret; - uint32_t version; + struct utsname uts; + char machine_arch[255]; + size_t len; + int error; - version = 0; - ret = -1; - scn = NULL; - abi = NULL; + error = uname(&uts); + if (error) + return (errno); - if (elf_version(EV_CURRENT) == EV_NONE) { - warnx("ELF library initialization failed: %s", - elf_errmsg(-1)); - return (-1); - } + len = sizeof(machine_arch); + error = sysctlbyname("hw.machine_arch", machine_arch, &len, NULL, 0); + if (error) + return (errno); + machine_arch[len] = '\0'; - if ((fd = open(_PATH_BSHELL, O_RDONLY)) < 0) { - warn("open()"); - return (-1); - } + /* + * Use __FreeBSD_version rather than kernel version (uts.release) for + * use in jails. This is equivalent to the value of uname -U. + */ + snprintf(dest, sz, "%s:%d:%s", uts.sysname, __FreeBSD_version/100000, + machine_arch); - if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { - ret = -1; - warnx("elf_begin() failed: %s.", elf_errmsg(-1)); - goto cleanup; - } - - if (gelf_getehdr(elf, &elfhdr) == NULL) { - ret = -1; - warn("getehdr() failed: %s.", elf_errmsg(-1)); - goto cleanup; - } - while ((scn = elf_nextscn(elf, scn)) != NULL) { - if (gelf_getshdr(scn, &shdr) != &shdr) { - ret = -1; - warn("getshdr() failed: %s.", elf_errmsg(-1)); - goto cleanup; - } - - if (shdr.sh_type == SHT_NOTE) - break; - } - - if (scn == NULL) { - ret = -1; - warn("failed to get the note section"); - goto cleanup; - } - - data = elf_getdata(scn, NULL); - src = data->d_buf; - for (;;) { - memcpy(¬e, src, sizeof(Elf_Note)); - src += sizeof(Elf_Note); - if (note.n_type == NT_VERSION) - break; - src += note.n_namesz + note.n_descsz; - } - osname = src; - src += roundup2(note.n_namesz, 4); - if (elfhdr.e_ident[EI_DATA] == ELFDATA2MSB) - version = be32dec(src); - else - version = le32dec(src); - - for (i = 0; osname[i] != '\0'; i++) - osname[i] = (char)tolower(osname[i]); - - wordsize_corres_str = elf_corres_to_string(wordsize_corres, - (int)elfhdr.e_ident[EI_CLASS]); - - arch = elf_corres_to_string(mach_corres, (int) elfhdr.e_machine); - - snprintf(dest, sz, "%s:%d", - osname, version / 100000); - - ret = 0; - - switch (elfhdr.e_machine) { - case EM_ARM: - endian_corres_str = elf_corres_to_string(endian_corres, - (int)elfhdr.e_ident[EI_DATA]); - - /* FreeBSD doesn't support the hard-float ABI yet */ - fpu = "softfp"; - if ((elfhdr.e_flags & 0xFF000000) != 0) { - const char *sh_name = NULL; - size_t shstrndx; - - /* This is an EABI file, the conformance level is set */ - abi = "eabi"; - /* Find which TARGET_ARCH we are building for. */ - elf_getshdrstrndx(elf, &shstrndx); - while ((scn = elf_nextscn(elf, scn)) != NULL) { - sh_name = NULL; - if (gelf_getshdr(scn, &shdr) != &shdr) { - scn = NULL; - break; - } - - sh_name = elf_strptr(elf, shstrndx, - shdr.sh_name); - if (sh_name == NULL) - continue; - if (strcmp(".ARM.attributes", sh_name) == 0) - break; - } - if (scn != NULL && sh_name != NULL) { - data = elf_getdata(scn, NULL); - /* - * Prior to FreeBSD 10.0 libelf would return - * NULL from elf_getdata on the .ARM.attributes - * section. As this was the first release to - * get armv6 support assume a NULL value means - * arm. - * - * This assumption can be removed when 9.x - * is unsupported. - */ - if (data != NULL) { - arch = aeabi_parse_arm_attributes( - data->d_buf, data->d_size); - if (arch == NULL) { - ret = 1; - warn("unknown ARM ARCH"); - goto cleanup; - } - } - } else { - ret = 1; - warn("Unable to find the .ARM.attributes " - "section"); - goto cleanup; - } - } else if (elfhdr.e_ident[EI_OSABI] != ELFOSABI_NONE) { - /* - * EABI executables all have this field set to - * ELFOSABI_NONE, therefore it must be an oabi file. - */ - abi = "oabi"; - } else { - ret = 1; - warn("unknown ARM ABI"); - goto cleanup; - } - snprintf(dest + strlen(dest), sz - strlen(dest), - ":%s:%s:%s:%s:%s", arch, wordsize_corres_str, - endian_corres_str, abi, fpu); - break; - case EM_MIPS: - /* - * this is taken from binutils sources: - * include/elf/mips.h - * mapping is figured out from binutils: - * gas/config/tc-mips.c - */ - switch (elfhdr.e_flags & EF_MIPS_ABI) { - case E_MIPS_ABI_O32: - abi = "o32"; - break; - case E_MIPS_ABI_N32: - abi = "n32"; - break; - default: - if (elfhdr.e_ident[EI_DATA] == - ELFCLASS32) - abi = "o32"; - else if (elfhdr.e_ident[EI_DATA] == - ELFCLASS64) - abi = "n64"; - break; - } - endian_corres_str = elf_corres_to_string(endian_corres, - (int)elfhdr.e_ident[EI_DATA]); - - snprintf(dest + strlen(dest), sz - strlen(dest), ":%s:%s:%s:%s", - arch, wordsize_corres_str, endian_corres_str, abi); - break; - default: - snprintf(dest + strlen(dest), sz - strlen(dest), ":%s:%s", - arch, wordsize_corres_str); - } - -cleanup: - if (elf != NULL) - elf_end(elf); - - close(fd); - return (ret); + return (error); } static void diff --git a/usr.sbin/pkg/elf_tables.h b/usr.sbin/pkg/elf_tables.h deleted file mode 100644 index 55fd3bbd2e95..000000000000 --- a/usr.sbin/pkg/elf_tables.h +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * Copyright (c) 2012 Olivier Houchard - * Copyright (c) 2012 Baptiste Daroussin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef ELF_TABLES_H_ -#define ELF_TABLES_H_ -struct _elf_corres { - int elf_nb; - const char *string; -}; - -static struct _elf_corres mach_corres[] = { - { EM_386, "x86" }, - { EM_AMD64, "x86" }, - { EM_ARM, "arm" }, - { EM_MIPS, "mips" }, - { EM_PPC, "powerpc" }, - { EM_PPC64, "powerpc" }, - { EM_SPARCV9, "sparc64" }, - { -1, NULL }, -}; - -static struct _elf_corres wordsize_corres[] = { - { ELFCLASS32, "32" }, - { ELFCLASS64, "64" }, - { -1, NULL}, -}; - -static struct _elf_corres endian_corres[] = { - { ELFDATA2MSB, "eb" }, - { ELFDATA2LSB, "el" }, - { -1, NULL} -}; - -#ifndef EF_MIPS_ABI -#define EF_MIPS_ABI 0x0000f000 -#endif -#define E_MIPS_ABI_O32 0x00001000 -#define E_MIPS_ABI_N32 0x00000020 - -#define NT_VERSION 1 -#define NT_ARCH 2 - -#endif /* ELF_TABLES_H_ */