1 /* Generate CodeView debugging info from the GCC DWARF.
2 Copyright (C) 2023-2025 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 /* See gas/codeview.h in binutils for more about the constants and structs
21 listed below. References to Microsoft files refer to Microsoft's PDB
22 repository: https://github.com/microsoft/microsoft-pdb. */
26 #include "coretypes.h"
34 #include "langhooks.h"
35 #include "dwarf2out.h"
36 #include "dwarf2codeview.h"
39 #ifdef CODEVIEW_DEBUGGING_INFO
41 #define CV_SIGNATURE_C13 4
43 #define DEBUG_S_SYMBOLS 0xf1
44 #define DEBUG_S_LINES 0xf2
45 #define DEBUG_S_STRINGTABLE 0xf3
46 #define DEBUG_S_FILECHKSMS 0xf4
47 #define DEBUG_S_INLINEELINES 0xf6
49 #define CHKSUM_TYPE_MD5 1
51 #define CV_CFL_80386 0x03
52 #define CV_CFL_X64 0xD0
55 #define CV_CFL_CXX 0x01
57 #define CV_INLINEE_SOURCE_LINE_SIGNATURE 0x0
59 #define FIRST_TYPE 0x1000
61 #define LINE_LABEL "Lcvline"
62 #define END_FUNC_LABEL "Lcvendfunc"
63 #define SYMBOL_START_LABEL "Lcvsymstart"
64 #define SYMBOL_END_LABEL "Lcvsymend"
66 /* There's two bytes available for each type's size, but follow MSVC's lead in
67 capping the LF_FIELDLIST size at fb00 (minus 8 bytes for the LF_INDEX
68 pointing to the overflow entry). */
69 #define MAX_FIELDLIST_SIZE 0xfaf8
73 /* This is enum SYM_ENUM_e in Microsoft's cvinfo.h. */
85 S_DEFRANGE_REGISTER
= 0x1141,
86 S_DEFRANGE_REGISTER_REL
= 0x1145,
87 S_LPROC32_ID
= 0x1146,
88 S_GPROC32_ID
= 0x1147,
89 S_INLINESITE
= 0x114d,
90 S_INLINESITE_END
= 0x114e,
91 S_PROC_ID_END
= 0x114f
94 /* This is enum LEAF_ENUM_e in Microsoft's cvinfo.h. */
100 LF_MODIFIER
= 0x1001,
102 LF_PROCEDURE
= 0x1008,
103 LF_MFUNCTION
= 0x1009,
105 LF_FIELDLIST
= 0x1203,
106 LF_BITFIELD
= 0x1205,
107 LF_METHODLIST
= 0x1206,
110 LF_ENUMERATE
= 0x1502,
113 LF_STRUCTURE
= 0x1505,
117 LF_STMEMBER
= 0x150e,
119 LF_NESTTYPE
= 0x1510,
120 LF_ONEMETHOD
= 0x1511,
122 LF_MFUNC_ID
= 0x1602,
123 LF_STRING_ID
= 0x1605,
129 LF_QUADWORD
= 0x8009,
130 LF_UQUADWORD
= 0x800a
133 /* These come from enum CV_HREG_e in Microsoft's cvconst.h. */
135 enum cv_x86_register
{
198 CV_REG_PSEUDO1
= 116,
199 CV_REG_PSEUDO2
= 117,
200 CV_REG_PSEUDO3
= 118,
201 CV_REG_PSEUDO4
= 119,
202 CV_REG_PSEUDO5
= 120,
203 CV_REG_PSEUDO6
= 121,
204 CV_REG_PSEUDO7
= 122,
205 CV_REG_PSEUDO8
= 123,
206 CV_REG_PSEUDO9
= 124,
473 enum cv_amd64_register
{
507 CV_AMD64_EFLAGS
= 34,
552 CV_AMD64_FPEIP
= 144,
553 CV_AMD64_FPEDO
= 145,
570 CV_AMD64_XMM0_0
= 162,
571 CV_AMD64_XMM0_1
= 163,
572 CV_AMD64_XMM0_2
= 164,
573 CV_AMD64_XMM0_3
= 165,
574 CV_AMD64_XMM1_0
= 166,
575 CV_AMD64_XMM1_1
= 167,
576 CV_AMD64_XMM1_2
= 168,
577 CV_AMD64_XMM1_3
= 169,
578 CV_AMD64_XMM2_0
= 170,
579 CV_AMD64_XMM2_1
= 171,
580 CV_AMD64_XMM2_2
= 172,
581 CV_AMD64_XMM2_3
= 173,
582 CV_AMD64_XMM3_0
= 174,
583 CV_AMD64_XMM3_1
= 175,
584 CV_AMD64_XMM3_2
= 176,
585 CV_AMD64_XMM3_3
= 177,
586 CV_AMD64_XMM4_0
= 178,
587 CV_AMD64_XMM4_1
= 179,
588 CV_AMD64_XMM4_2
= 180,
589 CV_AMD64_XMM4_3
= 181,
590 CV_AMD64_XMM5_0
= 182,
591 CV_AMD64_XMM5_1
= 183,
592 CV_AMD64_XMM5_2
= 184,
593 CV_AMD64_XMM5_3
= 185,
594 CV_AMD64_XMM6_0
= 186,
595 CV_AMD64_XMM6_1
= 187,
596 CV_AMD64_XMM6_2
= 188,
597 CV_AMD64_XMM6_3
= 189,
598 CV_AMD64_XMM7_0
= 190,
599 CV_AMD64_XMM7_1
= 191,
600 CV_AMD64_XMM7_2
= 192,
601 CV_AMD64_XMM7_3
= 193,
602 CV_AMD64_XMM0L
= 194,
603 CV_AMD64_XMM1L
= 195,
604 CV_AMD64_XMM2L
= 196,
605 CV_AMD64_XMM3L
= 197,
606 CV_AMD64_XMM4L
= 198,
607 CV_AMD64_XMM5L
= 199,
608 CV_AMD64_XMM6L
= 200,
609 CV_AMD64_XMM7L
= 201,
610 CV_AMD64_XMM0H
= 202,
611 CV_AMD64_XMM1H
= 203,
612 CV_AMD64_XMM2H
= 204,
613 CV_AMD64_XMM3H
= 205,
614 CV_AMD64_XMM4H
= 206,
615 CV_AMD64_XMM5H
= 207,
616 CV_AMD64_XMM6H
= 208,
617 CV_AMD64_XMM7H
= 209,
618 CV_AMD64_MXCSR
= 211,
619 CV_AMD64_EMM0L
= 220,
620 CV_AMD64_EMM1L
= 221,
621 CV_AMD64_EMM2L
= 222,
622 CV_AMD64_EMM3L
= 223,
623 CV_AMD64_EMM4L
= 224,
624 CV_AMD64_EMM5L
= 225,
625 CV_AMD64_EMM6L
= 226,
626 CV_AMD64_EMM7L
= 227,
627 CV_AMD64_EMM0H
= 228,
628 CV_AMD64_EMM1H
= 229,
629 CV_AMD64_EMM2H
= 230,
630 CV_AMD64_EMM3H
= 231,
631 CV_AMD64_EMM4H
= 232,
632 CV_AMD64_EMM5H
= 233,
633 CV_AMD64_EMM6H
= 234,
634 CV_AMD64_EMM7H
= 235,
653 CV_AMD64_XMM10
= 254,
654 CV_AMD64_XMM11
= 255,
655 CV_AMD64_XMM12
= 256,
656 CV_AMD64_XMM13
= 257,
657 CV_AMD64_XMM14
= 258,
658 CV_AMD64_XMM15
= 259,
659 CV_AMD64_XMM8_0
= 260,
660 CV_AMD64_XMM8_1
= 261,
661 CV_AMD64_XMM8_2
= 262,
662 CV_AMD64_XMM8_3
= 263,
663 CV_AMD64_XMM9_0
= 264,
664 CV_AMD64_XMM9_1
= 265,
665 CV_AMD64_XMM9_2
= 266,
666 CV_AMD64_XMM9_3
= 267,
667 CV_AMD64_XMM10_0
= 268,
668 CV_AMD64_XMM10_1
= 269,
669 CV_AMD64_XMM10_2
= 270,
670 CV_AMD64_XMM10_3
= 271,
671 CV_AMD64_XMM11_0
= 272,
672 CV_AMD64_XMM11_1
= 273,
673 CV_AMD64_XMM11_2
= 274,
674 CV_AMD64_XMM11_3
= 275,
675 CV_AMD64_XMM12_0
= 276,
676 CV_AMD64_XMM12_1
= 277,
677 CV_AMD64_XMM12_2
= 278,
678 CV_AMD64_XMM12_3
= 279,
679 CV_AMD64_XMM13_0
= 280,
680 CV_AMD64_XMM13_1
= 281,
681 CV_AMD64_XMM13_2
= 282,
682 CV_AMD64_XMM13_3
= 283,
683 CV_AMD64_XMM14_0
= 284,
684 CV_AMD64_XMM14_1
= 285,
685 CV_AMD64_XMM14_2
= 286,
686 CV_AMD64_XMM14_3
= 287,
687 CV_AMD64_XMM15_0
= 288,
688 CV_AMD64_XMM15_1
= 289,
689 CV_AMD64_XMM15_2
= 290,
690 CV_AMD64_XMM15_3
= 291,
691 CV_AMD64_XMM8L
= 292,
692 CV_AMD64_XMM9L
= 293,
693 CV_AMD64_XMM10L
= 294,
694 CV_AMD64_XMM11L
= 295,
695 CV_AMD64_XMM12L
= 296,
696 CV_AMD64_XMM13L
= 297,
697 CV_AMD64_XMM14L
= 298,
698 CV_AMD64_XMM15L
= 299,
699 CV_AMD64_XMM8H
= 300,
700 CV_AMD64_XMM9H
= 301,
701 CV_AMD64_XMM10H
= 302,
702 CV_AMD64_XMM11H
= 303,
703 CV_AMD64_XMM12H
= 304,
704 CV_AMD64_XMM13H
= 305,
705 CV_AMD64_XMM14H
= 306,
706 CV_AMD64_XMM15H
= 307,
707 CV_AMD64_EMM8L
= 308,
708 CV_AMD64_EMM9L
= 309,
709 CV_AMD64_EMM10L
= 310,
710 CV_AMD64_EMM11L
= 311,
711 CV_AMD64_EMM12L
= 312,
712 CV_AMD64_EMM13L
= 313,
713 CV_AMD64_EMM14L
= 314,
714 CV_AMD64_EMM15L
= 315,
715 CV_AMD64_EMM8H
= 316,
716 CV_AMD64_EMM9H
= 317,
717 CV_AMD64_EMM10H
= 318,
718 CV_AMD64_EMM11H
= 319,
719 CV_AMD64_EMM12H
= 320,
720 CV_AMD64_EMM13H
= 321,
721 CV_AMD64_EMM14H
= 322,
722 CV_AMD64_EMM15H
= 323,
777 CV_AMD64_YMM10
= 378,
778 CV_AMD64_YMM11
= 379,
779 CV_AMD64_YMM12
= 380,
780 CV_AMD64_YMM13
= 381,
781 CV_AMD64_YMM14
= 382,
782 CV_AMD64_YMM15
= 383,
783 CV_AMD64_YMM0H
= 384,
784 CV_AMD64_YMM1H
= 385,
785 CV_AMD64_YMM2H
= 386,
786 CV_AMD64_YMM3H
= 387,
787 CV_AMD64_YMM4H
= 388,
788 CV_AMD64_YMM5H
= 389,
789 CV_AMD64_YMM6H
= 390,
790 CV_AMD64_YMM7H
= 391,
791 CV_AMD64_YMM8H
= 392,
792 CV_AMD64_YMM9H
= 393,
793 CV_AMD64_YMM10H
= 394,
794 CV_AMD64_YMM11H
= 395,
795 CV_AMD64_YMM12H
= 396,
796 CV_AMD64_YMM13H
= 397,
797 CV_AMD64_YMM14H
= 398,
798 CV_AMD64_YMM15H
= 399,
799 CV_AMD64_XMM0IL
= 400,
800 CV_AMD64_XMM1IL
= 401,
801 CV_AMD64_XMM2IL
= 402,
802 CV_AMD64_XMM3IL
= 403,
803 CV_AMD64_XMM4IL
= 404,
804 CV_AMD64_XMM5IL
= 405,
805 CV_AMD64_XMM6IL
= 406,
806 CV_AMD64_XMM7IL
= 407,
807 CV_AMD64_XMM8IL
= 408,
808 CV_AMD64_XMM9IL
= 409,
809 CV_AMD64_XMM10IL
= 410,
810 CV_AMD64_XMM11IL
= 411,
811 CV_AMD64_XMM12IL
= 412,
812 CV_AMD64_XMM13IL
= 413,
813 CV_AMD64_XMM14IL
= 414,
814 CV_AMD64_XMM15IL
= 415,
815 CV_AMD64_XMM0IH
= 416,
816 CV_AMD64_XMM1IH
= 417,
817 CV_AMD64_XMM2IH
= 418,
818 CV_AMD64_XMM3IH
= 419,
819 CV_AMD64_XMM4IH
= 420,
820 CV_AMD64_XMM5IH
= 421,
821 CV_AMD64_XMM6IH
= 422,
822 CV_AMD64_XMM7IH
= 423,
823 CV_AMD64_XMM8IH
= 424,
824 CV_AMD64_XMM9IH
= 425,
825 CV_AMD64_XMM10IH
= 426,
826 CV_AMD64_XMM11IH
= 427,
827 CV_AMD64_XMM12IH
= 428,
828 CV_AMD64_XMM13IH
= 429,
829 CV_AMD64_XMM14IH
= 430,
830 CV_AMD64_XMM15IH
= 431,
831 CV_AMD64_YMM0I0
= 432,
832 CV_AMD64_YMM0I1
= 433,
833 CV_AMD64_YMM0I2
= 434,
834 CV_AMD64_YMM0I3
= 435,
835 CV_AMD64_YMM1I0
= 436,
836 CV_AMD64_YMM1I1
= 437,
837 CV_AMD64_YMM1I2
= 438,
838 CV_AMD64_YMM1I3
= 439,
839 CV_AMD64_YMM2I0
= 440,
840 CV_AMD64_YMM2I1
= 441,
841 CV_AMD64_YMM2I2
= 442,
842 CV_AMD64_YMM2I3
= 443,
843 CV_AMD64_YMM3I0
= 444,
844 CV_AMD64_YMM3I1
= 445,
845 CV_AMD64_YMM3I2
= 446,
846 CV_AMD64_YMM3I3
= 447,
847 CV_AMD64_YMM4I0
= 448,
848 CV_AMD64_YMM4I1
= 449,
849 CV_AMD64_YMM4I2
= 450,
850 CV_AMD64_YMM4I3
= 451,
851 CV_AMD64_YMM5I0
= 452,
852 CV_AMD64_YMM5I1
= 453,
853 CV_AMD64_YMM5I2
= 454,
854 CV_AMD64_YMM5I3
= 455,
855 CV_AMD64_YMM6I0
= 456,
856 CV_AMD64_YMM6I1
= 457,
857 CV_AMD64_YMM6I2
= 458,
858 CV_AMD64_YMM6I3
= 459,
859 CV_AMD64_YMM7I0
= 460,
860 CV_AMD64_YMM7I1
= 461,
861 CV_AMD64_YMM7I2
= 462,
862 CV_AMD64_YMM7I3
= 463,
863 CV_AMD64_YMM8I0
= 464,
864 CV_AMD64_YMM8I1
= 465,
865 CV_AMD64_YMM8I2
= 466,
866 CV_AMD64_YMM8I3
= 467,
867 CV_AMD64_YMM9I0
= 468,
868 CV_AMD64_YMM9I1
= 469,
869 CV_AMD64_YMM9I2
= 470,
870 CV_AMD64_YMM9I3
= 471,
871 CV_AMD64_YMM10I0
= 472,
872 CV_AMD64_YMM10I1
= 473,
873 CV_AMD64_YMM10I2
= 474,
874 CV_AMD64_YMM10I3
= 475,
875 CV_AMD64_YMM11I0
= 476,
876 CV_AMD64_YMM11I1
= 477,
877 CV_AMD64_YMM11I2
= 478,
878 CV_AMD64_YMM11I3
= 479,
879 CV_AMD64_YMM12I0
= 480,
880 CV_AMD64_YMM12I1
= 481,
881 CV_AMD64_YMM12I2
= 482,
882 CV_AMD64_YMM12I3
= 483,
883 CV_AMD64_YMM13I0
= 484,
884 CV_AMD64_YMM13I1
= 485,
885 CV_AMD64_YMM13I2
= 486,
886 CV_AMD64_YMM13I3
= 487,
887 CV_AMD64_YMM14I0
= 488,
888 CV_AMD64_YMM14I1
= 489,
889 CV_AMD64_YMM14I2
= 490,
890 CV_AMD64_YMM14I3
= 491,
891 CV_AMD64_YMM15I0
= 492,
892 CV_AMD64_YMM15I1
= 493,
893 CV_AMD64_YMM15I2
= 494,
894 CV_AMD64_YMM15I3
= 495,
895 CV_AMD64_YMM0F0
= 496,
896 CV_AMD64_YMM0F1
= 497,
897 CV_AMD64_YMM0F2
= 498,
898 CV_AMD64_YMM0F3
= 499,
899 CV_AMD64_YMM0F4
= 500,
900 CV_AMD64_YMM0F5
= 501,
901 CV_AMD64_YMM0F6
= 502,
902 CV_AMD64_YMM0F7
= 503,
903 CV_AMD64_YMM1F0
= 504,
904 CV_AMD64_YMM1F1
= 505,
905 CV_AMD64_YMM1F2
= 506,
906 CV_AMD64_YMM1F3
= 507,
907 CV_AMD64_YMM1F4
= 508,
908 CV_AMD64_YMM1F5
= 509,
909 CV_AMD64_YMM1F6
= 510,
910 CV_AMD64_YMM1F7
= 511,
911 CV_AMD64_YMM2F0
= 512,
912 CV_AMD64_YMM2F1
= 513,
913 CV_AMD64_YMM2F2
= 514,
914 CV_AMD64_YMM2F3
= 515,
915 CV_AMD64_YMM2F4
= 516,
916 CV_AMD64_YMM2F5
= 517,
917 CV_AMD64_YMM2F6
= 518,
918 CV_AMD64_YMM2F7
= 519,
919 CV_AMD64_YMM3F0
= 520,
920 CV_AMD64_YMM3F1
= 521,
921 CV_AMD64_YMM3F2
= 522,
922 CV_AMD64_YMM3F3
= 523,
923 CV_AMD64_YMM3F4
= 524,
924 CV_AMD64_YMM3F5
= 525,
925 CV_AMD64_YMM3F6
= 526,
926 CV_AMD64_YMM3F7
= 527,
927 CV_AMD64_YMM4F0
= 528,
928 CV_AMD64_YMM4F1
= 529,
929 CV_AMD64_YMM4F2
= 530,
930 CV_AMD64_YMM4F3
= 531,
931 CV_AMD64_YMM4F4
= 532,
932 CV_AMD64_YMM4F5
= 533,
933 CV_AMD64_YMM4F6
= 534,
934 CV_AMD64_YMM4F7
= 535,
935 CV_AMD64_YMM5F0
= 536,
936 CV_AMD64_YMM5F1
= 537,
937 CV_AMD64_YMM5F2
= 538,
938 CV_AMD64_YMM5F3
= 539,
939 CV_AMD64_YMM5F4
= 540,
940 CV_AMD64_YMM5F5
= 541,
941 CV_AMD64_YMM5F6
= 542,
942 CV_AMD64_YMM5F7
= 543,
943 CV_AMD64_YMM6F0
= 544,
944 CV_AMD64_YMM6F1
= 545,
945 CV_AMD64_YMM6F2
= 546,
946 CV_AMD64_YMM6F3
= 547,
947 CV_AMD64_YMM6F4
= 548,
948 CV_AMD64_YMM6F5
= 549,
949 CV_AMD64_YMM6F6
= 550,
950 CV_AMD64_YMM6F7
= 551,
951 CV_AMD64_YMM7F0
= 552,
952 CV_AMD64_YMM7F1
= 553,
953 CV_AMD64_YMM7F2
= 554,
954 CV_AMD64_YMM7F3
= 555,
955 CV_AMD64_YMM7F4
= 556,
956 CV_AMD64_YMM7F5
= 557,
957 CV_AMD64_YMM7F6
= 558,
958 CV_AMD64_YMM7F7
= 559,
959 CV_AMD64_YMM8F0
= 560,
960 CV_AMD64_YMM8F1
= 561,
961 CV_AMD64_YMM8F2
= 562,
962 CV_AMD64_YMM8F3
= 563,
963 CV_AMD64_YMM8F4
= 564,
964 CV_AMD64_YMM8F5
= 565,
965 CV_AMD64_YMM8F6
= 566,
966 CV_AMD64_YMM8F7
= 567,
967 CV_AMD64_YMM9F0
= 568,
968 CV_AMD64_YMM9F1
= 569,
969 CV_AMD64_YMM9F2
= 570,
970 CV_AMD64_YMM9F3
= 571,
971 CV_AMD64_YMM9F4
= 572,
972 CV_AMD64_YMM9F5
= 573,
973 CV_AMD64_YMM9F6
= 574,
974 CV_AMD64_YMM9F7
= 575,
975 CV_AMD64_YMM10F0
= 576,
976 CV_AMD64_YMM10F1
= 577,
977 CV_AMD64_YMM10F2
= 578,
978 CV_AMD64_YMM10F3
= 579,
979 CV_AMD64_YMM10F4
= 580,
980 CV_AMD64_YMM10F5
= 581,
981 CV_AMD64_YMM10F6
= 582,
982 CV_AMD64_YMM10F7
= 583,
983 CV_AMD64_YMM11F0
= 584,
984 CV_AMD64_YMM11F1
= 585,
985 CV_AMD64_YMM11F2
= 586,
986 CV_AMD64_YMM11F3
= 587,
987 CV_AMD64_YMM11F4
= 588,
988 CV_AMD64_YMM11F5
= 589,
989 CV_AMD64_YMM11F6
= 590,
990 CV_AMD64_YMM11F7
= 591,
991 CV_AMD64_YMM12F0
= 592,
992 CV_AMD64_YMM12F1
= 593,
993 CV_AMD64_YMM12F2
= 594,
994 CV_AMD64_YMM12F3
= 595,
995 CV_AMD64_YMM12F4
= 596,
996 CV_AMD64_YMM12F5
= 597,
997 CV_AMD64_YMM12F6
= 598,
998 CV_AMD64_YMM12F7
= 599,
999 CV_AMD64_YMM13F0
= 600,
1000 CV_AMD64_YMM13F1
= 601,
1001 CV_AMD64_YMM13F2
= 602,
1002 CV_AMD64_YMM13F3
= 603,
1003 CV_AMD64_YMM13F4
= 604,
1004 CV_AMD64_YMM13F5
= 605,
1005 CV_AMD64_YMM13F6
= 606,
1006 CV_AMD64_YMM13F7
= 607,
1007 CV_AMD64_YMM14F0
= 608,
1008 CV_AMD64_YMM14F1
= 609,
1009 CV_AMD64_YMM14F2
= 610,
1010 CV_AMD64_YMM14F3
= 611,
1011 CV_AMD64_YMM14F4
= 612,
1012 CV_AMD64_YMM14F5
= 613,
1013 CV_AMD64_YMM14F6
= 614,
1014 CV_AMD64_YMM14F7
= 615,
1015 CV_AMD64_YMM15F0
= 616,
1016 CV_AMD64_YMM15F1
= 617,
1017 CV_AMD64_YMM15F2
= 618,
1018 CV_AMD64_YMM15F3
= 619,
1019 CV_AMD64_YMM15F4
= 620,
1020 CV_AMD64_YMM15F5
= 621,
1021 CV_AMD64_YMM15F6
= 622,
1022 CV_AMD64_YMM15F7
= 623,
1023 CV_AMD64_YMM0D0
= 624,
1024 CV_AMD64_YMM0D1
= 625,
1025 CV_AMD64_YMM0D2
= 626,
1026 CV_AMD64_YMM0D3
= 627,
1027 CV_AMD64_YMM1D0
= 628,
1028 CV_AMD64_YMM1D1
= 629,
1029 CV_AMD64_YMM1D2
= 630,
1030 CV_AMD64_YMM1D3
= 631,
1031 CV_AMD64_YMM2D0
= 632,
1032 CV_AMD64_YMM2D1
= 633,
1033 CV_AMD64_YMM2D2
= 634,
1034 CV_AMD64_YMM2D3
= 635,
1035 CV_AMD64_YMM3D0
= 636,
1036 CV_AMD64_YMM3D1
= 637,
1037 CV_AMD64_YMM3D2
= 638,
1038 CV_AMD64_YMM3D3
= 639,
1039 CV_AMD64_YMM4D0
= 640,
1040 CV_AMD64_YMM4D1
= 641,
1041 CV_AMD64_YMM4D2
= 642,
1042 CV_AMD64_YMM4D3
= 643,
1043 CV_AMD64_YMM5D0
= 644,
1044 CV_AMD64_YMM5D1
= 645,
1045 CV_AMD64_YMM5D2
= 646,
1046 CV_AMD64_YMM5D3
= 647,
1047 CV_AMD64_YMM6D0
= 648,
1048 CV_AMD64_YMM6D1
= 649,
1049 CV_AMD64_YMM6D2
= 650,
1050 CV_AMD64_YMM6D3
= 651,
1051 CV_AMD64_YMM7D0
= 652,
1052 CV_AMD64_YMM7D1
= 653,
1053 CV_AMD64_YMM7D2
= 654,
1054 CV_AMD64_YMM7D3
= 655,
1055 CV_AMD64_YMM8D0
= 656,
1056 CV_AMD64_YMM8D1
= 657,
1057 CV_AMD64_YMM8D2
= 658,
1058 CV_AMD64_YMM8D3
= 659,
1059 CV_AMD64_YMM9D0
= 660,
1060 CV_AMD64_YMM9D1
= 661,
1061 CV_AMD64_YMM9D2
= 662,
1062 CV_AMD64_YMM9D3
= 663,
1063 CV_AMD64_YMM10D0
= 664,
1064 CV_AMD64_YMM10D1
= 665,
1065 CV_AMD64_YMM10D2
= 666,
1066 CV_AMD64_YMM10D3
= 667,
1067 CV_AMD64_YMM11D0
= 668,
1068 CV_AMD64_YMM11D1
= 669,
1069 CV_AMD64_YMM11D2
= 670,
1070 CV_AMD64_YMM11D3
= 671,
1071 CV_AMD64_YMM12D0
= 672,
1072 CV_AMD64_YMM12D1
= 673,
1073 CV_AMD64_YMM12D2
= 674,
1074 CV_AMD64_YMM12D3
= 675,
1075 CV_AMD64_YMM13D0
= 676,
1076 CV_AMD64_YMM13D1
= 677,
1077 CV_AMD64_YMM13D2
= 678,
1078 CV_AMD64_YMM13D3
= 679,
1079 CV_AMD64_YMM14D0
= 680,
1080 CV_AMD64_YMM14D1
= 681,
1081 CV_AMD64_YMM14D2
= 682,
1082 CV_AMD64_YMM14D3
= 683,
1083 CV_AMD64_YMM15D0
= 684,
1084 CV_AMD64_YMM15D1
= 685,
1085 CV_AMD64_YMM15D2
= 686,
1086 CV_AMD64_YMM15D3
= 687
1089 /* This is enum BinaryAnnotationOpcode in Microsoft's cvinfo.h. */
1091 enum binary_annotation_opcode
{
1094 ba_op_change_code_offset_base
,
1095 ba_op_change_code_offset
,
1096 ba_op_change_code_length
,
1098 ba_op_change_line_offset
,
1099 ba_op_change_line_end_delta
,
1100 ba_op_change_range_kind
,
1101 ba_op_change_column_start
,
1102 ba_op_change_column_end_delta
,
1103 ba_op_change_code_offset_and_line_offset
,
1104 ba_op_change_code_length_and_code_offset
,
1105 ba_op_change_column_end
1108 struct codeview_string
1110 codeview_string
*next
;
1115 struct string_hasher
: free_ptr_hash
<struct codeview_string
>
1117 typedef const char *compare_type
;
1119 static hashval_t
hash (const codeview_string
*x
)
1121 return htab_hash_string (x
->string
);
1124 static bool equal (const codeview_string
*x
, const char *y
)
1126 return !strcmp (x
->string
, y
);
1129 static void mark_empty (codeview_string
*x
)
1138 static void remove (codeview_string
*&x
)
1144 struct codeview_source_file
1146 codeview_source_file
*next
;
1147 unsigned int file_num
;
1148 uint32_t string_offset
;
1150 uint8_t hash
[HASH_SIZE
];
1153 struct codeview_line
1155 codeview_line
*next
;
1156 unsigned int line_no
;
1157 unsigned int label_num
;
1160 struct codeview_line_block
1162 codeview_line_block
*next
;
1164 unsigned int num_lines
;
1165 codeview_line
*lines
, *last_line
;
1168 struct codeview_inlinee_lines
1170 codeview_inlinee_lines
*next
;
1173 uint32_t starting_line
;
1176 struct codeview_function
1178 codeview_function
*next
;
1179 codeview_function
*htab_next
;
1181 unsigned int end_label
;
1182 codeview_line_block
*blocks
, *last_block
;
1183 codeview_function
*parent
;
1184 unsigned int inline_block
;
1185 location_t inline_loc
;
1188 struct codeview_symbol
1190 codeview_symbol
*next
;
1191 enum cv_sym_type kind
;
1214 struct codeview_type
1221 struct die_hasher
: free_ptr_hash
<codeview_type
>
1223 typedef dw_die_ref compare_type
;
1225 static hashval_t
hash (const codeview_type
*x
)
1227 return htab_hash_pointer (x
->die
);
1230 static bool equal (const codeview_type
*x
, const dw_die_ref y
)
1236 struct codeview_integer
1242 struct codeview_subtype
1244 struct codeview_subtype
*next
;
1245 enum cv_leaf_type kind
;
1252 struct codeview_integer value
;
1260 uint16_t attributes
;
1262 codeview_integer offset
;
1267 uint16_t attributes
;
1273 uint16_t method_attribute
;
1274 uint32_t method_type
;
1280 uint32_t method_list
;
1285 uint16_t attributes
;
1286 uint32_t base_class_type
;
1287 codeview_integer offset
;
1297 struct lf_methodlist_entry
1299 uint16_t method_attribute
;
1300 uint32_t method_type
;
1303 struct codeview_custom_type
1305 struct codeview_custom_type
*next
;
1307 enum cv_leaf_type kind
;
1314 uint32_t attributes
;
1315 uint32_t containing_class
;
1316 uint16_t ptr_to_mem_type
;
1326 codeview_subtype
*subtypes
;
1327 codeview_subtype
*last_subtype
;
1332 uint16_t properties
;
1333 uint32_t underlying_type
;
1339 uint16_t num_members
;
1340 uint16_t properties
;
1341 uint32_t field_list
;
1342 uint32_t derived_from
;
1344 codeview_integer length
;
1349 uint32_t element_type
;
1350 uint32_t index_type
;
1351 codeview_integer length_in_bytes
;
1361 uint32_t return_type
;
1362 uint8_t calling_convention
;
1364 uint16_t num_parameters
;
1369 uint32_t num_entries
;
1374 uint32_t parent_scope
;
1375 uint32_t function_type
;
1380 uint32_t parent_type
;
1381 uint32_t function_type
;
1391 uint32_t return_type
;
1392 uint32_t containing_class_type
;
1394 uint8_t calling_convention
;
1396 uint16_t num_parameters
;
1398 int32_t this_adjustment
;
1403 lf_methodlist_entry
*entries
;
1408 struct codeview_deferred_type
1410 struct codeview_deferred_type
*next
;
1414 struct string_id_hasher
: nofree_ptr_hash
<struct codeview_custom_type
>
1416 typedef const char *compare_type
;
1418 static hashval_t
hash (const codeview_custom_type
*x
)
1420 return htab_hash_string (x
->lf_string_id
.string
);
1423 static bool equal (const codeview_custom_type
*x
, const char *y
)
1425 return !strcmp (x
->lf_string_id
.string
, y
);
1429 struct codeview_method
1435 struct codeview_method
*next
;
1436 struct codeview_method
*last
;
1439 struct method_hasher
: nofree_ptr_hash
<struct codeview_method
>
1441 typedef const char *compare_type
;
1443 static hashval_t
hash (const codeview_method
*x
)
1445 return htab_hash_string (x
->name
);
1448 static bool equal (const codeview_method
*x
, const char *y
)
1450 return !strcmp (x
->name
, y
);
1454 struct inlinee_lines_hasher
: free_ptr_hash
<struct codeview_inlinee_lines
>
1456 typedef uint32_t compare_type
;
1458 static hashval_t
hash (const codeview_inlinee_lines
*il
)
1463 static bool equal (const codeview_inlinee_lines
*il
, uint32_t func_id
)
1465 return il
->func_id
== func_id
;
1469 struct cv_func_hasher
: nofree_ptr_hash
<struct codeview_function
>
1471 typedef dw_die_ref compare_type
;
1473 static bool equal (const codeview_function
*f
, dw_die_ref die
)
1475 return lookup_decl_die (f
->func
->decl
) == die
;
1479 static unsigned int line_label_num
;
1480 static unsigned int func_label_num
;
1481 static unsigned int sym_label_num
;
1482 static codeview_source_file
*files
, *last_file
;
1483 static unsigned int num_files
;
1484 static uint32_t string_offset
= 1;
1485 static hash_table
<string_hasher
> *strings_htab
;
1486 static codeview_string
*strings
, *last_string
;
1487 static codeview_function
*funcs
, *last_func
, *cur_func
;
1488 static const char* last_filename
;
1489 static uint32_t last_file_id
;
1490 static codeview_symbol
*sym
, *last_sym
;
1491 static hash_table
<die_hasher
> *types_htab
, *func_htab
;
1492 static codeview_custom_type
*custom_types
, *last_custom_type
;
1493 static codeview_deferred_type
*deferred_types
, *last_deferred_type
;
1494 static hash_table
<string_id_hasher
> *string_id_htab
;
1495 static hash_table
<inlinee_lines_hasher
> *inlinee_lines_htab
;
1496 static hash_table
<cv_func_hasher
> *cv_func_htab
;
1498 static uint32_t get_type_num (dw_die_ref type
, bool in_struct
, bool no_fwd_ref
);
1499 static uint32_t get_type_num_subroutine_type (dw_die_ref type
, bool in_struct
,
1500 uint32_t containing_class_type
,
1502 int32_t this_adjustment
);
1503 static void write_cv_padding (size_t padding
);
1504 static void flush_deferred_types (void);
1505 static uint32_t get_func_id (dw_die_ref die
);
1506 static void write_inlinesite_records (dw_die_ref func
, dw_die_ref die
);
1508 /* Return the file ID corresponding to a given source filename. */
1511 get_file_id (const char *filename
)
1513 codeview_source_file
*sf
= files
;
1515 if (filename
== last_filename
)
1516 return last_file_id
;
1520 if (!strcmp (sf
->filename
, filename
))
1524 /* 0x18 is the size of the checksum entry for each file.
1525 0x6 bytes for the header, plus 0x10 bytes for the hash,
1526 then padded to a multiple of 4. */
1528 file_id
= sf
->file_num
* 0x18;
1529 last_filename
= filename
;
1530 last_file_id
= file_id
;
1541 /* Allocate and initialize a codeview_function struct. */
1543 static codeview_function
*
1544 new_codeview_function (void)
1546 codeview_function
**slot
;
1548 codeview_function
*f
= (codeview_function
*)
1549 xmalloc (sizeof (codeview_function
));
1552 f
->htab_next
= NULL
;
1555 f
->blocks
= f
->last_block
= NULL
;
1556 f
->inline_block
= 0;
1562 last_func
->next
= f
;
1567 cv_func_htab
= new hash_table
<cv_func_hasher
> (10);
1569 die
= lookup_decl_die (cfun
->decl
);
1571 slot
= cv_func_htab
->find_slot_with_hash (die
, htab_hash_pointer (die
),
1574 f
->htab_next
= *slot
;
1581 /* Record new line number against the current function. */
1584 codeview_source_line (unsigned int line_no
, const char *filename
)
1587 uint32_t file_id
= get_file_id (filename
);
1588 unsigned int label_num
= ++line_label_num
;
1590 targetm
.asm_out
.internal_label (asm_out_file
, LINE_LABEL
, label_num
);
1592 if (!cur_func
|| cur_func
->func
!= cfun
)
1594 codeview_function
*f
= new_codeview_function ();
1601 if (!cur_func
->last_block
|| cur_func
->last_block
->file_id
!= file_id
)
1603 codeview_line_block
*b
;
1605 b
= (codeview_line_block
*) xmalloc (sizeof (codeview_line_block
));
1608 b
->file_id
= file_id
;
1610 b
->lines
= b
->last_line
= NULL
;
1612 if (!cur_func
->blocks
)
1613 cur_func
->blocks
= b
;
1615 cur_func
->last_block
->next
= b
;
1617 cur_func
->last_block
= b
;
1620 if (cur_func
->last_block
->last_line
1621 && cur_func
->last_block
->last_line
->line_no
== line_no
)
1624 l
= (codeview_line
*) xmalloc (sizeof (codeview_line
));
1627 l
->line_no
= line_no
;
1628 l
->label_num
= label_num
;
1630 if (!cur_func
->last_block
->lines
)
1631 cur_func
->last_block
->lines
= l
;
1633 cur_func
->last_block
->last_line
->next
= l
;
1635 cur_func
->last_block
->last_line
= l
;
1636 cur_func
->last_block
->num_lines
++;
1639 /* We have encountered the beginning of a lexical block. If this is actually
1640 an inlined function, allocate a new codeview_function for this. */
1643 codeview_begin_block (unsigned int line ATTRIBUTE_UNUSED
,
1644 unsigned int blocknum
, tree block
)
1646 if (inlined_function_outer_scope_p (block
))
1648 location_t locus
= BLOCK_SOURCE_LOCATION (block
);
1649 expanded_location s
= expand_location (locus
);
1650 codeview_function
*f
= new_codeview_function ();
1652 codeview_source_line (s
.line
, s
.file
);
1654 f
->parent
= cur_func
;
1655 f
->inline_block
= blocknum
;
1656 f
->inline_loc
= locus
;
1662 /* We have encountered the end of a lexical block. If this is the end of an
1663 inlined function, change cur_func back to its parent. */
1666 codeview_end_block (unsigned int line ATTRIBUTE_UNUSED
, unsigned int blocknum
)
1668 if (cur_func
&& cur_func
->inline_block
== blocknum
)
1670 /* If inlined function, add dummy source line at the end so we know how
1671 long the actual last line is. */
1672 codeview_source_line (0, "");
1674 cur_func
= cur_func
->parent
;
1678 /* Adds string to the string table, returning its offset. If already present,
1679 this returns the offset of the existing string. */
1682 add_string (const char *string
)
1684 codeview_string
**slot
;
1689 strings_htab
= new hash_table
<string_hasher
> (10);
1691 slot
= strings_htab
->find_slot_with_hash (string
, htab_hash_string (string
),
1695 return (*slot
)->offset
;
1697 s
= (codeview_string
*) xmalloc (sizeof (codeview_string
));
1698 len
= strlen (string
);
1702 s
->offset
= string_offset
;
1703 string_offset
+= len
+ 1;
1705 s
->string
= xstrdup (string
);
1708 last_string
->next
= s
;
1719 /* A new source file has been encountered - record the details and calculate
1723 codeview_start_source_file (const char *filename
)
1725 codeview_source_file
*sf
;
1727 uint32_t string_offset
;
1730 path
= lrealpath (filename
);
1731 string_offset
= add_string (path
);
1737 if (sf
->string_offset
== string_offset
)
1743 sf
= (codeview_source_file
*) xmalloc (sizeof (codeview_source_file
));
1745 sf
->file_num
= num_files
;
1746 sf
->string_offset
= string_offset
;
1747 sf
->filename
= xstrdup (filename
);
1749 f
= fopen (filename
, "r");
1751 internal_error ("could not open %s for reading", filename
);
1753 if (md5_stream (f
, sf
->hash
))
1756 internal_error ("md5_stream failed");
1762 last_file
->next
= sf
;
1770 /* Write out the strings table into the .debug$S section. The linker will
1771 parse this, and handle the deduplication and hashing for all the object
1775 write_strings_table (void)
1777 codeview_string
*string
;
1779 fputs (integer_asm_op (4, false), asm_out_file
);
1780 fprint_whex (asm_out_file
, DEBUG_S_STRINGTABLE
);
1781 putc ('\n', asm_out_file
);
1783 fputs (integer_asm_op (4, false), asm_out_file
);
1784 asm_fprintf (asm_out_file
, "%LLcv_strings_end - %LLcv_strings_start\n");
1786 asm_fprintf (asm_out_file
, "%LLcv_strings_start:\n");
1788 /* The first entry is always an empty string. */
1789 fputs (integer_asm_op (1, false), asm_out_file
);
1790 fprint_whex (asm_out_file
, 0);
1791 putc ('\n', asm_out_file
);
1796 ASM_OUTPUT_ASCII (asm_out_file
, string
->string
,
1797 strlen (string
->string
) + 1);
1799 string
= string
->next
;
1802 delete strings_htab
;
1804 asm_fprintf (asm_out_file
, "%LLcv_strings_end:\n");
1806 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
1809 /* Write out the file checksums data into the .debug$S section. */
1812 write_source_files (void)
1814 fputs (integer_asm_op (4, false), asm_out_file
);
1815 fprint_whex (asm_out_file
, DEBUG_S_FILECHKSMS
);
1816 putc ('\n', asm_out_file
);
1818 fputs (integer_asm_op (4, false), asm_out_file
);
1819 asm_fprintf (asm_out_file
,
1820 "%LLcv_filechksms_end - %LLcv_filechksms_start\n");
1822 asm_fprintf (asm_out_file
, "%LLcv_filechksms_start:\n");
1826 codeview_source_file
*next
= files
->next
;
1828 /* This is struct file_checksum in binutils, or filedata in Microsoft's
1831 struct file_checksum
1834 uint8_t checksum_length;
1835 uint8_t checksum_type;
1838 followed then by the bytes of the hash, padded to the next 4 bytes.
1839 file_id here is actually the offset in the strings table. */
1841 fputs (integer_asm_op (4, false), asm_out_file
);
1842 fprint_whex (asm_out_file
, files
->string_offset
);
1843 putc ('\n', asm_out_file
);
1845 fputs (integer_asm_op (1, false), asm_out_file
);
1846 fprint_whex (asm_out_file
, HASH_SIZE
);
1847 putc ('\n', asm_out_file
);
1849 fputs (integer_asm_op (1, false), asm_out_file
);
1850 fprint_whex (asm_out_file
, CHKSUM_TYPE_MD5
);
1851 putc ('\n', asm_out_file
);
1853 for (unsigned int i
= 0; i
< HASH_SIZE
; i
++)
1855 fputs (integer_asm_op (1, false), asm_out_file
);
1856 fprint_whex (asm_out_file
, files
->hash
[i
]);
1857 putc ('\n', asm_out_file
);
1860 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
1862 free (files
->filename
);
1868 asm_fprintf (asm_out_file
, "%LLcv_filechksms_end:\n");
1871 /* Write out the line number information for each function into the
1872 .debug$S section. */
1875 write_line_numbers (void)
1877 unsigned int func_num
= 0;
1878 codeview_function
*f
= funcs
;
1882 codeview_function
*next_func
= f
->next
;
1883 unsigned int first_label_num
;
1884 codeview_line_block
*b
= f
->blocks
;
1886 if (f
->inline_block
!= 0)
1892 fputs (integer_asm_op (4, false), asm_out_file
);
1893 fprint_whex (asm_out_file
, DEBUG_S_LINES
);
1894 putc ('\n', asm_out_file
);
1896 fputs (integer_asm_op (4, false), asm_out_file
);
1897 asm_fprintf (asm_out_file
, "%LLcv_lines%u_end - %LLcv_lines%u_start\n",
1898 func_num
, func_num
);
1900 asm_fprintf (asm_out_file
, "%LLcv_lines%u_start:\n", func_num
);
1902 /* Output the header (struct cv_lines_header in binutils or
1903 CV_DebugSLinesHeader_t in Microsoft's cvinfo.h):
1905 struct cv_lines_header
1914 asm_fprintf (asm_out_file
, "\t.secrel32\t%L" LINE_LABEL
"%u\n",
1915 b
->lines
->label_num
);
1916 asm_fprintf (asm_out_file
, "\t.secidx\t%L" LINE_LABEL
"%u\n",
1917 b
->lines
->label_num
);
1920 fputs (integer_asm_op (2, false), asm_out_file
);
1921 fprint_whex (asm_out_file
, 0);
1922 putc ('\n', asm_out_file
);
1924 first_label_num
= b
->lines
->label_num
;
1927 fputs (integer_asm_op (4, false), asm_out_file
);
1928 asm_fprintf (asm_out_file
,
1929 "%L" END_FUNC_LABEL
"%u - %L" LINE_LABEL
"%u\n",
1930 f
->end_label
, first_label_num
);
1934 codeview_line_block
*next_block
= b
->next
;
1935 codeview_line
*l
= b
->lines
;
1937 /* Next comes the blocks, each block being a part of a function
1938 within the same source file (struct cv_lines_block in binutils or
1939 CV_DebugSLinesFileBlockHeader_t in Microsoft's cvinfo.h):
1941 struct cv_lines_block
1950 fputs (integer_asm_op (4, false), asm_out_file
);
1951 fprint_whex (asm_out_file
, b
->file_id
);
1952 putc ('\n', asm_out_file
);
1954 /* number of lines */
1955 fputs (integer_asm_op (4, false), asm_out_file
);
1956 fprint_whex (asm_out_file
, b
->num_lines
);
1957 putc ('\n', asm_out_file
);
1959 /* length of code block: (num_lines * sizeof (struct cv_line)) +
1960 sizeof (struct cv_lines_block) */
1961 fputs (integer_asm_op (4, false), asm_out_file
);
1962 fprint_whex (asm_out_file
, (b
->num_lines
* 0x8) + 0xc);
1963 putc ('\n', asm_out_file
);
1967 codeview_line
*next_line
= l
->next
;
1969 /* Finally comes the line number information (struct cv_line in
1970 binutils or CV_Line_t in Microsoft's cvinfo.h):
1978 Strictly speaking line_no is a bitfield: the bottom 24 bits
1979 are the line number, and the top bit means "is a statement".
1982 fputs (integer_asm_op (4, false), asm_out_file
);
1983 asm_fprintf (asm_out_file
,
1984 "%L" LINE_LABEL
"%u - %L" LINE_LABEL
"%u\n",
1985 l
->label_num
, first_label_num
);
1987 fputs (integer_asm_op (4, false), asm_out_file
);
1988 fprint_whex (asm_out_file
,
1990 | (l
->line_no
& 0xffffff));
1991 putc ('\n', asm_out_file
);
1999 asm_fprintf (asm_out_file
, "%LLcv_lines%u_end:\n", func_num
);
2006 /* Write an entry in the S_INLINEELINES subsection of .debug$S. */
2009 write_inlinee_lines_entry (codeview_inlinee_lines
**slot
,
2010 void *ctx ATTRIBUTE_UNUSED
)
2012 codeview_inlinee_lines
*il
= *slot
;
2014 /* The inlinee lines data consists of a version uint32_t (0), followed by
2015 an array of struct inlinee_source_line:
2017 struct inlinee_source_line
2019 uint32_t function_id;
2024 (see InlineeSourceLine in cvinfo.h)
2027 fputs (integer_asm_op (4, false), asm_out_file
);
2028 fprint_whex (asm_out_file
, il
->func_id
);
2029 putc ('\n', asm_out_file
);
2031 fputs (integer_asm_op (4, false), asm_out_file
);
2032 fprint_whex (asm_out_file
, il
->file_id
);
2033 putc ('\n', asm_out_file
);
2035 fputs (integer_asm_op (4, false), asm_out_file
);
2036 fprint_whex (asm_out_file
, il
->starting_line
);
2037 putc ('\n', asm_out_file
);
2042 /* Write the S_INLINEELINES subsection of .debug$S, which lists the filename
2043 and line number for the start of each inlined function. */
2046 write_inlinee_lines (void)
2048 fputs (integer_asm_op (4, false), asm_out_file
);
2049 fprint_whex (asm_out_file
, DEBUG_S_INLINEELINES
);
2050 putc ('\n', asm_out_file
);
2052 fputs (integer_asm_op (4, false), asm_out_file
);
2053 asm_fprintf (asm_out_file
,
2054 "%LLcv_inlineelines_end - %LLcv_inlineelines_start\n");
2055 asm_fprintf (asm_out_file
, "%LLcv_inlineelines_start:\n");
2057 fputs (integer_asm_op (4, false), asm_out_file
);
2058 fprint_whex (asm_out_file
, CV_INLINEE_SOURCE_LINE_SIGNATURE
);
2059 putc ('\n', asm_out_file
);
2061 inlinee_lines_htab
->traverse
<void*, write_inlinee_lines_entry
> (NULL
);
2063 asm_fprintf (asm_out_file
, "%LLcv_inlineelines_end:\n");
2066 /* Treat cold sections as separate functions, for the purposes of line
2070 codeview_switch_text_section (void)
2072 codeview_function
*f
;
2074 if (cur_func
&& cur_func
->end_label
== 0)
2076 unsigned int label_num
= ++func_label_num
;
2078 targetm
.asm_out
.internal_label (asm_out_file
, END_FUNC_LABEL
,
2081 cur_func
->end_label
= label_num
;
2084 f
= new_codeview_function ();
2085 f
->parent
= cur_func
? cur_func
->parent
: NULL
;
2090 /* Mark the end of the current function. */
2093 codeview_end_epilogue (void)
2095 if (cur_func
&& cur_func
->end_label
== 0)
2097 unsigned int label_num
= ++func_label_num
;
2099 targetm
.asm_out
.internal_label (asm_out_file
, END_FUNC_LABEL
,
2102 cur_func
->end_label
= label_num
;
2106 /* Return the CodeView constant for the selected architecture. */
2109 target_processor (void)
2114 return CV_CFL_80386
;
2117 /* Return the CodeView constant for the language being used. */
2120 language_constant (void)
2122 const char *language_string
= lang_hooks
.name
;
2124 if (startswith (language_string
, "GNU C++"))
2126 else if (startswith (language_string
, "GNU C"))
2132 /* Write a S_COMPILE3 symbol, which records the details of the compiler
2136 write_compile3_symbol (void)
2138 unsigned int label_num
= ++sym_label_num
;
2140 static const char compiler_name
[] = "GCC ";
2142 /* This is struct COMPILESYM3 in binutils and Microsoft's cvinfo.h:
2150 uint16_t frontend_major;
2151 uint16_t frontend_minor;
2152 uint16_t frontend_build;
2153 uint16_t frontend_qfe;
2154 uint16_t backend_major;
2155 uint16_t backend_minor;
2156 uint16_t backend_build;
2157 uint16_t backend_qfe;
2161 fputs (integer_asm_op (2, false), asm_out_file
);
2162 asm_fprintf (asm_out_file
,
2163 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2164 label_num
, label_num
);
2166 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2168 fputs (integer_asm_op (2, false), asm_out_file
);
2169 fprint_whex (asm_out_file
, S_COMPILE3
);
2170 putc ('\n', asm_out_file
);
2172 /* Microsoft has the flags as a bitfield, with the bottom 8 bits being the
2173 language constant, and the reset being MSVC-specific stuff. */
2174 fputs (integer_asm_op (4, false), asm_out_file
);
2175 fprint_whex (asm_out_file
, language_constant ());
2176 putc ('\n', asm_out_file
);
2178 fputs (integer_asm_op (2, false), asm_out_file
);
2179 fprint_whex (asm_out_file
, target_processor ());
2180 putc ('\n', asm_out_file
);
2182 /* Write 8 uint16_ts for the frontend and backend versions. As with GAS, we
2183 zero these, as it's easier to record the version in the compiler
2185 for (unsigned int i
= 0; i
< 8; i
++)
2187 fputs (integer_asm_op (2, false), asm_out_file
);
2188 fprint_whex (asm_out_file
, 0);
2189 putc ('\n', asm_out_file
);
2192 ASM_OUTPUT_ASCII (asm_out_file
, compiler_name
, sizeof (compiler_name
) - 1);
2193 ASM_OUTPUT_ASCII (asm_out_file
, version_string
, strlen (version_string
) + 1);
2195 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2197 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2200 /* Write an S_GDATA32 symbol, representing a global variable, or an S_LDATA32
2201 symbol, for a static global variable. */
2204 write_data_symbol (codeview_symbol
*s
)
2206 unsigned int label_num
= ++sym_label_num
;
2208 dw_loc_descr_ref loc_ref
;
2210 /* This is struct datasym in binutils:
2223 /* Extract the DW_AT_location attribute from the DIE, and make sure it's in
2224 in a format we can parse. */
2226 loc
= get_AT (s
->data_symbol
.die
, DW_AT_location
);
2230 if (loc
->dw_attr_val
.val_class
!= dw_val_class_loc
)
2233 loc_ref
= loc
->dw_attr_val
.v
.val_loc
;
2234 if (!loc_ref
|| loc_ref
->dw_loc_opc
!= DW_OP_addr
)
2237 /* Output the S_GDATA32 / S_LDATA32 record. */
2239 fputs (integer_asm_op (2, false), asm_out_file
);
2240 asm_fprintf (asm_out_file
,
2241 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2242 label_num
, label_num
);
2244 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2246 fputs (integer_asm_op (2, false), asm_out_file
);
2247 fprint_whex (asm_out_file
, s
->kind
);
2248 putc ('\n', asm_out_file
);
2250 fputs (integer_asm_op (4, false), asm_out_file
);
2251 fprint_whex (asm_out_file
, s
->data_symbol
.type
);
2252 putc ('\n', asm_out_file
);
2254 asm_fprintf (asm_out_file
, "\t.secrel32 ");
2255 output_addr_const (asm_out_file
, loc_ref
->dw_loc_oprnd1
.v
.val_addr
);
2256 fputc ('\n', asm_out_file
);
2258 asm_fprintf (asm_out_file
, "\t.secidx ");
2259 output_addr_const (asm_out_file
, loc_ref
->dw_loc_oprnd1
.v
.val_addr
);
2260 fputc ('\n', asm_out_file
);
2262 ASM_OUTPUT_ASCII (asm_out_file
, s
->data_symbol
.name
,
2263 strlen (s
->data_symbol
.name
) + 1);
2265 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2267 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2270 free (s
->data_symbol
.name
);
2273 /* Write an S_LOCAL symbol, representing an optimized variable. This is then
2274 followed by various S_DEFRANGE_* symbols, which describe how to find the
2275 value of a variable and the range for which this is valid. */
2278 write_s_local (dw_die_ref die
)
2280 unsigned int label_num
= ++sym_label_num
;
2281 const char *name
= get_AT_string (die
, DW_AT_name
);
2284 /* This is struct LOCALSYM in Microsoft's cvinfo.h:
2295 fputs (integer_asm_op (2, false), asm_out_file
);
2296 asm_fprintf (asm_out_file
,
2297 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2298 label_num
, label_num
);
2300 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2302 fputs (integer_asm_op (2, false), asm_out_file
);
2303 fprint_whex (asm_out_file
, S_LOCAL
);
2304 putc ('\n', asm_out_file
);
2306 type
= get_type_num (get_AT_ref (die
, DW_AT_type
), false, false);
2308 fputs (integer_asm_op (4, false), asm_out_file
);
2309 fprint_whex (asm_out_file
, type
);
2310 putc ('\n', asm_out_file
);
2312 fputs (integer_asm_op (2, false), asm_out_file
);
2313 fprint_whex (asm_out_file
, 0);
2314 putc ('\n', asm_out_file
);
2316 ASM_OUTPUT_ASCII (asm_out_file
, name
, strlen (name
) + 1);
2318 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2320 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2323 /* Write an S_LDATA32 symbol, representing a static variable within a function.
2324 This symbol can also appear outside of a function block - see
2325 write_data_symbol. */
2328 write_local_s_ldata32 (dw_die_ref die
, dw_loc_descr_ref loc_ref
)
2330 unsigned int label_num
= ++sym_label_num
;
2331 const char *name
= get_AT_string (die
, DW_AT_name
);
2334 /* This is struct datasym in binutils:
2347 fputs (integer_asm_op (2, false), asm_out_file
);
2348 asm_fprintf (asm_out_file
,
2349 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2350 label_num
, label_num
);
2352 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2354 fputs (integer_asm_op (2, false), asm_out_file
);
2355 fprint_whex (asm_out_file
, S_LDATA32
);
2356 putc ('\n', asm_out_file
);
2358 type
= get_type_num (get_AT_ref (die
, DW_AT_type
), false, false);
2360 fputs (integer_asm_op (4, false), asm_out_file
);
2361 fprint_whex (asm_out_file
, type
);
2362 putc ('\n', asm_out_file
);
2364 asm_fprintf (asm_out_file
, "\t.secrel32 ");
2365 output_addr_const (asm_out_file
, loc_ref
->dw_loc_oprnd1
.v
.val_addr
);
2366 fputc ('\n', asm_out_file
);
2368 asm_fprintf (asm_out_file
, "\t.secidx ");
2369 output_addr_const (asm_out_file
, loc_ref
->dw_loc_oprnd1
.v
.val_addr
);
2370 fputc ('\n', asm_out_file
);
2372 ASM_OUTPUT_ASCII (asm_out_file
, name
, strlen (name
) + 1);
2374 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2376 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2379 /* Try to translate a DWARF register number into its CodeView equivalent. */
2382 dwarf_reg_to_cv (unsigned int regno
)
2384 static const cv_amd64_register amd64_reg_mapping
[] = {
2454 static const cv_x86_register x86_reg_mapping
[] = {
2500 if (regno
< sizeof (amd64_reg_mapping
) / sizeof (*amd64_reg_mapping
))
2501 return amd64_reg_mapping
[regno
];
2503 return CV_AMD64_NOREG
;
2507 if (regno
< sizeof (x86_reg_mapping
) / sizeof (*x86_reg_mapping
))
2508 return x86_reg_mapping
[regno
];
2514 /* Write an S_REGISTER symbol, representing an unoptimized variable that has
2515 been assigned to a register. */
2518 write_s_register (dw_die_ref die
, dw_loc_descr_ref loc_ref
)
2520 unsigned int label_num
= ++sym_label_num
;
2521 const char *name
= get_AT_string (die
, DW_AT_name
);
2525 /* This is struct regsym in binutils and REGSYM in Microsoft's cvinfo.h:
2537 if (loc_ref
->dw_loc_opc
== DW_OP_regx
)
2538 regno
= dwarf_reg_to_cv (loc_ref
->dw_loc_oprnd1
.v
.val_int
);
2540 regno
= dwarf_reg_to_cv (loc_ref
->dw_loc_opc
- DW_OP_reg0
);
2545 fputs (integer_asm_op (2, false), asm_out_file
);
2546 asm_fprintf (asm_out_file
,
2547 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2548 label_num
, label_num
);
2550 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2552 fputs (integer_asm_op (2, false), asm_out_file
);
2553 fprint_whex (asm_out_file
, S_REGISTER
);
2554 putc ('\n', asm_out_file
);
2556 type
= get_type_num (get_AT_ref (die
, DW_AT_type
), false, false);
2558 fputs (integer_asm_op (4, false), asm_out_file
);
2559 fprint_whex (asm_out_file
, type
);
2560 putc ('\n', asm_out_file
);
2562 fputs (integer_asm_op (2, false), asm_out_file
);
2563 fprint_whex (asm_out_file
, regno
);
2564 putc ('\n', asm_out_file
);
2566 ASM_OUTPUT_ASCII (asm_out_file
, name
, strlen (name
) + 1);
2568 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2570 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2573 /* Write an S_REGREL32 symbol in order to represent an unoptimized stack
2574 variable. The memory address is given by a register value plus an offset,
2575 so we need to parse the function's DW_AT_frame_base attribute for this. */
2578 write_fbreg_variable (dw_die_ref die
, dw_loc_descr_ref loc_ref
,
2579 dw_loc_descr_ref fbloc
)
2581 unsigned int label_num
= ++sym_label_num
;
2582 const char *name
= get_AT_string (die
, DW_AT_name
);
2587 /* This is struct regrel in binutils and REGREL32 in Microsoft's cvinfo.h:
2603 if (fbloc
->dw_loc_opc
>= DW_OP_breg0
&& fbloc
->dw_loc_opc
<= DW_OP_breg31
)
2605 regno
= dwarf_reg_to_cv (fbloc
->dw_loc_opc
- DW_OP_breg0
);
2606 offset
= fbloc
->dw_loc_oprnd1
.v
.val_int
;
2608 else if (fbloc
->dw_loc_opc
== DW_OP_bregx
)
2610 regno
= dwarf_reg_to_cv (fbloc
->dw_loc_oprnd1
.v
.val_int
);
2611 offset
= fbloc
->dw_loc_oprnd2
.v
.val_int
;
2618 if (loc_ref
->dw_loc_oprnd1
.val_class
!= dw_val_class_unsigned_const
)
2621 offset
+= loc_ref
->dw_loc_oprnd1
.v
.val_int
;
2623 fputs (integer_asm_op (2, false), asm_out_file
);
2624 asm_fprintf (asm_out_file
,
2625 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2626 label_num
, label_num
);
2628 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2630 fputs (integer_asm_op (2, false), asm_out_file
);
2631 fprint_whex (asm_out_file
, S_REGREL32
);
2632 putc ('\n', asm_out_file
);
2634 fputs (integer_asm_op (4, false), asm_out_file
);
2635 fprint_whex (asm_out_file
, offset
);
2636 putc ('\n', asm_out_file
);
2638 type
= get_type_num (get_AT_ref (die
, DW_AT_type
), false, false);
2640 fputs (integer_asm_op (4, false), asm_out_file
);
2641 fprint_whex (asm_out_file
, type
);
2642 putc ('\n', asm_out_file
);
2644 fputs (integer_asm_op (2, false), asm_out_file
);
2645 fprint_whex (asm_out_file
, regno
);
2646 putc ('\n', asm_out_file
);
2648 ASM_OUTPUT_ASCII (asm_out_file
, name
, strlen (name
) + 1);
2650 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2652 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2655 /* Write an S_DEFRANGE_REGISTER symbol, which describes a range for which an
2656 S_LOCAL variable is held in a certain register. */
2659 write_defrange_register (dw_loc_descr_ref expr
, rtx range_start
, rtx range_end
)
2661 unsigned int label_num
= ++sym_label_num
;
2664 /* This is defrange_register in binutils and DEFRANGESYMREGISTER in
2665 Microsoft's cvinfo.h:
2667 struct lvar_addr_range
2674 struct lvar_addr_gap {
2679 struct defrange_register
2684 uint16_t attributes;
2685 struct lvar_addr_range range;
2686 struct lvar_addr_gap gaps[];
2690 if (expr
->dw_loc_opc
== DW_OP_regx
)
2691 regno
= dwarf_reg_to_cv (expr
->dw_loc_oprnd1
.v
.val_int
);
2693 regno
= dwarf_reg_to_cv (expr
->dw_loc_opc
- DW_OP_reg0
);
2698 fputs (integer_asm_op (2, false), asm_out_file
);
2699 asm_fprintf (asm_out_file
,
2700 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2701 label_num
, label_num
);
2703 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2705 fputs (integer_asm_op (2, false), asm_out_file
);
2706 fprint_whex (asm_out_file
, S_DEFRANGE_REGISTER
);
2707 putc ('\n', asm_out_file
);
2709 fputs (integer_asm_op (2, false), asm_out_file
);
2710 fprint_whex (asm_out_file
, regno
);
2711 putc ('\n', asm_out_file
);
2713 fputs (integer_asm_op (2, false), asm_out_file
);
2714 fprint_whex (asm_out_file
, 0);
2715 putc ('\n', asm_out_file
);
2717 asm_fprintf (asm_out_file
, "\t.secrel32 ");
2718 output_addr_const (asm_out_file
, range_start
);
2719 fputc ('\n', asm_out_file
);
2721 asm_fprintf (asm_out_file
, "\t.secidx ");
2722 output_addr_const (asm_out_file
, range_start
);
2723 fputc ('\n', asm_out_file
);
2725 fputs (integer_asm_op (2, false), asm_out_file
);
2726 output_addr_const (asm_out_file
, range_end
);
2727 fputs (" - ", asm_out_file
);
2728 output_addr_const (asm_out_file
, range_start
);
2729 putc ('\n', asm_out_file
);
2731 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2734 /* Write an S_DEFRANGE_REGISTER_REL symbol, which describes a range for which
2735 an S_LOCAL variable is held in memory given by the value of a certain
2736 register plus an offset. */
2739 write_defrange_register_rel (dw_loc_descr_ref expr
, dw_loc_descr_ref fbloc
,
2740 rtx range_start
, rtx range_end
)
2742 unsigned int label_num
= ++sym_label_num
;
2746 /* This is defrange_register_rel in binutils and DEFRANGESYMREGISTERREL in
2747 Microsoft's cvinfo.h:
2749 struct lvar_addr_range
2756 struct lvar_addr_gap {
2761 struct defrange_register_rel
2766 uint16_t offset_parent;
2767 uint32_t offset_register;
2768 struct lvar_addr_range range;
2769 struct lvar_addr_gap gaps[];
2776 if (fbloc
->dw_loc_opc
>= DW_OP_breg0
&& fbloc
->dw_loc_opc
<= DW_OP_breg31
)
2778 regno
= dwarf_reg_to_cv (fbloc
->dw_loc_opc
- DW_OP_breg0
);
2779 offset
= fbloc
->dw_loc_oprnd1
.v
.val_int
;
2781 else if (fbloc
->dw_loc_opc
== DW_OP_bregx
)
2783 regno
= dwarf_reg_to_cv (fbloc
->dw_loc_oprnd1
.v
.val_int
);
2784 offset
= fbloc
->dw_loc_oprnd2
.v
.val_int
;
2791 if (expr
->dw_loc_oprnd1
.val_class
!= dw_val_class_unsigned_const
)
2794 offset
+= expr
->dw_loc_oprnd1
.v
.val_int
;
2796 fputs (integer_asm_op (2, false), asm_out_file
);
2797 asm_fprintf (asm_out_file
,
2798 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2799 label_num
, label_num
);
2801 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2803 fputs (integer_asm_op (2, false), asm_out_file
);
2804 fprint_whex (asm_out_file
, S_DEFRANGE_REGISTER_REL
);
2805 putc ('\n', asm_out_file
);
2807 fputs (integer_asm_op (2, false), asm_out_file
);
2808 fprint_whex (asm_out_file
, regno
);
2809 putc ('\n', asm_out_file
);
2811 fputs (integer_asm_op (2, false), asm_out_file
);
2812 fprint_whex (asm_out_file
, 0);
2813 putc ('\n', asm_out_file
);
2815 fputs (integer_asm_op (4, false), asm_out_file
);
2816 fprint_whex (asm_out_file
, offset
);
2817 putc ('\n', asm_out_file
);
2819 asm_fprintf (asm_out_file
, "\t.secrel32 ");
2820 output_addr_const (asm_out_file
, range_start
);
2821 fputc ('\n', asm_out_file
);
2823 asm_fprintf (asm_out_file
, "\t.secidx ");
2824 output_addr_const (asm_out_file
, range_start
);
2825 fputc ('\n', asm_out_file
);
2827 fputs (integer_asm_op (2, false), asm_out_file
);
2828 output_addr_const (asm_out_file
, range_end
);
2829 fputs (" - ", asm_out_file
);
2830 output_addr_const (asm_out_file
, range_start
);
2831 putc ('\n', asm_out_file
);
2833 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2836 /* Try to write an S_DEFRANGE_* symbol for the given DWARF location. */
2839 write_optimized_local_variable_loc (dw_loc_descr_ref expr
,
2840 dw_loc_descr_ref fbloc
, rtx range_start
,
2843 if (expr
->dw_loc_next
)
2852 switch (expr
->dw_loc_opc
)
2887 write_defrange_register (expr
, range_start
, range_end
);
2891 write_defrange_register_rel (expr
, fbloc
, range_start
, range_end
);
2899 /* Write an optimized local variable, given by an S_LOCAL symbol followed by
2900 any number of S_DEFRANGE_* symbols. We can't mix and match optimized and
2901 unoptimized variables in the same function, so even if it stays in the same
2902 place for the whole block we need to write an S_LOCAL. */
2905 write_optimized_local_variable (dw_die_ref die
, dw_loc_descr_ref fbloc
,
2906 rtx block_start
, rtx block_end
)
2909 dw_loc_list_ref loc_list
;
2911 loc
= get_AT (die
, DW_AT_location
);
2915 switch (loc
->dw_attr_val
.val_class
)
2917 case dw_val_class_loc_list
:
2918 loc_list
= loc
->dw_attr_val
.v
.val_loc_list
;
2920 write_s_local (die
);
2924 rtx range_start
= NULL
, range_end
= NULL
;
2926 if (loc_list
->begin
)
2927 range_start
= gen_rtx_SYMBOL_REF (Pmode
, loc_list
->begin
);
2930 range_end
= gen_rtx_SYMBOL_REF (Pmode
, loc_list
->end
);
2932 write_optimized_local_variable_loc (loc_list
->expr
, fbloc
,
2933 range_start
, range_end
);
2935 loc_list
= loc_list
->dw_loc_next
;
2939 case dw_val_class_loc
:
2940 write_s_local (die
);
2942 write_optimized_local_variable_loc (loc
->dw_attr_val
.v
.val_loc
, fbloc
,
2943 block_start
, block_end
);
2951 /* Write a symbol representing an unoptimized variable within a function, if
2952 we're able to translate the DIE's DW_AT_location into its CodeView
2956 write_unoptimized_local_variable (dw_die_ref die
, dw_loc_descr_ref fbloc
)
2959 dw_loc_descr_ref loc_ref
;
2961 loc
= get_AT (die
, DW_AT_location
);
2965 if (loc
->dw_attr_val
.val_class
!= dw_val_class_loc
)
2968 loc_ref
= loc
->dw_attr_val
.v
.val_loc
;
2972 switch (loc_ref
->dw_loc_opc
)
2975 write_local_s_ldata32 (die
, loc_ref
);
3011 write_s_register (die
, loc_ref
);
3015 write_fbreg_variable (die
, loc_ref
, fbloc
);
3023 /* Translate a DW_TAG_lexical_block DIE into an S_BLOCK32 symbol, representing
3024 a block within an unoptimized function. Returns false if we're not able
3025 to resolve the location, which will prevent the caller from issuing an
3029 write_s_block32 (dw_die_ref die
)
3031 unsigned int label_num
= ++sym_label_num
;
3032 dw_attr_node
*loc_low
, *loc_high
;
3033 const char *label_low
, *label_high
;
3034 rtx rtx_low
, rtx_high
;
3036 /* This is struct blocksym in binutils and BLOCKSYM32 in Microsoft's
3052 loc_low
= get_AT (die
, DW_AT_low_pc
);
3056 if (loc_low
->dw_attr_val
.val_class
!= dw_val_class_lbl_id
)
3059 label_low
= loc_low
->dw_attr_val
.v
.val_lbl_id
;
3063 rtx_low
= gen_rtx_SYMBOL_REF (Pmode
, label_low
);
3065 loc_high
= get_AT (die
, DW_AT_high_pc
);
3069 if (loc_high
->dw_attr_val
.val_class
!= dw_val_class_high_pc
)
3072 label_high
= loc_high
->dw_attr_val
.v
.val_lbl_id
;
3076 rtx_high
= gen_rtx_SYMBOL_REF (Pmode
, label_high
);
3078 fputs (integer_asm_op (2, false), asm_out_file
);
3079 asm_fprintf (asm_out_file
,
3080 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
3081 label_num
, label_num
);
3083 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
3085 fputs (integer_asm_op (2, false), asm_out_file
);
3086 fprint_whex (asm_out_file
, S_BLOCK32
);
3087 putc ('\n', asm_out_file
);
3089 /* The parent and end fields get filled in by the linker. */
3091 fputs (integer_asm_op (4, false), asm_out_file
);
3092 fprint_whex (asm_out_file
, 0);
3093 putc ('\n', asm_out_file
);
3095 fputs (integer_asm_op (4, false), asm_out_file
);
3096 fprint_whex (asm_out_file
, 0);
3097 putc ('\n', asm_out_file
);
3099 fputs (integer_asm_op (4, false), asm_out_file
);
3100 output_addr_const (asm_out_file
, rtx_high
);
3101 fputs (" - ", asm_out_file
);
3102 output_addr_const (asm_out_file
, rtx_low
);
3103 putc ('\n', asm_out_file
);
3105 asm_fprintf (asm_out_file
, "\t.secrel32 ");
3106 output_addr_const (asm_out_file
, rtx_low
);
3107 fputc ('\n', asm_out_file
);
3109 asm_fprintf (asm_out_file
, "\t.secidx ");
3110 output_addr_const (asm_out_file
, rtx_low
);
3111 fputc ('\n', asm_out_file
);
3113 ASM_OUTPUT_ASCII (asm_out_file
, "", 1);
3115 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
3117 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
3122 /* Write an S_END symbol, which is used to finish off a number of different
3123 symbol types. Here we use it to mark the S_BLOCK32 as finished. */
3128 unsigned int label_num
= ++sym_label_num
;
3130 fputs (integer_asm_op (2, false), asm_out_file
);
3131 asm_fprintf (asm_out_file
,
3132 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
3133 label_num
, label_num
);
3135 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
3137 fputs (integer_asm_op (2, false), asm_out_file
);
3138 fprint_whex (asm_out_file
, S_END
);
3139 putc ('\n', asm_out_file
);
3141 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
3143 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
3146 /* Write the S_FRAMEPROC symbol, which is supposed to give information about
3147 the function frame. It doesn't seem to be really used in modern versions of
3148 MSVC, which is why we zero-out everything here. You still need to write it
3149 though, otherwise windbg won't necessarily show all the local variables. */
3152 write_s_frameproc (void)
3154 unsigned int label_num
= ++sym_label_num
;
3156 /* This is struct FRAMEPROCSYM in Microsoft's cvinfo.h:
3162 uint32_t frame_size;
3163 uint32_t padding_size;
3164 uint32_t padding_offset;
3165 uint32_t saved_registers_size;
3166 uint32_t exception_handler_offset;
3167 uint16_t exception_handler_section;
3172 fputs (integer_asm_op (2, false), asm_out_file
);
3173 asm_fprintf (asm_out_file
,
3174 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
3175 label_num
, label_num
);
3177 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
3179 fputs (integer_asm_op (2, false), asm_out_file
);
3180 fprint_whex (asm_out_file
, S_FRAMEPROC
);
3181 putc ('\n', asm_out_file
);
3183 fputs (integer_asm_op (4, false), asm_out_file
);
3184 fprint_whex (asm_out_file
, 0);
3185 putc ('\n', asm_out_file
);
3187 fputs (integer_asm_op (4, false), asm_out_file
);
3188 fprint_whex (asm_out_file
, 0);
3189 putc ('\n', asm_out_file
);
3191 fputs (integer_asm_op (4, false), asm_out_file
);
3192 fprint_whex (asm_out_file
, 0);
3193 putc ('\n', asm_out_file
);
3195 fputs (integer_asm_op (4, false), asm_out_file
);
3196 fprint_whex (asm_out_file
, 0);
3197 putc ('\n', asm_out_file
);
3199 fputs (integer_asm_op (4, false), asm_out_file
);
3200 fprint_whex (asm_out_file
, 0);
3201 putc ('\n', asm_out_file
);
3203 fputs (integer_asm_op (2, false), asm_out_file
);
3204 fprint_whex (asm_out_file
, 0);
3205 putc ('\n', asm_out_file
);
3207 fputs (integer_asm_op (4, false), asm_out_file
);
3208 fprint_whex (asm_out_file
, 0);
3209 putc ('\n', asm_out_file
);
3211 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
3213 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
3216 /* Loop through the DIEs in an unoptimized function, writing out any variables
3217 or blocks that we encounter. */
3220 write_unoptimized_function_vars (dw_die_ref die
, dw_loc_descr_ref fbloc
)
3222 dw_die_ref first_child
, c
;
3224 first_child
= dw_get_die_child (die
);
3232 c
= dw_get_die_sib (c
);
3234 switch (dw_get_die_tag (c
))
3236 case DW_TAG_formal_parameter
:
3237 case DW_TAG_variable
:
3238 write_unoptimized_local_variable (c
, fbloc
);
3241 case DW_TAG_lexical_block
:
3243 bool block_started
= write_s_block32 (c
);
3245 write_unoptimized_function_vars (c
, fbloc
);
3257 while (c
!= first_child
);
3260 /* Write the variables in an optimized function or block. There's no S_BLOCK32s
3261 here, with the range determining the lifetime of a variable. Unfortunately
3262 for us CodeView is much less expressive than DWARF when it comes to variable
3263 locations, so some degree of "optimized out"s is inevitable. */
3266 write_optimized_function_vars (dw_die_ref die
, dw_loc_descr_ref fbloc
,
3267 rtx block_start
, rtx block_end
)
3269 dw_die_ref first_child
, c
;
3271 first_child
= dw_get_die_child (die
);
3279 c
= dw_get_die_sib (c
);
3281 switch (dw_get_die_tag (c
))
3283 case DW_TAG_formal_parameter
:
3284 case DW_TAG_variable
:
3285 write_optimized_local_variable (c
, fbloc
, block_start
, block_end
);
3288 case DW_TAG_lexical_block
:
3290 dw_attr_node
*loc_low
, *loc_high
;
3291 const char *label_low
, *label_high
;
3292 rtx rtx_low
, rtx_high
;
3294 loc_low
= get_AT (die
, DW_AT_low_pc
);
3298 if (loc_low
->dw_attr_val
.val_class
!= dw_val_class_lbl_id
)
3301 label_low
= loc_low
->dw_attr_val
.v
.val_lbl_id
;
3305 rtx_low
= gen_rtx_SYMBOL_REF (Pmode
, label_low
);
3307 loc_high
= get_AT (die
, DW_AT_high_pc
);
3311 if (loc_high
->dw_attr_val
.val_class
!= dw_val_class_high_pc
)
3314 label_high
= loc_high
->dw_attr_val
.v
.val_lbl_id
;
3318 rtx_high
= gen_rtx_SYMBOL_REF (Pmode
, label_high
);
3320 write_optimized_function_vars (c
, fbloc
, rtx_low
, rtx_high
);
3329 while (c
!= first_child
);
3332 /* There's no way to mark the range of a static local variable in an optimized
3333 function: there's no S_DEFRANGE_* symbol for this, and you can't have
3334 S_BLOCK32 symbols. So instead we have to loop through after the S_FRAMEPROC
3335 has been written, and write the S_LDATA32s at the end. */
3338 write_optimized_static_local_vars (dw_die_ref die
)
3340 dw_die_ref first_child
, c
;
3342 first_child
= dw_get_die_child (die
);
3350 c
= dw_get_die_sib (c
);
3352 switch (dw_get_die_tag (c
))
3354 case DW_TAG_variable
:
3357 dw_loc_descr_ref loc_ref
;
3359 loc
= get_AT (c
, DW_AT_location
);
3363 if (loc
->dw_attr_val
.val_class
!= dw_val_class_loc
)
3366 loc_ref
= loc
->dw_attr_val
.v
.val_loc
;
3370 if (loc_ref
->dw_loc_opc
!= DW_OP_addr
)
3373 write_local_s_ldata32 (c
, loc_ref
);
3377 case DW_TAG_lexical_block
:
3378 write_optimized_static_local_vars (c
);
3385 while (c
!= first_child
);
3388 #ifdef HAVE_GAS_CV_UCOMP
3390 /* Given a DW_TAG_inlined_subroutine DIE within parent_func, return a pointer
3391 to the corresponding codeview_function, which is used to map addresses
3394 static codeview_function
*
3395 find_line_function (dw_die_ref parent_func
, dw_die_ref die
)
3397 codeview_function
**slot
, *f
;
3402 slot
= cv_func_htab
->find_slot_with_hash (parent_func
,
3403 htab_hash_pointer (parent_func
),
3406 if (!slot
|| !*slot
)
3413 expanded_location loc
;
3414 dwarf_file_data
*call_file
;
3416 if (f
->inline_block
== 0)
3422 loc
= expand_location (f
->inline_loc
);
3424 if ((unsigned) loc
.line
!= get_AT_unsigned (die
, DW_AT_call_line
)
3425 || (unsigned) loc
.column
!= get_AT_unsigned (die
, DW_AT_call_column
))
3431 call_file
= get_AT_file (die
, DW_AT_call_file
);
3433 if (!call_file
|| strcmp (call_file
->filename
, loc
.file
))
3445 /* Write the "binary annotations" for an S_INLINESITE symbol, which are how
3446 CodeView represents line numbers within inlined functions. This is
3447 completely different to how line numbers are represented normally, and
3448 requires assembler support for the .cv_ucomp and .cv_scomp pseudos. */
3451 write_binary_annotations (codeview_function
*line_func
, uint32_t func_id
)
3453 codeview_line_block
*b
;
3454 codeview_inlinee_lines
**slot
, *il
;
3455 codeview_function
*top_parent
;
3456 unsigned int line_no
, label_num
;
3458 slot
= inlinee_lines_htab
->find_slot_with_hash (func_id
, func_id
, NO_INSERT
);
3459 if (!slot
|| !*slot
)
3464 line_no
= il
->starting_line
;
3466 top_parent
= line_func
;
3467 while (top_parent
->parent
)
3469 top_parent
= top_parent
->parent
;
3472 label_num
= top_parent
->blocks
->lines
->label_num
;
3474 b
= line_func
->blocks
;
3477 codeview_line
*l
= b
->lines
;
3481 if (!l
->next
&& !b
->next
) /* last line (end of block) */
3483 asm_fprintf (asm_out_file
, "\t.cv_ucomp %u\n",
3484 ba_op_change_code_length
);
3485 asm_fprintf (asm_out_file
,
3486 "\t.cv_ucomp %L" LINE_LABEL
"%u - %L" LINE_LABEL
"%u\n",
3487 l
->label_num
, label_num
);
3491 if (l
->line_no
!= line_no
)
3493 asm_fprintf (asm_out_file
, "\t.cv_ucomp %u\n",
3494 ba_op_change_line_offset
);
3495 asm_fprintf (asm_out_file
, "\t.cv_scomp %i\n",
3496 l
->line_no
- line_no
);
3498 line_no
= l
->line_no
;
3501 asm_fprintf (asm_out_file
, "\t.cv_ucomp %u\n",
3502 ba_op_change_code_offset
);
3503 asm_fprintf (asm_out_file
,
3504 "\t.cv_ucomp %L" LINE_LABEL
"%u - %L" LINE_LABEL
"%u\n",
3505 l
->label_num
, label_num
);
3508 label_num
= l
->label_num
;
3519 /* Write an S_INLINESITE symbol, to record that a function has been inlined
3520 inside another function. */
3523 write_s_inlinesite (dw_die_ref parent_func
, dw_die_ref die
)
3525 unsigned int label_num
= ++sym_label_num
;
3528 codeview_function
*line_func
;
3530 func
= get_AT_ref (die
, DW_AT_abstract_origin
);
3534 func_id
= get_func_id (func
);
3538 /* This is struct inline_site in binutils and INLINESITESYM in Microsoft's
3548 uint8_t binary_annotations[];
3552 fputs (integer_asm_op (2, false), asm_out_file
);
3553 asm_fprintf (asm_out_file
,
3554 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
3555 label_num
, label_num
);
3557 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
3559 fputs (integer_asm_op (2, false), asm_out_file
);
3560 fprint_whex (asm_out_file
, S_INLINESITE
);
3561 putc ('\n', asm_out_file
);
3563 /* parent, filled in by linker */
3564 fputs (integer_asm_op (4, false), asm_out_file
);
3565 fprint_whex (asm_out_file
, 0);
3566 putc ('\n', asm_out_file
);
3568 /* end, filled in by linker */
3569 fputs (integer_asm_op (4, false), asm_out_file
);
3570 fprint_whex (asm_out_file
, 0);
3571 putc ('\n', asm_out_file
);
3573 fputs (integer_asm_op (4, false), asm_out_file
);
3574 fprint_whex (asm_out_file
, func_id
);
3575 putc ('\n', asm_out_file
);
3577 #ifdef HAVE_GAS_CV_UCOMP
3578 line_func
= find_line_function (parent_func
, die
);
3582 write_binary_annotations (line_func
, func_id
);
3583 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
3589 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
3591 write_inlinesite_records (parent_func
, die
);
3593 /* Write S_INLINESITE_END symbol. */
3595 label_num
= ++sym_label_num
;
3597 fputs (integer_asm_op (2, false), asm_out_file
);
3598 asm_fprintf (asm_out_file
,
3599 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
3600 label_num
, label_num
);
3602 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
3604 fputs (integer_asm_op (2, false), asm_out_file
);
3605 fprint_whex (asm_out_file
, S_INLINESITE_END
);
3606 putc ('\n', asm_out_file
);
3608 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
3611 /* Loop through a function, and translate its DW_TAG_inlined_subroutine DIEs
3612 into CodeView S_INLINESITE symbols. */
3615 write_inlinesite_records (dw_die_ref func
, dw_die_ref die
)
3617 dw_die_ref first_child
, c
;
3619 first_child
= dw_get_die_child (die
);
3627 c
= dw_get_die_sib (c
);
3629 switch (dw_get_die_tag (c
))
3631 case DW_TAG_lexical_block
:
3632 write_inlinesite_records (func
, c
);
3635 case DW_TAG_inlined_subroutine
:
3636 write_s_inlinesite (func
, c
);
3643 while (c
!= first_child
);
3646 /* Write an S_GPROC32_ID symbol, representing a global function, or an
3647 S_LPROC32_ID symbol, for a static function. */
3650 write_function (codeview_symbol
*s
)
3652 unsigned int label_num
= ++sym_label_num
;
3653 dw_attr_node
*loc_low
, *loc_high
, *frame_base
;
3654 const char *label_low
, *label_high
;
3655 rtx rtx_low
, rtx_high
;
3656 dw_loc_descr_ref fbloc
= NULL
;
3658 /* This is struct procsym in binutils and PROCSYM32 in Microsoft's cvinfo.h:
3668 uint32_t debug_start;
3678 loc_low
= get_AT (s
->function
.die
, DW_AT_low_pc
);
3682 if (loc_low
->dw_attr_val
.val_class
!= dw_val_class_lbl_id
)
3685 label_low
= loc_low
->dw_attr_val
.v
.val_lbl_id
;
3689 rtx_low
= gen_rtx_SYMBOL_REF (Pmode
, label_low
);
3691 loc_high
= get_AT (s
->function
.die
, DW_AT_high_pc
);
3695 if (loc_high
->dw_attr_val
.val_class
!= dw_val_class_high_pc
)
3698 label_high
= loc_high
->dw_attr_val
.v
.val_lbl_id
;
3702 rtx_high
= gen_rtx_SYMBOL_REF (Pmode
, label_high
);
3704 /* Output the S_GPROC32_ID / S_LPROC32_ID record. */
3706 fputs (integer_asm_op (2, false), asm_out_file
);
3707 asm_fprintf (asm_out_file
,
3708 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
3709 label_num
, label_num
);
3711 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
3713 fputs (integer_asm_op (2, false), asm_out_file
);
3714 fprint_whex (asm_out_file
, s
->kind
);
3715 putc ('\n', asm_out_file
);
3717 fputs (integer_asm_op (4, false), asm_out_file
);
3718 fprint_whex (asm_out_file
, s
->function
.parent
);
3719 putc ('\n', asm_out_file
);
3721 fputs (integer_asm_op (4, false), asm_out_file
);
3722 fprint_whex (asm_out_file
, s
->function
.end
);
3723 putc ('\n', asm_out_file
);
3725 fputs (integer_asm_op (4, false), asm_out_file
);
3726 fprint_whex (asm_out_file
, s
->function
.next
);
3727 putc ('\n', asm_out_file
);
3729 fputs (integer_asm_op (4, false), asm_out_file
);
3730 output_addr_const (asm_out_file
, rtx_high
);
3731 fputs (" - ", asm_out_file
);
3732 output_addr_const (asm_out_file
, rtx_low
);
3733 putc ('\n', asm_out_file
);
3735 /* FIXME - debug_start should be the end of the prologue, and debug_end
3736 the beginning of the epilogue. Do the whole function for
3739 fputs (integer_asm_op (4, false), asm_out_file
);
3740 fprint_whex (asm_out_file
, 0);
3741 putc ('\n', asm_out_file
);
3743 fputs (integer_asm_op (4, false), asm_out_file
);
3744 output_addr_const (asm_out_file
, rtx_high
);
3745 fputs (" - ", asm_out_file
);
3746 output_addr_const (asm_out_file
, rtx_low
);
3747 putc ('\n', asm_out_file
);
3749 fputs (integer_asm_op (4, false), asm_out_file
);
3750 fprint_whex (asm_out_file
, s
->function
.type
);
3751 putc ('\n', asm_out_file
);
3753 asm_fprintf (asm_out_file
, "\t.secrel32 ");
3754 output_addr_const (asm_out_file
, rtx_low
);
3755 fputc ('\n', asm_out_file
);
3757 asm_fprintf (asm_out_file
, "\t.secidx ");
3758 output_addr_const (asm_out_file
, rtx_low
);
3759 fputc ('\n', asm_out_file
);
3761 fputs (integer_asm_op (1, false), asm_out_file
);
3762 fprint_whex (asm_out_file
, s
->function
.flags
);
3763 putc ('\n', asm_out_file
);
3765 ASM_OUTPUT_ASCII (asm_out_file
, s
->function
.name
,
3766 strlen (s
->function
.name
) + 1);
3768 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
3770 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
3772 write_inlinesite_records (s
->function
.die
, s
->function
.die
);
3774 frame_base
= get_AT (s
->function
.die
, DW_AT_frame_base
);
3776 if (frame_base
&& frame_base
->dw_attr_val
.val_class
== dw_val_class_loc
)
3777 fbloc
= frame_base
->dw_attr_val
.v
.val_loc
;
3779 if (flag_var_tracking
)
3781 write_optimized_function_vars (s
->function
.die
, fbloc
, rtx_low
,
3783 write_s_frameproc ();
3784 write_optimized_static_local_vars (s
->function
.die
);
3788 write_s_frameproc ();
3789 write_unoptimized_function_vars (s
->function
.die
, fbloc
);
3792 /* Output the S_PROC_ID_END record. */
3794 label_num
= ++sym_label_num
;
3796 fputs (integer_asm_op (2, false), asm_out_file
);
3797 asm_fprintf (asm_out_file
,
3798 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
3799 label_num
, label_num
);
3801 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
3803 fputs (integer_asm_op (2, false), asm_out_file
);
3804 fprint_whex (asm_out_file
, S_PROC_ID_END
);
3805 putc ('\n', asm_out_file
);
3807 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
3810 free (s
->function
.name
);
3813 /* Write the CodeView symbols into the .debug$S section. */
3816 write_codeview_symbols (void)
3818 fputs (integer_asm_op (4, false), asm_out_file
);
3819 fprint_whex (asm_out_file
, DEBUG_S_SYMBOLS
);
3820 putc ('\n', asm_out_file
);
3822 fputs (integer_asm_op (4, false), asm_out_file
);
3823 asm_fprintf (asm_out_file
, "%LLcv_syms_end - %LLcv_syms_start\n");
3825 asm_fprintf (asm_out_file
, "%LLcv_syms_start:\n");
3827 write_compile3_symbol ();
3831 codeview_symbol
*n
= sym
->next
;
3837 write_data_symbol (sym
);
3841 write_function (sym
);
3851 asm_fprintf (asm_out_file
, "%LLcv_syms_end:\n");
3854 /* Write an LF_POINTER type. */
3857 write_lf_pointer (codeview_custom_type
*t
)
3859 /* This is lf_pointer in binutils and lfPointer in Microsoft's cvinfo.h:
3866 uint32_t attributes;
3867 (following only if CV_PTR_MODE_PMEM or CV_PTR_MODE_PMFUNC in attributes)
3868 uint32_t containing_class;
3869 uint16_t ptr_to_mem_type;
3874 fputs (integer_asm_op (2, false), asm_out_file
);
3875 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
3878 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
3880 fputs (integer_asm_op (2, false), asm_out_file
);
3881 fprint_whex (asm_out_file
, t
->kind
);
3882 putc ('\n', asm_out_file
);
3884 fputs (integer_asm_op (4, false), asm_out_file
);
3885 fprint_whex (asm_out_file
, t
->lf_pointer
.base_type
);
3886 putc ('\n', asm_out_file
);
3888 fputs (integer_asm_op (4, false), asm_out_file
);
3889 fprint_whex (asm_out_file
, t
->lf_pointer
.attributes
);
3890 putc ('\n', asm_out_file
);
3892 if ((t
->lf_pointer
.attributes
& CV_PTR_MODE_MASK
) == CV_PTR_MODE_PMEM
3893 || (t
->lf_pointer
.attributes
& CV_PTR_MODE_MASK
) == CV_PTR_MODE_PMFUNC
)
3895 fputs (integer_asm_op (4, false), asm_out_file
);
3896 fprint_whex (asm_out_file
, t
->lf_pointer
.containing_class
);
3897 putc ('\n', asm_out_file
);
3899 fputs (integer_asm_op (2, false), asm_out_file
);
3900 fprint_whex (asm_out_file
, t
->lf_pointer
.ptr_to_mem_type
);
3901 putc ('\n', asm_out_file
);
3903 write_cv_padding (2);
3906 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
3909 /* All CodeView type definitions have to be aligned to a four-byte boundary,
3910 so write some padding bytes if necessary. These have to be specific values:
3911 LF_PAD3, LF_PAD2, LF_PAD1. */
3914 write_cv_padding (size_t padding
)
3916 if (padding
== 4 || padding
== 0)
3921 fputs (integer_asm_op (1, false), asm_out_file
);
3922 fprint_whex (asm_out_file
, LF_PAD3
);
3923 putc ('\n', asm_out_file
);
3928 fputs (integer_asm_op (1, false), asm_out_file
);
3929 fprint_whex (asm_out_file
, LF_PAD2
);
3930 putc ('\n', asm_out_file
);
3933 fputs (integer_asm_op (1, false), asm_out_file
);
3934 fprint_whex (asm_out_file
, LF_PAD1
);
3935 putc ('\n', asm_out_file
);
3938 /* Write an LF_MODIFIER type, representing a const and/or volatile modification
3942 write_lf_modifier (codeview_custom_type
*t
)
3944 /* This is lf_modifier in binutils and lfModifier in Microsoft's cvinfo.h:
3956 fputs (integer_asm_op (2, false), asm_out_file
);
3957 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
3960 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
3962 fputs (integer_asm_op (2, false), asm_out_file
);
3963 fprint_whex (asm_out_file
, t
->kind
);
3964 putc ('\n', asm_out_file
);
3966 fputs (integer_asm_op (4, false), asm_out_file
);
3967 fprint_whex (asm_out_file
, t
->lf_modifier
.base_type
);
3968 putc ('\n', asm_out_file
);
3970 fputs (integer_asm_op (2, false), asm_out_file
);
3971 fprint_whex (asm_out_file
, t
->lf_modifier
.modifier
);
3972 putc ('\n', asm_out_file
);
3974 write_cv_padding (2);
3976 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
3979 /* Write a CodeView extensible integer. If the value is non-negative and
3980 < 0x8000, the value gets written directly as an uint16_t. Otherwise, we
3981 output two bytes for the integer type (LF_CHAR, LF_SHORT, ...), and the
3982 actual value follows. Returns the total number of bytes written. */
3985 write_cv_integer (codeview_integer
*i
)
3991 fputs (integer_asm_op (2, false), asm_out_file
);
3992 fprint_whex (asm_out_file
, LF_CHAR
);
3993 putc ('\n', asm_out_file
);
3995 fputs (integer_asm_op (1, false), asm_out_file
);
3996 fprint_whex (asm_out_file
, -i
->num
);
3997 putc ('\n', asm_out_file
);
4001 else if (i
->num
<= 0x8000)
4003 fputs (integer_asm_op (2, false), asm_out_file
);
4004 fprint_whex (asm_out_file
, LF_SHORT
);
4005 putc ('\n', asm_out_file
);
4007 fputs (integer_asm_op (2, false), asm_out_file
);
4008 fprint_whex (asm_out_file
, -i
->num
);
4009 putc ('\n', asm_out_file
);
4013 else if (i
->num
<= 0x80000000)
4015 fputs (integer_asm_op (2, false), asm_out_file
);
4016 fprint_whex (asm_out_file
, LF_LONG
);
4017 putc ('\n', asm_out_file
);
4019 fputs (integer_asm_op (4, false), asm_out_file
);
4020 fprint_whex (asm_out_file
, -i
->num
);
4021 putc ('\n', asm_out_file
);
4027 fputs (integer_asm_op (2, false), asm_out_file
);
4028 fprint_whex (asm_out_file
, LF_QUADWORD
);
4029 putc ('\n', asm_out_file
);
4031 fputs (integer_asm_op (8, false), asm_out_file
);
4032 fprint_whex (asm_out_file
, -i
->num
);
4033 putc ('\n', asm_out_file
);
4040 if (i
->num
<= 0x7fff)
4042 fputs (integer_asm_op (2, false), asm_out_file
);
4043 fprint_whex (asm_out_file
, i
->num
);
4044 putc ('\n', asm_out_file
);
4048 else if (i
->num
<= 0xffff)
4050 fputs (integer_asm_op (2, false), asm_out_file
);
4051 fprint_whex (asm_out_file
, LF_USHORT
);
4052 putc ('\n', asm_out_file
);
4054 fputs (integer_asm_op (2, false), asm_out_file
);
4055 fprint_whex (asm_out_file
, i
->num
);
4056 putc ('\n', asm_out_file
);
4060 else if (i
->num
<= 0xffffffff)
4062 fputs (integer_asm_op (2, false), asm_out_file
);
4063 fprint_whex (asm_out_file
, LF_ULONG
);
4064 putc ('\n', asm_out_file
);
4066 fputs (integer_asm_op (4, false), asm_out_file
);
4067 fprint_whex (asm_out_file
, i
->num
);
4068 putc ('\n', asm_out_file
);
4074 fputs (integer_asm_op (2, false), asm_out_file
);
4075 fprint_whex (asm_out_file
, LF_UQUADWORD
);
4076 putc ('\n', asm_out_file
);
4078 fputs (integer_asm_op (8, false), asm_out_file
);
4079 fprint_whex (asm_out_file
, i
->num
);
4080 putc ('\n', asm_out_file
);
4087 /* Return the extra size needed for an extensible integer. */
4090 cv_integer_len (codeview_integer
*i
)
4095 return sizeof (int8_t);
4096 else if (i
->num
<= 0x8000)
4097 return sizeof (int16_t);
4098 else if (i
->num
<= 0x80000000)
4099 return sizeof (int32_t);
4101 return sizeof (int64_t);
4105 if (i
->num
<= 0x7fff)
4107 else if (i
->num
<= 0xffff)
4108 return sizeof (uint16_t);
4109 else if (i
->num
<= 0xffffffff)
4110 return sizeof (uint32_t);
4112 return sizeof (uint64_t);
4116 /* Write an LF_FIELDLIST type, which is a container for various subtypes. This
4117 has two uses: for the values in an enum, and for the member, operators etc.
4118 for a struct, class, or union. */
4121 write_lf_fieldlist (codeview_custom_type
*t
)
4123 fputs (integer_asm_op (2, false), asm_out_file
);
4124 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4127 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4129 fputs (integer_asm_op (2, false), asm_out_file
);
4130 fprint_whex (asm_out_file
, t
->kind
);
4131 putc ('\n', asm_out_file
);
4133 while (t
->lf_fieldlist
.subtypes
)
4135 codeview_subtype
*v
= t
->lf_fieldlist
.subtypes
;
4136 codeview_subtype
*next
= v
->next
;
4137 size_t name_len
, leaf_len
;
4142 /* This is lf_enumerate in binutils and lfEnumerate in Microsoft's
4148 uint16_t attributes;
4150 (then actual value if value >= 0x8000)
4155 fputs (integer_asm_op (2, false), asm_out_file
);
4156 fprint_whex (asm_out_file
, LF_ENUMERATE
);
4157 putc ('\n', asm_out_file
);
4159 fputs (integer_asm_op (2, false), asm_out_file
);
4160 fprint_whex (asm_out_file
, CV_ACCESS_PUBLIC
);
4161 putc ('\n', asm_out_file
);
4163 leaf_len
= 4 + write_cv_integer (&v
->lf_enumerate
.value
);
4165 name_len
= strlen (v
->lf_enumerate
.name
) + 1;
4166 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_enumerate
.name
, name_len
);
4168 leaf_len
+= name_len
;
4169 write_cv_padding (4 - (leaf_len
% 4));
4171 free (v
->lf_enumerate
.name
);
4175 /* This is lf_member in binutils and lfMember in Microsoft's
4181 uint16_t attributes;
4188 fputs (integer_asm_op (2, false), asm_out_file
);
4189 fprint_whex (asm_out_file
, LF_MEMBER
);
4190 putc ('\n', asm_out_file
);
4192 fputs (integer_asm_op (2, false), asm_out_file
);
4193 fprint_whex (asm_out_file
, v
->lf_member
.attributes
);
4194 putc ('\n', asm_out_file
);
4196 fputs (integer_asm_op (4, false), asm_out_file
);
4197 fprint_whex (asm_out_file
, v
->lf_member
.type
);
4198 putc ('\n', asm_out_file
);
4200 leaf_len
= 8 + write_cv_integer (&v
->lf_member
.offset
);
4202 if (v
->lf_member
.name
)
4204 name_len
= strlen (v
->lf_member
.name
) + 1;
4205 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_member
.name
, name_len
);
4210 ASM_OUTPUT_ASCII (asm_out_file
, "", name_len
);
4213 leaf_len
+= name_len
;
4214 write_cv_padding (4 - (leaf_len
% 4));
4216 free (v
->lf_member
.name
);
4220 /* This is lf_index in binutils and lfIndex in Microsoft's cvinfo.h:
4230 fputs (integer_asm_op (2, false), asm_out_file
);
4231 fprint_whex (asm_out_file
, LF_INDEX
);
4232 putc ('\n', asm_out_file
);
4234 fputs (integer_asm_op (2, false), asm_out_file
);
4235 fprint_whex (asm_out_file
, 0);
4236 putc ('\n', asm_out_file
);
4238 fputs (integer_asm_op (4, false), asm_out_file
);
4239 fprint_whex (asm_out_file
, v
->lf_index
.type_num
);
4240 putc ('\n', asm_out_file
);
4245 /* This is lf_static_member in binutils and lfSTMember in Microsoft's
4248 struct lf_static_member
4251 uint16_t attributes;
4257 fputs (integer_asm_op (2, false), asm_out_file
);
4258 fprint_whex (asm_out_file
, LF_STMEMBER
);
4259 putc ('\n', asm_out_file
);
4261 fputs (integer_asm_op (2, false), asm_out_file
);
4262 fprint_whex (asm_out_file
, v
->lf_static_member
.attributes
);
4263 putc ('\n', asm_out_file
);
4265 fputs (integer_asm_op (4, false), asm_out_file
);
4266 fprint_whex (asm_out_file
, v
->lf_static_member
.type
);
4267 putc ('\n', asm_out_file
);
4269 name_len
= strlen (v
->lf_static_member
.name
) + 1;
4270 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_static_member
.name
, name_len
);
4272 leaf_len
= 8 + name_len
;
4273 write_cv_padding (4 - (leaf_len
% 4));
4275 free (v
->lf_static_member
.name
);
4279 /* This is lf_onemethod in binutils and lfOneMethod in Microsoft's
4285 uint16_t method_attribute;
4286 uint32_t method_type;
4291 fputs (integer_asm_op (2, false), asm_out_file
);
4292 fprint_whex (asm_out_file
, LF_ONEMETHOD
);
4293 putc ('\n', asm_out_file
);
4295 fputs (integer_asm_op (2, false), asm_out_file
);
4296 fprint_whex (asm_out_file
, v
->lf_onemethod
.method_attribute
);
4297 putc ('\n', asm_out_file
);
4299 fputs (integer_asm_op (4, false), asm_out_file
);
4300 fprint_whex (asm_out_file
, v
->lf_onemethod
.method_type
);
4301 putc ('\n', asm_out_file
);
4303 name_len
= strlen (v
->lf_onemethod
.name
) + 1;
4304 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_onemethod
.name
, name_len
);
4306 leaf_len
= 8 + name_len
;
4307 write_cv_padding (4 - (leaf_len
% 4));
4309 free (v
->lf_onemethod
.name
);
4313 /* This is lf_method in binutils and lfMethod in Microsoft's
4320 uint32_t method_list;
4325 fputs (integer_asm_op (2, false), asm_out_file
);
4326 fprint_whex (asm_out_file
, LF_METHOD
);
4327 putc ('\n', asm_out_file
);
4329 fputs (integer_asm_op (2, false), asm_out_file
);
4330 fprint_whex (asm_out_file
, v
->lf_method
.count
);
4331 putc ('\n', asm_out_file
);
4333 fputs (integer_asm_op (4, false), asm_out_file
);
4334 fprint_whex (asm_out_file
, v
->lf_method
.method_list
);
4335 putc ('\n', asm_out_file
);
4337 name_len
= strlen (v
->lf_method
.name
) + 1;
4338 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_method
.name
, name_len
);
4340 leaf_len
= 8 + name_len
;
4341 write_cv_padding (4 - (leaf_len
% 4));
4343 free (v
->lf_method
.name
);
4347 /* This is lf_bclass in binutils and lfBClass in Microsoft's
4353 uint16_t attributes;
4354 uint32_t base_class_type;
4359 fputs (integer_asm_op (2, false), asm_out_file
);
4360 fprint_whex (asm_out_file
, LF_BCLASS
);
4361 putc ('\n', asm_out_file
);
4363 fputs (integer_asm_op (2, false), asm_out_file
);
4364 fprint_whex (asm_out_file
, v
->lf_bclass
.attributes
);
4365 putc ('\n', asm_out_file
);
4367 fputs (integer_asm_op (4, false), asm_out_file
);
4368 fprint_whex (asm_out_file
, v
->lf_bclass
.base_class_type
);
4369 putc ('\n', asm_out_file
);
4371 leaf_len
= 8 + write_cv_integer (&v
->lf_bclass
.offset
);
4373 write_cv_padding (4 - (leaf_len
% 4));
4377 /* This is lf_nest_type in binutils and lfNestType in Microsoft's
4389 fputs (integer_asm_op (2, false), asm_out_file
);
4390 fprint_whex (asm_out_file
, LF_NESTTYPE
);
4391 putc ('\n', asm_out_file
);
4393 fputs (integer_asm_op (2, false), asm_out_file
);
4394 fprint_whex (asm_out_file
, 0);
4395 putc ('\n', asm_out_file
);
4397 fputs (integer_asm_op (4, false), asm_out_file
);
4398 fprint_whex (asm_out_file
, v
->lf_nesttype
.type
);
4399 putc ('\n', asm_out_file
);
4401 name_len
= strlen (v
->lf_nesttype
.name
) + 1;
4402 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_nesttype
.name
, name_len
);
4404 leaf_len
= 8 + name_len
;
4405 write_cv_padding (4 - (leaf_len
% 4));
4407 free (v
->lf_nesttype
.name
);
4414 t
->lf_fieldlist
.subtypes
= next
;
4418 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4421 /* Write an LF_ENUM type. */
4424 write_lf_enum (codeview_custom_type
*t
)
4426 size_t name_len
, leaf_len
;
4428 /* This is lf_enum in binutils and lfEnum in Microsoft's cvinfo.h:
4434 uint16_t num_elements;
4435 uint16_t properties;
4436 uint32_t underlying_type;
4437 uint32_t field_list;
4442 fputs (integer_asm_op (2, false), asm_out_file
);
4443 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4446 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4448 fputs (integer_asm_op (2, false), asm_out_file
);
4449 fprint_whex (asm_out_file
, t
->kind
);
4450 putc ('\n', asm_out_file
);
4452 fputs (integer_asm_op (2, false), asm_out_file
);
4453 fprint_whex (asm_out_file
, t
->lf_enum
.count
);
4454 putc ('\n', asm_out_file
);
4456 fputs (integer_asm_op (2, false), asm_out_file
);
4457 fprint_whex (asm_out_file
, t
->lf_enum
.properties
);
4458 putc ('\n', asm_out_file
);
4460 fputs (integer_asm_op (4, false), asm_out_file
);
4461 fprint_whex (asm_out_file
, t
->lf_enum
.underlying_type
);
4462 putc ('\n', asm_out_file
);
4464 fputs (integer_asm_op (4, false), asm_out_file
);
4465 fprint_whex (asm_out_file
, t
->lf_enum
.fieldlist
);
4466 putc ('\n', asm_out_file
);
4468 name_len
= strlen (t
->lf_enum
.name
) + 1;
4469 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_enum
.name
, name_len
);
4471 leaf_len
= 14 + name_len
;
4472 write_cv_padding (4 - (leaf_len
% 4));
4474 free (t
->lf_enum
.name
);
4476 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4479 /* Write an LF_STRUCTURE or LF_CLASS type (the two have the same structure). */
4482 write_lf_structure (codeview_custom_type
*t
)
4484 size_t name_len
, leaf_len
;
4486 /* This is lf_class in binutils and lfClass in Microsoft's cvinfo.h:
4492 uint16_t num_members;
4493 uint16_t properties;
4494 uint32_t field_list;
4495 uint32_t derived_from;
4502 fputs (integer_asm_op (2, false), asm_out_file
);
4503 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4506 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4508 fputs (integer_asm_op (2, false), asm_out_file
);
4509 fprint_whex (asm_out_file
, t
->kind
);
4510 putc ('\n', asm_out_file
);
4512 fputs (integer_asm_op (2, false), asm_out_file
);
4513 fprint_whex (asm_out_file
, t
->lf_structure
.num_members
);
4514 putc ('\n', asm_out_file
);
4516 fputs (integer_asm_op (2, false), asm_out_file
);
4517 fprint_whex (asm_out_file
, t
->lf_structure
.properties
);
4518 putc ('\n', asm_out_file
);
4520 fputs (integer_asm_op (4, false), asm_out_file
);
4521 fprint_whex (asm_out_file
, t
->lf_structure
.field_list
);
4522 putc ('\n', asm_out_file
);
4524 fputs (integer_asm_op (4, false), asm_out_file
);
4525 fprint_whex (asm_out_file
, t
->lf_structure
.derived_from
);
4526 putc ('\n', asm_out_file
);
4528 fputs (integer_asm_op (4, false), asm_out_file
);
4529 fprint_whex (asm_out_file
, t
->lf_structure
.vshape
);
4530 putc ('\n', asm_out_file
);
4532 leaf_len
= 20 + write_cv_integer (&t
->lf_structure
.length
);
4534 if (t
->lf_structure
.name
)
4536 name_len
= strlen (t
->lf_structure
.name
) + 1;
4537 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_structure
.name
, name_len
);
4541 static const char unnamed_struct
[] = "<unnamed-tag>";
4543 name_len
= sizeof (unnamed_struct
);
4544 ASM_OUTPUT_ASCII (asm_out_file
, unnamed_struct
, name_len
);
4547 leaf_len
+= name_len
;
4548 write_cv_padding (4 - (leaf_len
% 4));
4550 free (t
->lf_structure
.name
);
4552 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4555 /* Write an LF_UNION type. */
4558 write_lf_union (codeview_custom_type
*t
)
4560 size_t name_len
, leaf_len
;
4562 /* This is lf_union in binutils and lfUnion in Microsoft's cvinfo.h:
4568 uint16_t num_members;
4569 uint16_t properties;
4570 uint32_t field_list;
4576 fputs (integer_asm_op (2, false), asm_out_file
);
4577 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4580 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4582 fputs (integer_asm_op (2, false), asm_out_file
);
4583 fprint_whex (asm_out_file
, t
->kind
);
4584 putc ('\n', asm_out_file
);
4586 fputs (integer_asm_op (2, false), asm_out_file
);
4587 fprint_whex (asm_out_file
, t
->lf_structure
.num_members
);
4588 putc ('\n', asm_out_file
);
4590 fputs (integer_asm_op (2, false), asm_out_file
);
4591 fprint_whex (asm_out_file
, t
->lf_structure
.properties
);
4592 putc ('\n', asm_out_file
);
4594 fputs (integer_asm_op (4, false), asm_out_file
);
4595 fprint_whex (asm_out_file
, t
->lf_structure
.field_list
);
4596 putc ('\n', asm_out_file
);
4598 leaf_len
= 12 + write_cv_integer (&t
->lf_structure
.length
);
4600 if (t
->lf_structure
.name
)
4602 name_len
= strlen (t
->lf_structure
.name
) + 1;
4603 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_structure
.name
, name_len
);
4607 static const char unnamed_struct
[] = "<unnamed-tag>";
4609 name_len
= sizeof (unnamed_struct
);
4610 ASM_OUTPUT_ASCII (asm_out_file
, unnamed_struct
, name_len
);
4613 leaf_len
+= name_len
;
4614 write_cv_padding (4 - (leaf_len
% 4));
4616 free (t
->lf_structure
.name
);
4618 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4621 /* Write an LF_ARRAY type. */
4624 write_lf_array (codeview_custom_type
*t
)
4628 /* This is lf_array in binutils and lfArray in Microsoft's cvinfo.h:
4634 uint32_t element_type;
4635 uint32_t index_type;
4636 uint16_t length_in_bytes;
4641 fputs (integer_asm_op (2, false), asm_out_file
);
4642 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4645 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4647 fputs (integer_asm_op (2, false), asm_out_file
);
4648 fprint_whex (asm_out_file
, t
->kind
);
4649 putc ('\n', asm_out_file
);
4651 fputs (integer_asm_op (4, false), asm_out_file
);
4652 fprint_whex (asm_out_file
, t
->lf_array
.element_type
);
4653 putc ('\n', asm_out_file
);
4655 fputs (integer_asm_op (4, false), asm_out_file
);
4656 fprint_whex (asm_out_file
, t
->lf_array
.index_type
);
4657 putc ('\n', asm_out_file
);
4659 leaf_len
= 13 + write_cv_integer (&t
->lf_array
.length_in_bytes
);
4661 ASM_OUTPUT_ASCII (asm_out_file
, "", 1);
4663 write_cv_padding (4 - (leaf_len
% 4));
4665 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4668 /* Write an LF_BITFIELD type. */
4671 write_lf_bitfield (codeview_custom_type
*t
)
4673 /* This is lf_bitfield in binutils and lfBitfield in Microsoft's cvinfo.h:
4685 fputs (integer_asm_op (2, false), asm_out_file
);
4686 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4689 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4691 fputs (integer_asm_op (2, false), asm_out_file
);
4692 fprint_whex (asm_out_file
, t
->kind
);
4693 putc ('\n', asm_out_file
);
4695 fputs (integer_asm_op (4, false), asm_out_file
);
4696 fprint_whex (asm_out_file
, t
->lf_bitfield
.base_type
);
4697 putc ('\n', asm_out_file
);
4699 fputs (integer_asm_op (1, false), asm_out_file
);
4700 fprint_whex (asm_out_file
, t
->lf_bitfield
.length
);
4701 putc ('\n', asm_out_file
);
4703 fputs (integer_asm_op (1, false), asm_out_file
);
4704 fprint_whex (asm_out_file
, t
->lf_bitfield
.position
);
4705 putc ('\n', asm_out_file
);
4707 write_cv_padding (2);
4709 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4712 /* Write an LF_PROCEDURE type. Function pointers are implemented as pointers
4716 write_lf_procedure (codeview_custom_type
*t
)
4718 /* This is lf_procedure in binutils and lfProc in Microsoft's cvinfo.h:
4724 uint32_t return_type;
4725 uint8_t calling_convention;
4727 uint16_t num_parameters;
4732 fputs (integer_asm_op (2, false), asm_out_file
);
4733 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4736 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4738 fputs (integer_asm_op (2, false), asm_out_file
);
4739 fprint_whex (asm_out_file
, t
->kind
);
4740 putc ('\n', asm_out_file
);
4742 fputs (integer_asm_op (4, false), asm_out_file
);
4743 fprint_whex (asm_out_file
, t
->lf_procedure
.return_type
);
4744 putc ('\n', asm_out_file
);
4746 fputs (integer_asm_op (1, false), asm_out_file
);
4747 fprint_whex (asm_out_file
, t
->lf_procedure
.calling_convention
);
4748 putc ('\n', asm_out_file
);
4750 fputs (integer_asm_op (1, false), asm_out_file
);
4751 fprint_whex (asm_out_file
, t
->lf_procedure
.attributes
);
4752 putc ('\n', asm_out_file
);
4754 fputs (integer_asm_op (2, false), asm_out_file
);
4755 fprint_whex (asm_out_file
, t
->lf_procedure
.num_parameters
);
4756 putc ('\n', asm_out_file
);
4758 fputs (integer_asm_op (4, false), asm_out_file
);
4759 fprint_whex (asm_out_file
, t
->lf_procedure
.arglist
);
4760 putc ('\n', asm_out_file
);
4762 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4765 /* Write an LF_ARGLIST type. This is just a list of other types. LF_PROCEDURE
4766 entries point to one of these. */
4769 write_lf_arglist (codeview_custom_type
*t
)
4771 /* This is lf_arglist in binutils and lfArgList in Microsoft's cvinfo.h:
4777 uint32_t num_entries;
4782 fputs (integer_asm_op (2, false), asm_out_file
);
4783 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4786 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4788 fputs (integer_asm_op (2, false), asm_out_file
);
4789 fprint_whex (asm_out_file
, t
->kind
);
4790 putc ('\n', asm_out_file
);
4792 fputs (integer_asm_op (4, false), asm_out_file
);
4793 fprint_whex (asm_out_file
, t
->lf_arglist
.num_entries
);
4794 putc ('\n', asm_out_file
);
4796 for (uint32_t i
= 0; i
< t
->lf_arglist
.num_entries
; i
++)
4798 fputs (integer_asm_op (4, false), asm_out_file
);
4799 fprint_whex (asm_out_file
, t
->lf_arglist
.args
[i
]);
4800 putc ('\n', asm_out_file
);
4803 free (t
->lf_arglist
.args
);
4805 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4808 /* Write an LF_FUNC_ID type, which marries together a function type with its
4809 name. This will end up in the alternative types stream in the final PDB,
4810 but we can just stick it in the normal .debug$T section. */
4813 write_lf_func_id (codeview_custom_type
*t
)
4817 /* This is lf_func_id in binutils and lfFuncId in Microsoft's cvinfo.h:
4823 uint32_t parent_scope;
4824 uint32_t function_type;
4829 fputs (integer_asm_op (2, false), asm_out_file
);
4830 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4833 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4835 fputs (integer_asm_op (2, false), asm_out_file
);
4836 fprint_whex (asm_out_file
, t
->kind
);
4837 putc ('\n', asm_out_file
);
4839 fputs (integer_asm_op (4, false), asm_out_file
);
4840 fprint_whex (asm_out_file
, t
->lf_func_id
.parent_scope
);
4841 putc ('\n', asm_out_file
);
4843 fputs (integer_asm_op (4, false), asm_out_file
);
4844 fprint_whex (asm_out_file
, t
->lf_func_id
.function_type
);
4845 putc ('\n', asm_out_file
);
4847 name_len
= strlen (t
->lf_func_id
.name
) + 1;
4849 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_func_id
.name
, name_len
);
4851 write_cv_padding (4 - (name_len
% 4));
4853 free (t
->lf_func_id
.name
);
4855 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4858 /* Write an LF_MFUNC_ID type, which is the version of LF_FUNC_ID for struct
4859 functions. Instead of an LF_STRING_ID for the parent scope, we write the
4860 type number of the parent struct. */
4863 write_lf_mfunc_id (codeview_custom_type
*t
)
4867 /* This is lf_mfunc_id in binutils and lfMFuncId in Microsoft's cvinfo.h:
4873 uint32_t parent_type;
4874 uint32_t function_type;
4879 fputs (integer_asm_op (2, false), asm_out_file
);
4880 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4883 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4885 fputs (integer_asm_op (2, false), asm_out_file
);
4886 fprint_whex (asm_out_file
, t
->kind
);
4887 putc ('\n', asm_out_file
);
4889 fputs (integer_asm_op (4, false), asm_out_file
);
4890 fprint_whex (asm_out_file
, t
->lf_mfunc_id
.parent_type
);
4891 putc ('\n', asm_out_file
);
4893 fputs (integer_asm_op (4, false), asm_out_file
);
4894 fprint_whex (asm_out_file
, t
->lf_mfunc_id
.function_type
);
4895 putc ('\n', asm_out_file
);
4897 name_len
= strlen (t
->lf_mfunc_id
.name
) + 1;
4899 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_mfunc_id
.name
, name_len
);
4901 write_cv_padding (4 - (name_len
% 4));
4903 free (t
->lf_mfunc_id
.name
);
4905 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4908 /* Write an LF_STRING_ID type, which provides a deduplicated string that other
4909 types can reference. */
4912 write_lf_string_id (codeview_custom_type
*t
)
4916 /* This is lf_string_id in binutils and lfStringId in Microsoft's cvinfo.h:
4927 fputs (integer_asm_op (2, false), asm_out_file
);
4928 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4931 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4933 fputs (integer_asm_op (2, false), asm_out_file
);
4934 fprint_whex (asm_out_file
, t
->kind
);
4935 putc ('\n', asm_out_file
);
4937 fputs (integer_asm_op (4, false), asm_out_file
);
4938 fprint_whex (asm_out_file
, t
->lf_string_id
.substring
);
4939 putc ('\n', asm_out_file
);
4941 string_len
= strlen (t
->lf_string_id
.string
) + 1;
4943 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_string_id
.string
, string_len
);
4945 write_cv_padding (4 - (string_len
% 4));
4947 free (t
->lf_string_id
.string
);
4949 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4952 /* Write an LF_MFUNCTION type, representing a member function. This is the
4953 struct-scoped equivalent of the LF_PROCEDURE type. */
4956 write_lf_mfunction (codeview_custom_type
*t
)
4958 /* This is lf_mfunction in binutils and lfMFunc in Microsoft's cvinfo.h:
4964 uint32_t return_type;
4965 uint32_t containing_class_type;
4967 uint8_t calling_convention;
4969 uint16_t num_parameters;
4971 int32_t this_adjustment;
4975 fputs (integer_asm_op (2, false), asm_out_file
);
4976 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4979 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4981 fputs (integer_asm_op (2, false), asm_out_file
);
4982 fprint_whex (asm_out_file
, t
->kind
);
4983 putc ('\n', asm_out_file
);
4985 fputs (integer_asm_op (4, false), asm_out_file
);
4986 fprint_whex (asm_out_file
, t
->lf_mfunction
.return_type
);
4987 putc ('\n', asm_out_file
);
4989 fputs (integer_asm_op (4, false), asm_out_file
);
4990 fprint_whex (asm_out_file
, t
->lf_mfunction
.containing_class_type
);
4991 putc ('\n', asm_out_file
);
4993 fputs (integer_asm_op (4, false), asm_out_file
);
4994 fprint_whex (asm_out_file
, t
->lf_mfunction
.this_type
);
4995 putc ('\n', asm_out_file
);
4997 fputs (integer_asm_op (1, false), asm_out_file
);
4998 fprint_whex (asm_out_file
, t
->lf_mfunction
.calling_convention
);
4999 putc ('\n', asm_out_file
);
5001 fputs (integer_asm_op (1, false), asm_out_file
);
5002 fprint_whex (asm_out_file
, t
->lf_mfunction
.attributes
);
5003 putc ('\n', asm_out_file
);
5005 fputs (integer_asm_op (2, false), asm_out_file
);
5006 fprint_whex (asm_out_file
, t
->lf_mfunction
.num_parameters
);
5007 putc ('\n', asm_out_file
);
5009 fputs (integer_asm_op (4, false), asm_out_file
);
5010 fprint_whex (asm_out_file
, t
->lf_mfunction
.arglist
);
5011 putc ('\n', asm_out_file
);
5013 fputs (integer_asm_op (4, false), asm_out_file
);
5014 fprint_whex (asm_out_file
, t
->lf_mfunction
.this_adjustment
);
5015 putc ('\n', asm_out_file
);
5017 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
5020 /* Write an LF_METHODLIST type, which is an array of type numbers for
5021 LF_MFUNCTION types. Overloaded functions are represented by a LF_METHOD
5022 subtype in the field list, which points to a LF_METHODLIST type for the
5023 function's various forms. */
5026 write_lf_methodlist (codeview_custom_type
*t
)
5028 /* This is lf_methodlist in binutils and lMethodList in Microsoft's cvinfo.h:
5030 struct lf_methodlist_entry
5032 uint16_t method_attribute;
5034 uint32_t method_type;
5037 struct lf_methodlist
5041 struct lf_methodlist_entry entries[];
5045 fputs (integer_asm_op (2, false), asm_out_file
);
5046 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
5049 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
5051 fputs (integer_asm_op (2, false), asm_out_file
);
5052 fprint_whex (asm_out_file
, t
->kind
);
5053 putc ('\n', asm_out_file
);
5055 for (unsigned int i
= 0; i
< t
->lf_methodlist
.count
; i
++)
5057 fputs (integer_asm_op (2, false), asm_out_file
);
5058 fprint_whex (asm_out_file
, t
->lf_methodlist
.entries
[i
].method_attribute
);
5059 putc ('\n', asm_out_file
);
5061 fputs (integer_asm_op (2, false), asm_out_file
);
5062 fprint_whex (asm_out_file
, 0);
5063 putc ('\n', asm_out_file
);
5065 fputs (integer_asm_op (4, false), asm_out_file
);
5066 fprint_whex (asm_out_file
, t
->lf_methodlist
.entries
[i
].method_type
);
5067 putc ('\n', asm_out_file
);
5070 free (t
->lf_methodlist
.entries
);
5072 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
5075 /* Write the .debug$T section, which contains all of our custom type
5079 write_custom_types (void)
5081 targetm
.asm_out
.named_section (".debug$T", SECTION_DEBUG
, NULL
);
5083 fputs (integer_asm_op (4, false), asm_out_file
);
5084 fprint_whex (asm_out_file
, CV_SIGNATURE_C13
);
5085 putc ('\n', asm_out_file
);
5087 while (custom_types
)
5089 codeview_custom_type
*n
= custom_types
->next
;
5091 switch (custom_types
->kind
)
5094 write_lf_pointer (custom_types
);
5098 write_lf_modifier (custom_types
);
5102 write_lf_fieldlist (custom_types
);
5106 write_lf_enum (custom_types
);
5111 write_lf_structure (custom_types
);
5115 write_lf_union (custom_types
);
5119 write_lf_array (custom_types
);
5123 write_lf_bitfield (custom_types
);
5127 write_lf_procedure (custom_types
);
5131 write_lf_arglist (custom_types
);
5135 write_lf_func_id (custom_types
);
5139 write_lf_mfunc_id (custom_types
);
5143 write_lf_string_id (custom_types
);
5147 write_lf_mfunction (custom_types
);
5151 write_lf_methodlist (custom_types
);
5158 free (custom_types
);
5163 /* Finish CodeView debug info emission. */
5166 codeview_debug_finish (void)
5168 targetm
.asm_out
.named_section (".debug$S", SECTION_DEBUG
, NULL
);
5170 fputs (integer_asm_op (4, false), asm_out_file
);
5171 fprint_whex (asm_out_file
, CV_SIGNATURE_C13
);
5172 putc ('\n', asm_out_file
);
5174 write_strings_table ();
5175 write_source_files ();
5176 write_line_numbers ();
5178 if (inlinee_lines_htab
)
5179 write_inlinee_lines ();
5181 write_codeview_symbols ();
5183 /* If we reference a nested struct but not its parent, add_deferred_type
5184 gets called if we create a forward reference for this, even though we've
5185 already flushed this in codeview_debug_early_finish. In this case we will
5186 need to flush this list again. */
5187 flush_deferred_types ();
5190 write_custom_types ();
5194 codeview_function
*next_func
= funcs
->next
;
5196 while (funcs
->blocks
)
5198 codeview_line_block
*next_block
= funcs
->blocks
->next
;
5200 while (funcs
->blocks
->lines
)
5202 codeview_line
*next_line
= funcs
->blocks
->lines
->next
;
5204 free (funcs
->blocks
->lines
);
5205 funcs
->blocks
->lines
= next_line
;
5208 free (funcs
->blocks
);
5209 funcs
->blocks
= next_block
;
5223 delete string_id_htab
;
5225 if (inlinee_lines_htab
)
5226 delete inlinee_lines_htab
;
5229 delete cv_func_htab
;
5232 /* Translate a DWARF base type (DW_TAG_base_type) into its CodeView
5236 get_type_num_base_type (dw_die_ref type
)
5238 unsigned int size
= get_AT_unsigned (type
, DW_AT_byte_size
);
5240 switch (get_AT_unsigned (type
, DW_AT_encoding
))
5242 case DW_ATE_signed_char
:
5244 const char *name
= get_AT_string (type
, DW_AT_name
);
5249 if (name
&& !strcmp (name
, "signed char"))
5255 case DW_ATE_unsigned_char
:
5269 const char *name
= get_AT_string (type
, DW_AT_name
);
5271 if (name
&& !strcmp (name
, "int"))
5284 case DW_ATE_unsigned
:
5289 const char *name
= get_AT_string (type
, DW_AT_name
);
5291 if (name
&& !strcmp (name
, "wchar_t"))
5299 const char *name
= get_AT_string (type
, DW_AT_name
);
5301 if (name
&& !strcmp (name
, "unsigned int"))
5349 case DW_ATE_boolean
:
5360 /* Add a new codeview_custom_type to our singly-linked custom_types list. */
5363 add_custom_type (codeview_custom_type
*ct
)
5367 if (last_custom_type
)
5369 num
= last_custom_type
->num
+ 1;
5370 last_custom_type
->next
= ct
;
5378 last_custom_type
= ct
;
5383 /* Process a DW_TAG_pointer_type DIE. If this is a pointer to a builtin
5384 type, return the predefined constant for this. Otherwise, add a new
5385 LF_POINTER type and return its number. */
5388 get_type_num_pointer_type (dw_die_ref type
, bool in_struct
)
5390 uint32_t base_type_num
, byte_size
;
5391 dw_die_ref base_type
;
5392 codeview_custom_type
*ct
;
5394 byte_size
= get_AT_unsigned (type
, DW_AT_byte_size
);
5395 if (byte_size
!= 4 && byte_size
!= 8)
5398 base_type
= get_AT_ref (type
, DW_AT_type
);
5400 /* If DW_AT_type is not set, this must be a void pointer. */
5402 return byte_size
== 4 ? T_32PVOID
: T_64PVOID
;
5404 base_type_num
= get_type_num (base_type
, in_struct
, false);
5405 if (base_type_num
== 0)
5408 /* Pointers to builtin types have predefined type numbers, with the top byte
5409 determining the pointer size - 0x0400 for a 32-bit pointer and 0x0600
5411 if (base_type_num
< FIRST_TYPE
&& !(base_type_num
& 0xff00))
5414 return CV_POINTER_32
| base_type_num
;
5416 return CV_POINTER_64
| base_type_num
;
5419 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5422 ct
->kind
= LF_POINTER
;
5423 ct
->lf_pointer
.base_type
= base_type_num
;
5426 ct
->lf_pointer
.attributes
= CV_PTR_NEAR32
;
5428 ct
->lf_pointer
.attributes
= CV_PTR_64
;
5430 ct
->lf_pointer
.attributes
|= byte_size
<< 13;
5432 add_custom_type (ct
);
5437 /* Process a DW_TAG_reference_type or DW_TAG_rvalue_reference_type DIE, add a
5438 new LF_POINTER type, and return its number. */
5441 get_type_num_reference_type (dw_die_ref type
, bool in_struct
, bool rvref
)
5443 uint32_t base_type_num
, byte_size
;
5444 dw_die_ref base_type
;
5445 codeview_custom_type
*ct
;
5447 byte_size
= get_AT_unsigned (type
, DW_AT_byte_size
);
5448 if (byte_size
!= 4 && byte_size
!= 8)
5451 base_type
= get_AT_ref (type
, DW_AT_type
);
5453 base_type_num
= get_type_num (base_type
, in_struct
, false);
5454 if (base_type_num
== 0)
5457 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5460 ct
->kind
= LF_POINTER
;
5461 ct
->lf_pointer
.base_type
= base_type_num
;
5462 ct
->lf_pointer
.attributes
= rvref
? CV_PTR_MODE_RVREF
: CV_PTR_MODE_LVREF
;
5465 ct
->lf_pointer
.attributes
|= CV_PTR_NEAR32
;
5467 ct
->lf_pointer
.attributes
|= CV_PTR_64
;
5469 ct
->lf_pointer
.attributes
|= byte_size
<< 13;
5471 add_custom_type (ct
);
5476 /* Process a DW_TAG_const_type DIE, adding an LF_MODIFIER type and returning
5480 get_type_num_const_type (dw_die_ref type
, bool in_struct
)
5482 dw_die_ref base_type
;
5483 uint32_t base_type_num
;
5484 codeview_custom_type
*ct
;
5485 bool is_volatile
= false;
5487 base_type
= get_AT_ref (type
, DW_AT_type
);
5489 /* Handle case when this is a const volatile type - we only need one
5490 LF_MODIFIER for this. */
5491 if (base_type
&& dw_get_die_tag (base_type
) == DW_TAG_volatile_type
)
5495 base_type
= get_AT_ref (base_type
, DW_AT_type
);
5500 base_type_num
= T_VOID
;
5504 base_type_num
= get_type_num (base_type
, in_struct
, false);
5505 if (base_type_num
== 0)
5509 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5512 ct
->kind
= LF_MODIFIER
;
5513 ct
->lf_modifier
.base_type
= base_type_num
;
5514 ct
->lf_modifier
.modifier
= MOD_const
;
5517 ct
->lf_modifier
.modifier
|= MOD_volatile
;
5519 add_custom_type (ct
);
5524 /* Process a DW_TAG_volatile_type DIE, adding an LF_MODIFIER type and
5525 returning its number. */
5528 get_type_num_volatile_type (dw_die_ref type
, bool in_struct
)
5530 dw_die_ref base_type
;
5531 uint32_t base_type_num
;
5532 codeview_custom_type
*ct
;
5534 base_type
= get_AT_ref (type
, DW_AT_type
);
5538 base_type_num
= get_type_num (base_type
, in_struct
, false);
5539 if (base_type_num
== 0)
5544 base_type_num
= T_VOID
;
5547 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5550 ct
->kind
= LF_MODIFIER
;
5551 ct
->lf_modifier
.base_type
= base_type_num
;
5552 ct
->lf_modifier
.modifier
= MOD_volatile
;
5554 add_custom_type (ct
);
5559 /* Return the name of a DIE, traversing its parents in order to construct a
5560 C++-style name if necessary. */
5562 get_name (dw_die_ref die
)
5564 dw_die_ref decl
= get_AT_ref (die
, DW_AT_specification
);
5570 static const char anon
[] = "<unnamed-tag>";
5571 static const char sep
[] = "::";
5576 name
= get_AT_string (die
, DW_AT_name
);
5581 parent
= dw_get_die_parent (die
);
5583 if (!parent
|| dw_get_die_tag (parent
) == DW_TAG_compile_unit
)
5584 return xstrdup (name
);
5586 len
= strlen (name
);
5587 while (parent
&& dw_get_die_tag (parent
) != DW_TAG_compile_unit
)
5589 const char *ns_name
= get_AT_string (parent
, DW_AT_name
);
5591 len
+= sizeof (sep
) - 1;
5594 len
+= strlen (ns_name
);
5596 len
+= sizeof (anon
) - 1;
5598 parent
= dw_get_die_parent (parent
);
5601 str
= (char *) xmalloc (len
+ 1);
5604 len
-= strlen (name
);
5605 memcpy (str
+ len
, name
, strlen (name
));
5607 parent
= dw_get_die_parent (die
);
5608 while (parent
&& dw_get_die_tag (parent
) != DW_TAG_compile_unit
)
5610 const char *ns_name
= get_AT_string (parent
, DW_AT_name
);
5612 len
-= sizeof (sep
) - 1;
5613 memcpy (str
+ len
, sep
, sizeof (sep
) - 1);
5617 len
-= strlen (ns_name
);
5618 memcpy (str
+ len
, ns_name
, strlen (ns_name
));
5622 len
-= sizeof (anon
) - 1;
5623 memcpy (str
+ len
, anon
, sizeof (anon
) - 1);
5626 parent
= dw_get_die_parent (parent
);
5632 /* Add a forward declaration for an enum. This is legal from C++11 onwards. */
5635 add_enum_forward_def (dw_die_ref type
)
5637 codeview_custom_type
*ct
;
5639 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5644 ct
->lf_enum
.count
= 0;
5645 ct
->lf_enum
.properties
= CV_PROP_FWDREF
;
5646 ct
->lf_enum
.underlying_type
= get_type_num (get_AT_ref (type
, DW_AT_type
),
5648 ct
->lf_enum
.fieldlist
= 0;
5649 ct
->lf_enum
.name
= get_name (type
);
5651 add_custom_type (ct
);
5656 /* Process a DW_TAG_enumeration_type DIE, adding an LF_FIELDLIST and an LF_ENUM
5657 type, returning the number of the latter. */
5660 get_type_num_enumeration_type (dw_die_ref type
, bool in_struct
)
5662 dw_die_ref first_child
;
5663 codeview_custom_type
*ct
;
5665 uint32_t last_type
= 0;
5667 if (get_AT_flag (type
, DW_AT_declaration
))
5668 return add_enum_forward_def (type
);
5670 /* First, add an LF_FIELDLIST for the enum's values. We don't need to worry
5671 about deduplication here, as ld will take care of that for us. If there's
5672 a lot of entries, add more LF_FIELDLISTs with LF_INDEXes pointing to
5673 the overflow lists. */
5675 first_child
= dw_get_die_child (type
);
5677 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5680 ct
->kind
= LF_FIELDLIST
;
5681 ct
->lf_fieldlist
.length
= 0;
5682 ct
->lf_fieldlist
.subtypes
= NULL
;
5683 ct
->lf_fieldlist
.last_subtype
= NULL
;
5693 codeview_subtype
*el
;
5696 c
= dw_get_die_sib (c
);
5698 if (dw_get_die_tag (c
) != DW_TAG_enumerator
)
5701 att
= get_AT (c
, DW_AT_const_value
);
5705 el
= (codeview_subtype
*) xmalloc (sizeof (*el
));
5707 el
->kind
= LF_ENUMERATE
;
5709 switch (AT_class (att
))
5711 case dw_val_class_unsigned_const
:
5712 case dw_val_class_unsigned_const_implicit
:
5713 el
->lf_enumerate
.value
.neg
= false;
5714 el
->lf_enumerate
.value
.num
= att
->dw_attr_val
.v
.val_unsigned
;
5717 case dw_val_class_const
:
5718 case dw_val_class_const_implicit
:
5719 if (att
->dw_attr_val
.v
.val_int
< 0)
5721 el
->lf_enumerate
.value
.neg
= true;
5722 el
->lf_enumerate
.value
.num
= -att
->dw_attr_val
.v
.val_int
;
5726 el
->lf_enumerate
.value
.neg
= false;
5727 el
->lf_enumerate
.value
.num
= att
->dw_attr_val
.v
.val_int
;
5736 el
->lf_enumerate
.name
= xstrdup (get_AT_string (c
, DW_AT_name
));
5738 el_len
= 7 + strlen (el
->lf_enumerate
.name
);
5739 el_len
+= cv_integer_len (&el
->lf_enumerate
.value
);
5742 el_len
+= 4 - (el_len
% 4);
5744 if (ct
->lf_fieldlist
.length
+ el_len
> MAX_FIELDLIST_SIZE
)
5746 codeview_subtype
*idx
;
5747 codeview_custom_type
*ct2
;
5749 idx
= (codeview_subtype
*) xmalloc (sizeof (*idx
));
5751 idx
->kind
= LF_INDEX
;
5752 idx
->lf_index
.type_num
= 0;
5754 ct
->lf_fieldlist
.last_subtype
->next
= idx
;
5755 ct
->lf_fieldlist
.last_subtype
= idx
;
5757 ct2
= (codeview_custom_type
*)
5758 xmalloc (sizeof (codeview_custom_type
));
5761 ct2
->kind
= LF_FIELDLIST
;
5762 ct2
->lf_fieldlist
.length
= 0;
5763 ct2
->lf_fieldlist
.subtypes
= NULL
;
5764 ct2
->lf_fieldlist
.last_subtype
= NULL
;
5769 ct
->lf_fieldlist
.length
+= el_len
;
5771 if (ct
->lf_fieldlist
.last_subtype
)
5772 ct
->lf_fieldlist
.last_subtype
->next
= el
;
5774 ct
->lf_fieldlist
.subtypes
= el
;
5776 ct
->lf_fieldlist
.last_subtype
= el
;
5779 while (c
!= first_child
);
5784 codeview_custom_type
*ct2
;
5789 if (ct
->lf_fieldlist
.last_subtype
->kind
== LF_INDEX
)
5790 ct
->lf_fieldlist
.last_subtype
->lf_index
.type_num
= last_type
;
5792 add_custom_type (ct
);
5793 last_type
= ct
->num
;
5798 /* Now add an LF_ENUM, pointing to the LF_FIELDLIST we just added. */
5800 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5804 ct
->lf_enum
.count
= count
;
5805 ct
->lf_enum
.properties
= 0;
5806 ct
->lf_enum
.underlying_type
= get_type_num (get_AT_ref (type
, DW_AT_type
),
5808 ct
->lf_enum
.fieldlist
= last_type
;
5809 ct
->lf_enum
.name
= get_name (type
);
5811 add_custom_type (ct
);
5816 /* Add a DIE to our deferred_types list. This happens when we have a struct
5817 with a pointer to a type that hasn't been defined yet, but which gets
5818 defined later on. */
5821 add_deferred_type (dw_die_ref type
)
5823 codeview_deferred_type
*def
;
5825 def
= (codeview_deferred_type
*) xmalloc (sizeof (codeview_deferred_type
));
5830 if (!deferred_types
)
5831 deferred_types
= def
;
5833 last_deferred_type
->next
= def
;
5835 last_deferred_type
= def
;
5838 /* Flush the contents of our deferred_types list. This happens after everything
5839 else has been written. We call get_type_num to ensure that a type gets
5840 added to custom_types, if it hasn't been already. */
5843 flush_deferred_types (void)
5845 while (deferred_types
)
5847 codeview_deferred_type
*next
;
5849 next
= deferred_types
->next
;
5851 get_type_num (deferred_types
->type
, false, true);
5853 free (deferred_types
);
5854 deferred_types
= next
;
5857 last_deferred_type
= NULL
;
5860 /* Add a forward definition for a struct, class, or union. */
5863 add_struct_forward_def (dw_die_ref type
)
5865 codeview_custom_type
*ct
;
5867 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5871 switch (dw_get_die_tag (type
))
5873 case DW_TAG_class_type
:
5874 ct
->kind
= LF_CLASS
;
5877 case DW_TAG_structure_type
:
5878 ct
->kind
= LF_STRUCTURE
;
5881 case DW_TAG_union_type
:
5882 ct
->kind
= LF_UNION
;
5889 ct
->lf_structure
.num_members
= 0;
5890 ct
->lf_structure
.properties
= CV_PROP_FWDREF
;
5891 ct
->lf_structure
.field_list
= 0;
5892 ct
->lf_structure
.derived_from
= 0;
5893 ct
->lf_structure
.vshape
= 0;
5894 ct
->lf_structure
.length
.neg
= false;
5895 ct
->lf_structure
.length
.num
= 0;
5896 ct
->lf_structure
.name
= get_name (type
);
5898 add_custom_type (ct
);
5900 if (!get_AT_flag (type
, DW_AT_declaration
))
5901 add_deferred_type (type
);
5906 /* Add a new subtype to an LF_FIELDLIST type, and handle overflows if
5910 add_to_fieldlist (codeview_custom_type
**ct
, uint16_t *num_members
,
5911 codeview_subtype
*el
, size_t el_len
)
5913 /* Add an LF_INDEX subtype if everything's too big for one
5916 if ((*ct
)->lf_fieldlist
.length
+ el_len
> MAX_FIELDLIST_SIZE
)
5918 codeview_subtype
*idx
;
5919 codeview_custom_type
*ct2
;
5921 idx
= (codeview_subtype
*) xmalloc (sizeof (*idx
));
5923 idx
->kind
= LF_INDEX
;
5924 idx
->lf_index
.type_num
= 0;
5926 (*ct
)->lf_fieldlist
.last_subtype
->next
= idx
;
5927 (*ct
)->lf_fieldlist
.last_subtype
= idx
;
5929 ct2
= (codeview_custom_type
*)
5930 xmalloc (sizeof (codeview_custom_type
));
5933 ct2
->kind
= LF_FIELDLIST
;
5934 ct2
->lf_fieldlist
.length
= 0;
5935 ct2
->lf_fieldlist
.subtypes
= NULL
;
5936 ct2
->lf_fieldlist
.last_subtype
= NULL
;
5941 (*ct
)->lf_fieldlist
.length
+= el_len
;
5943 if ((*ct
)->lf_fieldlist
.last_subtype
)
5944 (*ct
)->lf_fieldlist
.last_subtype
->next
= el
;
5946 (*ct
)->lf_fieldlist
.subtypes
= el
;
5948 (*ct
)->lf_fieldlist
.last_subtype
= el
;
5952 /* Add an LF_BITFIELD type, returning its number. DWARF represents bitfields
5953 as members in a struct with a DW_AT_data_bit_offset attribute, whereas in
5954 CodeView they're a distinct type. */
5957 create_bitfield (dw_die_ref c
)
5959 codeview_custom_type
*ct
;
5962 base_type
= get_type_num (get_AT_ref (c
, DW_AT_type
), true, false);
5966 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5969 ct
->kind
= LF_BITFIELD
;
5970 ct
->lf_bitfield
.base_type
= base_type
;
5971 ct
->lf_bitfield
.length
= get_AT_unsigned (c
, DW_AT_bit_size
);
5972 ct
->lf_bitfield
.position
= get_AT_unsigned (c
, DW_AT_data_bit_offset
);
5974 add_custom_type (ct
);
5979 /* Create an LF_MEMBER field list subtype for a struct member, returning its
5980 pointer in el and its size in el_len. */
5983 add_struct_member (dw_die_ref c
, uint16_t accessibility
,
5984 codeview_custom_type
**ct
, uint16_t *num_members
,
5985 unsigned int base_offset
)
5987 codeview_subtype
*el
;
5989 dw_die_ref type
= get_AT_ref (c
, DW_AT_type
);
5990 unsigned int offset
;
5992 offset
= base_offset
+ get_AT_unsigned (c
, DW_AT_data_member_location
);
5994 /* If the data member is actually an anonymous struct, class, or union,
5995 follow MSVC by flattening this into its parent. */
5996 if (!get_AT_string (c
, DW_AT_name
) && type
5997 && (dw_get_die_tag (type
) == DW_TAG_structure_type
5998 || dw_get_die_tag (type
) == DW_TAG_class_type
5999 || dw_get_die_tag (type
) == DW_TAG_union_type
))
6001 dw_die_ref c2
, first_child
;
6003 first_child
= dw_get_die_child (type
);
6008 c2
= dw_get_die_sib (c2
);
6010 if (dw_get_die_tag (c2
) == DW_TAG_member
)
6011 add_struct_member (c2
, accessibility
, ct
, num_members
, offset
);
6013 while (c2
!= first_child
);
6018 el
= (codeview_subtype
*) xmalloc (sizeof (*el
));
6020 el
->kind
= LF_MEMBER
;
6021 el
->lf_member
.attributes
= accessibility
;
6023 if (get_AT (c
, DW_AT_data_bit_offset
))
6024 el
->lf_member
.type
= create_bitfield (c
);
6026 el
->lf_member
.type
= get_type_num (type
, true, false);
6028 el
->lf_member
.offset
.neg
= false;
6029 el
->lf_member
.offset
.num
= offset
;
6031 el_len
= 11 + cv_integer_len (&el
->lf_member
.offset
);
6033 if (get_AT_string (c
, DW_AT_name
))
6035 el
->lf_member
.name
= xstrdup (get_AT_string (c
, DW_AT_name
));
6036 el_len
+= strlen (el
->lf_member
.name
);
6040 el
->lf_member
.name
= NULL
;
6044 el_len
+= 4 - (el_len
% 4);
6046 add_to_fieldlist (ct
, num_members
, el
, el_len
);
6049 /* Create an LF_STMEMBER field list subtype for a static struct member,
6050 returning its pointer in el and its size in el_len. */
6053 add_struct_static_member (dw_die_ref c
, uint16_t accessibility
,
6054 codeview_custom_type
**ct
, uint16_t *num_members
)
6056 codeview_subtype
*el
;
6059 el
= (codeview_subtype
*) xmalloc (sizeof (*el
));
6061 el
->kind
= LF_STMEMBER
;
6062 el
->lf_static_member
.attributes
= accessibility
;
6063 el
->lf_static_member
.type
= get_type_num (get_AT_ref (c
, DW_AT_type
),
6065 el
->lf_static_member
.name
= xstrdup (get_AT_string (c
, DW_AT_name
));
6067 el_len
= 9 + strlen (el
->lf_static_member
.name
);
6070 el_len
+= 4 - (el_len
% 4);
6072 add_to_fieldlist (ct
, num_members
, el
, el_len
);
6075 /* Create a field list subtype for a struct function, returning its pointer in
6076 el and its size in el_len. If the function is not overloaded, create an
6077 LF_ONEMETHOD subtype pointing to the LF_MFUNCTION. Otherwise, add an
6078 LF_METHODLIST type of the function's forms, and create an LF_METHOD subtype
6079 pointing to this. */
6082 add_struct_function (dw_die_ref c
, hash_table
<method_hasher
> *method_htab
,
6083 codeview_custom_type
**ct
, uint16_t *num_members
)
6085 const char *name
= get_AT_string (c
, DW_AT_name
);
6086 codeview_method
**slot
, *meth
;
6087 codeview_subtype
*el
;
6090 slot
= method_htab
->find_slot_with_hash (name
, htab_hash_string (name
),
6097 el
= (codeview_subtype
*) xmalloc (sizeof (*el
));
6100 if (meth
->count
== 1)
6102 el
->kind
= LF_ONEMETHOD
;
6103 el
->lf_onemethod
.method_attribute
= meth
->attribute
;
6104 el
->lf_onemethod
.method_type
= meth
->type
;
6105 el
->lf_onemethod
.name
= xstrdup (name
);
6107 el_len
= 9 + strlen (el
->lf_onemethod
.name
);
6111 codeview_custom_type
*ct
;
6112 lf_methodlist_entry
*ent
;
6114 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6117 ct
->kind
= LF_METHODLIST
;
6118 ct
->lf_methodlist
.count
= meth
->count
;
6119 ct
->lf_methodlist
.entries
= (lf_methodlist_entry
*)
6120 xmalloc (meth
->count
* sizeof (lf_methodlist_entry
));
6122 ent
= ct
->lf_methodlist
.entries
;
6123 for (codeview_method
*m
= meth
; m
; m
= m
->next
)
6125 ent
->method_attribute
= m
->attribute
;
6126 ent
->method_type
= m
->type
;
6130 add_custom_type (ct
);
6132 el
->kind
= LF_METHOD
;
6133 el
->lf_method
.count
= meth
->count
;
6134 el
->lf_method
.method_list
= ct
->num
;
6135 el
->lf_method
.name
= xstrdup (name
);
6137 el_len
= 9 + strlen (el
->lf_method
.name
);
6141 el_len
+= 4 - (el_len
% 4);
6143 add_to_fieldlist (ct
, num_members
, el
, el_len
);
6145 method_htab
->remove_elt_with_hash (name
, htab_hash_string (name
));
6149 codeview_method
*next
= meth
->next
;
6157 /* Create a field list subtype that records the base class that a struct
6161 add_struct_inheritance (dw_die_ref c
, uint16_t accessibility
,
6162 codeview_custom_type
**ct
, uint16_t *num_members
)
6164 codeview_subtype
*el
;
6167 /* FIXME: if DW_AT_virtuality is DW_VIRTUALITY_virtual this is a virtual
6168 base class, and we should be issuing an LF_VBCLASS record
6170 if (get_AT_unsigned (c
, DW_AT_virtuality
) == DW_VIRTUALITY_virtual
)
6173 el
= (codeview_subtype
*) xmalloc (sizeof (*el
));
6175 el
->kind
= LF_BCLASS
;
6176 el
->lf_bclass
.attributes
= accessibility
;
6177 el
->lf_bclass
.base_class_type
= get_type_num (get_AT_ref (c
, DW_AT_type
),
6179 el
->lf_bclass
.offset
.neg
= false;
6180 el
->lf_bclass
.offset
.num
= get_AT_unsigned (c
, DW_AT_data_member_location
);
6182 el_len
= 10 + cv_integer_len (&el
->lf_bclass
.offset
);
6185 el_len
+= 4 - (el_len
% 4);
6187 add_to_fieldlist (ct
, num_members
, el
, el_len
);
6190 /* Create a new LF_MFUNCTION type for a struct function, add it to the
6191 types_htab hash table, and return its type number. */
6194 get_mfunction_type (dw_die_ref c
)
6196 uint32_t containing_class_type
, this_type
, mfunction_type
;
6197 dw_die_ref obj_pointer
;
6198 codeview_type
**slot
, *t
;
6200 containing_class_type
= get_type_num (dw_get_die_parent (c
), true, false);
6202 obj_pointer
= get_AT_ref (c
, DW_AT_object_pointer
);
6203 if (obj_pointer
&& dw_get_die_tag (obj_pointer
) == DW_TAG_formal_parameter
)
6205 this_type
= get_type_num (get_AT_ref (obj_pointer
, DW_AT_type
),
6213 mfunction_type
= get_type_num_subroutine_type (c
, true, containing_class_type
,
6216 slot
= types_htab
->find_slot_with_hash (c
, htab_hash_pointer (c
), INSERT
);
6218 t
= (codeview_type
*) xmalloc (sizeof (codeview_type
));
6221 t
->num
= mfunction_type
;
6222 t
->is_fwd_ref
= false;
6226 return mfunction_type
;
6229 /* Translate a DWARF DW_AT_accessibility constant into its CodeView
6230 equivalent. If implicit, follow the C++ rules. */
6233 get_accessibility (dw_die_ref c
)
6235 switch (get_AT_unsigned (c
, DW_AT_accessibility
))
6237 case DW_ACCESS_private
:
6238 return CV_ACCESS_PRIVATE
;
6240 case DW_ACCESS_protected
:
6241 return CV_ACCESS_PROTECTED
;
6243 case DW_ACCESS_public
:
6244 return CV_ACCESS_PUBLIC
;
6246 /* Members in a C++ struct or union are public by default, members
6247 in a class are private. */
6249 if (dw_get_die_tag (dw_get_die_parent (c
)) == DW_TAG_class_type
)
6250 return CV_ACCESS_PRIVATE
;
6252 return CV_ACCESS_PUBLIC
;
6256 /* Returns true if the struct function pointed to by die is an instantiated
6257 template function. These are skipped in CodeView struct definitions, as
6258 otherwise the same type might not be deduplicated across different TUs. */
6261 is_templated_func (dw_die_ref die
)
6263 dw_die_ref c
= dw_get_die_child (die
);
6270 c
= dw_get_die_sib (c
);
6272 if (dw_get_die_tag (c
) == DW_TAG_template_type_param
)
6275 while (c
!= dw_get_die_child (die
));
6280 /* Create a field list subtype that records that a struct has a nested type
6281 contained within it. */
6284 add_struct_nested_type (dw_die_ref c
, codeview_custom_type
**ct
,
6285 uint16_t *num_members
)
6287 const char *name
= get_AT_string (c
, DW_AT_name
);
6288 codeview_subtype
*el
;
6289 size_t name_len
, el_len
;
6294 name_len
= strlen (name
);
6296 el
= (codeview_subtype
*) xmalloc (sizeof (*el
));
6298 el
->kind
= LF_NESTTYPE
;
6299 el
->lf_nesttype
.type
= get_type_num (c
, true, false);
6300 el
->lf_nesttype
.name
= xstrdup (name
);
6302 el_len
= 9 + name_len
;
6305 el_len
+= 4 - (el_len
% 4);
6307 add_to_fieldlist (ct
, num_members
, el
, el_len
);
6310 /* Process a DW_TAG_structure_type, DW_TAG_class_type, or DW_TAG_union_type
6311 DIE, add an LF_FIELDLIST and an LF_STRUCTURE / LF_CLASS / LF_UNION type,
6312 and return the number of the latter. */
6315 get_type_num_struct (dw_die_ref type
, bool in_struct
, bool *is_fwd_ref
)
6317 dw_die_ref parent
, first_child
;
6318 codeview_custom_type
*ct
;
6319 uint16_t num_members
= 0;
6320 uint32_t last_type
= 0;
6322 parent
= dw_get_die_parent(type
);
6324 if (parent
&& (dw_get_die_tag (parent
) == DW_TAG_structure_type
6325 || dw_get_die_tag (parent
) == DW_TAG_class_type
6326 || dw_get_die_tag (parent
) == DW_TAG_union_type
))
6327 get_type_num (parent
, true, false);
6329 if ((in_struct
&& get_AT_string (type
, DW_AT_name
))
6330 || get_AT_flag (type
, DW_AT_declaration
))
6333 return add_struct_forward_def (type
);
6336 *is_fwd_ref
= false;
6338 /* First, add an LF_FIELDLIST for the structure's members. We don't need to
6339 worry about deduplication here, as ld will take care of that for us.
6340 If there's a lot of entries, add more LF_FIELDLISTs with LF_INDEXes
6341 pointing to the overflow lists. */
6343 first_child
= dw_get_die_child (type
);
6345 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6348 ct
->kind
= LF_FIELDLIST
;
6349 ct
->lf_fieldlist
.length
= 0;
6350 ct
->lf_fieldlist
.subtypes
= NULL
;
6351 ct
->lf_fieldlist
.last_subtype
= NULL
;
6355 hash_table
<method_hasher
> *method_htab
= NULL
;
6358 /* First, loop through and record any non-templated member functions.
6359 This is because overloaded and non-overloaded functions are expressed
6360 differently in CodeView, so we need to have a hash table on the name
6361 to know how to record it later on. */
6366 c
= dw_get_die_sib (c
);
6368 if (dw_get_die_tag (c
) == DW_TAG_subprogram
)
6370 const char *name
= get_AT_string (c
, DW_AT_name
);
6371 codeview_method
*meth
, **slot
;
6373 if (is_templated_func (c
))
6377 method_htab
= new hash_table
<method_hasher
> (10);
6379 meth
= (codeview_method
*) xmalloc (sizeof (*meth
));
6381 slot
= method_htab
->find_slot_with_hash (name
,
6382 htab_hash_string (name
),
6385 meth
->attribute
= get_accessibility (c
);
6387 if (!get_AT_ref (c
, DW_AT_object_pointer
))
6388 meth
->attribute
|= CV_METHOD_STATIC
;
6390 meth
->type
= get_mfunction_type (c
);
6396 (*slot
)->last
->next
= meth
;
6398 (*slot
)->next
= meth
;
6400 (*slot
)->last
= meth
;
6407 meth
->name
= xstrdup (name
);
6414 while (c
!= first_child
);
6416 /* Now loop through again and record the actual members. */
6421 uint16_t accessibility
;
6423 c
= dw_get_die_sib (c
);
6425 accessibility
= get_accessibility (c
);
6427 switch (dw_get_die_tag (c
))
6430 add_struct_member (c
, accessibility
, &ct
, &num_members
, 0);
6433 case DW_TAG_variable
:
6434 add_struct_static_member (c
, accessibility
, &ct
, &num_members
);
6437 case DW_TAG_subprogram
:
6438 if (!is_templated_func (c
))
6439 add_struct_function (c
, method_htab
, &ct
, &num_members
);
6442 case DW_TAG_inheritance
:
6443 add_struct_inheritance (c
, accessibility
, &ct
, &num_members
);
6446 case DW_TAG_structure_type
:
6447 case DW_TAG_class_type
:
6448 case DW_TAG_union_type
:
6449 case DW_TAG_enumeration_type
:
6450 add_struct_nested_type (c
, &ct
, &num_members
);
6457 while (c
!= first_child
);
6465 codeview_custom_type
*ct2
;
6470 if (ct
->lf_fieldlist
.last_subtype
6471 && ct
->lf_fieldlist
.last_subtype
->kind
== LF_INDEX
)
6473 ct
->lf_fieldlist
.last_subtype
->lf_index
.type_num
= last_type
;
6476 add_custom_type (ct
);
6477 last_type
= ct
->num
;
6482 /* Now add an LF_STRUCTURE / LF_CLASS / LF_UNION, pointing to the
6483 LF_FIELDLIST we just added. */
6485 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6489 switch (dw_get_die_tag (type
))
6491 case DW_TAG_class_type
:
6492 ct
->kind
= LF_CLASS
;
6495 case DW_TAG_structure_type
:
6496 ct
->kind
= LF_STRUCTURE
;
6499 case DW_TAG_union_type
:
6500 ct
->kind
= LF_UNION
;
6507 ct
->lf_structure
.num_members
= num_members
;
6508 ct
->lf_structure
.properties
= 0;
6509 ct
->lf_structure
.field_list
= last_type
;
6510 ct
->lf_structure
.derived_from
= 0;
6511 ct
->lf_structure
.vshape
= 0;
6512 ct
->lf_structure
.length
.neg
= false;
6513 ct
->lf_structure
.length
.num
= get_AT_unsigned (type
, DW_AT_byte_size
);
6514 ct
->lf_structure
.name
= get_name (type
);
6516 add_custom_type (ct
);
6521 /* Process a DW_TAG_subroutine_type DIE, adding an LF_ARGLIST and an
6522 LF_PROCEDURE or LF_MFUNCTION type, and returning the number of the
6526 get_type_num_subroutine_type (dw_die_ref type
, bool in_struct
,
6527 uint32_t containing_class_type
,
6528 uint32_t this_type
, int32_t this_adjustment
)
6530 codeview_custom_type
*ct
;
6531 uint32_t return_type
, arglist_type
;
6533 dw_die_ref first_child
;
6535 /* Find the return type. */
6537 if (get_AT_ref (type
, DW_AT_type
))
6539 return_type
= get_type_num (get_AT_ref (type
, DW_AT_type
), in_struct
,
6541 if (return_type
== 0)
6546 return_type
= T_VOID
;
6549 /* Handle pointer to member function. */
6550 if (containing_class_type
== 0)
6552 dw_die_ref obj_ptr
= get_AT_ref (type
, DW_AT_object_pointer
);
6556 dw_die_ref obj_ptr_type
= get_AT_ref (obj_ptr
, DW_AT_type
);
6559 && dw_get_die_tag (obj_ptr_type
) == DW_TAG_pointer_type
)
6561 dw_die_ref cont_class
= get_AT_ref (obj_ptr_type
, DW_AT_type
);
6563 if (dw_get_die_tag (cont_class
) == DW_TAG_const_type
)
6564 cont_class
= get_AT_ref (cont_class
, DW_AT_type
);
6566 containing_class_type
= get_type_num (cont_class
, in_struct
,
6568 this_type
= get_type_num (obj_ptr_type
, in_struct
, false);
6573 /* Count the arguments. */
6575 first_child
= dw_get_die_child (type
);
6585 c
= dw_get_die_sib (c
);
6587 if (dw_get_die_tag (c
) != DW_TAG_formal_parameter
6588 && dw_get_die_tag (c
) != DW_TAG_unspecified_parameters
)
6591 /* We ignore "this" params here. */
6592 if (get_AT_flag (c
, DW_AT_artificial
) != 0)
6597 while (c
!= first_child
);
6600 /* Create an LF_ARGLIST for the arguments. If this is a duplicate, ld
6601 will take care of this for us. */
6603 first_child
= dw_get_die_child (type
);
6605 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6608 ct
->kind
= LF_ARGLIST
;
6609 ct
->lf_arglist
.num_entries
= num_args
;
6616 ct
->lf_arglist
.args
= (uint32_t *) xmalloc (sizeof (uint32_t) * num_args
);
6617 argptr
= ct
->lf_arglist
.args
;
6622 c
= dw_get_die_sib (c
);
6624 if (get_AT_flag (c
, DW_AT_artificial
) != 0)
6627 switch (dw_get_die_tag (c
))
6629 case DW_TAG_formal_parameter
:
6630 *argptr
= get_type_num (get_AT_ref (c
, DW_AT_type
), in_struct
,
6635 case DW_TAG_unspecified_parameters
:
6644 while (c
!= first_child
);
6648 ct
->lf_arglist
.args
= NULL
;
6651 add_custom_type (ct
);
6653 arglist_type
= ct
->num
;
6655 /* Finally, create an LF_PROCEDURE or LF_MFUNCTION type. */
6657 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6661 if (containing_class_type
!= 0)
6663 ct
->kind
= LF_MFUNCTION
;
6664 ct
->lf_mfunction
.return_type
= return_type
;
6665 ct
->lf_mfunction
.containing_class_type
= containing_class_type
;
6666 ct
->lf_mfunction
.this_type
= this_type
;
6667 ct
->lf_mfunction
.calling_convention
= 0;
6668 ct
->lf_mfunction
.attributes
= 0;
6669 ct
->lf_mfunction
.num_parameters
= num_args
;
6670 ct
->lf_mfunction
.arglist
= arglist_type
;
6671 ct
->lf_mfunction
.this_adjustment
= this_adjustment
;
6675 ct
->kind
= LF_PROCEDURE
;
6676 ct
->lf_procedure
.return_type
= return_type
;
6677 ct
->lf_procedure
.calling_convention
= 0;
6678 ct
->lf_procedure
.attributes
= 0;
6679 ct
->lf_procedure
.num_parameters
= num_args
;
6680 ct
->lf_procedure
.arglist
= arglist_type
;
6683 add_custom_type (ct
);
6688 /* Process a DW_TAG_array_type DIE, adding an LF_ARRAY type and returning its
6692 get_type_num_array_type (dw_die_ref type
, bool in_struct
)
6694 dw_die_ref base_type
, t
, first_child
, c
, *dimension_arr
;
6696 unsigned int dimensions
, i
;
6697 uint32_t element_type
;
6699 base_type
= get_AT_ref (type
, DW_AT_type
);
6703 /* We need to know the size of our base type. Loop through until we find
6706 while (t
&& size
== 0)
6708 switch (dw_get_die_tag (t
))
6710 case DW_TAG_const_type
:
6711 case DW_TAG_volatile_type
:
6712 case DW_TAG_typedef
:
6713 case DW_TAG_enumeration_type
:
6714 t
= get_AT_ref (t
, DW_AT_type
);
6717 case DW_TAG_base_type
:
6718 case DW_TAG_structure_type
:
6719 case DW_TAG_class_type
:
6720 case DW_TAG_union_type
:
6721 case DW_TAG_pointer_type
:
6722 case DW_TAG_reference_type
:
6723 case DW_TAG_rvalue_reference_type
:
6724 size
= get_AT_unsigned (t
, DW_AT_byte_size
);
6735 first_child
= dw_get_die_child (type
);
6739 element_type
= get_type_num (base_type
, in_struct
, false);
6740 if (element_type
== 0)
6743 /* Create an array of our DW_TAG_subrange_type children, in reverse order.
6744 We have to do this because unlike DWARF CodeView doesn't have
6745 multidimensional arrays, so instead we do arrays of arrays. */
6751 c
= dw_get_die_sib (c
);
6752 if (dw_get_die_tag (c
) != DW_TAG_subrange_type
)
6757 while (c
!= first_child
);
6759 if (dimensions
== 0)
6762 dimension_arr
= (dw_die_ref
*) xmalloc (sizeof (dw_die_ref
) * dimensions
);
6768 c
= dw_get_die_sib (c
);
6769 if (dw_get_die_tag (c
) != DW_TAG_subrange_type
)
6772 dimension_arr
[dimensions
- i
- 1] = c
;
6775 while (c
!= first_child
);
6777 /* Record an LF_ARRAY entry for each array dimension. If this leads to
6778 duplicate types, ld will take care of it for us. */
6780 for (i
= 0; i
< dimensions
; i
++)
6782 codeview_custom_type
*ct
;
6785 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6787 size
*= get_AT_unsigned (dimension_arr
[i
], DW_AT_upper_bound
) + 1;
6789 index
= get_AT_ref (dimension_arr
[i
], DW_AT_type
);
6792 ct
->kind
= LF_ARRAY
;
6793 ct
->lf_array
.element_type
= element_type
;
6794 ct
->lf_array
.index_type
= get_type_num (index
, in_struct
, false);
6795 ct
->lf_array
.length_in_bytes
.neg
= false;
6796 ct
->lf_array
.length_in_bytes
.num
= size
;
6798 add_custom_type (ct
);
6800 element_type
= ct
->num
;
6803 free (dimension_arr
);
6805 return element_type
;
6808 /* Translate a DW_TAG_ptr_to_member_type DIE, that is a pointer to member
6809 function or field, into an LF_POINTER record. */
6812 get_type_num_ptr_to_member_type (dw_die_ref type
, bool in_struct
)
6814 uint32_t base_type_num
;
6815 uint32_t containing_class
;
6816 dw_die_ref base_type
;
6817 codeview_custom_type
*ct
;
6819 base_type
= get_AT_ref (type
, DW_AT_type
);
6821 base_type_num
= get_type_num (base_type
, in_struct
, false);
6822 if (base_type_num
== 0)
6825 containing_class
= get_type_num (get_AT_ref (type
, DW_AT_containing_type
),
6828 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6831 ct
->kind
= LF_POINTER
;
6832 ct
->lf_pointer
.base_type
= base_type_num
;
6836 ct
->lf_pointer
.attributes
= CV_PTR_64
;
6837 ct
->lf_pointer
.attributes
|= 8 << 13;
6841 ct
->lf_pointer
.attributes
= CV_PTR_NEAR32
;
6842 ct
->lf_pointer
.attributes
|= 4 << 13;
6845 ct
->lf_pointer
.containing_class
= containing_class
;
6847 if (base_type
&& dw_get_die_tag (base_type
) == DW_TAG_subroutine_type
)
6849 ct
->lf_pointer
.attributes
|= CV_PTR_MODE_PMFUNC
;
6850 ct
->lf_pointer
.ptr_to_mem_type
= CV_PMTYPE_F_Single
;
6854 ct
->lf_pointer
.attributes
|= CV_PTR_MODE_PMEM
;
6855 ct
->lf_pointer
.ptr_to_mem_type
= CV_PMTYPE_D_Single
;
6858 add_custom_type (ct
);
6863 /* Return the type number that corresponds to a DW_TAG_typedef DIE: either the
6864 type number of the base type, or follow MSVC in having a special value
6865 for the HRESULT used by COM. */
6868 get_type_num_typedef (dw_die_ref type
, bool in_struct
)
6872 num
= get_type_num (get_AT_ref (type
, DW_AT_type
), in_struct
, false);
6876 const char *name
= get_AT_string (type
, DW_AT_name
);
6878 /* longs typedef'd as "HRESULT" get their own type */
6879 if (name
&& !strcmp (name
, "HRESULT"))
6886 /* Process a DIE representing a type definition, add a CodeView type if
6887 necessary, and return its number. If it's something we can't handle, return
6888 0. We keep a hash table so that we're not adding the same type multiple
6889 times - though if we do it's not disastrous, as ld will deduplicate
6890 everything for us. */
6893 get_type_num (dw_die_ref type
, bool in_struct
, bool no_fwd_ref
)
6895 codeview_type
**slot
, *t
;
6903 types_htab
= new hash_table
<die_hasher
> (10);
6905 slot
= types_htab
->find_slot_with_hash (type
, htab_hash_pointer (type
),
6908 if (slot
&& *slot
&& (!no_fwd_ref
|| !(*slot
)->is_fwd_ref
))
6909 return (*slot
)->num
;
6913 switch (dw_get_die_tag (type
))
6915 case DW_TAG_base_type
:
6916 num
= get_type_num_base_type (type
);
6919 case DW_TAG_typedef
:
6920 num
= get_type_num_typedef (type
, in_struct
);
6923 case DW_TAG_pointer_type
:
6924 num
= get_type_num_pointer_type (type
, in_struct
);
6927 case DW_TAG_reference_type
:
6928 num
= get_type_num_reference_type (type
, in_struct
, false);
6931 case DW_TAG_rvalue_reference_type
:
6932 num
= get_type_num_reference_type (type
, in_struct
, true);
6935 case DW_TAG_const_type
:
6936 num
= get_type_num_const_type (type
, in_struct
);
6939 case DW_TAG_volatile_type
:
6940 num
= get_type_num_volatile_type (type
, in_struct
);
6943 case DW_TAG_enumeration_type
:
6944 num
= get_type_num_enumeration_type (type
, in_struct
);
6947 case DW_TAG_structure_type
:
6948 case DW_TAG_class_type
:
6949 case DW_TAG_union_type
:
6950 num
= get_type_num_struct (type
, in_struct
, &is_fwd_ref
);
6953 case DW_TAG_array_type
:
6954 num
= get_type_num_array_type (type
, in_struct
);
6957 case DW_TAG_subroutine_type
:
6958 num
= get_type_num_subroutine_type (type
, in_struct
, 0, 0, 0);
6961 case DW_TAG_ptr_to_member_type
:
6962 num
= get_type_num_ptr_to_member_type (type
, in_struct
);
6970 /* Check hash table again, and account for the fact that self-referential
6971 structs will have created a forward reference to themselves. */
6973 slot
= types_htab
->find_slot_with_hash (type
, htab_hash_pointer (type
),
6976 if (*slot
&& (*slot
)->is_fwd_ref
&& !is_fwd_ref
)
6979 (*slot
)->is_fwd_ref
= false;
6983 t
= (codeview_type
*) xmalloc (sizeof (codeview_type
));
6986 t
->is_fwd_ref
= is_fwd_ref
;
6993 /* Process a DW_TAG_variable DIE, and add an S_GDATA32 or S_LDATA32 symbol for
6997 add_variable (dw_die_ref die
)
7002 name
= get_AT_string (die
, DW_AT_name
);
7006 s
= (codeview_symbol
*) xmalloc (sizeof (codeview_symbol
));
7009 s
->kind
= get_AT (die
, DW_AT_external
) ? S_GDATA32
: S_LDATA32
;
7010 s
->data_symbol
.type
= get_type_num (get_AT_ref (die
, DW_AT_type
), false,
7012 s
->data_symbol
.name
= get_name (die
);
7013 s
->data_symbol
.die
= die
;
7023 /* Return the type number of the LF_STRING_ID entry corresponding to the given
7024 string, creating a new one if necessary. */
7027 add_string_id (const char *s
)
7029 codeview_custom_type
**slot
;
7030 codeview_custom_type
*ct
;
7032 if (!string_id_htab
)
7033 string_id_htab
= new hash_table
<string_id_hasher
> (10);
7035 slot
= string_id_htab
->find_slot_with_hash (s
, htab_hash_string (s
),
7038 return (*slot
)->num
;
7040 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
7043 ct
->kind
= LF_STRING_ID
;
7044 ct
->lf_string_id
.substring
= 0;
7045 ct
->lf_string_id
.string
= xstrdup (s
);
7047 add_custom_type (ct
);
7054 /* Return the type number of the LF_STRING_ID corresponding to the given DIE's
7055 parent, or 0 if it is in the global scope. */
7058 get_scope_string_id (dw_die_ref die
)
7060 dw_die_ref decl
= get_AT_ref (die
, DW_AT_specification
);
7067 die
= dw_get_die_parent (die
);
7071 if (dw_get_die_tag (die
) == DW_TAG_compile_unit
)
7074 name
= get_name (die
);
7078 ret
= add_string_id (name
);
7084 /* Add an LF_FUNC_ID type and return its number (see write_lf_func_id). */
7087 add_lf_func_id (dw_die_ref die
, const char *name
)
7089 uint32_t function_type
, scope_type
;
7090 codeview_custom_type
*ct
;
7092 function_type
= get_type_num_subroutine_type (die
, false, 0, 0, 0);
7093 scope_type
= get_scope_string_id (die
);
7095 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
7098 ct
->kind
= LF_FUNC_ID
;
7099 ct
->lf_func_id
.parent_scope
= scope_type
;
7100 ct
->lf_func_id
.function_type
= function_type
;
7101 ct
->lf_func_id
.name
= xstrdup (name
);
7103 add_custom_type (ct
);
7108 /* Add an LF_MFUNC_ID type and return its number (see write_lf_mfunc_id). */
7111 add_lf_mfunc_id (dw_die_ref die
, const char *name
)
7113 uint32_t function_type
= 0, parent_type
;
7114 codeview_custom_type
*ct
;
7115 dw_die_ref spec
= get_AT_ref (die
, DW_AT_specification
);
7117 parent_type
= get_type_num (dw_get_die_parent (spec
), false, false);
7121 codeview_type
**slot
;
7123 slot
= types_htab
->find_slot_with_hash (spec
, htab_hash_pointer (spec
),
7127 function_type
= (*slot
)->num
;
7130 if (function_type
== 0)
7132 function_type
= get_type_num_subroutine_type (die
, false, parent_type
,
7136 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
7139 ct
->kind
= LF_MFUNC_ID
;
7140 ct
->lf_mfunc_id
.parent_type
= parent_type
;
7141 ct
->lf_mfunc_id
.function_type
= function_type
;
7142 ct
->lf_mfunc_id
.name
= xstrdup (name
);
7144 add_custom_type (ct
);
7149 /* Generate a new LF_FUNC_ID or LF_MFUNC_ID type for a DW_TAG_subprogram DIE
7150 and return its number, or return the existing type number if already
7154 get_func_id (dw_die_ref die
)
7156 const char *name
= get_AT_string (die
, DW_AT_name
);
7157 dw_die_ref spec
= get_AT_ref (die
, DW_AT_specification
);
7158 bool do_mfunc_id
= false;
7159 codeview_type
**slot
, *t
;
7166 func_htab
= new hash_table
<die_hasher
> (10);
7168 slot
= func_htab
->find_slot_with_hash (die
, htab_hash_pointer (die
), INSERT
);
7171 return (*slot
)->num
;
7173 if (spec
&& dw_get_die_parent (spec
))
7175 switch (dw_get_die_tag (dw_get_die_parent (spec
)))
7177 case DW_TAG_class_type
:
7178 case DW_TAG_structure_type
:
7179 case DW_TAG_union_type
:
7189 num
= add_lf_mfunc_id (die
, name
);
7191 num
= add_lf_func_id (die
, name
);
7193 t
= (codeview_type
*) xmalloc (sizeof (codeview_type
));
7197 t
->is_fwd_ref
= false;
7204 /* Process a DW_TAG_subprogram DIE, and add an S_GPROC32_ID or S_LPROC32_ID
7208 add_function (dw_die_ref die
)
7210 uint32_t func_id_type
;
7213 func_id_type
= get_func_id (die
);
7214 if (func_id_type
== 0)
7217 /* Add an S_GPROC32_ID / S_LPROC32_ID symbol. */
7219 s
= (codeview_symbol
*) xmalloc (sizeof (codeview_symbol
));
7222 s
->kind
= get_AT (die
, DW_AT_external
) ? S_GPROC32_ID
: S_LPROC32_ID
;
7223 s
->function
.parent
= 0;
7224 s
->function
.end
= 0;
7225 s
->function
.next
= 0;
7226 s
->function
.type
= func_id_type
;
7227 s
->function
.flags
= 0;
7228 s
->function
.name
= get_name (die
);
7229 s
->function
.die
= die
;
7239 /* If we have encountered a new inlined function, add this to
7240 inlinee_lines_htab so that it can be output to the S_INLINEELINES subsection
7244 codeview_abstract_function (tree decl
)
7246 codeview_inlinee_lines
*il
, **slot
;
7249 struct dwarf_file_data
*file
;
7251 if (!DECL_DECLARED_INLINE_P (decl
))
7254 die
= lookup_decl_die (decl
);
7258 func_id
= get_func_id (die
);
7262 file
= get_AT_file (die
, DW_AT_decl_file
);
7266 if (!inlinee_lines_htab
)
7267 inlinee_lines_htab
= new hash_table
<inlinee_lines_hasher
> (10);
7269 slot
= inlinee_lines_htab
->find_slot_with_hash (func_id
, func_id
, INSERT
);
7273 il
= (codeview_inlinee_lines
*) xmalloc (sizeof (codeview_inlinee_lines
));
7276 il
->func_id
= func_id
;
7277 il
->file_id
= get_file_id (file
->filename
);
7278 il
->starting_line
= get_AT_unsigned (die
, DW_AT_decl_line
);
7283 /* Loop through the DIEs that have been output for our TU, and add CodeView
7284 symbols for them. */
7287 codeview_debug_early_finish (dw_die_ref die
)
7289 dw_die_ref first_child
, c
;
7291 first_child
= dw_get_die_child (die
);
7300 switch (dw_get_die_tag (c
))
7302 case DW_TAG_variable
:
7305 case DW_TAG_subprogram
:
7312 c
= dw_get_die_sib (c
);
7314 while (c
!= first_child
);
7316 flush_deferred_types ();