diff options
author | Robert Mustacchi <rm@fingolfin.org> | 2022-07-16 15:26:14 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@fingolfin.org> | 2022-09-11 04:06:00 +0000 |
commit | 56726c7e321b6e5ecb2f10215f5386016547e68c (patch) | |
tree | c2962155102bc009959ab350494becc3204feef7 /usr/src/cmd | |
parent | f2ae17ede4a9a93585872a9aa83120497285bdd0 (diff) | |
download | illumos-gate-56726c7e321b6e5ecb2f10215f5386016547e68c.tar.gz |
14821 Add additional AVX512 capabilities
14822 Need new word of hardware capabilities
14823 aux vector feature mapping should use x86_featureset
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Patrick Mooney <pmooney@pfmooney.com>
Approved by: Dan McDonald <danmcd@mnx.io>
Diffstat (limited to 'usr/src/cmd')
39 files changed, 750 insertions, 70 deletions
diff --git a/usr/src/cmd/isainfo/isainfo.c b/usr/src/cmd/isainfo/isainfo.c index dcc07197cd..393b854bdf 100644 --- a/usr/src/cmd/isainfo/isainfo.c +++ b/usr/src/cmd/isainfo/isainfo.c @@ -25,6 +25,7 @@ /* * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright 2022 Oxide Computer Company */ #include <sys/types.h> @@ -147,31 +148,53 @@ static void report_hwcap(int d, const char *isa) { struct cpuid_get_hwcap __cgh, *cgh = &__cgh; - char buffer[1024], cap2[1024]; + char cap1[ELFCAP_HW1_BUFSIZE]; + char cap2[ELFCAP_HW2_BUFSIZE]; + char cap3[ELFCAP_HW3_BUFSIZE]; cgh->cgh_archname = (char *)isa; if (ioctl(d, CPUID_GET_HWCAP, cgh) != 0) return; (void) elfcap_hw1_to_str(ELFCAP_STYLE_LC, cgh->cgh_hwcap[0], - buffer, sizeof (buffer), ELFCAP_FMT_SNGSPACE, machtype(isa)); + cap1, sizeof (cap1), ELFCAP_FMT_SNGSPACE, machtype(isa)); - if (cgh->cgh_hwcap[1] != 0) + if (cgh->cgh_hwcap[1] != 0) { (void) elfcap_hw2_to_str(ELFCAP_STYLE_LC, cgh->cgh_hwcap[1], cap2, sizeof (cap2), ELFCAP_FMT_SNGSPACE, machtype(isa)); - else + } else { cap2[0] = '\0'; + } + + if (cgh->cgh_hwcap[2] != 0) { + (void) elfcap_hw3_to_str(ELFCAP_STYLE_LC, cgh->cgh_hwcap[2], + cap3, sizeof (cap3), ELFCAP_FMT_SNGSPACE, machtype(isa)); + } else { + cap3[0] = '\0'; + } if (mode & EXTN_MODE) { (void) printf(":"); + if (cgh->cgh_hwcap[2] != 0) + (void) printf(" %s", cap3); if (cgh->cgh_hwcap[1] != 0) (void) printf(" %s", cap2); - (void) printf(" %s", buffer); + (void) printf(" %s", cap1); (void) printf("\n"); } else { char *p; int linecnt = 0; + for (p = strtok(cap3, " "); p; p = strtok(NULL, " ")) { + if (linecnt + strlen(p) > 68) { + (void) printf("\n"); + linecnt = 0; + } + if (linecnt == 0) + linecnt = printf("\t"); + linecnt += printf("%s ", p); + } + for (p = strtok(cap2, " "); p; p = strtok(NULL, " ")) { if (linecnt + strlen(p) > 68) { (void) printf("\n"); @@ -182,7 +205,7 @@ report_hwcap(int d, const char *isa) linecnt += printf("%s ", p); } - for (p = strtok(buffer, " "); p; p = strtok(NULL, " ")) { + for (p = strtok(cap1, " "); p; p = strtok(NULL, " ")) { if (linecnt + strlen(p) > 68) { (void) printf("\n"); linecnt = 0; diff --git a/usr/src/cmd/ptools/pargs/pargs.c b/usr/src/cmd/ptools/pargs/pargs.c index 9f284e0731..a4a2654e30 100644 --- a/usr/src/cmd/ptools/pargs/pargs.c +++ b/usr/src/cmd/ptools/pargs/pargs.c @@ -24,6 +24,7 @@ */ /* * Copyright (c) 2018, Joyent, Inc. + * Copyright 2022 Oxide Computer Company */ /* @@ -754,6 +755,17 @@ at_hwcap2(long val, char *instr, size_t n, char *str) #endif } +/*ARGSUSED*/ +static void +at_hwcap3(long val, char *instr, size_t n, char *str) +{ +#if defined(__i386) || defined(__amd64) + (void) elfcap_hw3_to_str(ELFCAP_STYLE_UC, val, str, n, + ELFCAP_FMT_PIPSPACE, EM_386); +#else +#error "port me" +#endif +} /*ARGSUSED*/ static void @@ -835,6 +847,7 @@ static struct aux_id aux_arr[] = { { AT_SUN_EXECNAME, "AT_SUN_EXECNAME", at_str }, { AT_SUN_HWCAP, "AT_SUN_HWCAP", at_hwcap }, { AT_SUN_HWCAP2, "AT_SUN_HWCAP2", at_hwcap2 }, + { AT_SUN_HWCAP3, "AT_SUN_HWCAP3", at_hwcap3 }, { AT_SUN_IFLUSH, "AT_SUN_IFLUSH", at_null }, { AT_SUN_CPU, "AT_SUN_CPU", at_null }, { AT_SUN_MMU, "AT_SUN_MMU", at_null }, diff --git a/usr/src/cmd/sgs/Makefile b/usr/src/cmd/sgs/Makefile index 203246897e..3d645521a7 100644 --- a/usr/src/cmd/sgs/Makefile +++ b/usr/src/cmd/sgs/Makefile @@ -60,6 +60,7 @@ SUBDIRS= libconv \ crle \ ar \ dump \ + elfcap.chk \ elfdump \ elfedit \ elfwrap \ @@ -94,6 +95,8 @@ MSGSUBDIRS= ld ldd libld liblddbg \ elfedit crle moe lari \ librtld_db elfwrap ar +CHKSUBDIRS= elfcap.chk + MSGDIR= messages all := TARGET= all @@ -104,6 +107,7 @@ _msg := TARGET= catalog _msg_gettext := TARGET= catalog _msg_sgsmsg := TARGET= catalog chkmsg := TARGET= chkmsg +check := TARGET= check .KEEP_STATE: @@ -134,7 +138,7 @@ $(MSGDIR): $(MSGSUBDIRS) FRC chkmsg: libconv $(MSGSUBDIRS) FRC -check: chkmsg +check: chkmsg $(CHKSUBDIRS) # built from lib/Makefile install_lib: FRC diff --git a/usr/src/cmd/sgs/elfcap.chk/Makefile b/usr/src/cmd/sgs/elfcap.chk/Makefile new file mode 100644 index 0000000000..9e446ff0e3 --- /dev/null +++ b/usr/src/cmd/sgs/elfcap.chk/Makefile @@ -0,0 +1,53 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2022 Oxide Computer Company +# + +PROG = elfcap.chk +OBJS = elfcap_chk.o elfcap.o + +include $(SRC)/Makefile.master +include $(SRC)/Makefile.master.64 +include ../Makefile.com + +CSTD = $(GNU_C99) +NATIVE_LIBS += libc.so +CPPFLAGS = $(CPPFLAGS.native) +CFLAGS = $(NATIVE_CFLAGS) +CC = $(NATIVECC) +LDCHECKS = + +CPPFLAGS += -I$(ELFCAP) + +all: $(PROG) + +install: + +check: $(PROG) + ./$(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) + $(POST_PROCESS) + +%.o: %.c + $(COMPILE.c) $< + +%.o: $(ELFCAP)/%.c + $(COMPILE.c) $< + +clean: + $(RM) $(OBJS) + +clobber: clean + $(RM) $(PROG) diff --git a/usr/src/cmd/sgs/elfcap.chk/elfcap_chk.c b/usr/src/cmd/sgs/elfcap.chk/elfcap_chk.c new file mode 100644 index 0000000000..5598e59972 --- /dev/null +++ b/usr/src/cmd/sgs/elfcap.chk/elfcap_chk.c @@ -0,0 +1,160 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2022 Oxide Computer Company + */ + +/* + * This tool is used to try and figure out what the value of various static + * buffers should be and if the current compile time defaults are correct. In + * particular, this covers the various elfcap values and is used to drive how we + * calculate the overall size definition. + * + * To calculate this, we assume the following: + * + * o We are using the ELFCAP_FMT_PIPSPACE as that is the longest. We don't + * have access to the actual strings right now. + * o We are using the ELFCAP_STYLE_FULL variant of the name as that's the + * longest. + * o We are going to have leftover bits that we don't know (unless we have + * 32-bits defined). This uses the 0x%x format and therefore is 10 + * characters. + * o We check all architectures set of values and take the largest. + * + * While elfcap related information is in multiple places in the build, sgs and + * libconv are the places that seem most intertwined. In particular, we believe + * it's important that this program execute as part of make check and also get + * rebuilt normally as part of a build. This also allows one to iterate in + * cmd/sgs which is the most common place that you're working in when adding new + * hardware capabilities. By making it a part of the cmd/sgs suite, that also + * ensures that normal build logic always rebuilds this program with changes to + * elfcap.[ch]. + */ + +#include <stdio.h> +#include <elfcap.h> +#include <sys/sysmacros.h> +#include <stdlib.h> + +/* + * The length of 0x%x. + */ +#define ECS_UNKNOWN 10 + +typedef const elfcap_desc_t *(*elfcap_getdesc_f)(void); + +typedef struct elfcap_getdesc { + uint32_t eg_nents; + elfcap_getdesc_f eg_func; +} elfcap_getdesc_t; + +typedef struct elfcap_case { + const char *ec_tag; + size_t ec_header; + elfcap_getdesc_t ec_descs[2]; +} elfcap_case_t; + +const elfcap_case_t elfcaps[] = { + { "ELFCAP_SF1_BUFSIZE", ELFCAP_SF1_BUFSIZE, { + { ELFCAP_NUM_SF1, elfcap_getdesc_sf1 }, + { 0, NULL } + } }, + { "ELFCAP_HW1_BUFSIZE", ELFCAP_HW1_BUFSIZE, { + { ELFCAP_NUM_HW1_386, elfcap_getdesc_hw1_386 }, + { ELFCAP_NUM_HW1_SPARC, elfcap_getdesc_hw1_sparc } + } }, + { "ELFCAP_HW1_BUFSIZE", ELFCAP_HW2_BUFSIZE, { + { ELFCAP_NUM_HW2_386, elfcap_getdesc_hw2_386 }, + { 0, NULL } + } }, + { "ELFCAP_HW1_BUFSIZE", ELFCAP_HW3_BUFSIZE, { + { ELFCAP_NUM_HW3_386, elfcap_getdesc_hw3_386 }, + { 0, NULL } + } }, +}; + +static size_t +elfcap_calc_len(const elfcap_desc_t *desc, uint32_t nents, size_t space) +{ + size_t len = 0; + + for (uint32_t i = 0; i < nents; i++) { + len += desc[i].c_full.s_len; + if (i > 0) { + len += space; + } + } + + if (nents < 32) { + len += space + ECS_UNKNOWN; + } + + /* + * Finally, add one for a terminator and we add an 8 character buffer in + * case we screwed up. + */ + len += 9; + + return (len); +} + +static size_t +elfcap_max_len(const elfcap_case_t *ec, size_t slen) +{ + size_t max = 0; + + for (size_t i = 0; i < ARRAY_SIZE(ec->ec_descs); i++) { + const elfcap_desc_t *desc; + size_t len; + + if (ec->ec_descs[i].eg_func == NULL) + continue; + + desc = ec->ec_descs[i].eg_func(); + len = elfcap_calc_len(desc, ec->ec_descs[i].eg_nents, slen); + if (len > max) + max = len; + } + + return (max); +} + +int +main(void) +{ + size_t slen; + const elfcap_str_t *strs; + int ret = EXIT_SUCCESS; + + strs = elfcap_getdesc_formats(); + slen = strs[ELFCAP_FMT_PIPSPACE].s_len; + + for (size_t i = 0; i < ARRAY_SIZE(elfcaps); i++) { + size_t out = elfcap_max_len(&elfcaps[i], slen); + + if (out != elfcaps[i].ec_header) { + (void) fprintf(stderr, "elfcap size for %s is not " + "expected value!\n\tCurrent value is %zu, should " + "be %zu\n", elfcaps[i].ec_tag, elfcaps[i].ec_header, + out); + ret = EXIT_FAILURE; + } + } + + if (ret != EXIT_SUCCESS) { + (void) fprintf(stderr, "please update $SRC/common/elfcap/" + "elfcap.h and $SRC/cmd/sgs/include/conv.h with the new " + "values reported above\n"); + } + + return (ret); +} diff --git a/usr/src/cmd/sgs/elfdump/common/corenote.c b/usr/src/cmd/sgs/elfdump/common/corenote.c index d848221648..b06b3bf2cf 100644 --- a/usr/src/cmd/sgs/elfdump/common/corenote.c +++ b/usr/src/cmd/sgs/elfdump/common/corenote.c @@ -26,7 +26,7 @@ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. - * Copyright 2020 Oxide Computer Company + * Copyright 2022 Oxide Computer Company */ #include <stdlib.h> @@ -46,7 +46,7 @@ /* * This module contains the code that displays data from the note - * sections found in Solaris core files. The format of these + * sections found in illumos core files. The format of these * note sections are described in the core(5) manpage. */ @@ -470,6 +470,7 @@ dump_auxv(note_state_t *state, const char *title) union { Conv_cap_val_hw1_buf_t hw1; Conv_cap_val_hw2_buf_t hw2; + Conv_cap_val_hw3_buf_t hw3; Conv_cnote_auxv_af_buf_t auxv_af; Conv_ehdr_flags_buf_t ehdr_flags; Conv_secflags_buf_t secflags; @@ -586,8 +587,27 @@ dump_auxv(note_state_t *state, const char *title) vstr = NULL; num_fmt = SL_FMT_NUM_HEX; break; - - + case AT_SUN_HWCAP3: + w = extract_as_word(state, &layout->a_val); + vstr = conv_cap_val_hw3(w, state->ns_mach, + 0, &conv_buf.hw3); + /* + * conv_cap_val_hw3() produces output like: + * + * 0xfff [ flg1 flg2 0xff] + * + * where the first hex value is the complete value, + * and the second is the leftover bits. We only + * want the part in brackets, and failing that, + * would rather fall back to formatting the full + * value ourselves. + */ + while ((*vstr != '\0') && (*vstr != '[')) + vstr++; + if (*vstr != '[') + vstr = NULL; + num_fmt = SL_FMT_NUM_HEX; + break; case AT_SUN_AUXFLAGS: w = extract_as_word(state, &layout->a_val); diff --git a/usr/src/cmd/sgs/elfedit/common/elfconst.c b/usr/src/cmd/sgs/elfedit/common/elfconst.c index 0ee1e7158d..b550222a9a 100644 --- a/usr/src/cmd/sgs/elfedit/common/elfconst.c +++ b/usr/src/cmd/sgs/elfedit/common/elfconst.c @@ -22,6 +22,8 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2022 Oxide Computer Company */ #include <stdlib.h> @@ -411,6 +413,7 @@ init_libconv_strings(conv_iter_osabi_t *osabi, Half *mach) LC_MACH(ELFEDIT_CONST_HW1_SUNW, conv_iter_cap_val_hw1); LC(ELFEDIT_CONST_SF1_SUNW, conv_iter_cap_val_sf1); LC_MACH(ELFEDIT_CONST_HW2_SUNW, conv_iter_cap_val_hw2); + LC_MACH(ELFEDIT_CONST_HW3_SUNW, conv_iter_cap_val_hw3); #undef LC #undef LC_OS diff --git a/usr/src/cmd/sgs/elfedit/modules/common/cap.c b/usr/src/cmd/sgs/elfedit/modules/common/cap.c index 7430d4d84f..0cde92f90a 100644 --- a/usr/src/cmd/sgs/elfedit/modules/common/cap.c +++ b/usr/src/cmd/sgs/elfedit/modules/common/cap.c @@ -23,6 +23,7 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright 2012 Milan Jurik. All rights reserved. + * Copyright 2022 Oxide Computer Company */ #include <ctype.h> @@ -60,6 +61,7 @@ typedef enum { CAP_CMD_T_HW1 = 5, /* cap:hw1 */ CAP_CMD_T_SF1 = 6, /* cap:sf1 */ CAP_CMD_T_HW2 = 7, /* cap:hw2 */ + CAP_CMD_T_HW3 = 8, /* cap:hw3 */ } CAP_CMD_T; @@ -532,6 +534,14 @@ print_cap(CAP_CMD_T cmd, int autoprint, ARGSTATE *argstate, ELFEDIT_MSG_ERR, 0)); printed = 1; continue; + case CA_SUNW_HW_3: + elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), + conv_cap_val_hw3(cap->c_un.c_val, + argstate->obj_state->os_ehdr-> + e_machine, CONV_FMT_NOBKT, + &cap_val_buf.cap_val_hw3_buf)); + printed = 1; + continue; } } elfedit_printf(MSG_ORIG(MSG_FMT_HEXXWORDNL), @@ -843,6 +853,13 @@ cmd_body(CAP_CMD_T cmd, elfedit_obj_state_t *obj_state, MSG_ORIG(MSG_STR_VALUE), print_only, &print_type); break; + case CAP_CMD_T_HW3: + print_only = (argstate.argc == 0); + ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str( + ELFEDIT_CONST_CA, CA_SUNW_HW_3, 1), + MSG_ORIG(MSG_STR_VALUE), print_only, &print_type); + break; + default: /* Note expected: All commands should have been caught above */ elfedit_command_usage(); @@ -1024,6 +1041,14 @@ cmd_body(CAP_CMD_T cmd, elfedit_obj_state_t *obj_state, CA_SUNW_HW_2, ELFEDIT_CONST_HW2_SUNW); } break; + + case CAP_CMD_T_HW3: + { + ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name, + CA_SUNW_HW_3, ELFEDIT_CONST_HW3_SUNW); + } + break; + } /* @@ -1180,6 +1205,19 @@ cpl_hw2(elfedit_obj_state_t *obj_state, void *cpldata, int argc, elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_HW2_SUNW); } +static void +cpl_hw3(elfedit_obj_state_t *obj_state, void *cpldata, int argc, + const char *argv[], int num_opt) +{ + /* -capid id_name */ + if (argc <= num_opt) { + cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt); + return; + } + + /* This routine allows multiple flags to be specified */ + elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_HW3_SUNW); +} /* * Implementation functions for the commands */ @@ -1231,6 +1269,12 @@ cmd_hw2(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) return (cmd_body(CAP_CMD_T_HW2, obj_state, argc, argv)); } +static elfedit_cmdret_t +cmd_hw3(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) +{ + return (cmd_body(CAP_CMD_T_HW3, obj_state, argc, argv)); +} + /*ARGSUSED*/ elfedit_module_t * elfedit_init(elfedit_module_version_t version) @@ -1406,6 +1450,15 @@ elfedit_init(elfedit_module_version_t version) { NULL } }; + /* cap:hw3 */ + static const char *name_hw3[] = { MSG_ORIG(MSG_CMD_HW3), NULL }; + static elfedit_cmd_optarg_t arg_hw3[] = { + { MSG_ORIG(MSG_STR_VALUE), + /* MSG_INTL(MSG_A1_HW3_VALUE) */ + ELFEDIT_I18NHDL(MSG_A1_HW3_VALUE), + ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT }, + { NULL } + }; static elfedit_cmd_t cmds[] = { /* cap:dump */ @@ -1472,6 +1525,14 @@ elfedit_init(elfedit_module_version_t version) ELFEDIT_I18NHDL(MSG_HELP_HW2), opt_ostyle_capid_bitop, arg_hw2 }, + /* cap:hw3 */ + { cmd_hw3, cpl_hw3, name_hw3, + /* MSG_INTL(MSG_DESC_HW3) */ + ELFEDIT_I18NHDL(MSG_DESC_HW3), + /* MSG_INTL(MSG_HELP_HW3) */ + ELFEDIT_I18NHDL(MSG_HELP_HW3), + opt_ostyle_capid_bitop, arg_hw3 }, + { NULL } }; diff --git a/usr/src/cmd/sgs/elfedit/modules/common/cap.msg b/usr/src/cmd/sgs/elfedit/modules/common/cap.msg index cd311144a0..da6e062df1 100644 --- a/usr/src/cmd/sgs/elfedit/modules/common/cap.msg +++ b/usr/src/cmd/sgs/elfedit/modules/common/cap.msg @@ -23,6 +23,8 @@ # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2022 Oxide Computer Company +# @ _START_ @@ -76,6 +78,7 @@ @ MSG_DESC_HW1 "Hardware capabilities (CA_SUNW_HW_1) bit values" @ MSG_DESC_SF1 "Software capabilities (CA_SUNW_SF_1) bit values" @ MSG_DESC_HW2 "Hardware capabilities (CA_SUNW_HW_2) bit values" +@ MSG_DESC_HW3 "Hardware capabilities (CA_SUNW_HW_3) bit values" # Command option description strings @@ -160,9 +163,14 @@ /usr/include/sys/elf.h.\n" @ MSG_A1_HW2_VALUE "\ - Hardware capability (CA_SUNW_HW_2) values. This is available for\n\ - future expansion.\n" + Hardware capability (CA_SUNW_HW_2) values. This can be an integer\n\ + value, any of the AV_386_2_ symbolic constants defined in\n\ + /usr/include/sys/auxv_386.h.\n" +@ MSG_A1_HW3_VALUE "\ + Hardware capability (CA_SUNW_HW_3) values. This can be an integer\n\ + value, any of the AV_386_3_ symbolic constants defined in\n\ + /usr/include/sys/auxv_386.h.\n" # Help strings @@ -266,6 +274,26 @@ \tspecified, the new value is OR'd against the existing\n\ \tvalue. If neither -and or -or are specified, the new value\n\ \treplaces the existing value.\n" + +@ MSG_HELP_HW3 " \ + The cap:hw3 command is used to display or alter the\n\ + value of the hardware capabilities element (CA_SUNW_HW_3).\n\ + \n\ + If cap:hw3 is called without arguments, the current\n\ + value is shown. If one or more value arguments are present,\n\ + the following steps are taken:\n\ + \n \ + o\tAll the value arguments are OR'd together.\n\ + \n \ + o\tIf the -cmp option has been specified, the new value\n\ + \tis complemented.\n\ + \n \ + o\tThe CA_SUNW_HW_3 element of the capabilities section is\n\ + \tupdated with the new value. If -and is specified, the new\n\ + \tvalue is AND'd against the existing value. If -or is\n\ + \tspecified, the new value is OR'd against the existing\n\ + \tvalue. If neither -and or -or are specified, the new value\n\ + \treplaces the existing value.\n" @ _END_ @@ -306,3 +334,4 @@ @ MSG_CMD_HW1 "hw1" @ MSG_CMD_SF1 "sf1" @ MSG_CMD_HW2 "hw2" +@ MSG_CMD_HW3 "hw3" diff --git a/usr/src/cmd/sgs/include/conv.h b/usr/src/cmd/sgs/include/conv.h index f47b58e907..cfd690098c 100644 --- a/usr/src/cmd/sgs/include/conv.h +++ b/usr/src/cmd/sgs/include/conv.h @@ -27,7 +27,7 @@ * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. * Copyright 2016 RackTop Systems. - * Copyright 2021 Oxide Computer Company + * Copyright 2022 Oxide Computer Company */ #ifndef _CONV_H @@ -166,30 +166,37 @@ typedef union { * These sizes are based on the maximum number of capabilities that exist. * See common/elfcap. */ -#define CONV_CAP_VAL_HW1_BUFSIZE 195 +#define CONV_CAP_VAL_HW1_BUFSIZE 528 typedef union { Conv_inv_buf_t inv_buf; char buf[CONV_CAP_VAL_HW1_BUFSIZE]; } Conv_cap_val_hw1_buf_t; -#define CONV_CAP_VAL_HW2_BUFSIZE 350 +#define CONV_CAP_VAL_HW2_BUFSIZE 632 typedef union { Conv_inv_buf_t inv_buf; char buf[CONV_CAP_VAL_HW2_BUFSIZE]; } Conv_cap_val_hw2_buf_t; -#define CONV_CAP_VAL_SF1_BUFSIZE 45 +#define CONV_CAP_VAL_SF1_BUFSIZE 73 typedef union { Conv_inv_buf_t inv_buf; char buf[CONV_CAP_VAL_SF1_BUFSIZE]; } Conv_cap_val_sf1_buf_t; +#define CONV_CAP_VAL_HW3_BUFSIZE 66 +typedef union { + Conv_inv_buf_t inv_buf; + char buf[CONV_CAP_VAL_HW3_BUFSIZE]; +} Conv_cap_val_hw3_buf_t; + /* conv_cap_val_buf() */ typedef union { Conv_inv_buf_t inv_buf; Conv_cap_val_hw1_buf_t cap_val_hw1_buf; Conv_cap_val_sf1_buf_t cap_val_sf1_buf; Conv_cap_val_hw2_buf_t cap_val_hw2_buf; + Conv_cap_val_hw3_buf_t cap_val_hw3_buf; } Conv_cap_val_buf_t; /* conv_config_feat() */ @@ -962,6 +969,8 @@ extern conv_iter_ret_t conv_iter_cap_val_hw2(Half, Conv_fmt_flags_t, conv_iter_cb_t, void *); extern conv_iter_ret_t conv_iter_cap_val_sf1(Conv_fmt_flags_t, conv_iter_cb_t, void *); +extern conv_iter_ret_t conv_iter_cap_val_hw3(Half, Conv_fmt_flags_t, + conv_iter_cb_t, void *); extern conv_iter_ret_t conv_iter_dyn_feature1(Conv_fmt_flags_t, conv_iter_cb_t, void *); @@ -1027,6 +1036,7 @@ extern conv_iter_ret_t conv_iter_syminfo_flags(Conv_fmt_flags_t, #define conv_cap_val conv64_cap_val #define conv_cap_val_hw1 conv64_cap_val_hw1 #define conv_cap_val_hw2 conv64_cap_val_hw2 +#define conv_cap_val_hw3 conv64_cap_val_hw3 #define conv_cap_val_sf1 conv64_cap_val_sf1 #define conv_dyn_feature1 conv64_dyn_feature1 #define conv_dyn_flag1 conv64_dyn_flag1 @@ -1045,6 +1055,7 @@ extern conv_iter_ret_t conv_iter_syminfo_flags(Conv_fmt_flags_t, #define conv_cap_val conv32_cap_val #define conv_cap_val_hw1 conv32_cap_val_hw1 #define conv_cap_val_hw2 conv32_cap_val_hw2 +#define conv_cap_val_hw3 conv32_cap_val_hw3 #define conv_cap_val_sf1 conv32_cap_val_sf1 #define conv_dyn_feature1 conv32_dyn_feature1 #define conv_dyn_flag1 conv32_dyn_flag1 @@ -1082,6 +1093,8 @@ extern const char *conv_cap_val_hw1(Xword, Half, Conv_fmt_flags_t, Conv_cap_val_hw1_buf_t *); extern const char *conv_cap_val_hw2(Xword, Half, Conv_fmt_flags_t, Conv_cap_val_hw2_buf_t *); +extern const char *conv_cap_val_hw3(Xword, Half, Conv_fmt_flags_t, + Conv_cap_val_hw3_buf_t *); extern const char *conv_cap_val_sf1(Xword, Half, Conv_fmt_flags_t, Conv_cap_val_sf1_buf_t *); extern const char *conv_dyn_flag1(Xword, Conv_fmt_flags_t, diff --git a/usr/src/cmd/sgs/include/debug.h b/usr/src/cmd/sgs/include/debug.h index 4df1885e33..d1e49a94ed 100644 --- a/usr/src/cmd/sgs/include/debug.h +++ b/usr/src/cmd/sgs/include/debug.h @@ -21,6 +21,7 @@ /* * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ #ifndef _DEBUG_H @@ -152,6 +153,7 @@ extern "C" { #define DBG_CAP_HW_2 6 #define DBG_CAP_PLAT 7 #define DBG_CAP_MACH 8 +#define DBG_CAP_HW_3 9 #define DBG_REL_START 1 #define DBG_REL_FINISH 2 diff --git a/usr/src/cmd/sgs/include/elfedit.h b/usr/src/cmd/sgs/include/elfedit.h index 6c5a204f1a..16f3657905 100644 --- a/usr/src/cmd/sgs/include/elfedit.h +++ b/usr/src/cmd/sgs/include/elfedit.h @@ -22,6 +22,8 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2022 Oxide Computer Company */ #ifndef _ELFEDIT_H @@ -455,7 +457,7 @@ typedef struct { elfedit_i18nhdl_t oa_help; /* Help text for option */ elfedit_cmd_oa_flag_t oa_flags; /* Additional attributes */ elfedit_cmd_oa_mask_t oa_idmask; /* Unique id, returned by */ - /* elfedit_getopt */ + /* elfedit_getopt */ /* for use by caller */ elfedit_cmd_oa_mask_t oa_excmask; /* Mutual exclusion mask */ } elfedit_cmd_optarg_t; @@ -739,8 +741,9 @@ typedef enum { ELFEDIT_CONST_HW1_SUNW = 33, /* hardware capabilities */ ELFEDIT_CONST_SF1_SUNW = 34, /* software capabilities */ ELFEDIT_CONST_HW2_SUNW = 35, /* hardware capabilities */ + ELFEDIT_CONST_HW3_SUNW = 36, /* hardware capabilities */ - ELFEDIT_CONST_NUM = 36, /* # of constant types */ + ELFEDIT_CONST_NUM = 37, /* # of constant types */ } elfedit_const_t; /* diff --git a/usr/src/cmd/sgs/include/libld.h b/usr/src/cmd/sgs/include/libld.h index bf451f8f2a..67c877c082 100644 --- a/usr/src/cmd/sgs/include/libld.h +++ b/usr/src/cmd/sgs/include/libld.h @@ -24,6 +24,7 @@ * All Rights Reserved * * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ #ifndef _LIBLD_H @@ -210,6 +211,7 @@ typedef struct { Caplist oc_plat; /* CA_SUNW_PLAT capabilities */ Caplist oc_mach; /* CA_SUNW_MACH capabilities */ Capstr oc_id; /* CA_SUNW_ID capability */ + Capmask oc_hw_3; /* CA_SUNW_HW_3 capabilities */ oc_flag_t oc_flags; } Objcapset; @@ -524,6 +526,7 @@ struct ofl_desc { #define FLG_OF1_OVMACHCAP 0x0800000000 /* override CA_SUNW_MACH capability */ #define FLG_OF1_OVPLATCAP 0x1000000000 /* override CA_SUNW_PLAT capability */ #define FLG_OF1_OVIDCAP 0x2000000000 /* override CA_SUNW_ID capability */ +#define FLG_OF1_OVHWCAP3 0x4000000000 /* override CA_SUNW_HW_3 capabilities */ /* * Guidance flags. The flags with the FLG_OFG_NO_ prefix are used to suppress diff --git a/usr/src/cmd/sgs/include/rtld.h b/usr/src/cmd/sgs/include/rtld.h index 052cb109ee..4fe123c47d 100644 --- a/usr/src/cmd/sgs/include/rtld.h +++ b/usr/src/cmd/sgs/include/rtld.h @@ -22,6 +22,7 @@ /* * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, Joyent, Inc. + * Copyright 2022 Oxide Computer Company */ #ifndef _RTLD_H #define _RTLD_H @@ -1119,6 +1120,7 @@ typedef struct { elfcap_mask_t sc_hw_1; /* CA_SUNW_HW_1 capabilities */ elfcap_mask_t sc_sf_1; /* CA_SUNW_SF_1 capabilities */ elfcap_mask_t sc_hw_2; /* CA_SUNW_HW_2 capabilities */ + elfcap_mask_t sc_hw_3; /* CA_SUNW_HW_3 capabilities */ char *sc_plat; /* CA_SUNW_PLAT capability */ size_t sc_platsz; /* and size */ char *sc_mach; /* CA_SUNW_MACH capability */ diff --git a/usr/src/cmd/sgs/include/sgs.h b/usr/src/cmd/sgs/include/sgs.h index 4480d78470..54d3f60722 100644 --- a/usr/src/cmd/sgs/include/sgs.h +++ b/usr/src/cmd/sgs/include/sgs.h @@ -25,6 +25,7 @@ * * * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company * * Global include file for all sgs. */ @@ -195,7 +196,8 @@ typedef struct { #define SGS_REJ_HWCAP_2 17 /* hardware capabilities mismatch */ #define SGS_REJ_ARCHIVE 18 /* archive used in invalid context */ #define SGS_REJ_KMOD 19 /* object is a kernel module */ -#define SGS_REJ_NUM 20 +#define SGS_REJ_HWCAP_3 20 /* hardware capabilities mismatch */ +#define SGS_REJ_NUM 21 #define FLG_REJ_ALTER 0x01 /* object name is an alternative */ diff --git a/usr/src/cmd/sgs/libconv/common/cap.c b/usr/src/cmd/sgs/libconv/common/cap.c index 750bb36c56..c3197cf57d 100644 --- a/usr/src/cmd/sgs/libconv/common/cap.c +++ b/usr/src/cmd/sgs/libconv/common/cap.c @@ -22,6 +22,8 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2022 Oxide Computer Company */ /* @@ -33,23 +35,43 @@ #include "cap_msg.h" #include "_conv.h" +/* + * These are assertions that the various sizes that are dependent on elfcap.c + * are actually all the same. + */ +#if CONV_CAP_VAL_HW1_BUFSIZE != ELFCAP_HW1_BUFSIZE +#error "libconv needs to update CONV_CAP_VAL_HW1_BUFSIZE to match elfcap.h" +#endif + +#if CONV_CAP_VAL_HW2_BUFSIZE != ELFCAP_HW2_BUFSIZE +#error "libconv needs to update CONV_CAP_VAL_HW2_BUFSIZE to match elfcap.h" +#endif + +#if CONV_CAP_VAL_HW3_BUFSIZE != ELFCAP_HW3_BUFSIZE +#error "libconv needs to update CONV_CAP_VAL_HW3_BUFSIZE to match elfcap.h" +#endif + +#if CONV_CAP_VAL_SF1_BUFSIZE != ELFCAP_SF1_BUFSIZE +#error "libconv needs to update CONV_CAP_VAL_SF1_BUFSIZE to match elfcap.h" +#endif + const conv_ds_t ** conv_cap_tag_strings(Conv_fmt_flags_t fmt_flags) { -#if (CA_SUNW_NUM != (CA_SUNW_ID + 1)) +#if (CA_SUNW_NUM != (CA_SUNW_HW_3 + 1)) #error "CA_SUNW_NUM has grown" #endif static const Msg tags_cf[] = { MSG_CA_SUNW_NULL_CF, MSG_CA_SUNW_HW_1_CF, MSG_CA_SUNW_SF_1_CF, MSG_CA_SUNW_HW_2_CF, MSG_CA_SUNW_PLAT_CF, MSG_CA_SUNW_MACH_CF, - MSG_CA_SUNW_ID_CF + MSG_CA_SUNW_ID_CF, MSG_CA_SUNW_HW_3_CF }; static const Msg tags_nf[] = { MSG_CA_SUNW_NULL_NF, MSG_CA_SUNW_HW_1_NF, MSG_CA_SUNW_SF_1_NF, MSG_CA_SUNW_HW_2_NF, MSG_CA_SUNW_PLAT_NF, MSG_CA_SUNW_MACH_NF, - MSG_CA_SUNW_ID_NF + MSG_CA_SUNW_ID_NF, MSG_CA_SUNW_HW_3_NF }; static const conv_ds_msg_t ds_tags_cf = { CONV_DS_MSG_INIT(ELFCLASSNONE, tags_cf) }; @@ -140,6 +162,13 @@ conv_iter_ret_t conv_iter_cap_val_hw2(Half mach, Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue) { + if ((mach == EM_386) || (mach == EM_486) || + (mach == EM_AMD64) || (mach == CONV_MACH_ALL)) + if (conv_iter_elfcap(elfcap_getdesc_hw2_386(), + ELFCAP_NUM_HW2_386, fmt_flags, func, uvalue) == + CONV_ITER_DONE) + return (CONV_ITER_DONE); + return (CONV_ITER_DONE); } @@ -153,3 +182,17 @@ conv_iter_cap_val_sf1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, return (conv_iter_elfcap(elfcap_getdesc_sf1(), ELFCAP_NUM_SF1, fmt_flags, func, uvalue)); } + +conv_iter_ret_t +conv_iter_cap_val_hw3(Half mach, Conv_fmt_flags_t fmt_flags, + conv_iter_cb_t func, void *uvalue) +{ + if ((mach == EM_386) || (mach == EM_486) || + (mach == EM_AMD64) || (mach == CONV_MACH_ALL)) + if (conv_iter_elfcap(elfcap_getdesc_hw3_386(), + ELFCAP_NUM_HW3_386, fmt_flags, func, uvalue) == + CONV_ITER_DONE) + return (CONV_ITER_DONE); + + return (CONV_ITER_DONE); +} diff --git a/usr/src/cmd/sgs/libconv/common/cap.msg b/usr/src/cmd/sgs/libconv/common/cap.msg index ce07a0e001..5e0c56782c 100644 --- a/usr/src/cmd/sgs/libconv/common/cap.msg +++ b/usr/src/cmd/sgs/libconv/common/cap.msg @@ -2,6 +2,8 @@ # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2022 Oxide Computer Company +# # CDDL HEADER START # # The contents of this file are subject to the terms of the @@ -38,6 +40,8 @@ @ MSG_CA_SUNW_MACH_NF "mach" @ MSG_CA_SUNW_ID_CF "CA_SUNW_ID" # 6 @ MSG_CA_SUNW_ID_NF "id" +@ MSG_CA_SUNW_HW_3_CF "CA_SUNW_HW_3" # 7 +@ MSG_CA_SUNW_HW_3_NF "hw_3" @ MSG_GBL_ZERO "0" @ MSG_GBL_OSQBRKT "0x%llx [ " diff --git a/usr/src/cmd/sgs/libconv/common/cap_machelf.c b/usr/src/cmd/sgs/libconv/common/cap_machelf.c index d572e29409..ce8bbbde47 100644 --- a/usr/src/cmd/sgs/libconv/common/cap_machelf.c +++ b/usr/src/cmd/sgs/libconv/common/cap_machelf.c @@ -22,6 +22,8 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2022 Oxide Computer Company */ /* @@ -108,6 +110,19 @@ conv_cap_val_sf1(Xword val, Half mach, Conv_fmt_flags_t fmt_flags, } const char * +conv_cap_val_hw3(Xword val, Half mach, Conv_fmt_flags_t fmt_flags, + Conv_cap_val_hw3_buf_t *cap_val_hw3_buf) +{ + if (val == 0) + return (MSG_ORIG(MSG_GBL_ZERO)); + + if (conv_cap(val, cap_val_hw3_buf->buf, sizeof (cap_val_hw3_buf->buf), + mach, fmt_flags, elfcap_hw3_to_str) == 0) + return (conv_invalid_val(&cap_val_hw3_buf->inv_buf, val, 0)); + return ((const char *)cap_val_hw3_buf->buf); +} + +const char * conv_cap_tag(Xword tag, Conv_fmt_flags_t fmt_flags, Conv_inv_buf_t *inv_buf) { #ifdef _ELF64 @@ -144,6 +159,10 @@ conv_cap_val(Xword tag, Xword val, Half mach, Conv_fmt_flags_t fmt_flags, return (conv_cap_val_hw2(val, mach, fmt_flags, &cap_val_buf->cap_val_hw2_buf)); + case CA_SUNW_HW_3: + return (conv_cap_val_hw3(val, mach, fmt_flags, + &cap_val_buf->cap_val_hw3_buf)); + default: return (conv_invalid_val(&cap_val_buf->inv_buf, val, 0)); } diff --git a/usr/src/cmd/sgs/libconv/common/corenote.c b/usr/src/cmd/sgs/libconv/common/corenote.c index 79f976bda1..d23a1086d3 100644 --- a/usr/src/cmd/sgs/libconv/common/corenote.c +++ b/usr/src/cmd/sgs/libconv/common/corenote.c @@ -26,7 +26,7 @@ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2018 Joyent, Inc. - * Copyright 2021 Oxide Computer Company + * Copyright 2022 Oxide Computer Company */ /* @@ -107,7 +107,7 @@ conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags, static const conv_ds_msg_t ds_types_2000_2011 = { CONV_DS_MSG_INIT(2000, types_2000_2011) }; - static const Msg types_2014_2028[] = { + static const Msg types_2014_2029[] = { MSG_AUXV_AT_SUN_EXECNAME, MSG_AUXV_AT_SUN_MMU, MSG_AUXV_AT_SUN_LDDATA, MSG_AUXV_AT_SUN_AUXFLAGS, MSG_AUXV_AT_SUN_EMULATOR, MSG_AUXV_AT_SUN_BRANDNAME, @@ -115,14 +115,14 @@ conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags, MSG_AUXV_AT_SUN_BRAND_AUX3, MSG_AUXV_AT_SUN_HWCAP2, 0, 0, MSG_AUXV_AT_SUN_COMMPAGE, MSG_AUXV_AT_SUN_FPTYPE, - MSG_AUXV_AT_SUN_FPSIZE + MSG_AUXV_AT_SUN_FPSIZE, MSG_AUXV_AT_SUN_HWCAP3 }; - static const conv_ds_msg_t ds_types_2014_2028 = { - CONV_DS_MSG_INIT(2014, types_2014_2028) }; + static const conv_ds_msg_t ds_types_2014_2029 = { + CONV_DS_MSG_INIT(2014, types_2014_2029) }; static const conv_ds_t *ds[] = { CONV_DS_ADDR(ds_types_0_22), CONV_DS_ADDR(ds_types_2000_2011), - CONV_DS_ADDR(ds_types_2014_2028), NULL }; + CONV_DS_ADDR(ds_types_2014_2029), NULL }; return (conv_map_ds(ELFOSABI_NONE, EM_NONE, type, ds, fmt_flags, inv_buf)); diff --git a/usr/src/cmd/sgs/libconv/common/corenote.msg b/usr/src/cmd/sgs/libconv/common/corenote.msg index 7387815761..1d944cc18c 100644 --- a/usr/src/cmd/sgs/libconv/common/corenote.msg +++ b/usr/src/cmd/sgs/libconv/common/corenote.msg @@ -25,7 +25,7 @@ # # Copyright 2012 DEY Storage Systems, Inc. All rights reserved. # Copyright (c) 2018 Joyent, Inc. -# Copyright 2021 Oxide Computer Company +# Copyright 2022 Oxide Computer Company # @ MSG_NT_PRSTATUS "[ NT_PRSTATUS ]" @@ -107,6 +107,7 @@ @ MSG_AUXV_AT_SUN_COMMPAGE "SUN_COMMPAGE" @ MSG_AUXV_AT_SUN_FPTYPE "SUN_FPTYPE" @ MSG_AUXV_AT_SUN_FPSIZE "SUN_FPSIZE" +@ MSG_AUXV_AT_SUN_HWCAP3 "SUN_HWCAP3" @ MSG_CC_CONTENT_STACK "STACK" diff --git a/usr/src/cmd/sgs/libconv/common/elf.c b/usr/src/cmd/sgs/libconv/common/elf.c index 2ef1f55963..a61cc5450e 100644 --- a/usr/src/cmd/sgs/libconv/common/elf.c +++ b/usr/src/cmd/sgs/libconv/common/elf.c @@ -22,6 +22,7 @@ /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, Joyent, Inc. + * Copyright 2022 Oxide Computer Company */ /* @@ -1217,6 +1218,7 @@ conv_reject_desc(Rej_desc * rej, Conv_reject_desc_buf_t *reject_desc_buf, case SGS_REJ_HWCAP_1: case SGS_REJ_SFCAP_1: case SGS_REJ_HWCAP_2: + case SGS_REJ_HWCAP_3: case SGS_REJ_MACHCAP: case SGS_REJ_PLATCAP: if (rej->rej_str) diff --git a/usr/src/cmd/sgs/libld/common/files.c b/usr/src/cmd/sgs/libld/common/files.c index a3277b4bf1..4ae59398b1 100644 --- a/usr/src/cmd/sgs/libld/common/files.c +++ b/usr/src/cmd/sgs/libld/common/files.c @@ -25,6 +25,7 @@ * * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright 2022 Oxide Computer Company */ /* @@ -389,12 +390,21 @@ hw_cap(Ofl_desc *ofl, Xword tag, Xword val) elfcap_mask_t *hwcap; ofl_flag_t flags1; - if (tag == CA_SUNW_HW_1) { + switch (tag) { + case CA_SUNW_HW_1: hwcap = &ofl->ofl_ocapset.oc_hw_1.cm_val; flags1 = FLG_OF1_OVHWCAP1; - } else { + break; + case CA_SUNW_HW_2: hwcap = &ofl->ofl_ocapset.oc_hw_2.cm_val; flags1 = FLG_OF1_OVHWCAP2; + break; + case CA_SUNW_HW_3: + hwcap = &ofl->ofl_ocapset.oc_hw_3.cm_val; + flags1 = FLG_OF1_OVHWCAP3; + break; + default: + assert(0); } /* @@ -547,6 +557,9 @@ ld_cap_move_symtoobj(Ofl_desc *ofl) CA_SUNW_MACH, &ofl->ofl_ocapset.oc_mach); } } + if (scapset->oc_hw_3.cm_val) + hw_cap(ofl, CA_SUNW_HW_3, scapset->oc_hw_3.cm_val); + if (scapset->oc_hw_2.cm_val) hw_cap(ofl, CA_SUNW_HW_2, scapset->oc_hw_2.cm_val); @@ -599,6 +612,8 @@ get_cap_group(Objcapset *ocapset, Word cnum, Ofl_desc *ofl, Is_desc *isp) continue; if (cgp->cg_set.oc_hw_2.cm_val != ocapset->oc_hw_2.cm_val) continue; + if (cgp->cg_set.oc_hw_3.cm_val != ocapset->oc_hw_3.cm_val) + continue; calp = cgp->cg_set.oc_plat.cl_val; oalp = ocapset->oc_plat.cl_val; @@ -898,6 +913,7 @@ process_cap(Ofl_desc *ofl, Ifl_desc *ifl, Is_desc *cisp) case CA_SUNW_HW_1: case CA_SUNW_SF_1: case CA_SUNW_HW_2: + case CA_SUNW_HW_3: /* * If this is the start of a new group, save it. */ @@ -1099,7 +1115,8 @@ process_cap(Ofl_desc *ofl, Ifl_desc *ifl, Is_desc *cisp) */ ocapset.oc_hw_1.cm_val = ocapset.oc_sf_1.cm_val = - ocapset.oc_hw_2.cm_val = 0; + ocapset.oc_hw_2.cm_val = + ocapset.oc_hw_3.cm_val = 0; if (ocapset.oc_plat.cl_val) { free((void *)ocapset.oc_plat.cl_val); ocapset.oc_plat.cl_val = NULL; @@ -1157,6 +1174,13 @@ process_cap(Ofl_desc *ofl, Ifl_desc *ifl, Is_desc *cisp) DBG_STATE_ORIGINAL, CA_SUNW_ID, ocapset.oc_id.cs_str)); break; + + case CA_SUNW_HW_3: + ocapset.oc_hw_3.cm_val = data->c_un.c_val; + DBG_CALL(Dbg_cap_val_entry(ofl->ofl_lml, + DBG_STATE_ORIGINAL, CA_SUNW_HW_3, + ocapset.oc_hw_3.cm_val, ld_targ.t_m.m_mach)); + break; } /* diff --git a/usr/src/cmd/sgs/libld/common/globals.c b/usr/src/cmd/sgs/libld/common/globals.c index 71dda65bf2..c57dafc426 100644 --- a/usr/src/cmd/sgs/libld/common/globals.c +++ b/usr/src/cmd/sgs/libld/common/globals.c @@ -24,6 +24,7 @@ * All Rights Reserved * * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ /* @@ -77,9 +78,10 @@ reject[SGS_REJ_NUM] = { MSG_REJ_PLATCAP, /* MSG_INTL(MSG_REJ_PLATCAP) */ MSG_REJ_HWCAP_2, /* MSG_INTL(MSG_REJ_HWCAP_2) */ MSG_REJ_ARCHIVE, /* MSG_INTL(MSG_REJ_ARCHIVE) */ - MSG_REJ_KMOD /* MSG_INTL(MSG_REJ_KMOD) */ + MSG_REJ_KMOD, /* MSG_INTL(MSG_REJ_KMOD) */ + MSG_REJ_HWCAP_3 /* MSG_INTL(MSG_REJ_HWCAP_3) */ }; -#if SGS_REJ_NUM != (SGS_REJ_KMOD + 1) +#if SGS_REJ_NUM != (SGS_REJ_HWCAP_3 + 1) #error SGS_REJ_NUM has changed #endif diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg index 659c40bf73..e575a263f0 100644 --- a/usr/src/cmd/sgs/libld/common/libld.msg +++ b/usr/src/cmd/sgs/libld/common/libld.msg @@ -23,6 +23,7 @@ # Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2012, Joyent, Inc. All rights reserved. # Copyright 2017 RackTop Systems. +# Copyright 2022 Oxide Computer Company # @ _START_ @@ -693,6 +694,8 @@ unsupported: %s" @ MSG_REJ_ARCHIVE "file %s: invalid archive use" @ MSG_REJ_KMOD "file %s: kernel modules can't be link-edit input" +@ MSG_REJ_HWCAP_3 "file %s: hardware capability (CA_SUNW_HW_3) \ + unsupported: %s" # Guidance messages @ MSG_GUIDE_UNKNOWN "unrecognized -z guidance item: %s" @@ -1617,6 +1620,7 @@ @ MSG_MAPKW_HW "HW" @ MSG_MAPKW_HW_1 "HW_1" @ MSG_MAPKW_HW_2 "HW_2" +@ MSG_MAPKW_HW_3 "HW_3" @ MSG_MAPKW_INTERPOSE "INTERPOSE" @ MSG_MAPKW_IS_NAME "IS_NAME" @ MSG_MAPKW_IS_ORDER "IS_ORDER" diff --git a/usr/src/cmd/sgs/libld/common/map_support.c b/usr/src/cmd/sgs/libld/common/map_support.c index 61d64b7fd9..ea11c8aefb 100644 --- a/usr/src/cmd/sgs/libld/common/map_support.c +++ b/usr/src/cmd/sgs/libld/common/map_support.c @@ -29,6 +29,7 @@ /* * Copyright 2019 Joyent, Inc. + * Copyright 2022 Oxide Computer Company */ /* @@ -203,9 +204,10 @@ ld_map_cap_set_ovflag(Mapfile *mf, Word type) FLG_OF1_OVHWCAP2, /* CA_SUNW_HW_2 */ FLG_OF1_OVPLATCAP, /* CA_SUNW_PLAT */ FLG_OF1_OVMACHCAP, /* CA_SUNW_MACH */ - FLG_OF1_OVIDCAP /* CA_SUNW_ID */ + FLG_OF1_OVIDCAP, /* CA_SUNW_ID */ + FLG_OF1_OVHWCAP3 /* CA_SUNW_HW_3 */ }; -#if CA_SUNW_NUM != (CA_SUNW_ID + 1) +#if CA_SUNW_NUM != (CA_SUNW_HW_3 + 1) #error "CA_SUNW_NUM has grown" #endif mf->mf_ofl->ofl_flags1 |= override_flag[type]; diff --git a/usr/src/cmd/sgs/libld/common/map_v2.c b/usr/src/cmd/sgs/libld/common/map_v2.c index 791ad34971..c3e8ef77eb 100644 --- a/usr/src/cmd/sgs/libld/common/map_v2.c +++ b/usr/src/cmd/sgs/libld/common/map_v2.c @@ -26,6 +26,7 @@ /* * Copyright 2019 Joyent, Inc. + * Copyright 2022 Oxide Computer Company */ /* @@ -1063,7 +1064,7 @@ at_cap_hw(Mapfile *mf, Token eq_tok, void *uvalue) Token tok; ld_map_tkval_t tkv; Conv_inv_buf_t inv_buf; - Word hw1 = 0, hw2 = 0; + Word hw1 = 0, hw2 = 0, hw3 = 0; uint64_t v; for (done = 0; done == 0; ) { @@ -1082,6 +1083,12 @@ at_cap_hw(Mapfile *mf, Token eq_tok, void *uvalue) hw2 |= v; break; } + + if ((v = elfcap_hw3_from_str(ELFCAP_STYLE, + tkv.tkv_str, ld_targ.t_m.m_mach)) != 0) { + hw3 |= v; + break; + } goto bad_flag; case TK_SEMICOLON: @@ -1103,6 +1110,9 @@ at_cap_hw(Mapfile *mf, Token eq_tok, void *uvalue) if (!set_capmask(mf, &mf->mf_ofl->ofl_ocapset.oc_hw_2, eq_tok, CA_SUNW_HW_2, hw2, FALSE)) return (TK_ERROR); + if (!set_capmask(mf, &mf->mf_ofl->ofl_ocapset.oc_hw_3, eq_tok, + CA_SUNW_HW_3, hw3, FALSE)) + return (TK_ERROR); return (tok); } @@ -1209,6 +1219,17 @@ at_cap_plat(Mapfile *mf, Token eq_tok, void *uvalue) } /* + * CAPABILITY [capid] { HW_3 = value ; + * ---------------------------^ + */ +static Token +at_cap_hw_3(Mapfile *mf, Token eq_tok, void *uvalue) +{ + return (parse_cap_mask(mf, eq_tok, &mf->mf_ofl->ofl_ocapset.oc_hw_3, + CA_SUNW_HW_3, elfcap_hw3_from_str)); +} + +/* * Top Level Directive: * * CAPABILITY [capid] { ... @@ -1222,6 +1243,7 @@ dir_capability(Mapfile *mf) { MSG_ORIG(MSG_MAPKW_HW), at_cap_hw, ATTR_FMT_EQ_ALL }, { MSG_ORIG(MSG_MAPKW_HW_1), at_cap_hw_1, ATTR_FMT_EQ_ALL }, { MSG_ORIG(MSG_MAPKW_HW_2), at_cap_hw_2, ATTR_FMT_EQ_ALL }, + { MSG_ORIG(MSG_MAPKW_HW_3), at_cap_hw_3, ATTR_FMT_EQ_ALL }, { MSG_ORIG(MSG_MAPKW_MACHINE), at_cap_mach, ATTR_FMT_EQ_ALL }, { MSG_ORIG(MSG_MAPKW_PLATFORM), at_cap_plat, ATTR_FMT_EQ_ALL }, @@ -1241,6 +1263,7 @@ dir_capability(Mapfile *mf) KW_NAME_SIZE(MSG_MAPKW_HW) + KW_NAME_SIZE(MSG_MAPKW_HW_1) + KW_NAME_SIZE(MSG_MAPKW_HW_2) + + KW_NAME_SIZE(MSG_MAPKW_HW_3) + KW_NAME_SIZE(MSG_MAPKW_MACHINE) + KW_NAME_SIZE(MSG_MAPKW_PLATFORM) + KW_NAME_SIZE(MSG_MAPKW_SF) + diff --git a/usr/src/cmd/sgs/libld/common/sections.c b/usr/src/cmd/sgs/libld/common/sections.c index 984c3c9b8e..5ff110e346 100644 --- a/usr/src/cmd/sgs/libld/common/sections.c +++ b/usr/src/cmd/sgs/libld/common/sections.c @@ -24,6 +24,7 @@ * All Rights Reserved * * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ /* @@ -1494,6 +1495,14 @@ is_cap_redundant(Objcapset *ocapset, Objcapset *scapset) * could be considered to be less important than lower ones. However, * this is the only reasonable non-subjective definition. */ + omsk = ocapset->oc_hw_3.cm_val; + smsk = scapset->oc_hw_3.cm_val; + if ((omsk > smsk) || (omsk && (omsk == smsk))) + return (1); + if (omsk < smsk) + return (0); + + omsk = ocapset->oc_hw_2.cm_val; smsk = scapset->oc_hw_2.cm_val; if ((omsk > smsk) || (omsk && (omsk == smsk))) @@ -1650,6 +1659,7 @@ make_cap(Ofl_desc *ofl, Word shtype, const char *shname, int ident) */ capstr_value(ofl->ofl_lml, CA_SUNW_PLAT, &ocapset->oc_plat, &title); capstr_value(ofl->ofl_lml, CA_SUNW_MACH, &ocapset->oc_mach, &title); + capmask_value(ofl->ofl_lml, CA_SUNW_HW_3, &ocapset->oc_hw_3, &title); capmask_value(ofl->ofl_lml, CA_SUNW_HW_2, &ocapset->oc_hw_2, &title); capmask_value(ofl->ofl_lml, CA_SUNW_HW_1, &ocapset->oc_hw_1, &title); capmask_value(ofl->ofl_lml, CA_SUNW_SF_1, &ocapset->oc_sf_1, &title); @@ -1659,6 +1669,8 @@ make_cap(Ofl_desc *ofl, Word shtype, const char *shname, int ident) */ size += alist_nitems(ocapset->oc_plat.cl_val); size += alist_nitems(ocapset->oc_mach.cl_val); + if (ocapset->oc_hw_3.cm_val) + size++; if (ocapset->oc_hw_2.cm_val) size++; if (ocapset->oc_hw_1.cm_val) @@ -1750,6 +1762,10 @@ make_cap(Ofl_desc *ofl, Word shtype, const char *shname, int ident) CAP_UPDATE(cap, capndx, CA_SUNW_MACH, 0); } } + if (ocapset->oc_hw_3.cm_val) { + ofl->ofl_flags |= FLG_OF_PTCAP; + CAP_UPDATE(cap, capndx, CA_SUNW_HW_3, ocapset->oc_hw_3.cm_val); + } if (ocapset->oc_hw_2.cm_val) { ofl->ofl_flags |= FLG_OF_PTCAP; CAP_UPDATE(cap, capndx, CA_SUNW_HW_2, ocapset->oc_hw_2.cm_val); @@ -1830,6 +1846,10 @@ make_cap(Ofl_desc *ofl, Word shtype, const char *shname, int ident) CA_SUNW_MACH, 0); } } + if (scapset->oc_hw_3.cm_val) { + CAP_UPDATE(cap, capndx, CA_SUNW_HW_3, + scapset->oc_hw_3.cm_val); + } if (scapset->oc_hw_2.cm_val) { CAP_UPDATE(cap, capndx, CA_SUNW_HW_2, scapset->oc_hw_2.cm_val); diff --git a/usr/src/cmd/sgs/liblddbg/common/cap.c b/usr/src/cmd/sgs/liblddbg/common/cap.c index d1429920c7..0e5f12ad16 100644 --- a/usr/src/cmd/sgs/liblddbg/common/cap.c +++ b/usr/src/cmd/sgs/liblddbg/common/cap.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ #include <stdio.h> @@ -82,6 +83,11 @@ Dbg_cap_val(Lm_list *lml, Syscapset *sys, Syscapset *alt, Half mach) if (sys->sc_mach) { dbg_print(lml, MSG_INTL(MSG_CAP_SYS_MACH), sys->sc_mach); } + if (sys->sc_hw_3) { + dbg_print(lml, MSG_INTL(MSG_CAP_SYS_HW_3), + conv_cap_val_hw3(sys->sc_hw_3, mach, 0, + &cap_val_buf.cap_val_hw3_buf)); + } if (sys->sc_hw_2) { dbg_print(lml, MSG_INTL(MSG_CAP_SYS_HW_2), conv_cap_val_hw2(sys->sc_hw_2, mach, 0, @@ -108,6 +114,11 @@ Dbg_cap_val(Lm_list *lml, Syscapset *sys, Syscapset *alt, Half mach) dbg_print(lml, MSG_INTL(MSG_CAP_ALT_MACH), alt->sc_mach); } + if (alt->sc_hw_3 != sys->sc_hw_3) { + dbg_print(lml, MSG_INTL(MSG_CAP_ALT_HW_3), + conv_cap_val_hw3(alt->sc_hw_3, mach, 0, + &cap_val_buf.cap_val_hw3_buf)); + } if (alt->sc_hw_2 != sys->sc_hw_2) { dbg_print(lml, MSG_INTL(MSG_CAP_ALT_HW_2), conv_cap_val_hw2(alt->sc_hw_2, mach, 0, diff --git a/usr/src/cmd/sgs/liblddbg/common/files.c b/usr/src/cmd/sgs/liblddbg/common/files.c index b44aabd116..5e167103a0 100644 --- a/usr/src/cmd/sgs/liblddbg/common/files.c +++ b/usr/src/cmd/sgs/liblddbg/common/files.c @@ -21,6 +21,7 @@ /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ #include <sys/auxv.h> @@ -652,8 +653,11 @@ Dbg_file_generic(Lm_list *lml, Ifl_desc *ifl) ifl->ifl_ehdr->e_type, 0, &inv_buf)); } -static const Msg -reject[] = { +#if SGS_REJ_NUM != (SGS_REJ_HWCAP_3 + 1) +#error SGS_REJ_NUM has changed +#endif + +static const Msg reject[SGS_REJ_NUM] = { MSG_STR_EMPTY, MSG_REJ_MACH, /* MSG_INTL(MSG_REJ_MACH) */ MSG_REJ_CLASS, /* MSG_INTL(MSG_REJ_CLASS) */ @@ -671,7 +675,10 @@ reject[] = { MSG_REJ_SFCAP_1, /* MSG_INTL(MSG_REJ_SFCAP_1) */ MSG_REJ_MACHCAP, /* MSG_INTL(MSG_REJ_MACHCAP) */ MSG_REJ_PLATCAP, /* MSG_INTL(MSG_REJ_PLATCAP) */ - MSG_REJ_HWCAP_2 /* MSG_INTL(MSG_REJ_HWCAP_2) */ + MSG_REJ_HWCAP_2, /* MSG_INTL(MSG_REJ_HWCAP_2) */ + MSG_REJ_ARCHIVE, /* MSG_INTL(MSG_REJ_ARCHIVE) */ + MSG_REJ_KMOD, /* MSG_INTL(MSG_REJ_KMOD) */ + MSG_REJ_HWCAP_3 /* MSG_INTL(MSG_REJ_HWCAP_3) */ }; void diff --git a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg index 74619ae699..56c4f0ada6 100644 --- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg +++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg @@ -21,6 +21,7 @@ # # Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2022 Oxide Computer Company # @ _START_ @@ -751,6 +752,10 @@ unsupported: %s" @ MSG_REJ_HWCAP_2 "obj=%s; rejected: hardware capability (CA_SUNW_HW_2) \ unsupported: %s" +@ MSG_REJ_ARCHIVE "obj=%s; rejected: archive unsed incorrectly" +@ MSG_REJ_KMOD "obj=%s; rejected: kernel module" +@ MSG_REJ_HWCAP_3 "obj=%s; rejected: hardware capability (CA_SUNW_HW_3) \ + unsupported: %s" # Libs messages @@ -996,6 +1001,8 @@ (CA_SUNW_PLAT): [ %s ]" @ MSG_CAP_SYM_HW_2 " symbol=%s[%u]: capability specific \ (CA_SUNW_HW_2): [ %s ]" +@ MSG_CAP_SYM_HW_3 " symbol=%s[%u]: capability specific \ + (CA_SUNW_HW_3): [ %s ]" @ MSG_SYM_LAZY_RESCAN "rescanning for lazy dependencies for symbol: %s" @@ -1181,12 +1188,14 @@ @ MSG_CAP_SYS_MACH "machine capability (CA_SUNW_MACH) - %s" @ MSG_CAP_SYS_PLAT "platform capability (CA_SUNW_PLAT) - %s" @ MSG_CAP_SYS_HW_2 "hardware capabilities (CA_SUNW_HW_2) - %s" +@ MSG_CAP_SYS_HW_3 "hardware capabilities (CA_SUNW_HW_3) - %s" @ MSG_CAP_ALT_HW_1 "alternative hardware capabilities (CA_SUNW_HW_1) - %s" @ MSG_CAP_ALT_SF_1 "alternative software capabilities (CA_SUNW_SF_1) - %s" @ MSG_CAP_ALT_MACH "alternative machine capability (CA_SUNW_MACH) - %s" @ MSG_CAP_ALT_PLAT "alternative platform capability (CA_SUNW_PLAT) - %s" @ MSG_CAP_ALT_HW_2 "alternative hardware capabilities (CA_SUNW_HW_2) - %s" +@ MSG_CAP_ALT_HW_3 "alternative hardware capabilities (CA_SUNW_HW_3) - %s" @ MSG_CAP_SEC_TITLE "capabilities; input file=%s" @ MSG_CAP_SEC_ENTRY "%12.12s %-15.15s %s" diff --git a/usr/src/cmd/sgs/liblddbg/common/syms.c b/usr/src/cmd/sgs/liblddbg/common/syms.c index be3315243a..446499b6e5 100644 --- a/usr/src/cmd/sgs/liblddbg/common/syms.c +++ b/usr/src/cmd/sgs/liblddbg/common/syms.c @@ -21,6 +21,7 @@ /* * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ #include <stdio.h> @@ -40,7 +41,7 @@ Dbg_syms_lookup(Rt_map *lmp, const char *name, const char *type) NAME(lmp), type); } -static const Msg captype[DBG_CAP_MACH + 1] = { +static const Msg captype[DBG_CAP_HW_3 + 1] = { MSG_CAP_SYM_DEFAULT, /* MSG_INTL(MSG_CAP_SYM_DEFAULT) */ MSG_CAP_SYM_USED, /* MSG_INTL(MSG_CAP_SYM_USED) */ MSG_CAP_SYM_CANDIDATE, /* MSG_INTL(MSG_CAP_SYM_CANDIDATE) */ @@ -49,7 +50,8 @@ static const Msg captype[DBG_CAP_MACH + 1] = { MSG_CAP_SYM_SF_1, /* MSG_INTL(MSG_CAP_SYM_SF_1) */ MSG_CAP_SYM_HW_2, /* MSG_INTL(MSG_CAP_SYM_HW_2) */ MSG_CAP_SYM_PLAT, /* MSG_INTL(MSG_CAP_SYM_PLAT) */ - MSG_CAP_SYM_MACH /* MSG_INTL(MSG_CAP_SYM_MACH) */ + MSG_CAP_SYM_MACH, /* MSG_INTL(MSG_CAP_SYM_MACH) */ + MSG_CAP_SYM_HW_3 /* MSG_INTL(MSG_CAP_SYM_HW_3) */ }; void @@ -82,6 +84,10 @@ Dbg_syms_cap_lookup(Rt_map *lmp, uint_t type, const char *name, uint_t ndx, case DBG_CAP_PLAT: str = scapset->sc_plat; break; + case DBG_CAP_HW_3: + str = conv_cap_val_hw3(scapset->sc_hw_3, mach, 0, + &cap_val_buf.cap_val_hw3_buf); + break; } dbg_print(lml, MSG_INTL(captype[type]), Dbg_demangle_name(name), diff --git a/usr/src/cmd/sgs/rtld/amd64/_setup.c b/usr/src/cmd/sgs/rtld/amd64/_setup.c index e48db1cc11..1d45699da2 100644 --- a/usr/src/cmd/sgs/rtld/amd64/_setup.c +++ b/usr/src/cmd/sgs/rtld/amd64/_setup.c @@ -25,6 +25,7 @@ */ /* * Copyright (c) 2018, Joyent, Inc. + * Copyright 2022 Oxide Computer Company */ /* @@ -121,7 +122,7 @@ _setup(Boot *ebp, Dyn *ld_dyn) char *_rt_name, **_envp, **_argv; int _syspagsz = 0, fd = -1; uint_t _flags = 0; - uint_t hwcap[2] = { 0, 0 }; + uint_t hwcap[3] = { 0, 0, 0 }; Dyn *dyn_ptr; Phdr *phdr = NULL; Rt_map *lmp; @@ -217,6 +218,10 @@ _setup(Boot *ebp, Dyn *ld_dyn) /* hardware capabilities */ hwcap[1] = (uint_t)auxv->a_un.a_val; break; + case AT_SUN_HWCAP3: + /* hardware capabilities */ + hwcap[2] = (uint_t)auxv->a_un.a_val; + break; case AT_SUN_EMULATOR: /* name of emulation library, if any */ _emulator = auxv->a_un.a_ptr; diff --git a/usr/src/cmd/sgs/rtld/common/cap.c b/usr/src/cmd/sgs/rtld/common/cap.c index 47abbc78bc..0c4109c97a 100644 --- a/usr/src/cmd/sgs/rtld/common/cap.c +++ b/usr/src/cmd/sgs/rtld/common/cap.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ #include <sys/types.h> @@ -69,9 +70,19 @@ compare(const void *vp_a, const void *vp_b) return (-1); if (strcap_b && (strcap_a == NULL)) return (1); + /* + * Third, investigate any CA_SUNW_HW_3 hardware capabilities. + */ + hwcap_a = fdp_a->fd_scapset.sc_hw_3; + hwcap_b = fdp_b->fd_scapset.sc_hw_3; + + if (hwcap_a > hwcap_b) + return (-1); + if (hwcap_a < hwcap_b) + return (1); /* - * Third, investigate any CA_SUNW_HW_2 hardware capabilities. + * Fourth, investigate any CA_SUNW_HW_2 hardware capabilities. */ hwcap_a = fdp_a->fd_scapset.sc_hw_2; hwcap_b = fdp_b->fd_scapset.sc_hw_2; @@ -160,6 +171,30 @@ hwcap2_check(Syscapset *scapset, Xword val, Rej_desc *rej) } /* + * Determine whether HWCAP3 capabilities value is supported. + */ +int +hwcap3_check(Syscapset *scapset, Xword val, Rej_desc *rej) +{ + Xword mval; + + /* + * Ensure that the kernel can cope with the required capabilities. + */ + if ((mval = (val & ~scapset->sc_hw_3)) != 0) { + if (rej) { + static Conv_cap_val_hw3_buf_t cap_buf; + + rej->rej_type = SGS_REJ_HWCAP_3; + rej->rej_str = conv_cap_val_hw3(mval, + M_MACH, 0, &cap_buf); + } + return (0); + } + return (1); +} + +/* * Process any software capabilities. */ /* ARGSUSED0 */ @@ -343,6 +378,12 @@ cap_check(Cap *cptr, char *strs, int alt, Fdesc *fdp, Rej_desc *rej) * the system. They are ignored. */ break; + case CA_SUNW_HW_3: + if (hwcap3_check(scapset, val, rej) == 0) + return (0); + if (fdp) + fdp->fd_scapset.sc_hw_3 = val; + break; default: rej->rej_type = SGS_REJ_UNKCAP; rej->rej_info = cptr->c_tag; @@ -837,15 +878,28 @@ typedef enum { CAP_DISABLE = 2 /* disable capabilities */ } cap_mode; +/* + * The override indexes originally followed the values of CA_SUNW_HW_1, SF_1, + * etc. + */ +typedef enum { + CAP_OVR_HW_1 = 0, + CAP_OVR_SF_1, + CAP_OVR_HW_2, + CAP_OVR_HW_3, + CAP_OVR_MAX +} cap_index_t; + static struct { elfcap_mask_t cs_val[3]; /* value settings, and indicator for */ int cs_set[3]; /* OVERRIDE, ENABLE and DISABLE */ elfcap_mask_t *cs_aval; /* alternative variable for final */ /* update */ -} cap_settings[3] = { +} cap_settings[CAP_OVR_MAX] = { { { 0, 0, 0 }, { 0, 0, 0 }, NULL }, /* CA_SUNW_HW_1 */ { { 0, 0, 0 }, { 0, 0, 0 }, NULL }, /* CA_SUNW_SF_1 */ - { { 0, 0, 0 }, { 0, 0, 0 }, NULL } /* CA_SUNW_HW_2 */ + { { 0, 0, 0 }, { 0, 0, 0 }, NULL }, /* CA_SUNW_HW_2 */ + { { 0, 0, 0 }, { 0, 0, 0 }, NULL } /* CA_SUNW_HW_3 */ }; static int @@ -853,7 +907,7 @@ cap_modify(Xword tag, const char *str) { char *caps, *ptr, *next; cap_mode mode = CAP_OVERRIDE; - Xword ndx; + cap_index_t ndx; if ((caps = strdup(str)) == NULL) return (0); @@ -885,16 +939,22 @@ cap_modify(Xword tag, const char *str) * a known hardware capability mask. Note, the caller * indicates that these are hardware capabilities by * passing in the CA_SUNW_HW_1 tag. However, the - * tokens could be CA_SUNW_HW_1 or CA_SUNW_HW_2. + * tokens could be CA_SUNW_HW_1, CA_SUNW_HW_2, or + * CA_SUNW_HW_3. */ + if ((val = (Xword)elfcap_hw3_from_str(ELFCAP_STYLE, + ptr, M_MACH)) != 0) { + ndx = CAP_OVR_HW_3; + break; + } if ((val = (Xword)elfcap_hw2_from_str(ELFCAP_STYLE, ptr, M_MACH)) != 0) { - ndx = CA_SUNW_HW_2; + ndx = CAP_OVR_HW_2; break; } if ((val = (Xword)elfcap_hw1_from_str(ELFCAP_STYLE, ptr, M_MACH)) != 0) - ndx = CA_SUNW_HW_1; + ndx = CAP_OVR_HW_1; break; case CA_SUNW_SF_1: /* @@ -906,7 +966,7 @@ cap_modify(Xword tag, const char *str) */ if ((val = (Xword)elfcap_sf1_from_str(ELFCAP_STYLE, ptr, M_MACH)) != 0) - ndx = CA_SUNW_SF_1; + ndx = CAP_OVR_SF_1; break; } @@ -918,6 +978,7 @@ cap_modify(Xword tag, const char *str) * * LD_HWCAP=[1]0x40 sets CA_SUNW_HW_1 with 0x40 * LD_HWCAP=[2]0x80 sets CA_SUNW_HW_2 with 0x80 + * LD_HWCAP=[3]0x44 sets CA_SUNW_HW_3 with 0x44 * * Invalid indexes are ignored. */ @@ -926,11 +987,19 @@ cap_modify(Xword tag, const char *str) if ((*ptr == '[') && (*(ptr + 2) == ']')) { if (*(ptr + 1) == '1') { - ndx = tag; + ndx = CAP_OVR_HW_1; ptr += 3; + } else if (*(ptr + 1) == '3') { + if (tag == CA_SUNW_HW_1) { + ndx = CAP_OVR_HW_3; + ptr += 3; + } else { + /* invalid index */ + continue; + } } else if (*(ptr + 1) == '2') { if (tag == CA_SUNW_HW_1) { - ndx = CA_SUNW_HW_2; + ndx = CAP_OVR_HW_2; ptr += 3; } else { /* invalid index */ @@ -940,8 +1009,9 @@ cap_modify(Xword tag, const char *str) /* invalid index */ continue; } - } else - ndx = tag; + } else { + ndx = tag - 1; + } errno = 0; if (((val = strtol(ptr, &end, 16)) == 0) && errno) @@ -959,8 +1029,8 @@ cap_modify(Xword tag, const char *str) } } - cap_settings[ndx - 1].cs_val[mode] |= val; - cap_settings[ndx - 1].cs_set[mode]++; + cap_settings[ndx].cs_val[mode] |= val; + cap_settings[ndx].cs_set[mode]++; } @@ -968,7 +1038,7 @@ cap_modify(Xword tag, const char *str) * If the "override" token was supplied, set the alternative * system capabilities, then enable or disable others. */ - for (ndx = 0; ndx < CA_SUNW_HW_2; ndx++) { + for (ndx = 0; ndx < CAP_OVR_MAX; ndx++) { if (cap_settings[ndx].cs_set[CAP_OVERRIDE]) *(cap_settings[ndx].cs_aval) = cap_settings[ndx].cs_val[CAP_OVERRIDE]; @@ -1046,9 +1116,10 @@ cap_alternative(void) return (0); *alt_scapset = *org_scapset; - cap_settings[CA_SUNW_HW_1 - 1].cs_aval = &alt_scapset->sc_hw_1; - cap_settings[CA_SUNW_SF_1 - 1].cs_aval = &alt_scapset->sc_sf_1; - cap_settings[CA_SUNW_HW_2 - 1].cs_aval = &alt_scapset->sc_hw_2; + cap_settings[CAP_OVR_HW_1].cs_aval = &alt_scapset->sc_hw_1; + cap_settings[CAP_OVR_SF_1].cs_aval = &alt_scapset->sc_sf_1; + cap_settings[CAP_OVR_HW_2].cs_aval = &alt_scapset->sc_hw_2; + cap_settings[CAP_OVR_HW_3].cs_aval = &alt_scapset->sc_hw_3; /* * Process any replaceable variables. @@ -1203,6 +1274,15 @@ sym_cap_check(Cap *cptr, uint_t cndx, Syscapset *bestcapset, Rt_map *lmp, ivlmach++; } break; + case CA_SUNW_HW_3: + bestcapset->sc_hw_3 = val; + DBG_CALL(Dbg_syms_cap_lookup(lmp, DBG_CAP_HW_3, + name, ndx, M_MACH, bestcapset)); + + if (hwcap3_check(scapset, val, NULL) == 0) + capfail++; + break; + default: break; } @@ -1269,12 +1349,18 @@ is_sym_the_best(Syscapset *bestcapset, Syscapset *symcapset) return (1); /* - * Check the hardware capabilities. If the best symbols CA_SUNW_HW_2 + * Check the hardware capabilities. If the best symbols CA_SUNW_HW_3 * capabilities are greater than the new symbols capabilities, then - * retain the best capabilities group. If the new symbols CA_SUNW_HW_2 + * retain the best capabilities group. If the new symbols CA_SUNW_HW_3 * capabilities are greater than the best symbol, then the new symbol - * needs to be taken. + * needs to be taken. Repeat the same process for CA_SUNW_HW_2. */ + if (bestcapset->sc_hw_3 > symcapset->sc_hw_3) + return (0); + + if (bestcapset->sc_hw_3 < symcapset->sc_hw_3) + return (1); + if (bestcapset->sc_hw_2 > symcapset->sc_hw_2) return (0); diff --git a/usr/src/cmd/sgs/rtld/common/elf.c b/usr/src/cmd/sgs/rtld/common/elf.c index d1d5ae3c59..31e57eeedd 100644 --- a/usr/src/cmd/sgs/rtld/common/elf.c +++ b/usr/src/cmd/sgs/rtld/common/elf.c @@ -27,6 +27,7 @@ */ /* * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright 2022 Oxide Computer Company */ /* @@ -2312,6 +2313,9 @@ elf_new_lmp(Lm_list *lml, Aliste lmco, Fdesc *fdp, Addr addr, size_t msize, CAPSET(lmp).sc_mach = STRTAB(lmp) + cap->c_un.c_ptr; break; + case CA_SUNW_HW_3: + CAPSET(lmp).sc_hw_3 = cap->c_un.c_val; + break; } cap++; } diff --git a/usr/src/cmd/sgs/rtld/common/globals.c b/usr/src/cmd/sgs/rtld/common/globals.c index bb47b12540..3bf68a17da 100644 --- a/usr/src/cmd/sgs/rtld/common/globals.c +++ b/usr/src/cmd/sgs/rtld/common/globals.c @@ -24,6 +24,7 @@ * All Rights Reserved * * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Company */ #include <sys/types.h> @@ -232,9 +233,10 @@ ldd_reject[SGS_REJ_NUM] = { MSG_LDD_REJ_PLATCAP, /* MSG_INTL(MSG_LDD_REJ_PLATCAP) */ MSG_LDD_REJ_HWCAP_2, /* MSG_INTL(MSG_LDD_REJ_HWCAP_2) */ MSG_LDD_REJ_ARCHIVE, /* MSG_INTL(MSG_LDD_REJ_ARCHIVE) */ - MSG_LDD_REJ_KMOD /* MSG_INTL(MSG_LDD_REJ_KMOD) */ + MSG_LDD_REJ_KMOD, /* MSG_INTL(MSG_LDD_REJ_KMOD) */ + MSG_LDD_REJ_HWCAP_3 /* MSG_INTL(MSG_LDD_REJ_HWCAP_3) */ }; -#if SGS_REJ_NUM != (SGS_REJ_KMOD + 1) +#if SGS_REJ_NUM != (SGS_REJ_HWCAP_3 + 1) #error SGS_REJ_NUM has changed #endif @@ -260,8 +262,9 @@ err_reject[SGS_REJ_NUM] = { MSG_ERR_REJ_HWCAP_2, /* MSG_INTL(MSG_ERR_REJ_HWCAP_2) */ MSG_ERR_REJ_ARCHIVE, /* MSG_INTL(MSG_ERR_REJ_ARCHIVE) */ MSG_ERR_REJ_KMOD, /* MSG_INTL(MSG_ERR_REJ_KMOD) */ + MSG_ERR_REJ_HWCAP_3 /* MSG_INTL(MSG_ERR_REJ_HWCAP_3) */ }; -#if SGS_REJ_NUM != (SGS_REJ_KMOD + 1) +#if SGS_REJ_NUM != (SGS_REJ_HWCAP_3 + 1) #error SGS_REJ_NUM has changed #endif @@ -287,7 +290,8 @@ ldd_warn[SGS_REJ_NUM] = { MSG_LDD_WARN_HWCAP_2, /* MSG_INTL(MSG_LDD_WARN_HWCAP_2) */ MSG_STR_EMPTY, MSG_STR_EMPTY, + MSG_LDD_WARN_HWCAP_3 /* MSG_INTL(MSG_LDD_WARN_HWCAP_3) */ }; -#if SGS_REJ_NUM != (SGS_REJ_KMOD + 1) +#if SGS_REJ_NUM != (SGS_REJ_HWCAP_3 + 1) #error SGS_REJ_NUM has changed #endif diff --git a/usr/src/cmd/sgs/rtld/common/rtld.msg b/usr/src/cmd/sgs/rtld/common/rtld.msg index 7d0f45c9e0..f511806030 100644 --- a/usr/src/cmd/sgs/rtld/common/rtld.msg +++ b/usr/src/cmd/sgs/rtld/common/rtld.msg @@ -21,6 +21,7 @@ # # Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2022 Oxide Computer Company # @ _START_ @@ -193,6 +194,7 @@ @ MSG_LDD_REJ_MACHCAP " - machine capability (CA_SUNW_MACH) unsupported: %s" @ MSG_LDD_REJ_PLATCAP " - platform capability (CA_SUNW_PLAT) unsupported: %s" @ MSG_LDD_REJ_HWCAP_2 " - hardware capability (CA_SUNW_HW_2) unsupported: %s" +@ MSG_LDD_REJ_HWCAP_3 " - hardware capability (CA_SUNW_HW_3) unsupported: %s" @ MSG_LDD_REJ_ARCHIVE " - invalid archive use" @ MSG_LDD_REJ_KMOD " - invalid kernel module use" @@ -207,6 +209,8 @@ unsupported: %s\n" @ MSG_LDD_WARN_HWCAP_2 "%s: warning: hardware capability (CA_SUNW_HW_2) \ unsupported: %s\n" +@ MSG_LDD_WARN_HWCAP_3 "%s: warning: hardware capability (CA_SUNW_HW_3) \ + unsupported: %s\n" # Error rejection messages. @@ -229,6 +233,7 @@ @ MSG_ERR_REJ_HWCAP_2 "%s: hardware capability (CA_SUNW_HW_2) unsupported: %s" @ MSG_ERR_REJ_ARCHIVE "%s: invalid archive use" @ MSG_ERR_REJ_KMOD "%s: invalid kernel module use" +@ MSG_ERR_REJ_HWCAP_3 "%s: hardware capability (CA_SUNW_HW_3) unsupported: %s" # Error TLS failures diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c index 43a72fcd1e..1cbe41aa6b 100644 --- a/usr/src/cmd/sgs/rtld/common/setup.c +++ b/usr/src/cmd/sgs/rtld/common/setup.c @@ -29,6 +29,7 @@ */ /* * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright 2022 Oxide Computer Company */ /* @@ -407,6 +408,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, rtld_flags2 |= RT_FL2_HWCAP; org_scapset->sc_hw_1 = (Xword)hwcap[0]; org_scapset->sc_hw_2 = (Xword)hwcap[1]; + org_scapset->sc_hw_3 = (Xword)hwcap[2]; } /* diff --git a/usr/src/cmd/sgs/rtld/i386/_setup.c b/usr/src/cmd/sgs/rtld/i386/_setup.c index da208c45cd..aaa1bca08e 100644 --- a/usr/src/cmd/sgs/rtld/i386/_setup.c +++ b/usr/src/cmd/sgs/rtld/i386/_setup.c @@ -30,6 +30,7 @@ */ /* * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright 2022 Oxide Computer Company */ /* @@ -64,7 +65,7 @@ _setup(Boot *ebp, Dyn *ld_dyn) char *_rt_name, **_envp, **_argv; int _syspagsz = 0, fd = -1; uint_t _flags = 0; - uint_t hwcap[2] = { 0, 0 }; + uint_t hwcap[3] = { 0, 0, 0 }; Dyn *dyn_ptr; Phdr *phdr = NULL; Rt_map *lmp; @@ -159,6 +160,10 @@ _setup(Boot *ebp, Dyn *ld_dyn) /* hardware capabilities */ hwcap[1] = (uint_t)auxv->a_un.a_val; break; + case AT_SUN_HWCAP3: + /* hardware capabilities */ + hwcap[2] = (uint_t)auxv->a_un.a_val; + break; case AT_SUN_EMULATOR: /* name of emulation library, if any */ _emulator = auxv->a_un.a_ptr; diff --git a/usr/src/cmd/sgs/tools/SUNWonld-README b/usr/src/cmd/sgs/tools/SUNWonld-README index 288d18aafc..13f33502da 100644 --- a/usr/src/cmd/sgs/tools/SUNWonld-README +++ b/usr/src/cmd/sgs/tools/SUNWonld-README @@ -1691,3 +1691,4 @@ Bugid Risk Synopsis 14722 ld should keep group members in separate output sections 14770 ld(1) should be 64bit only 14901 remove remaining a.out support from sgs +14822 Need new word of hardware capabilities |