1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2022 Oxide Computer Company 25 */ 26 27 #include <stdio.h> 28 #include <debug.h> 29 #include <libld.h> 30 #include <conv.h> 31 #include "msg.h" 32 #include "_debug.h" 33 34 void 35 Dbg_cap_candidate(Lm_list *lml, const char *name) 36 { 37 if (DBG_NOTCLASS(DBG_C_CAP | DBG_C_FILES)) 38 return; 39 40 dbg_print(lml, MSG_INTL(MSG_CAP_CANDIDATE), name); 41 } 42 43 void 44 Dbg_cap_filter(Lm_list *lml, const char *dir, Rt_map *flmp) 45 { 46 if (DBG_NOTCLASS(DBG_C_CAP | DBG_C_FILES)) 47 return; 48 49 Dbg_util_nl(lml, DBG_NL_STD); 50 if (flmp) 51 dbg_print(lml, MSG_INTL(MSG_CAP_FILTER_1), dir, NAME(flmp)); 52 else 53 dbg_print(lml, MSG_INTL(MSG_CAP_FILTER_2), dir); 54 } 55 56 void 57 Dbg_cap_identical(Lm_list *lml, const char *file1, const char *file2) 58 { 59 if (DBG_NOTCLASS(DBG_C_CAP | DBG_C_FILES)) 60 return; 61 62 dbg_print(lml, MSG_INTL(MSG_CAP_IDENTICAL), file1, file2); 63 } 64 65 void 66 Dbg_cap_val(Lm_list *lml, Syscapset *sys, Syscapset *alt, Half mach) 67 { 68 Conv_cap_val_buf_t cap_val_buf; 69 70 if ((sys->sc_plat == NULL) && (sys->sc_mach == NULL) && 71 (sys->sc_hw_2 == 0) && (sys->sc_hw_1 == 0) && 72 (sys->sc_sf_1 == 0)) 73 return; 74 75 Dbg_util_nl(lml, DBG_NL_FRC); 76 77 /* 78 * Print any capabilities in precedence order. 79 */ 80 if (sys->sc_plat) { 81 dbg_print(lml, MSG_INTL(MSG_CAP_SYS_PLAT), sys->sc_plat); 82 } 83 if (sys->sc_mach) { 84 dbg_print(lml, MSG_INTL(MSG_CAP_SYS_MACH), sys->sc_mach); 85 } 86 if (sys->sc_hw_3) { 87 dbg_print(lml, MSG_INTL(MSG_CAP_SYS_HW_3), 88 conv_cap_val_hw3(sys->sc_hw_3, mach, 0, 89 &cap_val_buf.cap_val_hw3_buf)); 90 } 91 if (sys->sc_hw_2) { 92 dbg_print(lml, MSG_INTL(MSG_CAP_SYS_HW_2), 93 conv_cap_val_hw2(sys->sc_hw_2, mach, 0, 94 &cap_val_buf.cap_val_hw2_buf)); 95 } 96 if (sys->sc_hw_1) { 97 dbg_print(lml, MSG_INTL(MSG_CAP_SYS_HW_1), 98 conv_cap_val_hw1(sys->sc_hw_1, mach, 0, 99 &cap_val_buf.cap_val_hw1_buf)); 100 } 101 if (sys->sc_sf_1) { 102 dbg_print(lml, MSG_INTL(MSG_CAP_SYS_SF_1), 103 conv_cap_val_sf1(sys->sc_sf_1, mach, 0, 104 &cap_val_buf.cap_val_sf1_buf)); 105 } 106 107 if (alt != sys) { 108 Dbg_util_nl(lml, DBG_NL_FRC); 109 if (alt->sc_plat != sys->sc_plat) { 110 dbg_print(lml, MSG_INTL(MSG_CAP_ALT_PLAT), 111 alt->sc_plat); 112 } 113 if (alt->sc_mach != sys->sc_mach) { 114 dbg_print(lml, MSG_INTL(MSG_CAP_ALT_MACH), 115 alt->sc_mach); 116 } 117 if (alt->sc_hw_3 != sys->sc_hw_3) { 118 dbg_print(lml, MSG_INTL(MSG_CAP_ALT_HW_3), 119 conv_cap_val_hw3(alt->sc_hw_3, mach, 0, 120 &cap_val_buf.cap_val_hw3_buf)); 121 } 122 if (alt->sc_hw_2 != sys->sc_hw_2) { 123 dbg_print(lml, MSG_INTL(MSG_CAP_ALT_HW_2), 124 conv_cap_val_hw2(alt->sc_hw_2, mach, 0, 125 &cap_val_buf.cap_val_hw2_buf)); 126 } 127 if (alt->sc_hw_1 != sys->sc_hw_1) { 128 dbg_print(lml, MSG_INTL(MSG_CAP_ALT_HW_1), 129 conv_cap_val_hw1(alt->sc_hw_1, mach, 0, 130 &cap_val_buf.cap_val_hw1_buf)); 131 } 132 if (alt->sc_sf_1 != sys->sc_sf_1) { 133 dbg_print(lml, MSG_INTL(MSG_CAP_ALT_SF_1), 134 conv_cap_val_sf1(alt->sc_sf_1, mach, 0, 135 &cap_val_buf.cap_val_sf1_buf)); 136 } 137 } 138 139 Dbg_util_nl(lml, DBG_NL_FRC); 140 } 141 142 /* 143 * This version takes a pointer to a Capmask, and will report the exclusion 144 * bits if they exist. 145 */ 146 void 147 Dbg_cap_ptr_entry(Lm_list *lml, dbg_state_t dbg_state, Xword tag, 148 const char *ptr) 149 { 150 Conv_inv_buf_t inv_buf; 151 152 if (DBG_NOTCLASS(DBG_C_CAP)) 153 return; 154 155 dbg_print(lml, MSG_INTL(MSG_CAP_SEC_ENTRY), Dbg_state_str(dbg_state), 156 conv_cap_tag(tag, 0, &inv_buf), ptr); 157 } 158 159 /* 160 * This version takes a pointer to a CapMask, and will report the exclusion 161 * bits if they exist. 162 */ 163 void 164 Dbg_cap_val_entry(Lm_list *lml, dbg_state_t dbg_state, Xword tag, Xword val, 165 Half mach) 166 { 167 Conv_inv_buf_t inv_buf; 168 Conv_cap_val_buf_t cap_val_buf; 169 170 if (DBG_NOTCLASS(DBG_C_CAP)) 171 return; 172 173 dbg_print(lml, MSG_INTL(MSG_CAP_SEC_ENTRY), Dbg_state_str(dbg_state), 174 conv_cap_tag(tag, 0, &inv_buf), conv_cap_val(tag, val, mach, 0, 175 &cap_val_buf)); 176 } 177 178 void 179 Dbg_cap_sec_title(Lm_list *lml, const char *name) 180 { 181 if (DBG_NOTCLASS(DBG_C_CAP)) 182 return; 183 184 Dbg_util_nl(lml, DBG_NL_STD); 185 dbg_print(lml, MSG_INTL(MSG_CAP_SEC_TITLE), name); 186 } 187 188 void 189 Dbg_cap_mapfile_title(Lm_list *lml, Lineno lineno) 190 { 191 if (DBG_NOTCLASS(DBG_C_MAP | DBG_C_CAP)) 192 return; 193 194 dbg_print(lml, MSG_INTL(MSG_MAP_CAP), EC_LINENO(lineno)); 195 } 196 197 void 198 Dbg_cap_id(Lm_list *lml, Lineno lineno, const char *oid, const char *nid) 199 { 200 Dbg_cap_mapfile_title(lml, lineno); 201 Dbg_cap_ptr_entry(lml, DBG_STATE_CURRENT, CA_SUNW_ID, oid); 202 Dbg_cap_ptr_entry(lml, DBG_STATE_NEW, CA_SUNW_ID, nid); 203 Dbg_cap_ptr_entry(lml, DBG_STATE_RESOLVED, CA_SUNW_ID, nid); 204 } 205 206 void 207 Dbg_cap_post_title(Lm_list *lml, int *title) 208 { 209 if (DBG_NOTCLASS(DBG_C_CAP)) 210 return; 211 212 Dbg_util_nl(lml, DBG_NL_STD); 213 if ((*title)++ == 0) 214 dbg_print(lml, MSG_INTL(MSG_CAP_POST_TITLE)); 215 } 216 217 void 218 Elf_cap_title(Lm_list *lml) 219 { 220 dbg_print(lml, MSG_INTL(MSG_CAP_ELF_TITLE)); 221 } 222 223 void 224 Elf_cap_entry(Lm_list *lml, Cap *cap, int ndx, const char *str, size_t str_size, 225 Half mach) 226 { 227 Conv_inv_buf_t inv_buf; 228 Conv_cap_val_buf_t cap_val_buf; 229 char index[INDEX_STR_SIZE]; 230 231 (void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_FMT_INDEX), ndx); 232 233 switch (cap->c_tag) { 234 case CA_SUNW_PLAT: 235 case CA_SUNW_MACH: 236 case CA_SUNW_ID: 237 /* If offset is in range, format as a string */ 238 if (str && (cap->c_un.c_ptr < str_size)) { 239 str += cap->c_un.c_ptr; 240 break; 241 } 242 /*FALLTHROUGH*/ 243 default: 244 /* Format numerically */ 245 str = conv_cap_val(cap->c_tag, cap->c_un.c_val, mach, 0, 246 &cap_val_buf); 247 } 248 249 dbg_print(lml, MSG_INTL(MSG_CAP_ELF_ENTRY), index, 250 conv_cap_tag(cap->c_tag, 0, &inv_buf), str); 251 } 252