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
Dbg_cap_candidate(Lm_list * lml,const char * name)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
Dbg_cap_filter(Lm_list * lml,const char * dir,Rt_map * flmp)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
Dbg_cap_identical(Lm_list * lml,const char * file1,const char * file2)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
Dbg_cap_val(Lm_list * lml,Syscapset * sys,Syscapset * alt,Half mach)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
Dbg_cap_ptr_entry(Lm_list * lml,dbg_state_t dbg_state,Xword tag,const char * ptr)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
Dbg_cap_val_entry(Lm_list * lml,dbg_state_t dbg_state,Xword tag,Xword val,Half mach)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
Dbg_cap_sec_title(Lm_list * lml,const char * name)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
Dbg_cap_mapfile_title(Lm_list * lml,Lineno lineno)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
Dbg_cap_id(Lm_list * lml,Lineno lineno,const char * oid,const char * nid)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
Dbg_cap_post_title(Lm_list * lml,int * title)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
Elf_cap_title(Lm_list * lml)218 Elf_cap_title(Lm_list *lml)
219 {
220 dbg_print(lml, MSG_INTL(MSG_CAP_ELF_TITLE));
221 }
222
223 void
Elf_cap_entry(Lm_list * lml,Cap * cap,int ndx,const char * str,size_t str_size,Half mach)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