1 1.1 christos /* prdbg.c -- Print out generic debugging information. 2 1.10 christos Copyright (C) 1995-2025 Free Software Foundation, Inc. 3 1.1 christos Written by Ian Lance Taylor <ian (at) cygnus.com>. 4 1.1 christos Tags style generation written by Salvador E. Tropea <set (at) computer.org>. 5 1.1 christos 6 1.1 christos This file is part of GNU Binutils. 7 1.1 christos 8 1.1 christos This program is free software; you can redistribute it and/or modify 9 1.1 christos it under the terms of the GNU General Public License as published by 10 1.1 christos the Free Software Foundation; either version 3 of the License, or 11 1.1 christos (at your option) any later version. 12 1.1 christos 13 1.1 christos This program is distributed in the hope that it will be useful, 14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 1.1 christos GNU General Public License for more details. 17 1.1 christos 18 1.1 christos You should have received a copy of the GNU General Public License 19 1.1 christos along with this program; if not, write to the Free Software 20 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 21 1.1 christos 02110-1301, USA. */ 22 1.1 christos 23 1.1 christos /* This file prints out the generic debugging information, by 24 1.1 christos supplying a set of routines to debug_write. */ 25 1.1 christos 26 1.1 christos #include "sysdep.h" 27 1.1 christos #include <assert.h> 28 1.1 christos #include "bfd.h" 29 1.1 christos #include "libiberty.h" 30 1.1 christos #include "demangle.h" 31 1.1 christos #include "debug.h" 32 1.1 christos #include "budbg.h" 33 1.1 christos 34 1.1 christos /* This is the structure we use as a handle for these routines. */ 35 1.1 christos 36 1.1 christos struct pr_handle 37 1.1 christos { 38 1.1 christos /* File to print information to. */ 39 1.1 christos FILE *f; 40 1.1 christos /* Current indentation level. */ 41 1.1 christos unsigned int indent; 42 1.1 christos /* Type stack. */ 43 1.1 christos struct pr_stack *stack; 44 1.1 christos /* Parameter number we are about to output. */ 45 1.1 christos int parameter; 46 1.1 christos /* The following are used only by the tags code (tg_). */ 47 1.1 christos /* Name of the file we are using. */ 48 1.1 christos char *filename; 49 1.1 christos /* The BFD. */ 50 1.1 christos bfd *abfd; 51 1.1 christos /* The symbols table for this BFD. */ 52 1.1 christos asymbol **syms; 53 1.1 christos /* Pointer to a function to demangle symbols. */ 54 1.1 christos char *(*demangler) (bfd *, const char *, int); 55 1.1 christos }; 56 1.1 christos 57 1.1 christos /* The type stack. */ 58 1.1 christos 59 1.1 christos struct pr_stack 60 1.1 christos { 61 1.1 christos /* Next element on the stack. */ 62 1.1 christos struct pr_stack *next; 63 1.1 christos /* This element. */ 64 1.1 christos char *type; 65 1.1 christos /* Current visibility of fields if this is a class. */ 66 1.1 christos enum debug_visibility visibility; 67 1.1 christos /* Name of the current method we are handling. */ 68 1.9 christos char *method; 69 1.1 christos /* The following are used only by the tags code (tg_). */ 70 1.1 christos /* Type for the container (struct, union, class, union class). */ 71 1.1 christos const char *flavor; 72 1.1 christos /* A comma separated list of parent classes. */ 73 1.1 christos char *parents; 74 1.1 christos }; 75 1.1 christos 76 1.8 christos static bool pr_start_compilation_unit (void *, const char *); 77 1.8 christos static bool pr_start_source (void *, const char *); 78 1.8 christos static bool pr_empty_type (void *); 79 1.8 christos static bool pr_void_type (void *); 80 1.8 christos static bool pr_int_type (void *, unsigned int, bool); 81 1.8 christos static bool pr_float_type (void *, unsigned int); 82 1.8 christos static bool pr_complex_type (void *, unsigned int); 83 1.8 christos static bool pr_bool_type (void *, unsigned int); 84 1.8 christos static bool pr_enum_type 85 1.1 christos (void *, const char *, const char **, bfd_signed_vma *); 86 1.8 christos static bool pr_pointer_type (void *); 87 1.8 christos static bool pr_function_type (void *, int, bool); 88 1.8 christos static bool pr_reference_type (void *); 89 1.8 christos static bool pr_range_type (void *, bfd_signed_vma, bfd_signed_vma); 90 1.8 christos static bool pr_array_type (void *, bfd_signed_vma, bfd_signed_vma, bool); 91 1.8 christos static bool pr_set_type (void *, bool); 92 1.8 christos static bool pr_offset_type (void *); 93 1.8 christos static bool pr_method_type (void *, bool, int, bool); 94 1.8 christos static bool pr_const_type (void *); 95 1.8 christos static bool pr_volatile_type (void *); 96 1.8 christos static bool pr_start_struct_type 97 1.8 christos (void *, const char *, unsigned int, bool, unsigned int); 98 1.8 christos static bool pr_struct_field 99 1.1 christos (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); 100 1.8 christos static bool pr_end_struct_type (void *); 101 1.8 christos static bool pr_start_class_type 102 1.8 christos (void *, const char *, unsigned int, bool, unsigned int, bool, bool); 103 1.8 christos static bool pr_class_static_member 104 1.1 christos (void *, const char *, const char *, enum debug_visibility); 105 1.8 christos static bool pr_class_baseclass 106 1.8 christos (void *, bfd_vma, bool, enum debug_visibility); 107 1.8 christos static bool pr_class_start_method (void *, const char *); 108 1.8 christos static bool pr_class_method_variant 109 1.8 christos (void *, const char *, enum debug_visibility, bool, bool, bfd_vma, bool); 110 1.8 christos static bool pr_class_static_method_variant 111 1.8 christos (void *, const char *, enum debug_visibility, bool, bool); 112 1.8 christos static bool pr_class_end_method (void *); 113 1.8 christos static bool pr_end_class_type (void *); 114 1.8 christos static bool pr_typedef_type (void *, const char *); 115 1.8 christos static bool pr_tag_type 116 1.1 christos (void *, const char *, unsigned int, enum debug_type_kind); 117 1.8 christos static bool pr_typdef (void *, const char *); 118 1.8 christos static bool pr_tag (void *, const char *); 119 1.8 christos static bool pr_int_constant (void *, const char *, bfd_vma); 120 1.8 christos static bool pr_float_constant (void *, const char *, double); 121 1.8 christos static bool pr_typed_constant (void *, const char *, bfd_vma); 122 1.8 christos static bool pr_variable (void *, const char *, enum debug_var_kind, bfd_vma); 123 1.8 christos static bool pr_start_function (void *, const char *, bool); 124 1.8 christos static bool pr_function_parameter 125 1.1 christos (void *, const char *, enum debug_parm_kind, bfd_vma); 126 1.8 christos static bool pr_start_block (void *, bfd_vma); 127 1.8 christos static bool pr_end_block (void *, bfd_vma); 128 1.8 christos static bool pr_end_function (void *); 129 1.8 christos static bool pr_lineno (void *, const char *, unsigned long, bfd_vma); 130 1.9 christos 131 1.1 christos static const char *visibility_name (enum debug_visibility); 132 1.9 christos 133 1.1 christos /* Tags style replacements. */ 134 1.8 christos static bool tg_start_compilation_unit (void *, const char *); 135 1.8 christos static bool tg_start_source (void *, const char *); 136 1.8 christos static bool tg_enum_type 137 1.1 christos (void *, const char *, const char **, bfd_signed_vma *); 138 1.8 christos static bool tg_start_struct_type 139 1.8 christos (void *, const char *, unsigned int, bool, unsigned int); 140 1.8 christos static bool pr_struct_field 141 1.1 christos (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); 142 1.8 christos static bool tg_struct_field 143 1.1 christos (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); 144 1.8 christos static bool tg_struct_field 145 1.1 christos (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); 146 1.8 christos static bool tg_end_struct_type (void *); 147 1.8 christos static bool tg_start_class_type 148 1.8 christos (void *, const char *, unsigned int, bool, unsigned int, bool, bool); 149 1.8 christos static bool tg_class_static_member 150 1.1 christos (void *, const char *, const char *, enum debug_visibility); 151 1.8 christos static bool tg_class_baseclass (void *, bfd_vma, bool, enum debug_visibility); 152 1.8 christos static bool tg_class_method_variant 153 1.8 christos (void *, const char *, enum debug_visibility, bool, bool, bfd_vma, bool); 154 1.8 christos static bool tg_class_static_method_variant 155 1.8 christos (void *, const char *, enum debug_visibility, bool, bool); 156 1.8 christos static bool tg_end_class_type (void *); 157 1.8 christos static bool tg_tag_type 158 1.1 christos (void *, const char *, unsigned int, enum debug_type_kind); 159 1.8 christos static bool tg_typdef (void *, const char *); 160 1.8 christos static bool tg_tag (void *, const char *); 161 1.8 christos static bool tg_int_constant (void *, const char *, bfd_vma); 162 1.8 christos static bool tg_float_constant (void *, const char *, double); 163 1.8 christos static bool tg_typed_constant (void *, const char *, bfd_vma); 164 1.8 christos static bool tg_variable (void *, const char *, enum debug_var_kind, bfd_vma); 165 1.8 christos static bool tg_start_function (void *, const char *, bool); 166 1.8 christos static bool tg_function_parameter 167 1.1 christos (void *, const char *, enum debug_parm_kind, bfd_vma); 168 1.8 christos static bool tg_start_block (void *, bfd_vma); 169 1.8 christos static bool tg_end_block (void *, bfd_vma); 170 1.8 christos static bool tg_lineno (void *, const char *, unsigned long, bfd_vma); 171 1.1 christos 172 1.1 christos static const struct debug_write_fns pr_fns = 174 1.1 christos { 175 1.1 christos pr_start_compilation_unit, 176 1.1 christos pr_start_source, 177 1.1 christos pr_empty_type, 178 1.1 christos pr_void_type, 179 1.1 christos pr_int_type, 180 1.1 christos pr_float_type, 181 1.1 christos pr_complex_type, 182 1.1 christos pr_bool_type, 183 1.1 christos pr_enum_type, 184 1.1 christos pr_pointer_type, 185 1.1 christos pr_function_type, 186 1.1 christos pr_reference_type, 187 1.1 christos pr_range_type, 188 1.1 christos pr_array_type, 189 1.1 christos pr_set_type, 190 1.1 christos pr_offset_type, 191 1.1 christos pr_method_type, 192 1.1 christos pr_const_type, 193 1.1 christos pr_volatile_type, 194 1.1 christos pr_start_struct_type, 195 1.1 christos pr_struct_field, 196 1.1 christos pr_end_struct_type, 197 1.1 christos pr_start_class_type, 198 1.1 christos pr_class_static_member, 199 1.1 christos pr_class_baseclass, 200 1.1 christos pr_class_start_method, 201 1.1 christos pr_class_method_variant, 202 1.1 christos pr_class_static_method_variant, 203 1.1 christos pr_class_end_method, 204 1.1 christos pr_end_class_type, 205 1.1 christos pr_typedef_type, 206 1.1 christos pr_tag_type, 207 1.1 christos pr_typdef, 208 1.1 christos pr_tag, 209 1.1 christos pr_int_constant, 210 1.1 christos pr_float_constant, 211 1.1 christos pr_typed_constant, 212 1.1 christos pr_variable, 213 1.1 christos pr_start_function, 214 1.1 christos pr_function_parameter, 215 1.1 christos pr_start_block, 216 1.1 christos pr_end_block, 217 1.1 christos pr_end_function, 218 1.1 christos pr_lineno 219 1.1 christos }; 220 1.1 christos 221 1.1 christos static const struct debug_write_fns tg_fns = 223 1.1 christos { 224 1.1 christos tg_start_compilation_unit, 225 1.1 christos tg_start_source, 226 1.1 christos pr_empty_type, /* Same, push_type. */ 227 1.1 christos pr_void_type, /* Same, push_type. */ 228 1.1 christos pr_int_type, /* Same, push_type. */ 229 1.1 christos pr_float_type, /* Same, push_type. */ 230 1.1 christos pr_complex_type, /* Same, push_type. */ 231 1.1 christos pr_bool_type, /* Same, push_type. */ 232 1.1 christos tg_enum_type, 233 1.1 christos pr_pointer_type, /* Same, changes to pointer. */ 234 1.1 christos pr_function_type, /* Same, push_type. */ 235 1.1 christos pr_reference_type, /* Same, changes to reference. */ 236 1.1 christos pr_range_type, /* FIXME: What's that?. */ 237 1.1 christos pr_array_type, /* Same, push_type. */ 238 1.1 christos pr_set_type, /* FIXME: What's that?. */ 239 1.1 christos pr_offset_type, /* FIXME: What's that?. */ 240 1.1 christos pr_method_type, /* Same. */ 241 1.1 christos pr_const_type, /* Same, changes to const. */ 242 1.1 christos pr_volatile_type, /* Same, changes to volatile. */ 243 1.1 christos tg_start_struct_type, 244 1.1 christos tg_struct_field, 245 1.1 christos tg_end_struct_type, 246 1.1 christos tg_start_class_type, 247 1.1 christos tg_class_static_member, 248 1.1 christos tg_class_baseclass, 249 1.1 christos pr_class_start_method, /* Same, remembers that's a method. */ 250 1.1 christos tg_class_method_variant, 251 1.1 christos tg_class_static_method_variant, 252 1.1 christos pr_class_end_method, /* Same, forgets that's a method. */ 253 1.1 christos tg_end_class_type, 254 1.1 christos pr_typedef_type, /* Same, just push type. */ 255 1.1 christos tg_tag_type, 256 1.1 christos tg_typdef, 257 1.1 christos tg_tag, 258 1.1 christos tg_int_constant, /* Untested. */ 259 1.1 christos tg_float_constant, /* Untested. */ 260 1.1 christos tg_typed_constant, /* Untested. */ 261 1.1 christos tg_variable, 262 1.1 christos tg_start_function, 263 1.1 christos tg_function_parameter, 264 1.1 christos tg_start_block, 265 1.1 christos tg_end_block, 266 1.1 christos pr_end_function, /* Same, does nothing. */ 267 1.7 christos tg_lineno 268 1.7 christos }; 269 1.1 christos 270 1.1 christos static int demangle_flags = DMGL_ANSI | DMGL_PARAMS; 271 1.1 christos 272 1.8 christos /* Print out the generic debugging information recorded in dhandle. */ 274 1.3 christos 275 1.8 christos bool 276 1.1 christos print_debugging_info (FILE *f, void *dhandle, bfd *abfd, asymbol **syms, 277 1.1 christos char * (*demangler) (struct bfd *, const char *, int), 278 1.1 christos bool as_tags) 279 1.1 christos { 280 1.1 christos struct pr_handle info; 281 1.1 christos 282 1.1 christos info.f = f; 283 1.1 christos info.indent = 0; 284 1.1 christos info.stack = NULL; 285 1.1 christos info.parameter = 0; 286 1.3 christos info.filename = NULL; 287 1.1 christos info.abfd = abfd; 288 1.1 christos info.syms = syms; 289 1.1 christos info.demangler = demangler; 290 1.1 christos 291 1.1 christos if (as_tags) 292 1.1 christos { 293 1.1 christos fputs ("!_TAG_FILE_FORMAT\t2\t/extended format/\n", f); 294 1.1 christos fputs ("!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted/\n", f); 295 1.1 christos fputs ("!_TAG_PROGRAM_AUTHOR\tIan Lance Taylor, Salvador E. Tropea and others\t//\n", f); 296 1.9 christos fputs ("!_TAG_PROGRAM_NAME\tobjdump\t/From GNU binutils/\n", f); 297 1.9 christos } 298 1.9 christos 299 1.9 christos bool ret = debug_write (dhandle, as_tags ? &tg_fns : &pr_fns, &info); 300 1.9 christos while (info.stack != NULL) 301 1.9 christos { 302 1.9 christos struct pr_stack *s = info.stack; 303 1.9 christos info.stack = s->next; 304 1.9 christos free (s->type); 305 1.9 christos free (s->method); 306 1.9 christos free (s->parents); 307 1.9 christos free (s); 308 1.1 christos } 309 1.1 christos free (info.filename); 310 1.1 christos return ret; 311 1.1 christos } 312 1.1 christos 313 1.1 christos /* Indent to the current indentation level. */ 315 1.1 christos 316 1.1 christos static void 317 1.1 christos indent (struct pr_handle *info) 318 1.1 christos { 319 1.1 christos unsigned int i; 320 1.1 christos 321 1.1 christos for (i = 0; i < info->indent; i++) 322 1.1 christos putc (' ', info->f); 323 1.8 christos } 324 1.1 christos 325 1.1 christos /* Push a type on the type stack. */ 326 1.1 christos 327 1.1 christos static bool 328 1.1 christos push_type (struct pr_handle *info, const char *type) 329 1.8 christos { 330 1.1 christos struct pr_stack *n; 331 1.9 christos 332 1.1 christos if (type == NULL) 333 1.1 christos return false; 334 1.1 christos 335 1.1 christos n = xmalloc (sizeof *n); 336 1.1 christos memset (n, 0, sizeof *n); 337 1.1 christos 338 1.1 christos n->type = xstrdup (type); 339 1.1 christos n->visibility = DEBUG_VISIBILITY_IGNORE; 340 1.8 christos n->method = NULL; 341 1.1 christos n->next = info->stack; 342 1.1 christos info->stack = n; 343 1.1 christos 344 1.1 christos return true; 345 1.8 christos } 346 1.1 christos 347 1.1 christos /* Prepend a string onto the type on the top of the type stack. */ 348 1.1 christos 349 1.1 christos static bool 350 1.1 christos prepend_type (struct pr_handle *info, const char *s) 351 1.1 christos { 352 1.9 christos char *n; 353 1.1 christos 354 1.1 christos assert (info->stack != NULL); 355 1.1 christos 356 1.1 christos n = xmalloc (strlen (s) + strlen (info->stack->type) + 1); 357 1.8 christos sprintf (n, "%s%s", s, info->stack->type); 358 1.1 christos free (info->stack->type); 359 1.1 christos info->stack->type = n; 360 1.1 christos 361 1.1 christos return true; 362 1.8 christos } 363 1.1 christos 364 1.1 christos /* Append a string to the type on the top of the type stack. */ 365 1.1 christos 366 1.1 christos static bool 367 1.1 christos append_type (struct pr_handle *info, const char *s) 368 1.8 christos { 369 1.1 christos unsigned int len; 370 1.1 christos 371 1.1 christos if (s == NULL) 372 1.1 christos return false; 373 1.9 christos 374 1.1 christos assert (info->stack != NULL); 375 1.1 christos 376 1.8 christos len = strlen (info->stack->type); 377 1.1 christos info->stack->type = xrealloc (info->stack->type, len + strlen (s) + 1); 378 1.1 christos strcpy (info->stack->type + len, s); 379 1.1 christos 380 1.1 christos return true; 381 1.8 christos } 382 1.1 christos 383 1.1 christos /* Append a string to the parents on the top of the type stack. */ 384 1.1 christos 385 1.1 christos static bool 386 1.1 christos append_parent (struct pr_handle *info, const char *s) 387 1.8 christos { 388 1.1 christos unsigned int len; 389 1.1 christos 390 1.1 christos if (s == NULL) 391 1.1 christos return false; 392 1.9 christos 393 1.1 christos assert (info->stack != NULL); 394 1.1 christos 395 1.8 christos len = info->stack->parents ? strlen (info->stack->parents) : 0; 396 1.1 christos info->stack->parents = xrealloc (info->stack->parents, len + strlen (s) + 1); 397 1.1 christos strcpy (info->stack->parents + len, s); 398 1.1 christos 399 1.1 christos return true; 400 1.1 christos } 401 1.1 christos 402 1.8 christos /* We use an underscore to indicate where the name should go in a type 403 1.1 christos string. This function substitutes a string for the underscore. If 404 1.1 christos there is no underscore, the name follows the type. */ 405 1.1 christos 406 1.1 christos static bool 407 1.1 christos substitute_type (struct pr_handle *info, const char *s) 408 1.1 christos { 409 1.1 christos char *u; 410 1.1 christos 411 1.1 christos assert (info->stack != NULL); 412 1.1 christos 413 1.1 christos u = strchr (info->stack->type, '|'); 414 1.9 christos if (u != NULL) 415 1.1 christos { 416 1.1 christos char *n; 417 1.1 christos 418 1.1 christos n = xmalloc (strlen (info->stack->type) + strlen (s)); 419 1.1 christos 420 1.1 christos memcpy (n, info->stack->type, u - info->stack->type); 421 1.1 christos strcpy (n + (u - info->stack->type), s); 422 1.1 christos strcat (n, u + 1); 423 1.8 christos 424 1.1 christos free (info->stack->type); 425 1.1 christos info->stack->type = n; 426 1.1 christos 427 1.1 christos return true; 428 1.1 christos } 429 1.1 christos 430 1.1 christos if (strchr (s, '|') != NULL 431 1.1 christos && (strchr (info->stack->type, '{') != NULL 432 1.8 christos || strchr (info->stack->type, '(') != NULL)) 433 1.1 christos { 434 1.1 christos if (! prepend_type (info, "(") 435 1.1 christos || ! append_type (info, ")")) 436 1.8 christos return false; 437 1.1 christos } 438 1.1 christos 439 1.1 christos if (*s == '\0') 440 1.1 christos return true; 441 1.1 christos 442 1.1 christos return (append_type (info, " ") 443 1.1 christos && append_type (info, s)); 444 1.8 christos } 445 1.1 christos 446 1.1 christos /* Indent the type at the top of the stack by appending spaces. */ 447 1.1 christos 448 1.1 christos static bool 449 1.1 christos indent_type (struct pr_handle *info) 450 1.1 christos { 451 1.1 christos unsigned int i; 452 1.8 christos 453 1.1 christos for (i = 0; i < info->indent; i++) 454 1.1 christos { 455 1.8 christos if (! append_type (info, " ")) 456 1.1 christos return false; 457 1.1 christos } 458 1.1 christos 459 1.1 christos return true; 460 1.1 christos } 461 1.1 christos 462 1.1 christos /* Pop a type from the type stack. */ 463 1.1 christos 464 1.1 christos static char * 465 1.1 christos pop_type (struct pr_handle *info) 466 1.1 christos { 467 1.1 christos struct pr_stack *o; 468 1.1 christos char *ret; 469 1.1 christos 470 1.1 christos assert (info->stack != NULL); 471 1.1 christos 472 1.1 christos o = info->stack; 473 1.1 christos info->stack = o->next; 474 1.1 christos ret = o->type; 475 1.1 christos free (o); 476 1.1 christos 477 1.1 christos return ret; 478 1.1 christos } 479 1.8 christos 480 1.1 christos /* Print a VMA value into a string. */ 481 1.8 christos 482 1.8 christos static void 483 1.8 christos print_vma (bfd_vma vma, char *buf, bool unsignedp, bool hexp) 484 1.8 christos { 485 1.1 christos if (hexp) 486 1.8 christos sprintf (buf, "%#" PRIx64, (uint64_t) vma); 487 1.1 christos else if (unsignedp) 488 1.1 christos sprintf (buf, "%" PRIu64, (uint64_t) vma); 489 1.1 christos else 490 1.1 christos sprintf (buf, "%" PRId64, (int64_t) vma); 491 1.8 christos } 492 1.1 christos 493 1.1 christos /* Start a new compilation unit. */ 495 1.1 christos 496 1.1 christos static bool 497 1.1 christos pr_start_compilation_unit (void *p, const char *filename) 498 1.1 christos { 499 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 500 1.8 christos 501 1.1 christos assert (info->indent == 0); 502 1.1 christos 503 1.1 christos fprintf (info->f, "%s:\n", filename); 504 1.1 christos 505 1.8 christos return true; 506 1.1 christos } 507 1.1 christos 508 1.1 christos /* Start a source file within a compilation unit. */ 509 1.1 christos 510 1.1 christos static bool 511 1.1 christos pr_start_source (void *p, const char *filename) 512 1.1 christos { 513 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 514 1.8 christos 515 1.1 christos assert (info->indent == 0); 516 1.1 christos 517 1.1 christos fprintf (info->f, " %s:\n", filename); 518 1.1 christos 519 1.8 christos return true; 520 1.1 christos } 521 1.1 christos 522 1.1 christos /* Push an empty type onto the type stack. */ 523 1.1 christos 524 1.1 christos static bool 525 1.1 christos pr_empty_type (void *p) 526 1.1 christos { 527 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 528 1.1 christos 529 1.8 christos return push_type (info, "<undefined>"); 530 1.1 christos } 531 1.1 christos 532 1.1 christos /* Push a void type onto the type stack. */ 533 1.1 christos 534 1.1 christos static bool 535 1.1 christos pr_void_type (void *p) 536 1.1 christos { 537 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 538 1.1 christos 539 1.8 christos return push_type (info, "void"); 540 1.8 christos } 541 1.1 christos 542 1.1 christos /* Push an integer type onto the type stack. */ 543 1.6 christos 544 1.1 christos static bool 545 1.1 christos pr_int_type (void *p, unsigned int size, bool unsignedp) 546 1.1 christos { 547 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 548 1.1 christos char ab[40]; 549 1.1 christos 550 1.1 christos sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8); 551 1.8 christos return push_type (info, ab); 552 1.1 christos } 553 1.1 christos 554 1.1 christos /* Push a floating type onto the type stack. */ 555 1.6 christos 556 1.1 christos static bool 557 1.1 christos pr_float_type (void *p, unsigned int size) 558 1.1 christos { 559 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 560 1.1 christos char ab[40]; 561 1.1 christos 562 1.1 christos if (size == 4) 563 1.1 christos return push_type (info, "float"); 564 1.1 christos else if (size == 8) 565 1.1 christos return push_type (info, "double"); 566 1.1 christos 567 1.1 christos sprintf (ab, "float%d", size * 8); 568 1.8 christos return push_type (info, ab); 569 1.1 christos } 570 1.1 christos 571 1.1 christos /* Push a complex type onto the type stack. */ 572 1.1 christos 573 1.1 christos static bool 574 1.8 christos pr_complex_type (void *p, unsigned int size) 575 1.1 christos { 576 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 577 1.1 christos 578 1.1 christos if (! pr_float_type (p, size)) 579 1.8 christos return false; 580 1.1 christos 581 1.8 christos return prepend_type (info, "complex "); 582 1.1 christos } 583 1.1 christos 584 1.1 christos /* Push a bool type onto the type stack. */ 585 1.6 christos 586 1.1 christos static bool 587 1.1 christos pr_bool_type (void *p, unsigned int size) 588 1.1 christos { 589 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 590 1.1 christos char ab[40]; 591 1.1 christos 592 1.1 christos sprintf (ab, "bool%d", size * 8); 593 1.1 christos 594 1.8 christos return push_type (info, ab); 595 1.1 christos } 596 1.1 christos 597 1.1 christos /* Push an enum type onto the type stack. */ 598 1.1 christos 599 1.1 christos static bool 600 1.1 christos pr_enum_type (void *p, const char *tag, const char **names, 601 1.1 christos bfd_signed_vma *values) 602 1.1 christos { 603 1.8 christos struct pr_handle *info = (struct pr_handle *) p; 604 1.1 christos unsigned int i; 605 1.1 christos bfd_signed_vma val; 606 1.1 christos 607 1.1 christos if (! push_type (info, "enum ")) 608 1.8 christos return false; 609 1.1 christos if (tag != NULL) 610 1.1 christos { 611 1.8 christos if (! append_type (info, tag) 612 1.1 christos || ! append_type (info, " ")) 613 1.1 christos return false; 614 1.1 christos } 615 1.1 christos if (! append_type (info, "{ ")) 616 1.8 christos return false; 617 1.1 christos 618 1.1 christos if (names == NULL) 619 1.1 christos { 620 1.1 christos if (! append_type (info, "/* undefined */")) 621 1.1 christos return false; 622 1.1 christos } 623 1.1 christos else 624 1.1 christos { 625 1.1 christos val = 0; 626 1.8 christos for (i = 0; names[i] != NULL; i++) 627 1.1 christos { 628 1.1 christos if (i > 0) 629 1.1 christos { 630 1.8 christos if (! append_type (info, ", ")) 631 1.1 christos return false; 632 1.1 christos } 633 1.1 christos 634 1.6 christos if (! append_type (info, names[i])) 635 1.1 christos return false; 636 1.8 christos 637 1.1 christos if (values[i] != val) 638 1.1 christos { 639 1.8 christos char ab[22]; 640 1.1 christos 641 1.1 christos print_vma (values[i], ab, false, false); 642 1.1 christos if (! append_type (info, " = ") 643 1.1 christos || ! append_type (info, ab)) 644 1.1 christos return false; 645 1.1 christos val = values[i]; 646 1.1 christos } 647 1.1 christos 648 1.1 christos ++val; 649 1.1 christos } 650 1.1 christos } 651 1.1 christos 652 1.8 christos return append_type (info, " }"); 653 1.1 christos } 654 1.1 christos 655 1.1 christos /* Turn the top type on the stack into a pointer. */ 656 1.1 christos 657 1.1 christos static bool 658 1.1 christos pr_pointer_type (void *p) 659 1.1 christos { 660 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 661 1.1 christos char *s; 662 1.1 christos 663 1.1 christos assert (info->stack != NULL); 664 1.1 christos 665 1.1 christos s = strchr (info->stack->type, '|'); 666 1.1 christos if (s != NULL && s[1] == '[') 667 1.1 christos return substitute_type (info, "(*|)"); 668 1.8 christos return substitute_type (info, "*|"); 669 1.8 christos } 670 1.1 christos 671 1.1 christos /* Turn the top type on the stack into a function returning that type. */ 672 1.1 christos 673 1.1 christos static bool 674 1.1 christos pr_function_type (void *p, int argcount, bool varargs) 675 1.1 christos { 676 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 677 1.1 christos char **arg_types; 678 1.1 christos unsigned int len; 679 1.1 christos char *s; 680 1.1 christos 681 1.1 christos assert (info->stack != NULL); 682 1.1 christos 683 1.1 christos len = 10; 684 1.1 christos 685 1.1 christos if (argcount <= 0) 686 1.1 christos { 687 1.1 christos arg_types = NULL; 688 1.1 christos len += 15; 689 1.9 christos } 690 1.1 christos else 691 1.1 christos { 692 1.9 christos int i; 693 1.9 christos 694 1.1 christos arg_types = xmalloc (argcount * sizeof (*arg_types)); 695 1.9 christos for (i = argcount - 1; i >= 0; i--) 696 1.9 christos { 697 1.1 christos if (!substitute_type (info, "") 698 1.8 christos || (arg_types[i] = pop_type (info)) == NULL) 699 1.1 christos { 700 1.1 christos for (int j = i + 1; j < argcount; j++) 701 1.1 christos free (arg_types[j]); 702 1.1 christos free (arg_types); 703 1.1 christos return false; 704 1.1 christos } 705 1.1 christos len += strlen (arg_types[i]) + 2; 706 1.1 christos } 707 1.1 christos if (varargs) 708 1.9 christos len += 5; 709 1.8 christos } 710 1.1 christos 711 1.1 christos /* Now the return type is on the top of the stack. */ 712 1.1 christos 713 1.1 christos s = xmalloc (len); 714 1.1 christos strcpy (s, "(|) ("); 715 1.1 christos 716 1.1 christos if (argcount < 0) 717 1.1 christos strcat (s, "/* unknown */"); 718 1.1 christos else 719 1.1 christos { 720 1.1 christos int i; 721 1.1 christos 722 1.9 christos for (i = 0; i < argcount; i++) 723 1.1 christos { 724 1.1 christos if (i > 0) 725 1.1 christos strcat (s, ", "); 726 1.1 christos strcat (s, arg_types[i]); 727 1.1 christos free (arg_types[i]); 728 1.1 christos } 729 1.1 christos if (varargs) 730 1.9 christos { 731 1.1 christos if (i > 0) 732 1.1 christos strcat (s, ", "); 733 1.1 christos strcat (s, "..."); 734 1.1 christos } 735 1.8 christos free (arg_types); 736 1.1 christos } 737 1.8 christos 738 1.1 christos strcat (s, ")"); 739 1.1 christos 740 1.1 christos bool ret = substitute_type (info, s); 741 1.1 christos free (s); 742 1.8 christos return ret; 743 1.1 christos } 744 1.1 christos 745 1.1 christos /* Turn the top type on the stack into a reference to that type. */ 746 1.1 christos 747 1.1 christos static bool 748 1.1 christos pr_reference_type (void *p) 749 1.1 christos { 750 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 751 1.1 christos 752 1.1 christos assert (info->stack != NULL); 753 1.1 christos 754 1.8 christos return substitute_type (info, "&|"); 755 1.1 christos } 756 1.1 christos 757 1.1 christos /* Make a range type. */ 758 1.6 christos 759 1.1 christos static bool 760 1.1 christos pr_range_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper) 761 1.1 christos { 762 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 763 1.8 christos char abl[22], abu[22]; 764 1.1 christos 765 1.8 christos assert (info->stack != NULL); 766 1.8 christos 767 1.1 christos if (! substitute_type (info, "")) 768 1.1 christos return false; 769 1.1 christos 770 1.1 christos print_vma (lower, abl, false, false); 771 1.1 christos print_vma (upper, abu, false, false); 772 1.1 christos 773 1.1 christos return (prepend_type (info, "range (") 774 1.1 christos && append_type (info, "):") 775 1.1 christos && append_type (info, abl) 776 1.1 christos && append_type (info, ":") 777 1.8 christos && append_type (info, abu)); 778 1.1 christos } 779 1.8 christos 780 1.1 christos /* Make an array type. */ 781 1.1 christos 782 1.1 christos static bool 783 1.6 christos pr_array_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper, 784 1.1 christos bool stringp) 785 1.1 christos { 786 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 787 1.8 christos char *range_type; 788 1.1 christos char abl[22], abu[22], ab[50]; 789 1.1 christos 790 1.1 christos range_type = pop_type (info); 791 1.1 christos if (range_type == NULL) 792 1.1 christos return false; 793 1.1 christos 794 1.1 christos if (lower == 0) 795 1.8 christos { 796 1.1 christos if (upper == -1) 797 1.1 christos sprintf (ab, "|[]"); 798 1.1 christos else 799 1.1 christos { 800 1.1 christos print_vma (upper + 1, abu, false, false); 801 1.8 christos sprintf (ab, "|[%s]", abu); 802 1.8 christos } 803 1.1 christos } 804 1.1 christos else 805 1.1 christos { 806 1.1 christos print_vma (lower, abl, false, false); 807 1.9 christos print_vma (upper, abu, false, false); 808 1.1 christos sprintf (ab, "|[%s:%s]", abl, abu); 809 1.1 christos } 810 1.1 christos 811 1.1 christos if (! substitute_type (info, ab)) 812 1.1 christos goto fail; 813 1.9 christos 814 1.1 christos if (strcmp (range_type, "int") != 0) 815 1.1 christos { 816 1.1 christos if (! append_type (info, ":") 817 1.1 christos || ! append_type (info, range_type)) 818 1.1 christos goto fail; 819 1.9 christos } 820 1.1 christos 821 1.1 christos if (stringp) 822 1.9 christos { 823 1.8 christos if (! append_type (info, " /* string */")) 824 1.9 christos goto fail; 825 1.9 christos } 826 1.9 christos 827 1.9 christos free (range_type); 828 1.1 christos return true; 829 1.1 christos 830 1.1 christos fail: 831 1.1 christos free (range_type); 832 1.8 christos return false; 833 1.8 christos } 834 1.1 christos 835 1.1 christos /* Make a set type. */ 836 1.1 christos 837 1.1 christos static bool 838 1.8 christos pr_set_type (void *p, bool bitstringp) 839 1.1 christos { 840 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 841 1.1 christos 842 1.8 christos if (! substitute_type (info, "")) 843 1.1 christos return false; 844 1.1 christos 845 1.1 christos if (! prepend_type (info, "set { ") 846 1.1 christos || ! append_type (info, " }")) 847 1.8 christos return false; 848 1.1 christos 849 1.1 christos if (bitstringp) 850 1.8 christos { 851 1.1 christos if (! append_type (info, "/* bitstring */")) 852 1.1 christos return false; 853 1.1 christos } 854 1.1 christos 855 1.8 christos return true; 856 1.1 christos } 857 1.1 christos 858 1.1 christos /* Make an offset type. */ 859 1.1 christos 860 1.1 christos static bool 861 1.1 christos pr_offset_type (void *p) 862 1.8 christos { 863 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 864 1.1 christos char *t; 865 1.1 christos 866 1.8 christos if (! substitute_type (info, "")) 867 1.1 christos return false; 868 1.9 christos 869 1.9 christos t = pop_type (info); 870 1.9 christos if (t == NULL) 871 1.9 christos return false; 872 1.9 christos 873 1.9 christos bool ret = (substitute_type (info, "") 874 1.1 christos && prepend_type (info, " ") 875 1.1 christos && prepend_type (info, t) 876 1.1 christos && append_type (info, "::|")); 877 1.1 christos free (t); 878 1.8 christos return ret; 879 1.8 christos } 880 1.1 christos 881 1.1 christos /* Make a method type. */ 882 1.1 christos 883 1.9 christos static bool 884 1.1 christos pr_method_type (void *p, bool domain, int argcount, bool varargs) 885 1.1 christos { 886 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 887 1.1 christos unsigned int len; 888 1.1 christos char *domain_type = NULL, *free_domain = NULL; 889 1.9 christos char **arg_types; 890 1.1 christos char *s; 891 1.1 christos 892 1.8 christos len = 10; 893 1.1 christos 894 1.1 christos if (domain) 895 1.8 christos { 896 1.9 christos if (! substitute_type (info, "")) 897 1.8 christos return false; 898 1.1 christos domain_type = pop_type (info); 899 1.1 christos if (domain_type == NULL) 900 1.8 christos return false; 901 1.1 christos free_domain = domain_type; 902 1.1 christos if (startswith (domain_type, "class ") 903 1.1 christos && strchr (domain_type + sizeof "class " - 1, ' ') == NULL) 904 1.1 christos domain_type += sizeof "class " - 1; 905 1.1 christos else if (startswith (domain_type, "union class ") 906 1.1 christos && (strchr (domain_type + sizeof "union class " - 1, ' ') 907 1.1 christos == NULL)) 908 1.1 christos domain_type += sizeof "union class " - 1; 909 1.1 christos len += strlen (domain_type); 910 1.1 christos } 911 1.1 christos 912 1.1 christos if (argcount <= 0) 913 1.1 christos { 914 1.1 christos arg_types = NULL; 915 1.1 christos len += 15; 916 1.9 christos } 917 1.1 christos else 918 1.1 christos { 919 1.9 christos int i; 920 1.9 christos 921 1.1 christos arg_types = xmalloc (argcount * sizeof (*arg_types)); 922 1.9 christos for (i = argcount - 1; i >= 0; i--) 923 1.9 christos { 924 1.1 christos if (!substitute_type (info, "") 925 1.8 christos || (arg_types[i] = pop_type (info)) == NULL) 926 1.1 christos { 927 1.1 christos for (int j = i + 1; j < argcount; ++j) 928 1.1 christos free (arg_types[j]); 929 1.1 christos free (arg_types); 930 1.1 christos return false; 931 1.1 christos } 932 1.1 christos len += strlen (arg_types[i]) + 2; 933 1.1 christos } 934 1.1 christos if (varargs) 935 1.9 christos len += 5; 936 1.9 christos } 937 1.9 christos 938 1.9 christos /* Now the return type is on the top of the stack. */ 939 1.9 christos 940 1.9 christos s = xmalloc (len); 941 1.9 christos *s = 0; 942 1.1 christos if (domain) 943 1.1 christos { 944 1.1 christos strcpy (s, domain_type); 945 1.1 christos free (free_domain); 946 1.1 christos } 947 1.1 christos strcat (s, "::| ("); 948 1.1 christos 949 1.1 christos if (argcount < 0) 950 1.1 christos strcat (s, "/* unknown */"); 951 1.1 christos else 952 1.1 christos { 953 1.1 christos int i; 954 1.1 christos 955 1.9 christos for (i = 0; i < argcount; i++) 956 1.1 christos { 957 1.1 christos if (i > 0) 958 1.1 christos strcat (s, ", "); 959 1.1 christos strcat (s, arg_types[i]); 960 1.1 christos free (arg_types[i]); 961 1.1 christos } 962 1.1 christos if (varargs) 963 1.9 christos { 964 1.1 christos if (i > 0) 965 1.1 christos strcat (s, ", "); 966 1.1 christos strcat (s, "..."); 967 1.1 christos } 968 1.9 christos free (arg_types); 969 1.1 christos } 970 1.9 christos 971 1.1 christos strcat (s, ")"); 972 1.1 christos 973 1.1 christos bool ret = substitute_type (info, s); 974 1.1 christos free (s); 975 1.8 christos return ret; 976 1.1 christos } 977 1.1 christos 978 1.1 christos /* Make a const qualified type. */ 979 1.1 christos 980 1.1 christos static bool 981 1.1 christos pr_const_type (void *p) 982 1.1 christos { 983 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 984 1.1 christos 985 1.8 christos return substitute_type (info, "const |"); 986 1.1 christos } 987 1.1 christos 988 1.1 christos /* Make a volatile qualified type. */ 989 1.1 christos 990 1.1 christos static bool 991 1.1 christos pr_volatile_type (void *p) 992 1.1 christos { 993 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 994 1.1 christos 995 1.8 christos return substitute_type (info, "volatile |"); 996 1.1 christos } 997 1.8 christos 998 1.1 christos /* Start accumulating a struct type. */ 999 1.1 christos 1000 1.1 christos static bool 1001 1.1 christos pr_start_struct_type (void *p, const char *tag, unsigned int id, 1002 1.1 christos bool structp, unsigned int size) 1003 1.1 christos { 1004 1.8 christos struct pr_handle *info = (struct pr_handle *) p; 1005 1.1 christos 1006 1.1 christos info->indent += 2; 1007 1.1 christos 1008 1.8 christos if (! push_type (info, structp ? "struct " : "union ")) 1009 1.1 christos return false; 1010 1.1 christos if (tag != NULL) 1011 1.1 christos { 1012 1.1 christos if (! append_type (info, tag)) 1013 1.1 christos return false; 1014 1.1 christos } 1015 1.1 christos else 1016 1.8 christos { 1017 1.1 christos char idbuf[20]; 1018 1.1 christos 1019 1.1 christos sprintf (idbuf, "%%anon%u", id); 1020 1.8 christos if (! append_type (info, idbuf)) 1021 1.1 christos return false; 1022 1.1 christos } 1023 1.1 christos 1024 1.1 christos if (! append_type (info, " {")) 1025 1.1 christos return false; 1026 1.8 christos if (size != 0 || tag != NULL) 1027 1.1 christos { 1028 1.1 christos char ab[30]; 1029 1.1 christos 1030 1.1 christos if (! append_type (info, " /*")) 1031 1.1 christos return false; 1032 1.8 christos 1033 1.1 christos if (size != 0) 1034 1.1 christos { 1035 1.1 christos sprintf (ab, " size %u", size); 1036 1.1 christos if (! append_type (info, ab)) 1037 1.1 christos return false; 1038 1.8 christos } 1039 1.1 christos if (tag != NULL) 1040 1.1 christos { 1041 1.8 christos sprintf (ab, " id %u", id); 1042 1.1 christos if (! append_type (info, ab)) 1043 1.1 christos return false; 1044 1.8 christos } 1045 1.1 christos if (! append_type (info, " */")) 1046 1.1 christos return false; 1047 1.1 christos } 1048 1.1 christos if (! append_type (info, "\n")) 1049 1.1 christos return false; 1050 1.1 christos 1051 1.1 christos info->stack->visibility = DEBUG_VISIBILITY_PUBLIC; 1052 1.1 christos 1053 1.8 christos return indent_type (info); 1054 1.1 christos } 1055 1.1 christos 1056 1.1 christos /* Output the visibility of a field in a struct. */ 1057 1.1 christos 1058 1.1 christos static bool 1059 1.1 christos pr_fix_visibility (struct pr_handle *info, enum debug_visibility visibility) 1060 1.1 christos { 1061 1.1 christos const char *s = NULL; 1062 1.1 christos char *t; 1063 1.8 christos unsigned int len; 1064 1.1 christos 1065 1.1 christos assert (info->stack != NULL); 1066 1.1 christos 1067 1.1 christos if (info->stack->visibility == visibility) 1068 1.1 christos return true; 1069 1.1 christos 1070 1.1 christos switch (visibility) 1071 1.1 christos { 1072 1.1 christos case DEBUG_VISIBILITY_PUBLIC: 1073 1.1 christos s = "public"; 1074 1.1 christos break; 1075 1.1 christos case DEBUG_VISIBILITY_PRIVATE: 1076 1.1 christos s = "private"; 1077 1.1 christos break; 1078 1.1 christos case DEBUG_VISIBILITY_PROTECTED: 1079 1.1 christos s = "protected"; 1080 1.1 christos break; 1081 1.8 christos case DEBUG_VISIBILITY_IGNORE: 1082 1.1 christos s = "/* ignore */"; 1083 1.1 christos break; 1084 1.1 christos default: 1085 1.1 christos abort (); 1086 1.1 christos return false; 1087 1.1 christos } 1088 1.1 christos 1089 1.1 christos /* Trim off a trailing space in the struct string, to make the 1090 1.1 christos output look a bit better, then stick on the visibility string. */ 1091 1.1 christos 1092 1.1 christos t = info->stack->type; 1093 1.1 christos len = strlen (t); 1094 1.1 christos assert (t[len - 1] == ' '); 1095 1.8 christos t[len - 1] = '\0'; 1096 1.1 christos 1097 1.1 christos if (! append_type (info, s) 1098 1.1 christos || ! append_type (info, ":\n") 1099 1.8 christos || ! indent_type (info)) 1100 1.1 christos return false; 1101 1.1 christos 1102 1.1 christos info->stack->visibility = visibility; 1103 1.1 christos 1104 1.8 christos return true; 1105 1.1 christos } 1106 1.1 christos 1107 1.1 christos /* Add a field to a struct type. */ 1108 1.1 christos 1109 1.6 christos static bool 1110 1.1 christos pr_struct_field (void *p, const char *name, bfd_vma bitpos, bfd_vma bitsize, 1111 1.1 christos enum debug_visibility visibility) 1112 1.1 christos { 1113 1.8 christos struct pr_handle *info = (struct pr_handle *) p; 1114 1.1 christos char ab[22]; 1115 1.1 christos char *t; 1116 1.8 christos 1117 1.1 christos if (! substitute_type (info, name)) 1118 1.1 christos return false; 1119 1.1 christos 1120 1.8 christos if (! append_type (info, "; /* ")) 1121 1.1 christos return false; 1122 1.1 christos 1123 1.1 christos if (bitsize != 0) 1124 1.8 christos { 1125 1.1 christos print_vma (bitsize, ab, true, false); 1126 1.1 christos if (! append_type (info, "bitsize ") 1127 1.8 christos || ! append_type (info, ab) 1128 1.1 christos || ! append_type (info, ", ")) 1129 1.1 christos return false; 1130 1.1 christos } 1131 1.1 christos 1132 1.8 christos print_vma (bitpos, ab, true, false); 1133 1.1 christos if (! append_type (info, "bitpos ") 1134 1.1 christos || ! append_type (info, ab) 1135 1.1 christos || ! append_type (info, " */\n") 1136 1.8 christos || ! indent_type (info)) 1137 1.1 christos return false; 1138 1.9 christos 1139 1.9 christos t = pop_type (info); 1140 1.9 christos if (t == NULL) 1141 1.1 christos return false; 1142 1.1 christos 1143 1.1 christos bool ret = pr_fix_visibility (info, visibility) && append_type (info, t); 1144 1.1 christos free (t); 1145 1.8 christos return ret; 1146 1.1 christos } 1147 1.1 christos 1148 1.1 christos /* Finish a struct type. */ 1149 1.1 christos 1150 1.1 christos static bool 1151 1.1 christos pr_end_struct_type (void *p) 1152 1.1 christos { 1153 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1154 1.1 christos char *s; 1155 1.1 christos 1156 1.1 christos assert (info->stack != NULL); 1157 1.1 christos assert (info->indent >= 2); 1158 1.1 christos 1159 1.1 christos info->indent -= 2; 1160 1.1 christos 1161 1.1 christos /* Change the trailing indentation to have a close brace. */ 1162 1.1 christos s = info->stack->type + strlen (info->stack->type) - 2; 1163 1.8 christos assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0'); 1164 1.1 christos 1165 1.1 christos *s++ = '}'; 1166 1.1 christos *s = '\0'; 1167 1.1 christos 1168 1.8 christos return true; 1169 1.1 christos } 1170 1.8 christos 1171 1.8 christos /* Start a class type. */ 1172 1.1 christos 1173 1.1 christos static bool 1174 1.1 christos pr_start_class_type (void *p, const char *tag, unsigned int id, 1175 1.9 christos bool structp, unsigned int size, 1176 1.1 christos bool vptr, bool ownvptr) 1177 1.1 christos { 1178 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1179 1.1 christos char *tv = NULL; 1180 1.1 christos bool ret = false; 1181 1.1 christos 1182 1.1 christos info->indent += 2; 1183 1.8 christos 1184 1.1 christos if (vptr && ! ownvptr) 1185 1.1 christos { 1186 1.1 christos tv = pop_type (info); 1187 1.9 christos if (tv == NULL) 1188 1.1 christos return false; 1189 1.1 christos } 1190 1.1 christos 1191 1.9 christos if (! push_type (info, structp ? "class " : "union class ")) 1192 1.1 christos goto out; 1193 1.1 christos if (tag != NULL) 1194 1.1 christos { 1195 1.1 christos if (! append_type (info, tag)) 1196 1.1 christos goto out; 1197 1.1 christos } 1198 1.1 christos else 1199 1.9 christos { 1200 1.1 christos char idbuf[20]; 1201 1.1 christos 1202 1.1 christos sprintf (idbuf, "%%anon%u", id); 1203 1.9 christos if (! append_type (info, idbuf)) 1204 1.1 christos goto out; 1205 1.1 christos } 1206 1.1 christos 1207 1.9 christos if (! append_type (info, " {")) 1208 1.1 christos goto out; 1209 1.1 christos if (size != 0 || vptr || ownvptr || tag != NULL) 1210 1.1 christos { 1211 1.1 christos if (! append_type (info, " /*")) 1212 1.1 christos goto out; 1213 1.1 christos 1214 1.1 christos if (size != 0) 1215 1.1 christos { 1216 1.9 christos char ab[20]; 1217 1.1 christos 1218 1.1 christos sprintf (ab, "%u", size); 1219 1.1 christos if (! append_type (info, " size ") 1220 1.1 christos || ! append_type (info, ab)) 1221 1.1 christos goto out; 1222 1.9 christos } 1223 1.1 christos 1224 1.1 christos if (vptr) 1225 1.1 christos { 1226 1.9 christos if (! append_type (info, " vtable ")) 1227 1.1 christos goto out; 1228 1.1 christos if (ownvptr) 1229 1.1 christos { 1230 1.1 christos if (! append_type (info, "self ")) 1231 1.1 christos goto out; 1232 1.9 christos } 1233 1.1 christos else 1234 1.1 christos { 1235 1.1 christos if (! append_type (info, tv) 1236 1.1 christos || ! append_type (info, " ")) 1237 1.1 christos goto out; 1238 1.1 christos } 1239 1.1 christos } 1240 1.1 christos 1241 1.1 christos if (tag != NULL) 1242 1.9 christos { 1243 1.1 christos char ab[30]; 1244 1.1 christos 1245 1.1 christos sprintf (ab, " id %u", id); 1246 1.9 christos if (! append_type (info, ab)) 1247 1.1 christos goto out; 1248 1.1 christos } 1249 1.1 christos 1250 1.1 christos if (! append_type (info, " */")) 1251 1.9 christos goto out; 1252 1.9 christos } 1253 1.9 christos 1254 1.9 christos info->stack->visibility = DEBUG_VISIBILITY_PRIVATE; 1255 1.1 christos 1256 1.1 christos ret = append_type (info, "\n") && indent_type (info); 1257 1.1 christos out: 1258 1.1 christos free (tv); 1259 1.8 christos return ret; 1260 1.1 christos } 1261 1.1 christos 1262 1.1 christos /* Add a static member to a class. */ 1263 1.1 christos 1264 1.1 christos static bool 1265 1.1 christos pr_class_static_member (void *p, const char *name, const char *physname, 1266 1.1 christos enum debug_visibility visibility) 1267 1.8 christos { 1268 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1269 1.1 christos char *t; 1270 1.1 christos 1271 1.1 christos if (! substitute_type (info, name)) 1272 1.1 christos return false; 1273 1.1 christos 1274 1.8 christos if (! prepend_type (info, "static ") 1275 1.1 christos || ! append_type (info, "; /* ") 1276 1.1 christos || ! append_type (info, physname) 1277 1.1 christos || ! append_type (info, " */\n") 1278 1.8 christos || ! indent_type (info)) 1279 1.1 christos return false; 1280 1.9 christos 1281 1.9 christos t = pop_type (info); 1282 1.9 christos if (t == NULL) 1283 1.1 christos return false; 1284 1.1 christos 1285 1.1 christos bool ret = pr_fix_visibility (info, visibility) && append_type (info, t); 1286 1.1 christos free (t); 1287 1.8 christos return ret; 1288 1.8 christos } 1289 1.1 christos 1290 1.1 christos /* Add a base class to a class. */ 1291 1.1 christos 1292 1.1 christos static bool 1293 1.1 christos pr_class_baseclass (void *p, bfd_vma bitpos, bool is_virtual, 1294 1.6 christos enum debug_visibility visibility) 1295 1.1 christos { 1296 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1297 1.1 christos char *t; 1298 1.1 christos const char *prefix; 1299 1.1 christos char ab[22]; 1300 1.8 christos char *s, *l, *n; 1301 1.1 christos 1302 1.1 christos assert (info->stack != NULL && info->stack->next != NULL); 1303 1.1 christos 1304 1.8 christos if (! substitute_type (info, "")) 1305 1.1 christos return false; 1306 1.1 christos 1307 1.1 christos t = pop_type (info); 1308 1.9 christos if (t == NULL) 1309 1.9 christos return false; 1310 1.9 christos 1311 1.9 christos /* Push it back on to take advantage of the prepend_type and 1312 1.9 christos append_type routines. */ 1313 1.9 christos if (! push_type (info, t + (startswith (t, "class ") 1314 1.9 christos ? sizeof "class " - 1 : 0))) 1315 1.1 christos { 1316 1.1 christos free (t); 1317 1.1 christos return false; 1318 1.1 christos } 1319 1.8 christos free (t); 1320 1.1 christos 1321 1.1 christos if (is_virtual) 1322 1.1 christos { 1323 1.1 christos if (! prepend_type (info, "virtual ")) 1324 1.1 christos return false; 1325 1.1 christos } 1326 1.1 christos 1327 1.1 christos switch (visibility) 1328 1.1 christos { 1329 1.1 christos case DEBUG_VISIBILITY_PUBLIC: 1330 1.1 christos prefix = "public "; 1331 1.1 christos break; 1332 1.1 christos case DEBUG_VISIBILITY_PROTECTED: 1333 1.1 christos prefix = "protected "; 1334 1.1 christos break; 1335 1.1 christos case DEBUG_VISIBILITY_PRIVATE: 1336 1.1 christos prefix = "private "; 1337 1.1 christos break; 1338 1.1 christos default: 1339 1.8 christos prefix = "/* unknown visibility */ "; 1340 1.1 christos break; 1341 1.1 christos } 1342 1.1 christos 1343 1.8 christos if (! prepend_type (info, prefix)) 1344 1.1 christos return false; 1345 1.1 christos 1346 1.1 christos if (bitpos != 0) 1347 1.8 christos { 1348 1.1 christos print_vma (bitpos, ab, true, false); 1349 1.1 christos if (! append_type (info, " /* bitpos ") 1350 1.1 christos || ! append_type (info, ab) 1351 1.1 christos || ! append_type (info, " */")) 1352 1.1 christos return false; 1353 1.1 christos } 1354 1.1 christos 1355 1.1 christos /* Now the top of the stack is something like "public A / * bitpos 1356 1.1 christos 10 * /". The next element on the stack is something like "class 1357 1.1 christos xx { / * size 8 * /\n...". We want to substitute the top of the 1358 1.1 christos stack in before the {. */ 1359 1.1 christos s = strchr (info->stack->next->type, '{'); 1360 1.1 christos assert (s != NULL); 1361 1.1 christos --s; 1362 1.1 christos 1363 1.1 christos /* If there is already a ':', then we already have a baseclass, and 1364 1.8 christos we must append this one after a comma. */ 1365 1.1 christos for (l = info->stack->next->type; l != s; l++) 1366 1.1 christos if (*l == ':') 1367 1.1 christos break; 1368 1.8 christos if (! prepend_type (info, l == s ? " : " : ", ")) 1369 1.1 christos return false; 1370 1.9 christos 1371 1.1 christos t = pop_type (info); 1372 1.1 christos if (t == NULL) 1373 1.1 christos return false; 1374 1.1 christos 1375 1.1 christos n = xmalloc (strlen (info->stack->type) + strlen (t) + 1); 1376 1.1 christos memcpy (n, info->stack->type, s - info->stack->type); 1377 1.1 christos strcpy (n + (s - info->stack->type), t); 1378 1.1 christos strcat (n, s); 1379 1.1 christos 1380 1.8 christos free (info->stack->type); 1381 1.1 christos info->stack->type = n; 1382 1.1 christos 1383 1.1 christos free (t); 1384 1.1 christos 1385 1.8 christos return true; 1386 1.1 christos } 1387 1.1 christos 1388 1.1 christos /* Start adding a method to a class. */ 1389 1.1 christos 1390 1.1 christos static bool 1391 1.9 christos pr_class_start_method (void *p, const char *name) 1392 1.9 christos { 1393 1.8 christos struct pr_handle *info = (struct pr_handle *) p; 1394 1.1 christos 1395 1.1 christos assert (info->stack != NULL); 1396 1.1 christos free (info->stack->method); 1397 1.1 christos info->stack->method = xstrdup (name); 1398 1.8 christos return true; 1399 1.1 christos } 1400 1.1 christos 1401 1.8 christos /* Add a variant to a method. */ 1402 1.8 christos 1403 1.1 christos static bool 1404 1.1 christos pr_class_method_variant (void *p, const char *physname, 1405 1.1 christos enum debug_visibility visibility, 1406 1.1 christos bool constp, bool volatilep, 1407 1.9 christos bfd_vma voffset, bool context) 1408 1.1 christos { 1409 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1410 1.1 christos char *method_type; 1411 1.1 christos char *context_type; 1412 1.1 christos bool ret = false; 1413 1.1 christos 1414 1.1 christos assert (info->stack != NULL); 1415 1.1 christos assert (info->stack->next != NULL); 1416 1.8 christos 1417 1.1 christos /* Put the const and volatile qualifiers on the type. */ 1418 1.1 christos if (volatilep) 1419 1.1 christos { 1420 1.1 christos if (! append_type (info, " volatile")) 1421 1.8 christos return false; 1422 1.1 christos } 1423 1.1 christos if (constp) 1424 1.1 christos { 1425 1.1 christos if (! append_type (info, " const")) 1426 1.1 christos return false; 1427 1.1 christos } 1428 1.1 christos 1429 1.8 christos /* Stick the name of the method into its type. */ 1430 1.1 christos if (! substitute_type (info, 1431 1.1 christos (context 1432 1.1 christos ? info->stack->next->next->method 1433 1.1 christos : info->stack->next->method))) 1434 1.8 christos return false; 1435 1.1 christos 1436 1.1 christos /* Get the type. */ 1437 1.1 christos method_type = pop_type (info); 1438 1.1 christos if (method_type == NULL) 1439 1.1 christos return false; 1440 1.1 christos 1441 1.1 christos /* Pull off the context type if there is one. */ 1442 1.1 christos if (! context) 1443 1.9 christos context_type = NULL; 1444 1.1 christos else 1445 1.1 christos { 1446 1.1 christos context_type = pop_type (info); 1447 1.1 christos if (context_type == NULL) 1448 1.1 christos goto out; 1449 1.9 christos } 1450 1.1 christos 1451 1.1 christos /* Now the top of the stack is the class. */ 1452 1.1 christos 1453 1.1 christos if (! pr_fix_visibility (info, visibility)) 1454 1.1 christos goto out; 1455 1.9 christos 1456 1.1 christos if (! append_type (info, method_type) 1457 1.1 christos || ! append_type (info, " /* ") 1458 1.6 christos || ! append_type (info, physname) 1459 1.1 christos || ! append_type (info, " ")) 1460 1.1 christos goto out; 1461 1.1 christos if (context || voffset != 0) 1462 1.1 christos { 1463 1.1 christos char ab[22]; 1464 1.1 christos 1465 1.9 christos if (context) 1466 1.1 christos { 1467 1.8 christos if (! append_type (info, "context ") 1468 1.1 christos || ! append_type (info, context_type) 1469 1.1 christos || ! append_type (info, " ")) 1470 1.9 christos goto out; 1471 1.1 christos } 1472 1.1 christos print_vma (voffset, ab, true, false); 1473 1.9 christos if (! append_type (info, "voffset ") 1474 1.9 christos || ! append_type (info, ab)) 1475 1.9 christos goto out; 1476 1.9 christos } 1477 1.9 christos 1478 1.1 christos ret = append_type (info, " */;\n") && indent_type (info); 1479 1.1 christos out: 1480 1.1 christos free (method_type); 1481 1.1 christos free (context_type); 1482 1.8 christos return ret; 1483 1.1 christos } 1484 1.1 christos 1485 1.8 christos /* Add a static variant to a method. */ 1486 1.1 christos 1487 1.1 christos static bool 1488 1.1 christos pr_class_static_method_variant (void *p, const char *physname, 1489 1.1 christos enum debug_visibility visibility, 1490 1.1 christos bool constp, bool volatilep) 1491 1.1 christos { 1492 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1493 1.1 christos char *method_type; 1494 1.1 christos 1495 1.1 christos assert (info->stack != NULL); 1496 1.1 christos assert (info->stack->next != NULL); 1497 1.1 christos assert (info->stack->next->method != NULL); 1498 1.8 christos 1499 1.1 christos /* Put the const and volatile qualifiers on the type. */ 1500 1.1 christos if (volatilep) 1501 1.1 christos { 1502 1.1 christos if (! append_type (info, " volatile")) 1503 1.8 christos return false; 1504 1.1 christos } 1505 1.1 christos if (constp) 1506 1.1 christos { 1507 1.1 christos if (! append_type (info, " const")) 1508 1.8 christos return false; 1509 1.1 christos } 1510 1.1 christos 1511 1.1 christos /* Mark it as static. */ 1512 1.8 christos if (! prepend_type (info, "static ")) 1513 1.1 christos return false; 1514 1.1 christos 1515 1.1 christos /* Stick the name of the method into its type. */ 1516 1.1 christos if (! substitute_type (info, info->stack->next->method)) 1517 1.8 christos return false; 1518 1.1 christos 1519 1.1 christos /* Get the type. */ 1520 1.1 christos method_type = pop_type (info); 1521 1.9 christos if (method_type == NULL) 1522 1.9 christos return false; 1523 1.9 christos 1524 1.9 christos /* Now the top of the stack is the class. */ 1525 1.9 christos 1526 1.9 christos bool ret = (pr_fix_visibility (info, visibility) 1527 1.9 christos && append_type (info, method_type) 1528 1.9 christos && append_type (info, " /* ") 1529 1.1 christos && append_type (info, physname) 1530 1.1 christos && append_type (info, " */;\n") 1531 1.1 christos && indent_type (info)); 1532 1.1 christos free (method_type); 1533 1.8 christos return ret; 1534 1.1 christos } 1535 1.1 christos 1536 1.1 christos /* Finish up a method. */ 1537 1.1 christos 1538 1.9 christos static bool 1539 1.1 christos pr_class_end_method (void *p) 1540 1.8 christos { 1541 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1542 1.1 christos 1543 1.1 christos free (info->stack->method); 1544 1.1 christos info->stack->method = NULL; 1545 1.8 christos return true; 1546 1.1 christos } 1547 1.1 christos 1548 1.1 christos /* Finish up a class. */ 1549 1.1 christos 1550 1.1 christos static bool 1551 1.1 christos pr_end_class_type (void *p) 1552 1.1 christos { 1553 1.8 christos return pr_end_struct_type (p); 1554 1.1 christos } 1555 1.1 christos 1556 1.1 christos /* Push a type on the stack using a typedef name. */ 1557 1.1 christos 1558 1.1 christos static bool 1559 1.1 christos pr_typedef_type (void *p, const char *name) 1560 1.1 christos { 1561 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1562 1.1 christos 1563 1.8 christos return push_type (info, name); 1564 1.1 christos } 1565 1.1 christos 1566 1.1 christos /* Push a type on the stack using a tag name. */ 1567 1.1 christos 1568 1.1 christos static bool 1569 1.6 christos pr_tag_type (void *p, const char *name, unsigned int id, 1570 1.1 christos enum debug_type_kind kind) 1571 1.1 christos { 1572 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1573 1.1 christos const char *t, *tag; 1574 1.1 christos char idbuf[22]; 1575 1.1 christos 1576 1.1 christos switch (kind) 1577 1.1 christos { 1578 1.1 christos case DEBUG_KIND_STRUCT: 1579 1.1 christos t = "struct "; 1580 1.1 christos break; 1581 1.1 christos case DEBUG_KIND_UNION: 1582 1.1 christos t = "union "; 1583 1.1 christos break; 1584 1.1 christos case DEBUG_KIND_ENUM: 1585 1.1 christos t = "enum "; 1586 1.1 christos break; 1587 1.1 christos case DEBUG_KIND_CLASS: 1588 1.1 christos t = "class "; 1589 1.8 christos break; 1590 1.8 christos case DEBUG_KIND_UNION_CLASS: 1591 1.1 christos t = "union class "; 1592 1.1 christos break; 1593 1.1 christos default: 1594 1.8 christos /* PR 25625: Corrupt input can trigger this case. */ 1595 1.1 christos return false; 1596 1.1 christos } 1597 1.1 christos 1598 1.1 christos if (! push_type (info, t)) 1599 1.1 christos return false; 1600 1.1 christos if (name != NULL) 1601 1.1 christos tag = name; 1602 1.1 christos else 1603 1.1 christos { 1604 1.8 christos sprintf (idbuf, "%%anon%u", id); 1605 1.1 christos tag = idbuf; 1606 1.1 christos } 1607 1.1 christos 1608 1.1 christos if (! append_type (info, tag)) 1609 1.8 christos return false; 1610 1.1 christos if (name != NULL && kind != DEBUG_KIND_ENUM) 1611 1.1 christos { 1612 1.8 christos sprintf (idbuf, " /* id %u */", id); 1613 1.1 christos if (! append_type (info, idbuf)) 1614 1.1 christos return false; 1615 1.1 christos } 1616 1.1 christos 1617 1.8 christos return true; 1618 1.1 christos } 1619 1.1 christos 1620 1.1 christos /* Output a typedef. */ 1621 1.1 christos 1622 1.1 christos static bool 1623 1.1 christos pr_typdef (void *p, const char *name) 1624 1.8 christos { 1625 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1626 1.1 christos char *s; 1627 1.1 christos 1628 1.8 christos if (! substitute_type (info, name)) 1629 1.1 christos return false; 1630 1.1 christos 1631 1.1 christos s = pop_type (info); 1632 1.1 christos if (s == NULL) 1633 1.1 christos return false; 1634 1.1 christos 1635 1.8 christos indent (info); 1636 1.1 christos fprintf (info->f, "typedef %s;\n", s); 1637 1.1 christos 1638 1.1 christos free (s); 1639 1.1 christos 1640 1.1 christos return true; 1641 1.8 christos } 1642 1.1 christos 1643 1.1 christos /* Output a tag. The tag should already be in the string on the 1644 1.1 christos stack, so all we have to do here is print it out. */ 1645 1.1 christos 1646 1.1 christos static bool 1647 1.1 christos pr_tag (void *p, const char *name ATTRIBUTE_UNUSED) 1648 1.1 christos { 1649 1.8 christos struct pr_handle *info = (struct pr_handle *) p; 1650 1.1 christos char *t; 1651 1.1 christos 1652 1.1 christos t = pop_type (info); 1653 1.1 christos if (t == NULL) 1654 1.1 christos return false; 1655 1.1 christos 1656 1.8 christos indent (info); 1657 1.1 christos fprintf (info->f, "%s;\n", t); 1658 1.1 christos 1659 1.1 christos free (t); 1660 1.1 christos 1661 1.8 christos return true; 1662 1.1 christos } 1663 1.1 christos 1664 1.1 christos /* Output an integer constant. */ 1665 1.6 christos 1666 1.1 christos static bool 1667 1.1 christos pr_int_constant (void *p, const char *name, bfd_vma val) 1668 1.8 christos { 1669 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1670 1.8 christos char ab[22]; 1671 1.1 christos 1672 1.1 christos indent (info); 1673 1.1 christos print_vma (val, ab, false, false); 1674 1.1 christos fprintf (info->f, "const int %s = %s;\n", name, ab); 1675 1.8 christos return true; 1676 1.1 christos } 1677 1.1 christos 1678 1.1 christos /* Output a floating point constant. */ 1679 1.1 christos 1680 1.1 christos static bool 1681 1.1 christos pr_float_constant (void *p, const char *name, double val) 1682 1.8 christos { 1683 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1684 1.1 christos 1685 1.1 christos indent (info); 1686 1.1 christos fprintf (info->f, "const double %s = %g;\n", name, val); 1687 1.8 christos return true; 1688 1.1 christos } 1689 1.1 christos 1690 1.1 christos /* Output a typed constant. */ 1691 1.1 christos 1692 1.6 christos static bool 1693 1.1 christos pr_typed_constant (void *p, const char *name, bfd_vma val) 1694 1.1 christos { 1695 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1696 1.8 christos char *t; 1697 1.1 christos char ab[22]; 1698 1.1 christos 1699 1.8 christos t = pop_type (info); 1700 1.1 christos if (t == NULL) 1701 1.1 christos return false; 1702 1.1 christos 1703 1.1 christos indent (info); 1704 1.8 christos print_vma (val, ab, false, false); 1705 1.1 christos fprintf (info->f, "const %s %s = %s;\n", t, name, ab); 1706 1.1 christos 1707 1.1 christos free (t); 1708 1.1 christos 1709 1.8 christos return true; 1710 1.1 christos } 1711 1.1 christos 1712 1.1 christos /* Output a variable. */ 1713 1.1 christos 1714 1.1 christos static bool 1715 1.6 christos pr_variable (void *p, const char *name, enum debug_var_kind kind, 1716 1.1 christos bfd_vma val) 1717 1.1 christos { 1718 1.8 christos struct pr_handle *info = (struct pr_handle *) p; 1719 1.1 christos char *t; 1720 1.1 christos char ab[22]; 1721 1.1 christos 1722 1.8 christos if (! substitute_type (info, name)) 1723 1.1 christos return false; 1724 1.1 christos 1725 1.1 christos t = pop_type (info); 1726 1.1 christos if (t == NULL) 1727 1.1 christos return false; 1728 1.1 christos 1729 1.1 christos indent (info); 1730 1.1 christos switch (kind) 1731 1.1 christos { 1732 1.1 christos case DEBUG_STATIC: 1733 1.1 christos case DEBUG_LOCAL_STATIC: 1734 1.1 christos fprintf (info->f, "static "); 1735 1.1 christos break; 1736 1.1 christos case DEBUG_REGISTER: 1737 1.8 christos fprintf (info->f, "register "); 1738 1.1 christos break; 1739 1.1 christos default: 1740 1.1 christos break; 1741 1.1 christos } 1742 1.8 christos print_vma (val, ab, true, true); 1743 1.1 christos fprintf (info->f, "%s /* %s */;\n", t, ab); 1744 1.1 christos 1745 1.1 christos free (t); 1746 1.1 christos 1747 1.8 christos return true; 1748 1.8 christos } 1749 1.1 christos 1750 1.1 christos /* Start outputting a function. */ 1751 1.1 christos 1752 1.1 christos static bool 1753 1.1 christos pr_start_function (void *p, const char *name, bool global) 1754 1.8 christos { 1755 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1756 1.1 christos char *t; 1757 1.1 christos 1758 1.8 christos if (! substitute_type (info, name)) 1759 1.1 christos return false; 1760 1.1 christos 1761 1.1 christos t = pop_type (info); 1762 1.1 christos if (t == NULL) 1763 1.1 christos return false; 1764 1.1 christos 1765 1.9 christos indent (info); 1766 1.9 christos if (! global) 1767 1.1 christos fprintf (info->f, "static "); 1768 1.1 christos fprintf (info->f, "%s (", t); 1769 1.8 christos 1770 1.1 christos free (t); 1771 1.1 christos 1772 1.1 christos info->parameter = 1; 1773 1.1 christos 1774 1.8 christos return true; 1775 1.1 christos } 1776 1.1 christos 1777 1.1 christos /* Output a function parameter. */ 1778 1.1 christos 1779 1.1 christos static bool 1780 1.6 christos pr_function_parameter (void *p, const char *name, 1781 1.1 christos enum debug_parm_kind kind, bfd_vma val) 1782 1.1 christos { 1783 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1784 1.1 christos char *t; 1785 1.1 christos char ab[22]; 1786 1.8 christos 1787 1.1 christos if (kind == DEBUG_PARM_REFERENCE 1788 1.1 christos || kind == DEBUG_PARM_REF_REG) 1789 1.1 christos { 1790 1.8 christos if (! pr_reference_type (p)) 1791 1.1 christos return false; 1792 1.1 christos } 1793 1.1 christos 1794 1.8 christos if (! substitute_type (info, name)) 1795 1.1 christos return false; 1796 1.1 christos 1797 1.1 christos t = pop_type (info); 1798 1.1 christos if (t == NULL) 1799 1.1 christos return false; 1800 1.1 christos 1801 1.1 christos if (info->parameter != 1) 1802 1.8 christos fprintf (info->f, ", "); 1803 1.1 christos 1804 1.1 christos if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG) 1805 1.1 christos fprintf (info->f, "register "); 1806 1.1 christos 1807 1.1 christos print_vma (val, ab, true, true); 1808 1.1 christos fprintf (info->f, "%s /* %s */", t, ab); 1809 1.8 christos 1810 1.1 christos free (t); 1811 1.1 christos 1812 1.1 christos ++info->parameter; 1813 1.1 christos 1814 1.8 christos return true; 1815 1.1 christos } 1816 1.1 christos 1817 1.1 christos /* Start writing out a block. */ 1818 1.6 christos 1819 1.1 christos static bool 1820 1.1 christos pr_start_block (void *p, bfd_vma addr) 1821 1.1 christos { 1822 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1823 1.1 christos char ab[22]; 1824 1.1 christos 1825 1.1 christos if (info->parameter > 0) 1826 1.1 christos { 1827 1.8 christos fprintf (info->f, ")\n"); 1828 1.1 christos info->parameter = 0; 1829 1.1 christos } 1830 1.1 christos 1831 1.1 christos indent (info); 1832 1.8 christos print_vma (addr, ab, true, true); 1833 1.1 christos fprintf (info->f, "{ /* %s */\n", ab); 1834 1.1 christos 1835 1.1 christos info->indent += 2; 1836 1.1 christos 1837 1.8 christos return true; 1838 1.1 christos } 1839 1.1 christos 1840 1.1 christos /* Write out line number information. */ 1841 1.6 christos 1842 1.1 christos static bool 1843 1.1 christos pr_lineno (void *p, const char *filename, unsigned long lineno, bfd_vma addr) 1844 1.8 christos { 1845 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1846 1.1 christos char ab[22]; 1847 1.8 christos 1848 1.1 christos indent (info); 1849 1.1 christos print_vma (addr, ab, true, true); 1850 1.1 christos fprintf (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab); 1851 1.1 christos 1852 1.8 christos return true; 1853 1.1 christos } 1854 1.1 christos 1855 1.1 christos /* Finish writing out a block. */ 1856 1.6 christos 1857 1.1 christos static bool 1858 1.1 christos pr_end_block (void *p, bfd_vma addr) 1859 1.1 christos { 1860 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 1861 1.8 christos char ab[22]; 1862 1.1 christos 1863 1.1 christos info->indent -= 2; 1864 1.8 christos 1865 1.1 christos indent (info); 1866 1.1 christos print_vma (addr, ab, true, true); 1867 1.1 christos fprintf (info->f, "} /* %s */\n", ab); 1868 1.1 christos 1869 1.8 christos return true; 1870 1.1 christos } 1871 1.1 christos 1872 1.8 christos /* Finish writing out a function. */ 1873 1.1 christos 1874 1.1 christos static bool 1875 1.1 christos pr_end_function (void *p ATTRIBUTE_UNUSED) 1876 1.1 christos { 1877 1.1 christos return true; 1878 1.1 christos } 1879 1.1 christos 1880 1.1 christos /* Tags style generation functions start here. */ 1882 1.8 christos 1883 1.1 christos /* Variables for address to line translation. */ 1884 1.1 christos static bfd_vma pc; 1885 1.1 christos static const char *filename; 1886 1.1 christos static const char *functionname; 1887 1.1 christos static unsigned int line; 1888 1.1 christos static bool found; 1889 1.1 christos 1890 1.1 christos /* Look for an address in a section. This is called via 1891 1.1 christos bfd_map_over_sections. */ 1892 1.1 christos 1893 1.1 christos static void 1894 1.1 christos find_address_in_section (bfd *abfd, asection *section, void *data) 1895 1.1 christos { 1896 1.1 christos bfd_vma vma; 1897 1.7 christos bfd_size_type size; 1898 1.1 christos asymbol **syms = (asymbol **) data; 1899 1.1 christos 1900 1.7 christos if (found) 1901 1.1 christos return; 1902 1.1 christos 1903 1.1 christos if ((bfd_section_flags (section) & SEC_ALLOC) == 0) 1904 1.7 christos return; 1905 1.1 christos 1906 1.1 christos vma = bfd_section_vma (section); 1907 1.1 christos if (pc < vma) 1908 1.1 christos return; 1909 1.1 christos 1910 1.1 christos size = bfd_section_size (section); 1911 1.1 christos if (pc >= vma + size) 1912 1.1 christos return; 1913 1.1 christos 1914 1.1 christos found = bfd_find_nearest_line (abfd, section, syms, pc - vma, 1915 1.1 christos &filename, &functionname, &line); 1916 1.8 christos } 1917 1.1 christos 1918 1.1 christos static void 1919 1.1 christos translate_addresses (bfd *abfd, char *addr_hex, FILE *f, asymbol **syms) 1920 1.1 christos { 1921 1.1 christos pc = bfd_scan_vma (addr_hex, NULL, 16); 1922 1.1 christos found = false; 1923 1.1 christos bfd_map_over_sections (abfd, find_address_in_section, syms); 1924 1.1 christos 1925 1.1 christos if (! found) 1926 1.1 christos fprintf (f, "??"); 1927 1.8 christos else 1928 1.1 christos fprintf (f, "%u", line); 1929 1.1 christos } 1930 1.1 christos 1931 1.1 christos /* Start a new compilation unit. */ 1932 1.1 christos 1933 1.1 christos static bool 1934 1.9 christos tg_start_compilation_unit (void * p, const char *fname ATTRIBUTE_UNUSED) 1935 1.1 christos { 1936 1.8 christos struct pr_handle *info = (struct pr_handle *) p; 1937 1.1 christos 1938 1.1 christos free (info->filename); 1939 1.1 christos /* Should it be relative? best way to do it here?. */ 1940 1.1 christos info->filename = xstrdup (fname); 1941 1.8 christos 1942 1.1 christos return true; 1943 1.1 christos } 1944 1.1 christos 1945 1.1 christos /* Start a source file within a compilation unit. */ 1946 1.1 christos 1947 1.1 christos static bool 1948 1.9 christos tg_start_source (void *p, const char *fname) 1949 1.1 christos { 1950 1.8 christos struct pr_handle *info = (struct pr_handle *) p; 1951 1.1 christos 1952 1.1 christos free (info->filename); 1953 1.1 christos /* Should it be relative? best way to do it here?. */ 1954 1.1 christos info->filename = xstrdup (fname); 1955 1.8 christos 1956 1.1 christos return true; 1957 1.1 christos } 1958 1.1 christos 1959 1.1 christos /* Push an enum type onto the type stack. */ 1960 1.1 christos 1961 1.1 christos static bool 1962 1.6 christos tg_enum_type (void *p, const char *tag, const char **names, 1963 1.1 christos bfd_signed_vma *values) 1964 1.1 christos { 1965 1.8 christos struct pr_handle *info = (struct pr_handle *) p; 1966 1.1 christos unsigned int i; 1967 1.1 christos const char *name; 1968 1.1 christos char ab[22]; 1969 1.1 christos 1970 1.1 christos if (! pr_enum_type (p, tag, names, values)) 1971 1.1 christos return false; 1972 1.1 christos 1973 1.1 christos name = tag ? tag : "unknown"; 1974 1.1 christos /* Generate an entry for the enum. */ 1975 1.1 christos if (tag) 1976 1.1 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:e\ttype:%s\n", tag, 1977 1.1 christos info->filename, info->stack->type); 1978 1.8 christos 1979 1.1 christos /* Generate entries for the values. */ 1980 1.1 christos if (names != NULL) 1981 1.1 christos { 1982 1.1 christos for (i = 0; names[i] != NULL; i++) 1983 1.1 christos { 1984 1.8 christos print_vma (values[i], ab, false, false); 1985 1.1 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:g\tenum:%s\tvalue:%s\n", 1986 1.1 christos names[i], info->filename, name, ab); 1987 1.1 christos } 1988 1.1 christos } 1989 1.8 christos 1990 1.1 christos return true; 1991 1.8 christos } 1992 1.1 christos 1993 1.1 christos /* Start accumulating a struct type. */ 1994 1.1 christos 1995 1.1 christos static bool 1996 1.1 christos tg_start_struct_type (void *p, const char *tag, unsigned int id, 1997 1.1 christos bool structp, 1998 1.1 christos unsigned int size ATTRIBUTE_UNUSED) 1999 1.1 christos { 2000 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2001 1.1 christos const char *name; 2002 1.1 christos char idbuf[20]; 2003 1.1 christos 2004 1.1 christos if (tag != NULL) 2005 1.1 christos name = tag; 2006 1.1 christos else 2007 1.8 christos { 2008 1.1 christos name = idbuf; 2009 1.1 christos sprintf (idbuf, "%%anon%u", id); 2010 1.1 christos } 2011 1.1 christos 2012 1.1 christos if (! push_type (info, name)) 2013 1.1 christos return false; 2014 1.1 christos 2015 1.1 christos info->stack->flavor = structp ? "struct" : "union"; 2016 1.1 christos 2017 1.1 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:%c\n", name, info->filename, 2018 1.1 christos info->stack->flavor[0]); 2019 1.1 christos 2020 1.1 christos info->stack->visibility = DEBUG_VISIBILITY_PUBLIC; 2021 1.8 christos 2022 1.1 christos return indent_type (info); 2023 1.1 christos } 2024 1.1 christos 2025 1.1 christos /* Output the visibility of a field in a struct. */ 2026 1.1 christos 2027 1.8 christos static bool 2028 1.1 christos tg_fix_visibility (struct pr_handle *info, enum debug_visibility visibility) 2029 1.1 christos { 2030 1.1 christos assert (info->stack != NULL); 2031 1.1 christos 2032 1.1 christos if (info->stack->visibility == visibility) 2033 1.8 christos return true; 2034 1.1 christos 2035 1.1 christos assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE); 2036 1.1 christos 2037 1.1 christos info->stack->visibility = visibility; 2038 1.8 christos 2039 1.1 christos return true; 2040 1.1 christos } 2041 1.1 christos 2042 1.1 christos /* Add a field to a struct type. */ 2043 1.1 christos 2044 1.1 christos static bool 2045 1.1 christos tg_struct_field (void *p, const char *name, bfd_vma bitpos ATTRIBUTE_UNUSED, 2046 1.1 christos bfd_vma bitsize ATTRIBUTE_UNUSED, 2047 1.1 christos enum debug_visibility visibility) 2048 1.8 christos { 2049 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2050 1.1 christos char *t; 2051 1.9 christos 2052 1.9 christos t = pop_type (info); 2053 1.9 christos if (t == NULL) 2054 1.9 christos return false; 2055 1.1 christos 2056 1.1 christos if (! tg_fix_visibility (info, visibility)) 2057 1.1 christos { 2058 1.9 christos free (t); 2059 1.9 christos return false; 2060 1.9 christos } 2061 1.9 christos 2062 1.1 christos /* It happens, a bug? */ 2063 1.1 christos if (! name[0]) 2064 1.1 christos { 2065 1.1 christos free (t); 2066 1.1 christos return true; 2067 1.9 christos } 2068 1.9 christos 2069 1.8 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:m\ttype:%s\t%s:%s\taccess:%s\n", 2070 1.1 christos name, info->filename, t, info->stack->flavor, info->stack->type, 2071 1.1 christos visibility_name (visibility)); 2072 1.1 christos 2073 1.1 christos free (t); 2074 1.8 christos 2075 1.1 christos return true; 2076 1.1 christos } 2077 1.1 christos 2078 1.1 christos /* Finish a struct type. */ 2079 1.8 christos 2080 1.1 christos static bool 2081 1.1 christos tg_end_struct_type (void *p ATTRIBUTE_UNUSED) 2082 1.1 christos { 2083 1.1 christos assert (((struct pr_handle *) p)->stack != NULL); 2084 1.8 christos 2085 1.1 christos return true; 2086 1.8 christos } 2087 1.8 christos 2088 1.1 christos /* Start a class type. */ 2089 1.1 christos 2090 1.1 christos static bool 2091 1.1 christos tg_start_class_type (void *p, const char *tag, unsigned int id, 2092 1.7 christos bool structp, unsigned int size, 2093 1.9 christos bool vptr, bool ownvptr) 2094 1.1 christos { 2095 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2096 1.1 christos char *tv = NULL; 2097 1.1 christos const char *name; 2098 1.1 christos char idbuf[20]; 2099 1.1 christos bool ret = false; 2100 1.1 christos 2101 1.8 christos info->indent += 2; 2102 1.1 christos 2103 1.1 christos if (vptr && ! ownvptr) 2104 1.1 christos { 2105 1.1 christos tv = pop_type (info); 2106 1.1 christos if (tv == NULL) 2107 1.1 christos return false; 2108 1.1 christos } 2109 1.1 christos 2110 1.1 christos if (tag != NULL) 2111 1.1 christos name = tag; 2112 1.1 christos else 2113 1.9 christos { 2114 1.1 christos sprintf (idbuf, "%%anon%u", id); 2115 1.1 christos name = idbuf; 2116 1.9 christos } 2117 1.1 christos 2118 1.1 christos if (! push_type (info, name)) 2119 1.1 christos goto out; 2120 1.1 christos 2121 1.1 christos info->stack->flavor = structp ? "class" : "union class"; 2122 1.1 christos free (info->stack->parents); 2123 1.1 christos info->stack->parents = NULL; 2124 1.9 christos 2125 1.1 christos if (size != 0 || vptr || ownvptr || tag != NULL) 2126 1.1 christos { 2127 1.1 christos if (vptr) 2128 1.9 christos { 2129 1.1 christos if (! append_type (info, " vtable ")) 2130 1.1 christos goto out; 2131 1.1 christos if (ownvptr) 2132 1.1 christos { 2133 1.1 christos if (! append_type (info, "self ")) 2134 1.9 christos goto out; 2135 1.1 christos } 2136 1.1 christos else 2137 1.1 christos { 2138 1.1 christos if (! append_type (info, tv) 2139 1.1 christos || ! append_type (info, " ")) 2140 1.1 christos goto out; 2141 1.9 christos } 2142 1.9 christos } 2143 1.9 christos } 2144 1.9 christos 2145 1.1 christos info->stack->visibility = DEBUG_VISIBILITY_PRIVATE; 2146 1.1 christos 2147 1.1 christos ret = true; 2148 1.1 christos out: 2149 1.8 christos free (tv); 2150 1.1 christos return ret; 2151 1.1 christos } 2152 1.1 christos 2153 1.1 christos /* Add a static member to a class. */ 2154 1.1 christos 2155 1.1 christos static bool 2156 1.1 christos tg_class_static_member (void *p, const char *name, 2157 1.1 christos const char *physname ATTRIBUTE_UNUSED, 2158 1.1 christos enum debug_visibility visibility) 2159 1.1 christos { 2160 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2161 1.9 christos char *t; 2162 1.1 christos int len_var, len_class; 2163 1.1 christos char *full_name; 2164 1.1 christos 2165 1.1 christos len_var = strlen (name); 2166 1.1 christos len_class = strlen (info->stack->next->type); 2167 1.8 christos full_name = xmalloc (len_var + len_class + 3); 2168 1.1 christos sprintf (full_name, "%s::%s", info->stack->next->type, name); 2169 1.1 christos 2170 1.1 christos if (! substitute_type (info, full_name)) 2171 1.1 christos { 2172 1.1 christos free (full_name); 2173 1.8 christos return false; 2174 1.1 christos } 2175 1.1 christos 2176 1.1 christos if (! prepend_type (info, "static ")) 2177 1.1 christos { 2178 1.1 christos free (full_name); 2179 1.1 christos return false; 2180 1.8 christos } 2181 1.1 christos 2182 1.1 christos t = pop_type (info); 2183 1.1 christos if (t == NULL) 2184 1.1 christos { 2185 1.1 christos free (full_name); 2186 1.1 christos return false; 2187 1.8 christos } 2188 1.1 christos 2189 1.1 christos if (! tg_fix_visibility (info, visibility)) 2190 1.1 christos { 2191 1.1 christos free (t); 2192 1.1 christos free (full_name); 2193 1.1 christos return false; 2194 1.1 christos } 2195 1.1 christos 2196 1.8 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:x\ttype:%s\tclass:%s\taccess:%s\n", 2197 1.1 christos name, info->filename, t, info->stack->type, 2198 1.1 christos visibility_name (visibility)); 2199 1.1 christos free (t); 2200 1.1 christos free (full_name); 2201 1.8 christos 2202 1.1 christos return true; 2203 1.8 christos } 2204 1.1 christos 2205 1.1 christos /* Add a base class to a class. */ 2206 1.1 christos 2207 1.1 christos static bool 2208 1.1 christos tg_class_baseclass (void *p, bfd_vma bitpos ATTRIBUTE_UNUSED, 2209 1.1 christos bool is_virtual, enum debug_visibility visibility) 2210 1.1 christos { 2211 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2212 1.1 christos char *t; 2213 1.8 christos const char *prefix; 2214 1.1 christos 2215 1.1 christos assert (info->stack != NULL && info->stack->next != NULL); 2216 1.1 christos 2217 1.9 christos t = pop_type (info); 2218 1.9 christos if (t == NULL) 2219 1.9 christos return false; 2220 1.9 christos 2221 1.9 christos /* Push it back on to take advantage of the prepend_type and 2222 1.9 christos append_type routines. */ 2223 1.9 christos if (! push_type (info, t + (startswith (t, "class ") 2224 1.1 christos ? sizeof "class " - 1 : 0))) 2225 1.1 christos { 2226 1.1 christos free (t); 2227 1.1 christos return false; 2228 1.8 christos } 2229 1.1 christos free (t); 2230 1.1 christos 2231 1.1 christos if (is_virtual) 2232 1.1 christos { 2233 1.1 christos if (! prepend_type (info, "virtual ")) 2234 1.1 christos return false; 2235 1.1 christos } 2236 1.1 christos 2237 1.1 christos switch (visibility) 2238 1.1 christos { 2239 1.1 christos case DEBUG_VISIBILITY_PUBLIC: 2240 1.1 christos prefix = "public "; 2241 1.1 christos break; 2242 1.1 christos case DEBUG_VISIBILITY_PROTECTED: 2243 1.1 christos prefix = "protected "; 2244 1.1 christos break; 2245 1.1 christos case DEBUG_VISIBILITY_PRIVATE: 2246 1.1 christos prefix = "private "; 2247 1.1 christos break; 2248 1.8 christos default: 2249 1.1 christos prefix = "/* unknown visibility */ "; 2250 1.1 christos break; 2251 1.1 christos } 2252 1.8 christos 2253 1.1 christos if (! prepend_type (info, prefix)) 2254 1.9 christos return false; 2255 1.9 christos 2256 1.1 christos t = pop_type (info); 2257 1.9 christos if (t == NULL) 2258 1.1 christos return false; 2259 1.1 christos 2260 1.1 christos bool ret = ((!info->stack->parents || append_parent (info, ", ")) 2261 1.1 christos && append_parent (info, t)); 2262 1.8 christos free (t); 2263 1.1 christos return ret; 2264 1.1 christos } 2265 1.8 christos 2266 1.1 christos /* Add a variant to a method. */ 2267 1.8 christos 2268 1.1 christos static bool 2269 1.1 christos tg_class_method_variant (void *p, const char *physname ATTRIBUTE_UNUSED, 2270 1.1 christos enum debug_visibility visibility, 2271 1.1 christos bool constp, bool volatilep, 2272 1.1 christos bfd_vma voffset ATTRIBUTE_UNUSED, 2273 1.1 christos bool context) 2274 1.1 christos { 2275 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2276 1.1 christos char *method_type; 2277 1.1 christos char *context_type; 2278 1.1 christos char *method_name; 2279 1.1 christos 2280 1.1 christos assert (info->stack != NULL); 2281 1.8 christos assert (info->stack->next != NULL); 2282 1.1 christos 2283 1.1 christos /* Put the const and volatile qualifiers on the type. */ 2284 1.1 christos if (volatilep) 2285 1.1 christos { 2286 1.8 christos if (! append_type (info, " volatile")) 2287 1.1 christos return false; 2288 1.1 christos } 2289 1.1 christos if (constp) 2290 1.1 christos { 2291 1.1 christos if (! append_type (info, " const")) 2292 1.1 christos return false; 2293 1.1 christos } 2294 1.1 christos 2295 1.1 christos method_name = strdup (context ? info->stack->next->next->method 2296 1.8 christos : info->stack->next->method); 2297 1.1 christos 2298 1.1 christos /* Stick the name of the method into its type. */ 2299 1.1 christos if (! substitute_type (info, method_name)) 2300 1.1 christos { 2301 1.1 christos free (method_name); 2302 1.1 christos return false; 2303 1.1 christos } 2304 1.8 christos 2305 1.1 christos /* Get the type. */ 2306 1.1 christos method_type = pop_type (info); 2307 1.1 christos if (method_type == NULL) 2308 1.1 christos { 2309 1.1 christos free (method_name); 2310 1.1 christos return false; 2311 1.1 christos } 2312 1.1 christos 2313 1.1 christos /* Pull off the context type if there is one. */ 2314 1.1 christos if (! context) 2315 1.1 christos context_type = NULL; 2316 1.1 christos else 2317 1.8 christos { 2318 1.1 christos context_type = pop_type (info); 2319 1.1 christos if (context_type == NULL) 2320 1.1 christos { 2321 1.1 christos free (method_type); 2322 1.1 christos free (method_name); 2323 1.1 christos return false; 2324 1.1 christos } 2325 1.1 christos } 2326 1.1 christos 2327 1.8 christos /* Now the top of the stack is the class. */ 2328 1.1 christos if (! tg_fix_visibility (info, visibility)) 2329 1.1 christos { 2330 1.1 christos free (method_type); 2331 1.1 christos free (method_name); 2332 1.1 christos free (context_type); 2333 1.1 christos return false; 2334 1.1 christos } 2335 1.1 christos 2336 1.8 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\n", 2337 1.1 christos method_name, info->filename, method_type, info->stack->type); 2338 1.1 christos free (method_type); 2339 1.1 christos free (method_name); 2340 1.1 christos free (context_type); 2341 1.8 christos 2342 1.1 christos return true; 2343 1.1 christos } 2344 1.1 christos 2345 1.8 christos /* Add a static variant to a method. */ 2346 1.1 christos 2347 1.1 christos static bool 2348 1.1 christos tg_class_static_method_variant (void *p, 2349 1.1 christos const char *physname ATTRIBUTE_UNUSED, 2350 1.1 christos enum debug_visibility visibility, 2351 1.1 christos bool constp, bool volatilep) 2352 1.1 christos { 2353 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2354 1.1 christos char *method_type; 2355 1.1 christos char *method_name; 2356 1.1 christos 2357 1.1 christos assert (info->stack != NULL); 2358 1.1 christos assert (info->stack->next != NULL); 2359 1.8 christos assert (info->stack->next->method != NULL); 2360 1.1 christos 2361 1.1 christos /* Put the const and volatile qualifiers on the type. */ 2362 1.1 christos if (volatilep) 2363 1.1 christos { 2364 1.8 christos if (! append_type (info, " volatile")) 2365 1.1 christos return false; 2366 1.1 christos } 2367 1.1 christos if (constp) 2368 1.1 christos { 2369 1.8 christos if (! append_type (info, " const")) 2370 1.1 christos return false; 2371 1.1 christos } 2372 1.1 christos 2373 1.1 christos /* Mark it as static. */ 2374 1.1 christos if (! prepend_type (info, "static ")) 2375 1.1 christos return false; 2376 1.8 christos 2377 1.1 christos method_name = strdup (info->stack->next->method); 2378 1.1 christos /* Stick the name of the method into its type. */ 2379 1.1 christos if (! substitute_type (info, info->stack->next->method)) 2380 1.1 christos { 2381 1.1 christos free (method_name); 2382 1.1 christos return false; 2383 1.1 christos } 2384 1.8 christos 2385 1.1 christos /* Get the type. */ 2386 1.1 christos method_type = pop_type (info); 2387 1.1 christos if (method_type == NULL) 2388 1.1 christos { 2389 1.1 christos free (method_name); 2390 1.1 christos return false; 2391 1.1 christos } 2392 1.8 christos 2393 1.1 christos /* Now the top of the stack is the class. */ 2394 1.1 christos if (! tg_fix_visibility (info, visibility)) 2395 1.1 christos { 2396 1.1 christos free (method_type); 2397 1.1 christos free (method_name); 2398 1.1 christos return false; 2399 1.1 christos } 2400 1.1 christos 2401 1.8 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\taccess:%s\n", 2402 1.1 christos method_name, info->filename, method_type, info->stack->type, 2403 1.1 christos visibility_name (visibility)); 2404 1.1 christos free (method_type); 2405 1.1 christos free (method_name); 2406 1.8 christos 2407 1.1 christos return true; 2408 1.1 christos } 2409 1.1 christos 2410 1.1 christos /* Finish up a class. */ 2411 1.1 christos 2412 1.1 christos static bool 2413 1.9 christos tg_end_class_type (void *p) 2414 1.1 christos { 2415 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2416 1.1 christos 2417 1.9 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:c\ttype:%s", info->stack->type, 2418 1.1 christos info->filename, info->stack->flavor); 2419 1.1 christos if (info->stack->parents) 2420 1.1 christos { 2421 1.1 christos fprintf (info->f, "\tinherits:%s", info->stack->parents); 2422 1.1 christos free (info->stack->parents); 2423 1.1 christos info->stack->parents = NULL; 2424 1.1 christos } 2425 1.1 christos fputc ('\n', info->f); 2426 1.8 christos 2427 1.1 christos return tg_end_struct_type (p); 2428 1.1 christos } 2429 1.1 christos 2430 1.1 christos /* Push a type on the stack using a tag name. */ 2431 1.1 christos 2432 1.1 christos static bool 2433 1.1 christos tg_tag_type (void *p, const char *name, unsigned int id, 2434 1.1 christos enum debug_type_kind kind) 2435 1.1 christos { 2436 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2437 1.1 christos const char *t, *tag; 2438 1.1 christos char idbuf[20]; 2439 1.1 christos 2440 1.1 christos switch (kind) 2441 1.1 christos { 2442 1.1 christos case DEBUG_KIND_STRUCT: 2443 1.1 christos t = "struct "; 2444 1.1 christos break; 2445 1.1 christos case DEBUG_KIND_UNION: 2446 1.1 christos t = "union "; 2447 1.1 christos break; 2448 1.1 christos case DEBUG_KIND_ENUM: 2449 1.1 christos t = "enum "; 2450 1.1 christos break; 2451 1.1 christos case DEBUG_KIND_CLASS: 2452 1.1 christos t = "class "; 2453 1.8 christos break; 2454 1.1 christos case DEBUG_KIND_UNION_CLASS: 2455 1.1 christos t = "union class "; 2456 1.1 christos break; 2457 1.8 christos default: 2458 1.1 christos abort (); 2459 1.1 christos return false; 2460 1.1 christos } 2461 1.1 christos 2462 1.1 christos if (! push_type (info, t)) 2463 1.1 christos return false; 2464 1.1 christos if (name != NULL) 2465 1.1 christos tag = name; 2466 1.1 christos else 2467 1.8 christos { 2468 1.1 christos sprintf (idbuf, "%%anon%u", id); 2469 1.8 christos tag = idbuf; 2470 1.1 christos } 2471 1.1 christos 2472 1.1 christos if (! append_type (info, tag)) 2473 1.1 christos return false; 2474 1.8 christos 2475 1.1 christos return true; 2476 1.1 christos } 2477 1.1 christos 2478 1.1 christos /* Output a typedef. */ 2479 1.1 christos 2480 1.1 christos static bool 2481 1.1 christos tg_typdef (void *p, const char *name) 2482 1.8 christos { 2483 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2484 1.1 christos char *s; 2485 1.1 christos 2486 1.1 christos s = pop_type (info); 2487 1.1 christos if (s == NULL) 2488 1.1 christos return false; 2489 1.8 christos 2490 1.1 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:t\ttype:%s\n", name, 2491 1.1 christos info->filename, s); 2492 1.1 christos 2493 1.1 christos free (s); 2494 1.1 christos 2495 1.8 christos return true; 2496 1.1 christos } 2497 1.1 christos 2498 1.1 christos /* Output a tag. The tag should already be in the string on the 2499 1.1 christos stack, so all we have to do here is print it out. */ 2500 1.1 christos 2501 1.1 christos static bool 2502 1.1 christos tg_tag (void *p ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED) 2503 1.8 christos { 2504 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2505 1.1 christos char *t; 2506 1.8 christos 2507 1.1 christos t = pop_type (info); 2508 1.1 christos if (t == NULL) 2509 1.1 christos return false; 2510 1.1 christos free (t); 2511 1.8 christos 2512 1.1 christos return true; 2513 1.1 christos } 2514 1.1 christos 2515 1.6 christos /* Output an integer constant. */ 2516 1.1 christos 2517 1.1 christos static bool 2518 1.8 christos tg_int_constant (void *p, const char *name, bfd_vma val) 2519 1.1 christos { 2520 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2521 1.8 christos char ab[22]; 2522 1.1 christos 2523 1.1 christos indent (info); 2524 1.1 christos print_vma (val, ab, false, false); 2525 1.1 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const int\tvalue:%s\n", 2526 1.8 christos name, info->filename, ab); 2527 1.1 christos return true; 2528 1.1 christos } 2529 1.1 christos 2530 1.1 christos /* Output a floating point constant. */ 2531 1.1 christos 2532 1.1 christos static bool 2533 1.1 christos tg_float_constant (void *p, const char *name, double val) 2534 1.8 christos { 2535 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2536 1.1 christos 2537 1.1 christos indent (info); 2538 1.1 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const double\tvalue:%g\n", 2539 1.8 christos name, info->filename, val); 2540 1.1 christos return true; 2541 1.1 christos } 2542 1.1 christos 2543 1.1 christos /* Output a typed constant. */ 2544 1.6 christos 2545 1.1 christos static bool 2546 1.1 christos tg_typed_constant (void *p, const char *name, bfd_vma val) 2547 1.1 christos { 2548 1.8 christos struct pr_handle *info = (struct pr_handle *) p; 2549 1.1 christos char *t; 2550 1.1 christos char ab[22]; 2551 1.8 christos 2552 1.1 christos t = pop_type (info); 2553 1.1 christos if (t == NULL) 2554 1.1 christos return false; 2555 1.1 christos 2556 1.1 christos indent (info); 2557 1.8 christos print_vma (val, ab, false, false); 2558 1.1 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const %s\tvalue:%s\n", 2559 1.1 christos name, info->filename, t, ab); 2560 1.1 christos 2561 1.1 christos free (t); 2562 1.8 christos 2563 1.1 christos return true; 2564 1.1 christos } 2565 1.1 christos 2566 1.1 christos /* Output a variable. */ 2567 1.1 christos 2568 1.1 christos static bool 2569 1.1 christos tg_variable (void *p, const char *name, enum debug_var_kind kind, 2570 1.1 christos bfd_vma val ATTRIBUTE_UNUSED) 2571 1.8 christos { 2572 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2573 1.1 christos char *t, *dname, *from_class; 2574 1.1 christos 2575 1.7 christos t = pop_type (info); 2576 1.1 christos if (t == NULL) 2577 1.1 christos return false; 2578 1.1 christos 2579 1.1 christos dname = NULL; 2580 1.1 christos if (info->demangler) 2581 1.1 christos dname = info->demangler (info->abfd, name, demangle_flags); 2582 1.1 christos 2583 1.1 christos from_class = NULL; 2584 1.1 christos if (dname != NULL) 2585 1.1 christos { 2586 1.1 christos char *sep; 2587 1.1 christos sep = strstr (dname, "::"); 2588 1.1 christos if (sep) 2589 1.1 christos { 2590 1.1 christos *sep = 0; 2591 1.1 christos name = sep + 2; 2592 1.1 christos from_class = dname; 2593 1.1 christos } 2594 1.1 christos else 2595 1.1 christos /* Obscure types as vts and type_info nodes. */ 2596 1.1 christos name = dname; 2597 1.1 christos } 2598 1.1 christos 2599 1.1 christos fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:%s", name, info->filename, t); 2600 1.1 christos 2601 1.1 christos switch (kind) 2602 1.1 christos { 2603 1.1 christos case DEBUG_STATIC: 2604 1.1 christos case DEBUG_LOCAL_STATIC: 2605 1.1 christos fprintf (info->f, "\tfile:"); 2606 1.1 christos break; 2607 1.1 christos case DEBUG_REGISTER: 2608 1.1 christos fprintf (info->f, "\tregister:"); 2609 1.1 christos break; 2610 1.1 christos default: 2611 1.1 christos break; 2612 1.1 christos } 2613 1.1 christos 2614 1.1 christos if (from_class) 2615 1.1 christos fprintf (info->f, "\tclass:%s", from_class); 2616 1.1 christos 2617 1.1 christos if (dname) 2618 1.8 christos free (dname); 2619 1.1 christos 2620 1.1 christos fprintf (info->f, "\n"); 2621 1.1 christos 2622 1.1 christos free (t); 2623 1.8 christos 2624 1.8 christos return true; 2625 1.1 christos } 2626 1.1 christos 2627 1.1 christos /* Start outputting a function. */ 2628 1.1 christos 2629 1.1 christos static bool 2630 1.1 christos tg_start_function (void *p, const char *name, bool global) 2631 1.1 christos { 2632 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2633 1.1 christos char *dname; 2634 1.1 christos 2635 1.1 christos if (! global) 2636 1.7 christos info->stack->flavor = "static"; 2637 1.1 christos else 2638 1.1 christos info->stack->flavor = NULL; 2639 1.8 christos 2640 1.1 christos dname = NULL; 2641 1.9 christos if (info->demangler) 2642 1.1 christos dname = info->demangler (info->abfd, name, demangle_flags); 2643 1.1 christos 2644 1.1 christos if (! substitute_type (info, dname ? dname : name)) 2645 1.1 christos return false; 2646 1.1 christos 2647 1.1 christos free (info->stack->method); 2648 1.1 christos info->stack->method = NULL; 2649 1.1 christos if (dname != NULL) 2650 1.9 christos { 2651 1.1 christos char *sep; 2652 1.1 christos sep = strstr (dname, "::"); 2653 1.1 christos if (sep) 2654 1.1 christos { 2655 1.1 christos info->stack->method = dname; 2656 1.9 christos dname = NULL; 2657 1.1 christos *sep = 0; 2658 1.1 christos name = sep + 2; 2659 1.1 christos } 2660 1.1 christos else 2661 1.1 christos { 2662 1.1 christos info->stack->method = xstrdup (""); 2663 1.1 christos name = dname; 2664 1.1 christos } 2665 1.9 christos sep = strchr (name, '('); 2666 1.1 christos if (sep) 2667 1.9 christos *sep = 0; 2668 1.1 christos /* Obscure functions as type_info function. */ 2669 1.1 christos } 2670 1.8 christos 2671 1.1 christos free (info->stack->parents); 2672 1.1 christos info->stack->parents = strdup (name); 2673 1.1 christos free (dname); 2674 1.8 christos 2675 1.1 christos if (! info->stack->method && ! append_type (info, "(")) 2676 1.1 christos return false; 2677 1.1 christos 2678 1.1 christos info->parameter = 1; 2679 1.8 christos 2680 1.1 christos return true; 2681 1.1 christos } 2682 1.1 christos 2683 1.1 christos /* Output a function parameter. */ 2684 1.1 christos 2685 1.1 christos static bool 2686 1.1 christos tg_function_parameter (void *p, const char *name, enum debug_parm_kind kind, 2687 1.1 christos bfd_vma val ATTRIBUTE_UNUSED) 2688 1.1 christos { 2689 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2690 1.8 christos char *t; 2691 1.1 christos 2692 1.1 christos if (kind == DEBUG_PARM_REFERENCE 2693 1.1 christos || kind == DEBUG_PARM_REF_REG) 2694 1.8 christos { 2695 1.1 christos if (! pr_reference_type (p)) 2696 1.1 christos return false; 2697 1.1 christos } 2698 1.8 christos 2699 1.1 christos if (! substitute_type (info, name)) 2700 1.1 christos return false; 2701 1.1 christos 2702 1.1 christos t = pop_type (info); 2703 1.9 christos if (t == NULL) 2704 1.9 christos return false; 2705 1.9 christos 2706 1.9 christos if (! info->stack->method) 2707 1.1 christos { 2708 1.1 christos if (info->parameter != 1 && ! append_type (info, ", ")) 2709 1.1 christos { 2710 1.9 christos free (t); 2711 1.9 christos return false; 2712 1.9 christos } 2713 1.9 christos 2714 1.1 christos if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG) 2715 1.1 christos if (! append_type (info, "register ")) 2716 1.9 christos { 2717 1.9 christos free (t); 2718 1.9 christos return false; 2719 1.9 christos } 2720 1.1 christos 2721 1.1 christos if (! append_type (info, t)) 2722 1.1 christos { 2723 1.1 christos free (t); 2724 1.1 christos return false; 2725 1.1 christos } 2726 1.8 christos } 2727 1.1 christos 2728 1.1 christos free (t); 2729 1.1 christos 2730 1.1 christos ++info->parameter; 2731 1.8 christos 2732 1.1 christos return true; 2733 1.1 christos } 2734 1.1 christos 2735 1.6 christos /* Start writing out a block. */ 2736 1.1 christos 2737 1.8 christos static bool 2738 1.1 christos tg_start_block (void *p, bfd_vma addr) 2739 1.1 christos { 2740 1.1 christos struct pr_handle *info = (struct pr_handle *) p; 2741 1.1 christos char ab[22], kind, *partof; 2742 1.1 christos char *t; 2743 1.1 christos bool local; 2744 1.1 christos 2745 1.1 christos if (info->parameter > 0) 2746 1.9 christos { 2747 1.1 christos info->parameter = 0; 2748 1.8 christos 2749 1.1 christos /* Delayed name. */ 2750 1.1 christos fprintf (info->f, "%s\t%s\t", info->stack->parents, info->filename); 2751 1.1 christos free (info->stack->parents); 2752 1.1 christos info->stack->parents = NULL; 2753 1.1 christos 2754 1.1 christos print_vma (addr, ab, true, true); 2755 1.1 christos translate_addresses (info->abfd, ab, info->f, info->syms); 2756 1.1 christos local = info->stack->flavor != NULL; 2757 1.1 christos if (info->stack->method && *info->stack->method) 2758 1.1 christos { 2759 1.1 christos kind = 'm'; 2760 1.1 christos partof = (char *) info->stack->method; 2761 1.8 christos } 2762 1.1 christos else 2763 1.1 christos { 2764 1.1 christos kind = 'f'; 2765 1.8 christos partof = NULL; 2766 1.1 christos if (! info->stack->method && ! append_type (info, ")")) 2767 1.9 christos return false; 2768 1.1 christos } 2769 1.1 christos t = pop_type (info); 2770 1.1 christos if (t == NULL) 2771 1.9 christos return false; 2772 1.1 christos fprintf (info->f, ";\"\tkind:%c\ttype:%s", kind, t); 2773 1.9 christos free (t); 2774 1.9 christos if (local) 2775 1.1 christos fputs ("\tfile:", info->f); 2776 1.1 christos if (partof) 2777 1.8 christos fprintf (info->f, "\tclass:%s", partof); 2778 1.1 christos fputc ('\n', info->f); 2779 1.1 christos free (info->stack->method); 2780 1.1 christos info->stack->method = NULL; 2781 1.1 christos } 2782 1.8 christos 2783 1.1 christos return true; 2784 1.1 christos } 2785 1.1 christos 2786 1.1 christos /* Write out line number information. */ 2787 1.8 christos 2788 1.1 christos static bool 2789 1.1 christos tg_lineno (void *p ATTRIBUTE_UNUSED, const char *fname ATTRIBUTE_UNUSED, 2790 1.1 christos unsigned long lineno ATTRIBUTE_UNUSED, 2791 1.1 christos bfd_vma addr ATTRIBUTE_UNUSED) 2792 1.8 christos { 2793 1.1 christos return true; 2794 1.1 christos } 2795 1.8 christos 2796 1.1 christos /* Finish writing out a block. */ 2797 1.1 christos 2798 1.1 christos static bool 2799 1.1 christos tg_end_block (void *p ATTRIBUTE_UNUSED, bfd_vma addr ATTRIBUTE_UNUSED) 2800 1.1 christos { 2801 1.1 christos return true; 2802 1.1 christos } 2803 1.1 christos 2804 1.1 christos /* Convert the visibility value into a human readable name. */ 2805 1.1 christos 2806 1.1 christos static const char * 2807 1.1 christos visibility_name (enum debug_visibility visibility) 2808 1.1 christos { 2809 1.1 christos const char *s; 2810 1.1 christos 2811 1.1 christos switch (visibility) 2812 1.1 christos { 2813 1.1 christos case DEBUG_VISIBILITY_PUBLIC: 2814 1.1 christos s = "public"; 2815 1.1 christos break; 2816 1.1 christos case DEBUG_VISIBILITY_PRIVATE: 2817 1.1 christos s = "private"; 2818 1.1 christos break; 2819 1.1 christos case DEBUG_VISIBILITY_PROTECTED: 2820 1.1 christos s = "protected"; 2821 1.10 christos break; 2822 1.1 christos case DEBUG_VISIBILITY_IGNORE: 2823 1.1 christos s = "/* ignore */"; 2824 1.1 christos break; 2825 default: 2826 abort (); 2827 return NULL; 2828 } 2829 return s; 2830 } 2831