Print this page
10132 smatch fixes for MDB
Reviewed by: Andy Fiddaman <andy@omniosce.org>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/mdb/mdb_nm.c
+++ new/usr/src/cmd/mdb/common/mdb/mdb_nm.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 +/*
27 + * Copyright (c) 2018, Joyent, Inc.
28 + */
29 +
26 30 #include <sys/elf.h>
27 31 #include <sys/elf_SPARC.h>
28 32
29 33 #include <libproc.h>
30 34 #include <libctf.h>
31 35 #include <stdlib.h>
32 36 #include <string.h>
33 37 #include <fcntl.h>
34 38 #include <errno.h>
35 39
36 40 #include <mdb/mdb_string.h>
37 41 #include <mdb/mdb_argvec.h>
38 42 #include <mdb/mdb_nv.h>
39 43 #include <mdb/mdb_fmt.h>
40 44 #include <mdb/mdb_target.h>
41 45 #include <mdb/mdb_err.h>
42 46 #include <mdb/mdb_debug.h>
43 47 #include <mdb/mdb_conf.h>
44 48 #include <mdb/mdb_module.h>
45 49 #include <mdb/mdb_modapi.h>
46 50 #include <mdb/mdb_stdlib.h>
47 51 #include <mdb/mdb_lex.h>
48 52 #include <mdb/mdb_io_impl.h>
49 53 #include <mdb/mdb_help.h>
50 54 #include <mdb/mdb_disasm.h>
51 55 #include <mdb/mdb_frame.h>
52 56 #include <mdb/mdb_evset.h>
53 57 #include <mdb/mdb_print.h>
54 58 #include <mdb/mdb_nm.h>
55 59 #include <mdb/mdb_set.h>
56 60 #include <mdb/mdb_demangle.h>
57 61 #include <mdb/mdb.h>
58 62
59 63 enum {
60 64 NM_FMT_INDEX = 0x0001, /* -f ndx */
61 65 NM_FMT_VALUE = 0x0002, /* -f val */
62 66 NM_FMT_SIZE = 0x0004, /* -f size */
63 67 NM_FMT_TYPE = 0x0008, /* -f type */
64 68 NM_FMT_BIND = 0x0010, /* -f bind */
65 69 NM_FMT_OTHER = 0x0020, /* -f oth */
66 70 NM_FMT_SHNDX = 0x0040, /* -f shndx */
67 71 NM_FMT_NAME = 0x0080, /* -f name */
68 72 NM_FMT_CTYPE = 0x0100, /* -f ctype */
69 73 NM_FMT_OBJECT = 0x0200, /* -f obj */
70 74
71 75 NM_FMT_CTFID = 0x1000 /* -f ctfid */
72 76 };
73 77
74 78 enum {
75 79 NM_TYPE_NOTY = 1 << STT_NOTYPE, /* -t noty */
76 80 NM_TYPE_OBJT = 1 << STT_OBJECT, /* -t objt */
77 81 NM_TYPE_FUNC = 1 << STT_FUNC, /* -t func */
78 82 NM_TYPE_SECT = 1 << STT_SECTION, /* -t sect */
79 83 NM_TYPE_FILE = 1 << STT_FILE, /* -t file */
80 84 NM_TYPE_COMM = 1 << STT_COMMON, /* -t comm */
81 85 NM_TYPE_TLS = 1 << STT_TLS, /* -t tls */
82 86 NM_TYPE_REGI = 1 << STT_SPARC_REGISTER /* -t regi */
83 87 };
84 88
85 89 typedef struct {
86 90 GElf_Sym nm_sym;
87 91 const char *nm_name;
88 92 mdb_syminfo_t nm_si;
89 93 const char *nm_object;
90 94 ctf_file_t *nm_fp;
91 95 } nm_sym_t;
92 96
93 97 typedef struct {
94 98 ctf_file_t *nii_fp;
95 99
96 100 uint_t nii_flags;
97 101 uint_t nii_types;
98 102 ulong_t nii_id;
99 103 const char *nii_pfmt;
100 104 const char *nii_ofmt;
101 105
102 106 const GElf_Sym *nii_symp;
103 107
104 108 nm_sym_t **nii_sympp;
105 109 } nm_iter_info_t;
106 110
107 111 typedef struct {
108 112 mdb_tgt_sym_f *ngs_cb;
109 113 void *ngs_arg;
110 114 mdb_syminfo_t ngs_si;
111 115 const char *ngs_object;
112 116 } nm_gelf_symtab_t;
113 117
114 118 typedef struct {
115 119 uint_t noi_which;
116 120 uint_t noi_type;
117 121 mdb_tgt_sym_f *noi_cb;
118 122 nm_iter_info_t *noi_niip;
119 123 } nm_object_iter_t;
120 124
121 125 static const char *
122 126 nm_type2str(uchar_t info)
123 127 {
124 128 switch (GELF_ST_TYPE(info)) {
125 129 case STT_NOTYPE:
126 130 return ("NOTY");
127 131 case STT_OBJECT:
128 132 return ("OBJT");
129 133 case STT_FUNC:
130 134 return ("FUNC");
131 135 case STT_SECTION:
132 136 return ("SECT");
133 137 case STT_FILE:
134 138 return ("FILE");
135 139 case STT_COMMON:
136 140 return ("COMM");
137 141 case STT_TLS:
138 142 return ("TLS");
139 143 case STT_SPARC_REGISTER:
140 144 return ("REGI");
141 145 default:
142 146 return ("?");
143 147 }
144 148 }
145 149
146 150 static const char *
147 151 nm_bind2str(uchar_t info)
148 152 {
149 153 switch (GELF_ST_BIND(info)) {
150 154 case STB_LOCAL:
151 155 return ("LOCL");
152 156 case STB_GLOBAL:
153 157 return ("GLOB");
154 158 case STB_WEAK:
155 159 return ("WEAK");
156 160 default:
157 161 return ("?");
158 162 }
159 163 }
160 164
161 165 static const char *
162 166 nm_sect2str(GElf_Half shndx)
163 167 {
164 168 static char buf[16];
165 169
166 170 switch (shndx) {
167 171 case SHN_UNDEF:
168 172 return ("UNDEF");
169 173 case SHN_ABS:
170 174 return ("ABS");
171 175 case SHN_COMMON:
172 176 return ("COMMON");
173 177 default:
174 178 (void) mdb_iob_snprintf(buf, sizeof (buf), "%hu", shndx);
175 179 return (buf);
176 180 }
177 181 }
178 182
179 183 static char *
180 184 nm_func_signature(ctf_file_t *fp, uint_t index, char *buf, size_t len)
181 185 {
182 186 int n;
183 187 ctf_funcinfo_t f;
184 188 ctf_id_t argv[32];
185 189 char arg[32];
186 190 char *start = buf;
187 191 char *sep = "";
188 192 int i;
189 193
190 194 if (ctf_func_info(fp, index, &f) == CTF_ERR)
191 195 return (NULL);
192 196
193 197 if (ctf_type_name(fp, f.ctc_return, arg, sizeof (arg)) != NULL)
194 198 n = mdb_snprintf(buf, len, "%s (*)(", arg);
195 199 else
196 200 n = mdb_snprintf(buf, len, "<%ld> (*)(", f.ctc_return);
197 201
198 202 if (len <= n)
199 203 return (start);
200 204
201 205 buf += n;
202 206 len -= n;
203 207
204 208 (void) ctf_func_args(fp, index, sizeof (argv) / sizeof (argv[0]), argv);
205 209
206 210 for (i = 0; i < f.ctc_argc; i++) {
207 211 if (ctf_type_name(fp, argv[i], arg, sizeof (arg)) != NULL)
208 212 n = mdb_snprintf(buf, len, "%s%s", sep, arg);
209 213 else
210 214 n = mdb_snprintf(buf, len, "%s<%ld>", sep, argv[i]);
211 215
212 216 if (len <= n)
213 217 return (start);
214 218
215 219 buf += n;
216 220 len -= n;
217 221
218 222 sep = ", ";
219 223 }
220 224
221 225 if (f.ctc_flags & CTF_FUNC_VARARG) {
222 226 n = mdb_snprintf(buf, len, "%s...", sep);
223 227 if (len <= n)
224 228 return (start);
225 229 buf += n;
226 230 len -= n;
227 231 } else if (f.ctc_argc == 0) {
228 232 n = mdb_snprintf(buf, len, "void");
229 233 if (len <= n)
230 234 return (start);
231 235 buf += n;
232 236 len -= n;
233 237 }
234 238
235 239 (void) mdb_snprintf(buf, len, ")");
236 240
237 241 return (start);
238 242 }
239 243
240 244 static void
241 245 nm_print_ctype(void *data)
242 246 {
243 247 nm_iter_info_t *niip = data;
244 248 char buf[256];
245 249 ctf_id_t id;
246 250 char *str = NULL;
247 251 uint_t index = niip->nii_id;
248 252 ctf_file_t *fp = niip->nii_fp;
249 253
250 254 if (fp != NULL) {
251 255 if (GELF_ST_TYPE(niip->nii_symp->st_info) == STT_FUNC)
252 256 str = nm_func_signature(fp, index, buf, sizeof (buf));
253 257 else if ((id = ctf_lookup_by_symbol(fp, index)) != CTF_ERR)
254 258 str = ctf_type_name(fp, id, buf, sizeof (buf));
255 259 }
256 260
257 261 if (str == NULL)
258 262 str = "<unknown type>";
259 263
260 264 mdb_printf("%-50s", str);
261 265 }
262 266
263 267 static void
264 268 nm_print_ctfid(void *data)
265 269 {
266 270 nm_iter_info_t *niip = data;
267 271 ctf_id_t id;
268 272 uint_t index = niip->nii_id;
269 273 ctf_file_t *fp = niip->nii_fp;
270 274
271 275 if (fp != NULL && (id = ctf_lookup_by_symbol(fp, index)) != CTF_ERR) {
272 276 mdb_printf("%-9ld", id);
273 277 } else {
274 278 mdb_printf("%9s", "");
275 279 }
276 280 }
277 281
278 282 static void
279 283 nm_print_obj(void *data)
280 284 {
281 285 const char *obj = (const char *)data;
282 286
283 287 if (obj == MDB_TGT_OBJ_EXEC)
284 288 obj = "exec";
285 289 else if (obj == MDB_TGT_OBJ_RTLD)
286 290 obj = "rtld";
287 291 else if (obj == MDB_TGT_OBJ_EVERY)
288 292 obj = "";
289 293
290 294 mdb_printf("%-15s", obj);
291 295 }
292 296
293 297 /*ARGSUSED*/
294 298 static int
295 299 nm_print(void *data, const GElf_Sym *sym, const char *name,
296 300 const mdb_syminfo_t *sip, const char *obj)
297 301 {
298 302 nm_iter_info_t *niip = data;
299 303
300 304 if (!((1 << GELF_ST_TYPE(sym->st_info)) & niip->nii_types))
301 305 return (0);
302 306
303 307 niip->nii_id = sip->sym_id;
304 308 niip->nii_symp = sym;
305 309
306 310 mdb_table_print(niip->nii_flags, "|",
307 311 MDB_TBL_PRNT, NM_FMT_INDEX, "%5u", sip->sym_id,
308 312 MDB_TBL_FUNC, NM_FMT_OBJECT, nm_print_obj, obj,
309 313 MDB_TBL_PRNT, NM_FMT_VALUE, niip->nii_pfmt, sym->st_value,
310 314 MDB_TBL_PRNT, NM_FMT_SIZE, niip->nii_pfmt, sym->st_size,
311 315 MDB_TBL_PRNT, NM_FMT_TYPE, "%-5s", nm_type2str(sym->st_info),
312 316 MDB_TBL_PRNT, NM_FMT_BIND, "%-5s", nm_bind2str(sym->st_info),
313 317 MDB_TBL_PRNT, NM_FMT_OTHER, niip->nii_ofmt, sym->st_other,
314 318 MDB_TBL_PRNT, NM_FMT_SHNDX, "%-8s", nm_sect2str(sym->st_shndx),
315 319 MDB_TBL_FUNC, NM_FMT_CTFID, nm_print_ctfid, niip,
316 320 MDB_TBL_FUNC, NM_FMT_CTYPE, nm_print_ctype, niip,
317 321 MDB_TBL_PRNT, NM_FMT_NAME, "%s", name,
318 322 MDB_TBL_DONE);
319 323
320 324 mdb_printf("\n");
321 325
322 326 return (0);
323 327 }
324 328
325 329 /*ARGSUSED*/
326 330 static int
327 331 nm_any(void *data, const GElf_Sym *sym, const char *name,
328 332 const mdb_syminfo_t *sip, const char *obj)
329 333 {
330 334 return (nm_print(data, sym, name, sip, obj));
331 335 }
332 336
333 337 /*ARGSUSED*/
334 338 static int
335 339 nm_undef(void *data, const GElf_Sym *sym, const char *name,
336 340 const mdb_syminfo_t *sip, const char *obj)
337 341 {
338 342 if (sym->st_shndx == SHN_UNDEF)
339 343 return (nm_print(data, sym, name, sip, obj));
340 344
341 345 return (0);
342 346 }
343 347
344 348 /*ARGSUSED*/
345 349 static int
346 350 nm_asgn(void *data, const GElf_Sym *sym, const char *name,
347 351 const mdb_syminfo_t *sip, const char *obj)
348 352 {
349 353 const char *opts;
350 354
351 355 switch (GELF_ST_TYPE(sym->st_info)) {
352 356 case STT_FUNC:
353 357 opts = "-f";
354 358 break;
355 359 case STT_OBJECT:
356 360 opts = "-o";
357 361 break;
358 362 default:
359 363 opts = "";
360 364 }
361 365
362 366 mdb_printf("%#llr::nmadd %s -s %#llr %s\n",
363 367 sym->st_value, opts, sym->st_size, name);
364 368
365 369 return (0);
366 370 }
367 371
368 372 /*ARGSUSED*/
369 373 static int
370 374 nm_cnt_any(void *data, const GElf_Sym *sym, const char *name,
371 375 const mdb_syminfo_t *sip, const char *obj)
372 376 {
373 377 size_t *cntp = (size_t *)data;
374 378 (*cntp)++;
375 379 return (0);
376 380 }
377 381
378 382 /*ARGSUSED*/
379 383 static int
380 384 nm_cnt_undef(void *data, const GElf_Sym *sym, const char *name,
381 385 const mdb_syminfo_t *sip, const char *obj)
382 386 {
383 387 if (sym->st_shndx == SHN_UNDEF)
384 388 return (nm_cnt_any(data, sym, name, sip, obj));
385 389
386 390 return (0);
387 391 }
388 392
389 393 /*ARGSUSED*/
390 394 static int
391 395 nm_get_any(void *data, const GElf_Sym *sym, const char *name,
392 396 const mdb_syminfo_t *sip, const char *obj)
393 397 {
394 398 nm_iter_info_t *niip = data;
395 399 nm_sym_t **sympp = niip->nii_sympp;
396 400
397 401 (*sympp)->nm_sym = *sym;
398 402 (*sympp)->nm_name = name;
399 403 (*sympp)->nm_si = *sip;
400 404 (*sympp)->nm_object = obj;
401 405 (*sympp)->nm_fp = niip->nii_fp;
402 406 (*sympp)++;
403 407
404 408 return (0);
405 409 }
406 410
407 411 /*ARGSUSED*/
408 412 static int
409 413 nm_get_undef(void *data, const GElf_Sym *sym, const char *name,
410 414 const mdb_syminfo_t *sip, const char *obj)
411 415 {
412 416 if (sym->st_shndx == SHN_UNDEF)
413 417 return (nm_get_any(data, sym, name, sip, obj));
414 418
415 419 return (0);
416 420 }
417 421
418 422 static int
419 423 nm_compare_name(const void *lp, const void *rp)
420 424 {
421 425 const nm_sym_t *lhs = (nm_sym_t *)lp;
422 426 const nm_sym_t *rhs = (nm_sym_t *)rp;
423 427
424 428 return (strcmp(lhs->nm_name, rhs->nm_name));
425 429 }
426 430
427 431 static int
428 432 nm_compare_val(const void *lp, const void *rp)
429 433 {
430 434 const nm_sym_t *lhs = (nm_sym_t *)lp;
431 435 const nm_sym_t *rhs = (nm_sym_t *)rp;
432 436
433 437 return (lhs->nm_sym.st_value < rhs->nm_sym.st_value ? -1 :
434 438 (lhs->nm_sym.st_value > rhs->nm_sym.st_value ? 1 : 0));
435 439 }
436 440
437 441 static int
438 442 nm_gelf_symtab_cb(void *data, const GElf_Sym *symp, const char *name, uint_t id)
439 443 {
440 444 nm_gelf_symtab_t *ngsp = data;
441 445
442 446 ngsp->ngs_si.sym_id = id;
443 447
444 448 return (ngsp->ngs_cb(ngsp->ngs_arg, symp, name, &ngsp->ngs_si,
445 449 ngsp->ngs_object));
446 450 }
447 451
448 452 static void
449 453 nm_gelf_symtab_iter(mdb_gelf_symtab_t *gst, const char *object, uint_t table,
450 454 mdb_tgt_sym_f *cb, void *arg)
451 455 {
452 456 nm_gelf_symtab_t ngs;
453 457
454 458 ngs.ngs_cb = cb;
455 459 ngs.ngs_arg = arg;
456 460
457 461 ngs.ngs_si.sym_table = table;
458 462 ngs.ngs_object = object;
459 463
460 464 mdb_gelf_symtab_iter(gst, nm_gelf_symtab_cb, &ngs);
461 465 }
462 466
463 467 static int nm_symbol_iter(const char *, uint_t, uint_t, mdb_tgt_sym_f *,
464 468 nm_iter_info_t *);
465 469
466 470 /*ARGSUSED*/
467 471 static int
468 472 nm_object_iter_cb(void *data, const mdb_map_t *mp, const char *name)
469 473 {
470 474 nm_object_iter_t *noip = data;
471 475
472 476 /*
473 477 * Since we're interating over all the objects in a target,
474 478 * don't return an error if we hit an object that we can't
475 479 * get symbol data for.
476 480 */
477 481 if (nm_symbol_iter(name, noip->noi_which, noip->noi_type,
478 482 noip->noi_cb, noip->noi_niip) != 0)
479 483 mdb_warn("unable to dump symbol data for: %s\n", name);
480 484 return (0);
481 485 }
482 486
483 487 int
484 488 nm_symbol_iter(const char *object, uint_t which, uint_t type,
485 489 mdb_tgt_sym_f *cb, nm_iter_info_t *niip)
486 490 {
487 491 mdb_tgt_t *t = mdb.m_target;
488 492
489 493 if (object == MDB_TGT_OBJ_EVERY) {
490 494 nm_object_iter_t noi;
491 495
492 496 noi.noi_which = which;
493 497 noi.noi_type = type;
494 498 noi.noi_cb = cb;
495 499 noi.noi_niip = niip;
496 500
497 501 return (mdb_tgt_object_iter(t, nm_object_iter_cb, &noi));
498 502 }
499 503
500 504 niip->nii_fp = mdb_tgt_name_to_ctf(t, object);
501 505
502 506 return (mdb_tgt_symbol_iter(t, object, which, type, cb, niip));
503 507 }
504 508
505 509 /*ARGSUSED*/
506 510 int
507 511 cmd_nm(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
508 512 {
509 513 enum {
510 514 NM_DYNSYM = 0x0001, /* -D (use dynsym) */
511 515 NM_DEC = 0x0002, /* -d (decimal output) */
512 516 NM_GLOBAL = 0x0004, /* -g (globals only) */
513 517 NM_NOHDRS = 0x0008, /* -h (suppress header) */
514 518 NM_OCT = 0x0010, /* -o (octal output) */
515 519 NM_UNDEF = 0x0020, /* -u (undefs only) */
516 520 NM_HEX = 0x0040, /* -x (hex output) */
517 521 NM_SORT_NAME = 0x0080, /* -n (sort by name) */
518 522 NM_SORT_VALUE = 0x0100, /* -v (sort by value) */
519 523 NM_PRVSYM = 0x0200, /* -P (use private symtab) */
520 524 NM_PRTASGN = 0x0400 /* -p (print in asgn syntax) */
521 525 };
522 526
523 527 mdb_subopt_t opt_fmt_opts[] = {
524 528 { NM_FMT_INDEX, "ndx" },
525 529 { NM_FMT_VALUE, "val" },
526 530 { NM_FMT_SIZE, "sz" },
527 531 { NM_FMT_TYPE, "type" },
528 532 { NM_FMT_BIND, "bind" },
529 533 { NM_FMT_OTHER, "oth" },
530 534 { NM_FMT_SHNDX, "shndx" },
531 535 { NM_FMT_NAME, "name" },
532 536 { NM_FMT_CTYPE, "ctype" },
533 537 { NM_FMT_OBJECT, "obj" },
534 538 { NM_FMT_CTFID, "ctfid" },
535 539 { 0, NULL }
536 540 };
537 541
538 542 mdb_subopt_t opt_type_opts[] = {
539 543 { NM_TYPE_NOTY, "noty" },
540 544 { NM_TYPE_OBJT, "objt" },
541 545 { NM_TYPE_FUNC, "func" },
542 546 { NM_TYPE_SECT, "sect" },
543 547 { NM_TYPE_FILE, "file" },
544 548 { NM_TYPE_COMM, "comm" },
545 549 { NM_TYPE_TLS, "tls" },
546 550 { NM_TYPE_REGI, "regi" },
547 551 { 0, NULL }
548 552 };
549 553
550 554 uint_t optf = 0;
551 555 uint_t opt_fmt;
552 556 uint_t opt_types;
553 557 int i;
554 558
555 559 mdb_tgt_sym_f *callback;
556 560 uint_t which, type;
557 561
558 562 char *object = (char *)MDB_TGT_OBJ_EVERY;
559 563 int hwidth;
560 564 size_t nsyms = 0;
561 565
562 566 nm_sym_t *syms, *symp;
563 567
564 568 nm_iter_info_t nii;
565 569
566 570 /* default output columns */
567 571 opt_fmt = NM_FMT_VALUE | NM_FMT_SIZE | NM_FMT_TYPE | NM_FMT_BIND |
568 572 NM_FMT_OTHER | NM_FMT_SHNDX | NM_FMT_NAME;
569 573
570 574 /* default output types */
571 575 opt_types = NM_TYPE_NOTY | NM_TYPE_OBJT | NM_TYPE_FUNC | NM_TYPE_SECT |
572 576 NM_TYPE_FILE | NM_TYPE_COMM | NM_TYPE_TLS | NM_TYPE_REGI;
573 577
574 578 i = mdb_getopts(argc, argv,
575 579 'D', MDB_OPT_SETBITS, NM_DYNSYM, &optf,
576 580 'P', MDB_OPT_SETBITS, NM_PRVSYM, &optf,
577 581 'd', MDB_OPT_SETBITS, NM_DEC, &optf,
578 582 'g', MDB_OPT_SETBITS, NM_GLOBAL, &optf,
579 583 'h', MDB_OPT_SETBITS, NM_NOHDRS, &optf,
580 584 'n', MDB_OPT_SETBITS, NM_SORT_NAME, &optf,
581 585 'o', MDB_OPT_SETBITS, NM_OCT, &optf,
582 586 'p', MDB_OPT_SETBITS, NM_PRTASGN | NM_NOHDRS, &optf,
583 587 'u', MDB_OPT_SETBITS, NM_UNDEF, &optf,
584 588 'v', MDB_OPT_SETBITS, NM_SORT_VALUE, &optf,
585 589 'x', MDB_OPT_SETBITS, NM_HEX, &optf,
586 590 'f', MDB_OPT_SUBOPTS, opt_fmt_opts, &opt_fmt,
587 591 't', MDB_OPT_SUBOPTS, opt_type_opts, &opt_types,
588 592 NULL);
589 593
590 594 if (i != argc) {
591 595 if (flags & DCMD_ADDRSPEC)
592 596 return (DCMD_USAGE);
593 597
594 598 if (argc != 0 && (argc - i) == 1) {
595 599 if (argv[i].a_type != MDB_TYPE_STRING ||
596 600 argv[i].a_un.a_str[0] == '-')
597 601 return (DCMD_USAGE);
598 602 else
599 603 object = (char *)argv[i].a_un.a_str;
600 604 } else
601 605 return (DCMD_USAGE);
602 606 }
603 607
604 608 if ((optf & (NM_DEC | NM_HEX | NM_OCT)) == 0) {
605 609 switch (mdb.m_radix) {
606 610 case 8:
607 611 optf |= NM_OCT;
608 612 break;
609 613 case 10:
610 614 optf |= NM_DEC;
611 615 break;
612 616 default:
613 617 optf |= NM_HEX;
614 618 }
615 619 }
616 620
617 621 switch (optf & (NM_DEC | NM_HEX | NM_OCT)) {
618 622 case NM_DEC:
619 623 #ifdef _LP64
620 624 nii.nii_pfmt = "%-20llu";
621 625 nii.nii_ofmt = "%-5u";
622 626 hwidth = 20;
623 627 #else
624 628 nii.nii_pfmt = "%-10llu";
625 629 nii.nii_ofmt = "%-5u";
626 630 hwidth = 10;
627 631 #endif
628 632 break;
629 633 case NM_HEX:
630 634 #ifdef _LP64
631 635 nii.nii_pfmt = "0x%016llx";
632 636 nii.nii_ofmt = "0x%-3x";
633 637 hwidth = 18;
634 638 #else
635 639 nii.nii_pfmt = "0x%08llx";
636 640 nii.nii_ofmt = "0x%-3x";
637 641 hwidth = 10;
638 642 #endif
639 643 break;
640 644 case NM_OCT:
641 645 #ifdef _LP64
642 646 nii.nii_pfmt = "%-22llo";
643 647 nii.nii_ofmt = "%-5o";
644 648 hwidth = 22;
645 649 #else
646 650 nii.nii_pfmt = "%-11llo";
647 651 nii.nii_ofmt = "%-5o";
648 652 hwidth = 11;
649 653 #endif
650 654 break;
651 655 default:
652 656 mdb_warn("-d/-o/-x options are mutually exclusive\n");
653 657 return (DCMD_USAGE);
654 658 }
655 659
656 660 if (object != MDB_TGT_OBJ_EVERY && (optf & NM_PRVSYM)) {
657 661 mdb_warn("-P/object options are mutually exclusive\n");
658 662 return (DCMD_USAGE);
659 663 }
660 664
661 665 if ((flags & DCMD_ADDRSPEC) && (optf & NM_PRVSYM)) {
662 666 mdb_warn("-P/address options are mutually exclusive\n");
663 667 return (DCMD_USAGE);
664 668 }
665 669
666 670 if (!(optf & NM_NOHDRS)) {
667 671 mdb_printf("%<u>");
668 672 mdb_table_print(opt_fmt, " ",
669 673 MDB_TBL_PRNT, NM_FMT_INDEX, "Index",
670 674 MDB_TBL_PRNT, NM_FMT_OBJECT, "%-15s", "Object",
671 675 MDB_TBL_PRNT, NM_FMT_VALUE, "%-*s", hwidth, "Value",
672 676 MDB_TBL_PRNT, NM_FMT_SIZE, "%-*s", hwidth, "Size",
673 677 MDB_TBL_PRNT, NM_FMT_TYPE, "%-5s", "Type",
674 678 MDB_TBL_PRNT, NM_FMT_BIND, "%-5s", "Bind",
675 679 MDB_TBL_PRNT, NM_FMT_OTHER, "%-5s", "Other",
676 680 MDB_TBL_PRNT, NM_FMT_SHNDX, "%-8s", "Shndx",
677 681 MDB_TBL_PRNT, NM_FMT_CTFID, "%-9s", "CTF ID",
678 682 MDB_TBL_PRNT, NM_FMT_CTYPE, "%-50s", "C Type",
679 683 MDB_TBL_PRNT, NM_FMT_NAME, "%s", "Name",
680 684 MDB_TBL_DONE);
681 685
682 686 mdb_printf("%</u>\n");
683 687 }
684 688
685 689 nii.nii_flags = opt_fmt;
686 690 nii.nii_types = opt_types;
687 691
688 692 if (optf & NM_DYNSYM)
689 693 which = MDB_TGT_DYNSYM;
690 694 else
691 695 which = MDB_TGT_SYMTAB;
692 696
693 697 if (optf & NM_GLOBAL)
694 698 type = MDB_TGT_BIND_GLOBAL | MDB_TGT_TYPE_ANY;
695 699 else
696 700 type = MDB_TGT_BIND_ANY | MDB_TGT_TYPE_ANY;
697 701
698 702 if (flags & DCMD_ADDRSPEC)
699 703 optf |= NM_SORT_NAME; /* use sorting path if only one symbol */
700 704
701 705 if (optf & (NM_SORT_NAME | NM_SORT_VALUE)) {
702 706 char name[MDB_SYM_NAMLEN];
703 707 GElf_Sym sym;
704 708 mdb_syminfo_t si;
705 709
706 710 if (optf & NM_UNDEF)
707 711 callback = nm_cnt_undef;
708 712 else
709 713 callback = nm_cnt_any;
710 714
711 715 if (flags & DCMD_ADDRSPEC) {
712 716 const mdb_map_t *mp;
713 717 /* gather relevant data for the specified addr */
714 718
715 719 nii.nii_fp = mdb_tgt_addr_to_ctf(mdb.m_target, addr);
716 720
717 721 if (mdb_tgt_lookup_by_addr(mdb.m_target, addr,
718 722 MDB_SYM_FUZZY, name, sizeof (name), &sym,
719 723 &si) == -1) {
720 724 mdb_warn("%lr", addr);
721 725 return (DCMD_ERR);
722 726 }
723 727
724 728 if ((mp = mdb_tgt_addr_to_map(mdb.m_target, addr))
725 729 != NULL) {
726 730 object = mdb_alloc(strlen(mp->map_name) + 1,
727 731 UM_SLEEP | UM_GC);
728 732
729 733 (void) strcpy(object, mp->map_name);
730 734
731 735 /*
732 736 * Try to find a better match for the syminfo.
733 737 */
734 738 (void) mdb_tgt_lookup_by_name(mdb.m_target,
735 739 object, name, &sym, &si);
736 740 }
737 741
738 742 (void) callback(&nsyms, &sym, name, &si, object);
739 743
740 744 } else if (optf & NM_PRVSYM) {
741 745 nsyms = mdb_gelf_symtab_size(mdb.m_prsym);
742 746 } else {
743 747 (void) mdb_tgt_symbol_iter(mdb.m_target, object,
744 748 which, type, callback, &nsyms);
745 749 }
746 750
747 751 if (nsyms == 0)
748 752 return (DCMD_OK);
749 753
750 754 syms = symp = mdb_alloc(sizeof (nm_sym_t) * nsyms,
751 755 UM_SLEEP | UM_GC);
752 756
753 757 nii.nii_sympp = &symp;
754 758
755 759 if (optf & NM_UNDEF)
756 760 callback = nm_get_undef;
757 761 else
758 762 callback = nm_get_any;
759 763
760 764 if (flags & DCMD_ADDRSPEC) {
761 765 (void) callback(&nii, &sym, name, &si, object);
762 766 } else if (optf & NM_PRVSYM) {
763 767 nm_gelf_symtab_iter(mdb.m_prsym, object, MDB_TGT_PRVSYM,
764 768 callback, &nii);
765 769 } else if (nm_symbol_iter(object, which, type, callback,
766 770 &nii) == -1) {
767 771 mdb_warn("failed to iterate over symbols");
768 772 return (DCMD_ERR);
769 773 }
770 774
771 775 if (optf & NM_SORT_NAME)
772 776 qsort(syms, nsyms, sizeof (nm_sym_t), nm_compare_name);
773 777 else
774 778 qsort(syms, nsyms, sizeof (nm_sym_t), nm_compare_val);
775 779 }
776 780
777 781 if ((optf & (NM_PRVSYM | NM_PRTASGN)) == (NM_PRVSYM | NM_PRTASGN))
↓ open down ↓ |
742 lines elided |
↑ open up ↑ |
778 782 callback = nm_asgn;
779 783 else if (optf & NM_UNDEF)
780 784 callback = nm_undef;
781 785 else
782 786 callback = nm_any;
783 787
784 788 if (optf & (NM_SORT_NAME | NM_SORT_VALUE)) {
785 789 for (symp = syms; nsyms-- != 0; symp++) {
786 790 nii.nii_fp = symp->nm_fp;
787 791
788 - callback(&nii, &symp->nm_sym, symp->nm_name,
792 + (void) callback(&nii, &symp->nm_sym, symp->nm_name,
789 793 &symp->nm_si, symp->nm_object);
790 794 }
791 795
792 796 } else {
793 797 if (optf & NM_PRVSYM) {
794 798 nm_gelf_symtab_iter(mdb.m_prsym, object, MDB_TGT_PRVSYM,
795 799 callback, &nii);
796 800
797 801 } else if (nm_symbol_iter(object, which, type, callback, &nii)
798 802 == -1) {
799 803 mdb_warn("failed to iterate over symbols");
800 804 return (DCMD_ERR);
801 805 }
802 806 }
803 807
804 808 return (DCMD_OK);
805 809 }
806 810
807 811 int
808 812 cmd_nmadd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
809 813 {
810 814 uintptr_t opt_e = 0, opt_s = 0;
811 815 uint_t opt_f = FALSE, opt_o = FALSE;
812 816
813 817 GElf_Sym sym;
814 818 int i;
815 819
816 820 if (!(flags & DCMD_ADDRSPEC))
817 821 return (DCMD_USAGE);
818 822
819 823 i = mdb_getopts(argc, argv,
820 824 'f', MDB_OPT_SETBITS, TRUE, &opt_f,
821 825 'o', MDB_OPT_SETBITS, TRUE, &opt_o,
822 826 'e', MDB_OPT_UINTPTR, &opt_e,
823 827 's', MDB_OPT_UINTPTR, &opt_s, NULL);
824 828
825 829 if (i != (argc - 1) || argv[i].a_type != MDB_TYPE_STRING ||
826 830 argv[i].a_un.a_str[0] == '-' || argv[i].a_un.a_str[0] == '+')
827 831 return (DCMD_USAGE);
828 832
829 833 if (opt_e && opt_e < addr) {
830 834 mdb_warn("end (%p) is less than start address (%p)\n",
831 835 (void *)opt_e, (void *)addr);
832 836 return (DCMD_USAGE);
833 837 }
834 838
835 839 if (mdb_gelf_symtab_lookup_by_name(mdb.m_prsym,
836 840 argv[i].a_un.a_str, &sym, NULL) == -1) {
837 841 bzero(&sym, sizeof (sym));
838 842 sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
839 843 }
840 844
841 845 if (opt_f)
842 846 sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC);
843 847 if (opt_o)
844 848 sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
845 849 if (opt_e)
846 850 sym.st_size = (GElf_Xword)(opt_e - addr);
847 851 if (opt_s)
848 852 sym.st_size = (GElf_Xword)(opt_s);
849 853 sym.st_value = (GElf_Addr)addr;
850 854
851 855 mdb_gelf_symtab_insert(mdb.m_prsym, argv[i].a_un.a_str, &sym);
852 856
853 857 mdb_iob_printf(mdb.m_out, "added %s, value=%llr size=%llr\n",
854 858 argv[i].a_un.a_str, sym.st_value, sym.st_size);
855 859
856 860 return (DCMD_OK);
857 861 }
858 862
859 863 /*ARGSUSED*/
860 864 int
861 865 cmd_nmdel(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
862 866 {
863 867 const char *name;
864 868 GElf_Sym sym;
865 869 uint_t id;
866 870
867 871 if (argc != 1 || argv->a_type != MDB_TYPE_STRING ||
868 872 argv->a_un.a_str[0] == '-' || (flags & DCMD_ADDRSPEC))
869 873 return (DCMD_USAGE);
870 874
871 875 name = argv->a_un.a_str;
872 876
873 877 if (mdb_gelf_symtab_lookup_by_name(mdb.m_prsym, name, &sym, &id) == 0) {
874 878 mdb_gelf_symtab_delete(mdb.m_prsym, name, &sym);
875 879 mdb_printf("deleted %s, value=%llr size=%llr\n",
876 880 name, sym.st_value, sym.st_size);
877 881 return (DCMD_OK);
878 882 }
879 883
880 884 mdb_warn("symbol '%s' not found in private symbol table\n", name);
881 885 return (DCMD_ERR);
882 886 }
883 887
884 888 void
885 889 nm_help(void)
886 890 {
887 891 mdb_printf("-D print .dynsym instead of .symtab\n"
888 892 "-P print private symbol table instead of .symtab\n"
889 893 "-d print value and size in decimal\n"
890 894 "-g only print global symbols\n"
891 895 "-h suppress header line\n"
892 896 "-n sort symbols by name\n"
893 897 "-o print value and size in octal\n"
894 898 "-p print symbols as a series of ::nmadd commands\n"
895 899 "-u only print undefined symbols\n"
896 900 "-v sort symbols by value\n"
897 901 "-x print value and size in hexadecimal\n"
898 902 "-f format use specified format\n"
899 903 " ndx, val, sz, type, bind, oth, shndx, "
900 904 "name, ctype, obj\n"
901 905 "-t types display symbols with the specified types\n"
902 906 " noty, objt, func, sect, file, regi\n"
903 907 "obj specify object whose symbol table should be used\n");
904 908 }
905 909
906 910 void
907 911 nmadd_help(void)
908 912 {
909 913 mdb_printf("-f set type of symbol to STT_FUNC\n"
910 914 "-o set type of symbol to STT_OBJECT\n"
911 915 "-e end set size of symbol to end - start address\n"
912 916 "-s size set size of symbol to explicit value\n"
913 917 "name specify symbol name to add\n");
914 918 }
↓ open down ↓ |
116 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX