| 1 | /* DTrace probe support for GDB. |
| 2 | |
| 3 | Copyright (C) 2014-2016 Free Software Foundation, Inc. |
| 4 | |
| 5 | Contributed by Oracle, Inc. |
| 6 | |
| 7 | This file is part of GDB. |
| 8 | |
| 9 | This program is free software; you can redistribute it and/or modify |
| 10 | it under the terms of the GNU General Public License as published by |
| 11 | the Free Software Foundation; either version 3 of the License, or |
| 12 | (at your option) any later version. |
| 13 | |
| 14 | This program is distributed in the hope that it will be useful, |
| 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 | GNU General Public License for more details. |
| 18 | |
| 19 | You should have received a copy of the GNU General Public License |
| 20 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 21 | |
| 22 | #include "defs.h" |
| 23 | #include "probe.h" |
| 24 | #include "vec.h" |
| 25 | #include "elf-bfd.h" |
| 26 | #include "gdbtypes.h" |
| 27 | #include "obstack.h" |
| 28 | #include "objfiles.h" |
| 29 | #include "complaints.h" |
| 30 | #include "value.h" |
| 31 | #include "ax.h" |
| 32 | #include "ax-gdb.h" |
| 33 | #include "language.h" |
| 34 | #include "parser-defs.h" |
| 35 | #include "inferior.h" |
| 36 | |
| 37 | /* The type of the ELF sections where we will find the DOF programs |
| 38 | with information about probes. */ |
| 39 | |
| 40 | #ifndef SHT_SUNW_dof |
| 41 | # define SHT_SUNW_dof 0x6ffffff4 |
| 42 | #endif |
| 43 | |
| 44 | /* Forward declaration. */ |
| 45 | |
| 46 | extern const struct probe_ops dtrace_probe_ops; |
| 47 | |
| 48 | /* The following structure represents a single argument for the |
| 49 | probe. */ |
| 50 | |
| 51 | struct dtrace_probe_arg |
| 52 | { |
| 53 | /* The type of the probe argument. */ |
| 54 | struct type *type; |
| 55 | |
| 56 | /* A string describing the type. */ |
| 57 | char *type_str; |
| 58 | |
| 59 | /* The argument converted to an internal GDB expression. */ |
| 60 | struct expression *expr; |
| 61 | }; |
| 62 | |
| 63 | typedef struct dtrace_probe_arg dtrace_probe_arg_s; |
| 64 | DEF_VEC_O (dtrace_probe_arg_s); |
| 65 | |
| 66 | /* The following structure represents an enabler for a probe. */ |
| 67 | |
| 68 | struct dtrace_probe_enabler |
| 69 | { |
| 70 | /* Program counter where the is-enabled probe is installed. The |
| 71 | contents (nops, whatever...) stored at this address are |
| 72 | architecture dependent. */ |
| 73 | CORE_ADDR address; |
| 74 | }; |
| 75 | |
| 76 | typedef struct dtrace_probe_enabler dtrace_probe_enabler_s; |
| 77 | DEF_VEC_O (dtrace_probe_enabler_s); |
| 78 | |
| 79 | /* The following structure represents a dtrace probe. */ |
| 80 | |
| 81 | struct dtrace_probe |
| 82 | { |
| 83 | /* Generic information about the probe. This must be the first |
| 84 | element of this struct, in order to maintain binary compatibility |
| 85 | with the `struct probe' and be able to fully abstract it. */ |
| 86 | struct probe p; |
| 87 | |
| 88 | /* A probe can have zero or more arguments. */ |
| 89 | int probe_argc; |
| 90 | VEC (dtrace_probe_arg_s) *args; |
| 91 | |
| 92 | /* A probe can have zero or more "enablers" associated with it. */ |
| 93 | VEC (dtrace_probe_enabler_s) *enablers; |
| 94 | |
| 95 | /* Whether the expressions for the arguments have been built. */ |
| 96 | unsigned int args_expr_built : 1; |
| 97 | }; |
| 98 | |
| 99 | /* Implementation of the probe_is_linespec method. */ |
| 100 | |
| 101 | static int |
| 102 | dtrace_probe_is_linespec (const char **linespecp) |
| 103 | { |
| 104 | static const char *const keywords[] = { "-pdtrace", "-probe-dtrace", NULL }; |
| 105 | |
| 106 | return probe_is_linespec_by_keyword (linespecp, keywords); |
| 107 | } |
| 108 | |
| 109 | /* DOF programs can contain an arbitrary number of sections of 26 |
| 110 | different types. In order to support DTrace USDT probes we only |
| 111 | need to handle a subset of these section types, fortunately. These |
| 112 | section types are defined in the following enumeration. |
| 113 | |
| 114 | See linux/dtrace/dof_defines.h for a complete list of section types |
| 115 | along with their values. */ |
| 116 | |
| 117 | enum dtrace_dof_sect_type |
| 118 | { |
| 119 | /* Null section. */ |
| 120 | DTRACE_DOF_SECT_TYPE_NONE = 0, |
| 121 | /* A dof_ecbdesc_t. */ |
| 122 | DTRACE_DOF_SECT_TYPE_ECBDESC = 3, |
| 123 | /* A string table. */ |
| 124 | DTRACE_DOF_SECT_TYPE_STRTAB = 8, |
| 125 | /* A dof_provider_t */ |
| 126 | DTRACE_DOF_SECT_TYPE_PROVIDER = 15, |
| 127 | /* Array of dof_probe_t */ |
| 128 | DTRACE_DOF_SECT_TYPE_PROBES = 16, |
| 129 | /* An array of probe arg mappings. */ |
| 130 | DTRACE_DOF_SECT_TYPE_PRARGS = 17, |
| 131 | /* An array of probe arg offsets. */ |
| 132 | DTRACE_DOF_SECT_TYPE_PROFFS = 18, |
| 133 | /* An array of probe is-enabled offsets. */ |
| 134 | DTRACE_DOF_SECT_TYPE_PRENOFFS = 26 |
| 135 | }; |
| 136 | |
| 137 | /* The following collection of data structures map the structure of |
| 138 | DOF entities. Again, we only cover the subset of DOF used to |
| 139 | implement USDT probes. |
| 140 | |
| 141 | See linux/dtrace/dof.h header for a complete list of data |
| 142 | structures. */ |
| 143 | |
| 144 | /* Offsets to index the dofh_ident[] array defined below. */ |
| 145 | |
| 146 | enum dtrace_dof_ident |
| 147 | { |
| 148 | /* First byte of the magic number. */ |
| 149 | DTRACE_DOF_ID_MAG0 = 0, |
| 150 | /* Second byte of the magic number. */ |
| 151 | DTRACE_DOF_ID_MAG1 = 1, |
| 152 | /* Third byte of the magic number. */ |
| 153 | DTRACE_DOF_ID_MAG2 = 2, |
| 154 | /* Fourth byte of the magic number. */ |
| 155 | DTRACE_DOF_ID_MAG3 = 3, |
| 156 | /* An enum_dof_encoding value. */ |
| 157 | DTRACE_DOF_ID_ENCODING = 5 |
| 158 | }; |
| 159 | |
| 160 | /* Possible values for dofh_ident[DOF_ID_ENCODING]. */ |
| 161 | |
| 162 | enum dtrace_dof_encoding |
| 163 | { |
| 164 | /* The DOF program is little-endian. */ |
| 165 | DTRACE_DOF_ENCODE_LSB = 1, |
| 166 | /* The DOF program is big-endian. */ |
| 167 | DTRACE_DOF_ENCODE_MSB = 2 |
| 168 | }; |
| 169 | |
| 170 | /* A DOF header, which describes the contents of a DOF program: number |
| 171 | of sections, size, etc. */ |
| 172 | |
| 173 | struct dtrace_dof_hdr |
| 174 | { |
| 175 | /* Identification bytes (see above). */ |
| 176 | uint8_t dofh_ident[16]; |
| 177 | /* File attribute flags (if any). */ |
| 178 | uint32_t dofh_flags; |
| 179 | /* Size of file header in bytes. */ |
| 180 | uint32_t dofh_hdrsize; |
| 181 | /* Size of section header in bytes. */ |
| 182 | uint32_t dofh_secsize; |
| 183 | /* Number of section headers. */ |
| 184 | uint32_t dofh_secnum; |
| 185 | /* File offset of section headers. */ |
| 186 | uint64_t dofh_secoff; |
| 187 | /* File size of loadable portion. */ |
| 188 | uint64_t dofh_loadsz; |
| 189 | /* File size of entire DOF file. */ |
| 190 | uint64_t dofh_filesz; |
| 191 | /* Reserved for future use. */ |
| 192 | uint64_t dofh_pad; |
| 193 | }; |
| 194 | |
| 195 | /* A DOF section, whose contents depend on its type. The several |
| 196 | supported section types are described in the enum |
| 197 | dtrace_dof_sect_type above. */ |
| 198 | |
| 199 | struct dtrace_dof_sect |
| 200 | { |
| 201 | /* Section type (see the define above). */ |
| 202 | uint32_t dofs_type; |
| 203 | /* Section data memory alignment. */ |
| 204 | uint32_t dofs_align; |
| 205 | /* Section flags (if any). */ |
| 206 | uint32_t dofs_flags; |
| 207 | /* Size of section entry (if table). */ |
| 208 | uint32_t dofs_entsize; |
| 209 | /* DOF + offset points to the section data. */ |
| 210 | uint64_t dofs_offset; |
| 211 | /* Size of section data in bytes. */ |
| 212 | uint64_t dofs_size; |
| 213 | }; |
| 214 | |
| 215 | /* A DOF provider, which is the provider of a probe. */ |
| 216 | |
| 217 | struct dtrace_dof_provider |
| 218 | { |
| 219 | /* Link to a DTRACE_DOF_SECT_TYPE_STRTAB section. */ |
| 220 | uint32_t dofpv_strtab; |
| 221 | /* Link to a DTRACE_DOF_SECT_TYPE_PROBES section. */ |
| 222 | uint32_t dofpv_probes; |
| 223 | /* Link to a DTRACE_DOF_SECT_TYPE_PRARGS section. */ |
| 224 | uint32_t dofpv_prargs; |
| 225 | /* Link to a DTRACE_DOF_SECT_TYPE_PROFFS section. */ |
| 226 | uint32_t dofpv_proffs; |
| 227 | /* Provider name string. */ |
| 228 | uint32_t dofpv_name; |
| 229 | /* Provider attributes. */ |
| 230 | uint32_t dofpv_provattr; |
| 231 | /* Module attributes. */ |
| 232 | uint32_t dofpv_modattr; |
| 233 | /* Function attributes. */ |
| 234 | uint32_t dofpv_funcattr; |
| 235 | /* Name attributes. */ |
| 236 | uint32_t dofpv_nameattr; |
| 237 | /* Args attributes. */ |
| 238 | uint32_t dofpv_argsattr; |
| 239 | /* Link to a DTRACE_DOF_SECT_PRENOFFS section. */ |
| 240 | uint32_t dofpv_prenoffs; |
| 241 | }; |
| 242 | |
| 243 | /* A set of DOF probes and is-enabled probes sharing a base address |
| 244 | and several attributes. The particular locations and attributes of |
| 245 | each probe are maintained in arrays in several other DOF sections. |
| 246 | See the comment in dtrace_process_dof_probe for details on how |
| 247 | these attributes are stored. */ |
| 248 | |
| 249 | struct dtrace_dof_probe |
| 250 | { |
| 251 | /* Probe base address or offset. */ |
| 252 | uint64_t dofpr_addr; |
| 253 | /* Probe function string. */ |
| 254 | uint32_t dofpr_func; |
| 255 | /* Probe name string. */ |
| 256 | uint32_t dofpr_name; |
| 257 | /* Native argument type strings. */ |
| 258 | uint32_t dofpr_nargv; |
| 259 | /* Translated argument type strings. */ |
| 260 | uint32_t dofpr_xargv; |
| 261 | /* Index of first argument mapping. */ |
| 262 | uint32_t dofpr_argidx; |
| 263 | /* Index of first offset entry. */ |
| 264 | uint32_t dofpr_offidx; |
| 265 | /* Native argument count. */ |
| 266 | uint8_t dofpr_nargc; |
| 267 | /* Translated argument count. */ |
| 268 | uint8_t dofpr_xargc; |
| 269 | /* Number of offset entries for probe. */ |
| 270 | uint16_t dofpr_noffs; |
| 271 | /* Index of first is-enabled offset. */ |
| 272 | uint32_t dofpr_enoffidx; |
| 273 | /* Number of is-enabled offsets. */ |
| 274 | uint16_t dofpr_nenoffs; |
| 275 | /* Reserved for future use. */ |
| 276 | uint16_t dofpr_pad1; |
| 277 | /* Reserved for future use. */ |
| 278 | uint32_t dofpr_pad2; |
| 279 | }; |
| 280 | |
| 281 | /* DOF supports two different encodings: MSB (big-endian) and LSB |
| 282 | (little-endian). The encoding is itself encoded in the DOF header. |
| 283 | The following function returns an unsigned value in the host |
| 284 | endianness. */ |
| 285 | |
| 286 | #define DOF_UINT(dof, field) \ |
| 287 | extract_unsigned_integer ((gdb_byte *) &(field), \ |
| 288 | sizeof ((field)), \ |
| 289 | (((dof)->dofh_ident[DTRACE_DOF_ID_ENCODING] \ |
| 290 | == DTRACE_DOF_ENCODE_MSB) \ |
| 291 | ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE)) |
| 292 | |
| 293 | /* The following macro applies a given byte offset to a DOF (a pointer |
| 294 | to a dtrace_dof_hdr structure) and returns the resulting |
| 295 | address. */ |
| 296 | |
| 297 | #define DTRACE_DOF_PTR(dof, offset) (&((char *) (dof))[(offset)]) |
| 298 | |
| 299 | /* The following macro returns a pointer to the beginning of a given |
| 300 | section in a DOF object. The section is referred to by its index |
| 301 | in the sections array. */ |
| 302 | |
| 303 | #define DTRACE_DOF_SECT(dof, idx) \ |
| 304 | ((struct dtrace_dof_sect *) \ |
| 305 | DTRACE_DOF_PTR ((dof), \ |
| 306 | DOF_UINT ((dof), (dof)->dofh_secoff) \ |
| 307 | + ((idx) * DOF_UINT ((dof), (dof)->dofh_secsize)))) |
| 308 | |
| 309 | /* Helper function to examine the probe described by the given PROBE |
| 310 | and PROVIDER data structures and add it to the PROBESP vector. |
| 311 | STRTAB, OFFTAB, EOFFTAB and ARGTAB are pointers to tables in the |
| 312 | DOF program containing the attributes for the probe. */ |
| 313 | |
| 314 | static void |
| 315 | dtrace_process_dof_probe (struct objfile *objfile, |
| 316 | struct gdbarch *gdbarch, VEC (probe_p) **probesp, |
| 317 | struct dtrace_dof_hdr *dof, |
| 318 | struct dtrace_dof_probe *probe, |
| 319 | struct dtrace_dof_provider *provider, |
| 320 | char *strtab, char *offtab, char *eofftab, |
| 321 | char *argtab, uint64_t strtab_size) |
| 322 | { |
| 323 | int i, j, num_probes, num_enablers; |
| 324 | struct cleanup *cleanup; |
| 325 | VEC (dtrace_probe_enabler_s) *enablers; |
| 326 | char *p; |
| 327 | |
| 328 | /* Each probe section can define zero or more probes of two |
| 329 | different types: |
| 330 | |
| 331 | - probe->dofpr_noffs regular probes whose program counters are |
| 332 | stored in 32bit words starting at probe->dofpr_addr + |
| 333 | offtab[probe->dofpr_offidx]. |
| 334 | |
| 335 | - probe->dofpr_nenoffs is-enabled probes whose program counters |
| 336 | are stored in 32bit words starting at probe->dofpr_addr + |
| 337 | eofftab[probe->dofpr_enoffidx]. |
| 338 | |
| 339 | However is-enabled probes are not probes per-se, but an |
| 340 | optimization hack that is implemented in the kernel in a very |
| 341 | similar way than normal probes. This is how we support |
| 342 | is-enabled probes on GDB: |
| 343 | |
| 344 | - Our probes are always DTrace regular probes. |
| 345 | |
| 346 | - Our probes can be associated with zero or more "enablers". The |
| 347 | list of enablers is built from the is-enabled probes defined in |
| 348 | the Probe section. |
| 349 | |
| 350 | - Probes having a non-empty list of enablers can be enabled or |
| 351 | disabled using the `enable probe' and `disable probe' commands |
| 352 | respectively. The `Enabled' column in the output of `info |
| 353 | probes' will read `yes' if the enablers are activated, `no' |
| 354 | otherwise. |
| 355 | |
| 356 | - Probes having an empty list of enablers are always enabled. |
| 357 | The `Enabled' column in the output of `info probes' will |
| 358 | read `always'. |
| 359 | |
| 360 | It follows that if there are DTrace is-enabled probes defined for |
| 361 | some provider/name but no DTrace regular probes defined then the |
| 362 | GDB user wont be able to enable/disable these conditionals. */ |
| 363 | |
| 364 | num_probes = DOF_UINT (dof, probe->dofpr_noffs); |
| 365 | if (num_probes == 0) |
| 366 | return; |
| 367 | |
| 368 | /* Build the list of enablers for the probes defined in this Probe |
| 369 | DOF section. */ |
| 370 | enablers = NULL; |
| 371 | cleanup |
| 372 | = make_cleanup (VEC_cleanup (dtrace_probe_enabler_s), &enablers); |
| 373 | num_enablers = DOF_UINT (dof, probe->dofpr_nenoffs); |
| 374 | for (i = 0; i < num_enablers; i++) |
| 375 | { |
| 376 | struct dtrace_probe_enabler enabler; |
| 377 | uint32_t enabler_offset |
| 378 | = ((uint32_t *) eofftab)[DOF_UINT (dof, probe->dofpr_enoffidx) + i]; |
| 379 | |
| 380 | enabler.address = DOF_UINT (dof, probe->dofpr_addr) |
| 381 | + DOF_UINT (dof, enabler_offset); |
| 382 | VEC_safe_push (dtrace_probe_enabler_s, enablers, &enabler); |
| 383 | } |
| 384 | |
| 385 | for (i = 0; i < num_probes; i++) |
| 386 | { |
| 387 | uint32_t probe_offset |
| 388 | = ((uint32_t *) offtab)[DOF_UINT (dof, probe->dofpr_offidx) + i]; |
| 389 | struct dtrace_probe *ret = |
| 390 | XOBNEW (&objfile->per_bfd->storage_obstack, struct dtrace_probe); |
| 391 | |
| 392 | ret->p.pops = &dtrace_probe_ops; |
| 393 | ret->p.arch = gdbarch; |
| 394 | ret->args_expr_built = 0; |
| 395 | |
| 396 | /* Set the provider and the name of the probe. */ |
| 397 | ret->p.provider |
| 398 | = xstrdup (strtab + DOF_UINT (dof, provider->dofpv_name)); |
| 399 | ret->p.name = xstrdup (strtab + DOF_UINT (dof, probe->dofpr_name)); |
| 400 | |
| 401 | /* The probe address. */ |
| 402 | ret->p.address |
| 403 | = DOF_UINT (dof, probe->dofpr_addr) + DOF_UINT (dof, probe_offset); |
| 404 | |
| 405 | /* Number of arguments in the probe. */ |
| 406 | ret->probe_argc = DOF_UINT (dof, probe->dofpr_nargc); |
| 407 | |
| 408 | /* Store argument type descriptions. A description of the type |
| 409 | of the argument is in the (J+1)th null-terminated string |
| 410 | starting at 'strtab' + 'probe->dofpr_nargv'. */ |
| 411 | ret->args = NULL; |
| 412 | p = strtab + DOF_UINT (dof, probe->dofpr_nargv); |
| 413 | for (j = 0; j < ret->probe_argc; j++) |
| 414 | { |
| 415 | struct dtrace_probe_arg arg; |
| 416 | struct expression *expr = NULL; |
| 417 | |
| 418 | /* Set arg.expr to ensure all fields in expr are initialized and |
| 419 | the compiler will not warn when arg is used. */ |
| 420 | arg.expr = NULL; |
| 421 | arg.type_str = xstrdup (p); |
| 422 | |
| 423 | /* Use strtab_size as a sentinel. */ |
| 424 | while (*p++ != '\0' && p - strtab < strtab_size); |
| 425 | |
| 426 | /* Try to parse a type expression from the type string. If |
| 427 | this does not work then we set the type to `long |
| 428 | int'. */ |
| 429 | arg.type = builtin_type (gdbarch)->builtin_long; |
| 430 | |
| 431 | TRY |
| 432 | { |
| 433 | expr = parse_expression_with_language (arg.type_str, language_c); |
| 434 | } |
| 435 | CATCH (ex, RETURN_MASK_ERROR) |
| 436 | { |
| 437 | expr = NULL; |
| 438 | } |
| 439 | END_CATCH |
| 440 | |
| 441 | if (expr != NULL && expr->elts[0].opcode == OP_TYPE) |
| 442 | arg.type = expr->elts[1].type; |
| 443 | |
| 444 | VEC_safe_push (dtrace_probe_arg_s, ret->args, &arg); |
| 445 | } |
| 446 | |
| 447 | /* Add the vector of enablers to this probe, if any. */ |
| 448 | ret->enablers = VEC_copy (dtrace_probe_enabler_s, enablers); |
| 449 | |
| 450 | /* Successfully created probe. */ |
| 451 | VEC_safe_push (probe_p, *probesp, (struct probe *) ret); |
| 452 | } |
| 453 | |
| 454 | do_cleanups (cleanup); |
| 455 | } |
| 456 | |
| 457 | /* Helper function to collect the probes described in the DOF program |
| 458 | whose header is pointed by DOF and add them to the PROBESP vector. |
| 459 | SECT is the ELF section containing the DOF program and OBJFILE is |
| 460 | its containing object file. */ |
| 461 | |
| 462 | static void |
| 463 | dtrace_process_dof (asection *sect, struct objfile *objfile, |
| 464 | VEC (probe_p) **probesp, struct dtrace_dof_hdr *dof) |
| 465 | { |
| 466 | struct gdbarch *gdbarch = get_objfile_arch (objfile); |
| 467 | struct dtrace_dof_sect *section; |
| 468 | int i; |
| 469 | |
| 470 | /* The first step is to check for the DOF magic number. If no valid |
| 471 | DOF data is found in the section then a complaint is issued to |
| 472 | the user and the section skipped. */ |
| 473 | if (dof->dofh_ident[DTRACE_DOF_ID_MAG0] != 0x7F |
| 474 | || dof->dofh_ident[DTRACE_DOF_ID_MAG1] != 'D' |
| 475 | || dof->dofh_ident[DTRACE_DOF_ID_MAG2] != 'O' |
| 476 | || dof->dofh_ident[DTRACE_DOF_ID_MAG3] != 'F') |
| 477 | goto invalid_dof_data; |
| 478 | |
| 479 | /* Make sure the encoding mark is either DTRACE_DOF_ENCODE_LSB or |
| 480 | DTRACE_DOF_ENCODE_MSB. */ |
| 481 | if (dof->dofh_ident[DTRACE_DOF_ID_ENCODING] != DTRACE_DOF_ENCODE_LSB |
| 482 | && dof->dofh_ident[DTRACE_DOF_ID_ENCODING] != DTRACE_DOF_ENCODE_MSB) |
| 483 | goto invalid_dof_data; |
| 484 | |
| 485 | /* Make sure this DOF is not an enabling DOF, i.e. there are no ECB |
| 486 | Description sections. */ |
| 487 | section = (struct dtrace_dof_sect *) DTRACE_DOF_PTR (dof, |
| 488 | DOF_UINT (dof, dof->dofh_secoff)); |
| 489 | for (i = 0; i < DOF_UINT (dof, dof->dofh_secnum); i++, section++) |
| 490 | if (section->dofs_type == DTRACE_DOF_SECT_TYPE_ECBDESC) |
| 491 | return; |
| 492 | |
| 493 | /* Iterate over any section of type Provider and extract the probe |
| 494 | information from them. If there are no "provider" sections on |
| 495 | the DOF then we just return. */ |
| 496 | section = (struct dtrace_dof_sect *) DTRACE_DOF_PTR (dof, |
| 497 | DOF_UINT (dof, dof->dofh_secoff)); |
| 498 | for (i = 0; i < DOF_UINT (dof, dof->dofh_secnum); i++, section++) |
| 499 | if (DOF_UINT (dof, section->dofs_type) == DTRACE_DOF_SECT_TYPE_PROVIDER) |
| 500 | { |
| 501 | struct dtrace_dof_provider *provider = (struct dtrace_dof_provider *) |
| 502 | DTRACE_DOF_PTR (dof, DOF_UINT (dof, section->dofs_offset)); |
| 503 | struct dtrace_dof_sect *strtab_s |
| 504 | = DTRACE_DOF_SECT (dof, DOF_UINT (dof, provider->dofpv_strtab)); |
| 505 | struct dtrace_dof_sect *probes_s |
| 506 | = DTRACE_DOF_SECT (dof, DOF_UINT (dof, provider->dofpv_probes)); |
| 507 | struct dtrace_dof_sect *args_s |
| 508 | = DTRACE_DOF_SECT (dof, DOF_UINT (dof, provider->dofpv_prargs)); |
| 509 | struct dtrace_dof_sect *offsets_s |
| 510 | = DTRACE_DOF_SECT (dof, DOF_UINT (dof, provider->dofpv_proffs)); |
| 511 | struct dtrace_dof_sect *eoffsets_s |
| 512 | = DTRACE_DOF_SECT (dof, DOF_UINT (dof, provider->dofpv_prenoffs)); |
| 513 | char *strtab = DTRACE_DOF_PTR (dof, DOF_UINT (dof, strtab_s->dofs_offset)); |
| 514 | char *offtab = DTRACE_DOF_PTR (dof, DOF_UINT (dof, offsets_s->dofs_offset)); |
| 515 | char *eofftab = DTRACE_DOF_PTR (dof, DOF_UINT (dof, eoffsets_s->dofs_offset)); |
| 516 | char *argtab = DTRACE_DOF_PTR (dof, DOF_UINT (dof, args_s->dofs_offset)); |
| 517 | unsigned int entsize = DOF_UINT (dof, probes_s->dofs_entsize); |
| 518 | int num_probes; |
| 519 | |
| 520 | if (DOF_UINT (dof, section->dofs_size) |
| 521 | < sizeof (struct dtrace_dof_provider)) |
| 522 | { |
| 523 | /* The section is smaller than expected, so do not use it. |
| 524 | This has been observed on x86-solaris 10. */ |
| 525 | goto invalid_dof_data; |
| 526 | } |
| 527 | |
| 528 | /* Very, unlikely, but could crash gdb if not handled |
| 529 | properly. */ |
| 530 | if (entsize == 0) |
| 531 | goto invalid_dof_data; |
| 532 | |
| 533 | num_probes = DOF_UINT (dof, probes_s->dofs_size) / entsize; |
| 534 | |
| 535 | for (i = 0; i < num_probes; i++) |
| 536 | { |
| 537 | struct dtrace_dof_probe *probe = (struct dtrace_dof_probe *) |
| 538 | DTRACE_DOF_PTR (dof, DOF_UINT (dof, probes_s->dofs_offset) |
| 539 | + (i * DOF_UINT (dof, probes_s->dofs_entsize))); |
| 540 | |
| 541 | dtrace_process_dof_probe (objfile, |
| 542 | gdbarch, probesp, |
| 543 | dof, probe, |
| 544 | provider, strtab, offtab, eofftab, argtab, |
| 545 | DOF_UINT (dof, strtab_s->dofs_size)); |
| 546 | } |
| 547 | } |
| 548 | |
| 549 | return; |
| 550 | |
| 551 | invalid_dof_data: |
| 552 | complaint (&symfile_complaints, |
| 553 | _("skipping section '%s' which does not contain valid DOF data."), |
| 554 | sect->name); |
| 555 | } |
| 556 | |
| 557 | /* Helper function to build the GDB internal expressiosn that, once |
| 558 | evaluated, will calculate the values of the arguments of a given |
| 559 | PROBE. */ |
| 560 | |
| 561 | static void |
| 562 | dtrace_build_arg_exprs (struct dtrace_probe *probe, |
| 563 | struct gdbarch *gdbarch) |
| 564 | { |
| 565 | struct parser_state pstate; |
| 566 | struct dtrace_probe_arg *arg; |
| 567 | int i; |
| 568 | |
| 569 | probe->args_expr_built = 1; |
| 570 | |
| 571 | /* Iterate over the arguments in the probe and build the |
| 572 | corresponding GDB internal expression that will generate the |
| 573 | value of the argument when executed at the PC of the probe. */ |
| 574 | for (i = 0; i < probe->probe_argc; i++) |
| 575 | { |
| 576 | struct cleanup *back_to; |
| 577 | |
| 578 | arg = VEC_index (dtrace_probe_arg_s, probe->args, i); |
| 579 | |
| 580 | /* Initialize the expression buffer in the parser state. The |
| 581 | language does not matter, since we are using our own |
| 582 | parser. */ |
| 583 | initialize_expout (&pstate, 10, current_language, gdbarch); |
| 584 | back_to = make_cleanup (free_current_contents, &pstate.expout); |
| 585 | |
| 586 | /* The argument value, which is ABI dependent and casted to |
| 587 | `long int'. */ |
| 588 | gdbarch_dtrace_parse_probe_argument (gdbarch, &pstate, i); |
| 589 | |
| 590 | discard_cleanups (back_to); |
| 591 | |
| 592 | /* Casting to the expected type, but only if the type was |
| 593 | recognized at probe load time. Otherwise the argument will |
| 594 | be evaluated as the long integer passed to the probe. */ |
| 595 | if (arg->type != NULL) |
| 596 | { |
| 597 | write_exp_elt_opcode (&pstate, UNOP_CAST); |
| 598 | write_exp_elt_type (&pstate, arg->type); |
| 599 | write_exp_elt_opcode (&pstate, UNOP_CAST); |
| 600 | } |
| 601 | |
| 602 | reallocate_expout (&pstate); |
| 603 | arg->expr = pstate.expout; |
| 604 | prefixify_expression (arg->expr); |
| 605 | } |
| 606 | } |
| 607 | |
| 608 | /* Helper function to return the Nth argument of a given PROBE. */ |
| 609 | |
| 610 | static struct dtrace_probe_arg * |
| 611 | dtrace_get_arg (struct dtrace_probe *probe, unsigned n, |
| 612 | struct gdbarch *gdbarch) |
| 613 | { |
| 614 | if (!probe->args_expr_built) |
| 615 | dtrace_build_arg_exprs (probe, gdbarch); |
| 616 | |
| 617 | return VEC_index (dtrace_probe_arg_s, probe->args, n); |
| 618 | } |
| 619 | |
| 620 | /* Implementation of the get_probes method. */ |
| 621 | |
| 622 | static void |
| 623 | dtrace_get_probes (VEC (probe_p) **probesp, struct objfile *objfile) |
| 624 | { |
| 625 | bfd *abfd = objfile->obfd; |
| 626 | asection *sect = NULL; |
| 627 | |
| 628 | /* Do nothing in case this is a .debug file, instead of the objfile |
| 629 | itself. */ |
| 630 | if (objfile->separate_debug_objfile_backlink != NULL) |
| 631 | return; |
| 632 | |
| 633 | /* Iterate over the sections in OBJFILE looking for DTrace |
| 634 | information. */ |
| 635 | for (sect = abfd->sections; sect != NULL; sect = sect->next) |
| 636 | { |
| 637 | if (elf_section_data (sect)->this_hdr.sh_type == SHT_SUNW_dof) |
| 638 | { |
| 639 | bfd_byte *dof; |
| 640 | |
| 641 | /* Read the contents of the DOF section and then process it to |
| 642 | extract the information of any probe defined into it. */ |
| 643 | if (!bfd_malloc_and_get_section (abfd, sect, &dof)) |
| 644 | complaint (&symfile_complaints, |
| 645 | _("could not obtain the contents of" |
| 646 | "section '%s' in objfile `%s'."), |
| 647 | sect->name, abfd->filename); |
| 648 | |
| 649 | dtrace_process_dof (sect, objfile, probesp, |
| 650 | (struct dtrace_dof_hdr *) dof); |
| 651 | xfree (dof); |
| 652 | } |
| 653 | } |
| 654 | } |
| 655 | |
| 656 | /* Helper function to determine whether a given probe is "enabled" or |
| 657 | "disabled". A disabled probe is a probe in which one or more |
| 658 | enablers are disabled. */ |
| 659 | |
| 660 | static int |
| 661 | dtrace_probe_is_enabled (struct dtrace_probe *probe) |
| 662 | { |
| 663 | int i; |
| 664 | struct gdbarch *gdbarch = probe->p.arch; |
| 665 | struct dtrace_probe_enabler *enabler; |
| 666 | |
| 667 | for (i = 0; |
| 668 | VEC_iterate (dtrace_probe_enabler_s, probe->enablers, i, enabler); |
| 669 | i++) |
| 670 | if (!gdbarch_dtrace_probe_is_enabled (gdbarch, enabler->address)) |
| 671 | return 0; |
| 672 | |
| 673 | return 1; |
| 674 | } |
| 675 | |
| 676 | /* Implementation of the get_probe_address method. */ |
| 677 | |
| 678 | static CORE_ADDR |
| 679 | dtrace_get_probe_address (struct probe *probe, struct objfile *objfile) |
| 680 | { |
| 681 | gdb_assert (probe->pops == &dtrace_probe_ops); |
| 682 | return probe->address + ANOFFSET (objfile->section_offsets, |
| 683 | SECT_OFF_DATA (objfile)); |
| 684 | } |
| 685 | |
| 686 | /* Implementation of the get_probe_argument_count method. */ |
| 687 | |
| 688 | static unsigned |
| 689 | dtrace_get_probe_argument_count (struct probe *probe_generic, |
| 690 | struct frame_info *frame) |
| 691 | { |
| 692 | struct dtrace_probe *dtrace_probe = (struct dtrace_probe *) probe_generic; |
| 693 | |
| 694 | gdb_assert (probe_generic->pops == &dtrace_probe_ops); |
| 695 | |
| 696 | return dtrace_probe->probe_argc; |
| 697 | } |
| 698 | |
| 699 | /* Implementation of the can_evaluate_probe_arguments method. */ |
| 700 | |
| 701 | static int |
| 702 | dtrace_can_evaluate_probe_arguments (struct probe *probe_generic) |
| 703 | { |
| 704 | struct gdbarch *gdbarch = probe_generic->arch; |
| 705 | |
| 706 | gdb_assert (probe_generic->pops == &dtrace_probe_ops); |
| 707 | return gdbarch_dtrace_parse_probe_argument_p (gdbarch); |
| 708 | } |
| 709 | |
| 710 | /* Implementation of the evaluate_probe_argument method. */ |
| 711 | |
| 712 | static struct value * |
| 713 | dtrace_evaluate_probe_argument (struct probe *probe_generic, unsigned n, |
| 714 | struct frame_info *frame) |
| 715 | { |
| 716 | struct gdbarch *gdbarch = probe_generic->arch; |
| 717 | struct dtrace_probe *dtrace_probe = (struct dtrace_probe *) probe_generic; |
| 718 | struct dtrace_probe_arg *arg; |
| 719 | int pos = 0; |
| 720 | |
| 721 | gdb_assert (probe_generic->pops == &dtrace_probe_ops); |
| 722 | |
| 723 | arg = dtrace_get_arg (dtrace_probe, n, gdbarch); |
| 724 | return evaluate_subexp_standard (arg->type, arg->expr, &pos, EVAL_NORMAL); |
| 725 | } |
| 726 | |
| 727 | /* Implementation of the compile_to_ax method. */ |
| 728 | |
| 729 | static void |
| 730 | dtrace_compile_to_ax (struct probe *probe_generic, struct agent_expr *expr, |
| 731 | struct axs_value *value, unsigned n) |
| 732 | { |
| 733 | struct dtrace_probe *dtrace_probe = (struct dtrace_probe *) probe_generic; |
| 734 | struct dtrace_probe_arg *arg; |
| 735 | union exp_element *pc; |
| 736 | |
| 737 | gdb_assert (probe_generic->pops == &dtrace_probe_ops); |
| 738 | |
| 739 | arg = dtrace_get_arg (dtrace_probe, n, expr->gdbarch); |
| 740 | |
| 741 | pc = arg->expr->elts; |
| 742 | gen_expr (arg->expr, &pc, expr, value); |
| 743 | |
| 744 | require_rvalue (expr, value); |
| 745 | value->type = arg->type; |
| 746 | } |
| 747 | |
| 748 | /* Implementation of the probe_destroy method. */ |
| 749 | |
| 750 | static void |
| 751 | dtrace_probe_destroy (struct probe *probe_generic) |
| 752 | { |
| 753 | struct dtrace_probe *probe = (struct dtrace_probe *) probe_generic; |
| 754 | struct dtrace_probe_arg *arg; |
| 755 | int i; |
| 756 | |
| 757 | gdb_assert (probe_generic->pops == &dtrace_probe_ops); |
| 758 | |
| 759 | for (i = 0; VEC_iterate (dtrace_probe_arg_s, probe->args, i, arg); i++) |
| 760 | { |
| 761 | xfree (arg->type_str); |
| 762 | xfree (arg->expr); |
| 763 | } |
| 764 | |
| 765 | VEC_free (dtrace_probe_enabler_s, probe->enablers); |
| 766 | VEC_free (dtrace_probe_arg_s, probe->args); |
| 767 | } |
| 768 | |
| 769 | /* Implementation of the type_name method. */ |
| 770 | |
| 771 | static const char * |
| 772 | dtrace_type_name (struct probe *probe_generic) |
| 773 | { |
| 774 | gdb_assert (probe_generic->pops == &dtrace_probe_ops); |
| 775 | return "dtrace"; |
| 776 | } |
| 777 | |
| 778 | /* Implementation of the gen_info_probes_table_header method. */ |
| 779 | |
| 780 | static void |
| 781 | dtrace_gen_info_probes_table_header (VEC (info_probe_column_s) **heads) |
| 782 | { |
| 783 | info_probe_column_s dtrace_probe_column; |
| 784 | |
| 785 | dtrace_probe_column.field_name = "enabled"; |
| 786 | dtrace_probe_column.print_name = _("Enabled"); |
| 787 | |
| 788 | VEC_safe_push (info_probe_column_s, *heads, &dtrace_probe_column); |
| 789 | } |
| 790 | |
| 791 | /* Implementation of the gen_info_probes_table_values method. */ |
| 792 | |
| 793 | static void |
| 794 | dtrace_gen_info_probes_table_values (struct probe *probe_generic, |
| 795 | VEC (const_char_ptr) **ret) |
| 796 | { |
| 797 | struct dtrace_probe *probe = (struct dtrace_probe *) probe_generic; |
| 798 | const char *val = NULL; |
| 799 | |
| 800 | gdb_assert (probe_generic->pops == &dtrace_probe_ops); |
| 801 | |
| 802 | if (VEC_empty (dtrace_probe_enabler_s, probe->enablers)) |
| 803 | val = "always"; |
| 804 | else if (!gdbarch_dtrace_probe_is_enabled_p (probe_generic->arch)) |
| 805 | val = "unknown"; |
| 806 | else if (dtrace_probe_is_enabled (probe)) |
| 807 | val = "yes"; |
| 808 | else |
| 809 | val = "no"; |
| 810 | |
| 811 | VEC_safe_push (const_char_ptr, *ret, val); |
| 812 | } |
| 813 | |
| 814 | /* Implementation of the enable_probe method. */ |
| 815 | |
| 816 | static void |
| 817 | dtrace_enable_probe (struct probe *probe) |
| 818 | { |
| 819 | struct gdbarch *gdbarch = probe->arch; |
| 820 | struct dtrace_probe *dtrace_probe = (struct dtrace_probe *) probe; |
| 821 | struct dtrace_probe_enabler *enabler; |
| 822 | int i; |
| 823 | |
| 824 | gdb_assert (probe->pops == &dtrace_probe_ops); |
| 825 | |
| 826 | /* Enabling a dtrace probe implies patching the text section of the |
| 827 | running process, so make sure the inferior is indeed running. */ |
| 828 | if (ptid_equal (inferior_ptid, null_ptid)) |
| 829 | error (_("No inferior running")); |
| 830 | |
| 831 | /* Fast path. */ |
| 832 | if (dtrace_probe_is_enabled (dtrace_probe)) |
| 833 | return; |
| 834 | |
| 835 | /* Iterate over all defined enabler in the given probe and enable |
| 836 | them all using the corresponding gdbarch hook. */ |
| 837 | |
| 838 | for (i = 0; |
| 839 | VEC_iterate (dtrace_probe_enabler_s, dtrace_probe->enablers, i, enabler); |
| 840 | i++) |
| 841 | if (gdbarch_dtrace_enable_probe_p (gdbarch)) |
| 842 | gdbarch_dtrace_enable_probe (gdbarch, enabler->address); |
| 843 | } |
| 844 | |
| 845 | |
| 846 | /* Implementation of the disable_probe method. */ |
| 847 | |
| 848 | static void |
| 849 | dtrace_disable_probe (struct probe *probe) |
| 850 | { |
| 851 | struct gdbarch *gdbarch = probe->arch; |
| 852 | struct dtrace_probe *dtrace_probe = (struct dtrace_probe *) probe; |
| 853 | struct dtrace_probe_enabler *enabler; |
| 854 | int i; |
| 855 | |
| 856 | gdb_assert (probe->pops == &dtrace_probe_ops); |
| 857 | |
| 858 | /* Disabling a dtrace probe implies patching the text section of the |
| 859 | running process, so make sure the inferior is indeed running. */ |
| 860 | if (ptid_equal (inferior_ptid, null_ptid)) |
| 861 | error (_("No inferior running")); |
| 862 | |
| 863 | /* Fast path. */ |
| 864 | if (!dtrace_probe_is_enabled (dtrace_probe)) |
| 865 | return; |
| 866 | |
| 867 | /* Are we trying to disable a probe that does not have any enabler |
| 868 | associated? */ |
| 869 | if (VEC_empty (dtrace_probe_enabler_s, dtrace_probe->enablers)) |
| 870 | error (_("Probe %s:%s cannot be disabled: no enablers."), probe->provider, probe->name); |
| 871 | |
| 872 | /* Iterate over all defined enabler in the given probe and disable |
| 873 | them all using the corresponding gdbarch hook. */ |
| 874 | |
| 875 | for (i = 0; |
| 876 | VEC_iterate (dtrace_probe_enabler_s, dtrace_probe->enablers, i, enabler); |
| 877 | i++) |
| 878 | if (gdbarch_dtrace_disable_probe_p (gdbarch)) |
| 879 | gdbarch_dtrace_disable_probe (gdbarch, enabler->address); |
| 880 | } |
| 881 | |
| 882 | /* DTrace probe_ops. */ |
| 883 | |
| 884 | const struct probe_ops dtrace_probe_ops = |
| 885 | { |
| 886 | dtrace_probe_is_linespec, |
| 887 | dtrace_get_probes, |
| 888 | dtrace_get_probe_address, |
| 889 | dtrace_get_probe_argument_count, |
| 890 | dtrace_can_evaluate_probe_arguments, |
| 891 | dtrace_evaluate_probe_argument, |
| 892 | dtrace_compile_to_ax, |
| 893 | NULL, /* set_semaphore */ |
| 894 | NULL, /* clear_semaphore */ |
| 895 | dtrace_probe_destroy, |
| 896 | dtrace_type_name, |
| 897 | dtrace_gen_info_probes_table_header, |
| 898 | dtrace_gen_info_probes_table_values, |
| 899 | dtrace_enable_probe, |
| 900 | dtrace_disable_probe |
| 901 | }; |
| 902 | |
| 903 | /* Implementation of the `info probes dtrace' command. */ |
| 904 | |
| 905 | static void |
| 906 | info_probes_dtrace_command (char *arg, int from_tty) |
| 907 | { |
| 908 | info_probes_for_ops (arg, from_tty, &dtrace_probe_ops); |
| 909 | } |
| 910 | |
| 911 | void _initialize_dtrace_probe (void); |
| 912 | |
| 913 | void |
| 914 | _initialize_dtrace_probe (void) |
| 915 | { |
| 916 | VEC_safe_push (probe_ops_cp, all_probe_ops, &dtrace_probe_ops); |
| 917 | |
| 918 | add_cmd ("dtrace", class_info, info_probes_dtrace_command, |
| 919 | _("\ |
| 920 | Show information about DTrace static probes.\n\ |
| 921 | Usage: info probes dtrace [PROVIDER [NAME [OBJECT]]]\n\ |
| 922 | Each argument is a regular expression, used to select probes.\n\ |
| 923 | PROVIDER matches probe provider names.\n\ |
| 924 | NAME matches the probe names.\n\ |
| 925 | OBJECT matches the executable or shared library name."), |
| 926 | info_probes_cmdlist_get ()); |
| 927 | } |