1 /* Generate CodeView debugging info from the GCC DWARF.
2 Copyright (C) 2023 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
48 #define CHKSUM_TYPE_MD5 1
50 #define CV_CFL_80386 0x03
51 #define CV_CFL_X64 0xD0
54 #define CV_CFL_CXX 0x01
56 #define FIRST_TYPE 0x1000
58 #define LINE_LABEL "Lcvline"
59 #define END_FUNC_LABEL "Lcvendfunc"
60 #define SYMBOL_START_LABEL "Lcvsymstart"
61 #define SYMBOL_END_LABEL "Lcvsymend"
63 /* There's two bytes available for each type's size, but follow MSVC's lead in
64 capping the LF_FIELDLIST size at fb00 (minus 8 bytes for the LF_INDEX
65 pointing to the overflow entry). */
66 #define MAX_FIELDLIST_SIZE 0xfaf8
70 /* This is enum SYM_ENUM_e in Microsoft's cvinfo.h. */
82 S_DEFRANGE_REGISTER
= 0x1141,
83 S_DEFRANGE_REGISTER_REL
= 0x1145,
84 S_LPROC32_ID
= 0x1146,
85 S_GPROC32_ID
= 0x1147,
86 S_PROC_ID_END
= 0x114f
89 /* This is enum LEAF_ENUM_e in Microsoft's cvinfo.h. */
97 LF_PROCEDURE
= 0x1008,
98 LF_MFUNCTION
= 0x1009,
100 LF_FIELDLIST
= 0x1203,
101 LF_BITFIELD
= 0x1205,
102 LF_METHODLIST
= 0x1206,
104 LF_ENUMERATE
= 0x1502,
107 LF_STRUCTURE
= 0x1505,
111 LF_STMEMBER
= 0x150e,
113 LF_ONEMETHOD
= 0x1511,
115 LF_MFUNC_ID
= 0x1602,
116 LF_STRING_ID
= 0x1605,
122 LF_QUADWORD
= 0x8009,
123 LF_UQUADWORD
= 0x800a
126 /* These come from enum CV_HREG_e in Microsoft's cvconst.h. */
128 enum cv_x86_register
{
191 CV_REG_PSEUDO1
= 116,
192 CV_REG_PSEUDO2
= 117,
193 CV_REG_PSEUDO3
= 118,
194 CV_REG_PSEUDO4
= 119,
195 CV_REG_PSEUDO5
= 120,
196 CV_REG_PSEUDO6
= 121,
197 CV_REG_PSEUDO7
= 122,
198 CV_REG_PSEUDO8
= 123,
199 CV_REG_PSEUDO9
= 124,
466 enum cv_amd64_register
{
500 CV_AMD64_EFLAGS
= 34,
545 CV_AMD64_FPEIP
= 144,
546 CV_AMD64_FPEDO
= 145,
563 CV_AMD64_XMM0_0
= 162,
564 CV_AMD64_XMM0_1
= 163,
565 CV_AMD64_XMM0_2
= 164,
566 CV_AMD64_XMM0_3
= 165,
567 CV_AMD64_XMM1_0
= 166,
568 CV_AMD64_XMM1_1
= 167,
569 CV_AMD64_XMM1_2
= 168,
570 CV_AMD64_XMM1_3
= 169,
571 CV_AMD64_XMM2_0
= 170,
572 CV_AMD64_XMM2_1
= 171,
573 CV_AMD64_XMM2_2
= 172,
574 CV_AMD64_XMM2_3
= 173,
575 CV_AMD64_XMM3_0
= 174,
576 CV_AMD64_XMM3_1
= 175,
577 CV_AMD64_XMM3_2
= 176,
578 CV_AMD64_XMM3_3
= 177,
579 CV_AMD64_XMM4_0
= 178,
580 CV_AMD64_XMM4_1
= 179,
581 CV_AMD64_XMM4_2
= 180,
582 CV_AMD64_XMM4_3
= 181,
583 CV_AMD64_XMM5_0
= 182,
584 CV_AMD64_XMM5_1
= 183,
585 CV_AMD64_XMM5_2
= 184,
586 CV_AMD64_XMM5_3
= 185,
587 CV_AMD64_XMM6_0
= 186,
588 CV_AMD64_XMM6_1
= 187,
589 CV_AMD64_XMM6_2
= 188,
590 CV_AMD64_XMM6_3
= 189,
591 CV_AMD64_XMM7_0
= 190,
592 CV_AMD64_XMM7_1
= 191,
593 CV_AMD64_XMM7_2
= 192,
594 CV_AMD64_XMM7_3
= 193,
595 CV_AMD64_XMM0L
= 194,
596 CV_AMD64_XMM1L
= 195,
597 CV_AMD64_XMM2L
= 196,
598 CV_AMD64_XMM3L
= 197,
599 CV_AMD64_XMM4L
= 198,
600 CV_AMD64_XMM5L
= 199,
601 CV_AMD64_XMM6L
= 200,
602 CV_AMD64_XMM7L
= 201,
603 CV_AMD64_XMM0H
= 202,
604 CV_AMD64_XMM1H
= 203,
605 CV_AMD64_XMM2H
= 204,
606 CV_AMD64_XMM3H
= 205,
607 CV_AMD64_XMM4H
= 206,
608 CV_AMD64_XMM5H
= 207,
609 CV_AMD64_XMM6H
= 208,
610 CV_AMD64_XMM7H
= 209,
611 CV_AMD64_MXCSR
= 211,
612 CV_AMD64_EMM0L
= 220,
613 CV_AMD64_EMM1L
= 221,
614 CV_AMD64_EMM2L
= 222,
615 CV_AMD64_EMM3L
= 223,
616 CV_AMD64_EMM4L
= 224,
617 CV_AMD64_EMM5L
= 225,
618 CV_AMD64_EMM6L
= 226,
619 CV_AMD64_EMM7L
= 227,
620 CV_AMD64_EMM0H
= 228,
621 CV_AMD64_EMM1H
= 229,
622 CV_AMD64_EMM2H
= 230,
623 CV_AMD64_EMM3H
= 231,
624 CV_AMD64_EMM4H
= 232,
625 CV_AMD64_EMM5H
= 233,
626 CV_AMD64_EMM6H
= 234,
627 CV_AMD64_EMM7H
= 235,
646 CV_AMD64_XMM10
= 254,
647 CV_AMD64_XMM11
= 255,
648 CV_AMD64_XMM12
= 256,
649 CV_AMD64_XMM13
= 257,
650 CV_AMD64_XMM14
= 258,
651 CV_AMD64_XMM15
= 259,
652 CV_AMD64_XMM8_0
= 260,
653 CV_AMD64_XMM8_1
= 261,
654 CV_AMD64_XMM8_2
= 262,
655 CV_AMD64_XMM8_3
= 263,
656 CV_AMD64_XMM9_0
= 264,
657 CV_AMD64_XMM9_1
= 265,
658 CV_AMD64_XMM9_2
= 266,
659 CV_AMD64_XMM9_3
= 267,
660 CV_AMD64_XMM10_0
= 268,
661 CV_AMD64_XMM10_1
= 269,
662 CV_AMD64_XMM10_2
= 270,
663 CV_AMD64_XMM10_3
= 271,
664 CV_AMD64_XMM11_0
= 272,
665 CV_AMD64_XMM11_1
= 273,
666 CV_AMD64_XMM11_2
= 274,
667 CV_AMD64_XMM11_3
= 275,
668 CV_AMD64_XMM12_0
= 276,
669 CV_AMD64_XMM12_1
= 277,
670 CV_AMD64_XMM12_2
= 278,
671 CV_AMD64_XMM12_3
= 279,
672 CV_AMD64_XMM13_0
= 280,
673 CV_AMD64_XMM13_1
= 281,
674 CV_AMD64_XMM13_2
= 282,
675 CV_AMD64_XMM13_3
= 283,
676 CV_AMD64_XMM14_0
= 284,
677 CV_AMD64_XMM14_1
= 285,
678 CV_AMD64_XMM14_2
= 286,
679 CV_AMD64_XMM14_3
= 287,
680 CV_AMD64_XMM15_0
= 288,
681 CV_AMD64_XMM15_1
= 289,
682 CV_AMD64_XMM15_2
= 290,
683 CV_AMD64_XMM15_3
= 291,
684 CV_AMD64_XMM8L
= 292,
685 CV_AMD64_XMM9L
= 293,
686 CV_AMD64_XMM10L
= 294,
687 CV_AMD64_XMM11L
= 295,
688 CV_AMD64_XMM12L
= 296,
689 CV_AMD64_XMM13L
= 297,
690 CV_AMD64_XMM14L
= 298,
691 CV_AMD64_XMM15L
= 299,
692 CV_AMD64_XMM8H
= 300,
693 CV_AMD64_XMM9H
= 301,
694 CV_AMD64_XMM10H
= 302,
695 CV_AMD64_XMM11H
= 303,
696 CV_AMD64_XMM12H
= 304,
697 CV_AMD64_XMM13H
= 305,
698 CV_AMD64_XMM14H
= 306,
699 CV_AMD64_XMM15H
= 307,
700 CV_AMD64_EMM8L
= 308,
701 CV_AMD64_EMM9L
= 309,
702 CV_AMD64_EMM10L
= 310,
703 CV_AMD64_EMM11L
= 311,
704 CV_AMD64_EMM12L
= 312,
705 CV_AMD64_EMM13L
= 313,
706 CV_AMD64_EMM14L
= 314,
707 CV_AMD64_EMM15L
= 315,
708 CV_AMD64_EMM8H
= 316,
709 CV_AMD64_EMM9H
= 317,
710 CV_AMD64_EMM10H
= 318,
711 CV_AMD64_EMM11H
= 319,
712 CV_AMD64_EMM12H
= 320,
713 CV_AMD64_EMM13H
= 321,
714 CV_AMD64_EMM14H
= 322,
715 CV_AMD64_EMM15H
= 323,
770 CV_AMD64_YMM10
= 378,
771 CV_AMD64_YMM11
= 379,
772 CV_AMD64_YMM12
= 380,
773 CV_AMD64_YMM13
= 381,
774 CV_AMD64_YMM14
= 382,
775 CV_AMD64_YMM15
= 383,
776 CV_AMD64_YMM0H
= 384,
777 CV_AMD64_YMM1H
= 385,
778 CV_AMD64_YMM2H
= 386,
779 CV_AMD64_YMM3H
= 387,
780 CV_AMD64_YMM4H
= 388,
781 CV_AMD64_YMM5H
= 389,
782 CV_AMD64_YMM6H
= 390,
783 CV_AMD64_YMM7H
= 391,
784 CV_AMD64_YMM8H
= 392,
785 CV_AMD64_YMM9H
= 393,
786 CV_AMD64_YMM10H
= 394,
787 CV_AMD64_YMM11H
= 395,
788 CV_AMD64_YMM12H
= 396,
789 CV_AMD64_YMM13H
= 397,
790 CV_AMD64_YMM14H
= 398,
791 CV_AMD64_YMM15H
= 399,
792 CV_AMD64_XMM0IL
= 400,
793 CV_AMD64_XMM1IL
= 401,
794 CV_AMD64_XMM2IL
= 402,
795 CV_AMD64_XMM3IL
= 403,
796 CV_AMD64_XMM4IL
= 404,
797 CV_AMD64_XMM5IL
= 405,
798 CV_AMD64_XMM6IL
= 406,
799 CV_AMD64_XMM7IL
= 407,
800 CV_AMD64_XMM8IL
= 408,
801 CV_AMD64_XMM9IL
= 409,
802 CV_AMD64_XMM10IL
= 410,
803 CV_AMD64_XMM11IL
= 411,
804 CV_AMD64_XMM12IL
= 412,
805 CV_AMD64_XMM13IL
= 413,
806 CV_AMD64_XMM14IL
= 414,
807 CV_AMD64_XMM15IL
= 415,
808 CV_AMD64_XMM0IH
= 416,
809 CV_AMD64_XMM1IH
= 417,
810 CV_AMD64_XMM2IH
= 418,
811 CV_AMD64_XMM3IH
= 419,
812 CV_AMD64_XMM4IH
= 420,
813 CV_AMD64_XMM5IH
= 421,
814 CV_AMD64_XMM6IH
= 422,
815 CV_AMD64_XMM7IH
= 423,
816 CV_AMD64_XMM8IH
= 424,
817 CV_AMD64_XMM9IH
= 425,
818 CV_AMD64_XMM10IH
= 426,
819 CV_AMD64_XMM11IH
= 427,
820 CV_AMD64_XMM12IH
= 428,
821 CV_AMD64_XMM13IH
= 429,
822 CV_AMD64_XMM14IH
= 430,
823 CV_AMD64_XMM15IH
= 431,
824 CV_AMD64_YMM0I0
= 432,
825 CV_AMD64_YMM0I1
= 433,
826 CV_AMD64_YMM0I2
= 434,
827 CV_AMD64_YMM0I3
= 435,
828 CV_AMD64_YMM1I0
= 436,
829 CV_AMD64_YMM1I1
= 437,
830 CV_AMD64_YMM1I2
= 438,
831 CV_AMD64_YMM1I3
= 439,
832 CV_AMD64_YMM2I0
= 440,
833 CV_AMD64_YMM2I1
= 441,
834 CV_AMD64_YMM2I2
= 442,
835 CV_AMD64_YMM2I3
= 443,
836 CV_AMD64_YMM3I0
= 444,
837 CV_AMD64_YMM3I1
= 445,
838 CV_AMD64_YMM3I2
= 446,
839 CV_AMD64_YMM3I3
= 447,
840 CV_AMD64_YMM4I0
= 448,
841 CV_AMD64_YMM4I1
= 449,
842 CV_AMD64_YMM4I2
= 450,
843 CV_AMD64_YMM4I3
= 451,
844 CV_AMD64_YMM5I0
= 452,
845 CV_AMD64_YMM5I1
= 453,
846 CV_AMD64_YMM5I2
= 454,
847 CV_AMD64_YMM5I3
= 455,
848 CV_AMD64_YMM6I0
= 456,
849 CV_AMD64_YMM6I1
= 457,
850 CV_AMD64_YMM6I2
= 458,
851 CV_AMD64_YMM6I3
= 459,
852 CV_AMD64_YMM7I0
= 460,
853 CV_AMD64_YMM7I1
= 461,
854 CV_AMD64_YMM7I2
= 462,
855 CV_AMD64_YMM7I3
= 463,
856 CV_AMD64_YMM8I0
= 464,
857 CV_AMD64_YMM8I1
= 465,
858 CV_AMD64_YMM8I2
= 466,
859 CV_AMD64_YMM8I3
= 467,
860 CV_AMD64_YMM9I0
= 468,
861 CV_AMD64_YMM9I1
= 469,
862 CV_AMD64_YMM9I2
= 470,
863 CV_AMD64_YMM9I3
= 471,
864 CV_AMD64_YMM10I0
= 472,
865 CV_AMD64_YMM10I1
= 473,
866 CV_AMD64_YMM10I2
= 474,
867 CV_AMD64_YMM10I3
= 475,
868 CV_AMD64_YMM11I0
= 476,
869 CV_AMD64_YMM11I1
= 477,
870 CV_AMD64_YMM11I2
= 478,
871 CV_AMD64_YMM11I3
= 479,
872 CV_AMD64_YMM12I0
= 480,
873 CV_AMD64_YMM12I1
= 481,
874 CV_AMD64_YMM12I2
= 482,
875 CV_AMD64_YMM12I3
= 483,
876 CV_AMD64_YMM13I0
= 484,
877 CV_AMD64_YMM13I1
= 485,
878 CV_AMD64_YMM13I2
= 486,
879 CV_AMD64_YMM13I3
= 487,
880 CV_AMD64_YMM14I0
= 488,
881 CV_AMD64_YMM14I1
= 489,
882 CV_AMD64_YMM14I2
= 490,
883 CV_AMD64_YMM14I3
= 491,
884 CV_AMD64_YMM15I0
= 492,
885 CV_AMD64_YMM15I1
= 493,
886 CV_AMD64_YMM15I2
= 494,
887 CV_AMD64_YMM15I3
= 495,
888 CV_AMD64_YMM0F0
= 496,
889 CV_AMD64_YMM0F1
= 497,
890 CV_AMD64_YMM0F2
= 498,
891 CV_AMD64_YMM0F3
= 499,
892 CV_AMD64_YMM0F4
= 500,
893 CV_AMD64_YMM0F5
= 501,
894 CV_AMD64_YMM0F6
= 502,
895 CV_AMD64_YMM0F7
= 503,
896 CV_AMD64_YMM1F0
= 504,
897 CV_AMD64_YMM1F1
= 505,
898 CV_AMD64_YMM1F2
= 506,
899 CV_AMD64_YMM1F3
= 507,
900 CV_AMD64_YMM1F4
= 508,
901 CV_AMD64_YMM1F5
= 509,
902 CV_AMD64_YMM1F6
= 510,
903 CV_AMD64_YMM1F7
= 511,
904 CV_AMD64_YMM2F0
= 512,
905 CV_AMD64_YMM2F1
= 513,
906 CV_AMD64_YMM2F2
= 514,
907 CV_AMD64_YMM2F3
= 515,
908 CV_AMD64_YMM2F4
= 516,
909 CV_AMD64_YMM2F5
= 517,
910 CV_AMD64_YMM2F6
= 518,
911 CV_AMD64_YMM2F7
= 519,
912 CV_AMD64_YMM3F0
= 520,
913 CV_AMD64_YMM3F1
= 521,
914 CV_AMD64_YMM3F2
= 522,
915 CV_AMD64_YMM3F3
= 523,
916 CV_AMD64_YMM3F4
= 524,
917 CV_AMD64_YMM3F5
= 525,
918 CV_AMD64_YMM3F6
= 526,
919 CV_AMD64_YMM3F7
= 527,
920 CV_AMD64_YMM4F0
= 528,
921 CV_AMD64_YMM4F1
= 529,
922 CV_AMD64_YMM4F2
= 530,
923 CV_AMD64_YMM4F3
= 531,
924 CV_AMD64_YMM4F4
= 532,
925 CV_AMD64_YMM4F5
= 533,
926 CV_AMD64_YMM4F6
= 534,
927 CV_AMD64_YMM4F7
= 535,
928 CV_AMD64_YMM5F0
= 536,
929 CV_AMD64_YMM5F1
= 537,
930 CV_AMD64_YMM5F2
= 538,
931 CV_AMD64_YMM5F3
= 539,
932 CV_AMD64_YMM5F4
= 540,
933 CV_AMD64_YMM5F5
= 541,
934 CV_AMD64_YMM5F6
= 542,
935 CV_AMD64_YMM5F7
= 543,
936 CV_AMD64_YMM6F0
= 544,
937 CV_AMD64_YMM6F1
= 545,
938 CV_AMD64_YMM6F2
= 546,
939 CV_AMD64_YMM6F3
= 547,
940 CV_AMD64_YMM6F4
= 548,
941 CV_AMD64_YMM6F5
= 549,
942 CV_AMD64_YMM6F6
= 550,
943 CV_AMD64_YMM6F7
= 551,
944 CV_AMD64_YMM7F0
= 552,
945 CV_AMD64_YMM7F1
= 553,
946 CV_AMD64_YMM7F2
= 554,
947 CV_AMD64_YMM7F3
= 555,
948 CV_AMD64_YMM7F4
= 556,
949 CV_AMD64_YMM7F5
= 557,
950 CV_AMD64_YMM7F6
= 558,
951 CV_AMD64_YMM7F7
= 559,
952 CV_AMD64_YMM8F0
= 560,
953 CV_AMD64_YMM8F1
= 561,
954 CV_AMD64_YMM8F2
= 562,
955 CV_AMD64_YMM8F3
= 563,
956 CV_AMD64_YMM8F4
= 564,
957 CV_AMD64_YMM8F5
= 565,
958 CV_AMD64_YMM8F6
= 566,
959 CV_AMD64_YMM8F7
= 567,
960 CV_AMD64_YMM9F0
= 568,
961 CV_AMD64_YMM9F1
= 569,
962 CV_AMD64_YMM9F2
= 570,
963 CV_AMD64_YMM9F3
= 571,
964 CV_AMD64_YMM9F4
= 572,
965 CV_AMD64_YMM9F5
= 573,
966 CV_AMD64_YMM9F6
= 574,
967 CV_AMD64_YMM9F7
= 575,
968 CV_AMD64_YMM10F0
= 576,
969 CV_AMD64_YMM10F1
= 577,
970 CV_AMD64_YMM10F2
= 578,
971 CV_AMD64_YMM10F3
= 579,
972 CV_AMD64_YMM10F4
= 580,
973 CV_AMD64_YMM10F5
= 581,
974 CV_AMD64_YMM10F6
= 582,
975 CV_AMD64_YMM10F7
= 583,
976 CV_AMD64_YMM11F0
= 584,
977 CV_AMD64_YMM11F1
= 585,
978 CV_AMD64_YMM11F2
= 586,
979 CV_AMD64_YMM11F3
= 587,
980 CV_AMD64_YMM11F4
= 588,
981 CV_AMD64_YMM11F5
= 589,
982 CV_AMD64_YMM11F6
= 590,
983 CV_AMD64_YMM11F7
= 591,
984 CV_AMD64_YMM12F0
= 592,
985 CV_AMD64_YMM12F1
= 593,
986 CV_AMD64_YMM12F2
= 594,
987 CV_AMD64_YMM12F3
= 595,
988 CV_AMD64_YMM12F4
= 596,
989 CV_AMD64_YMM12F5
= 597,
990 CV_AMD64_YMM12F6
= 598,
991 CV_AMD64_YMM12F7
= 599,
992 CV_AMD64_YMM13F0
= 600,
993 CV_AMD64_YMM13F1
= 601,
994 CV_AMD64_YMM13F2
= 602,
995 CV_AMD64_YMM13F3
= 603,
996 CV_AMD64_YMM13F4
= 604,
997 CV_AMD64_YMM13F5
= 605,
998 CV_AMD64_YMM13F6
= 606,
999 CV_AMD64_YMM13F7
= 607,
1000 CV_AMD64_YMM14F0
= 608,
1001 CV_AMD64_YMM14F1
= 609,
1002 CV_AMD64_YMM14F2
= 610,
1003 CV_AMD64_YMM14F3
= 611,
1004 CV_AMD64_YMM14F4
= 612,
1005 CV_AMD64_YMM14F5
= 613,
1006 CV_AMD64_YMM14F6
= 614,
1007 CV_AMD64_YMM14F7
= 615,
1008 CV_AMD64_YMM15F0
= 616,
1009 CV_AMD64_YMM15F1
= 617,
1010 CV_AMD64_YMM15F2
= 618,
1011 CV_AMD64_YMM15F3
= 619,
1012 CV_AMD64_YMM15F4
= 620,
1013 CV_AMD64_YMM15F5
= 621,
1014 CV_AMD64_YMM15F6
= 622,
1015 CV_AMD64_YMM15F7
= 623,
1016 CV_AMD64_YMM0D0
= 624,
1017 CV_AMD64_YMM0D1
= 625,
1018 CV_AMD64_YMM0D2
= 626,
1019 CV_AMD64_YMM0D3
= 627,
1020 CV_AMD64_YMM1D0
= 628,
1021 CV_AMD64_YMM1D1
= 629,
1022 CV_AMD64_YMM1D2
= 630,
1023 CV_AMD64_YMM1D3
= 631,
1024 CV_AMD64_YMM2D0
= 632,
1025 CV_AMD64_YMM2D1
= 633,
1026 CV_AMD64_YMM2D2
= 634,
1027 CV_AMD64_YMM2D3
= 635,
1028 CV_AMD64_YMM3D0
= 636,
1029 CV_AMD64_YMM3D1
= 637,
1030 CV_AMD64_YMM3D2
= 638,
1031 CV_AMD64_YMM3D3
= 639,
1032 CV_AMD64_YMM4D0
= 640,
1033 CV_AMD64_YMM4D1
= 641,
1034 CV_AMD64_YMM4D2
= 642,
1035 CV_AMD64_YMM4D3
= 643,
1036 CV_AMD64_YMM5D0
= 644,
1037 CV_AMD64_YMM5D1
= 645,
1038 CV_AMD64_YMM5D2
= 646,
1039 CV_AMD64_YMM5D3
= 647,
1040 CV_AMD64_YMM6D0
= 648,
1041 CV_AMD64_YMM6D1
= 649,
1042 CV_AMD64_YMM6D2
= 650,
1043 CV_AMD64_YMM6D3
= 651,
1044 CV_AMD64_YMM7D0
= 652,
1045 CV_AMD64_YMM7D1
= 653,
1046 CV_AMD64_YMM7D2
= 654,
1047 CV_AMD64_YMM7D3
= 655,
1048 CV_AMD64_YMM8D0
= 656,
1049 CV_AMD64_YMM8D1
= 657,
1050 CV_AMD64_YMM8D2
= 658,
1051 CV_AMD64_YMM8D3
= 659,
1052 CV_AMD64_YMM9D0
= 660,
1053 CV_AMD64_YMM9D1
= 661,
1054 CV_AMD64_YMM9D2
= 662,
1055 CV_AMD64_YMM9D3
= 663,
1056 CV_AMD64_YMM10D0
= 664,
1057 CV_AMD64_YMM10D1
= 665,
1058 CV_AMD64_YMM10D2
= 666,
1059 CV_AMD64_YMM10D3
= 667,
1060 CV_AMD64_YMM11D0
= 668,
1061 CV_AMD64_YMM11D1
= 669,
1062 CV_AMD64_YMM11D2
= 670,
1063 CV_AMD64_YMM11D3
= 671,
1064 CV_AMD64_YMM12D0
= 672,
1065 CV_AMD64_YMM12D1
= 673,
1066 CV_AMD64_YMM12D2
= 674,
1067 CV_AMD64_YMM12D3
= 675,
1068 CV_AMD64_YMM13D0
= 676,
1069 CV_AMD64_YMM13D1
= 677,
1070 CV_AMD64_YMM13D2
= 678,
1071 CV_AMD64_YMM13D3
= 679,
1072 CV_AMD64_YMM14D0
= 680,
1073 CV_AMD64_YMM14D1
= 681,
1074 CV_AMD64_YMM14D2
= 682,
1075 CV_AMD64_YMM14D3
= 683,
1076 CV_AMD64_YMM15D0
= 684,
1077 CV_AMD64_YMM15D1
= 685,
1078 CV_AMD64_YMM15D2
= 686,
1079 CV_AMD64_YMM15D3
= 687
1082 struct codeview_string
1084 codeview_string
*next
;
1089 struct string_hasher
: free_ptr_hash
<struct codeview_string
>
1091 typedef const char *compare_type
;
1093 static hashval_t
hash (const codeview_string
*x
)
1095 return htab_hash_string (x
->string
);
1098 static bool equal (const codeview_string
*x
, const char *y
)
1100 return !strcmp (x
->string
, y
);
1103 static void mark_empty (codeview_string
*x
)
1112 static void remove (codeview_string
*&x
)
1118 struct codeview_source_file
1120 codeview_source_file
*next
;
1121 unsigned int file_num
;
1122 uint32_t string_offset
;
1124 uint8_t hash
[HASH_SIZE
];
1127 struct codeview_line
1129 codeview_line
*next
;
1130 unsigned int line_no
;
1131 unsigned int label_num
;
1134 struct codeview_line_block
1136 codeview_line_block
*next
;
1138 unsigned int num_lines
;
1139 codeview_line
*lines
, *last_line
;
1142 struct codeview_function
1144 codeview_function
*next
;
1146 unsigned int end_label
;
1147 codeview_line_block
*blocks
, *last_block
;
1150 struct codeview_symbol
1152 codeview_symbol
*next
;
1153 enum cv_sym_type kind
;
1176 struct codeview_type
1183 struct die_hasher
: free_ptr_hash
<codeview_type
>
1185 typedef dw_die_ref compare_type
;
1187 static hashval_t
hash (const codeview_type
*x
)
1189 return htab_hash_pointer (x
->die
);
1192 static bool equal (const codeview_type
*x
, const dw_die_ref y
)
1198 struct codeview_integer
1204 struct codeview_subtype
1206 struct codeview_subtype
*next
;
1207 enum cv_leaf_type kind
;
1214 struct codeview_integer value
;
1222 uint16_t attributes
;
1224 codeview_integer offset
;
1229 uint16_t attributes
;
1235 uint16_t method_attribute
;
1236 uint32_t method_type
;
1242 uint32_t method_list
;
1248 struct lf_methodlist_entry
1250 uint16_t method_attribute
;
1251 uint32_t method_type
;
1254 struct codeview_custom_type
1256 struct codeview_custom_type
*next
;
1258 enum cv_leaf_type kind
;
1265 uint32_t attributes
;
1275 codeview_subtype
*subtypes
;
1276 codeview_subtype
*last_subtype
;
1281 uint16_t properties
;
1282 uint32_t underlying_type
;
1288 uint16_t num_members
;
1289 uint16_t properties
;
1290 uint32_t field_list
;
1291 uint32_t derived_from
;
1293 codeview_integer length
;
1298 uint32_t element_type
;
1299 uint32_t index_type
;
1300 codeview_integer length_in_bytes
;
1310 uint32_t return_type
;
1311 uint8_t calling_convention
;
1313 uint16_t num_parameters
;
1318 uint32_t num_entries
;
1323 uint32_t parent_scope
;
1324 uint32_t function_type
;
1329 uint32_t parent_type
;
1330 uint32_t function_type
;
1340 uint32_t return_type
;
1341 uint32_t containing_class_type
;
1343 uint8_t calling_convention
;
1345 uint16_t num_parameters
;
1347 int32_t this_adjustment
;
1352 lf_methodlist_entry
*entries
;
1357 struct codeview_deferred_type
1359 struct codeview_deferred_type
*next
;
1363 struct string_id_hasher
: nofree_ptr_hash
<struct codeview_custom_type
>
1365 typedef const char *compare_type
;
1367 static hashval_t
hash (const codeview_custom_type
*x
)
1369 return htab_hash_string (x
->lf_string_id
.string
);
1372 static bool equal (const codeview_custom_type
*x
, const char *y
)
1374 return !strcmp (x
->lf_string_id
.string
, y
);
1378 struct codeview_method
1384 struct codeview_method
*next
;
1385 struct codeview_method
*last
;
1388 struct method_hasher
: nofree_ptr_hash
<struct codeview_method
>
1390 typedef const char *compare_type
;
1392 static hashval_t
hash (const codeview_method
*x
)
1394 return htab_hash_string (x
->name
);
1397 static bool equal (const codeview_method
*x
, const char *y
)
1399 return !strcmp (x
->name
, y
);
1403 static unsigned int line_label_num
;
1404 static unsigned int func_label_num
;
1405 static unsigned int sym_label_num
;
1406 static codeview_source_file
*files
, *last_file
;
1407 static unsigned int num_files
;
1408 static uint32_t string_offset
= 1;
1409 static hash_table
<string_hasher
> *strings_htab
;
1410 static codeview_string
*strings
, *last_string
;
1411 static codeview_function
*funcs
, *last_func
;
1412 static const char* last_filename
;
1413 static uint32_t last_file_id
;
1414 static codeview_symbol
*sym
, *last_sym
;
1415 static hash_table
<die_hasher
> *types_htab
;
1416 static codeview_custom_type
*custom_types
, *last_custom_type
;
1417 static codeview_deferred_type
*deferred_types
, *last_deferred_type
;
1418 static hash_table
<string_id_hasher
> *string_id_htab
;
1420 static uint32_t get_type_num (dw_die_ref type
, bool in_struct
, bool no_fwd_ref
);
1421 static uint32_t get_type_num_subroutine_type (dw_die_ref type
, bool in_struct
,
1422 uint32_t containing_class_type
,
1424 int32_t this_adjustment
);
1426 /* Record new line number against the current function. */
1429 codeview_source_line (unsigned int line_no
, const char *filename
)
1432 uint32_t file_id
= last_file_id
;
1433 unsigned int label_num
= ++line_label_num
;
1435 targetm
.asm_out
.internal_label (asm_out_file
, LINE_LABEL
, label_num
);
1437 if (!last_func
|| last_func
->func
!= cfun
)
1439 codeview_function
*f
= (codeview_function
*)
1440 xmalloc (sizeof (codeview_function
));
1445 f
->blocks
= f
->last_block
= NULL
;
1450 last_func
->next
= f
;
1455 if (filename
!= last_filename
)
1457 codeview_source_file
*sf
= files
;
1461 if (!strcmp (sf
->filename
, filename
))
1463 /* 0x18 is the size of the checksum entry for each file.
1464 0x6 bytes for the header, plus 0x10 bytes for the hash,
1465 then padded to a multiple of 4. */
1467 file_id
= sf
->file_num
* 0x18;
1468 last_filename
= filename
;
1469 last_file_id
= file_id
;
1477 if (!last_func
->last_block
|| last_func
->last_block
->file_id
!= file_id
)
1479 codeview_line_block
*b
;
1481 b
= (codeview_line_block
*) xmalloc (sizeof (codeview_line_block
));
1484 b
->file_id
= file_id
;
1486 b
->lines
= b
->last_line
= NULL
;
1488 if (!last_func
->blocks
)
1489 last_func
->blocks
= b
;
1491 last_func
->last_block
->next
= b
;
1493 last_func
->last_block
= b
;
1496 if (last_func
->last_block
->last_line
1497 && last_func
->last_block
->last_line
->line_no
== line_no
)
1500 l
= (codeview_line
*) xmalloc (sizeof (codeview_line
));
1503 l
->line_no
= line_no
;
1504 l
->label_num
= label_num
;
1506 if (!last_func
->last_block
->lines
)
1507 last_func
->last_block
->lines
= l
;
1509 last_func
->last_block
->last_line
->next
= l
;
1511 last_func
->last_block
->last_line
= l
;
1512 last_func
->last_block
->num_lines
++;
1515 /* Adds string to the string table, returning its offset. If already present,
1516 this returns the offset of the existing string. */
1519 add_string (const char *string
)
1521 codeview_string
**slot
;
1526 strings_htab
= new hash_table
<string_hasher
> (10);
1528 slot
= strings_htab
->find_slot_with_hash (string
, htab_hash_string (string
),
1532 return (*slot
)->offset
;
1534 s
= (codeview_string
*) xmalloc (sizeof (codeview_string
));
1535 len
= strlen (string
);
1539 s
->offset
= string_offset
;
1540 string_offset
+= len
+ 1;
1542 s
->string
= xstrdup (string
);
1545 last_string
->next
= s
;
1556 /* A new source file has been encountered - record the details and calculate
1560 codeview_start_source_file (const char *filename
)
1562 codeview_source_file
*sf
;
1564 uint32_t string_offset
;
1567 path
= lrealpath (filename
);
1568 string_offset
= add_string (path
);
1574 if (sf
->string_offset
== string_offset
)
1580 sf
= (codeview_source_file
*) xmalloc (sizeof (codeview_source_file
));
1582 sf
->file_num
= num_files
;
1583 sf
->string_offset
= string_offset
;
1584 sf
->filename
= xstrdup (filename
);
1586 f
= fopen (filename
, "r");
1588 internal_error ("could not open %s for reading", filename
);
1590 if (md5_stream (f
, sf
->hash
))
1593 internal_error ("md5_stream failed");
1599 last_file
->next
= sf
;
1607 /* Write out the strings table into the .debug$S section. The linker will
1608 parse this, and handle the deduplication and hashing for all the object
1612 write_strings_table (void)
1614 codeview_string
*string
;
1616 fputs (integer_asm_op (4, false), asm_out_file
);
1617 fprint_whex (asm_out_file
, DEBUG_S_STRINGTABLE
);
1618 putc ('\n', asm_out_file
);
1620 fputs (integer_asm_op (4, false), asm_out_file
);
1621 asm_fprintf (asm_out_file
, "%LLcv_strings_end - %LLcv_strings_start\n");
1623 asm_fprintf (asm_out_file
, "%LLcv_strings_start:\n");
1625 /* The first entry is always an empty string. */
1626 fputs (integer_asm_op (1, false), asm_out_file
);
1627 fprint_whex (asm_out_file
, 0);
1628 putc ('\n', asm_out_file
);
1633 ASM_OUTPUT_ASCII (asm_out_file
, string
->string
,
1634 strlen (string
->string
) + 1);
1636 string
= string
->next
;
1639 delete strings_htab
;
1641 asm_fprintf (asm_out_file
, "%LLcv_strings_end:\n");
1643 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
1646 /* Write out the file checksums data into the .debug$S section. */
1649 write_source_files (void)
1651 fputs (integer_asm_op (4, false), asm_out_file
);
1652 fprint_whex (asm_out_file
, DEBUG_S_FILECHKSMS
);
1653 putc ('\n', asm_out_file
);
1655 fputs (integer_asm_op (4, false), asm_out_file
);
1656 asm_fprintf (asm_out_file
,
1657 "%LLcv_filechksms_end - %LLcv_filechksms_start\n");
1659 asm_fprintf (asm_out_file
, "%LLcv_filechksms_start:\n");
1663 codeview_source_file
*next
= files
->next
;
1665 /* This is struct file_checksum in binutils, or filedata in Microsoft's
1668 struct file_checksum
1671 uint8_t checksum_length;
1672 uint8_t checksum_type;
1675 followed then by the bytes of the hash, padded to the next 4 bytes.
1676 file_id here is actually the offset in the strings table. */
1678 fputs (integer_asm_op (4, false), asm_out_file
);
1679 fprint_whex (asm_out_file
, files
->string_offset
);
1680 putc ('\n', asm_out_file
);
1682 fputs (integer_asm_op (1, false), asm_out_file
);
1683 fprint_whex (asm_out_file
, HASH_SIZE
);
1684 putc ('\n', asm_out_file
);
1686 fputs (integer_asm_op (1, false), asm_out_file
);
1687 fprint_whex (asm_out_file
, CHKSUM_TYPE_MD5
);
1688 putc ('\n', asm_out_file
);
1690 for (unsigned int i
= 0; i
< HASH_SIZE
; i
++)
1692 fputs (integer_asm_op (1, false), asm_out_file
);
1693 fprint_whex (asm_out_file
, files
->hash
[i
]);
1694 putc ('\n', asm_out_file
);
1697 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
1699 free (files
->filename
);
1705 asm_fprintf (asm_out_file
, "%LLcv_filechksms_end:\n");
1708 /* Write out the line number information for each function into the
1709 .debug$S section. */
1712 write_line_numbers (void)
1714 unsigned int func_num
= 0;
1718 codeview_function
*next
= funcs
->next
;
1719 unsigned int first_label_num
;
1721 fputs (integer_asm_op (4, false), asm_out_file
);
1722 fprint_whex (asm_out_file
, DEBUG_S_LINES
);
1723 putc ('\n', asm_out_file
);
1725 fputs (integer_asm_op (4, false), asm_out_file
);
1726 asm_fprintf (asm_out_file
, "%LLcv_lines%u_end - %LLcv_lines%u_start\n",
1727 func_num
, func_num
);
1729 asm_fprintf (asm_out_file
, "%LLcv_lines%u_start:\n", func_num
);
1731 /* Output the header (struct cv_lines_header in binutils or
1732 CV_DebugSLinesHeader_t in Microsoft's cvinfo.h):
1734 struct cv_lines_header
1743 asm_fprintf (asm_out_file
, "\t.secrel32\t%L" LINE_LABEL
"%u\n",
1744 funcs
->blocks
->lines
->label_num
);
1745 asm_fprintf (asm_out_file
, "\t.secidx\t%L" LINE_LABEL
"%u\n",
1746 funcs
->blocks
->lines
->label_num
);
1749 fputs (integer_asm_op (2, false), asm_out_file
);
1750 fprint_whex (asm_out_file
, 0);
1751 putc ('\n', asm_out_file
);
1753 first_label_num
= funcs
->blocks
->lines
->label_num
;
1756 fputs (integer_asm_op (4, false), asm_out_file
);
1757 asm_fprintf (asm_out_file
,
1758 "%L" END_FUNC_LABEL
"%u - %L" LINE_LABEL
"%u\n",
1759 funcs
->end_label
, first_label_num
);
1761 while (funcs
->blocks
)
1763 codeview_line_block
*next
= funcs
->blocks
->next
;
1765 /* Next comes the blocks, each block being a part of a function
1766 within the same source file (struct cv_lines_block in binutils or
1767 CV_DebugSLinesFileBlockHeader_t in Microsoft's cvinfo.h):
1769 struct cv_lines_block
1778 fputs (integer_asm_op (4, false), asm_out_file
);
1779 fprint_whex (asm_out_file
, funcs
->blocks
->file_id
);
1780 putc ('\n', asm_out_file
);
1782 /* number of lines */
1783 fputs (integer_asm_op (4, false), asm_out_file
);
1784 fprint_whex (asm_out_file
, funcs
->blocks
->num_lines
);
1785 putc ('\n', asm_out_file
);
1787 /* length of code block: (num_lines * sizeof (struct cv_line)) +
1788 sizeof (struct cv_lines_block) */
1789 fputs (integer_asm_op (4, false), asm_out_file
);
1790 fprint_whex (asm_out_file
, (funcs
->blocks
->num_lines
* 0x8) + 0xc);
1791 putc ('\n', asm_out_file
);
1793 while (funcs
->blocks
->lines
)
1795 codeview_line
*next
= funcs
->blocks
->lines
->next
;
1797 /* Finally comes the line number information (struct cv_line in
1798 binutils or CV_Line_t in Microsoft's cvinfo.h):
1806 Strictly speaking line_no is a bitfield: the bottom 24 bits
1807 are the line number, and the top bit means "is a statement".
1810 fputs (integer_asm_op (4, false), asm_out_file
);
1811 asm_fprintf (asm_out_file
,
1812 "%L" LINE_LABEL
"%u - %L" LINE_LABEL
"%u\n",
1813 funcs
->blocks
->lines
->label_num
, first_label_num
);
1815 fputs (integer_asm_op (4, false), asm_out_file
);
1816 fprint_whex (asm_out_file
,
1818 | (funcs
->blocks
->lines
->line_no
& 0xffffff));
1819 putc ('\n', asm_out_file
);
1821 free (funcs
->blocks
->lines
);
1823 funcs
->blocks
->lines
= next
;
1826 free (funcs
->blocks
);
1828 funcs
->blocks
= next
;
1833 asm_fprintf (asm_out_file
, "%LLcv_lines%u_end:\n", func_num
);
1840 /* Treat cold sections as separate functions, for the purposes of line
1844 codeview_switch_text_section (void)
1846 codeview_function
*f
;
1848 if (last_func
&& last_func
->end_label
== 0)
1850 unsigned int label_num
= ++func_label_num
;
1852 targetm
.asm_out
.internal_label (asm_out_file
, END_FUNC_LABEL
,
1855 last_func
->end_label
= label_num
;
1858 f
= (codeview_function
*) xmalloc (sizeof (codeview_function
));
1863 f
->blocks
= f
->last_block
= NULL
;
1868 last_func
->next
= f
;
1873 /* Mark the end of the current function. */
1876 codeview_end_epilogue (void)
1878 if (last_func
&& last_func
->end_label
== 0)
1880 unsigned int label_num
= ++func_label_num
;
1882 targetm
.asm_out
.internal_label (asm_out_file
, END_FUNC_LABEL
,
1885 last_func
->end_label
= label_num
;
1889 /* Return the CodeView constant for the selected architecture. */
1892 target_processor (void)
1897 return CV_CFL_80386
;
1900 /* Return the CodeView constant for the language being used. */
1903 language_constant (void)
1905 const char *language_string
= lang_hooks
.name
;
1907 if (startswith (language_string
, "GNU C++"))
1909 else if (startswith (language_string
, "GNU C"))
1915 /* Write a S_COMPILE3 symbol, which records the details of the compiler
1919 write_compile3_symbol (void)
1921 unsigned int label_num
= ++sym_label_num
;
1923 static const char compiler_name
[] = "GCC ";
1925 /* This is struct COMPILESYM3 in binutils and Microsoft's cvinfo.h:
1933 uint16_t frontend_major;
1934 uint16_t frontend_minor;
1935 uint16_t frontend_build;
1936 uint16_t frontend_qfe;
1937 uint16_t backend_major;
1938 uint16_t backend_minor;
1939 uint16_t backend_build;
1940 uint16_t backend_qfe;
1944 fputs (integer_asm_op (2, false), asm_out_file
);
1945 asm_fprintf (asm_out_file
,
1946 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
1947 label_num
, label_num
);
1949 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
1951 fputs (integer_asm_op (2, false), asm_out_file
);
1952 fprint_whex (asm_out_file
, S_COMPILE3
);
1953 putc ('\n', asm_out_file
);
1955 /* Microsoft has the flags as a bitfield, with the bottom 8 bits being the
1956 language constant, and the reset being MSVC-specific stuff. */
1957 fputs (integer_asm_op (4, false), asm_out_file
);
1958 fprint_whex (asm_out_file
, language_constant ());
1959 putc ('\n', asm_out_file
);
1961 fputs (integer_asm_op (2, false), asm_out_file
);
1962 fprint_whex (asm_out_file
, target_processor ());
1963 putc ('\n', asm_out_file
);
1965 /* Write 8 uint16_ts for the frontend and backend versions. As with GAS, we
1966 zero these, as it's easier to record the version in the compiler
1968 for (unsigned int i
= 0; i
< 8; i
++)
1970 fputs (integer_asm_op (2, false), asm_out_file
);
1971 fprint_whex (asm_out_file
, 0);
1972 putc ('\n', asm_out_file
);
1975 ASM_OUTPUT_ASCII (asm_out_file
, compiler_name
, sizeof (compiler_name
) - 1);
1976 ASM_OUTPUT_ASCII (asm_out_file
, version_string
, strlen (version_string
) + 1);
1978 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
1980 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
1983 /* Write an S_GDATA32 symbol, representing a global variable, or an S_LDATA32
1984 symbol, for a static global variable. */
1987 write_data_symbol (codeview_symbol
*s
)
1989 unsigned int label_num
= ++sym_label_num
;
1991 dw_loc_descr_ref loc_ref
;
1993 /* This is struct datasym in binutils:
2006 /* Extract the DW_AT_location attribute from the DIE, and make sure it's in
2007 in a format we can parse. */
2009 loc
= get_AT (s
->data_symbol
.die
, DW_AT_location
);
2013 if (loc
->dw_attr_val
.val_class
!= dw_val_class_loc
)
2016 loc_ref
= loc
->dw_attr_val
.v
.val_loc
;
2017 if (!loc_ref
|| loc_ref
->dw_loc_opc
!= DW_OP_addr
)
2020 /* Output the S_GDATA32 / S_LDATA32 record. */
2022 fputs (integer_asm_op (2, false), asm_out_file
);
2023 asm_fprintf (asm_out_file
,
2024 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2025 label_num
, label_num
);
2027 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2029 fputs (integer_asm_op (2, false), asm_out_file
);
2030 fprint_whex (asm_out_file
, s
->kind
);
2031 putc ('\n', asm_out_file
);
2033 fputs (integer_asm_op (4, false), asm_out_file
);
2034 fprint_whex (asm_out_file
, s
->data_symbol
.type
);
2035 putc ('\n', asm_out_file
);
2037 asm_fprintf (asm_out_file
, "\t.secrel32 ");
2038 output_addr_const (asm_out_file
, loc_ref
->dw_loc_oprnd1
.v
.val_addr
);
2039 fputc ('\n', asm_out_file
);
2041 asm_fprintf (asm_out_file
, "\t.secidx ");
2042 output_addr_const (asm_out_file
, loc_ref
->dw_loc_oprnd1
.v
.val_addr
);
2043 fputc ('\n', asm_out_file
);
2045 ASM_OUTPUT_ASCII (asm_out_file
, s
->data_symbol
.name
,
2046 strlen (s
->data_symbol
.name
) + 1);
2048 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2050 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2053 free (s
->data_symbol
.name
);
2056 /* Write an S_LOCAL symbol, representing an optimized variable. This is then
2057 followed by various S_DEFRANGE_* symbols, which describe how to find the
2058 value of a variable and the range for which this is valid. */
2061 write_s_local (dw_die_ref die
)
2063 unsigned int label_num
= ++sym_label_num
;
2064 const char *name
= get_AT_string (die
, DW_AT_name
);
2067 /* This is struct LOCALSYM in Microsoft's cvinfo.h:
2078 fputs (integer_asm_op (2, false), asm_out_file
);
2079 asm_fprintf (asm_out_file
,
2080 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2081 label_num
, label_num
);
2083 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2085 fputs (integer_asm_op (2, false), asm_out_file
);
2086 fprint_whex (asm_out_file
, S_LOCAL
);
2087 putc ('\n', asm_out_file
);
2089 type
= get_type_num (get_AT_ref (die
, DW_AT_type
), false, false);
2091 fputs (integer_asm_op (4, false), asm_out_file
);
2092 fprint_whex (asm_out_file
, type
);
2093 putc ('\n', asm_out_file
);
2095 fputs (integer_asm_op (2, false), asm_out_file
);
2096 fprint_whex (asm_out_file
, 0);
2097 putc ('\n', asm_out_file
);
2099 ASM_OUTPUT_ASCII (asm_out_file
, name
, strlen (name
) + 1);
2101 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2103 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2106 /* Write an S_LDATA32 symbol, representing a static variable within a function.
2107 This symbol can also appear outside of a function block - see
2108 write_data_symbol. */
2111 write_local_s_ldata32 (dw_die_ref die
, dw_loc_descr_ref loc_ref
)
2113 unsigned int label_num
= ++sym_label_num
;
2114 const char *name
= get_AT_string (die
, DW_AT_name
);
2117 /* This is struct datasym in binutils:
2130 fputs (integer_asm_op (2, false), asm_out_file
);
2131 asm_fprintf (asm_out_file
,
2132 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2133 label_num
, label_num
);
2135 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2137 fputs (integer_asm_op (2, false), asm_out_file
);
2138 fprint_whex (asm_out_file
, S_LDATA32
);
2139 putc ('\n', asm_out_file
);
2141 type
= get_type_num (get_AT_ref (die
, DW_AT_type
), false, false);
2143 fputs (integer_asm_op (4, false), asm_out_file
);
2144 fprint_whex (asm_out_file
, type
);
2145 putc ('\n', asm_out_file
);
2147 asm_fprintf (asm_out_file
, "\t.secrel32 ");
2148 output_addr_const (asm_out_file
, loc_ref
->dw_loc_oprnd1
.v
.val_addr
);
2149 fputc ('\n', asm_out_file
);
2151 asm_fprintf (asm_out_file
, "\t.secidx ");
2152 output_addr_const (asm_out_file
, loc_ref
->dw_loc_oprnd1
.v
.val_addr
);
2153 fputc ('\n', asm_out_file
);
2155 ASM_OUTPUT_ASCII (asm_out_file
, name
, strlen (name
) + 1);
2157 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2159 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2162 /* Try to translate a DWARF register number into its CodeView equivalent. */
2165 dwarf_reg_to_cv (unsigned int regno
)
2167 static const cv_amd64_register amd64_reg_mapping
[] = {
2237 static const cv_x86_register x86_reg_mapping
[] = {
2283 if (regno
< sizeof (amd64_reg_mapping
) / sizeof (*amd64_reg_mapping
))
2284 return amd64_reg_mapping
[regno
];
2286 return CV_AMD64_NOREG
;
2290 if (regno
< sizeof (x86_reg_mapping
) / sizeof (*x86_reg_mapping
))
2291 return x86_reg_mapping
[regno
];
2297 /* Write an S_REGISTER symbol, representing an unoptimized variable that has
2298 been assigned to a register. */
2301 write_s_register (dw_die_ref die
, dw_loc_descr_ref loc_ref
)
2303 unsigned int label_num
= ++sym_label_num
;
2304 const char *name
= get_AT_string (die
, DW_AT_name
);
2308 /* This is struct regsym in binutils and REGSYM in Microsoft's cvinfo.h:
2320 if (loc_ref
->dw_loc_opc
== DW_OP_regx
)
2321 regno
= dwarf_reg_to_cv (loc_ref
->dw_loc_oprnd1
.v
.val_int
);
2323 regno
= dwarf_reg_to_cv (loc_ref
->dw_loc_opc
- DW_OP_reg0
);
2328 fputs (integer_asm_op (2, false), asm_out_file
);
2329 asm_fprintf (asm_out_file
,
2330 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2331 label_num
, label_num
);
2333 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2335 fputs (integer_asm_op (2, false), asm_out_file
);
2336 fprint_whex (asm_out_file
, S_REGISTER
);
2337 putc ('\n', asm_out_file
);
2339 type
= get_type_num (get_AT_ref (die
, DW_AT_type
), false, false);
2341 fputs (integer_asm_op (4, false), asm_out_file
);
2342 fprint_whex (asm_out_file
, type
);
2343 putc ('\n', asm_out_file
);
2345 fputs (integer_asm_op (2, false), asm_out_file
);
2346 fprint_whex (asm_out_file
, regno
);
2347 putc ('\n', asm_out_file
);
2349 ASM_OUTPUT_ASCII (asm_out_file
, name
, strlen (name
) + 1);
2351 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2353 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2356 /* Write an S_REGREL32 symbol in order to represent an unoptimized stack
2357 variable. The memory address is given by a register value plus an offset,
2358 so we need to parse the function's DW_AT_frame_base attribute for this. */
2361 write_fbreg_variable (dw_die_ref die
, dw_loc_descr_ref loc_ref
,
2362 dw_loc_descr_ref fbloc
)
2364 unsigned int label_num
= ++sym_label_num
;
2365 const char *name
= get_AT_string (die
, DW_AT_name
);
2370 /* This is struct regrel in binutils and REGREL32 in Microsoft's cvinfo.h:
2386 if (fbloc
->dw_loc_opc
>= DW_OP_breg0
&& fbloc
->dw_loc_opc
<= DW_OP_breg31
)
2388 regno
= dwarf_reg_to_cv (fbloc
->dw_loc_opc
- DW_OP_breg0
);
2389 offset
= fbloc
->dw_loc_oprnd1
.v
.val_int
;
2391 else if (fbloc
->dw_loc_opc
== DW_OP_bregx
)
2393 regno
= dwarf_reg_to_cv (fbloc
->dw_loc_oprnd1
.v
.val_int
);
2394 offset
= fbloc
->dw_loc_oprnd2
.v
.val_int
;
2401 if (loc_ref
->dw_loc_oprnd1
.val_class
!= dw_val_class_unsigned_const
)
2404 offset
+= loc_ref
->dw_loc_oprnd1
.v
.val_int
;
2406 fputs (integer_asm_op (2, false), asm_out_file
);
2407 asm_fprintf (asm_out_file
,
2408 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2409 label_num
, label_num
);
2411 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2413 fputs (integer_asm_op (2, false), asm_out_file
);
2414 fprint_whex (asm_out_file
, S_REGREL32
);
2415 putc ('\n', asm_out_file
);
2417 fputs (integer_asm_op (4, false), asm_out_file
);
2418 fprint_whex (asm_out_file
, offset
);
2419 putc ('\n', asm_out_file
);
2421 type
= get_type_num (get_AT_ref (die
, DW_AT_type
), false, false);
2423 fputs (integer_asm_op (4, false), asm_out_file
);
2424 fprint_whex (asm_out_file
, type
);
2425 putc ('\n', asm_out_file
);
2427 fputs (integer_asm_op (2, false), asm_out_file
);
2428 fprint_whex (asm_out_file
, regno
);
2429 putc ('\n', asm_out_file
);
2431 ASM_OUTPUT_ASCII (asm_out_file
, name
, strlen (name
) + 1);
2433 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2435 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2438 /* Write an S_DEFRANGE_REGISTER symbol, which describes a range for which an
2439 S_LOCAL variable is held in a certain register. */
2442 write_defrange_register (dw_loc_descr_ref expr
, rtx range_start
, rtx range_end
)
2444 unsigned int label_num
= ++sym_label_num
;
2447 /* This is defrange_register in binutils and DEFRANGESYMREGISTER in
2448 Microsoft's cvinfo.h:
2450 struct lvar_addr_range
2457 struct lvar_addr_gap {
2462 struct defrange_register
2467 uint16_t attributes;
2468 struct lvar_addr_range range;
2469 struct lvar_addr_gap gaps[];
2473 if (expr
->dw_loc_opc
== DW_OP_regx
)
2474 regno
= dwarf_reg_to_cv (expr
->dw_loc_oprnd1
.v
.val_int
);
2476 regno
= dwarf_reg_to_cv (expr
->dw_loc_opc
- DW_OP_reg0
);
2481 fputs (integer_asm_op (2, false), asm_out_file
);
2482 asm_fprintf (asm_out_file
,
2483 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2484 label_num
, label_num
);
2486 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2488 fputs (integer_asm_op (2, false), asm_out_file
);
2489 fprint_whex (asm_out_file
, S_DEFRANGE_REGISTER
);
2490 putc ('\n', asm_out_file
);
2492 fputs (integer_asm_op (2, false), asm_out_file
);
2493 fprint_whex (asm_out_file
, regno
);
2494 putc ('\n', asm_out_file
);
2496 fputs (integer_asm_op (2, false), asm_out_file
);
2497 fprint_whex (asm_out_file
, 0);
2498 putc ('\n', asm_out_file
);
2500 asm_fprintf (asm_out_file
, "\t.secrel32 ");
2501 output_addr_const (asm_out_file
, range_start
);
2502 fputc ('\n', asm_out_file
);
2504 asm_fprintf (asm_out_file
, "\t.secidx ");
2505 output_addr_const (asm_out_file
, range_start
);
2506 fputc ('\n', asm_out_file
);
2508 fputs (integer_asm_op (2, false), asm_out_file
);
2509 output_addr_const (asm_out_file
, range_end
);
2510 fputs (" - ", asm_out_file
);
2511 output_addr_const (asm_out_file
, range_start
);
2512 putc ('\n', asm_out_file
);
2514 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2517 /* Write an S_DEFRANGE_REGISTER_REL symbol, which describes a range for which
2518 an S_LOCAL variable is held in memory given by the value of a certain
2519 register plus an offset. */
2522 write_defrange_register_rel (dw_loc_descr_ref expr
, dw_loc_descr_ref fbloc
,
2523 rtx range_start
, rtx range_end
)
2525 unsigned int label_num
= ++sym_label_num
;
2529 /* This is defrange_register_rel in binutils and DEFRANGESYMREGISTERREL in
2530 Microsoft's cvinfo.h:
2532 struct lvar_addr_range
2539 struct lvar_addr_gap {
2544 struct defrange_register_rel
2549 uint16_t offset_parent;
2550 uint32_t offset_register;
2551 struct lvar_addr_range range;
2552 struct lvar_addr_gap gaps[];
2559 if (fbloc
->dw_loc_opc
>= DW_OP_breg0
&& fbloc
->dw_loc_opc
<= DW_OP_breg31
)
2561 regno
= dwarf_reg_to_cv (fbloc
->dw_loc_opc
- DW_OP_breg0
);
2562 offset
= fbloc
->dw_loc_oprnd1
.v
.val_int
;
2564 else if (fbloc
->dw_loc_opc
== DW_OP_bregx
)
2566 regno
= dwarf_reg_to_cv (fbloc
->dw_loc_oprnd1
.v
.val_int
);
2567 offset
= fbloc
->dw_loc_oprnd2
.v
.val_int
;
2574 if (expr
->dw_loc_oprnd1
.val_class
!= dw_val_class_unsigned_const
)
2577 offset
+= expr
->dw_loc_oprnd1
.v
.val_int
;
2579 fputs (integer_asm_op (2, false), asm_out_file
);
2580 asm_fprintf (asm_out_file
,
2581 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2582 label_num
, label_num
);
2584 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2586 fputs (integer_asm_op (2, false), asm_out_file
);
2587 fprint_whex (asm_out_file
, S_DEFRANGE_REGISTER_REL
);
2588 putc ('\n', asm_out_file
);
2590 fputs (integer_asm_op (2, false), asm_out_file
);
2591 fprint_whex (asm_out_file
, regno
);
2592 putc ('\n', asm_out_file
);
2594 fputs (integer_asm_op (2, false), asm_out_file
);
2595 fprint_whex (asm_out_file
, 0);
2596 putc ('\n', asm_out_file
);
2598 fputs (integer_asm_op (4, false), asm_out_file
);
2599 fprint_whex (asm_out_file
, offset
);
2600 putc ('\n', asm_out_file
);
2602 asm_fprintf (asm_out_file
, "\t.secrel32 ");
2603 output_addr_const (asm_out_file
, range_start
);
2604 fputc ('\n', asm_out_file
);
2606 asm_fprintf (asm_out_file
, "\t.secidx ");
2607 output_addr_const (asm_out_file
, range_start
);
2608 fputc ('\n', asm_out_file
);
2610 fputs (integer_asm_op (2, false), asm_out_file
);
2611 output_addr_const (asm_out_file
, range_end
);
2612 fputs (" - ", asm_out_file
);
2613 output_addr_const (asm_out_file
, range_start
);
2614 putc ('\n', asm_out_file
);
2616 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2619 /* Try to write an S_DEFRANGE_* symbol for the given DWARF location. */
2622 write_optimized_local_variable_loc (dw_loc_descr_ref expr
,
2623 dw_loc_descr_ref fbloc
, rtx range_start
,
2626 if (expr
->dw_loc_next
)
2635 switch (expr
->dw_loc_opc
)
2670 write_defrange_register (expr
, range_start
, range_end
);
2674 write_defrange_register_rel (expr
, fbloc
, range_start
, range_end
);
2682 /* Write an optimized local variable, given by an S_LOCAL symbol followed by
2683 any number of S_DEFRANGE_* symbols. We can't mix and match optimized and
2684 unoptimized variables in the same function, so even if it stays in the same
2685 place for the whole block we need to write an S_LOCAL. */
2688 write_optimized_local_variable (dw_die_ref die
, dw_loc_descr_ref fbloc
,
2689 rtx block_start
, rtx block_end
)
2692 dw_loc_list_ref loc_list
;
2694 loc
= get_AT (die
, DW_AT_location
);
2698 switch (loc
->dw_attr_val
.val_class
)
2700 case dw_val_class_loc_list
:
2701 loc_list
= loc
->dw_attr_val
.v
.val_loc_list
;
2703 write_s_local (die
);
2707 rtx range_start
= NULL
, range_end
= NULL
;
2709 if (loc_list
->begin
)
2710 range_start
= gen_rtx_SYMBOL_REF (Pmode
, loc_list
->begin
);
2713 range_end
= gen_rtx_SYMBOL_REF (Pmode
, loc_list
->end
);
2715 write_optimized_local_variable_loc (loc_list
->expr
, fbloc
,
2716 range_start
, range_end
);
2718 loc_list
= loc_list
->dw_loc_next
;
2722 case dw_val_class_loc
:
2723 write_s_local (die
);
2725 write_optimized_local_variable_loc (loc
->dw_attr_val
.v
.val_loc
, fbloc
,
2726 block_start
, block_end
);
2734 /* Write a symbol representing an unoptimized variable within a function, if
2735 we're able to translate the DIE's DW_AT_location into its CodeView
2739 write_unoptimized_local_variable (dw_die_ref die
, dw_loc_descr_ref fbloc
)
2742 dw_loc_descr_ref loc_ref
;
2744 loc
= get_AT (die
, DW_AT_location
);
2748 if (loc
->dw_attr_val
.val_class
!= dw_val_class_loc
)
2751 loc_ref
= loc
->dw_attr_val
.v
.val_loc
;
2755 switch (loc_ref
->dw_loc_opc
)
2758 write_local_s_ldata32 (die
, loc_ref
);
2794 write_s_register (die
, loc_ref
);
2798 write_fbreg_variable (die
, loc_ref
, fbloc
);
2806 /* Translate a DW_TAG_lexical_block DIE into an S_BLOCK32 symbol, representing
2807 a block within an unoptimized function. Returns false if we're not able
2808 to resolve the location, which will prevent the caller from issuing an
2812 write_s_block32 (dw_die_ref die
)
2814 unsigned int label_num
= ++sym_label_num
;
2815 dw_attr_node
*loc_low
, *loc_high
;
2816 const char *label_low
, *label_high
;
2817 rtx rtx_low
, rtx_high
;
2819 /* This is struct blocksym in binutils and BLOCKSYM32 in Microsoft's
2835 loc_low
= get_AT (die
, DW_AT_low_pc
);
2839 if (loc_low
->dw_attr_val
.val_class
!= dw_val_class_lbl_id
)
2842 label_low
= loc_low
->dw_attr_val
.v
.val_lbl_id
;
2846 rtx_low
= gen_rtx_SYMBOL_REF (Pmode
, label_low
);
2848 loc_high
= get_AT (die
, DW_AT_high_pc
);
2852 if (loc_high
->dw_attr_val
.val_class
!= dw_val_class_high_pc
)
2855 label_high
= loc_high
->dw_attr_val
.v
.val_lbl_id
;
2859 rtx_high
= gen_rtx_SYMBOL_REF (Pmode
, label_high
);
2861 fputs (integer_asm_op (2, false), asm_out_file
);
2862 asm_fprintf (asm_out_file
,
2863 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2864 label_num
, label_num
);
2866 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2868 fputs (integer_asm_op (2, false), asm_out_file
);
2869 fprint_whex (asm_out_file
, S_BLOCK32
);
2870 putc ('\n', asm_out_file
);
2872 /* The parent and end fields get filled in by the linker. */
2874 fputs (integer_asm_op (4, false), asm_out_file
);
2875 fprint_whex (asm_out_file
, 0);
2876 putc ('\n', asm_out_file
);
2878 fputs (integer_asm_op (4, false), asm_out_file
);
2879 fprint_whex (asm_out_file
, 0);
2880 putc ('\n', asm_out_file
);
2882 fputs (integer_asm_op (4, false), asm_out_file
);
2883 output_addr_const (asm_out_file
, rtx_high
);
2884 fputs (" - ", asm_out_file
);
2885 output_addr_const (asm_out_file
, rtx_low
);
2886 putc ('\n', asm_out_file
);
2888 asm_fprintf (asm_out_file
, "\t.secrel32 ");
2889 output_addr_const (asm_out_file
, rtx_low
);
2890 fputc ('\n', asm_out_file
);
2892 asm_fprintf (asm_out_file
, "\t.secidx ");
2893 output_addr_const (asm_out_file
, rtx_low
);
2894 fputc ('\n', asm_out_file
);
2896 ASM_OUTPUT_ASCII (asm_out_file
, "", 1);
2898 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2900 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2905 /* Write an S_END symbol, which is used to finish off a number of different
2906 symbol types. Here we use it to mark the S_BLOCK32 as finished. */
2911 unsigned int label_num
= ++sym_label_num
;
2913 fputs (integer_asm_op (2, false), asm_out_file
);
2914 asm_fprintf (asm_out_file
,
2915 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2916 label_num
, label_num
);
2918 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2920 fputs (integer_asm_op (2, false), asm_out_file
);
2921 fprint_whex (asm_out_file
, S_END
);
2922 putc ('\n', asm_out_file
);
2924 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
2926 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2929 /* Write the S_FRAMEPROC symbol, which is supposed to give information about
2930 the function frame. It doesn't seem to be really used in modern versions of
2931 MSVC, which is why we zero-out everything here. You still need to write it
2932 though, otherwise windbg won't necessarily show all the local variables. */
2935 write_s_frameproc (void)
2937 unsigned int label_num
= ++sym_label_num
;
2939 /* This is struct FRAMEPROCSYM in Microsoft's cvinfo.h:
2945 uint32_t frame_size;
2946 uint32_t padding_size;
2947 uint32_t padding_offset;
2948 uint32_t saved_registers_size;
2949 uint32_t exception_handler_offset;
2950 uint16_t exception_handler_section;
2955 fputs (integer_asm_op (2, false), asm_out_file
);
2956 asm_fprintf (asm_out_file
,
2957 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
2958 label_num
, label_num
);
2960 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
2962 fputs (integer_asm_op (2, false), asm_out_file
);
2963 fprint_whex (asm_out_file
, S_FRAMEPROC
);
2964 putc ('\n', asm_out_file
);
2966 fputs (integer_asm_op (4, false), asm_out_file
);
2967 fprint_whex (asm_out_file
, 0);
2968 putc ('\n', asm_out_file
);
2970 fputs (integer_asm_op (4, false), asm_out_file
);
2971 fprint_whex (asm_out_file
, 0);
2972 putc ('\n', asm_out_file
);
2974 fputs (integer_asm_op (4, false), asm_out_file
);
2975 fprint_whex (asm_out_file
, 0);
2976 putc ('\n', asm_out_file
);
2978 fputs (integer_asm_op (4, false), asm_out_file
);
2979 fprint_whex (asm_out_file
, 0);
2980 putc ('\n', asm_out_file
);
2982 fputs (integer_asm_op (4, false), asm_out_file
);
2983 fprint_whex (asm_out_file
, 0);
2984 putc ('\n', asm_out_file
);
2986 fputs (integer_asm_op (2, false), asm_out_file
);
2987 fprint_whex (asm_out_file
, 0);
2988 putc ('\n', asm_out_file
);
2990 fputs (integer_asm_op (4, false), asm_out_file
);
2991 fprint_whex (asm_out_file
, 0);
2992 putc ('\n', asm_out_file
);
2994 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
2997 /* Loop through the DIEs in an unoptimized function, writing out any variables
2998 or blocks that we encounter. */
3001 write_unoptimized_function_vars (dw_die_ref die
, dw_loc_descr_ref fbloc
)
3003 dw_die_ref first_child
, c
;
3005 first_child
= dw_get_die_child (die
);
3013 c
= dw_get_die_sib (c
);
3015 switch (dw_get_die_tag (c
))
3017 case DW_TAG_formal_parameter
:
3018 case DW_TAG_variable
:
3019 write_unoptimized_local_variable (c
, fbloc
);
3022 case DW_TAG_lexical_block
:
3024 bool block_started
= write_s_block32 (c
);
3026 write_unoptimized_function_vars (c
, fbloc
);
3038 while (c
!= first_child
);
3041 /* Write the variables in an optimized function or block. There's no S_BLOCK32s
3042 here, with the range determining the lifetime of a variable. Unfortunately
3043 for us CodeView is much less expressive than DWARF when it comes to variable
3044 locations, so some degree of "optimized out"s is inevitable. */
3047 write_optimized_function_vars (dw_die_ref die
, dw_loc_descr_ref fbloc
,
3048 rtx block_start
, rtx block_end
)
3050 dw_die_ref first_child
, c
;
3052 first_child
= dw_get_die_child (die
);
3060 c
= dw_get_die_sib (c
);
3062 switch (dw_get_die_tag (c
))
3064 case DW_TAG_formal_parameter
:
3065 case DW_TAG_variable
:
3066 write_optimized_local_variable (c
, fbloc
, block_start
, block_end
);
3069 case DW_TAG_lexical_block
:
3071 dw_attr_node
*loc_low
, *loc_high
;
3072 const char *label_low
, *label_high
;
3073 rtx rtx_low
, rtx_high
;
3075 loc_low
= get_AT (die
, DW_AT_low_pc
);
3079 if (loc_low
->dw_attr_val
.val_class
!= dw_val_class_lbl_id
)
3082 label_low
= loc_low
->dw_attr_val
.v
.val_lbl_id
;
3086 rtx_low
= gen_rtx_SYMBOL_REF (Pmode
, label_low
);
3088 loc_high
= get_AT (die
, DW_AT_high_pc
);
3092 if (loc_high
->dw_attr_val
.val_class
!= dw_val_class_high_pc
)
3095 label_high
= loc_high
->dw_attr_val
.v
.val_lbl_id
;
3099 rtx_high
= gen_rtx_SYMBOL_REF (Pmode
, label_high
);
3101 write_optimized_function_vars (c
, fbloc
, rtx_low
, rtx_high
);
3110 while (c
!= first_child
);
3113 /* There's no way to mark the range of a static local variable in an optimized
3114 function: there's no S_DEFRANGE_* symbol for this, and you can't have
3115 S_BLOCK32 symbols. So instead we have to loop through after the S_FRAMEPROC
3116 has been written, and write the S_LDATA32s at the end. */
3119 write_optimized_static_local_vars (dw_die_ref die
)
3121 dw_die_ref first_child
, c
;
3123 first_child
= dw_get_die_child (die
);
3131 c
= dw_get_die_sib (c
);
3133 switch (dw_get_die_tag (c
))
3135 case DW_TAG_variable
:
3138 dw_loc_descr_ref loc_ref
;
3140 loc
= get_AT (c
, DW_AT_location
);
3144 if (loc
->dw_attr_val
.val_class
!= dw_val_class_loc
)
3147 loc_ref
= loc
->dw_attr_val
.v
.val_loc
;
3151 if (loc_ref
->dw_loc_opc
!= DW_OP_addr
)
3154 write_local_s_ldata32 (c
, loc_ref
);
3158 case DW_TAG_lexical_block
:
3159 write_optimized_static_local_vars (c
);
3166 while (c
!= first_child
);
3169 /* Write an S_GPROC32_ID symbol, representing a global function, or an
3170 S_LPROC32_ID symbol, for a static function. */
3173 write_function (codeview_symbol
*s
)
3175 unsigned int label_num
= ++sym_label_num
;
3176 dw_attr_node
*loc_low
, *loc_high
, *frame_base
;
3177 const char *label_low
, *label_high
;
3178 rtx rtx_low
, rtx_high
;
3179 dw_loc_descr_ref fbloc
= NULL
;
3181 /* This is struct procsym in binutils and PROCSYM32 in Microsoft's cvinfo.h:
3191 uint32_t debug_start;
3201 loc_low
= get_AT (s
->function
.die
, DW_AT_low_pc
);
3205 if (loc_low
->dw_attr_val
.val_class
!= dw_val_class_lbl_id
)
3208 label_low
= loc_low
->dw_attr_val
.v
.val_lbl_id
;
3212 rtx_low
= gen_rtx_SYMBOL_REF (Pmode
, label_low
);
3214 loc_high
= get_AT (s
->function
.die
, DW_AT_high_pc
);
3218 if (loc_high
->dw_attr_val
.val_class
!= dw_val_class_high_pc
)
3221 label_high
= loc_high
->dw_attr_val
.v
.val_lbl_id
;
3225 rtx_high
= gen_rtx_SYMBOL_REF (Pmode
, label_high
);
3227 /* Output the S_GPROC32_ID / S_LPROC32_ID record. */
3229 fputs (integer_asm_op (2, false), asm_out_file
);
3230 asm_fprintf (asm_out_file
,
3231 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
3232 label_num
, label_num
);
3234 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
3236 fputs (integer_asm_op (2, false), asm_out_file
);
3237 fprint_whex (asm_out_file
, s
->kind
);
3238 putc ('\n', asm_out_file
);
3240 fputs (integer_asm_op (4, false), asm_out_file
);
3241 fprint_whex (asm_out_file
, s
->function
.parent
);
3242 putc ('\n', asm_out_file
);
3244 fputs (integer_asm_op (4, false), asm_out_file
);
3245 fprint_whex (asm_out_file
, s
->function
.end
);
3246 putc ('\n', asm_out_file
);
3248 fputs (integer_asm_op (4, false), asm_out_file
);
3249 fprint_whex (asm_out_file
, s
->function
.next
);
3250 putc ('\n', asm_out_file
);
3252 fputs (integer_asm_op (4, false), asm_out_file
);
3253 output_addr_const (asm_out_file
, rtx_high
);
3254 fputs (" - ", asm_out_file
);
3255 output_addr_const (asm_out_file
, rtx_low
);
3256 putc ('\n', asm_out_file
);
3258 /* FIXME - debug_start should be the end of the prologue, and debug_end
3259 the beginning of the epilogue. Do the whole function for
3262 fputs (integer_asm_op (4, false), asm_out_file
);
3263 fprint_whex (asm_out_file
, 0);
3264 putc ('\n', asm_out_file
);
3266 fputs (integer_asm_op (4, false), asm_out_file
);
3267 output_addr_const (asm_out_file
, rtx_high
);
3268 fputs (" - ", asm_out_file
);
3269 output_addr_const (asm_out_file
, rtx_low
);
3270 putc ('\n', asm_out_file
);
3272 fputs (integer_asm_op (4, false), asm_out_file
);
3273 fprint_whex (asm_out_file
, s
->function
.type
);
3274 putc ('\n', asm_out_file
);
3276 asm_fprintf (asm_out_file
, "\t.secrel32 ");
3277 output_addr_const (asm_out_file
, rtx_low
);
3278 fputc ('\n', asm_out_file
);
3280 asm_fprintf (asm_out_file
, "\t.secidx ");
3281 output_addr_const (asm_out_file
, rtx_low
);
3282 fputc ('\n', asm_out_file
);
3284 fputs (integer_asm_op (1, false), asm_out_file
);
3285 fprint_whex (asm_out_file
, s
->function
.flags
);
3286 putc ('\n', asm_out_file
);
3288 ASM_OUTPUT_ASCII (asm_out_file
, s
->function
.name
,
3289 strlen (s
->function
.name
) + 1);
3291 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
3293 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
3295 frame_base
= get_AT (s
->function
.die
, DW_AT_frame_base
);
3297 if (frame_base
&& frame_base
->dw_attr_val
.val_class
== dw_val_class_loc
)
3298 fbloc
= frame_base
->dw_attr_val
.v
.val_loc
;
3300 if (flag_var_tracking
)
3302 write_optimized_function_vars (s
->function
.die
, fbloc
, rtx_low
,
3304 write_s_frameproc ();
3305 write_optimized_static_local_vars (s
->function
.die
);
3309 write_s_frameproc ();
3310 write_unoptimized_function_vars (s
->function
.die
, fbloc
);
3313 /* Output the S_PROC_ID_END record. */
3315 label_num
= ++sym_label_num
;
3317 fputs (integer_asm_op (2, false), asm_out_file
);
3318 asm_fprintf (asm_out_file
,
3319 "%L" SYMBOL_END_LABEL
"%u - %L" SYMBOL_START_LABEL
"%u\n",
3320 label_num
, label_num
);
3322 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_START_LABEL
, label_num
);
3324 fputs (integer_asm_op (2, false), asm_out_file
);
3325 fprint_whex (asm_out_file
, S_PROC_ID_END
);
3326 putc ('\n', asm_out_file
);
3328 targetm
.asm_out
.internal_label (asm_out_file
, SYMBOL_END_LABEL
, label_num
);
3331 free (s
->function
.name
);
3334 /* Write the CodeView symbols into the .debug$S section. */
3337 write_codeview_symbols (void)
3339 fputs (integer_asm_op (4, false), asm_out_file
);
3340 fprint_whex (asm_out_file
, DEBUG_S_SYMBOLS
);
3341 putc ('\n', asm_out_file
);
3343 fputs (integer_asm_op (4, false), asm_out_file
);
3344 asm_fprintf (asm_out_file
, "%LLcv_syms_end - %LLcv_syms_start\n");
3346 asm_fprintf (asm_out_file
, "%LLcv_syms_start:\n");
3348 write_compile3_symbol ();
3352 codeview_symbol
*n
= sym
->next
;
3358 write_data_symbol (sym
);
3362 write_function (sym
);
3372 asm_fprintf (asm_out_file
, "%LLcv_syms_end:\n");
3375 /* Write an LF_POINTER type. */
3378 write_lf_pointer (codeview_custom_type
*t
)
3380 /* This is lf_pointer in binutils and lfPointer in Microsoft's cvinfo.h:
3387 uint32_t attributes;
3391 fputs (integer_asm_op (2, false), asm_out_file
);
3392 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
3395 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
3397 fputs (integer_asm_op (2, false), asm_out_file
);
3398 fprint_whex (asm_out_file
, t
->kind
);
3399 putc ('\n', asm_out_file
);
3401 fputs (integer_asm_op (4, false), asm_out_file
);
3402 fprint_whex (asm_out_file
, t
->lf_pointer
.base_type
);
3403 putc ('\n', asm_out_file
);
3405 fputs (integer_asm_op (4, false), asm_out_file
);
3406 fprint_whex (asm_out_file
, t
->lf_pointer
.attributes
);
3407 putc ('\n', asm_out_file
);
3409 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
3412 /* All CodeView type definitions have to be aligned to a four-byte boundary,
3413 so write some padding bytes if necessary. These have to be specific values:
3414 LF_PAD3, LF_PAD2, LF_PAD1. */
3417 write_cv_padding (size_t padding
)
3419 if (padding
== 4 || padding
== 0)
3424 fputs (integer_asm_op (1, false), asm_out_file
);
3425 fprint_whex (asm_out_file
, LF_PAD3
);
3426 putc ('\n', asm_out_file
);
3431 fputs (integer_asm_op (1, false), asm_out_file
);
3432 fprint_whex (asm_out_file
, LF_PAD2
);
3433 putc ('\n', asm_out_file
);
3436 fputs (integer_asm_op (1, false), asm_out_file
);
3437 fprint_whex (asm_out_file
, LF_PAD1
);
3438 putc ('\n', asm_out_file
);
3441 /* Write an LF_MODIFIER type, representing a const and/or volatile modification
3445 write_lf_modifier (codeview_custom_type
*t
)
3447 /* This is lf_modifier in binutils and lfModifier in Microsoft's cvinfo.h:
3459 fputs (integer_asm_op (2, false), asm_out_file
);
3460 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
3463 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
3465 fputs (integer_asm_op (2, false), asm_out_file
);
3466 fprint_whex (asm_out_file
, t
->kind
);
3467 putc ('\n', asm_out_file
);
3469 fputs (integer_asm_op (4, false), asm_out_file
);
3470 fprint_whex (asm_out_file
, t
->lf_modifier
.base_type
);
3471 putc ('\n', asm_out_file
);
3473 fputs (integer_asm_op (2, false), asm_out_file
);
3474 fprint_whex (asm_out_file
, t
->lf_modifier
.modifier
);
3475 putc ('\n', asm_out_file
);
3477 write_cv_padding (2);
3479 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
3482 /* Write a CodeView extensible integer. If the value is non-negative and
3483 < 0x8000, the value gets written directly as an uint16_t. Otherwise, we
3484 output two bytes for the integer type (LF_CHAR, LF_SHORT, ...), and the
3485 actual value follows. Returns the total number of bytes written. */
3488 write_cv_integer (codeview_integer
*i
)
3494 fputs (integer_asm_op (2, false), asm_out_file
);
3495 fprint_whex (asm_out_file
, LF_CHAR
);
3496 putc ('\n', asm_out_file
);
3498 fputs (integer_asm_op (1, false), asm_out_file
);
3499 fprint_whex (asm_out_file
, -i
->num
);
3500 putc ('\n', asm_out_file
);
3504 else if (i
->num
<= 0x8000)
3506 fputs (integer_asm_op (2, false), asm_out_file
);
3507 fprint_whex (asm_out_file
, LF_SHORT
);
3508 putc ('\n', asm_out_file
);
3510 fputs (integer_asm_op (2, false), asm_out_file
);
3511 fprint_whex (asm_out_file
, -i
->num
);
3512 putc ('\n', asm_out_file
);
3516 else if (i
->num
<= 0x80000000)
3518 fputs (integer_asm_op (2, false), asm_out_file
);
3519 fprint_whex (asm_out_file
, LF_LONG
);
3520 putc ('\n', asm_out_file
);
3522 fputs (integer_asm_op (4, false), asm_out_file
);
3523 fprint_whex (asm_out_file
, -i
->num
);
3524 putc ('\n', asm_out_file
);
3530 fputs (integer_asm_op (2, false), asm_out_file
);
3531 fprint_whex (asm_out_file
, LF_QUADWORD
);
3532 putc ('\n', asm_out_file
);
3534 fputs (integer_asm_op (8, false), asm_out_file
);
3535 fprint_whex (asm_out_file
, -i
->num
);
3536 putc ('\n', asm_out_file
);
3543 if (i
->num
<= 0x7fff)
3545 fputs (integer_asm_op (2, false), asm_out_file
);
3546 fprint_whex (asm_out_file
, i
->num
);
3547 putc ('\n', asm_out_file
);
3551 else if (i
->num
<= 0xffff)
3553 fputs (integer_asm_op (2, false), asm_out_file
);
3554 fprint_whex (asm_out_file
, LF_USHORT
);
3555 putc ('\n', asm_out_file
);
3557 fputs (integer_asm_op (2, false), asm_out_file
);
3558 fprint_whex (asm_out_file
, i
->num
);
3559 putc ('\n', asm_out_file
);
3563 else if (i
->num
<= 0xffffffff)
3565 fputs (integer_asm_op (2, false), asm_out_file
);
3566 fprint_whex (asm_out_file
, LF_ULONG
);
3567 putc ('\n', asm_out_file
);
3569 fputs (integer_asm_op (4, false), asm_out_file
);
3570 fprint_whex (asm_out_file
, i
->num
);
3571 putc ('\n', asm_out_file
);
3577 fputs (integer_asm_op (2, false), asm_out_file
);
3578 fprint_whex (asm_out_file
, LF_UQUADWORD
);
3579 putc ('\n', asm_out_file
);
3581 fputs (integer_asm_op (8, false), asm_out_file
);
3582 fprint_whex (asm_out_file
, i
->num
);
3583 putc ('\n', asm_out_file
);
3590 /* Return the extra size needed for an extensible integer. */
3593 cv_integer_len (codeview_integer
*i
)
3598 return sizeof (int8_t);
3599 else if (i
->num
<= 0x8000)
3600 return sizeof (int16_t);
3601 else if (i
->num
<= 0x80000000)
3602 return sizeof (int32_t);
3604 return sizeof (int64_t);
3608 if (i
->num
<= 0x7fff)
3610 else if (i
->num
<= 0xffff)
3611 return sizeof (uint16_t);
3612 else if (i
->num
<= 0xffffffff)
3613 return sizeof (uint32_t);
3615 return sizeof (uint64_t);
3619 /* Write an LF_FIELDLIST type, which is a container for various subtypes. This
3620 has two uses: for the values in an enum, and for the member, operators etc.
3621 for a struct, class, or union. */
3624 write_lf_fieldlist (codeview_custom_type
*t
)
3626 fputs (integer_asm_op (2, false), asm_out_file
);
3627 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
3630 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
3632 fputs (integer_asm_op (2, false), asm_out_file
);
3633 fprint_whex (asm_out_file
, t
->kind
);
3634 putc ('\n', asm_out_file
);
3636 while (t
->lf_fieldlist
.subtypes
)
3638 codeview_subtype
*v
= t
->lf_fieldlist
.subtypes
;
3639 codeview_subtype
*next
= v
->next
;
3640 size_t name_len
, leaf_len
;
3645 /* This is lf_enumerate in binutils and lfEnumerate in Microsoft's
3651 uint16_t attributes;
3653 (then actual value if value >= 0x8000)
3658 fputs (integer_asm_op (2, false), asm_out_file
);
3659 fprint_whex (asm_out_file
, LF_ENUMERATE
);
3660 putc ('\n', asm_out_file
);
3662 fputs (integer_asm_op (2, false), asm_out_file
);
3663 fprint_whex (asm_out_file
, CV_ACCESS_PUBLIC
);
3664 putc ('\n', asm_out_file
);
3666 leaf_len
= 4 + write_cv_integer (&v
->lf_enumerate
.value
);
3668 name_len
= strlen (v
->lf_enumerate
.name
) + 1;
3669 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_enumerate
.name
, name_len
);
3671 leaf_len
+= name_len
;
3672 write_cv_padding (4 - (leaf_len
% 4));
3674 free (v
->lf_enumerate
.name
);
3678 /* This is lf_member in binutils and lfMember in Microsoft's
3684 uint16_t attributes;
3691 fputs (integer_asm_op (2, false), asm_out_file
);
3692 fprint_whex (asm_out_file
, LF_MEMBER
);
3693 putc ('\n', asm_out_file
);
3695 fputs (integer_asm_op (2, false), asm_out_file
);
3696 fprint_whex (asm_out_file
, v
->lf_member
.attributes
);
3697 putc ('\n', asm_out_file
);
3699 fputs (integer_asm_op (4, false), asm_out_file
);
3700 fprint_whex (asm_out_file
, v
->lf_member
.type
);
3701 putc ('\n', asm_out_file
);
3703 leaf_len
= 8 + write_cv_integer (&v
->lf_member
.offset
);
3705 if (v
->lf_member
.name
)
3707 name_len
= strlen (v
->lf_member
.name
) + 1;
3708 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_member
.name
, name_len
);
3713 ASM_OUTPUT_ASCII (asm_out_file
, "", name_len
);
3716 leaf_len
+= name_len
;
3717 write_cv_padding (4 - (leaf_len
% 4));
3719 free (v
->lf_member
.name
);
3723 /* This is lf_index in binutils and lfIndex in Microsoft's cvinfo.h:
3733 fputs (integer_asm_op (2, false), asm_out_file
);
3734 fprint_whex (asm_out_file
, LF_INDEX
);
3735 putc ('\n', asm_out_file
);
3737 fputs (integer_asm_op (2, false), asm_out_file
);
3738 fprint_whex (asm_out_file
, 0);
3739 putc ('\n', asm_out_file
);
3741 fputs (integer_asm_op (4, false), asm_out_file
);
3742 fprint_whex (asm_out_file
, v
->lf_index
.type_num
);
3743 putc ('\n', asm_out_file
);
3748 /* This is lf_static_member in binutils and lfSTMember in Microsoft's
3751 struct lf_static_member
3754 uint16_t attributes;
3760 fputs (integer_asm_op (2, false), asm_out_file
);
3761 fprint_whex (asm_out_file
, LF_STMEMBER
);
3762 putc ('\n', asm_out_file
);
3764 fputs (integer_asm_op (2, false), asm_out_file
);
3765 fprint_whex (asm_out_file
, v
->lf_static_member
.attributes
);
3766 putc ('\n', asm_out_file
);
3768 fputs (integer_asm_op (4, false), asm_out_file
);
3769 fprint_whex (asm_out_file
, v
->lf_static_member
.type
);
3770 putc ('\n', asm_out_file
);
3772 name_len
= strlen (v
->lf_static_member
.name
) + 1;
3773 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_static_member
.name
, name_len
);
3775 leaf_len
= 8 + name_len
;
3776 write_cv_padding (4 - (leaf_len
% 4));
3778 free (v
->lf_static_member
.name
);
3782 /* This is lf_onemethod in binutils and lfOneMethod in Microsoft's
3788 uint16_t method_attribute;
3789 uint32_t method_type;
3794 fputs (integer_asm_op (2, false), asm_out_file
);
3795 fprint_whex (asm_out_file
, LF_ONEMETHOD
);
3796 putc ('\n', asm_out_file
);
3798 fputs (integer_asm_op (2, false), asm_out_file
);
3799 fprint_whex (asm_out_file
, v
->lf_onemethod
.method_attribute
);
3800 putc ('\n', asm_out_file
);
3802 fputs (integer_asm_op (4, false), asm_out_file
);
3803 fprint_whex (asm_out_file
, v
->lf_onemethod
.method_type
);
3804 putc ('\n', asm_out_file
);
3806 name_len
= strlen (v
->lf_onemethod
.name
) + 1;
3807 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_onemethod
.name
, name_len
);
3809 leaf_len
= 8 + name_len
;
3810 write_cv_padding (4 - (leaf_len
% 4));
3812 free (v
->lf_onemethod
.name
);
3816 /* This is lf_method in binutils and lfMethod in Microsoft's
3823 uint32_t method_list;
3828 fputs (integer_asm_op (2, false), asm_out_file
);
3829 fprint_whex (asm_out_file
, LF_METHOD
);
3830 putc ('\n', asm_out_file
);
3832 fputs (integer_asm_op (2, false), asm_out_file
);
3833 fprint_whex (asm_out_file
, v
->lf_method
.count
);
3834 putc ('\n', asm_out_file
);
3836 fputs (integer_asm_op (4, false), asm_out_file
);
3837 fprint_whex (asm_out_file
, v
->lf_method
.method_list
);
3838 putc ('\n', asm_out_file
);
3840 name_len
= strlen (v
->lf_method
.name
) + 1;
3841 ASM_OUTPUT_ASCII (asm_out_file
, v
->lf_method
.name
, name_len
);
3843 leaf_len
= 8 + name_len
;
3844 write_cv_padding (4 - (leaf_len
% 4));
3846 free (v
->lf_method
.name
);
3853 t
->lf_fieldlist
.subtypes
= next
;
3857 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
3860 /* Write an LF_ENUM type. */
3863 write_lf_enum (codeview_custom_type
*t
)
3865 size_t name_len
, leaf_len
;
3867 /* This is lf_enum in binutils and lfEnum in Microsoft's cvinfo.h:
3873 uint16_t num_elements;
3874 uint16_t properties;
3875 uint32_t underlying_type;
3876 uint32_t field_list;
3881 fputs (integer_asm_op (2, false), asm_out_file
);
3882 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
3885 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
3887 fputs (integer_asm_op (2, false), asm_out_file
);
3888 fprint_whex (asm_out_file
, t
->kind
);
3889 putc ('\n', asm_out_file
);
3891 fputs (integer_asm_op (2, false), asm_out_file
);
3892 fprint_whex (asm_out_file
, t
->lf_enum
.count
);
3893 putc ('\n', asm_out_file
);
3895 fputs (integer_asm_op (2, false), asm_out_file
);
3896 fprint_whex (asm_out_file
, t
->lf_enum
.properties
);
3897 putc ('\n', asm_out_file
);
3899 fputs (integer_asm_op (4, false), asm_out_file
);
3900 fprint_whex (asm_out_file
, t
->lf_enum
.underlying_type
);
3901 putc ('\n', asm_out_file
);
3903 fputs (integer_asm_op (4, false), asm_out_file
);
3904 fprint_whex (asm_out_file
, t
->lf_enum
.fieldlist
);
3905 putc ('\n', asm_out_file
);
3907 name_len
= strlen (t
->lf_enum
.name
) + 1;
3908 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_enum
.name
, name_len
);
3910 leaf_len
= 14 + name_len
;
3911 write_cv_padding (4 - (leaf_len
% 4));
3913 free (t
->lf_enum
.name
);
3915 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
3918 /* Write an LF_STRUCTURE or LF_CLASS type (the two have the same structure). */
3921 write_lf_structure (codeview_custom_type
*t
)
3923 size_t name_len
, leaf_len
;
3925 /* This is lf_class in binutils and lfClass in Microsoft's cvinfo.h:
3931 uint16_t num_members;
3932 uint16_t properties;
3933 uint32_t field_list;
3934 uint32_t derived_from;
3941 fputs (integer_asm_op (2, false), asm_out_file
);
3942 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
3945 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
3947 fputs (integer_asm_op (2, false), asm_out_file
);
3948 fprint_whex (asm_out_file
, t
->kind
);
3949 putc ('\n', asm_out_file
);
3951 fputs (integer_asm_op (2, false), asm_out_file
);
3952 fprint_whex (asm_out_file
, t
->lf_structure
.num_members
);
3953 putc ('\n', asm_out_file
);
3955 fputs (integer_asm_op (2, false), asm_out_file
);
3956 fprint_whex (asm_out_file
, t
->lf_structure
.properties
);
3957 putc ('\n', asm_out_file
);
3959 fputs (integer_asm_op (4, false), asm_out_file
);
3960 fprint_whex (asm_out_file
, t
->lf_structure
.field_list
);
3961 putc ('\n', asm_out_file
);
3963 fputs (integer_asm_op (4, false), asm_out_file
);
3964 fprint_whex (asm_out_file
, t
->lf_structure
.derived_from
);
3965 putc ('\n', asm_out_file
);
3967 fputs (integer_asm_op (4, false), asm_out_file
);
3968 fprint_whex (asm_out_file
, t
->lf_structure
.vshape
);
3969 putc ('\n', asm_out_file
);
3971 leaf_len
= 20 + write_cv_integer (&t
->lf_structure
.length
);
3973 if (t
->lf_structure
.name
)
3975 name_len
= strlen (t
->lf_structure
.name
) + 1;
3976 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_structure
.name
, name_len
);
3980 static const char unnamed_struct
[] = "<unnamed-tag>";
3982 name_len
= sizeof (unnamed_struct
);
3983 ASM_OUTPUT_ASCII (asm_out_file
, unnamed_struct
, name_len
);
3986 leaf_len
+= name_len
;
3987 write_cv_padding (4 - (leaf_len
% 4));
3989 free (t
->lf_structure
.name
);
3991 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
3994 /* Write an LF_UNION type. */
3997 write_lf_union (codeview_custom_type
*t
)
3999 size_t name_len
, leaf_len
;
4001 /* This is lf_union in binutils and lfUnion in Microsoft's cvinfo.h:
4007 uint16_t num_members;
4008 uint16_t properties;
4009 uint32_t field_list;
4015 fputs (integer_asm_op (2, false), asm_out_file
);
4016 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4019 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4021 fputs (integer_asm_op (2, false), asm_out_file
);
4022 fprint_whex (asm_out_file
, t
->kind
);
4023 putc ('\n', asm_out_file
);
4025 fputs (integer_asm_op (2, false), asm_out_file
);
4026 fprint_whex (asm_out_file
, t
->lf_structure
.num_members
);
4027 putc ('\n', asm_out_file
);
4029 fputs (integer_asm_op (2, false), asm_out_file
);
4030 fprint_whex (asm_out_file
, t
->lf_structure
.properties
);
4031 putc ('\n', asm_out_file
);
4033 fputs (integer_asm_op (4, false), asm_out_file
);
4034 fprint_whex (asm_out_file
, t
->lf_structure
.field_list
);
4035 putc ('\n', asm_out_file
);
4037 leaf_len
= 12 + write_cv_integer (&t
->lf_structure
.length
);
4039 if (t
->lf_structure
.name
)
4041 name_len
= strlen (t
->lf_structure
.name
) + 1;
4042 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_structure
.name
, name_len
);
4046 static const char unnamed_struct
[] = "<unnamed-tag>";
4048 name_len
= sizeof (unnamed_struct
);
4049 ASM_OUTPUT_ASCII (asm_out_file
, unnamed_struct
, name_len
);
4052 leaf_len
+= name_len
;
4053 write_cv_padding (4 - (leaf_len
% 4));
4055 free (t
->lf_structure
.name
);
4057 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4060 /* Write an LF_ARRAY type. */
4063 write_lf_array (codeview_custom_type
*t
)
4067 /* This is lf_array in binutils and lfArray in Microsoft's cvinfo.h:
4073 uint32_t element_type;
4074 uint32_t index_type;
4075 uint16_t length_in_bytes;
4080 fputs (integer_asm_op (2, false), asm_out_file
);
4081 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4084 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4086 fputs (integer_asm_op (2, false), asm_out_file
);
4087 fprint_whex (asm_out_file
, t
->kind
);
4088 putc ('\n', asm_out_file
);
4090 fputs (integer_asm_op (4, false), asm_out_file
);
4091 fprint_whex (asm_out_file
, t
->lf_array
.element_type
);
4092 putc ('\n', asm_out_file
);
4094 fputs (integer_asm_op (4, false), asm_out_file
);
4095 fprint_whex (asm_out_file
, t
->lf_array
.index_type
);
4096 putc ('\n', asm_out_file
);
4098 leaf_len
= 13 + write_cv_integer (&t
->lf_array
.length_in_bytes
);
4100 ASM_OUTPUT_ASCII (asm_out_file
, "", 1);
4102 write_cv_padding (4 - (leaf_len
% 4));
4104 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4107 /* Write an LF_BITFIELD type. */
4110 write_lf_bitfield (codeview_custom_type
*t
)
4112 /* This is lf_bitfield in binutils and lfBitfield in Microsoft's cvinfo.h:
4124 fputs (integer_asm_op (2, false), asm_out_file
);
4125 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4128 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4130 fputs (integer_asm_op (2, false), asm_out_file
);
4131 fprint_whex (asm_out_file
, t
->kind
);
4132 putc ('\n', asm_out_file
);
4134 fputs (integer_asm_op (4, false), asm_out_file
);
4135 fprint_whex (asm_out_file
, t
->lf_bitfield
.base_type
);
4136 putc ('\n', asm_out_file
);
4138 fputs (integer_asm_op (1, false), asm_out_file
);
4139 fprint_whex (asm_out_file
, t
->lf_bitfield
.length
);
4140 putc ('\n', asm_out_file
);
4142 fputs (integer_asm_op (1, false), asm_out_file
);
4143 fprint_whex (asm_out_file
, t
->lf_bitfield
.position
);
4144 putc ('\n', asm_out_file
);
4146 write_cv_padding (2);
4148 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4151 /* Write an LF_PROCEDURE type. Function pointers are implemented as pointers
4155 write_lf_procedure (codeview_custom_type
*t
)
4157 /* This is lf_procedure in binutils and lfProc in Microsoft's cvinfo.h:
4163 uint32_t return_type;
4164 uint8_t calling_convention;
4166 uint16_t num_parameters;
4171 fputs (integer_asm_op (2, false), asm_out_file
);
4172 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4175 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4177 fputs (integer_asm_op (2, false), asm_out_file
);
4178 fprint_whex (asm_out_file
, t
->kind
);
4179 putc ('\n', asm_out_file
);
4181 fputs (integer_asm_op (4, false), asm_out_file
);
4182 fprint_whex (asm_out_file
, t
->lf_procedure
.return_type
);
4183 putc ('\n', asm_out_file
);
4185 fputs (integer_asm_op (1, false), asm_out_file
);
4186 fprint_whex (asm_out_file
, t
->lf_procedure
.calling_convention
);
4187 putc ('\n', asm_out_file
);
4189 fputs (integer_asm_op (1, false), asm_out_file
);
4190 fprint_whex (asm_out_file
, t
->lf_procedure
.attributes
);
4191 putc ('\n', asm_out_file
);
4193 fputs (integer_asm_op (2, false), asm_out_file
);
4194 fprint_whex (asm_out_file
, t
->lf_procedure
.num_parameters
);
4195 putc ('\n', asm_out_file
);
4197 fputs (integer_asm_op (4, false), asm_out_file
);
4198 fprint_whex (asm_out_file
, t
->lf_procedure
.arglist
);
4199 putc ('\n', asm_out_file
);
4201 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4204 /* Write an LF_ARGLIST type. This is just a list of other types. LF_PROCEDURE
4205 entries point to one of these. */
4208 write_lf_arglist (codeview_custom_type
*t
)
4210 /* This is lf_arglist in binutils and lfArgList in Microsoft's cvinfo.h:
4216 uint32_t num_entries;
4221 fputs (integer_asm_op (2, false), asm_out_file
);
4222 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4225 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4227 fputs (integer_asm_op (2, false), asm_out_file
);
4228 fprint_whex (asm_out_file
, t
->kind
);
4229 putc ('\n', asm_out_file
);
4231 fputs (integer_asm_op (4, false), asm_out_file
);
4232 fprint_whex (asm_out_file
, t
->lf_arglist
.num_entries
);
4233 putc ('\n', asm_out_file
);
4235 for (uint32_t i
= 0; i
< t
->lf_arglist
.num_entries
; i
++)
4237 fputs (integer_asm_op (4, false), asm_out_file
);
4238 fprint_whex (asm_out_file
, t
->lf_arglist
.args
[i
]);
4239 putc ('\n', asm_out_file
);
4242 free (t
->lf_arglist
.args
);
4244 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4247 /* Write an LF_FUNC_ID type, which marries together a function type with its
4248 name. This will end up in the alternative types stream in the final PDB,
4249 but we can just stick it in the normal .debug$T section. */
4252 write_lf_func_id (codeview_custom_type
*t
)
4256 /* This is lf_func_id in binutils and lfFuncId in Microsoft's cvinfo.h:
4262 uint32_t parent_scope;
4263 uint32_t function_type;
4268 fputs (integer_asm_op (2, false), asm_out_file
);
4269 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4272 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4274 fputs (integer_asm_op (2, false), asm_out_file
);
4275 fprint_whex (asm_out_file
, t
->kind
);
4276 putc ('\n', asm_out_file
);
4278 fputs (integer_asm_op (4, false), asm_out_file
);
4279 fprint_whex (asm_out_file
, t
->lf_func_id
.parent_scope
);
4280 putc ('\n', asm_out_file
);
4282 fputs (integer_asm_op (4, false), asm_out_file
);
4283 fprint_whex (asm_out_file
, t
->lf_func_id
.function_type
);
4284 putc ('\n', asm_out_file
);
4286 name_len
= strlen (t
->lf_func_id
.name
) + 1;
4288 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_func_id
.name
, name_len
);
4290 write_cv_padding (4 - (name_len
% 4));
4292 free (t
->lf_func_id
.name
);
4294 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4297 /* Write an LF_MFUNC_ID type, which is the version of LF_FUNC_ID for struct
4298 functions. Instead of an LF_STRING_ID for the parent scope, we write the
4299 type number of the parent struct. */
4302 write_lf_mfunc_id (codeview_custom_type
*t
)
4306 /* This is lf_mfunc_id in binutils and lfMFuncId in Microsoft's cvinfo.h:
4312 uint32_t parent_type;
4313 uint32_t function_type;
4318 fputs (integer_asm_op (2, false), asm_out_file
);
4319 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4322 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4324 fputs (integer_asm_op (2, false), asm_out_file
);
4325 fprint_whex (asm_out_file
, t
->kind
);
4326 putc ('\n', asm_out_file
);
4328 fputs (integer_asm_op (4, false), asm_out_file
);
4329 fprint_whex (asm_out_file
, t
->lf_mfunc_id
.parent_type
);
4330 putc ('\n', asm_out_file
);
4332 fputs (integer_asm_op (4, false), asm_out_file
);
4333 fprint_whex (asm_out_file
, t
->lf_mfunc_id
.function_type
);
4334 putc ('\n', asm_out_file
);
4336 name_len
= strlen (t
->lf_mfunc_id
.name
) + 1;
4338 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_mfunc_id
.name
, name_len
);
4340 write_cv_padding (4 - (name_len
% 4));
4342 free (t
->lf_mfunc_id
.name
);
4344 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4347 /* Write an LF_STRING_ID type, which provides a deduplicated string that other
4348 types can reference. */
4351 write_lf_string_id (codeview_custom_type
*t
)
4355 /* This is lf_string_id in binutils and lfStringId in Microsoft's cvinfo.h:
4366 fputs (integer_asm_op (2, false), asm_out_file
);
4367 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4370 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4372 fputs (integer_asm_op (2, false), asm_out_file
);
4373 fprint_whex (asm_out_file
, t
->kind
);
4374 putc ('\n', asm_out_file
);
4376 fputs (integer_asm_op (4, false), asm_out_file
);
4377 fprint_whex (asm_out_file
, t
->lf_string_id
.substring
);
4378 putc ('\n', asm_out_file
);
4380 string_len
= strlen (t
->lf_string_id
.string
) + 1;
4382 ASM_OUTPUT_ASCII (asm_out_file
, t
->lf_string_id
.string
, string_len
);
4384 write_cv_padding (4 - (string_len
% 4));
4386 free (t
->lf_string_id
.string
);
4388 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4391 /* Write an LF_MFUNCTION type, representing a member function. This is the
4392 struct-scoped equivalent of the LF_PROCEDURE type. */
4395 write_lf_mfunction (codeview_custom_type
*t
)
4397 /* This is lf_mfunction in binutils and lfMFunc in Microsoft's cvinfo.h:
4403 uint32_t return_type;
4404 uint32_t containing_class_type;
4406 uint8_t calling_convention;
4408 uint16_t num_parameters;
4410 int32_t this_adjustment;
4414 fputs (integer_asm_op (2, false), asm_out_file
);
4415 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4418 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4420 fputs (integer_asm_op (2, false), asm_out_file
);
4421 fprint_whex (asm_out_file
, t
->kind
);
4422 putc ('\n', asm_out_file
);
4424 fputs (integer_asm_op (4, false), asm_out_file
);
4425 fprint_whex (asm_out_file
, t
->lf_mfunction
.return_type
);
4426 putc ('\n', asm_out_file
);
4428 fputs (integer_asm_op (4, false), asm_out_file
);
4429 fprint_whex (asm_out_file
, t
->lf_mfunction
.containing_class_type
);
4430 putc ('\n', asm_out_file
);
4432 fputs (integer_asm_op (4, false), asm_out_file
);
4433 fprint_whex (asm_out_file
, t
->lf_mfunction
.this_type
);
4434 putc ('\n', asm_out_file
);
4436 fputs (integer_asm_op (1, false), asm_out_file
);
4437 fprint_whex (asm_out_file
, t
->lf_mfunction
.calling_convention
);
4438 putc ('\n', asm_out_file
);
4440 fputs (integer_asm_op (1, false), asm_out_file
);
4441 fprint_whex (asm_out_file
, t
->lf_mfunction
.attributes
);
4442 putc ('\n', asm_out_file
);
4444 fputs (integer_asm_op (2, false), asm_out_file
);
4445 fprint_whex (asm_out_file
, t
->lf_mfunction
.num_parameters
);
4446 putc ('\n', asm_out_file
);
4448 fputs (integer_asm_op (4, false), asm_out_file
);
4449 fprint_whex (asm_out_file
, t
->lf_mfunction
.arglist
);
4450 putc ('\n', asm_out_file
);
4452 fputs (integer_asm_op (4, false), asm_out_file
);
4453 fprint_whex (asm_out_file
, t
->lf_mfunction
.this_adjustment
);
4454 putc ('\n', asm_out_file
);
4456 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4459 /* Write an LF_METHODLIST type, which is an array of type numbers for
4460 LF_MFUNCTION types. Overloaded functions are represented by a LF_METHOD
4461 subtype in the field list, which points to a LF_METHODLIST type for the
4462 function's various forms. */
4465 write_lf_methodlist (codeview_custom_type
*t
)
4467 /* This is lf_methodlist in binutils and lMethodList in Microsoft's cvinfo.h:
4469 struct lf_methodlist_entry
4471 uint16_t method_attribute;
4473 uint32_t method_type;
4476 struct lf_methodlist
4480 struct lf_methodlist_entry entries[];
4484 fputs (integer_asm_op (2, false), asm_out_file
);
4485 asm_fprintf (asm_out_file
, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4488 asm_fprintf (asm_out_file
, "%LLcv_type%x_start:\n", t
->num
);
4490 fputs (integer_asm_op (2, false), asm_out_file
);
4491 fprint_whex (asm_out_file
, t
->kind
);
4492 putc ('\n', asm_out_file
);
4494 for (unsigned int i
= 0; i
< t
->lf_methodlist
.count
; i
++)
4496 fputs (integer_asm_op (2, false), asm_out_file
);
4497 fprint_whex (asm_out_file
, t
->lf_methodlist
.entries
[i
].method_attribute
);
4498 putc ('\n', asm_out_file
);
4500 fputs (integer_asm_op (2, false), asm_out_file
);
4501 fprint_whex (asm_out_file
, 0);
4502 putc ('\n', asm_out_file
);
4504 fputs (integer_asm_op (4, false), asm_out_file
);
4505 fprint_whex (asm_out_file
, t
->lf_methodlist
.entries
[i
].method_type
);
4506 putc ('\n', asm_out_file
);
4509 free (t
->lf_methodlist
.entries
);
4511 asm_fprintf (asm_out_file
, "%LLcv_type%x_end:\n", t
->num
);
4514 /* Write the .debug$T section, which contains all of our custom type
4518 write_custom_types (void)
4520 targetm
.asm_out
.named_section (".debug$T", SECTION_DEBUG
, NULL
);
4522 fputs (integer_asm_op (4, false), asm_out_file
);
4523 fprint_whex (asm_out_file
, CV_SIGNATURE_C13
);
4524 putc ('\n', asm_out_file
);
4526 while (custom_types
)
4528 codeview_custom_type
*n
= custom_types
->next
;
4530 switch (custom_types
->kind
)
4533 write_lf_pointer (custom_types
);
4537 write_lf_modifier (custom_types
);
4541 write_lf_fieldlist (custom_types
);
4545 write_lf_enum (custom_types
);
4550 write_lf_structure (custom_types
);
4554 write_lf_union (custom_types
);
4558 write_lf_array (custom_types
);
4562 write_lf_bitfield (custom_types
);
4566 write_lf_procedure (custom_types
);
4570 write_lf_arglist (custom_types
);
4574 write_lf_func_id (custom_types
);
4578 write_lf_mfunc_id (custom_types
);
4582 write_lf_string_id (custom_types
);
4586 write_lf_mfunction (custom_types
);
4590 write_lf_methodlist (custom_types
);
4597 free (custom_types
);
4602 /* Finish CodeView debug info emission. */
4605 codeview_debug_finish (void)
4607 targetm
.asm_out
.named_section (".debug$S", SECTION_DEBUG
, NULL
);
4609 fputs (integer_asm_op (4, false), asm_out_file
);
4610 fprint_whex (asm_out_file
, CV_SIGNATURE_C13
);
4611 putc ('\n', asm_out_file
);
4613 write_strings_table ();
4614 write_source_files ();
4615 write_line_numbers ();
4616 write_codeview_symbols ();
4619 write_custom_types ();
4625 delete string_id_htab
;
4628 /* Translate a DWARF base type (DW_TAG_base_type) into its CodeView
4632 get_type_num_base_type (dw_die_ref type
)
4634 unsigned int size
= get_AT_unsigned (type
, DW_AT_byte_size
);
4636 switch (get_AT_unsigned (type
, DW_AT_encoding
))
4638 case DW_ATE_signed_char
:
4640 const char *name
= get_AT_string (type
, DW_AT_name
);
4645 if (name
&& !strcmp (name
, "signed char"))
4651 case DW_ATE_unsigned_char
:
4665 const char *name
= get_AT_string (type
, DW_AT_name
);
4667 if (name
&& !strcmp (name
, "int"))
4680 case DW_ATE_unsigned
:
4685 const char *name
= get_AT_string (type
, DW_AT_name
);
4687 if (name
&& !strcmp (name
, "wchar_t"))
4695 const char *name
= get_AT_string (type
, DW_AT_name
);
4697 if (name
&& !strcmp (name
, "unsigned int"))
4745 case DW_ATE_boolean
:
4756 /* Add a new codeview_custom_type to our singly-linked custom_types list. */
4759 add_custom_type (codeview_custom_type
*ct
)
4763 if (last_custom_type
)
4765 num
= last_custom_type
->num
+ 1;
4766 last_custom_type
->next
= ct
;
4774 last_custom_type
= ct
;
4779 /* Process a DW_TAG_pointer_type DIE. If this is a pointer to a builtin
4780 type, return the predefined constant for this. Otherwise, add a new
4781 LF_POINTER type and return its number. */
4784 get_type_num_pointer_type (dw_die_ref type
, bool in_struct
)
4786 uint32_t base_type_num
, byte_size
;
4787 dw_die_ref base_type
;
4788 codeview_custom_type
*ct
;
4790 byte_size
= get_AT_unsigned (type
, DW_AT_byte_size
);
4791 if (byte_size
!= 4 && byte_size
!= 8)
4794 base_type
= get_AT_ref (type
, DW_AT_type
);
4796 /* If DW_AT_type is not set, this must be a void pointer. */
4798 return byte_size
== 4 ? T_32PVOID
: T_64PVOID
;
4800 base_type_num
= get_type_num (base_type
, in_struct
, false);
4801 if (base_type_num
== 0)
4804 /* Pointers to builtin types have predefined type numbers, with the top byte
4805 determining the pointer size - 0x0400 for a 32-bit pointer and 0x0600
4807 if (base_type_num
< FIRST_TYPE
&& !(base_type_num
& 0xff00))
4810 return CV_POINTER_32
| base_type_num
;
4812 return CV_POINTER_64
| base_type_num
;
4815 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
4818 ct
->kind
= LF_POINTER
;
4819 ct
->lf_pointer
.base_type
= base_type_num
;
4822 ct
->lf_pointer
.attributes
= CV_PTR_NEAR32
;
4824 ct
->lf_pointer
.attributes
= CV_PTR_64
;
4826 ct
->lf_pointer
.attributes
|= byte_size
<< 13;
4828 add_custom_type (ct
);
4833 /* Process a DW_TAG_reference_type or DW_TAG_rvalue_reference_type DIE, add a
4834 new LF_POINTER type, and return its number. */
4837 get_type_num_reference_type (dw_die_ref type
, bool in_struct
, bool rvref
)
4839 uint32_t base_type_num
, byte_size
;
4840 dw_die_ref base_type
;
4841 codeview_custom_type
*ct
;
4843 byte_size
= get_AT_unsigned (type
, DW_AT_byte_size
);
4844 if (byte_size
!= 4 && byte_size
!= 8)
4847 base_type
= get_AT_ref (type
, DW_AT_type
);
4849 base_type_num
= get_type_num (base_type
, in_struct
, false);
4850 if (base_type_num
== 0)
4853 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
4856 ct
->kind
= LF_POINTER
;
4857 ct
->lf_pointer
.base_type
= base_type_num
;
4858 ct
->lf_pointer
.attributes
= rvref
? CV_PTR_MODE_RVREF
: CV_PTR_MODE_LVREF
;
4861 ct
->lf_pointer
.attributes
|= CV_PTR_NEAR32
;
4863 ct
->lf_pointer
.attributes
|= CV_PTR_64
;
4865 ct
->lf_pointer
.attributes
|= byte_size
<< 13;
4867 add_custom_type (ct
);
4872 /* Process a DW_TAG_const_type DIE, adding an LF_MODIFIER type and returning
4876 get_type_num_const_type (dw_die_ref type
, bool in_struct
)
4878 dw_die_ref base_type
;
4879 uint32_t base_type_num
;
4880 codeview_custom_type
*ct
;
4881 bool is_volatile
= false;
4883 base_type
= get_AT_ref (type
, DW_AT_type
);
4885 /* Handle case when this is a const volatile type - we only need one
4886 LF_MODIFIER for this. */
4887 if (base_type
&& dw_get_die_tag (base_type
) == DW_TAG_volatile_type
)
4891 base_type
= get_AT_ref (base_type
, DW_AT_type
);
4896 base_type_num
= T_VOID
;
4900 base_type_num
= get_type_num (base_type
, in_struct
, false);
4901 if (base_type_num
== 0)
4905 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
4908 ct
->kind
= LF_MODIFIER
;
4909 ct
->lf_modifier
.base_type
= base_type_num
;
4910 ct
->lf_modifier
.modifier
= MOD_const
;
4913 ct
->lf_modifier
.modifier
|= MOD_volatile
;
4915 add_custom_type (ct
);
4920 /* Process a DW_TAG_volatile_type DIE, adding an LF_MODIFIER type and
4921 returning its number. */
4924 get_type_num_volatile_type (dw_die_ref type
, bool in_struct
)
4926 dw_die_ref base_type
;
4927 uint32_t base_type_num
;
4928 codeview_custom_type
*ct
;
4930 base_type
= get_AT_ref (type
, DW_AT_type
);
4934 base_type_num
= get_type_num (base_type
, in_struct
, false);
4935 if (base_type_num
== 0)
4940 base_type_num
= T_VOID
;
4943 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
4946 ct
->kind
= LF_MODIFIER
;
4947 ct
->lf_modifier
.base_type
= base_type_num
;
4948 ct
->lf_modifier
.modifier
= MOD_volatile
;
4950 add_custom_type (ct
);
4955 /* Return the name of a DIE, traversing its parents in order to construct a
4956 C++-style name if necessary. */
4958 get_name (dw_die_ref die
)
4960 dw_die_ref decl
= get_AT_ref (die
, DW_AT_specification
);
4966 static const char anon
[] = "<unnamed-tag>";
4967 static const char sep
[] = "::";
4972 name
= get_AT_string (die
, DW_AT_name
);
4977 parent
= dw_get_die_parent (die
);
4979 if (!parent
|| dw_get_die_tag (parent
) == DW_TAG_compile_unit
)
4980 return xstrdup (name
);
4982 len
= strlen (name
);
4983 while (parent
&& dw_get_die_tag (parent
) != DW_TAG_compile_unit
)
4985 const char *ns_name
= get_AT_string (parent
, DW_AT_name
);
4987 len
+= sizeof (sep
) - 1;
4990 len
+= strlen (ns_name
);
4992 len
+= sizeof (anon
) - 1;
4994 parent
= dw_get_die_parent (parent
);
4997 str
= (char *) xmalloc (len
+ 1);
5000 len
-= strlen (name
);
5001 memcpy (str
+ len
, name
, strlen (name
));
5003 parent
= dw_get_die_parent (die
);
5004 while (parent
&& dw_get_die_tag (parent
) != DW_TAG_compile_unit
)
5006 const char *ns_name
= get_AT_string (parent
, DW_AT_name
);
5008 len
-= sizeof (sep
) - 1;
5009 memcpy (str
+ len
, sep
, sizeof (sep
) - 1);
5013 len
-= strlen (ns_name
);
5014 memcpy (str
+ len
, ns_name
, strlen (ns_name
));
5018 len
-= sizeof (anon
) - 1;
5019 memcpy (str
+ len
, anon
, sizeof (anon
) - 1);
5022 parent
= dw_get_die_parent (parent
);
5028 /* Add a forward declaration for an enum. This is legal from C++11 onwards. */
5031 add_enum_forward_def (dw_die_ref type
)
5033 codeview_custom_type
*ct
;
5035 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5040 ct
->lf_enum
.count
= 0;
5041 ct
->lf_enum
.properties
= CV_PROP_FWDREF
;
5042 ct
->lf_enum
.underlying_type
= get_type_num (get_AT_ref (type
, DW_AT_type
),
5044 ct
->lf_enum
.fieldlist
= 0;
5045 ct
->lf_enum
.name
= get_name (type
);
5047 add_custom_type (ct
);
5052 /* Process a DW_TAG_enumeration_type DIE, adding an LF_FIELDLIST and an LF_ENUM
5053 type, returning the number of the latter. */
5056 get_type_num_enumeration_type (dw_die_ref type
, bool in_struct
)
5058 dw_die_ref first_child
;
5059 codeview_custom_type
*ct
;
5061 uint32_t last_type
= 0;
5063 if (get_AT_flag (type
, DW_AT_declaration
))
5064 return add_enum_forward_def (type
);
5066 /* First, add an LF_FIELDLIST for the enum's values. We don't need to worry
5067 about deduplication here, as ld will take care of that for us. If there's
5068 a lot of entries, add more LF_FIELDLISTs with LF_INDEXes pointing to
5069 the overflow lists. */
5071 first_child
= dw_get_die_child (type
);
5073 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5076 ct
->kind
= LF_FIELDLIST
;
5077 ct
->lf_fieldlist
.length
= 0;
5078 ct
->lf_fieldlist
.subtypes
= NULL
;
5079 ct
->lf_fieldlist
.last_subtype
= NULL
;
5089 codeview_subtype
*el
;
5092 c
= dw_get_die_sib (c
);
5094 if (dw_get_die_tag (c
) != DW_TAG_enumerator
)
5097 att
= get_AT (c
, DW_AT_const_value
);
5101 el
= (codeview_subtype
*) xmalloc (sizeof (*el
));
5103 el
->kind
= LF_ENUMERATE
;
5105 switch (AT_class (att
))
5107 case dw_val_class_unsigned_const
:
5108 case dw_val_class_unsigned_const_implicit
:
5109 el
->lf_enumerate
.value
.neg
= false;
5110 el
->lf_enumerate
.value
.num
= att
->dw_attr_val
.v
.val_unsigned
;
5113 case dw_val_class_const
:
5114 case dw_val_class_const_implicit
:
5115 if (att
->dw_attr_val
.v
.val_int
< 0)
5117 el
->lf_enumerate
.value
.neg
= true;
5118 el
->lf_enumerate
.value
.num
= -att
->dw_attr_val
.v
.val_int
;
5122 el
->lf_enumerate
.value
.neg
= false;
5123 el
->lf_enumerate
.value
.num
= att
->dw_attr_val
.v
.val_int
;
5132 el
->lf_enumerate
.name
= xstrdup (get_AT_string (c
, DW_AT_name
));
5134 el_len
= 7 + strlen (el
->lf_enumerate
.name
);
5135 el_len
+= cv_integer_len (&el
->lf_enumerate
.value
);
5138 el_len
+= 4 - (el_len
% 4);
5140 if (ct
->lf_fieldlist
.length
+ el_len
> MAX_FIELDLIST_SIZE
)
5142 codeview_subtype
*idx
;
5143 codeview_custom_type
*ct2
;
5145 idx
= (codeview_subtype
*) xmalloc (sizeof (*idx
));
5147 idx
->kind
= LF_INDEX
;
5148 idx
->lf_index
.type_num
= 0;
5150 ct
->lf_fieldlist
.last_subtype
->next
= idx
;
5151 ct
->lf_fieldlist
.last_subtype
= idx
;
5153 ct2
= (codeview_custom_type
*)
5154 xmalloc (sizeof (codeview_custom_type
));
5157 ct2
->kind
= LF_FIELDLIST
;
5158 ct2
->lf_fieldlist
.length
= 0;
5159 ct2
->lf_fieldlist
.subtypes
= NULL
;
5160 ct2
->lf_fieldlist
.last_subtype
= NULL
;
5165 ct
->lf_fieldlist
.length
+= el_len
;
5167 if (ct
->lf_fieldlist
.last_subtype
)
5168 ct
->lf_fieldlist
.last_subtype
->next
= el
;
5170 ct
->lf_fieldlist
.subtypes
= el
;
5172 ct
->lf_fieldlist
.last_subtype
= el
;
5175 while (c
!= first_child
);
5180 codeview_custom_type
*ct2
;
5185 if (ct
->lf_fieldlist
.last_subtype
->kind
== LF_INDEX
)
5186 ct
->lf_fieldlist
.last_subtype
->lf_index
.type_num
= last_type
;
5188 add_custom_type (ct
);
5189 last_type
= ct
->num
;
5194 /* Now add an LF_ENUM, pointing to the LF_FIELDLIST we just added. */
5196 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5200 ct
->lf_enum
.count
= count
;
5201 ct
->lf_enum
.properties
= 0;
5202 ct
->lf_enum
.underlying_type
= get_type_num (get_AT_ref (type
, DW_AT_type
),
5204 ct
->lf_enum
.fieldlist
= last_type
;
5205 ct
->lf_enum
.name
= get_name (type
);
5207 add_custom_type (ct
);
5212 /* Add a DIE to our deferred_types list. This happens when we have a struct
5213 with a pointer to a type that hasn't been defined yet, but which gets
5214 defined later on. */
5217 add_deferred_type (dw_die_ref type
)
5219 codeview_deferred_type
*def
;
5221 def
= (codeview_deferred_type
*) xmalloc (sizeof (codeview_deferred_type
));
5226 if (!deferred_types
)
5227 deferred_types
= def
;
5229 last_deferred_type
->next
= def
;
5231 last_deferred_type
= def
;
5234 /* Flush the contents of our deferred_types list. This happens after everything
5235 else has been written. We call get_type_num to ensure that a type gets
5236 added to custom_types, if it hasn't been already. */
5239 flush_deferred_types (void)
5241 while (deferred_types
)
5243 codeview_deferred_type
*next
;
5245 next
= deferred_types
->next
;
5247 get_type_num (deferred_types
->type
, false, true);
5249 free (deferred_types
);
5250 deferred_types
= next
;
5253 last_deferred_type
= NULL
;
5256 /* Add a forward definition for a struct, class, or union. */
5259 add_struct_forward_def (dw_die_ref type
)
5261 codeview_custom_type
*ct
;
5263 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5267 switch (dw_get_die_tag (type
))
5269 case DW_TAG_class_type
:
5270 ct
->kind
= LF_CLASS
;
5273 case DW_TAG_structure_type
:
5274 ct
->kind
= LF_STRUCTURE
;
5277 case DW_TAG_union_type
:
5278 ct
->kind
= LF_UNION
;
5285 ct
->lf_structure
.num_members
= 0;
5286 ct
->lf_structure
.properties
= CV_PROP_FWDREF
;
5287 ct
->lf_structure
.field_list
= 0;
5288 ct
->lf_structure
.derived_from
= 0;
5289 ct
->lf_structure
.vshape
= 0;
5290 ct
->lf_structure
.length
.neg
= false;
5291 ct
->lf_structure
.length
.num
= 0;
5292 ct
->lf_structure
.name
= get_name (type
);
5294 add_custom_type (ct
);
5296 if (!get_AT_flag (type
, DW_AT_declaration
))
5297 add_deferred_type (type
);
5302 /* Add an LF_BITFIELD type, returning its number. DWARF represents bitfields
5303 as members in a struct with a DW_AT_data_bit_offset attribute, whereas in
5304 CodeView they're a distinct type. */
5307 create_bitfield (dw_die_ref c
)
5309 codeview_custom_type
*ct
;
5312 base_type
= get_type_num (get_AT_ref (c
, DW_AT_type
), true, false);
5316 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5319 ct
->kind
= LF_BITFIELD
;
5320 ct
->lf_bitfield
.base_type
= base_type
;
5321 ct
->lf_bitfield
.length
= get_AT_unsigned (c
, DW_AT_bit_size
);
5322 ct
->lf_bitfield
.position
= get_AT_unsigned (c
, DW_AT_data_bit_offset
);
5324 add_custom_type (ct
);
5329 /* Create an LF_MEMBER field list subtype for a struct member, returning its
5330 pointer in el and its size in el_len. */
5333 add_struct_member (dw_die_ref c
, uint16_t accessibility
,
5334 codeview_subtype
**el
, size_t *el_len
)
5336 *el
= (codeview_subtype
*) xmalloc (sizeof (**el
));
5338 (*el
)->kind
= LF_MEMBER
;
5339 (*el
)->lf_member
.attributes
= accessibility
;
5341 if (get_AT (c
, DW_AT_data_bit_offset
))
5342 (*el
)->lf_member
.type
= create_bitfield (c
);
5344 (*el
)->lf_member
.type
= get_type_num (get_AT_ref (c
, DW_AT_type
),
5347 (*el
)->lf_member
.offset
.neg
= false;
5348 (*el
)->lf_member
.offset
.num
= get_AT_unsigned (c
, DW_AT_data_member_location
);
5350 *el_len
= 11 + cv_integer_len (&(*el
)->lf_member
.offset
);
5352 if (get_AT_string (c
, DW_AT_name
))
5354 (*el
)->lf_member
.name
= xstrdup (get_AT_string (c
, DW_AT_name
));
5355 *el_len
+= strlen ((*el
)->lf_member
.name
);
5359 (*el
)->lf_member
.name
= NULL
;
5363 *el_len
+= 4 - (*el_len
% 4);
5366 /* Create an LF_STMEMBER field list subtype for a static struct member,
5367 returning its pointer in el and its size in el_len. */
5370 add_struct_static_member (dw_die_ref c
, uint16_t accessibility
,
5371 codeview_subtype
**el
, size_t *el_len
)
5373 *el
= (codeview_subtype
*) xmalloc (sizeof (**el
));
5375 (*el
)->kind
= LF_STMEMBER
;
5376 (*el
)->lf_static_member
.attributes
= accessibility
;
5377 (*el
)->lf_static_member
.type
= get_type_num (get_AT_ref (c
, DW_AT_type
),
5379 (*el
)->lf_static_member
.name
= xstrdup (get_AT_string (c
, DW_AT_name
));
5381 *el_len
= 9 + strlen ((*el
)->lf_static_member
.name
);
5384 *el_len
+= 4 - (*el_len
% 4);
5387 /* Create a field list subtype for a struct function, returning its pointer in
5388 el and its size in el_len. If the function is not overloaded, create an
5389 LF_ONEMETHOD subtype pointing to the LF_MFUNCTION. Otherwise, add an
5390 LF_METHODLIST type of the function's forms, and create an LF_METHOD subtype
5391 pointing to this. */
5394 add_struct_function (dw_die_ref c
, hash_table
<method_hasher
> *method_htab
,
5395 codeview_subtype
**el
, size_t *el_len
)
5397 const char *name
= get_AT_string (c
, DW_AT_name
);
5398 codeview_method
**slot
, *meth
;
5400 slot
= method_htab
->find_slot_with_hash (name
, htab_hash_string (name
),
5407 *el
= (codeview_subtype
*) xmalloc (sizeof (**el
));
5410 if (meth
->count
== 1)
5412 (*el
)->kind
= LF_ONEMETHOD
;
5413 (*el
)->lf_onemethod
.method_attribute
= meth
->attribute
;
5414 (*el
)->lf_onemethod
.method_type
= meth
->type
;
5415 (*el
)->lf_onemethod
.name
= xstrdup (name
);
5417 *el_len
= 9 + strlen ((*el
)->lf_onemethod
.name
);
5421 codeview_custom_type
*ct
;
5422 lf_methodlist_entry
*ent
;
5424 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5427 ct
->kind
= LF_METHODLIST
;
5428 ct
->lf_methodlist
.count
= meth
->count
;
5429 ct
->lf_methodlist
.entries
= (lf_methodlist_entry
*)
5430 xmalloc (meth
->count
* sizeof (lf_methodlist_entry
));
5432 ent
= ct
->lf_methodlist
.entries
;
5433 for (codeview_method
*m
= meth
; m
; m
= m
->next
)
5435 ent
->method_attribute
= m
->attribute
;
5436 ent
->method_type
= m
->type
;
5440 add_custom_type (ct
);
5442 (*el
)->kind
= LF_METHOD
;
5443 (*el
)->lf_method
.count
= meth
->count
;
5444 (*el
)->lf_method
.method_list
= ct
->num
;
5445 (*el
)->lf_method
.name
= xstrdup (name
);
5447 *el_len
= 9 + strlen ((*el
)->lf_method
.name
);
5451 *el_len
+= 4 - (*el_len
% 4);
5453 method_htab
->remove_elt_with_hash (name
, htab_hash_string (name
));
5457 codeview_method
*next
= meth
->next
;
5465 /* Create a new LF_MFUNCTION type for a struct function, add it to the
5466 types_htab hash table, and return its type number. */
5469 get_mfunction_type (dw_die_ref c
)
5471 uint32_t containing_class_type
, this_type
, mfunction_type
;
5472 dw_die_ref obj_pointer
;
5473 codeview_type
**slot
, *t
;
5475 containing_class_type
= get_type_num (dw_get_die_parent (c
), true, false);
5477 obj_pointer
= get_AT_ref (c
, DW_AT_object_pointer
);
5478 if (obj_pointer
&& dw_get_die_tag (obj_pointer
) == DW_TAG_formal_parameter
)
5480 this_type
= get_type_num (get_AT_ref (obj_pointer
, DW_AT_type
),
5488 mfunction_type
= get_type_num_subroutine_type (c
, true, containing_class_type
,
5491 slot
= types_htab
->find_slot_with_hash (c
, htab_hash_pointer (c
), INSERT
);
5493 t
= (codeview_type
*) xmalloc (sizeof (codeview_type
));
5496 t
->num
= mfunction_type
;
5497 t
->is_fwd_ref
= false;
5501 return mfunction_type
;
5504 /* Translate a DWARF DW_AT_accessibility constant into its CodeView
5505 equivalent. If implicit, follow the C++ rules. */
5508 get_accessibility (dw_die_ref c
)
5510 switch (get_AT_unsigned (c
, DW_AT_accessibility
))
5512 case DW_ACCESS_private
:
5513 return CV_ACCESS_PRIVATE
;
5515 case DW_ACCESS_protected
:
5516 return CV_ACCESS_PROTECTED
;
5518 case DW_ACCESS_public
:
5519 return CV_ACCESS_PUBLIC
;
5521 /* Members in a C++ struct or union are public by default, members
5522 in a class are private. */
5524 if (dw_get_die_tag (dw_get_die_parent (c
)) == DW_TAG_class_type
)
5525 return CV_ACCESS_PRIVATE
;
5527 return CV_ACCESS_PUBLIC
;
5531 /* Returns true if the struct function pointed to by die is an instantiated
5532 template function. These are skipped in CodeView struct definitions, as
5533 otherwise the same type might not be deduplicated across different TUs. */
5536 is_templated_func (dw_die_ref die
)
5538 dw_die_ref c
= dw_get_die_child (die
);
5545 c
= dw_get_die_sib (c
);
5547 if (dw_get_die_tag (c
) == DW_TAG_template_type_param
)
5550 while (c
!= dw_get_die_child (die
));
5555 /* Process a DW_TAG_structure_type, DW_TAG_class_type, or DW_TAG_union_type
5556 DIE, add an LF_FIELDLIST and an LF_STRUCTURE / LF_CLASS / LF_UNION type,
5557 and return the number of the latter. */
5560 get_type_num_struct (dw_die_ref type
, bool in_struct
, bool *is_fwd_ref
)
5562 dw_die_ref first_child
;
5563 codeview_custom_type
*ct
;
5564 uint16_t num_members
= 0;
5565 uint32_t last_type
= 0;
5567 if ((in_struct
&& get_AT_string (type
, DW_AT_name
))
5568 || get_AT_flag (type
, DW_AT_declaration
))
5571 return add_struct_forward_def (type
);
5574 *is_fwd_ref
= false;
5576 /* First, add an LF_FIELDLIST for the structure's members. We don't need to
5577 worry about deduplication here, as ld will take care of that for us.
5578 If there's a lot of entries, add more LF_FIELDLISTs with LF_INDEXes
5579 pointing to the overflow lists. */
5581 first_child
= dw_get_die_child (type
);
5583 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5586 ct
->kind
= LF_FIELDLIST
;
5587 ct
->lf_fieldlist
.length
= 0;
5588 ct
->lf_fieldlist
.subtypes
= NULL
;
5589 ct
->lf_fieldlist
.last_subtype
= NULL
;
5593 hash_table
<method_hasher
> *method_htab
= NULL
;
5596 /* First, loop through and record any non-templated member functions.
5597 This is because overloaded and non-overloaded functions are expressed
5598 differently in CodeView, so we need to have a hash table on the name
5599 to know how to record it later on. */
5604 c
= dw_get_die_sib (c
);
5606 if (dw_get_die_tag (c
) == DW_TAG_subprogram
)
5608 const char *name
= get_AT_string (c
, DW_AT_name
);
5609 codeview_method
*meth
, **slot
;
5611 if (is_templated_func (c
))
5615 method_htab
= new hash_table
<method_hasher
> (10);
5617 meth
= (codeview_method
*) xmalloc (sizeof (*meth
));
5619 slot
= method_htab
->find_slot_with_hash (name
,
5620 htab_hash_string (name
),
5623 meth
->attribute
= get_accessibility (c
);
5625 if (!get_AT_ref (c
, DW_AT_object_pointer
))
5626 meth
->attribute
|= CV_METHOD_STATIC
;
5628 meth
->type
= get_mfunction_type (c
);
5634 (*slot
)->last
->next
= meth
;
5636 (*slot
)->next
= meth
;
5638 (*slot
)->last
= meth
;
5645 meth
->name
= xstrdup (name
);
5652 while (c
!= first_child
);
5654 /* Now loop through again and record the actual members. */
5659 codeview_subtype
*el
;
5661 uint16_t accessibility
;
5663 c
= dw_get_die_sib (c
);
5665 accessibility
= get_accessibility (c
);
5667 switch (dw_get_die_tag (c
))
5670 add_struct_member (c
, accessibility
, &el
, &el_len
);
5673 case DW_TAG_variable
:
5674 add_struct_static_member (c
, accessibility
, &el
, &el_len
);
5677 case DW_TAG_subprogram
:
5678 if (!is_templated_func (c
))
5679 add_struct_function (c
, method_htab
, &el
, &el_len
);
5689 /* Add an LF_INDEX subtype if everything's too big for one
5692 if (ct
->lf_fieldlist
.length
+ el_len
> MAX_FIELDLIST_SIZE
)
5694 codeview_subtype
*idx
;
5695 codeview_custom_type
*ct2
;
5697 idx
= (codeview_subtype
*) xmalloc (sizeof (*idx
));
5699 idx
->kind
= LF_INDEX
;
5700 idx
->lf_index
.type_num
= 0;
5702 ct
->lf_fieldlist
.last_subtype
->next
= idx
;
5703 ct
->lf_fieldlist
.last_subtype
= idx
;
5705 ct2
= (codeview_custom_type
*)
5706 xmalloc (sizeof (codeview_custom_type
));
5709 ct2
->kind
= LF_FIELDLIST
;
5710 ct2
->lf_fieldlist
.length
= 0;
5711 ct2
->lf_fieldlist
.subtypes
= NULL
;
5712 ct2
->lf_fieldlist
.last_subtype
= NULL
;
5717 ct
->lf_fieldlist
.length
+= el_len
;
5719 if (ct
->lf_fieldlist
.last_subtype
)
5720 ct
->lf_fieldlist
.last_subtype
->next
= el
;
5722 ct
->lf_fieldlist
.subtypes
= el
;
5724 ct
->lf_fieldlist
.last_subtype
= el
;
5727 while (c
!= first_child
);
5735 codeview_custom_type
*ct2
;
5740 if (ct
->lf_fieldlist
.last_subtype
5741 && ct
->lf_fieldlist
.last_subtype
->kind
== LF_INDEX
)
5743 ct
->lf_fieldlist
.last_subtype
->lf_index
.type_num
= last_type
;
5746 add_custom_type (ct
);
5747 last_type
= ct
->num
;
5752 /* Now add an LF_STRUCTURE / LF_CLASS / LF_UNION, pointing to the
5753 LF_FIELDLIST we just added. */
5755 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5759 switch (dw_get_die_tag (type
))
5761 case DW_TAG_class_type
:
5762 ct
->kind
= LF_CLASS
;
5765 case DW_TAG_structure_type
:
5766 ct
->kind
= LF_STRUCTURE
;
5769 case DW_TAG_union_type
:
5770 ct
->kind
= LF_UNION
;
5777 ct
->lf_structure
.num_members
= num_members
;
5778 ct
->lf_structure
.properties
= 0;
5779 ct
->lf_structure
.field_list
= last_type
;
5780 ct
->lf_structure
.derived_from
= 0;
5781 ct
->lf_structure
.vshape
= 0;
5782 ct
->lf_structure
.length
.neg
= false;
5783 ct
->lf_structure
.length
.num
= get_AT_unsigned (type
, DW_AT_byte_size
);
5784 ct
->lf_structure
.name
= get_name (type
);
5786 add_custom_type (ct
);
5791 /* Process a DW_TAG_subroutine_type DIE, adding an LF_ARGLIST and an
5792 LF_PROCEDURE or LF_MFUNCTION type, and returning the number of the
5796 get_type_num_subroutine_type (dw_die_ref type
, bool in_struct
,
5797 uint32_t containing_class_type
,
5798 uint32_t this_type
, int32_t this_adjustment
)
5800 codeview_custom_type
*ct
;
5801 uint32_t return_type
, arglist_type
;
5803 dw_die_ref first_child
;
5805 /* Find the return type. */
5807 if (get_AT_ref (type
, DW_AT_type
))
5809 return_type
= get_type_num (get_AT_ref (type
, DW_AT_type
), in_struct
,
5811 if (return_type
== 0)
5816 return_type
= T_VOID
;
5819 /* Count the arguments. */
5821 first_child
= dw_get_die_child (type
);
5831 c
= dw_get_die_sib (c
);
5833 if (dw_get_die_tag (c
) != DW_TAG_formal_parameter
5834 && dw_get_die_tag (c
) != DW_TAG_unspecified_parameters
)
5837 /* We ignore "this" params here. */
5838 if (get_AT_flag (c
, DW_AT_artificial
) != 0)
5843 while (c
!= first_child
);
5846 /* Create an LF_ARGLIST for the arguments. If this is a duplicate, ld
5847 will take care of this for us. */
5849 first_child
= dw_get_die_child (type
);
5851 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5854 ct
->kind
= LF_ARGLIST
;
5855 ct
->lf_arglist
.num_entries
= num_args
;
5862 ct
->lf_arglist
.args
= (uint32_t *) xmalloc (sizeof (uint32_t) * num_args
);
5863 argptr
= ct
->lf_arglist
.args
;
5868 c
= dw_get_die_sib (c
);
5870 if (get_AT_flag (c
, DW_AT_artificial
) != 0)
5873 switch (dw_get_die_tag (c
))
5875 case DW_TAG_formal_parameter
:
5876 *argptr
= get_type_num (get_AT_ref (c
, DW_AT_type
), in_struct
,
5881 case DW_TAG_unspecified_parameters
:
5890 while (c
!= first_child
);
5894 ct
->lf_arglist
.args
= NULL
;
5897 add_custom_type (ct
);
5899 arglist_type
= ct
->num
;
5901 /* Finally, create an LF_PROCEDURE or LF_MFUNCTION type. */
5903 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
5907 if (containing_class_type
!= 0)
5909 ct
->kind
= LF_MFUNCTION
;
5910 ct
->lf_mfunction
.return_type
= return_type
;
5911 ct
->lf_mfunction
.containing_class_type
= containing_class_type
;
5912 ct
->lf_mfunction
.this_type
= this_type
;
5913 ct
->lf_mfunction
.calling_convention
= 0;
5914 ct
->lf_mfunction
.attributes
= 0;
5915 ct
->lf_mfunction
.num_parameters
= num_args
;
5916 ct
->lf_mfunction
.arglist
= arglist_type
;
5917 ct
->lf_mfunction
.this_adjustment
= this_adjustment
;
5921 ct
->kind
= LF_PROCEDURE
;
5922 ct
->lf_procedure
.return_type
= return_type
;
5923 ct
->lf_procedure
.calling_convention
= 0;
5924 ct
->lf_procedure
.attributes
= 0;
5925 ct
->lf_procedure
.num_parameters
= num_args
;
5926 ct
->lf_procedure
.arglist
= arglist_type
;
5929 add_custom_type (ct
);
5934 /* Process a DW_TAG_array_type DIE, adding an LF_ARRAY type and returning its
5938 get_type_num_array_type (dw_die_ref type
, bool in_struct
)
5940 dw_die_ref base_type
, t
, first_child
, c
, *dimension_arr
;
5942 unsigned int dimensions
, i
;
5943 uint32_t element_type
;
5945 base_type
= get_AT_ref (type
, DW_AT_type
);
5949 /* We need to know the size of our base type. Loop through until we find
5952 while (t
&& size
== 0)
5954 switch (dw_get_die_tag (t
))
5956 case DW_TAG_const_type
:
5957 case DW_TAG_volatile_type
:
5958 case DW_TAG_typedef
:
5959 case DW_TAG_enumeration_type
:
5960 t
= get_AT_ref (t
, DW_AT_type
);
5963 case DW_TAG_base_type
:
5964 case DW_TAG_structure_type
:
5965 case DW_TAG_class_type
:
5966 case DW_TAG_union_type
:
5967 case DW_TAG_pointer_type
:
5968 case DW_TAG_reference_type
:
5969 case DW_TAG_rvalue_reference_type
:
5970 size
= get_AT_unsigned (t
, DW_AT_byte_size
);
5981 first_child
= dw_get_die_child (type
);
5985 element_type
= get_type_num (base_type
, in_struct
, false);
5986 if (element_type
== 0)
5989 /* Create an array of our DW_TAG_subrange_type children, in reverse order.
5990 We have to do this because unlike DWARF CodeView doesn't have
5991 multidimensional arrays, so instead we do arrays of arrays. */
5997 c
= dw_get_die_sib (c
);
5998 if (dw_get_die_tag (c
) != DW_TAG_subrange_type
)
6003 while (c
!= first_child
);
6005 if (dimensions
== 0)
6008 dimension_arr
= (dw_die_ref
*) xmalloc (sizeof (dw_die_ref
) * dimensions
);
6014 c
= dw_get_die_sib (c
);
6015 if (dw_get_die_tag (c
) != DW_TAG_subrange_type
)
6018 dimension_arr
[dimensions
- i
- 1] = c
;
6021 while (c
!= first_child
);
6023 /* Record an LF_ARRAY entry for each array dimension. If this leads to
6024 duplicate types, ld will take care of it for us. */
6026 for (i
= 0; i
< dimensions
; i
++)
6028 codeview_custom_type
*ct
;
6031 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6033 size
*= get_AT_unsigned (dimension_arr
[i
], DW_AT_upper_bound
) + 1;
6035 index
= get_AT_ref (dimension_arr
[i
], DW_AT_type
);
6038 ct
->kind
= LF_ARRAY
;
6039 ct
->lf_array
.element_type
= element_type
;
6040 ct
->lf_array
.index_type
= get_type_num (index
, in_struct
, false);
6041 ct
->lf_array
.length_in_bytes
.neg
= false;
6042 ct
->lf_array
.length_in_bytes
.num
= size
;
6044 add_custom_type (ct
);
6046 element_type
= ct
->num
;
6049 free (dimension_arr
);
6051 return element_type
;
6054 /* Process a DIE representing a type definition, add a CodeView type if
6055 necessary, and return its number. If it's something we can't handle, return
6056 0. We keep a hash table so that we're not adding the same type multiple
6057 times - though if we do it's not disastrous, as ld will deduplicate
6058 everything for us. */
6061 get_type_num (dw_die_ref type
, bool in_struct
, bool no_fwd_ref
)
6063 codeview_type
**slot
, *t
;
6071 types_htab
= new hash_table
<die_hasher
> (10);
6073 slot
= types_htab
->find_slot_with_hash (type
, htab_hash_pointer (type
),
6076 if (slot
&& *slot
&& (!no_fwd_ref
|| !(*slot
)->is_fwd_ref
))
6077 return (*slot
)->num
;
6081 switch (dw_get_die_tag (type
))
6083 case DW_TAG_base_type
:
6084 num
= get_type_num_base_type (type
);
6087 case DW_TAG_typedef
:
6088 /* FIXME - signed longs typedef'd as "HRESULT" should get their
6089 own type (T_HRESULT) */
6090 num
= get_type_num (get_AT_ref (type
, DW_AT_type
), in_struct
, false);
6093 case DW_TAG_pointer_type
:
6094 num
= get_type_num_pointer_type (type
, in_struct
);
6097 case DW_TAG_reference_type
:
6098 num
= get_type_num_reference_type (type
, in_struct
, false);
6101 case DW_TAG_rvalue_reference_type
:
6102 num
= get_type_num_reference_type (type
, in_struct
, true);
6105 case DW_TAG_const_type
:
6106 num
= get_type_num_const_type (type
, in_struct
);
6109 case DW_TAG_volatile_type
:
6110 num
= get_type_num_volatile_type (type
, in_struct
);
6113 case DW_TAG_enumeration_type
:
6114 num
= get_type_num_enumeration_type (type
, in_struct
);
6117 case DW_TAG_structure_type
:
6118 case DW_TAG_class_type
:
6119 case DW_TAG_union_type
:
6120 num
= get_type_num_struct (type
, in_struct
, &is_fwd_ref
);
6123 case DW_TAG_array_type
:
6124 num
= get_type_num_array_type (type
, in_struct
);
6127 case DW_TAG_subroutine_type
:
6128 num
= get_type_num_subroutine_type (type
, in_struct
, 0, 0, 0);
6136 /* Check hash table again, and account for the fact that self-referential
6137 structs will have created a forward reference to themselves. */
6139 slot
= types_htab
->find_slot_with_hash (type
, htab_hash_pointer (type
),
6142 if (*slot
&& (*slot
)->is_fwd_ref
&& !is_fwd_ref
)
6145 (*slot
)->is_fwd_ref
= false;
6149 t
= (codeview_type
*) xmalloc (sizeof (codeview_type
));
6152 t
->is_fwd_ref
= is_fwd_ref
;
6159 /* Process a DW_TAG_variable DIE, and add an S_GDATA32 or S_LDATA32 symbol for
6163 add_variable (dw_die_ref die
)
6168 name
= get_AT_string (die
, DW_AT_name
);
6172 s
= (codeview_symbol
*) xmalloc (sizeof (codeview_symbol
));
6175 s
->kind
= get_AT (die
, DW_AT_external
) ? S_GDATA32
: S_LDATA32
;
6176 s
->data_symbol
.type
= get_type_num (get_AT_ref (die
, DW_AT_type
), false,
6178 s
->data_symbol
.name
= get_name (die
);
6179 s
->data_symbol
.die
= die
;
6189 /* Return the type number of the LF_STRING_ID entry corresponding to the given
6190 string, creating a new one if necessary. */
6193 add_string_id (const char *s
)
6195 codeview_custom_type
**slot
;
6196 codeview_custom_type
*ct
;
6198 if (!string_id_htab
)
6199 string_id_htab
= new hash_table
<string_id_hasher
> (10);
6201 slot
= string_id_htab
->find_slot_with_hash (s
, htab_hash_string (s
),
6204 return (*slot
)->num
;
6206 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6209 ct
->kind
= LF_STRING_ID
;
6210 ct
->lf_string_id
.substring
= 0;
6211 ct
->lf_string_id
.string
= xstrdup (s
);
6213 add_custom_type (ct
);
6220 /* Return the type number of the LF_STRING_ID corresponding to the given DIE's
6221 parent, or 0 if it is in the global scope. */
6224 get_scope_string_id (dw_die_ref die
)
6226 dw_die_ref decl
= get_AT_ref (die
, DW_AT_specification
);
6233 die
= dw_get_die_parent (die
);
6237 if (dw_get_die_tag (die
) == DW_TAG_compile_unit
)
6240 name
= get_name (die
);
6244 ret
= add_string_id (name
);
6250 /* Add an LF_FUNC_ID type and return its number (see write_lf_func_id). */
6253 add_lf_func_id (dw_die_ref die
, const char *name
)
6255 uint32_t function_type
, scope_type
;
6256 codeview_custom_type
*ct
;
6258 function_type
= get_type_num_subroutine_type (die
, false, 0, 0, 0);
6259 scope_type
= get_scope_string_id (die
);
6261 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6264 ct
->kind
= LF_FUNC_ID
;
6265 ct
->lf_func_id
.parent_scope
= scope_type
;
6266 ct
->lf_func_id
.function_type
= function_type
;
6267 ct
->lf_func_id
.name
= xstrdup (name
);
6269 add_custom_type (ct
);
6274 /* Add an LF_MFUNC_ID type and return its number (see write_lf_mfunc_id). */
6277 add_lf_mfunc_id (dw_die_ref die
, const char *name
)
6279 uint32_t function_type
= 0, parent_type
;
6280 codeview_custom_type
*ct
;
6281 dw_die_ref spec
= get_AT_ref (die
, DW_AT_specification
);
6283 parent_type
= get_type_num (dw_get_die_parent (spec
), false, false);
6287 codeview_type
**slot
;
6289 slot
= types_htab
->find_slot_with_hash (spec
, htab_hash_pointer (spec
),
6293 function_type
= (*slot
)->num
;
6296 if (function_type
== 0)
6298 function_type
= get_type_num_subroutine_type (die
, false, parent_type
,
6302 ct
= (codeview_custom_type
*) xmalloc (sizeof (codeview_custom_type
));
6305 ct
->kind
= LF_MFUNC_ID
;
6306 ct
->lf_mfunc_id
.parent_type
= parent_type
;
6307 ct
->lf_mfunc_id
.function_type
= function_type
;
6308 ct
->lf_mfunc_id
.name
= xstrdup (name
);
6310 add_custom_type (ct
);
6315 /* Process a DW_TAG_subprogram DIE, and add an S_GPROC32_ID or S_LPROC32_ID
6319 add_function (dw_die_ref die
)
6321 const char *name
= get_AT_string (die
, DW_AT_name
);
6322 uint32_t func_id_type
;
6324 dw_die_ref spec
= get_AT_ref (die
, DW_AT_specification
);
6325 bool do_mfunc_id
= false;
6330 if (spec
&& dw_get_die_parent (spec
))
6332 switch (dw_get_die_tag (dw_get_die_parent (spec
)))
6334 case DW_TAG_class_type
:
6335 case DW_TAG_structure_type
:
6336 case DW_TAG_union_type
:
6346 func_id_type
= add_lf_mfunc_id (die
, name
);
6348 func_id_type
= add_lf_func_id (die
, name
);
6350 /* Add an S_GPROC32_ID / S_LPROC32_ID symbol. */
6352 s
= (codeview_symbol
*) xmalloc (sizeof (codeview_symbol
));
6355 s
->kind
= get_AT (die
, DW_AT_external
) ? S_GPROC32_ID
: S_LPROC32_ID
;
6356 s
->function
.parent
= 0;
6357 s
->function
.end
= 0;
6358 s
->function
.next
= 0;
6359 s
->function
.type
= func_id_type
;
6360 s
->function
.flags
= 0;
6361 s
->function
.name
= get_name (die
);
6362 s
->function
.die
= die
;
6372 /* Loop through the DIEs that have been output for our TU, and add CodeView
6373 symbols for them. */
6376 codeview_debug_early_finish (dw_die_ref die
)
6378 dw_die_ref first_child
, c
;
6380 first_child
= dw_get_die_child (die
);
6389 switch (dw_get_die_tag (c
))
6391 case DW_TAG_variable
:
6394 case DW_TAG_subprogram
:
6401 c
= dw_get_die_sib (c
);
6403 while (c
!= first_child
);
6405 flush_deferred_types ();