prdbg.c revision 60484
1/* prdbg.c -- Print out generic debugging information. 2 Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. 3 Written by Ian Lance Taylor <ian@cygnus.com>. 4 5 This file is part of GNU Binutils. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 02111-1307, USA. */ 21 22/* This file prints out the generic debugging information, by 23 supplying a set of routines to debug_write. */ 24 25#include <stdio.h> 26#include <assert.h> 27 28#include "bfd.h" 29#include "bucomm.h" 30#include "libiberty.h" 31#include "debug.h" 32#include "budbg.h" 33 34/* This is the structure we use as a handle for these routines. */ 35 36struct pr_handle 37{ 38 /* File to print information to. */ 39 FILE *f; 40 /* Current indentation level. */ 41 unsigned int indent; 42 /* Type stack. */ 43 struct pr_stack *stack; 44 /* Parameter number we are about to output. */ 45 int parameter; 46}; 47 48/* The type stack. */ 49 50struct pr_stack 51{ 52 /* Next element on the stack. */ 53 struct pr_stack *next; 54 /* This element. */ 55 char *type; 56 /* Current visibility of fields if this is a class. */ 57 enum debug_visibility visibility; 58 /* Name of the current method we are handling. */ 59 const char *method; 60}; 61 62static void indent PARAMS ((struct pr_handle *)); 63static boolean push_type PARAMS ((struct pr_handle *, const char *)); 64static boolean prepend_type PARAMS ((struct pr_handle *, const char *)); 65static boolean append_type PARAMS ((struct pr_handle *, const char *)); 66static boolean substitute_type PARAMS ((struct pr_handle *, const char *)); 67static boolean indent_type PARAMS ((struct pr_handle *)); 68static char *pop_type PARAMS ((struct pr_handle *)); 69static void print_vma PARAMS ((bfd_vma, char *, boolean, boolean)); 70static boolean pr_fix_visibility 71 PARAMS ((struct pr_handle *, enum debug_visibility)); 72 73static boolean pr_start_compilation_unit PARAMS ((PTR, const char *)); 74static boolean pr_start_source PARAMS ((PTR, const char *)); 75static boolean pr_empty_type PARAMS ((PTR)); 76static boolean pr_void_type PARAMS ((PTR)); 77static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean)); 78static boolean pr_float_type PARAMS ((PTR, unsigned int)); 79static boolean pr_complex_type PARAMS ((PTR, unsigned int)); 80static boolean pr_bool_type PARAMS ((PTR, unsigned int)); 81static boolean pr_enum_type 82 PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); 83static boolean pr_pointer_type PARAMS ((PTR)); 84static boolean pr_function_type PARAMS ((PTR, int, boolean)); 85static boolean pr_reference_type PARAMS ((PTR)); 86static boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); 87static boolean pr_array_type 88 PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean)); 89static boolean pr_set_type PARAMS ((PTR, boolean)); 90static boolean pr_offset_type PARAMS ((PTR)); 91static boolean pr_method_type PARAMS ((PTR, boolean, int, boolean)); 92static boolean pr_const_type PARAMS ((PTR)); 93static boolean pr_volatile_type PARAMS ((PTR)); 94static boolean pr_start_struct_type 95 PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int)); 96static boolean pr_struct_field 97 PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); 98static boolean pr_end_struct_type PARAMS ((PTR)); 99static boolean pr_start_class_type 100 PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean, 101 boolean)); 102static boolean pr_class_static_member 103 PARAMS ((PTR, const char *, const char *, enum debug_visibility)); 104static boolean pr_class_baseclass 105 PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility)); 106static boolean pr_class_start_method PARAMS ((PTR, const char *)); 107static boolean pr_class_method_variant 108 PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean, 109 bfd_vma, boolean)); 110static boolean pr_class_static_method_variant 111 PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean)); 112static boolean pr_class_end_method PARAMS ((PTR)); 113static boolean pr_end_class_type PARAMS ((PTR)); 114static boolean pr_typedef_type PARAMS ((PTR, const char *)); 115static boolean pr_tag_type 116 PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind)); 117static boolean pr_typdef PARAMS ((PTR, const char *)); 118static boolean pr_tag PARAMS ((PTR, const char *)); 119static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma)); 120static boolean pr_float_constant PARAMS ((PTR, const char *, double)); 121static boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma)); 122static boolean pr_variable 123 PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma)); 124static boolean pr_start_function PARAMS ((PTR, const char *, boolean)); 125static boolean pr_function_parameter 126 PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma)); 127static boolean pr_start_block PARAMS ((PTR, bfd_vma)); 128static boolean pr_end_block PARAMS ((PTR, bfd_vma)); 129static boolean pr_end_function PARAMS ((PTR)); 130static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma)); 131 132static const struct debug_write_fns pr_fns = 133{ 134 pr_start_compilation_unit, 135 pr_start_source, 136 pr_empty_type, 137 pr_void_type, 138 pr_int_type, 139 pr_float_type, 140 pr_complex_type, 141 pr_bool_type, 142 pr_enum_type, 143 pr_pointer_type, 144 pr_function_type, 145 pr_reference_type, 146 pr_range_type, 147 pr_array_type, 148 pr_set_type, 149 pr_offset_type, 150 pr_method_type, 151 pr_const_type, 152 pr_volatile_type, 153 pr_start_struct_type, 154 pr_struct_field, 155 pr_end_struct_type, 156 pr_start_class_type, 157 pr_class_static_member, 158 pr_class_baseclass, 159 pr_class_start_method, 160 pr_class_method_variant, 161 pr_class_static_method_variant, 162 pr_class_end_method, 163 pr_end_class_type, 164 pr_typedef_type, 165 pr_tag_type, 166 pr_typdef, 167 pr_tag, 168 pr_int_constant, 169 pr_float_constant, 170 pr_typed_constant, 171 pr_variable, 172 pr_start_function, 173 pr_function_parameter, 174 pr_start_block, 175 pr_end_block, 176 pr_end_function, 177 pr_lineno 178}; 179 180/* Print out the generic debugging information recorded in dhandle. */ 181 182boolean 183print_debugging_info (f, dhandle) 184 FILE *f; 185 PTR dhandle; 186{ 187 struct pr_handle info; 188 189 info.f = f; 190 info.indent = 0; 191 info.stack = NULL; 192 info.parameter = 0; 193 194 return debug_write (dhandle, &pr_fns, (PTR) &info); 195} 196 197/* Indent to the current indentation level. */ 198 199static void 200indent (info) 201 struct pr_handle *info; 202{ 203 unsigned int i; 204 205 for (i = 0; i < info->indent; i++) 206 putc (' ', info->f); 207} 208 209/* Push a type on the type stack. */ 210 211static boolean 212push_type (info, type) 213 struct pr_handle *info; 214 const char *type; 215{ 216 struct pr_stack *n; 217 218 if (type == NULL) 219 return false; 220 221 n = (struct pr_stack *) xmalloc (sizeof *n); 222 memset (n, 0, sizeof *n); 223 224 n->type = xstrdup (type); 225 n->visibility = DEBUG_VISIBILITY_IGNORE; 226 n->method = NULL; 227 n->next = info->stack; 228 info->stack = n; 229 230 return true; 231} 232 233/* Prepend a string onto the type on the top of the type stack. */ 234 235static boolean 236prepend_type (info, s) 237 struct pr_handle *info; 238 const char *s; 239{ 240 char *n; 241 242 assert (info->stack != NULL); 243 244 n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1); 245 sprintf (n, "%s%s", s, info->stack->type); 246 free (info->stack->type); 247 info->stack->type = n; 248 249 return true; 250} 251 252/* Append a string to the type on the top of the type stack. */ 253 254static boolean 255append_type (info, s) 256 struct pr_handle *info; 257 const char *s; 258{ 259 unsigned int len; 260 261 if (s == NULL) 262 return false; 263 264 assert (info->stack != NULL); 265 266 len = strlen (info->stack->type); 267 info->stack->type = (char *) xrealloc (info->stack->type, 268 len + strlen (s) + 1); 269 strcpy (info->stack->type + len, s); 270 271 return true; 272} 273 274/* We use an underscore to indicate where the name should go in a type 275 string. This function substitutes a string for the underscore. If 276 there is no underscore, the name follows the type. */ 277 278static boolean 279substitute_type (info, s) 280 struct pr_handle *info; 281 const char *s; 282{ 283 char *u; 284 285 assert (info->stack != NULL); 286 287 u = strchr (info->stack->type, '|'); 288 if (u != NULL) 289 { 290 char *n; 291 292 n = (char *) xmalloc (strlen (info->stack->type) + strlen (s)); 293 294 memcpy (n, info->stack->type, u - info->stack->type); 295 strcpy (n + (u - info->stack->type), s); 296 strcat (n, u + 1); 297 298 free (info->stack->type); 299 info->stack->type = n; 300 301 return true; 302 } 303 304 if (strchr (s, '|') != NULL 305 && (strchr (info->stack->type, '{') != NULL 306 || strchr (info->stack->type, '(') != NULL)) 307 { 308 if (! prepend_type (info, "(") 309 || ! append_type (info, ")")) 310 return false; 311 } 312 313 if (*s == '\0') 314 return true; 315 316 return (append_type (info, " ") 317 && append_type (info, s)); 318} 319 320/* Indent the type at the top of the stack by appending spaces. */ 321 322static boolean 323indent_type (info) 324 struct pr_handle *info; 325{ 326 unsigned int i; 327 328 for (i = 0; i < info->indent; i++) 329 { 330 if (! append_type (info, " ")) 331 return false; 332 } 333 334 return true; 335} 336 337/* Pop a type from the type stack. */ 338 339static char * 340pop_type (info) 341 struct pr_handle *info; 342{ 343 struct pr_stack *o; 344 char *ret; 345 346 assert (info->stack != NULL); 347 348 o = info->stack; 349 info->stack = o->next; 350 ret = o->type; 351 free (o); 352 353 return ret; 354} 355 356/* Print a VMA value into a string. */ 357 358static void 359print_vma (vma, buf, unsignedp, hexp) 360 bfd_vma vma; 361 char *buf; 362 boolean unsignedp; 363 boolean hexp; 364{ 365 if (sizeof (vma) <= sizeof (unsigned long)) 366 { 367 if (hexp) 368 sprintf (buf, "0x%lx", (unsigned long) vma); 369 else if (unsignedp) 370 sprintf (buf, "%lu", (unsigned long) vma); 371 else 372 sprintf (buf, "%ld", (long) vma); 373 } 374 else 375 { 376 buf[0] = '0'; 377 buf[1] = 'x'; 378 sprintf_vma (buf + 2, vma); 379 } 380} 381 382/* Start a new compilation unit. */ 383 384static boolean 385pr_start_compilation_unit (p, filename) 386 PTR p; 387 const char *filename; 388{ 389 struct pr_handle *info = (struct pr_handle *) p; 390 391 assert (info->indent == 0); 392 393 fprintf (info->f, "%s:\n", filename); 394 395 return true; 396} 397 398/* Start a source file within a compilation unit. */ 399 400static boolean 401pr_start_source (p, filename) 402 PTR p; 403 const char *filename; 404{ 405 struct pr_handle *info = (struct pr_handle *) p; 406 407 assert (info->indent == 0); 408 409 fprintf (info->f, " %s:\n", filename); 410 411 return true; 412} 413 414/* Push an empty type onto the type stack. */ 415 416static boolean 417pr_empty_type (p) 418 PTR p; 419{ 420 struct pr_handle *info = (struct pr_handle *) p; 421 422 return push_type (info, "<undefined>"); 423} 424 425/* Push a void type onto the type stack. */ 426 427static boolean 428pr_void_type (p) 429 PTR p; 430{ 431 struct pr_handle *info = (struct pr_handle *) p; 432 433 return push_type (info, "void"); 434} 435 436/* Push an integer type onto the type stack. */ 437 438static boolean 439pr_int_type (p, size, unsignedp) 440 PTR p; 441 unsigned int size; 442 boolean unsignedp; 443{ 444 struct pr_handle *info = (struct pr_handle *) p; 445 char ab[10]; 446 447 sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8); 448 return push_type (info, ab); 449} 450 451/* Push a floating type onto the type stack. */ 452 453static boolean 454pr_float_type (p, size) 455 PTR p; 456 unsigned int size; 457{ 458 struct pr_handle *info = (struct pr_handle *) p; 459 char ab[10]; 460 461 if (size == 4) 462 return push_type (info, "float"); 463 else if (size == 8) 464 return push_type (info, "double"); 465 466 sprintf (ab, "float%d", size * 8); 467 return push_type (info, ab); 468} 469 470/* Push a complex type onto the type stack. */ 471 472static boolean 473pr_complex_type (p, size) 474 PTR p; 475 unsigned int size; 476{ 477 struct pr_handle *info = (struct pr_handle *) p; 478 479 if (! pr_float_type (p, size)) 480 return false; 481 482 return prepend_type (info, "complex "); 483} 484 485/* Push a boolean type onto the type stack. */ 486 487static boolean 488pr_bool_type (p, size) 489 PTR p; 490 unsigned int size; 491{ 492 struct pr_handle *info = (struct pr_handle *) p; 493 char ab[10]; 494 495 sprintf (ab, "bool%d", size * 8); 496 497 return push_type (info, ab); 498} 499 500/* Push an enum type onto the type stack. */ 501 502static boolean 503pr_enum_type (p, tag, names, values) 504 PTR p; 505 const char *tag; 506 const char **names; 507 bfd_signed_vma *values; 508{ 509 struct pr_handle *info = (struct pr_handle *) p; 510 unsigned int i; 511 bfd_signed_vma val; 512 513 if (! push_type (info, "enum ")) 514 return false; 515 if (tag != NULL) 516 { 517 if (! append_type (info, tag) 518 || ! append_type (info, " ")) 519 return false; 520 } 521 if (! append_type (info, "{ ")) 522 return false; 523 524 if (names == NULL) 525 { 526 if (! append_type (info, "/* undefined */")) 527 return false; 528 } 529 else 530 { 531 val = 0; 532 for (i = 0; names[i] != NULL; i++) 533 { 534 if (i > 0) 535 { 536 if (! append_type (info, ", ")) 537 return false; 538 } 539 540 if (! append_type (info, names[i])) 541 return false; 542 543 if (values[i] != val) 544 { 545 char ab[20]; 546 547 print_vma (values[i], ab, false, false); 548 if (! append_type (info, " = ") 549 || ! append_type (info, ab)) 550 return false; 551 val = values[i]; 552 } 553 554 ++val; 555 } 556 } 557 558 return append_type (info, " }"); 559} 560 561/* Turn the top type on the stack into a pointer. */ 562 563static boolean 564pr_pointer_type (p) 565 PTR p; 566{ 567 struct pr_handle *info = (struct pr_handle *) p; 568 char *s; 569 570 assert (info->stack != NULL); 571 572 s = strchr (info->stack->type, '|'); 573 if (s != NULL && s[1] == '[') 574 return substitute_type (info, "(*|)"); 575 return substitute_type (info, "*|"); 576} 577 578/* Turn the top type on the stack into a function returning that type. */ 579 580static boolean 581pr_function_type (p, argcount, varargs) 582 PTR p; 583 int argcount; 584 boolean varargs; 585{ 586 struct pr_handle *info = (struct pr_handle *) p; 587 char **arg_types; 588 unsigned int len; 589 char *s; 590 591 assert (info->stack != NULL); 592 593 len = 10; 594 595 if (argcount <= 0) 596 { 597 arg_types = NULL; 598 len += 15; 599 } 600 else 601 { 602 int i; 603 604 arg_types = (char **) xmalloc (argcount * sizeof *arg_types); 605 for (i = argcount - 1; i >= 0; i--) 606 { 607 if (! substitute_type (info, "")) 608 return false; 609 arg_types[i] = pop_type (info); 610 if (arg_types[i] == NULL) 611 return false; 612 len += strlen (arg_types[i]) + 2; 613 } 614 if (varargs) 615 len += 5; 616 } 617 618 /* Now the return type is on the top of the stack. */ 619 620 s = (char *) xmalloc (len); 621 strcpy (s, "(|) ("); 622 623 if (argcount < 0) 624 strcat (s, "/* unknown */"); 625 else 626 { 627 int i; 628 629 for (i = 0; i < argcount; i++) 630 { 631 if (i > 0) 632 strcat (s, ", "); 633 strcat (s, arg_types[i]); 634 } 635 if (varargs) 636 { 637 if (i > 0) 638 strcat (s, ", "); 639 strcat (s, "..."); 640 } 641 if (argcount > 0) 642 free (arg_types); 643 } 644 645 strcat (s, ")"); 646 647 if (! substitute_type (info, s)) 648 return false; 649 650 free (s); 651 652 return true; 653} 654 655/* Turn the top type on the stack into a reference to that type. */ 656 657static boolean 658pr_reference_type (p) 659 PTR p; 660{ 661 struct pr_handle *info = (struct pr_handle *) p; 662 663 assert (info->stack != NULL); 664 665 return substitute_type (info, "&|"); 666} 667 668/* Make a range type. */ 669 670static boolean 671pr_range_type (p, lower, upper) 672 PTR p; 673 bfd_signed_vma lower; 674 bfd_signed_vma upper; 675{ 676 struct pr_handle *info = (struct pr_handle *) p; 677 char abl[20], abu[20]; 678 679 assert (info->stack != NULL); 680 681 if (! substitute_type (info, "")) 682 return false; 683 684 print_vma (lower, abl, false, false); 685 print_vma (upper, abu, false, false); 686 687 return (prepend_type (info, "range (") 688 && append_type (info, "):") 689 && append_type (info, abl) 690 && append_type (info, ":") 691 && append_type (info, abu)); 692} 693 694/* Make an array type. */ 695 696/*ARGSUSED*/ 697static boolean 698pr_array_type (p, lower, upper, stringp) 699 PTR p; 700 bfd_signed_vma lower; 701 bfd_signed_vma upper; 702 boolean stringp; 703{ 704 struct pr_handle *info = (struct pr_handle *) p; 705 char *range_type; 706 char abl[20], abu[20], ab[50]; 707 708 range_type = pop_type (info); 709 if (range_type == NULL) 710 return false; 711 712 if (lower == 0) 713 { 714 if (upper == -1) 715 sprintf (ab, "|[]"); 716 else 717 { 718 print_vma (upper + 1, abu, false, false); 719 sprintf (ab, "|[%s]", abu); 720 } 721 } 722 else 723 { 724 print_vma (lower, abl, false, false); 725 print_vma (upper, abu, false, false); 726 sprintf (ab, "|[%s:%s]", abl, abu); 727 } 728 729 if (! substitute_type (info, ab)) 730 return false; 731 732 if (strcmp (range_type, "int") != 0) 733 { 734 if (! append_type (info, ":") 735 || ! append_type (info, range_type)) 736 return false; 737 } 738 739 if (stringp) 740 { 741 if (! append_type (info, " /* string */")) 742 return false; 743 } 744 745 return true; 746} 747 748/* Make a set type. */ 749 750/*ARGSUSED*/ 751static boolean 752pr_set_type (p, bitstringp) 753 PTR p; 754 boolean bitstringp; 755{ 756 struct pr_handle *info = (struct pr_handle *) p; 757 758 if (! substitute_type (info, "")) 759 return false; 760 761 if (! prepend_type (info, "set { ") 762 || ! append_type (info, " }")) 763 return false; 764 765 if (bitstringp) 766 { 767 if (! append_type (info, "/* bitstring */")) 768 return false; 769 } 770 771 return true; 772} 773 774/* Make an offset type. */ 775 776static boolean 777pr_offset_type (p) 778 PTR p; 779{ 780 struct pr_handle *info = (struct pr_handle *) p; 781 char *t; 782 783 if (! substitute_type (info, "")) 784 return false; 785 786 t = pop_type (info); 787 if (t == NULL) 788 return false; 789 790 return (substitute_type (info, "") 791 && prepend_type (info, " ") 792 && prepend_type (info, t) 793 && append_type (info, "::|")); 794} 795 796/* Make a method type. */ 797 798static boolean 799pr_method_type (p, domain, argcount, varargs) 800 PTR p; 801 boolean domain; 802 int argcount; 803 boolean varargs; 804{ 805 struct pr_handle *info = (struct pr_handle *) p; 806 unsigned int len; 807 char *domain_type; 808 char **arg_types; 809 char *s; 810 811 len = 10; 812 813 if (! domain) 814 domain_type = NULL; 815 else 816 { 817 if (! substitute_type (info, "")) 818 return false; 819 domain_type = pop_type (info); 820 if (domain_type == NULL) 821 return false; 822 if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0 823 && strchr (domain_type + sizeof "class " - 1, ' ') == NULL) 824 domain_type += sizeof "class " - 1; 825 else if (strncmp (domain_type, "union class ", 826 sizeof "union class ") == 0 827 && (strchr (domain_type + sizeof "union class " - 1, ' ') 828 == NULL)) 829 domain_type += sizeof "union class " - 1; 830 len += strlen (domain_type); 831 } 832 833 if (argcount <= 0) 834 { 835 arg_types = NULL; 836 len += 15; 837 } 838 else 839 { 840 int i; 841 842 arg_types = (char **) xmalloc (argcount * sizeof *arg_types); 843 for (i = argcount - 1; i >= 0; i--) 844 { 845 if (! substitute_type (info, "")) 846 return false; 847 arg_types[i] = pop_type (info); 848 if (arg_types[i] == NULL) 849 return false; 850 len += strlen (arg_types[i]) + 2; 851 } 852 if (varargs) 853 len += 5; 854 } 855 856 /* Now the return type is on the top of the stack. */ 857 858 s = (char *) xmalloc (len); 859 if (! domain) 860 *s = '\0'; 861 else 862 strcpy (s, domain_type); 863 strcat (s, "::| ("); 864 865 if (argcount < 0) 866 strcat (s, "/* unknown */"); 867 else 868 { 869 int i; 870 871 for (i = 0; i < argcount; i++) 872 { 873 if (i > 0) 874 strcat (s, ", "); 875 strcat (s, arg_types[i]); 876 } 877 if (varargs) 878 { 879 if (i > 0) 880 strcat (s, ", "); 881 strcat (s, "..."); 882 } 883 if (argcount > 0) 884 free (arg_types); 885 } 886 887 strcat (s, ")"); 888 889 if (! substitute_type (info, s)) 890 return false; 891 892 free (s); 893 894 return true; 895} 896 897/* Make a const qualified type. */ 898 899static boolean 900pr_const_type (p) 901 PTR p; 902{ 903 struct pr_handle *info = (struct pr_handle *) p; 904 905 return substitute_type (info, "const |"); 906} 907 908/* Make a volatile qualified type. */ 909 910static boolean 911pr_volatile_type (p) 912 PTR p; 913{ 914 struct pr_handle *info = (struct pr_handle *) p; 915 916 return substitute_type (info, "volatile |"); 917} 918 919/* Start accumulating a struct type. */ 920 921static boolean 922pr_start_struct_type (p, tag, id, structp, size) 923 PTR p; 924 const char *tag; 925 unsigned int id; 926 boolean structp; 927 unsigned int size; 928{ 929 struct pr_handle *info = (struct pr_handle *) p; 930 931 info->indent += 2; 932 933 if (! push_type (info, structp ? "struct " : "union ")) 934 return false; 935 if (tag != NULL) 936 { 937 if (! append_type (info, tag)) 938 return false; 939 } 940 else 941 { 942 char idbuf[20]; 943 944 sprintf (idbuf, "%%anon%u", id); 945 if (! append_type (info, idbuf)) 946 return false; 947 } 948 949 if (! append_type (info, " {")) 950 return false; 951 if (size != 0 || tag != NULL) 952 { 953 char ab[30]; 954 955 if (! append_type (info, " /*")) 956 return false; 957 958 if (size != 0) 959 { 960 sprintf (ab, " size %u", size); 961 if (! append_type (info, ab)) 962 return false; 963 } 964 if (tag != NULL) 965 { 966 sprintf (ab, " id %u", id); 967 if (! append_type (info, ab)) 968 return false; 969 } 970 if (! append_type (info, " */")) 971 return false; 972 } 973 if (! append_type (info, "\n")) 974 return false; 975 976 info->stack->visibility = DEBUG_VISIBILITY_PUBLIC; 977 978 return indent_type (info); 979} 980 981/* Output the visibility of a field in a struct. */ 982 983static boolean 984pr_fix_visibility (info, visibility) 985 struct pr_handle *info; 986 enum debug_visibility visibility; 987{ 988 const char *s = NULL; 989 char *t; 990 unsigned int len; 991 992 assert (info->stack != NULL); 993 994 if (info->stack->visibility == visibility) 995 return true; 996 997 assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE); 998 999 switch (visibility) 1000 { 1001 case DEBUG_VISIBILITY_PUBLIC: 1002 s = "public"; 1003 break; 1004 case DEBUG_VISIBILITY_PRIVATE: 1005 s = "private"; 1006 break; 1007 case DEBUG_VISIBILITY_PROTECTED: 1008 s = "protected"; 1009 break; 1010 case DEBUG_VISIBILITY_IGNORE: 1011 s = "/* ignore */"; 1012 break; 1013 default: 1014 abort (); 1015 return false; 1016 } 1017 1018 /* Trim off a trailing space in the struct string, to make the 1019 output look a bit better, then stick on the visibility string. */ 1020 1021 t = info->stack->type; 1022 len = strlen (t); 1023 assert (t[len - 1] == ' '); 1024 t[len - 1] = '\0'; 1025 1026 if (! append_type (info, s) 1027 || ! append_type (info, ":\n") 1028 || ! indent_type (info)) 1029 return false; 1030 1031 info->stack->visibility = visibility; 1032 1033 return true; 1034} 1035 1036/* Add a field to a struct type. */ 1037 1038static boolean 1039pr_struct_field (p, name, bitpos, bitsize, visibility) 1040 PTR p; 1041 const char *name; 1042 bfd_vma bitpos; 1043 bfd_vma bitsize; 1044 enum debug_visibility visibility; 1045{ 1046 struct pr_handle *info = (struct pr_handle *) p; 1047 char ab[20]; 1048 char *t; 1049 1050 if (! substitute_type (info, name)) 1051 return false; 1052 1053 if (! append_type (info, "; /* ")) 1054 return false; 1055 1056 if (bitsize != 0) 1057 { 1058 print_vma (bitsize, ab, true, false); 1059 if (! append_type (info, "bitsize ") 1060 || ! append_type (info, ab) 1061 || ! append_type (info, ", ")) 1062 return false; 1063 } 1064 1065 print_vma (bitpos, ab, true, false); 1066 if (! append_type (info, "bitpos ") 1067 || ! append_type (info, ab) 1068 || ! append_type (info, " */\n") 1069 || ! indent_type (info)) 1070 return false; 1071 1072 t = pop_type (info); 1073 if (t == NULL) 1074 return false; 1075 1076 if (! pr_fix_visibility (info, visibility)) 1077 return false; 1078 1079 return append_type (info, t); 1080} 1081 1082/* Finish a struct type. */ 1083 1084static boolean 1085pr_end_struct_type (p) 1086 PTR p; 1087{ 1088 struct pr_handle *info = (struct pr_handle *) p; 1089 char *s; 1090 1091 assert (info->stack != NULL); 1092 assert (info->indent >= 2); 1093 1094 info->indent -= 2; 1095 1096 /* Change the trailing indentation to have a close brace. */ 1097 s = info->stack->type + strlen (info->stack->type) - 2; 1098 assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0'); 1099 1100 *s++ = '}'; 1101 *s = '\0'; 1102 1103 return true; 1104} 1105 1106/* Start a class type. */ 1107 1108static boolean 1109pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr) 1110 PTR p; 1111 const char *tag; 1112 unsigned int id; 1113 boolean structp; 1114 unsigned int size; 1115 boolean vptr; 1116 boolean ownvptr; 1117{ 1118 struct pr_handle *info = (struct pr_handle *) p; 1119 char *tv = NULL; 1120 1121 info->indent += 2; 1122 1123 if (vptr && ! ownvptr) 1124 { 1125 tv = pop_type (info); 1126 if (tv == NULL) 1127 return false; 1128 } 1129 1130 if (! push_type (info, structp ? "class " : "union class ")) 1131 return false; 1132 if (tag != NULL) 1133 { 1134 if (! append_type (info, tag)) 1135 return false; 1136 } 1137 else 1138 { 1139 char idbuf[20]; 1140 1141 sprintf (idbuf, "%%anon%u", id); 1142 if (! append_type (info, idbuf)) 1143 return false; 1144 } 1145 1146 if (! append_type (info, " {")) 1147 return false; 1148 if (size != 0 || vptr || ownvptr || tag != NULL) 1149 { 1150 if (! append_type (info, " /*")) 1151 return false; 1152 1153 if (size != 0) 1154 { 1155 char ab[20]; 1156 1157 sprintf (ab, "%u", size); 1158 if (! append_type (info, " size ") 1159 || ! append_type (info, ab)) 1160 return false; 1161 } 1162 1163 if (vptr) 1164 { 1165 if (! append_type (info, " vtable ")) 1166 return false; 1167 if (ownvptr) 1168 { 1169 if (! append_type (info, "self ")) 1170 return false; 1171 } 1172 else 1173 { 1174 if (! append_type (info, tv) 1175 || ! append_type (info, " ")) 1176 return false; 1177 } 1178 } 1179 1180 if (tag != NULL) 1181 { 1182 char ab[30]; 1183 1184 sprintf (ab, " id %u", id); 1185 if (! append_type (info, ab)) 1186 return false; 1187 } 1188 1189 if (! append_type (info, " */")) 1190 return false; 1191 } 1192 1193 info->stack->visibility = DEBUG_VISIBILITY_PRIVATE; 1194 1195 return (append_type (info, "\n") 1196 && indent_type (info)); 1197} 1198 1199/* Add a static member to a class. */ 1200 1201static boolean 1202pr_class_static_member (p, name, physname, visibility) 1203 PTR p; 1204 const char *name; 1205 const char *physname; 1206 enum debug_visibility visibility; 1207{ 1208 struct pr_handle *info = (struct pr_handle *) p; 1209 char *t; 1210 1211 if (! substitute_type (info, name)) 1212 return false; 1213 1214 if (! prepend_type (info, "static ") 1215 || ! append_type (info, "; /* ") 1216 || ! append_type (info, physname) 1217 || ! append_type (info, " */\n") 1218 || ! indent_type (info)) 1219 return false; 1220 1221 t = pop_type (info); 1222 if (t == NULL) 1223 return false; 1224 1225 if (! pr_fix_visibility (info, visibility)) 1226 return false; 1227 1228 return append_type (info, t); 1229} 1230 1231/* Add a base class to a class. */ 1232 1233static boolean 1234pr_class_baseclass (p, bitpos, virtual, visibility) 1235 PTR p; 1236 bfd_vma bitpos; 1237 boolean virtual; 1238 enum debug_visibility visibility; 1239{ 1240 struct pr_handle *info = (struct pr_handle *) p; 1241 char *t; 1242 const char *prefix; 1243 char ab[20]; 1244 char *s, *l, *n; 1245 1246 assert (info->stack != NULL && info->stack->next != NULL); 1247 1248 if (! substitute_type (info, "")) 1249 return false; 1250 1251 t = pop_type (info); 1252 if (t == NULL) 1253 return false; 1254 1255 if (strncmp (t, "class ", sizeof "class " - 1) == 0) 1256 t += sizeof "class " - 1; 1257 1258 /* Push it back on to take advantage of the prepend_type and 1259 append_type routines. */ 1260 if (! push_type (info, t)) 1261 return false; 1262 1263 if (virtual) 1264 { 1265 if (! prepend_type (info, "virtual ")) 1266 return false; 1267 } 1268 1269 switch (visibility) 1270 { 1271 case DEBUG_VISIBILITY_PUBLIC: 1272 prefix = "public "; 1273 break; 1274 case DEBUG_VISIBILITY_PROTECTED: 1275 prefix = "protected "; 1276 break; 1277 case DEBUG_VISIBILITY_PRIVATE: 1278 prefix = "private "; 1279 break; 1280 default: 1281 prefix = "/* unknown visibility */ "; 1282 break; 1283 } 1284 1285 if (! prepend_type (info, prefix)) 1286 return false; 1287 1288 if (bitpos != 0) 1289 { 1290 print_vma (bitpos, ab, true, false); 1291 if (! append_type (info, " /* bitpos ") 1292 || ! append_type (info, ab) 1293 || ! append_type (info, " */")) 1294 return false; 1295 } 1296 1297 /* Now the top of the stack is something like "public A / * bitpos 1298 10 * /". The next element on the stack is something like "class 1299 xx { / * size 8 * /\n...". We want to substitute the top of the 1300 stack in before the {. */ 1301 s = strchr (info->stack->next->type, '{'); 1302 assert (s != NULL); 1303 --s; 1304 1305 /* If there is already a ':', then we already have a baseclass, and 1306 we must append this one after a comma. */ 1307 for (l = info->stack->next->type; l != s; l++) 1308 if (*l == ':') 1309 break; 1310 if (! prepend_type (info, l == s ? " : " : ", ")) 1311 return false; 1312 1313 t = pop_type (info); 1314 if (t == NULL) 1315 return false; 1316 1317 n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1); 1318 memcpy (n, info->stack->type, s - info->stack->type); 1319 strcpy (n + (s - info->stack->type), t); 1320 strcat (n, s); 1321 1322 free (info->stack->type); 1323 info->stack->type = n; 1324 1325 free (t); 1326 1327 return true; 1328} 1329 1330/* Start adding a method to a class. */ 1331 1332static boolean 1333pr_class_start_method (p, name) 1334 PTR p; 1335 const char *name; 1336{ 1337 struct pr_handle *info = (struct pr_handle *) p; 1338 1339 assert (info->stack != NULL); 1340 info->stack->method = name; 1341 return true; 1342} 1343 1344/* Add a variant to a method. */ 1345 1346static boolean 1347pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset, 1348 context) 1349 PTR p; 1350 const char *physname; 1351 enum debug_visibility visibility; 1352 boolean constp; 1353 boolean volatilep; 1354 bfd_vma voffset; 1355 boolean context; 1356{ 1357 struct pr_handle *info = (struct pr_handle *) p; 1358 char *method_type; 1359 char *context_type; 1360 1361 assert (info->stack != NULL); 1362 assert (info->stack->next != NULL); 1363 1364 /* Put the const and volatile qualifiers on the type. */ 1365 if (volatilep) 1366 { 1367 if (! append_type (info, " volatile")) 1368 return false; 1369 } 1370 if (constp) 1371 { 1372 if (! append_type (info, " const")) 1373 return false; 1374 } 1375 1376 /* Stick the name of the method into its type. */ 1377 if (! substitute_type (info, 1378 (context 1379 ? info->stack->next->next->method 1380 : info->stack->next->method))) 1381 return false; 1382 1383 /* Get the type. */ 1384 method_type = pop_type (info); 1385 if (method_type == NULL) 1386 return false; 1387 1388 /* Pull off the context type if there is one. */ 1389 if (! context) 1390 context_type = NULL; 1391 else 1392 { 1393 context_type = pop_type (info); 1394 if (context_type == NULL) 1395 return false; 1396 } 1397 1398 /* Now the top of the stack is the class. */ 1399 1400 if (! pr_fix_visibility (info, visibility)) 1401 return false; 1402 1403 if (! append_type (info, method_type) 1404 || ! append_type (info, " /* ") 1405 || ! append_type (info, physname) 1406 || ! append_type (info, " ")) 1407 return false; 1408 if (context || voffset != 0) 1409 { 1410 char ab[20]; 1411 1412 if (context) 1413 { 1414 if (! append_type (info, "context ") 1415 || ! append_type (info, context_type) 1416 || ! append_type (info, " ")) 1417 return false; 1418 } 1419 print_vma (voffset, ab, true, false); 1420 if (! append_type (info, "voffset ") 1421 || ! append_type (info, ab)) 1422 return false; 1423 } 1424 1425 return (append_type (info, " */;\n") 1426 && indent_type (info)); 1427} 1428 1429/* Add a static variant to a method. */ 1430 1431static boolean 1432pr_class_static_method_variant (p, physname, visibility, constp, volatilep) 1433 PTR p; 1434 const char *physname; 1435 enum debug_visibility visibility; 1436 boolean constp; 1437 boolean volatilep; 1438{ 1439 struct pr_handle *info = (struct pr_handle *) p; 1440 char *method_type; 1441 1442 assert (info->stack != NULL); 1443 assert (info->stack->next != NULL); 1444 assert (info->stack->next->method != NULL); 1445 1446 /* Put the const and volatile qualifiers on the type. */ 1447 if (volatilep) 1448 { 1449 if (! append_type (info, " volatile")) 1450 return false; 1451 } 1452 if (constp) 1453 { 1454 if (! append_type (info, " const")) 1455 return false; 1456 } 1457 1458 /* Mark it as static. */ 1459 if (! prepend_type (info, "static ")) 1460 return false; 1461 1462 /* Stick the name of the method into its type. */ 1463 if (! substitute_type (info, info->stack->next->method)) 1464 return false; 1465 1466 /* Get the type. */ 1467 method_type = pop_type (info); 1468 if (method_type == NULL) 1469 return false; 1470 1471 /* Now the top of the stack is the class. */ 1472 1473 if (! pr_fix_visibility (info, visibility)) 1474 return false; 1475 1476 return (append_type (info, method_type) 1477 && append_type (info, " /* ") 1478 && append_type (info, physname) 1479 && append_type (info, " */;\n") 1480 && indent_type (info)); 1481} 1482 1483/* Finish up a method. */ 1484 1485static boolean 1486pr_class_end_method (p) 1487 PTR p; 1488{ 1489 struct pr_handle *info = (struct pr_handle *) p; 1490 1491 info->stack->method = NULL; 1492 return true; 1493} 1494 1495/* Finish up a class. */ 1496 1497static boolean 1498pr_end_class_type (p) 1499 PTR p; 1500{ 1501 return pr_end_struct_type (p); 1502} 1503 1504/* Push a type on the stack using a typedef name. */ 1505 1506static boolean 1507pr_typedef_type (p, name) 1508 PTR p; 1509 const char *name; 1510{ 1511 struct pr_handle *info = (struct pr_handle *) p; 1512 1513 return push_type (info, name); 1514} 1515 1516/* Push a type on the stack using a tag name. */ 1517 1518static boolean 1519pr_tag_type (p, name, id, kind) 1520 PTR p; 1521 const char *name; 1522 unsigned int id; 1523 enum debug_type_kind kind; 1524{ 1525 struct pr_handle *info = (struct pr_handle *) p; 1526 const char *t, *tag; 1527 char idbuf[20]; 1528 1529 switch (kind) 1530 { 1531 case DEBUG_KIND_STRUCT: 1532 t = "struct "; 1533 break; 1534 case DEBUG_KIND_UNION: 1535 t = "union "; 1536 break; 1537 case DEBUG_KIND_ENUM: 1538 t = "enum "; 1539 break; 1540 case DEBUG_KIND_CLASS: 1541 t = "class "; 1542 break; 1543 case DEBUG_KIND_UNION_CLASS: 1544 t = "union class "; 1545 break; 1546 default: 1547 abort (); 1548 return false; 1549 } 1550 1551 if (! push_type (info, t)) 1552 return false; 1553 if (name != NULL) 1554 tag = name; 1555 else 1556 { 1557 sprintf (idbuf, "%%anon%u", id); 1558 tag = idbuf; 1559 } 1560 1561 if (! append_type (info, tag)) 1562 return false; 1563 if (name != NULL && kind != DEBUG_KIND_ENUM) 1564 { 1565 sprintf (idbuf, " /* id %u */", id); 1566 if (! append_type (info, idbuf)) 1567 return false; 1568 } 1569 1570 return true; 1571} 1572 1573/* Output a typedef. */ 1574 1575static boolean 1576pr_typdef (p, name) 1577 PTR p; 1578 const char *name; 1579{ 1580 struct pr_handle *info = (struct pr_handle *) p; 1581 char *s; 1582 1583 if (! substitute_type (info, name)) 1584 return false; 1585 1586 s = pop_type (info); 1587 if (s == NULL) 1588 return false; 1589 1590 indent (info); 1591 fprintf (info->f, "typedef %s;\n", s); 1592 1593 free (s); 1594 1595 return true; 1596} 1597 1598/* Output a tag. The tag should already be in the string on the 1599 stack, so all we have to do here is print it out. */ 1600 1601/*ARGSUSED*/ 1602static boolean 1603pr_tag (p, name) 1604 PTR p; 1605 const char *name ATTRIBUTE_UNUSED; 1606{ 1607 struct pr_handle *info = (struct pr_handle *) p; 1608 char *t; 1609 1610 t = pop_type (info); 1611 if (t == NULL) 1612 return false; 1613 1614 indent (info); 1615 fprintf (info->f, "%s;\n", t); 1616 1617 free (t); 1618 1619 return true; 1620} 1621 1622/* Output an integer constant. */ 1623 1624static boolean 1625pr_int_constant (p, name, val) 1626 PTR p; 1627 const char *name; 1628 bfd_vma val; 1629{ 1630 struct pr_handle *info = (struct pr_handle *) p; 1631 char ab[20]; 1632 1633 indent (info); 1634 print_vma (val, ab, false, false); 1635 fprintf (info->f, "const int %s = %s;\n", name, ab); 1636 return true; 1637} 1638 1639/* Output a floating point constant. */ 1640 1641static boolean 1642pr_float_constant (p, name, val) 1643 PTR p; 1644 const char *name; 1645 double val; 1646{ 1647 struct pr_handle *info = (struct pr_handle *) p; 1648 1649 indent (info); 1650 fprintf (info->f, "const double %s = %g;\n", name, val); 1651 return true; 1652} 1653 1654/* Output a typed constant. */ 1655 1656static boolean 1657pr_typed_constant (p, name, val) 1658 PTR p; 1659 const char *name; 1660 bfd_vma val; 1661{ 1662 struct pr_handle *info = (struct pr_handle *) p; 1663 char *t; 1664 char ab[20]; 1665 1666 t = pop_type (info); 1667 if (t == NULL) 1668 return false; 1669 1670 indent (info); 1671 print_vma (val, ab, false, false); 1672 fprintf (info->f, "const %s %s = %s;\n", t, name, ab); 1673 1674 free (t); 1675 1676 return true; 1677} 1678 1679/* Output a variable. */ 1680 1681static boolean 1682pr_variable (p, name, kind, val) 1683 PTR p; 1684 const char *name; 1685 enum debug_var_kind kind; 1686 bfd_vma val; 1687{ 1688 struct pr_handle *info = (struct pr_handle *) p; 1689 char *t; 1690 char ab[20]; 1691 1692 if (! substitute_type (info, name)) 1693 return false; 1694 1695 t = pop_type (info); 1696 if (t == NULL) 1697 return false; 1698 1699 indent (info); 1700 switch (kind) 1701 { 1702 case DEBUG_STATIC: 1703 case DEBUG_LOCAL_STATIC: 1704 fprintf (info->f, "static "); 1705 break; 1706 case DEBUG_REGISTER: 1707 fprintf (info->f, "register "); 1708 break; 1709 default: 1710 break; 1711 } 1712 print_vma (val, ab, true, true); 1713 fprintf (info->f, "%s /* %s */;\n", t, ab); 1714 1715 free (t); 1716 1717 return true; 1718} 1719 1720/* Start outputting a function. */ 1721 1722static boolean 1723pr_start_function (p, name, global) 1724 PTR p; 1725 const char *name; 1726 boolean global; 1727{ 1728 struct pr_handle *info = (struct pr_handle *) p; 1729 char *t; 1730 1731 if (! substitute_type (info, name)) 1732 return false; 1733 1734 t = pop_type (info); 1735 if (t == NULL) 1736 return false; 1737 1738 indent (info); 1739 if (! global) 1740 fprintf (info->f, "static "); 1741 fprintf (info->f, "%s (", t); 1742 1743 info->parameter = 1; 1744 1745 return true; 1746} 1747 1748/* Output a function parameter. */ 1749 1750static boolean 1751pr_function_parameter (p, name, kind, val) 1752 PTR p; 1753 const char *name; 1754 enum debug_parm_kind kind; 1755 bfd_vma val; 1756{ 1757 struct pr_handle *info = (struct pr_handle *) p; 1758 char *t; 1759 char ab[20]; 1760 1761 if (kind == DEBUG_PARM_REFERENCE 1762 || kind == DEBUG_PARM_REF_REG) 1763 { 1764 if (! pr_reference_type (p)) 1765 return false; 1766 } 1767 1768 if (! substitute_type (info, name)) 1769 return false; 1770 1771 t = pop_type (info); 1772 if (t == NULL) 1773 return false; 1774 1775 if (info->parameter != 1) 1776 fprintf (info->f, ", "); 1777 1778 if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG) 1779 fprintf (info->f, "register "); 1780 1781 print_vma (val, ab, true, true); 1782 fprintf (info->f, "%s /* %s */", t, ab); 1783 1784 free (t); 1785 1786 ++info->parameter; 1787 1788 return true; 1789} 1790 1791/* Start writing out a block. */ 1792 1793static boolean 1794pr_start_block (p, addr) 1795 PTR p; 1796 bfd_vma addr; 1797{ 1798 struct pr_handle *info = (struct pr_handle *) p; 1799 char ab[20]; 1800 1801 if (info->parameter > 0) 1802 { 1803 fprintf (info->f, ")\n"); 1804 info->parameter = 0; 1805 } 1806 1807 indent (info); 1808 print_vma (addr, ab, true, true); 1809 fprintf (info->f, "{ /* %s */\n", ab); 1810 1811 info->indent += 2; 1812 1813 return true; 1814} 1815 1816/* Write out line number information. */ 1817 1818static boolean 1819pr_lineno (p, filename, lineno, addr) 1820 PTR p; 1821 const char *filename; 1822 unsigned long lineno; 1823 bfd_vma addr; 1824{ 1825 struct pr_handle *info = (struct pr_handle *) p; 1826 char ab[20]; 1827 1828 indent (info); 1829 print_vma (addr, ab, true, true); 1830 fprintf (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab); 1831 1832 return true; 1833} 1834 1835/* Finish writing out a block. */ 1836 1837static boolean 1838pr_end_block (p, addr) 1839 PTR p; 1840 bfd_vma addr; 1841{ 1842 struct pr_handle *info = (struct pr_handle *) p; 1843 char ab[20]; 1844 1845 info->indent -= 2; 1846 1847 indent (info); 1848 print_vma (addr, ab, true, true); 1849 fprintf (info->f, "} /* %s */\n", ab); 1850 1851 return true; 1852} 1853 1854/* Finish writing out a function. */ 1855 1856/*ARGSUSED*/ 1857static boolean 1858pr_end_function (p) 1859 PTR p ATTRIBUTE_UNUSED; 1860{ 1861 return true; 1862} 1863