[PATCH] RISC-V: Move UNSPEC_SSP_SET and UNSPEC_SSP_TEST to correct enum
[gcc.git] / gcc / dwarf2codeview.cc
blobd98b50c73c3ca0d3f30e9f0df4b6f113c3ed9e8b
1 /* Generate CodeView debugging info from the GCC DWARF.
2 Copyright (C) 2023-2025 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
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
14 for more details.
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. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "target.h"
28 #include "output.h"
29 #include "errors.h"
30 #include "md5.h"
31 #include "function.h"
32 #include "version.h"
33 #include "tree.h"
34 #include "langhooks.h"
35 #include "dwarf2out.h"
36 #include "dwarf2codeview.h"
37 #include "rtl.h"
39 #ifdef CODEVIEW_DEBUGGING_INFO
41 #define CV_SIGNATURE_C13 4
43 #define DEBUG_S_SYMBOLS 0xf1
44 #define DEBUG_S_LINES 0xf2
45 #define DEBUG_S_STRINGTABLE 0xf3
46 #define DEBUG_S_FILECHKSMS 0xf4
47 #define DEBUG_S_INLINEELINES 0xf6
49 #define CHKSUM_TYPE_MD5 1
51 #define CV_CFL_80386 0x03
52 #define CV_CFL_X64 0xD0
54 #define CV_CFL_C 0x00
55 #define CV_CFL_CXX 0x01
57 #define CV_INLINEE_SOURCE_LINE_SIGNATURE 0x0
59 #define FIRST_TYPE 0x1000
61 #define LINE_LABEL "Lcvline"
62 #define END_FUNC_LABEL "Lcvendfunc"
63 #define SYMBOL_START_LABEL "Lcvsymstart"
64 #define SYMBOL_END_LABEL "Lcvsymend"
66 /* There's two bytes available for each type's size, but follow MSVC's lead in
67 capping the LF_FIELDLIST size at fb00 (minus 8 bytes for the LF_INDEX
68 pointing to the overflow entry). */
69 #define MAX_FIELDLIST_SIZE 0xfaf8
71 #define HASH_SIZE 16
73 /* This is enum SYM_ENUM_e in Microsoft's cvinfo.h. */
75 enum cv_sym_type {
76 S_END = 0x0006,
77 S_FRAMEPROC = 0x1012,
78 S_BLOCK32 = 0x1103,
79 S_REGISTER = 0x1106,
80 S_LDATA32 = 0x110c,
81 S_GDATA32 = 0x110d,
82 S_REGREL32 = 0x1111,
83 S_COMPILE3 = 0x113c,
84 S_LOCAL = 0x113e,
85 S_DEFRANGE_REGISTER = 0x1141,
86 S_DEFRANGE_REGISTER_REL = 0x1145,
87 S_LPROC32_ID = 0x1146,
88 S_GPROC32_ID = 0x1147,
89 S_INLINESITE = 0x114d,
90 S_INLINESITE_END = 0x114e,
91 S_PROC_ID_END = 0x114f
94 /* This is enum LEAF_ENUM_e in Microsoft's cvinfo.h. */
96 enum cv_leaf_type {
97 LF_PAD1 = 0xf1,
98 LF_PAD2 = 0xf2,
99 LF_PAD3 = 0xf3,
100 LF_MODIFIER = 0x1001,
101 LF_POINTER = 0x1002,
102 LF_PROCEDURE = 0x1008,
103 LF_MFUNCTION = 0x1009,
104 LF_ARGLIST = 0x1201,
105 LF_FIELDLIST = 0x1203,
106 LF_BITFIELD = 0x1205,
107 LF_METHODLIST = 0x1206,
108 LF_BCLASS = 0x1400,
109 LF_INDEX = 0x1404,
110 LF_ENUMERATE = 0x1502,
111 LF_ARRAY = 0x1503,
112 LF_CLASS = 0x1504,
113 LF_STRUCTURE = 0x1505,
114 LF_UNION = 0x1506,
115 LF_ENUM = 0x1507,
116 LF_MEMBER = 0x150d,
117 LF_STMEMBER = 0x150e,
118 LF_METHOD = 0x150f,
119 LF_NESTTYPE = 0x1510,
120 LF_ONEMETHOD = 0x1511,
121 LF_FUNC_ID = 0x1601,
122 LF_MFUNC_ID = 0x1602,
123 LF_STRING_ID = 0x1605,
124 LF_CHAR = 0x8000,
125 LF_SHORT = 0x8001,
126 LF_USHORT = 0x8002,
127 LF_LONG = 0x8003,
128 LF_ULONG = 0x8004,
129 LF_QUADWORD = 0x8009,
130 LF_UQUADWORD = 0x800a
133 /* These come from enum CV_HREG_e in Microsoft's cvconst.h. */
135 enum cv_x86_register {
136 CV_REG_NONE = 0,
137 CV_REG_AL = 1,
138 CV_REG_CL = 2,
139 CV_REG_DL = 3,
140 CV_REG_BL = 4,
141 CV_REG_AH = 5,
142 CV_REG_CH = 6,
143 CV_REG_DH = 7,
144 CV_REG_BH = 8,
145 CV_REG_AX = 9,
146 CV_REG_CX = 10,
147 CV_REG_DX = 11,
148 CV_REG_BX = 12,
149 CV_REG_SP = 13,
150 CV_REG_BP = 14,
151 CV_REG_SI = 15,
152 CV_REG_DI = 16,
153 CV_REG_EAX = 17,
154 CV_REG_ECX = 18,
155 CV_REG_EDX = 19,
156 CV_REG_EBX = 20,
157 CV_REG_ESP = 21,
158 CV_REG_EBP = 22,
159 CV_REG_ESI = 23,
160 CV_REG_EDI = 24,
161 CV_REG_ES = 25,
162 CV_REG_CS = 26,
163 CV_REG_SS = 27,
164 CV_REG_DS = 28,
165 CV_REG_FS = 29,
166 CV_REG_GS = 30,
167 CV_REG_IP = 31,
168 CV_REG_FLAGS = 32,
169 CV_REG_EIP = 33,
170 CV_REG_EFLAGS = 34,
171 CV_REG_TEMP = 40,
172 CV_REG_TEMPH = 41,
173 CV_REG_QUOTE = 42,
174 CV_REG_PCDR3 = 43,
175 CV_REG_PCDR4 = 44,
176 CV_REG_PCDR5 = 45,
177 CV_REG_PCDR6 = 46,
178 CV_REG_PCDR7 = 47,
179 CV_REG_CR0 = 80,
180 CV_REG_CR1 = 81,
181 CV_REG_CR2 = 82,
182 CV_REG_CR3 = 83,
183 CV_REG_CR4 = 84,
184 CV_REG_DR0 = 90,
185 CV_REG_DR1 = 91,
186 CV_REG_DR2 = 92,
187 CV_REG_DR3 = 93,
188 CV_REG_DR4 = 94,
189 CV_REG_DR5 = 95,
190 CV_REG_DR6 = 96,
191 CV_REG_DR7 = 97,
192 CV_REG_GDTR = 110,
193 CV_REG_GDTL = 111,
194 CV_REG_IDTR = 112,
195 CV_REG_IDTL = 113,
196 CV_REG_LDTR = 114,
197 CV_REG_TR = 115,
198 CV_REG_PSEUDO1 = 116,
199 CV_REG_PSEUDO2 = 117,
200 CV_REG_PSEUDO3 = 118,
201 CV_REG_PSEUDO4 = 119,
202 CV_REG_PSEUDO5 = 120,
203 CV_REG_PSEUDO6 = 121,
204 CV_REG_PSEUDO7 = 122,
205 CV_REG_PSEUDO8 = 123,
206 CV_REG_PSEUDO9 = 124,
207 CV_REG_ST0 = 128,
208 CV_REG_ST1 = 129,
209 CV_REG_ST2 = 130,
210 CV_REG_ST3 = 131,
211 CV_REG_ST4 = 132,
212 CV_REG_ST5 = 133,
213 CV_REG_ST6 = 134,
214 CV_REG_ST7 = 135,
215 CV_REG_CTRL = 136,
216 CV_REG_STAT = 137,
217 CV_REG_TAG = 138,
218 CV_REG_FPIP = 139,
219 CV_REG_FPCS = 140,
220 CV_REG_FPDO = 141,
221 CV_REG_FPDS = 142,
222 CV_REG_ISEM = 143,
223 CV_REG_FPEIP = 144,
224 CV_REG_FPEDO = 145,
225 CV_REG_MM0 = 146,
226 CV_REG_MM1 = 147,
227 CV_REG_MM2 = 148,
228 CV_REG_MM3 = 149,
229 CV_REG_MM4 = 150,
230 CV_REG_MM5 = 151,
231 CV_REG_MM6 = 152,
232 CV_REG_MM7 = 153,
233 CV_REG_XMM0 = 154,
234 CV_REG_XMM1 = 155,
235 CV_REG_XMM2 = 156,
236 CV_REG_XMM3 = 157,
237 CV_REG_XMM4 = 158,
238 CV_REG_XMM5 = 159,
239 CV_REG_XMM6 = 160,
240 CV_REG_XMM7 = 161,
241 CV_REG_XMM00 = 162,
242 CV_REG_XMM01 = 163,
243 CV_REG_XMM02 = 164,
244 CV_REG_XMM03 = 165,
245 CV_REG_XMM10 = 166,
246 CV_REG_XMM11 = 167,
247 CV_REG_XMM12 = 168,
248 CV_REG_XMM13 = 169,
249 CV_REG_XMM20 = 170,
250 CV_REG_XMM21 = 171,
251 CV_REG_XMM22 = 172,
252 CV_REG_XMM23 = 173,
253 CV_REG_XMM30 = 174,
254 CV_REG_XMM31 = 175,
255 CV_REG_XMM32 = 176,
256 CV_REG_XMM33 = 177,
257 CV_REG_XMM40 = 178,
258 CV_REG_XMM41 = 179,
259 CV_REG_XMM42 = 180,
260 CV_REG_XMM43 = 181,
261 CV_REG_XMM50 = 182,
262 CV_REG_XMM51 = 183,
263 CV_REG_XMM52 = 184,
264 CV_REG_XMM53 = 185,
265 CV_REG_XMM60 = 186,
266 CV_REG_XMM61 = 187,
267 CV_REG_XMM62 = 188,
268 CV_REG_XMM63 = 189,
269 CV_REG_XMM70 = 190,
270 CV_REG_XMM71 = 191,
271 CV_REG_XMM72 = 192,
272 CV_REG_XMM73 = 193,
273 CV_REG_XMM0L = 194,
274 CV_REG_XMM1L = 195,
275 CV_REG_XMM2L = 196,
276 CV_REG_XMM3L = 197,
277 CV_REG_XMM4L = 198,
278 CV_REG_XMM5L = 199,
279 CV_REG_XMM6L = 200,
280 CV_REG_XMM7L = 201,
281 CV_REG_XMM0H = 202,
282 CV_REG_XMM1H = 203,
283 CV_REG_XMM2H = 204,
284 CV_REG_XMM3H = 205,
285 CV_REG_XMM4H = 206,
286 CV_REG_XMM5H = 207,
287 CV_REG_XMM6H = 208,
288 CV_REG_XMM7H = 209,
289 CV_REG_MXCSR = 211,
290 CV_REG_EDXEAX = 212,
291 CV_REG_EMM0L = 220,
292 CV_REG_EMM1L = 221,
293 CV_REG_EMM2L = 222,
294 CV_REG_EMM3L = 223,
295 CV_REG_EMM4L = 224,
296 CV_REG_EMM5L = 225,
297 CV_REG_EMM6L = 226,
298 CV_REG_EMM7L = 227,
299 CV_REG_EMM0H = 228,
300 CV_REG_EMM1H = 229,
301 CV_REG_EMM2H = 230,
302 CV_REG_EMM3H = 231,
303 CV_REG_EMM4H = 232,
304 CV_REG_EMM5H = 233,
305 CV_REG_EMM6H = 234,
306 CV_REG_EMM7H = 235,
307 CV_REG_MM00 = 236,
308 CV_REG_MM01 = 237,
309 CV_REG_MM10 = 238,
310 CV_REG_MM11 = 239,
311 CV_REG_MM20 = 240,
312 CV_REG_MM21 = 241,
313 CV_REG_MM30 = 242,
314 CV_REG_MM31 = 243,
315 CV_REG_MM40 = 244,
316 CV_REG_MM41 = 245,
317 CV_REG_MM50 = 246,
318 CV_REG_MM51 = 247,
319 CV_REG_MM60 = 248,
320 CV_REG_MM61 = 249,
321 CV_REG_MM70 = 250,
322 CV_REG_MM71 = 251,
323 CV_REG_YMM0 = 252,
324 CV_REG_YMM1 = 253,
325 CV_REG_YMM2 = 254,
326 CV_REG_YMM3 = 255,
327 CV_REG_YMM4 = 256,
328 CV_REG_YMM5 = 257,
329 CV_REG_YMM6 = 258,
330 CV_REG_YMM7 = 259,
331 CV_REG_YMM0H = 260,
332 CV_REG_YMM1H = 261,
333 CV_REG_YMM2H = 262,
334 CV_REG_YMM3H = 263,
335 CV_REG_YMM4H = 264,
336 CV_REG_YMM5H = 265,
337 CV_REG_YMM6H = 266,
338 CV_REG_YMM7H = 267,
339 CV_REG_YMM0I0 = 268,
340 CV_REG_YMM0I1 = 269,
341 CV_REG_YMM0I2 = 270,
342 CV_REG_YMM0I3 = 271,
343 CV_REG_YMM1I0 = 272,
344 CV_REG_YMM1I1 = 273,
345 CV_REG_YMM1I2 = 274,
346 CV_REG_YMM1I3 = 275,
347 CV_REG_YMM2I0 = 276,
348 CV_REG_YMM2I1 = 277,
349 CV_REG_YMM2I2 = 278,
350 CV_REG_YMM2I3 = 279,
351 CV_REG_YMM3I0 = 280,
352 CV_REG_YMM3I1 = 281,
353 CV_REG_YMM3I2 = 282,
354 CV_REG_YMM3I3 = 283,
355 CV_REG_YMM4I0 = 284,
356 CV_REG_YMM4I1 = 285,
357 CV_REG_YMM4I2 = 286,
358 CV_REG_YMM4I3 = 287,
359 CV_REG_YMM5I0 = 288,
360 CV_REG_YMM5I1 = 289,
361 CV_REG_YMM5I2 = 290,
362 CV_REG_YMM5I3 = 291,
363 CV_REG_YMM6I0 = 292,
364 CV_REG_YMM6I1 = 293,
365 CV_REG_YMM6I2 = 294,
366 CV_REG_YMM6I3 = 295,
367 CV_REG_YMM7I0 = 296,
368 CV_REG_YMM7I1 = 297,
369 CV_REG_YMM7I2 = 298,
370 CV_REG_YMM7I3 = 299,
371 CV_REG_YMM0F0 = 300,
372 CV_REG_YMM0F1 = 301,
373 CV_REG_YMM0F2 = 302,
374 CV_REG_YMM0F3 = 303,
375 CV_REG_YMM0F4 = 304,
376 CV_REG_YMM0F5 = 305,
377 CV_REG_YMM0F6 = 306,
378 CV_REG_YMM0F7 = 307,
379 CV_REG_YMM1F0 = 308,
380 CV_REG_YMM1F1 = 309,
381 CV_REG_YMM1F2 = 310,
382 CV_REG_YMM1F3 = 311,
383 CV_REG_YMM1F4 = 312,
384 CV_REG_YMM1F5 = 313,
385 CV_REG_YMM1F6 = 314,
386 CV_REG_YMM1F7 = 315,
387 CV_REG_YMM2F0 = 316,
388 CV_REG_YMM2F1 = 317,
389 CV_REG_YMM2F2 = 318,
390 CV_REG_YMM2F3 = 319,
391 CV_REG_YMM2F4 = 320,
392 CV_REG_YMM2F5 = 321,
393 CV_REG_YMM2F6 = 322,
394 CV_REG_YMM2F7 = 323,
395 CV_REG_YMM3F0 = 324,
396 CV_REG_YMM3F1 = 325,
397 CV_REG_YMM3F2 = 326,
398 CV_REG_YMM3F3 = 327,
399 CV_REG_YMM3F4 = 328,
400 CV_REG_YMM3F5 = 329,
401 CV_REG_YMM3F6 = 330,
402 CV_REG_YMM3F7 = 331,
403 CV_REG_YMM4F0 = 332,
404 CV_REG_YMM4F1 = 333,
405 CV_REG_YMM4F2 = 334,
406 CV_REG_YMM4F3 = 335,
407 CV_REG_YMM4F4 = 336,
408 CV_REG_YMM4F5 = 337,
409 CV_REG_YMM4F6 = 338,
410 CV_REG_YMM4F7 = 339,
411 CV_REG_YMM5F0 = 340,
412 CV_REG_YMM5F1 = 341,
413 CV_REG_YMM5F2 = 342,
414 CV_REG_YMM5F3 = 343,
415 CV_REG_YMM5F4 = 344,
416 CV_REG_YMM5F5 = 345,
417 CV_REG_YMM5F6 = 346,
418 CV_REG_YMM5F7 = 347,
419 CV_REG_YMM6F0 = 348,
420 CV_REG_YMM6F1 = 349,
421 CV_REG_YMM6F2 = 350,
422 CV_REG_YMM6F3 = 351,
423 CV_REG_YMM6F4 = 352,
424 CV_REG_YMM6F5 = 353,
425 CV_REG_YMM6F6 = 354,
426 CV_REG_YMM6F7 = 355,
427 CV_REG_YMM7F0 = 356,
428 CV_REG_YMM7F1 = 357,
429 CV_REG_YMM7F2 = 358,
430 CV_REG_YMM7F3 = 359,
431 CV_REG_YMM7F4 = 360,
432 CV_REG_YMM7F5 = 361,
433 CV_REG_YMM7F6 = 362,
434 CV_REG_YMM7F7 = 363,
435 CV_REG_YMM0D0 = 364,
436 CV_REG_YMM0D1 = 365,
437 CV_REG_YMM0D2 = 366,
438 CV_REG_YMM0D3 = 367,
439 CV_REG_YMM1D0 = 368,
440 CV_REG_YMM1D1 = 369,
441 CV_REG_YMM1D2 = 370,
442 CV_REG_YMM1D3 = 371,
443 CV_REG_YMM2D0 = 372,
444 CV_REG_YMM2D1 = 373,
445 CV_REG_YMM2D2 = 374,
446 CV_REG_YMM2D3 = 375,
447 CV_REG_YMM3D0 = 376,
448 CV_REG_YMM3D1 = 377,
449 CV_REG_YMM3D2 = 378,
450 CV_REG_YMM3D3 = 379,
451 CV_REG_YMM4D0 = 380,
452 CV_REG_YMM4D1 = 381,
453 CV_REG_YMM4D2 = 382,
454 CV_REG_YMM4D3 = 383,
455 CV_REG_YMM5D0 = 384,
456 CV_REG_YMM5D1 = 385,
457 CV_REG_YMM5D2 = 386,
458 CV_REG_YMM5D3 = 387,
459 CV_REG_YMM6D0 = 388,
460 CV_REG_YMM6D1 = 389,
461 CV_REG_YMM6D2 = 390,
462 CV_REG_YMM6D3 = 391,
463 CV_REG_YMM7D0 = 392,
464 CV_REG_YMM7D1 = 393,
465 CV_REG_YMM7D2 = 394,
466 CV_REG_YMM7D3 = 395,
467 CV_REG_BND0 = 396,
468 CV_REG_BND1 = 397,
469 CV_REG_BND2 = 398,
470 CV_REG_BND3 = 399
473 enum cv_amd64_register {
474 CV_AMD64_NOREG = 0,
475 CV_AMD64_AL = 1,
476 CV_AMD64_CL = 2,
477 CV_AMD64_DL = 3,
478 CV_AMD64_BL = 4,
479 CV_AMD64_AH = 5,
480 CV_AMD64_CH = 6,
481 CV_AMD64_DH = 7,
482 CV_AMD64_BH = 8,
483 CV_AMD64_AX = 9,
484 CV_AMD64_CX = 10,
485 CV_AMD64_DX = 11,
486 CV_AMD64_BX = 12,
487 CV_AMD64_SP = 13,
488 CV_AMD64_BP = 14,
489 CV_AMD64_SI = 15,
490 CV_AMD64_DI = 16,
491 CV_AMD64_EAX = 17,
492 CV_AMD64_ECX = 18,
493 CV_AMD64_EDX = 19,
494 CV_AMD64_EBX = 20,
495 CV_AMD64_ESP = 21,
496 CV_AMD64_EBP = 22,
497 CV_AMD64_ESI = 23,
498 CV_AMD64_EDI = 24,
499 CV_AMD64_ES = 25,
500 CV_AMD64_CS = 26,
501 CV_AMD64_SS = 27,
502 CV_AMD64_DS = 28,
503 CV_AMD64_FS = 29,
504 CV_AMD64_GS = 30,
505 CV_AMD64_FLAGS = 32,
506 CV_AMD64_RIP = 33,
507 CV_AMD64_EFLAGS = 34,
508 CV_AMD64_CR0 = 80,
509 CV_AMD64_CR1 = 81,
510 CV_AMD64_CR2 = 82,
511 CV_AMD64_CR3 = 83,
512 CV_AMD64_CR4 = 84,
513 CV_AMD64_CR8 = 88,
514 CV_AMD64_DR0 = 90,
515 CV_AMD64_DR1 = 91,
516 CV_AMD64_DR2 = 92,
517 CV_AMD64_DR3 = 93,
518 CV_AMD64_DR4 = 94,
519 CV_AMD64_DR5 = 95,
520 CV_AMD64_DR6 = 96,
521 CV_AMD64_DR7 = 97,
522 CV_AMD64_DR8 = 98,
523 CV_AMD64_DR9 = 99,
524 CV_AMD64_DR10 = 100,
525 CV_AMD64_DR11 = 101,
526 CV_AMD64_DR12 = 102,
527 CV_AMD64_DR13 = 103,
528 CV_AMD64_DR14 = 104,
529 CV_AMD64_DR15 = 105,
530 CV_AMD64_GDTR = 110,
531 CV_AMD64_GDTL = 111,
532 CV_AMD64_IDTR = 112,
533 CV_AMD64_IDTL = 113,
534 CV_AMD64_LDTR = 114,
535 CV_AMD64_TR = 115,
536 CV_AMD64_ST0 = 128,
537 CV_AMD64_ST1 = 129,
538 CV_AMD64_ST2 = 130,
539 CV_AMD64_ST3 = 131,
540 CV_AMD64_ST4 = 132,
541 CV_AMD64_ST5 = 133,
542 CV_AMD64_ST6 = 134,
543 CV_AMD64_ST7 = 135,
544 CV_AMD64_CTRL = 136,
545 CV_AMD64_STAT = 137,
546 CV_AMD64_TAG = 138,
547 CV_AMD64_FPIP = 139,
548 CV_AMD64_FPCS = 140,
549 CV_AMD64_FPDO = 141,
550 CV_AMD64_FPDS = 142,
551 CV_AMD64_ISEM = 143,
552 CV_AMD64_FPEIP = 144,
553 CV_AMD64_FPEDO = 145,
554 CV_AMD64_MM0 = 146,
555 CV_AMD64_MM1 = 147,
556 CV_AMD64_MM2 = 148,
557 CV_AMD64_MM3 = 149,
558 CV_AMD64_MM4 = 150,
559 CV_AMD64_MM5 = 151,
560 CV_AMD64_MM6 = 152,
561 CV_AMD64_MM7 = 153,
562 CV_AMD64_XMM0 = 154,
563 CV_AMD64_XMM1 = 155,
564 CV_AMD64_XMM2 = 156,
565 CV_AMD64_XMM3 = 157,
566 CV_AMD64_XMM4 = 158,
567 CV_AMD64_XMM5 = 159,
568 CV_AMD64_XMM6 = 160,
569 CV_AMD64_XMM7 = 161,
570 CV_AMD64_XMM0_0 = 162,
571 CV_AMD64_XMM0_1 = 163,
572 CV_AMD64_XMM0_2 = 164,
573 CV_AMD64_XMM0_3 = 165,
574 CV_AMD64_XMM1_0 = 166,
575 CV_AMD64_XMM1_1 = 167,
576 CV_AMD64_XMM1_2 = 168,
577 CV_AMD64_XMM1_3 = 169,
578 CV_AMD64_XMM2_0 = 170,
579 CV_AMD64_XMM2_1 = 171,
580 CV_AMD64_XMM2_2 = 172,
581 CV_AMD64_XMM2_3 = 173,
582 CV_AMD64_XMM3_0 = 174,
583 CV_AMD64_XMM3_1 = 175,
584 CV_AMD64_XMM3_2 = 176,
585 CV_AMD64_XMM3_3 = 177,
586 CV_AMD64_XMM4_0 = 178,
587 CV_AMD64_XMM4_1 = 179,
588 CV_AMD64_XMM4_2 = 180,
589 CV_AMD64_XMM4_3 = 181,
590 CV_AMD64_XMM5_0 = 182,
591 CV_AMD64_XMM5_1 = 183,
592 CV_AMD64_XMM5_2 = 184,
593 CV_AMD64_XMM5_3 = 185,
594 CV_AMD64_XMM6_0 = 186,
595 CV_AMD64_XMM6_1 = 187,
596 CV_AMD64_XMM6_2 = 188,
597 CV_AMD64_XMM6_3 = 189,
598 CV_AMD64_XMM7_0 = 190,
599 CV_AMD64_XMM7_1 = 191,
600 CV_AMD64_XMM7_2 = 192,
601 CV_AMD64_XMM7_3 = 193,
602 CV_AMD64_XMM0L = 194,
603 CV_AMD64_XMM1L = 195,
604 CV_AMD64_XMM2L = 196,
605 CV_AMD64_XMM3L = 197,
606 CV_AMD64_XMM4L = 198,
607 CV_AMD64_XMM5L = 199,
608 CV_AMD64_XMM6L = 200,
609 CV_AMD64_XMM7L = 201,
610 CV_AMD64_XMM0H = 202,
611 CV_AMD64_XMM1H = 203,
612 CV_AMD64_XMM2H = 204,
613 CV_AMD64_XMM3H = 205,
614 CV_AMD64_XMM4H = 206,
615 CV_AMD64_XMM5H = 207,
616 CV_AMD64_XMM6H = 208,
617 CV_AMD64_XMM7H = 209,
618 CV_AMD64_MXCSR = 211,
619 CV_AMD64_EMM0L = 220,
620 CV_AMD64_EMM1L = 221,
621 CV_AMD64_EMM2L = 222,
622 CV_AMD64_EMM3L = 223,
623 CV_AMD64_EMM4L = 224,
624 CV_AMD64_EMM5L = 225,
625 CV_AMD64_EMM6L = 226,
626 CV_AMD64_EMM7L = 227,
627 CV_AMD64_EMM0H = 228,
628 CV_AMD64_EMM1H = 229,
629 CV_AMD64_EMM2H = 230,
630 CV_AMD64_EMM3H = 231,
631 CV_AMD64_EMM4H = 232,
632 CV_AMD64_EMM5H = 233,
633 CV_AMD64_EMM6H = 234,
634 CV_AMD64_EMM7H = 235,
635 CV_AMD64_MM00 = 236,
636 CV_AMD64_MM01 = 237,
637 CV_AMD64_MM10 = 238,
638 CV_AMD64_MM11 = 239,
639 CV_AMD64_MM20 = 240,
640 CV_AMD64_MM21 = 241,
641 CV_AMD64_MM30 = 242,
642 CV_AMD64_MM31 = 243,
643 CV_AMD64_MM40 = 244,
644 CV_AMD64_MM41 = 245,
645 CV_AMD64_MM50 = 246,
646 CV_AMD64_MM51 = 247,
647 CV_AMD64_MM60 = 248,
648 CV_AMD64_MM61 = 249,
649 CV_AMD64_MM70 = 250,
650 CV_AMD64_MM71 = 251,
651 CV_AMD64_XMM8 = 252,
652 CV_AMD64_XMM9 = 253,
653 CV_AMD64_XMM10 = 254,
654 CV_AMD64_XMM11 = 255,
655 CV_AMD64_XMM12 = 256,
656 CV_AMD64_XMM13 = 257,
657 CV_AMD64_XMM14 = 258,
658 CV_AMD64_XMM15 = 259,
659 CV_AMD64_XMM8_0 = 260,
660 CV_AMD64_XMM8_1 = 261,
661 CV_AMD64_XMM8_2 = 262,
662 CV_AMD64_XMM8_3 = 263,
663 CV_AMD64_XMM9_0 = 264,
664 CV_AMD64_XMM9_1 = 265,
665 CV_AMD64_XMM9_2 = 266,
666 CV_AMD64_XMM9_3 = 267,
667 CV_AMD64_XMM10_0 = 268,
668 CV_AMD64_XMM10_1 = 269,
669 CV_AMD64_XMM10_2 = 270,
670 CV_AMD64_XMM10_3 = 271,
671 CV_AMD64_XMM11_0 = 272,
672 CV_AMD64_XMM11_1 = 273,
673 CV_AMD64_XMM11_2 = 274,
674 CV_AMD64_XMM11_3 = 275,
675 CV_AMD64_XMM12_0 = 276,
676 CV_AMD64_XMM12_1 = 277,
677 CV_AMD64_XMM12_2 = 278,
678 CV_AMD64_XMM12_3 = 279,
679 CV_AMD64_XMM13_0 = 280,
680 CV_AMD64_XMM13_1 = 281,
681 CV_AMD64_XMM13_2 = 282,
682 CV_AMD64_XMM13_3 = 283,
683 CV_AMD64_XMM14_0 = 284,
684 CV_AMD64_XMM14_1 = 285,
685 CV_AMD64_XMM14_2 = 286,
686 CV_AMD64_XMM14_3 = 287,
687 CV_AMD64_XMM15_0 = 288,
688 CV_AMD64_XMM15_1 = 289,
689 CV_AMD64_XMM15_2 = 290,
690 CV_AMD64_XMM15_3 = 291,
691 CV_AMD64_XMM8L = 292,
692 CV_AMD64_XMM9L = 293,
693 CV_AMD64_XMM10L = 294,
694 CV_AMD64_XMM11L = 295,
695 CV_AMD64_XMM12L = 296,
696 CV_AMD64_XMM13L = 297,
697 CV_AMD64_XMM14L = 298,
698 CV_AMD64_XMM15L = 299,
699 CV_AMD64_XMM8H = 300,
700 CV_AMD64_XMM9H = 301,
701 CV_AMD64_XMM10H = 302,
702 CV_AMD64_XMM11H = 303,
703 CV_AMD64_XMM12H = 304,
704 CV_AMD64_XMM13H = 305,
705 CV_AMD64_XMM14H = 306,
706 CV_AMD64_XMM15H = 307,
707 CV_AMD64_EMM8L = 308,
708 CV_AMD64_EMM9L = 309,
709 CV_AMD64_EMM10L = 310,
710 CV_AMD64_EMM11L = 311,
711 CV_AMD64_EMM12L = 312,
712 CV_AMD64_EMM13L = 313,
713 CV_AMD64_EMM14L = 314,
714 CV_AMD64_EMM15L = 315,
715 CV_AMD64_EMM8H = 316,
716 CV_AMD64_EMM9H = 317,
717 CV_AMD64_EMM10H = 318,
718 CV_AMD64_EMM11H = 319,
719 CV_AMD64_EMM12H = 320,
720 CV_AMD64_EMM13H = 321,
721 CV_AMD64_EMM14H = 322,
722 CV_AMD64_EMM15H = 323,
723 CV_AMD64_SIL = 324,
724 CV_AMD64_DIL = 325,
725 CV_AMD64_BPL = 326,
726 CV_AMD64_SPL = 327,
727 CV_AMD64_RAX = 328,
728 CV_AMD64_RBX = 329,
729 CV_AMD64_RCX = 330,
730 CV_AMD64_RDX = 331,
731 CV_AMD64_RSI = 332,
732 CV_AMD64_RDI = 333,
733 CV_AMD64_RBP = 334,
734 CV_AMD64_RSP = 335,
735 CV_AMD64_R8 = 336,
736 CV_AMD64_R9 = 337,
737 CV_AMD64_R10 = 338,
738 CV_AMD64_R11 = 339,
739 CV_AMD64_R12 = 340,
740 CV_AMD64_R13 = 341,
741 CV_AMD64_R14 = 342,
742 CV_AMD64_R15 = 343,
743 CV_AMD64_R8B = 344,
744 CV_AMD64_R9B = 345,
745 CV_AMD64_R10B = 346,
746 CV_AMD64_R11B = 347,
747 CV_AMD64_R12B = 348,
748 CV_AMD64_R13B = 349,
749 CV_AMD64_R14B = 350,
750 CV_AMD64_R15B = 351,
751 CV_AMD64_R8W = 352,
752 CV_AMD64_R9W = 353,
753 CV_AMD64_R10W = 354,
754 CV_AMD64_R11W = 355,
755 CV_AMD64_R12W = 356,
756 CV_AMD64_R13W = 357,
757 CV_AMD64_R14W = 358,
758 CV_AMD64_R15W = 359,
759 CV_AMD64_R8D = 360,
760 CV_AMD64_R9D = 361,
761 CV_AMD64_R10D = 362,
762 CV_AMD64_R11D = 363,
763 CV_AMD64_R12D = 364,
764 CV_AMD64_R13D = 365,
765 CV_AMD64_R14D = 366,
766 CV_AMD64_R15D = 367,
767 CV_AMD64_YMM0 = 368,
768 CV_AMD64_YMM1 = 369,
769 CV_AMD64_YMM2 = 370,
770 CV_AMD64_YMM3 = 371,
771 CV_AMD64_YMM4 = 372,
772 CV_AMD64_YMM5 = 373,
773 CV_AMD64_YMM6 = 374,
774 CV_AMD64_YMM7 = 375,
775 CV_AMD64_YMM8 = 376,
776 CV_AMD64_YMM9 = 377,
777 CV_AMD64_YMM10 = 378,
778 CV_AMD64_YMM11 = 379,
779 CV_AMD64_YMM12 = 380,
780 CV_AMD64_YMM13 = 381,
781 CV_AMD64_YMM14 = 382,
782 CV_AMD64_YMM15 = 383,
783 CV_AMD64_YMM0H = 384,
784 CV_AMD64_YMM1H = 385,
785 CV_AMD64_YMM2H = 386,
786 CV_AMD64_YMM3H = 387,
787 CV_AMD64_YMM4H = 388,
788 CV_AMD64_YMM5H = 389,
789 CV_AMD64_YMM6H = 390,
790 CV_AMD64_YMM7H = 391,
791 CV_AMD64_YMM8H = 392,
792 CV_AMD64_YMM9H = 393,
793 CV_AMD64_YMM10H = 394,
794 CV_AMD64_YMM11H = 395,
795 CV_AMD64_YMM12H = 396,
796 CV_AMD64_YMM13H = 397,
797 CV_AMD64_YMM14H = 398,
798 CV_AMD64_YMM15H = 399,
799 CV_AMD64_XMM0IL = 400,
800 CV_AMD64_XMM1IL = 401,
801 CV_AMD64_XMM2IL = 402,
802 CV_AMD64_XMM3IL = 403,
803 CV_AMD64_XMM4IL = 404,
804 CV_AMD64_XMM5IL = 405,
805 CV_AMD64_XMM6IL = 406,
806 CV_AMD64_XMM7IL = 407,
807 CV_AMD64_XMM8IL = 408,
808 CV_AMD64_XMM9IL = 409,
809 CV_AMD64_XMM10IL = 410,
810 CV_AMD64_XMM11IL = 411,
811 CV_AMD64_XMM12IL = 412,
812 CV_AMD64_XMM13IL = 413,
813 CV_AMD64_XMM14IL = 414,
814 CV_AMD64_XMM15IL = 415,
815 CV_AMD64_XMM0IH = 416,
816 CV_AMD64_XMM1IH = 417,
817 CV_AMD64_XMM2IH = 418,
818 CV_AMD64_XMM3IH = 419,
819 CV_AMD64_XMM4IH = 420,
820 CV_AMD64_XMM5IH = 421,
821 CV_AMD64_XMM6IH = 422,
822 CV_AMD64_XMM7IH = 423,
823 CV_AMD64_XMM8IH = 424,
824 CV_AMD64_XMM9IH = 425,
825 CV_AMD64_XMM10IH = 426,
826 CV_AMD64_XMM11IH = 427,
827 CV_AMD64_XMM12IH = 428,
828 CV_AMD64_XMM13IH = 429,
829 CV_AMD64_XMM14IH = 430,
830 CV_AMD64_XMM15IH = 431,
831 CV_AMD64_YMM0I0 = 432,
832 CV_AMD64_YMM0I1 = 433,
833 CV_AMD64_YMM0I2 = 434,
834 CV_AMD64_YMM0I3 = 435,
835 CV_AMD64_YMM1I0 = 436,
836 CV_AMD64_YMM1I1 = 437,
837 CV_AMD64_YMM1I2 = 438,
838 CV_AMD64_YMM1I3 = 439,
839 CV_AMD64_YMM2I0 = 440,
840 CV_AMD64_YMM2I1 = 441,
841 CV_AMD64_YMM2I2 = 442,
842 CV_AMD64_YMM2I3 = 443,
843 CV_AMD64_YMM3I0 = 444,
844 CV_AMD64_YMM3I1 = 445,
845 CV_AMD64_YMM3I2 = 446,
846 CV_AMD64_YMM3I3 = 447,
847 CV_AMD64_YMM4I0 = 448,
848 CV_AMD64_YMM4I1 = 449,
849 CV_AMD64_YMM4I2 = 450,
850 CV_AMD64_YMM4I3 = 451,
851 CV_AMD64_YMM5I0 = 452,
852 CV_AMD64_YMM5I1 = 453,
853 CV_AMD64_YMM5I2 = 454,
854 CV_AMD64_YMM5I3 = 455,
855 CV_AMD64_YMM6I0 = 456,
856 CV_AMD64_YMM6I1 = 457,
857 CV_AMD64_YMM6I2 = 458,
858 CV_AMD64_YMM6I3 = 459,
859 CV_AMD64_YMM7I0 = 460,
860 CV_AMD64_YMM7I1 = 461,
861 CV_AMD64_YMM7I2 = 462,
862 CV_AMD64_YMM7I3 = 463,
863 CV_AMD64_YMM8I0 = 464,
864 CV_AMD64_YMM8I1 = 465,
865 CV_AMD64_YMM8I2 = 466,
866 CV_AMD64_YMM8I3 = 467,
867 CV_AMD64_YMM9I0 = 468,
868 CV_AMD64_YMM9I1 = 469,
869 CV_AMD64_YMM9I2 = 470,
870 CV_AMD64_YMM9I3 = 471,
871 CV_AMD64_YMM10I0 = 472,
872 CV_AMD64_YMM10I1 = 473,
873 CV_AMD64_YMM10I2 = 474,
874 CV_AMD64_YMM10I3 = 475,
875 CV_AMD64_YMM11I0 = 476,
876 CV_AMD64_YMM11I1 = 477,
877 CV_AMD64_YMM11I2 = 478,
878 CV_AMD64_YMM11I3 = 479,
879 CV_AMD64_YMM12I0 = 480,
880 CV_AMD64_YMM12I1 = 481,
881 CV_AMD64_YMM12I2 = 482,
882 CV_AMD64_YMM12I3 = 483,
883 CV_AMD64_YMM13I0 = 484,
884 CV_AMD64_YMM13I1 = 485,
885 CV_AMD64_YMM13I2 = 486,
886 CV_AMD64_YMM13I3 = 487,
887 CV_AMD64_YMM14I0 = 488,
888 CV_AMD64_YMM14I1 = 489,
889 CV_AMD64_YMM14I2 = 490,
890 CV_AMD64_YMM14I3 = 491,
891 CV_AMD64_YMM15I0 = 492,
892 CV_AMD64_YMM15I1 = 493,
893 CV_AMD64_YMM15I2 = 494,
894 CV_AMD64_YMM15I3 = 495,
895 CV_AMD64_YMM0F0 = 496,
896 CV_AMD64_YMM0F1 = 497,
897 CV_AMD64_YMM0F2 = 498,
898 CV_AMD64_YMM0F3 = 499,
899 CV_AMD64_YMM0F4 = 500,
900 CV_AMD64_YMM0F5 = 501,
901 CV_AMD64_YMM0F6 = 502,
902 CV_AMD64_YMM0F7 = 503,
903 CV_AMD64_YMM1F0 = 504,
904 CV_AMD64_YMM1F1 = 505,
905 CV_AMD64_YMM1F2 = 506,
906 CV_AMD64_YMM1F3 = 507,
907 CV_AMD64_YMM1F4 = 508,
908 CV_AMD64_YMM1F5 = 509,
909 CV_AMD64_YMM1F6 = 510,
910 CV_AMD64_YMM1F7 = 511,
911 CV_AMD64_YMM2F0 = 512,
912 CV_AMD64_YMM2F1 = 513,
913 CV_AMD64_YMM2F2 = 514,
914 CV_AMD64_YMM2F3 = 515,
915 CV_AMD64_YMM2F4 = 516,
916 CV_AMD64_YMM2F5 = 517,
917 CV_AMD64_YMM2F6 = 518,
918 CV_AMD64_YMM2F7 = 519,
919 CV_AMD64_YMM3F0 = 520,
920 CV_AMD64_YMM3F1 = 521,
921 CV_AMD64_YMM3F2 = 522,
922 CV_AMD64_YMM3F3 = 523,
923 CV_AMD64_YMM3F4 = 524,
924 CV_AMD64_YMM3F5 = 525,
925 CV_AMD64_YMM3F6 = 526,
926 CV_AMD64_YMM3F7 = 527,
927 CV_AMD64_YMM4F0 = 528,
928 CV_AMD64_YMM4F1 = 529,
929 CV_AMD64_YMM4F2 = 530,
930 CV_AMD64_YMM4F3 = 531,
931 CV_AMD64_YMM4F4 = 532,
932 CV_AMD64_YMM4F5 = 533,
933 CV_AMD64_YMM4F6 = 534,
934 CV_AMD64_YMM4F7 = 535,
935 CV_AMD64_YMM5F0 = 536,
936 CV_AMD64_YMM5F1 = 537,
937 CV_AMD64_YMM5F2 = 538,
938 CV_AMD64_YMM5F3 = 539,
939 CV_AMD64_YMM5F4 = 540,
940 CV_AMD64_YMM5F5 = 541,
941 CV_AMD64_YMM5F6 = 542,
942 CV_AMD64_YMM5F7 = 543,
943 CV_AMD64_YMM6F0 = 544,
944 CV_AMD64_YMM6F1 = 545,
945 CV_AMD64_YMM6F2 = 546,
946 CV_AMD64_YMM6F3 = 547,
947 CV_AMD64_YMM6F4 = 548,
948 CV_AMD64_YMM6F5 = 549,
949 CV_AMD64_YMM6F6 = 550,
950 CV_AMD64_YMM6F7 = 551,
951 CV_AMD64_YMM7F0 = 552,
952 CV_AMD64_YMM7F1 = 553,
953 CV_AMD64_YMM7F2 = 554,
954 CV_AMD64_YMM7F3 = 555,
955 CV_AMD64_YMM7F4 = 556,
956 CV_AMD64_YMM7F5 = 557,
957 CV_AMD64_YMM7F6 = 558,
958 CV_AMD64_YMM7F7 = 559,
959 CV_AMD64_YMM8F0 = 560,
960 CV_AMD64_YMM8F1 = 561,
961 CV_AMD64_YMM8F2 = 562,
962 CV_AMD64_YMM8F3 = 563,
963 CV_AMD64_YMM8F4 = 564,
964 CV_AMD64_YMM8F5 = 565,
965 CV_AMD64_YMM8F6 = 566,
966 CV_AMD64_YMM8F7 = 567,
967 CV_AMD64_YMM9F0 = 568,
968 CV_AMD64_YMM9F1 = 569,
969 CV_AMD64_YMM9F2 = 570,
970 CV_AMD64_YMM9F3 = 571,
971 CV_AMD64_YMM9F4 = 572,
972 CV_AMD64_YMM9F5 = 573,
973 CV_AMD64_YMM9F6 = 574,
974 CV_AMD64_YMM9F7 = 575,
975 CV_AMD64_YMM10F0 = 576,
976 CV_AMD64_YMM10F1 = 577,
977 CV_AMD64_YMM10F2 = 578,
978 CV_AMD64_YMM10F3 = 579,
979 CV_AMD64_YMM10F4 = 580,
980 CV_AMD64_YMM10F5 = 581,
981 CV_AMD64_YMM10F6 = 582,
982 CV_AMD64_YMM10F7 = 583,
983 CV_AMD64_YMM11F0 = 584,
984 CV_AMD64_YMM11F1 = 585,
985 CV_AMD64_YMM11F2 = 586,
986 CV_AMD64_YMM11F3 = 587,
987 CV_AMD64_YMM11F4 = 588,
988 CV_AMD64_YMM11F5 = 589,
989 CV_AMD64_YMM11F6 = 590,
990 CV_AMD64_YMM11F7 = 591,
991 CV_AMD64_YMM12F0 = 592,
992 CV_AMD64_YMM12F1 = 593,
993 CV_AMD64_YMM12F2 = 594,
994 CV_AMD64_YMM12F3 = 595,
995 CV_AMD64_YMM12F4 = 596,
996 CV_AMD64_YMM12F5 = 597,
997 CV_AMD64_YMM12F6 = 598,
998 CV_AMD64_YMM12F7 = 599,
999 CV_AMD64_YMM13F0 = 600,
1000 CV_AMD64_YMM13F1 = 601,
1001 CV_AMD64_YMM13F2 = 602,
1002 CV_AMD64_YMM13F3 = 603,
1003 CV_AMD64_YMM13F4 = 604,
1004 CV_AMD64_YMM13F5 = 605,
1005 CV_AMD64_YMM13F6 = 606,
1006 CV_AMD64_YMM13F7 = 607,
1007 CV_AMD64_YMM14F0 = 608,
1008 CV_AMD64_YMM14F1 = 609,
1009 CV_AMD64_YMM14F2 = 610,
1010 CV_AMD64_YMM14F3 = 611,
1011 CV_AMD64_YMM14F4 = 612,
1012 CV_AMD64_YMM14F5 = 613,
1013 CV_AMD64_YMM14F6 = 614,
1014 CV_AMD64_YMM14F7 = 615,
1015 CV_AMD64_YMM15F0 = 616,
1016 CV_AMD64_YMM15F1 = 617,
1017 CV_AMD64_YMM15F2 = 618,
1018 CV_AMD64_YMM15F3 = 619,
1019 CV_AMD64_YMM15F4 = 620,
1020 CV_AMD64_YMM15F5 = 621,
1021 CV_AMD64_YMM15F6 = 622,
1022 CV_AMD64_YMM15F7 = 623,
1023 CV_AMD64_YMM0D0 = 624,
1024 CV_AMD64_YMM0D1 = 625,
1025 CV_AMD64_YMM0D2 = 626,
1026 CV_AMD64_YMM0D3 = 627,
1027 CV_AMD64_YMM1D0 = 628,
1028 CV_AMD64_YMM1D1 = 629,
1029 CV_AMD64_YMM1D2 = 630,
1030 CV_AMD64_YMM1D3 = 631,
1031 CV_AMD64_YMM2D0 = 632,
1032 CV_AMD64_YMM2D1 = 633,
1033 CV_AMD64_YMM2D2 = 634,
1034 CV_AMD64_YMM2D3 = 635,
1035 CV_AMD64_YMM3D0 = 636,
1036 CV_AMD64_YMM3D1 = 637,
1037 CV_AMD64_YMM3D2 = 638,
1038 CV_AMD64_YMM3D3 = 639,
1039 CV_AMD64_YMM4D0 = 640,
1040 CV_AMD64_YMM4D1 = 641,
1041 CV_AMD64_YMM4D2 = 642,
1042 CV_AMD64_YMM4D3 = 643,
1043 CV_AMD64_YMM5D0 = 644,
1044 CV_AMD64_YMM5D1 = 645,
1045 CV_AMD64_YMM5D2 = 646,
1046 CV_AMD64_YMM5D3 = 647,
1047 CV_AMD64_YMM6D0 = 648,
1048 CV_AMD64_YMM6D1 = 649,
1049 CV_AMD64_YMM6D2 = 650,
1050 CV_AMD64_YMM6D3 = 651,
1051 CV_AMD64_YMM7D0 = 652,
1052 CV_AMD64_YMM7D1 = 653,
1053 CV_AMD64_YMM7D2 = 654,
1054 CV_AMD64_YMM7D3 = 655,
1055 CV_AMD64_YMM8D0 = 656,
1056 CV_AMD64_YMM8D1 = 657,
1057 CV_AMD64_YMM8D2 = 658,
1058 CV_AMD64_YMM8D3 = 659,
1059 CV_AMD64_YMM9D0 = 660,
1060 CV_AMD64_YMM9D1 = 661,
1061 CV_AMD64_YMM9D2 = 662,
1062 CV_AMD64_YMM9D3 = 663,
1063 CV_AMD64_YMM10D0 = 664,
1064 CV_AMD64_YMM10D1 = 665,
1065 CV_AMD64_YMM10D2 = 666,
1066 CV_AMD64_YMM10D3 = 667,
1067 CV_AMD64_YMM11D0 = 668,
1068 CV_AMD64_YMM11D1 = 669,
1069 CV_AMD64_YMM11D2 = 670,
1070 CV_AMD64_YMM11D3 = 671,
1071 CV_AMD64_YMM12D0 = 672,
1072 CV_AMD64_YMM12D1 = 673,
1073 CV_AMD64_YMM12D2 = 674,
1074 CV_AMD64_YMM12D3 = 675,
1075 CV_AMD64_YMM13D0 = 676,
1076 CV_AMD64_YMM13D1 = 677,
1077 CV_AMD64_YMM13D2 = 678,
1078 CV_AMD64_YMM13D3 = 679,
1079 CV_AMD64_YMM14D0 = 680,
1080 CV_AMD64_YMM14D1 = 681,
1081 CV_AMD64_YMM14D2 = 682,
1082 CV_AMD64_YMM14D3 = 683,
1083 CV_AMD64_YMM15D0 = 684,
1084 CV_AMD64_YMM15D1 = 685,
1085 CV_AMD64_YMM15D2 = 686,
1086 CV_AMD64_YMM15D3 = 687
1089 /* This is enum BinaryAnnotationOpcode in Microsoft's cvinfo.h. */
1091 enum binary_annotation_opcode {
1092 ba_op_invalid,
1093 ba_op_code_offset,
1094 ba_op_change_code_offset_base,
1095 ba_op_change_code_offset,
1096 ba_op_change_code_length,
1097 ba_op_change_file,
1098 ba_op_change_line_offset,
1099 ba_op_change_line_end_delta,
1100 ba_op_change_range_kind,
1101 ba_op_change_column_start,
1102 ba_op_change_column_end_delta,
1103 ba_op_change_code_offset_and_line_offset,
1104 ba_op_change_code_length_and_code_offset,
1105 ba_op_change_column_end
1108 struct codeview_string
1110 codeview_string *next;
1111 uint32_t offset;
1112 char *string;
1115 struct string_hasher : free_ptr_hash <struct codeview_string>
1117 typedef const char *compare_type;
1119 static hashval_t hash (const codeview_string *x)
1121 return htab_hash_string (x->string);
1124 static bool equal (const codeview_string *x, const char *y)
1126 return !strcmp (x->string, y);
1129 static void mark_empty (codeview_string *x)
1131 if (x->string)
1133 free (x->string);
1134 x->string = NULL;
1138 static void remove (codeview_string *&x)
1140 free (x->string);
1144 struct codeview_source_file
1146 codeview_source_file *next;
1147 unsigned int file_num;
1148 uint32_t string_offset;
1149 char *filename;
1150 uint8_t hash[HASH_SIZE];
1153 struct codeview_line
1155 codeview_line *next;
1156 unsigned int line_no;
1157 unsigned int label_num;
1160 struct codeview_line_block
1162 codeview_line_block *next;
1163 uint32_t file_id;
1164 unsigned int num_lines;
1165 codeview_line *lines, *last_line;
1168 struct codeview_inlinee_lines
1170 codeview_inlinee_lines *next;
1171 uint32_t func_id;
1172 uint32_t file_id;
1173 uint32_t starting_line;
1176 struct codeview_function
1178 codeview_function *next;
1179 codeview_function *htab_next;
1180 function *func;
1181 unsigned int end_label;
1182 codeview_line_block *blocks, *last_block;
1183 codeview_function *parent;
1184 unsigned int inline_block;
1185 location_t inline_loc;
1188 struct codeview_symbol
1190 codeview_symbol *next;
1191 enum cv_sym_type kind;
1193 union
1195 struct
1197 uint32_t type;
1198 char *name;
1199 dw_die_ref die;
1200 } data_symbol;
1201 struct
1203 uint32_t parent;
1204 uint32_t end;
1205 uint32_t next;
1206 uint32_t type;
1207 uint8_t flags;
1208 char *name;
1209 dw_die_ref die;
1210 } function;
1214 struct codeview_type
1216 dw_die_ref die;
1217 uint32_t num;
1218 bool is_fwd_ref;
1221 struct die_hasher : free_ptr_hash <codeview_type>
1223 typedef dw_die_ref compare_type;
1225 static hashval_t hash (const codeview_type *x)
1227 return htab_hash_pointer (x->die);
1230 static bool equal (const codeview_type *x, const dw_die_ref y)
1232 return x->die == y;
1236 struct codeview_integer
1238 bool neg;
1239 uint64_t num;
1242 struct codeview_subtype
1244 struct codeview_subtype *next;
1245 enum cv_leaf_type kind;
1247 union
1249 struct
1251 char *name;
1252 struct codeview_integer value;
1253 } lf_enumerate;
1254 struct
1256 uint32_t type_num;
1257 } lf_index;
1258 struct
1260 uint16_t attributes;
1261 uint32_t type;
1262 codeview_integer offset;
1263 char *name;
1264 } lf_member;
1265 struct
1267 uint16_t attributes;
1268 uint32_t type;
1269 char *name;
1270 } lf_static_member;
1271 struct
1273 uint16_t method_attribute;
1274 uint32_t method_type;
1275 char *name;
1276 } lf_onemethod;
1277 struct
1279 uint16_t count;
1280 uint32_t method_list;
1281 char *name;
1282 } lf_method;
1283 struct
1285 uint16_t attributes;
1286 uint32_t base_class_type;
1287 codeview_integer offset;
1288 } lf_bclass;
1289 struct
1291 uint32_t type;
1292 char *name;
1293 } lf_nesttype;
1297 struct lf_methodlist_entry
1299 uint16_t method_attribute;
1300 uint32_t method_type;
1303 struct codeview_custom_type
1305 struct codeview_custom_type *next;
1306 uint32_t num;
1307 enum cv_leaf_type kind;
1309 union
1311 struct
1313 uint32_t base_type;
1314 uint32_t attributes;
1315 uint32_t containing_class;
1316 uint16_t ptr_to_mem_type;
1317 } lf_pointer;
1318 struct
1320 uint32_t base_type;
1321 uint16_t modifier;
1322 } lf_modifier;
1323 struct
1325 size_t length;
1326 codeview_subtype *subtypes;
1327 codeview_subtype *last_subtype;
1328 } lf_fieldlist;
1329 struct
1331 uint16_t count;
1332 uint16_t properties;
1333 uint32_t underlying_type;
1334 uint32_t fieldlist;
1335 char *name;
1336 } lf_enum;
1337 struct
1339 uint16_t num_members;
1340 uint16_t properties;
1341 uint32_t field_list;
1342 uint32_t derived_from;
1343 uint32_t vshape;
1344 codeview_integer length;
1345 char *name;
1346 } lf_structure;
1347 struct
1349 uint32_t element_type;
1350 uint32_t index_type;
1351 codeview_integer length_in_bytes;
1352 } lf_array;
1353 struct
1355 uint32_t base_type;
1356 uint8_t length;
1357 uint8_t position;
1358 } lf_bitfield;
1359 struct
1361 uint32_t return_type;
1362 uint8_t calling_convention;
1363 uint8_t attributes;
1364 uint16_t num_parameters;
1365 uint32_t arglist;
1366 } lf_procedure;
1367 struct
1369 uint32_t num_entries;
1370 uint32_t *args;
1371 } lf_arglist;
1372 struct
1374 uint32_t parent_scope;
1375 uint32_t function_type;
1376 char *name;
1377 } lf_func_id;
1378 struct
1380 uint32_t parent_type;
1381 uint32_t function_type;
1382 char *name;
1383 } lf_mfunc_id;
1384 struct
1386 uint32_t substring;
1387 char *string;
1388 } lf_string_id;
1389 struct
1391 uint32_t return_type;
1392 uint32_t containing_class_type;
1393 uint32_t this_type;
1394 uint8_t calling_convention;
1395 uint8_t attributes;
1396 uint16_t num_parameters;
1397 uint32_t arglist;
1398 int32_t this_adjustment;
1399 } lf_mfunction;
1400 struct
1402 unsigned int count;
1403 lf_methodlist_entry *entries;
1404 } lf_methodlist;
1408 struct codeview_deferred_type
1410 struct codeview_deferred_type *next;
1411 dw_die_ref type;
1414 struct string_id_hasher : nofree_ptr_hash <struct codeview_custom_type>
1416 typedef const char *compare_type;
1418 static hashval_t hash (const codeview_custom_type *x)
1420 return htab_hash_string (x->lf_string_id.string);
1423 static bool equal (const codeview_custom_type *x, const char *y)
1425 return !strcmp (x->lf_string_id.string, y);
1429 struct codeview_method
1431 uint16_t attribute;
1432 uint32_t type;
1433 char *name;
1434 unsigned int count;
1435 struct codeview_method *next;
1436 struct codeview_method *last;
1439 struct method_hasher : nofree_ptr_hash <struct codeview_method>
1441 typedef const char *compare_type;
1443 static hashval_t hash (const codeview_method *x)
1445 return htab_hash_string (x->name);
1448 static bool equal (const codeview_method *x, const char *y)
1450 return !strcmp (x->name, y);
1454 struct inlinee_lines_hasher : free_ptr_hash <struct codeview_inlinee_lines>
1456 typedef uint32_t compare_type;
1458 static hashval_t hash (const codeview_inlinee_lines *il)
1460 return il->func_id;
1463 static bool equal (const codeview_inlinee_lines *il, uint32_t func_id)
1465 return il->func_id == func_id;
1469 struct cv_func_hasher : nofree_ptr_hash <struct codeview_function>
1471 typedef dw_die_ref compare_type;
1473 static bool equal (const codeview_function *f, dw_die_ref die)
1475 return lookup_decl_die (f->func->decl) == die;
1479 static unsigned int line_label_num;
1480 static unsigned int func_label_num;
1481 static unsigned int sym_label_num;
1482 static codeview_source_file *files, *last_file;
1483 static unsigned int num_files;
1484 static uint32_t string_offset = 1;
1485 static hash_table<string_hasher> *strings_htab;
1486 static codeview_string *strings, *last_string;
1487 static codeview_function *funcs, *last_func, *cur_func;
1488 static const char* last_filename;
1489 static uint32_t last_file_id;
1490 static codeview_symbol *sym, *last_sym;
1491 static hash_table<die_hasher> *types_htab, *func_htab;
1492 static codeview_custom_type *custom_types, *last_custom_type;
1493 static codeview_deferred_type *deferred_types, *last_deferred_type;
1494 static hash_table<string_id_hasher> *string_id_htab;
1495 static hash_table<inlinee_lines_hasher> *inlinee_lines_htab;
1496 static hash_table<cv_func_hasher> *cv_func_htab;
1498 static uint32_t get_type_num (dw_die_ref type, bool in_struct, bool no_fwd_ref);
1499 static uint32_t get_type_num_subroutine_type (dw_die_ref type, bool in_struct,
1500 uint32_t containing_class_type,
1501 uint32_t this_type,
1502 int32_t this_adjustment);
1503 static void write_cv_padding (size_t padding);
1504 static void flush_deferred_types (void);
1505 static uint32_t get_func_id (dw_die_ref die);
1506 static void write_inlinesite_records (dw_die_ref func, dw_die_ref die);
1508 /* Return the file ID corresponding to a given source filename. */
1510 static uint32_t
1511 get_file_id (const char *filename)
1513 codeview_source_file *sf = files;
1515 if (filename == last_filename)
1516 return last_file_id;
1518 while (sf)
1520 if (!strcmp (sf->filename, filename))
1522 uint32_t file_id;
1524 /* 0x18 is the size of the checksum entry for each file.
1525 0x6 bytes for the header, plus 0x10 bytes for the hash,
1526 then padded to a multiple of 4. */
1528 file_id = sf->file_num * 0x18;
1529 last_filename = filename;
1530 last_file_id = file_id;
1532 return file_id;
1535 sf = sf->next;
1538 return 0;
1541 /* Allocate and initialize a codeview_function struct. */
1543 static codeview_function *
1544 new_codeview_function (void)
1546 codeview_function **slot;
1547 dw_die_ref die;
1548 codeview_function *f = (codeview_function *)
1549 xmalloc (sizeof (codeview_function));
1551 f->next = NULL;
1552 f->htab_next = NULL;
1553 f->func = cfun;
1554 f->end_label = 0;
1555 f->blocks = f->last_block = NULL;
1556 f->inline_block = 0;
1557 f->inline_loc = 0;
1559 if (!funcs)
1560 funcs = f;
1561 else
1562 last_func->next = f;
1564 last_func = f;
1566 if (!cv_func_htab)
1567 cv_func_htab = new hash_table<cv_func_hasher> (10);
1569 die = lookup_decl_die (cfun->decl);
1571 slot = cv_func_htab->find_slot_with_hash (die, htab_hash_pointer (die),
1572 INSERT);
1573 if (*slot)
1574 f->htab_next = *slot;
1576 *slot = f;
1578 return f;
1581 /* Record new line number against the current function. */
1583 void
1584 codeview_source_line (unsigned int line_no, const char *filename)
1586 codeview_line *l;
1587 uint32_t file_id = get_file_id (filename);
1588 unsigned int label_num = ++line_label_num;
1590 targetm.asm_out.internal_label (asm_out_file, LINE_LABEL, label_num);
1592 if (!cur_func || cur_func->func != cfun)
1594 codeview_function *f = new_codeview_function ();
1596 f->parent = NULL;
1598 cur_func = f;
1601 if (!cur_func->last_block || cur_func->last_block->file_id != file_id)
1603 codeview_line_block *b;
1605 b = (codeview_line_block *) xmalloc (sizeof (codeview_line_block));
1607 b->next = NULL;
1608 b->file_id = file_id;
1609 b->num_lines = 0;
1610 b->lines = b->last_line = NULL;
1612 if (!cur_func->blocks)
1613 cur_func->blocks = b;
1614 else
1615 cur_func->last_block->next = b;
1617 cur_func->last_block = b;
1620 if (cur_func->last_block->last_line
1621 && cur_func->last_block->last_line->line_no == line_no)
1622 return;
1624 l = (codeview_line *) xmalloc (sizeof (codeview_line));
1626 l->next = NULL;
1627 l->line_no = line_no;
1628 l->label_num = label_num;
1630 if (!cur_func->last_block->lines)
1631 cur_func->last_block->lines = l;
1632 else
1633 cur_func->last_block->last_line->next = l;
1635 cur_func->last_block->last_line = l;
1636 cur_func->last_block->num_lines++;
1639 /* We have encountered the beginning of a lexical block. If this is actually
1640 an inlined function, allocate a new codeview_function for this. */
1642 void
1643 codeview_begin_block (unsigned int line ATTRIBUTE_UNUSED,
1644 unsigned int blocknum, tree block)
1646 if (inlined_function_outer_scope_p (block))
1648 location_t locus = BLOCK_SOURCE_LOCATION (block);
1649 expanded_location s = expand_location (locus);
1650 codeview_function *f = new_codeview_function ();
1652 codeview_source_line (s.line, s.file);
1654 f->parent = cur_func;
1655 f->inline_block = blocknum;
1656 f->inline_loc = locus;
1658 cur_func = f;
1662 /* We have encountered the end of a lexical block. If this is the end of an
1663 inlined function, change cur_func back to its parent. */
1665 void
1666 codeview_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum)
1668 if (cur_func && cur_func->inline_block == blocknum)
1670 /* If inlined function, add dummy source line at the end so we know how
1671 long the actual last line is. */
1672 codeview_source_line (0, "");
1674 cur_func = cur_func->parent;
1678 /* Adds string to the string table, returning its offset. If already present,
1679 this returns the offset of the existing string. */
1681 static uint32_t
1682 add_string (const char *string)
1684 codeview_string **slot;
1685 codeview_string *s;
1686 size_t len;
1688 if (!strings_htab)
1689 strings_htab = new hash_table<string_hasher> (10);
1691 slot = strings_htab->find_slot_with_hash (string, htab_hash_string (string),
1692 INSERT);
1694 if (*slot)
1695 return (*slot)->offset;
1697 s = (codeview_string *) xmalloc (sizeof (codeview_string));
1698 len = strlen (string);
1700 s->next = NULL;
1702 s->offset = string_offset;
1703 string_offset += len + 1;
1705 s->string = xstrdup (string);
1707 if (last_string)
1708 last_string->next = s;
1709 else
1710 strings = s;
1712 last_string = s;
1714 *slot = s;
1716 return s->offset;
1719 /* A new source file has been encountered - record the details and calculate
1720 its hash. */
1722 void
1723 codeview_start_source_file (const char *filename)
1725 codeview_source_file *sf;
1726 char *path;
1727 uint32_t string_offset;
1728 FILE *f;
1730 path = lrealpath (filename);
1731 string_offset = add_string (path);
1732 free (path);
1734 sf = files;
1735 while (sf)
1737 if (sf->string_offset == string_offset)
1738 return;
1740 sf = sf->next;
1743 sf = (codeview_source_file *) xmalloc (sizeof (codeview_source_file));
1744 sf->next = NULL;
1745 sf->file_num = num_files;
1746 sf->string_offset = string_offset;
1747 sf->filename = xstrdup (filename);
1749 f = fopen (filename, "r");
1750 if (!f)
1751 internal_error ("could not open %s for reading", filename);
1753 if (md5_stream (f, sf->hash))
1755 fclose (f);
1756 internal_error ("md5_stream failed");
1759 fclose (f);
1761 if (last_file)
1762 last_file->next = sf;
1763 else
1764 files = sf;
1766 last_file = sf;
1767 num_files++;
1770 /* Write out the strings table into the .debug$S section. The linker will
1771 parse this, and handle the deduplication and hashing for all the object
1772 files. */
1774 static void
1775 write_strings_table (void)
1777 codeview_string *string;
1779 fputs (integer_asm_op (4, false), asm_out_file);
1780 fprint_whex (asm_out_file, DEBUG_S_STRINGTABLE);
1781 putc ('\n', asm_out_file);
1783 fputs (integer_asm_op (4, false), asm_out_file);
1784 asm_fprintf (asm_out_file, "%LLcv_strings_end - %LLcv_strings_start\n");
1786 asm_fprintf (asm_out_file, "%LLcv_strings_start:\n");
1788 /* The first entry is always an empty string. */
1789 fputs (integer_asm_op (1, false), asm_out_file);
1790 fprint_whex (asm_out_file, 0);
1791 putc ('\n', asm_out_file);
1793 string = strings;
1794 while (string)
1796 ASM_OUTPUT_ASCII (asm_out_file, string->string,
1797 strlen (string->string) + 1);
1799 string = string->next;
1802 delete strings_htab;
1804 asm_fprintf (asm_out_file, "%LLcv_strings_end:\n");
1806 ASM_OUTPUT_ALIGN (asm_out_file, 2);
1809 /* Write out the file checksums data into the .debug$S section. */
1811 static void
1812 write_source_files (void)
1814 fputs (integer_asm_op (4, false), asm_out_file);
1815 fprint_whex (asm_out_file, DEBUG_S_FILECHKSMS);
1816 putc ('\n', asm_out_file);
1818 fputs (integer_asm_op (4, false), asm_out_file);
1819 asm_fprintf (asm_out_file,
1820 "%LLcv_filechksms_end - %LLcv_filechksms_start\n");
1822 asm_fprintf (asm_out_file, "%LLcv_filechksms_start:\n");
1824 while (files)
1826 codeview_source_file *next = files->next;
1828 /* This is struct file_checksum in binutils, or filedata in Microsoft's
1829 dumpsym7.cpp:
1831 struct file_checksum
1833 uint32_t file_id;
1834 uint8_t checksum_length;
1835 uint8_t checksum_type;
1836 } ATTRIBUTE_PACKED;
1838 followed then by the bytes of the hash, padded to the next 4 bytes.
1839 file_id here is actually the offset in the strings table. */
1841 fputs (integer_asm_op (4, false), asm_out_file);
1842 fprint_whex (asm_out_file, files->string_offset);
1843 putc ('\n', asm_out_file);
1845 fputs (integer_asm_op (1, false), asm_out_file);
1846 fprint_whex (asm_out_file, HASH_SIZE);
1847 putc ('\n', asm_out_file);
1849 fputs (integer_asm_op (1, false), asm_out_file);
1850 fprint_whex (asm_out_file, CHKSUM_TYPE_MD5);
1851 putc ('\n', asm_out_file);
1853 for (unsigned int i = 0; i < HASH_SIZE; i++)
1855 fputs (integer_asm_op (1, false), asm_out_file);
1856 fprint_whex (asm_out_file, files->hash[i]);
1857 putc ('\n', asm_out_file);
1860 ASM_OUTPUT_ALIGN (asm_out_file, 2);
1862 free (files->filename);
1863 free (files);
1865 files = next;
1868 asm_fprintf (asm_out_file, "%LLcv_filechksms_end:\n");
1871 /* Write out the line number information for each function into the
1872 .debug$S section. */
1874 static void
1875 write_line_numbers (void)
1877 unsigned int func_num = 0;
1878 codeview_function *f = funcs;
1880 while (f)
1882 codeview_function *next_func = f->next;
1883 unsigned int first_label_num;
1884 codeview_line_block *b = f->blocks;
1886 if (f->inline_block != 0)
1888 f = next_func;
1889 continue;
1892 fputs (integer_asm_op (4, false), asm_out_file);
1893 fprint_whex (asm_out_file, DEBUG_S_LINES);
1894 putc ('\n', asm_out_file);
1896 fputs (integer_asm_op (4, false), asm_out_file);
1897 asm_fprintf (asm_out_file, "%LLcv_lines%u_end - %LLcv_lines%u_start\n",
1898 func_num, func_num);
1900 asm_fprintf (asm_out_file, "%LLcv_lines%u_start:\n", func_num);
1902 /* Output the header (struct cv_lines_header in binutils or
1903 CV_DebugSLinesHeader_t in Microsoft's cvinfo.h):
1905 struct cv_lines_header
1907 uint32_t offset;
1908 uint16_t section;
1909 uint16_t flags;
1910 uint32_t length;
1914 asm_fprintf (asm_out_file, "\t.secrel32\t%L" LINE_LABEL "%u\n",
1915 b->lines->label_num);
1916 asm_fprintf (asm_out_file, "\t.secidx\t%L" LINE_LABEL "%u\n",
1917 b->lines->label_num);
1919 /* flags */
1920 fputs (integer_asm_op (2, false), asm_out_file);
1921 fprint_whex (asm_out_file, 0);
1922 putc ('\n', asm_out_file);
1924 first_label_num = b->lines->label_num;
1926 /* length */
1927 fputs (integer_asm_op (4, false), asm_out_file);
1928 asm_fprintf (asm_out_file,
1929 "%L" END_FUNC_LABEL "%u - %L" LINE_LABEL "%u\n",
1930 f->end_label, first_label_num);
1932 while (b)
1934 codeview_line_block *next_block = b->next;
1935 codeview_line *l = b->lines;
1937 /* Next comes the blocks, each block being a part of a function
1938 within the same source file (struct cv_lines_block in binutils or
1939 CV_DebugSLinesFileBlockHeader_t in Microsoft's cvinfo.h):
1941 struct cv_lines_block
1943 uint32_t file_id;
1944 uint32_t num_lines;
1945 uint32_t length;
1949 /* file ID */
1950 fputs (integer_asm_op (4, false), asm_out_file);
1951 fprint_whex (asm_out_file, b->file_id);
1952 putc ('\n', asm_out_file);
1954 /* number of lines */
1955 fputs (integer_asm_op (4, false), asm_out_file);
1956 fprint_whex (asm_out_file, b->num_lines);
1957 putc ('\n', asm_out_file);
1959 /* length of code block: (num_lines * sizeof (struct cv_line)) +
1960 sizeof (struct cv_lines_block) */
1961 fputs (integer_asm_op (4, false), asm_out_file);
1962 fprint_whex (asm_out_file, (b->num_lines * 0x8) + 0xc);
1963 putc ('\n', asm_out_file);
1965 while (l)
1967 codeview_line *next_line = l->next;
1969 /* Finally comes the line number information (struct cv_line in
1970 binutils or CV_Line_t in Microsoft's cvinfo.h):
1972 struct cv_line
1974 uint32_t offset;
1975 uint32_t line_no;
1978 Strictly speaking line_no is a bitfield: the bottom 24 bits
1979 are the line number, and the top bit means "is a statement".
1982 fputs (integer_asm_op (4, false), asm_out_file);
1983 asm_fprintf (asm_out_file,
1984 "%L" LINE_LABEL "%u - %L" LINE_LABEL "%u\n",
1985 l->label_num, first_label_num);
1987 fputs (integer_asm_op (4, false), asm_out_file);
1988 fprint_whex (asm_out_file,
1989 0x80000000
1990 | (l->line_no & 0xffffff));
1991 putc ('\n', asm_out_file);
1993 l = next_line;
1996 b = next_block;
1999 asm_fprintf (asm_out_file, "%LLcv_lines%u_end:\n", func_num);
2000 func_num++;
2002 f = next_func;
2006 /* Write an entry in the S_INLINEELINES subsection of .debug$S. */
2008 static int
2009 write_inlinee_lines_entry (codeview_inlinee_lines **slot,
2010 void *ctx ATTRIBUTE_UNUSED)
2012 codeview_inlinee_lines *il = *slot;
2014 /* The inlinee lines data consists of a version uint32_t (0), followed by
2015 an array of struct inlinee_source_line:
2017 struct inlinee_source_line
2019 uint32_t function_id;
2020 uint32_t file_id;
2021 uint32_t line_no;
2024 (see InlineeSourceLine in cvinfo.h)
2027 fputs (integer_asm_op (4, false), asm_out_file);
2028 fprint_whex (asm_out_file, il->func_id);
2029 putc ('\n', asm_out_file);
2031 fputs (integer_asm_op (4, false), asm_out_file);
2032 fprint_whex (asm_out_file, il->file_id);
2033 putc ('\n', asm_out_file);
2035 fputs (integer_asm_op (4, false), asm_out_file);
2036 fprint_whex (asm_out_file, il->starting_line);
2037 putc ('\n', asm_out_file);
2039 return 1;
2042 /* Write the S_INLINEELINES subsection of .debug$S, which lists the filename
2043 and line number for the start of each inlined function. */
2045 static void
2046 write_inlinee_lines (void)
2048 fputs (integer_asm_op (4, false), asm_out_file);
2049 fprint_whex (asm_out_file, DEBUG_S_INLINEELINES);
2050 putc ('\n', asm_out_file);
2052 fputs (integer_asm_op (4, false), asm_out_file);
2053 asm_fprintf (asm_out_file,
2054 "%LLcv_inlineelines_end - %LLcv_inlineelines_start\n");
2055 asm_fprintf (asm_out_file, "%LLcv_inlineelines_start:\n");
2057 fputs (integer_asm_op (4, false), asm_out_file);
2058 fprint_whex (asm_out_file, CV_INLINEE_SOURCE_LINE_SIGNATURE);
2059 putc ('\n', asm_out_file);
2061 inlinee_lines_htab->traverse <void*, write_inlinee_lines_entry> (NULL);
2063 asm_fprintf (asm_out_file, "%LLcv_inlineelines_end:\n");
2066 /* Treat cold sections as separate functions, for the purposes of line
2067 numbers. */
2069 void
2070 codeview_switch_text_section (void)
2072 codeview_function *f;
2074 if (cur_func && cur_func->end_label == 0)
2076 unsigned int label_num = ++func_label_num;
2078 targetm.asm_out.internal_label (asm_out_file, END_FUNC_LABEL,
2079 label_num);
2081 cur_func->end_label = label_num;
2084 f = new_codeview_function ();
2085 f->parent = cur_func ? cur_func->parent : NULL;
2087 cur_func = f;
2090 /* Mark the end of the current function. */
2092 void
2093 codeview_end_epilogue (void)
2095 if (cur_func && cur_func->end_label == 0)
2097 unsigned int label_num = ++func_label_num;
2099 targetm.asm_out.internal_label (asm_out_file, END_FUNC_LABEL,
2100 label_num);
2102 cur_func->end_label = label_num;
2106 /* Return the CodeView constant for the selected architecture. */
2108 static uint16_t
2109 target_processor (void)
2111 if (TARGET_64BIT)
2112 return CV_CFL_X64;
2113 else
2114 return CV_CFL_80386;
2117 /* Return the CodeView constant for the language being used. */
2119 static uint32_t
2120 language_constant (void)
2122 const char *language_string = lang_hooks.name;
2124 if (startswith (language_string, "GNU C++"))
2125 return CV_CFL_CXX;
2126 else if (startswith (language_string, "GNU C"))
2127 return CV_CFL_C;
2129 return 0;
2132 /* Write a S_COMPILE3 symbol, which records the details of the compiler
2133 being used. */
2135 static void
2136 write_compile3_symbol (void)
2138 unsigned int label_num = ++sym_label_num;
2140 static const char compiler_name[] = "GCC ";
2142 /* This is struct COMPILESYM3 in binutils and Microsoft's cvinfo.h:
2144 struct COMPILESYM3
2146 uint16_t length;
2147 uint16_t type;
2148 uint32_t flags;
2149 uint16_t machine;
2150 uint16_t frontend_major;
2151 uint16_t frontend_minor;
2152 uint16_t frontend_build;
2153 uint16_t frontend_qfe;
2154 uint16_t backend_major;
2155 uint16_t backend_minor;
2156 uint16_t backend_build;
2157 uint16_t backend_qfe;
2158 } ATTRIBUTE_PACKED;
2161 fputs (integer_asm_op (2, false), asm_out_file);
2162 asm_fprintf (asm_out_file,
2163 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
2164 label_num, label_num);
2166 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
2168 fputs (integer_asm_op (2, false), asm_out_file);
2169 fprint_whex (asm_out_file, S_COMPILE3);
2170 putc ('\n', asm_out_file);
2172 /* Microsoft has the flags as a bitfield, with the bottom 8 bits being the
2173 language constant, and the reset being MSVC-specific stuff. */
2174 fputs (integer_asm_op (4, false), asm_out_file);
2175 fprint_whex (asm_out_file, language_constant ());
2176 putc ('\n', asm_out_file);
2178 fputs (integer_asm_op (2, false), asm_out_file);
2179 fprint_whex (asm_out_file, target_processor ());
2180 putc ('\n', asm_out_file);
2182 /* Write 8 uint16_ts for the frontend and backend versions. As with GAS, we
2183 zero these, as it's easier to record the version in the compiler
2184 string. */
2185 for (unsigned int i = 0; i < 8; i++)
2187 fputs (integer_asm_op (2, false), asm_out_file);
2188 fprint_whex (asm_out_file, 0);
2189 putc ('\n', asm_out_file);
2192 ASM_OUTPUT_ASCII (asm_out_file, compiler_name, sizeof (compiler_name) - 1);
2193 ASM_OUTPUT_ASCII (asm_out_file, version_string, strlen (version_string) + 1);
2195 ASM_OUTPUT_ALIGN (asm_out_file, 2);
2197 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
2200 /* Write an S_GDATA32 symbol, representing a global variable, or an S_LDATA32
2201 symbol, for a static global variable. */
2203 static void
2204 write_data_symbol (codeview_symbol *s)
2206 unsigned int label_num = ++sym_label_num;
2207 dw_attr_node *loc;
2208 dw_loc_descr_ref loc_ref;
2210 /* This is struct datasym in binutils:
2212 struct datasym
2214 uint16_t size;
2215 uint16_t kind;
2216 uint32_t type;
2217 uint32_t offset;
2218 uint16_t section;
2219 char name[];
2220 } ATTRIBUTE_PACKED;
2223 /* Extract the DW_AT_location attribute from the DIE, and make sure it's in
2224 in a format we can parse. */
2226 loc = get_AT (s->data_symbol.die, DW_AT_location);
2227 if (!loc)
2228 goto end;
2230 if (loc->dw_attr_val.val_class != dw_val_class_loc)
2231 goto end;
2233 loc_ref = loc->dw_attr_val.v.val_loc;
2234 if (!loc_ref || loc_ref->dw_loc_opc != DW_OP_addr)
2235 goto end;
2237 /* Output the S_GDATA32 / S_LDATA32 record. */
2239 fputs (integer_asm_op (2, false), asm_out_file);
2240 asm_fprintf (asm_out_file,
2241 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
2242 label_num, label_num);
2244 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
2246 fputs (integer_asm_op (2, false), asm_out_file);
2247 fprint_whex (asm_out_file, s->kind);
2248 putc ('\n', asm_out_file);
2250 fputs (integer_asm_op (4, false), asm_out_file);
2251 fprint_whex (asm_out_file, s->data_symbol.type);
2252 putc ('\n', asm_out_file);
2254 asm_fprintf (asm_out_file, "\t.secrel32 ");
2255 output_addr_const (asm_out_file, loc_ref->dw_loc_oprnd1.v.val_addr);
2256 fputc ('\n', asm_out_file);
2258 asm_fprintf (asm_out_file, "\t.secidx ");
2259 output_addr_const (asm_out_file, loc_ref->dw_loc_oprnd1.v.val_addr);
2260 fputc ('\n', asm_out_file);
2262 ASM_OUTPUT_ASCII (asm_out_file, s->data_symbol.name,
2263 strlen (s->data_symbol.name) + 1);
2265 ASM_OUTPUT_ALIGN (asm_out_file, 2);
2267 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
2269 end:
2270 free (s->data_symbol.name);
2273 /* Write an S_LOCAL symbol, representing an optimized variable. This is then
2274 followed by various S_DEFRANGE_* symbols, which describe how to find the
2275 value of a variable and the range for which this is valid. */
2277 static void
2278 write_s_local (dw_die_ref die)
2280 unsigned int label_num = ++sym_label_num;
2281 const char *name = get_AT_string (die, DW_AT_name);
2282 uint32_t type;
2284 /* This is struct LOCALSYM in Microsoft's cvinfo.h:
2286 struct LOCALSYM {
2287 uint16_t reclen;
2288 uint16_t rectyp;
2289 uint32_t typind;
2290 uint16_t flags;
2291 char name[];
2295 fputs (integer_asm_op (2, false), asm_out_file);
2296 asm_fprintf (asm_out_file,
2297 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
2298 label_num, label_num);
2300 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
2302 fputs (integer_asm_op (2, false), asm_out_file);
2303 fprint_whex (asm_out_file, S_LOCAL);
2304 putc ('\n', asm_out_file);
2306 type = get_type_num (get_AT_ref (die, DW_AT_type), false, false);
2308 fputs (integer_asm_op (4, false), asm_out_file);
2309 fprint_whex (asm_out_file, type);
2310 putc ('\n', asm_out_file);
2312 fputs (integer_asm_op (2, false), asm_out_file);
2313 fprint_whex (asm_out_file, 0);
2314 putc ('\n', asm_out_file);
2316 ASM_OUTPUT_ASCII (asm_out_file, name, strlen (name) + 1);
2318 ASM_OUTPUT_ALIGN (asm_out_file, 2);
2320 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
2323 /* Write an S_LDATA32 symbol, representing a static variable within a function.
2324 This symbol can also appear outside of a function block - see
2325 write_data_symbol. */
2327 static void
2328 write_local_s_ldata32 (dw_die_ref die, dw_loc_descr_ref loc_ref)
2330 unsigned int label_num = ++sym_label_num;
2331 const char *name = get_AT_string (die, DW_AT_name);
2332 uint32_t type;
2334 /* This is struct datasym in binutils:
2336 struct datasym
2338 uint16_t size;
2339 uint16_t kind;
2340 uint32_t type;
2341 uint32_t offset;
2342 uint16_t section;
2343 char name[];
2344 } ATTRIBUTE_PACKED;
2347 fputs (integer_asm_op (2, false), asm_out_file);
2348 asm_fprintf (asm_out_file,
2349 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
2350 label_num, label_num);
2352 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
2354 fputs (integer_asm_op (2, false), asm_out_file);
2355 fprint_whex (asm_out_file, S_LDATA32);
2356 putc ('\n', asm_out_file);
2358 type = get_type_num (get_AT_ref (die, DW_AT_type), false, false);
2360 fputs (integer_asm_op (4, false), asm_out_file);
2361 fprint_whex (asm_out_file, type);
2362 putc ('\n', asm_out_file);
2364 asm_fprintf (asm_out_file, "\t.secrel32 ");
2365 output_addr_const (asm_out_file, loc_ref->dw_loc_oprnd1.v.val_addr);
2366 fputc ('\n', asm_out_file);
2368 asm_fprintf (asm_out_file, "\t.secidx ");
2369 output_addr_const (asm_out_file, loc_ref->dw_loc_oprnd1.v.val_addr);
2370 fputc ('\n', asm_out_file);
2372 ASM_OUTPUT_ASCII (asm_out_file, name, strlen (name) + 1);
2374 ASM_OUTPUT_ALIGN (asm_out_file, 2);
2376 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
2379 /* Try to translate a DWARF register number into its CodeView equivalent. */
2381 static uint16_t
2382 dwarf_reg_to_cv (unsigned int regno)
2384 static const cv_amd64_register amd64_reg_mapping[] = {
2385 CV_AMD64_RAX,
2386 CV_AMD64_RDX,
2387 CV_AMD64_RCX,
2388 CV_AMD64_RBX,
2389 CV_AMD64_RSI,
2390 CV_AMD64_RDI,
2391 CV_AMD64_RBP,
2392 CV_AMD64_RSP,
2393 CV_AMD64_R8,
2394 CV_AMD64_R9,
2395 CV_AMD64_R10,
2396 CV_AMD64_R11,
2397 CV_AMD64_R12,
2398 CV_AMD64_R13,
2399 CV_AMD64_R14,
2400 CV_AMD64_R15,
2401 CV_AMD64_RIP,
2402 CV_AMD64_XMM0,
2403 CV_AMD64_XMM1,
2404 CV_AMD64_XMM2,
2405 CV_AMD64_XMM3,
2406 CV_AMD64_XMM4,
2407 CV_AMD64_XMM5,
2408 CV_AMD64_XMM6,
2409 CV_AMD64_XMM7,
2410 CV_AMD64_XMM8,
2411 CV_AMD64_XMM9,
2412 CV_AMD64_XMM10,
2413 CV_AMD64_XMM11,
2414 CV_AMD64_XMM12,
2415 CV_AMD64_XMM13,
2416 CV_AMD64_XMM14,
2417 CV_AMD64_XMM15,
2418 CV_AMD64_ST0,
2419 CV_AMD64_ST1,
2420 CV_AMD64_ST2,
2421 CV_AMD64_ST3,
2422 CV_AMD64_ST4,
2423 CV_AMD64_ST5,
2424 CV_AMD64_ST6,
2425 CV_AMD64_ST7,
2426 CV_AMD64_NOREG,
2427 CV_AMD64_NOREG,
2428 CV_AMD64_NOREG,
2429 CV_AMD64_NOREG,
2430 CV_AMD64_NOREG,
2431 CV_AMD64_NOREG,
2432 CV_AMD64_NOREG,
2433 CV_AMD64_NOREG,
2434 CV_AMD64_EFLAGS,
2435 CV_AMD64_ES,
2436 CV_AMD64_CS,
2437 CV_AMD64_SS,
2438 CV_AMD64_DS,
2439 CV_AMD64_FS,
2440 CV_AMD64_GS,
2441 CV_AMD64_NOREG,
2442 CV_AMD64_NOREG,
2443 CV_AMD64_NOREG,
2444 CV_AMD64_NOREG,
2445 CV_AMD64_NOREG,
2446 CV_AMD64_NOREG,
2447 CV_AMD64_TR,
2448 CV_AMD64_LDTR,
2449 CV_AMD64_MXCSR,
2450 CV_AMD64_CTRL,
2451 CV_AMD64_STAT
2454 static const cv_x86_register x86_reg_mapping[] = {
2455 CV_REG_EAX,
2456 CV_REG_ECX,
2457 CV_REG_EDX,
2458 CV_REG_EBX,
2459 CV_REG_EBP,
2460 CV_REG_ESP,
2461 CV_REG_ESI,
2462 CV_REG_EDI,
2463 CV_REG_EIP,
2464 CV_REG_EFLAGS,
2465 CV_REG_CS,
2466 CV_REG_SS,
2467 CV_REG_DS,
2468 CV_REG_ES,
2469 CV_REG_FS,
2470 CV_REG_GS,
2471 CV_REG_ST0,
2472 CV_REG_ST1,
2473 CV_REG_ST2,
2474 CV_REG_ST3,
2475 CV_REG_ST4,
2476 CV_REG_ST5,
2477 CV_REG_ST6,
2478 CV_REG_ST7,
2479 CV_REG_CTRL,
2480 CV_REG_STAT,
2481 CV_REG_TAG,
2482 CV_REG_FPCS,
2483 CV_REG_FPIP,
2484 CV_REG_FPDS,
2485 CV_REG_FPDO,
2486 CV_REG_NONE,
2487 CV_REG_XMM0,
2488 CV_REG_XMM1,
2489 CV_REG_XMM2,
2490 CV_REG_XMM3,
2491 CV_REG_XMM4,
2492 CV_REG_XMM5,
2493 CV_REG_XMM6,
2494 CV_REG_XMM7,
2495 CV_REG_MXCSR
2498 if (TARGET_64BIT)
2500 if (regno < sizeof (amd64_reg_mapping) / sizeof (*amd64_reg_mapping))
2501 return amd64_reg_mapping[regno];
2503 return CV_AMD64_NOREG;
2505 else
2507 if (regno < sizeof (x86_reg_mapping) / sizeof (*x86_reg_mapping))
2508 return x86_reg_mapping[regno];
2510 return CV_REG_NONE;
2514 /* Write an S_REGISTER symbol, representing an unoptimized variable that has
2515 been assigned to a register. */
2517 static void
2518 write_s_register (dw_die_ref die, dw_loc_descr_ref loc_ref)
2520 unsigned int label_num = ++sym_label_num;
2521 const char *name = get_AT_string (die, DW_AT_name);
2522 uint16_t regno;
2523 uint32_t type;
2525 /* This is struct regsym in binutils and REGSYM in Microsoft's cvinfo.h:
2527 struct regsym
2529 uint16_t size;
2530 uint16_t kind;
2531 uint32_t type;
2532 uint16_t reg;
2533 char name[];
2534 } ATTRIBUTE_PACKED;
2537 if (loc_ref->dw_loc_opc == DW_OP_regx)
2538 regno = dwarf_reg_to_cv (loc_ref->dw_loc_oprnd1.v.val_int);
2539 else
2540 regno = dwarf_reg_to_cv (loc_ref->dw_loc_opc - DW_OP_reg0);
2542 if (regno == 0)
2543 return;
2545 fputs (integer_asm_op (2, false), asm_out_file);
2546 asm_fprintf (asm_out_file,
2547 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
2548 label_num, label_num);
2550 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
2552 fputs (integer_asm_op (2, false), asm_out_file);
2553 fprint_whex (asm_out_file, S_REGISTER);
2554 putc ('\n', asm_out_file);
2556 type = get_type_num (get_AT_ref (die, DW_AT_type), false, false);
2558 fputs (integer_asm_op (4, false), asm_out_file);
2559 fprint_whex (asm_out_file, type);
2560 putc ('\n', asm_out_file);
2562 fputs (integer_asm_op (2, false), asm_out_file);
2563 fprint_whex (asm_out_file, regno);
2564 putc ('\n', asm_out_file);
2566 ASM_OUTPUT_ASCII (asm_out_file, name, strlen (name) + 1);
2568 ASM_OUTPUT_ALIGN (asm_out_file, 2);
2570 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
2573 /* Write an S_REGREL32 symbol in order to represent an unoptimized stack
2574 variable. The memory address is given by a register value plus an offset,
2575 so we need to parse the function's DW_AT_frame_base attribute for this. */
2577 static void
2578 write_fbreg_variable (dw_die_ref die, dw_loc_descr_ref loc_ref,
2579 dw_loc_descr_ref fbloc)
2581 unsigned int label_num = ++sym_label_num;
2582 const char *name = get_AT_string (die, DW_AT_name);
2583 uint32_t type;
2584 uint16_t regno;
2585 int offset;
2587 /* This is struct regrel in binutils and REGREL32 in Microsoft's cvinfo.h:
2589 struct regrel
2591 uint16_t size;
2592 uint16_t kind;
2593 uint32_t offset;
2594 uint32_t type;
2595 uint16_t reg;
2596 char name[];
2597 } ATTRIBUTE_PACKED;
2600 if (!fbloc)
2601 return;
2603 if (fbloc->dw_loc_opc >= DW_OP_breg0 && fbloc->dw_loc_opc <= DW_OP_breg31)
2605 regno = dwarf_reg_to_cv (fbloc->dw_loc_opc - DW_OP_breg0);
2606 offset = fbloc->dw_loc_oprnd1.v.val_int;
2608 else if (fbloc->dw_loc_opc == DW_OP_bregx)
2610 regno = dwarf_reg_to_cv (fbloc->dw_loc_oprnd1.v.val_int);
2611 offset = fbloc->dw_loc_oprnd2.v.val_int;
2613 else
2615 return;
2618 if (loc_ref->dw_loc_oprnd1.val_class != dw_val_class_unsigned_const)
2619 return;
2621 offset += loc_ref->dw_loc_oprnd1.v.val_int;
2623 fputs (integer_asm_op (2, false), asm_out_file);
2624 asm_fprintf (asm_out_file,
2625 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
2626 label_num, label_num);
2628 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
2630 fputs (integer_asm_op (2, false), asm_out_file);
2631 fprint_whex (asm_out_file, S_REGREL32);
2632 putc ('\n', asm_out_file);
2634 fputs (integer_asm_op (4, false), asm_out_file);
2635 fprint_whex (asm_out_file, offset);
2636 putc ('\n', asm_out_file);
2638 type = get_type_num (get_AT_ref (die, DW_AT_type), false, false);
2640 fputs (integer_asm_op (4, false), asm_out_file);
2641 fprint_whex (asm_out_file, type);
2642 putc ('\n', asm_out_file);
2644 fputs (integer_asm_op (2, false), asm_out_file);
2645 fprint_whex (asm_out_file, regno);
2646 putc ('\n', asm_out_file);
2648 ASM_OUTPUT_ASCII (asm_out_file, name, strlen (name) + 1);
2650 ASM_OUTPUT_ALIGN (asm_out_file, 2);
2652 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
2655 /* Write an S_DEFRANGE_REGISTER symbol, which describes a range for which an
2656 S_LOCAL variable is held in a certain register. */
2658 static void
2659 write_defrange_register (dw_loc_descr_ref expr, rtx range_start, rtx range_end)
2661 unsigned int label_num = ++sym_label_num;
2662 uint16_t regno;
2664 /* This is defrange_register in binutils and DEFRANGESYMREGISTER in
2665 Microsoft's cvinfo.h:
2667 struct lvar_addr_range
2669 uint32_t offset;
2670 uint16_t section;
2671 uint16_t length;
2672 } ATTRIBUTE_PACKED;
2674 struct lvar_addr_gap {
2675 uint16_t offset;
2676 uint16_t length;
2677 } ATTRIBUTE_PACKED;
2679 struct defrange_register
2681 uint16_t size;
2682 uint16_t kind;
2683 uint16_t reg;
2684 uint16_t attributes;
2685 struct lvar_addr_range range;
2686 struct lvar_addr_gap gaps[];
2687 } ATTRIBUTE_PACKED;
2690 if (expr->dw_loc_opc == DW_OP_regx)
2691 regno = dwarf_reg_to_cv (expr->dw_loc_oprnd1.v.val_int);
2692 else
2693 regno = dwarf_reg_to_cv (expr->dw_loc_opc - DW_OP_reg0);
2695 if (regno == 0)
2696 return;
2698 fputs (integer_asm_op (2, false), asm_out_file);
2699 asm_fprintf (asm_out_file,
2700 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
2701 label_num, label_num);
2703 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
2705 fputs (integer_asm_op (2, false), asm_out_file);
2706 fprint_whex (asm_out_file, S_DEFRANGE_REGISTER);
2707 putc ('\n', asm_out_file);
2709 fputs (integer_asm_op (2, false), asm_out_file);
2710 fprint_whex (asm_out_file, regno);
2711 putc ('\n', asm_out_file);
2713 fputs (integer_asm_op (2, false), asm_out_file);
2714 fprint_whex (asm_out_file, 0);
2715 putc ('\n', asm_out_file);
2717 asm_fprintf (asm_out_file, "\t.secrel32 ");
2718 output_addr_const (asm_out_file, range_start);
2719 fputc ('\n', asm_out_file);
2721 asm_fprintf (asm_out_file, "\t.secidx ");
2722 output_addr_const (asm_out_file, range_start);
2723 fputc ('\n', asm_out_file);
2725 fputs (integer_asm_op (2, false), asm_out_file);
2726 output_addr_const (asm_out_file, range_end);
2727 fputs (" - ", asm_out_file);
2728 output_addr_const (asm_out_file, range_start);
2729 putc ('\n', asm_out_file);
2731 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
2734 /* Write an S_DEFRANGE_REGISTER_REL symbol, which describes a range for which
2735 an S_LOCAL variable is held in memory given by the value of a certain
2736 register plus an offset. */
2738 static void
2739 write_defrange_register_rel (dw_loc_descr_ref expr, dw_loc_descr_ref fbloc,
2740 rtx range_start, rtx range_end)
2742 unsigned int label_num = ++sym_label_num;
2743 uint16_t regno;
2744 int offset;
2746 /* This is defrange_register_rel in binutils and DEFRANGESYMREGISTERREL in
2747 Microsoft's cvinfo.h:
2749 struct lvar_addr_range
2751 uint32_t offset;
2752 uint16_t section;
2753 uint16_t length;
2754 } ATTRIBUTE_PACKED;
2756 struct lvar_addr_gap {
2757 uint16_t offset;
2758 uint16_t length;
2759 } ATTRIBUTE_PACKED;
2761 struct defrange_register_rel
2763 uint16_t size;
2764 uint16_t kind;
2765 uint16_t reg;
2766 uint16_t offset_parent;
2767 uint32_t offset_register;
2768 struct lvar_addr_range range;
2769 struct lvar_addr_gap gaps[];
2770 } ATTRIBUTE_PACKED;
2773 if (!fbloc)
2774 return;
2776 if (fbloc->dw_loc_opc >= DW_OP_breg0 && fbloc->dw_loc_opc <= DW_OP_breg31)
2778 regno = dwarf_reg_to_cv (fbloc->dw_loc_opc - DW_OP_breg0);
2779 offset = fbloc->dw_loc_oprnd1.v.val_int;
2781 else if (fbloc->dw_loc_opc == DW_OP_bregx)
2783 regno = dwarf_reg_to_cv (fbloc->dw_loc_oprnd1.v.val_int);
2784 offset = fbloc->dw_loc_oprnd2.v.val_int;
2786 else
2788 return;
2791 if (expr->dw_loc_oprnd1.val_class != dw_val_class_unsigned_const)
2792 return;
2794 offset += expr->dw_loc_oprnd1.v.val_int;
2796 fputs (integer_asm_op (2, false), asm_out_file);
2797 asm_fprintf (asm_out_file,
2798 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
2799 label_num, label_num);
2801 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
2803 fputs (integer_asm_op (2, false), asm_out_file);
2804 fprint_whex (asm_out_file, S_DEFRANGE_REGISTER_REL);
2805 putc ('\n', asm_out_file);
2807 fputs (integer_asm_op (2, false), asm_out_file);
2808 fprint_whex (asm_out_file, regno);
2809 putc ('\n', asm_out_file);
2811 fputs (integer_asm_op (2, false), asm_out_file);
2812 fprint_whex (asm_out_file, 0);
2813 putc ('\n', asm_out_file);
2815 fputs (integer_asm_op (4, false), asm_out_file);
2816 fprint_whex (asm_out_file, offset);
2817 putc ('\n', asm_out_file);
2819 asm_fprintf (asm_out_file, "\t.secrel32 ");
2820 output_addr_const (asm_out_file, range_start);
2821 fputc ('\n', asm_out_file);
2823 asm_fprintf (asm_out_file, "\t.secidx ");
2824 output_addr_const (asm_out_file, range_start);
2825 fputc ('\n', asm_out_file);
2827 fputs (integer_asm_op (2, false), asm_out_file);
2828 output_addr_const (asm_out_file, range_end);
2829 fputs (" - ", asm_out_file);
2830 output_addr_const (asm_out_file, range_start);
2831 putc ('\n', asm_out_file);
2833 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
2836 /* Try to write an S_DEFRANGE_* symbol for the given DWARF location. */
2838 static void
2839 write_optimized_local_variable_loc (dw_loc_descr_ref expr,
2840 dw_loc_descr_ref fbloc, rtx range_start,
2841 rtx range_end)
2843 if (expr->dw_loc_next)
2844 return;
2846 if (!range_start)
2847 return;
2849 if (!range_end)
2850 return;
2852 switch (expr->dw_loc_opc)
2854 case DW_OP_reg0:
2855 case DW_OP_reg1:
2856 case DW_OP_reg2:
2857 case DW_OP_reg3:
2858 case DW_OP_reg4:
2859 case DW_OP_reg5:
2860 case DW_OP_reg6:
2861 case DW_OP_reg7:
2862 case DW_OP_reg8:
2863 case DW_OP_reg9:
2864 case DW_OP_reg10:
2865 case DW_OP_reg11:
2866 case DW_OP_reg12:
2867 case DW_OP_reg13:
2868 case DW_OP_reg14:
2869 case DW_OP_reg15:
2870 case DW_OP_reg16:
2871 case DW_OP_reg17:
2872 case DW_OP_reg18:
2873 case DW_OP_reg19:
2874 case DW_OP_reg20:
2875 case DW_OP_reg21:
2876 case DW_OP_reg22:
2877 case DW_OP_reg23:
2878 case DW_OP_reg24:
2879 case DW_OP_reg25:
2880 case DW_OP_reg26:
2881 case DW_OP_reg27:
2882 case DW_OP_reg28:
2883 case DW_OP_reg29:
2884 case DW_OP_reg30:
2885 case DW_OP_reg31:
2886 case DW_OP_regx:
2887 write_defrange_register (expr, range_start, range_end);
2888 break;
2890 case DW_OP_fbreg:
2891 write_defrange_register_rel (expr, fbloc, range_start, range_end);
2892 break;
2894 default:
2895 break;
2899 /* Write an optimized local variable, given by an S_LOCAL symbol followed by
2900 any number of S_DEFRANGE_* symbols. We can't mix and match optimized and
2901 unoptimized variables in the same function, so even if it stays in the same
2902 place for the whole block we need to write an S_LOCAL. */
2904 static void
2905 write_optimized_local_variable (dw_die_ref die, dw_loc_descr_ref fbloc,
2906 rtx block_start, rtx block_end)
2908 dw_attr_node *loc;
2909 dw_loc_list_ref loc_list;
2911 loc = get_AT (die, DW_AT_location);
2912 if (!loc)
2913 return;
2915 switch (loc->dw_attr_val.val_class)
2917 case dw_val_class_loc_list:
2918 loc_list = loc->dw_attr_val.v.val_loc_list;
2920 write_s_local (die);
2922 while (loc_list)
2924 rtx range_start = NULL, range_end = NULL;
2926 if (loc_list->begin)
2927 range_start = gen_rtx_SYMBOL_REF (Pmode, loc_list->begin);
2929 if (loc_list->end)
2930 range_end = gen_rtx_SYMBOL_REF (Pmode, loc_list->end);
2932 write_optimized_local_variable_loc (loc_list->expr, fbloc,
2933 range_start, range_end);
2935 loc_list = loc_list->dw_loc_next;
2937 break;
2939 case dw_val_class_loc:
2940 write_s_local (die);
2942 write_optimized_local_variable_loc (loc->dw_attr_val.v.val_loc, fbloc,
2943 block_start, block_end);
2944 break;
2946 default:
2947 break;
2951 /* Write a symbol representing an unoptimized variable within a function, if
2952 we're able to translate the DIE's DW_AT_location into its CodeView
2953 equivalent. */
2955 static void
2956 write_unoptimized_local_variable (dw_die_ref die, dw_loc_descr_ref fbloc)
2958 dw_attr_node *loc;
2959 dw_loc_descr_ref loc_ref;
2961 loc = get_AT (die, DW_AT_location);
2962 if (!loc)
2963 return;
2965 if (loc->dw_attr_val.val_class != dw_val_class_loc)
2966 return;
2968 loc_ref = loc->dw_attr_val.v.val_loc;
2969 if (!loc_ref)
2970 return;
2972 switch (loc_ref->dw_loc_opc)
2974 case DW_OP_addr:
2975 write_local_s_ldata32 (die, loc_ref);
2976 break;
2978 case DW_OP_reg0:
2979 case DW_OP_reg1:
2980 case DW_OP_reg2:
2981 case DW_OP_reg3:
2982 case DW_OP_reg4:
2983 case DW_OP_reg5:
2984 case DW_OP_reg6:
2985 case DW_OP_reg7:
2986 case DW_OP_reg8:
2987 case DW_OP_reg9:
2988 case DW_OP_reg10:
2989 case DW_OP_reg11:
2990 case DW_OP_reg12:
2991 case DW_OP_reg13:
2992 case DW_OP_reg14:
2993 case DW_OP_reg15:
2994 case DW_OP_reg16:
2995 case DW_OP_reg17:
2996 case DW_OP_reg18:
2997 case DW_OP_reg19:
2998 case DW_OP_reg20:
2999 case DW_OP_reg21:
3000 case DW_OP_reg22:
3001 case DW_OP_reg23:
3002 case DW_OP_reg24:
3003 case DW_OP_reg25:
3004 case DW_OP_reg26:
3005 case DW_OP_reg27:
3006 case DW_OP_reg28:
3007 case DW_OP_reg29:
3008 case DW_OP_reg30:
3009 case DW_OP_reg31:
3010 case DW_OP_regx:
3011 write_s_register (die, loc_ref);
3012 break;
3014 case DW_OP_fbreg:
3015 write_fbreg_variable (die, loc_ref, fbloc);
3016 break;
3018 default:
3019 break;
3023 /* Translate a DW_TAG_lexical_block DIE into an S_BLOCK32 symbol, representing
3024 a block within an unoptimized function. Returns false if we're not able
3025 to resolve the location, which will prevent the caller from issuing an
3026 unneeded S_END. */
3028 static bool
3029 write_s_block32 (dw_die_ref die)
3031 unsigned int label_num = ++sym_label_num;
3032 dw_attr_node *loc_low, *loc_high;
3033 const char *label_low, *label_high;
3034 rtx rtx_low, rtx_high;
3036 /* This is struct blocksym in binutils and BLOCKSYM32 in Microsoft's
3037 cvinfo.h:
3039 struct blocksym
3041 uint16_t size;
3042 uint16_t kind;
3043 uint32_t parent;
3044 uint32_t end;
3045 uint32_t len;
3046 uint32_t offset;
3047 uint16_t section;
3048 char name[];
3049 } ATTRIBUTE_PACKED;
3052 loc_low = get_AT (die, DW_AT_low_pc);
3053 if (!loc_low)
3054 return false;
3056 if (loc_low->dw_attr_val.val_class != dw_val_class_lbl_id)
3057 return false;
3059 label_low = loc_low->dw_attr_val.v.val_lbl_id;
3060 if (!label_low)
3061 return false;
3063 rtx_low = gen_rtx_SYMBOL_REF (Pmode, label_low);
3065 loc_high = get_AT (die, DW_AT_high_pc);
3066 if (!loc_high)
3067 return false;
3069 if (loc_high->dw_attr_val.val_class != dw_val_class_high_pc)
3070 return false;
3072 label_high = loc_high->dw_attr_val.v.val_lbl_id;
3073 if (!label_high)
3074 return false;
3076 rtx_high = gen_rtx_SYMBOL_REF (Pmode, label_high);
3078 fputs (integer_asm_op (2, false), asm_out_file);
3079 asm_fprintf (asm_out_file,
3080 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
3081 label_num, label_num);
3083 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
3085 fputs (integer_asm_op (2, false), asm_out_file);
3086 fprint_whex (asm_out_file, S_BLOCK32);
3087 putc ('\n', asm_out_file);
3089 /* The parent and end fields get filled in by the linker. */
3091 fputs (integer_asm_op (4, false), asm_out_file);
3092 fprint_whex (asm_out_file, 0);
3093 putc ('\n', asm_out_file);
3095 fputs (integer_asm_op (4, false), asm_out_file);
3096 fprint_whex (asm_out_file, 0);
3097 putc ('\n', asm_out_file);
3099 fputs (integer_asm_op (4, false), asm_out_file);
3100 output_addr_const (asm_out_file, rtx_high);
3101 fputs (" - ", asm_out_file);
3102 output_addr_const (asm_out_file, rtx_low);
3103 putc ('\n', asm_out_file);
3105 asm_fprintf (asm_out_file, "\t.secrel32 ");
3106 output_addr_const (asm_out_file, rtx_low);
3107 fputc ('\n', asm_out_file);
3109 asm_fprintf (asm_out_file, "\t.secidx ");
3110 output_addr_const (asm_out_file, rtx_low);
3111 fputc ('\n', asm_out_file);
3113 ASM_OUTPUT_ASCII (asm_out_file, "", 1);
3115 ASM_OUTPUT_ALIGN (asm_out_file, 2);
3117 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
3119 return true;
3122 /* Write an S_END symbol, which is used to finish off a number of different
3123 symbol types. Here we use it to mark the S_BLOCK32 as finished. */
3125 static void
3126 write_s_end (void)
3128 unsigned int label_num = ++sym_label_num;
3130 fputs (integer_asm_op (2, false), asm_out_file);
3131 asm_fprintf (asm_out_file,
3132 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
3133 label_num, label_num);
3135 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
3137 fputs (integer_asm_op (2, false), asm_out_file);
3138 fprint_whex (asm_out_file, S_END);
3139 putc ('\n', asm_out_file);
3141 ASM_OUTPUT_ALIGN (asm_out_file, 2);
3143 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
3146 /* Write the S_FRAMEPROC symbol, which is supposed to give information about
3147 the function frame. It doesn't seem to be really used in modern versions of
3148 MSVC, which is why we zero-out everything here. You still need to write it
3149 though, otherwise windbg won't necessarily show all the local variables. */
3151 static void
3152 write_s_frameproc (void)
3154 unsigned int label_num = ++sym_label_num;
3156 /* This is struct FRAMEPROCSYM in Microsoft's cvinfo.h:
3158 struct frameprocsym
3160 uint16_t size;
3161 uint16_t kind;
3162 uint32_t frame_size;
3163 uint32_t padding_size;
3164 uint32_t padding_offset;
3165 uint32_t saved_registers_size;
3166 uint32_t exception_handler_offset;
3167 uint16_t exception_handler_section;
3168 uint32_t flags;
3169 } ATTRIBUTE_PACKED;
3172 fputs (integer_asm_op (2, false), asm_out_file);
3173 asm_fprintf (asm_out_file,
3174 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
3175 label_num, label_num);
3177 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
3179 fputs (integer_asm_op (2, false), asm_out_file);
3180 fprint_whex (asm_out_file, S_FRAMEPROC);
3181 putc ('\n', asm_out_file);
3183 fputs (integer_asm_op (4, false), asm_out_file);
3184 fprint_whex (asm_out_file, 0);
3185 putc ('\n', asm_out_file);
3187 fputs (integer_asm_op (4, false), asm_out_file);
3188 fprint_whex (asm_out_file, 0);
3189 putc ('\n', asm_out_file);
3191 fputs (integer_asm_op (4, false), asm_out_file);
3192 fprint_whex (asm_out_file, 0);
3193 putc ('\n', asm_out_file);
3195 fputs (integer_asm_op (4, false), asm_out_file);
3196 fprint_whex (asm_out_file, 0);
3197 putc ('\n', asm_out_file);
3199 fputs (integer_asm_op (4, false), asm_out_file);
3200 fprint_whex (asm_out_file, 0);
3201 putc ('\n', asm_out_file);
3203 fputs (integer_asm_op (2, false), asm_out_file);
3204 fprint_whex (asm_out_file, 0);
3205 putc ('\n', asm_out_file);
3207 fputs (integer_asm_op (4, false), asm_out_file);
3208 fprint_whex (asm_out_file, 0);
3209 putc ('\n', asm_out_file);
3211 ASM_OUTPUT_ALIGN (asm_out_file, 2);
3213 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
3216 /* Loop through the DIEs in an unoptimized function, writing out any variables
3217 or blocks that we encounter. */
3219 static void
3220 write_unoptimized_function_vars (dw_die_ref die, dw_loc_descr_ref fbloc)
3222 dw_die_ref first_child, c;
3224 first_child = dw_get_die_child (die);
3226 if (!first_child)
3227 return;
3229 c = first_child;
3232 c = dw_get_die_sib (c);
3234 switch (dw_get_die_tag (c))
3236 case DW_TAG_formal_parameter:
3237 case DW_TAG_variable:
3238 write_unoptimized_local_variable (c, fbloc);
3239 break;
3241 case DW_TAG_lexical_block:
3243 bool block_started = write_s_block32 (c);
3245 write_unoptimized_function_vars (c, fbloc);
3247 if (block_started)
3248 write_s_end ();
3250 break;
3253 default:
3254 break;
3257 while (c != first_child);
3260 /* Write the variables in an optimized function or block. There's no S_BLOCK32s
3261 here, with the range determining the lifetime of a variable. Unfortunately
3262 for us CodeView is much less expressive than DWARF when it comes to variable
3263 locations, so some degree of "optimized out"s is inevitable. */
3265 static void
3266 write_optimized_function_vars (dw_die_ref die, dw_loc_descr_ref fbloc,
3267 rtx block_start, rtx block_end)
3269 dw_die_ref first_child, c;
3271 first_child = dw_get_die_child (die);
3273 if (!first_child)
3274 return;
3276 c = first_child;
3279 c = dw_get_die_sib (c);
3281 switch (dw_get_die_tag (c))
3283 case DW_TAG_formal_parameter:
3284 case DW_TAG_variable:
3285 write_optimized_local_variable (c, fbloc, block_start, block_end);
3286 break;
3288 case DW_TAG_lexical_block:
3290 dw_attr_node *loc_low, *loc_high;
3291 const char *label_low, *label_high;
3292 rtx rtx_low, rtx_high;
3294 loc_low = get_AT (die, DW_AT_low_pc);
3295 if (!loc_low)
3296 break;
3298 if (loc_low->dw_attr_val.val_class != dw_val_class_lbl_id)
3299 break;
3301 label_low = loc_low->dw_attr_val.v.val_lbl_id;
3302 if (!label_low)
3303 break;
3305 rtx_low = gen_rtx_SYMBOL_REF (Pmode, label_low);
3307 loc_high = get_AT (die, DW_AT_high_pc);
3308 if (!loc_high)
3309 break;
3311 if (loc_high->dw_attr_val.val_class != dw_val_class_high_pc)
3312 break;
3314 label_high = loc_high->dw_attr_val.v.val_lbl_id;
3315 if (!label_high)
3316 break;
3318 rtx_high = gen_rtx_SYMBOL_REF (Pmode, label_high);
3320 write_optimized_function_vars (c, fbloc, rtx_low, rtx_high);
3322 break;
3325 default:
3326 break;
3329 while (c != first_child);
3332 /* There's no way to mark the range of a static local variable in an optimized
3333 function: there's no S_DEFRANGE_* symbol for this, and you can't have
3334 S_BLOCK32 symbols. So instead we have to loop through after the S_FRAMEPROC
3335 has been written, and write the S_LDATA32s at the end. */
3337 static void
3338 write_optimized_static_local_vars (dw_die_ref die)
3340 dw_die_ref first_child, c;
3342 first_child = dw_get_die_child (die);
3344 if (!first_child)
3345 return;
3347 c = first_child;
3350 c = dw_get_die_sib (c);
3352 switch (dw_get_die_tag (c))
3354 case DW_TAG_variable:
3356 dw_attr_node *loc;
3357 dw_loc_descr_ref loc_ref;
3359 loc = get_AT (c, DW_AT_location);
3360 if (!loc)
3361 break;
3363 if (loc->dw_attr_val.val_class != dw_val_class_loc)
3364 break;
3366 loc_ref = loc->dw_attr_val.v.val_loc;
3367 if (!loc_ref)
3368 break;
3370 if (loc_ref->dw_loc_opc != DW_OP_addr)
3371 break;
3373 write_local_s_ldata32 (c, loc_ref);
3374 break;
3377 case DW_TAG_lexical_block:
3378 write_optimized_static_local_vars (c);
3379 break;
3381 default:
3382 break;
3385 while (c != first_child);
3388 #ifdef HAVE_GAS_CV_UCOMP
3390 /* Given a DW_TAG_inlined_subroutine DIE within parent_func, return a pointer
3391 to the corresponding codeview_function, which is used to map addresses
3392 to line numbers. */
3394 static codeview_function *
3395 find_line_function (dw_die_ref parent_func, dw_die_ref die)
3397 codeview_function **slot, *f;
3399 if (!cv_func_htab)
3400 return NULL;
3402 slot = cv_func_htab->find_slot_with_hash (parent_func,
3403 htab_hash_pointer (parent_func),
3404 NO_INSERT);
3406 if (!slot || !*slot)
3407 return NULL;
3409 f = *slot;
3411 while (f)
3413 expanded_location loc;
3414 dwarf_file_data *call_file;
3416 if (f->inline_block == 0)
3418 f = f->htab_next;
3419 continue;
3422 loc = expand_location (f->inline_loc);
3424 if ((unsigned) loc.line != get_AT_unsigned (die, DW_AT_call_line)
3425 || (unsigned) loc.column != get_AT_unsigned (die, DW_AT_call_column))
3427 f = f->htab_next;
3428 continue;
3431 call_file = get_AT_file (die, DW_AT_call_file);
3433 if (!call_file || strcmp (call_file->filename, loc.file))
3435 f = f->htab_next;
3436 continue;
3439 return f;
3442 return NULL;
3445 /* Write the "binary annotations" for an S_INLINESITE symbol, which are how
3446 CodeView represents line numbers within inlined functions. This is
3447 completely different to how line numbers are represented normally, and
3448 requires assembler support for the .cv_ucomp and .cv_scomp pseudos. */
3450 static void
3451 write_binary_annotations (codeview_function *line_func, uint32_t func_id)
3453 codeview_line_block *b;
3454 codeview_inlinee_lines **slot, *il;
3455 codeview_function *top_parent;
3456 unsigned int line_no, label_num;
3458 slot = inlinee_lines_htab->find_slot_with_hash (func_id, func_id, NO_INSERT);
3459 if (!slot || !*slot)
3460 return;
3462 il = *slot;
3464 line_no = il->starting_line;
3466 top_parent = line_func;
3467 while (top_parent->parent)
3469 top_parent = top_parent->parent;
3472 label_num = top_parent->blocks->lines->label_num;
3474 b = line_func->blocks;
3475 while (b)
3477 codeview_line *l = b->lines;
3479 while (l)
3481 if (!l->next && !b->next) /* last line (end of block) */
3483 asm_fprintf (asm_out_file, "\t.cv_ucomp %u\n",
3484 ba_op_change_code_length);
3485 asm_fprintf (asm_out_file,
3486 "\t.cv_ucomp %L" LINE_LABEL "%u - %L" LINE_LABEL "%u\n",
3487 l->label_num, label_num);
3489 else
3491 if (l->line_no != line_no)
3493 asm_fprintf (asm_out_file, "\t.cv_ucomp %u\n",
3494 ba_op_change_line_offset);
3495 asm_fprintf (asm_out_file, "\t.cv_scomp %i\n",
3496 l->line_no - line_no);
3498 line_no = l->line_no;
3501 asm_fprintf (asm_out_file, "\t.cv_ucomp %u\n",
3502 ba_op_change_code_offset);
3503 asm_fprintf (asm_out_file,
3504 "\t.cv_ucomp %L" LINE_LABEL "%u - %L" LINE_LABEL "%u\n",
3505 l->label_num, label_num);
3508 label_num = l->label_num;
3510 l = l->next;
3513 b = b->next;
3517 #endif
3519 /* Write an S_INLINESITE symbol, to record that a function has been inlined
3520 inside another function. */
3522 static void
3523 write_s_inlinesite (dw_die_ref parent_func, dw_die_ref die)
3525 unsigned int label_num = ++sym_label_num;
3526 dw_die_ref func;
3527 uint32_t func_id;
3528 codeview_function *line_func;
3530 func = get_AT_ref (die, DW_AT_abstract_origin);
3531 if (!func)
3532 return;
3534 func_id = get_func_id (func);
3535 if (func_id == 0)
3536 return;
3538 /* This is struct inline_site in binutils and INLINESITESYM in Microsoft's
3539 cvinfo.h:
3541 struct inline_site
3543 uint16_t size;
3544 uint16_t kind;
3545 uint32_t parent;
3546 uint32_t end;
3547 uint32_t inlinee;
3548 uint8_t binary_annotations[];
3549 } ATTRIBUTE_PACKED;
3552 fputs (integer_asm_op (2, false), asm_out_file);
3553 asm_fprintf (asm_out_file,
3554 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
3555 label_num, label_num);
3557 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
3559 fputs (integer_asm_op (2, false), asm_out_file);
3560 fprint_whex (asm_out_file, S_INLINESITE);
3561 putc ('\n', asm_out_file);
3563 /* parent, filled in by linker */
3564 fputs (integer_asm_op (4, false), asm_out_file);
3565 fprint_whex (asm_out_file, 0);
3566 putc ('\n', asm_out_file);
3568 /* end, filled in by linker */
3569 fputs (integer_asm_op (4, false), asm_out_file);
3570 fprint_whex (asm_out_file, 0);
3571 putc ('\n', asm_out_file);
3573 fputs (integer_asm_op (4, false), asm_out_file);
3574 fprint_whex (asm_out_file, func_id);
3575 putc ('\n', asm_out_file);
3577 #ifdef HAVE_GAS_CV_UCOMP
3578 line_func = find_line_function (parent_func, die);
3580 if (line_func)
3582 write_binary_annotations (line_func, func_id);
3583 ASM_OUTPUT_ALIGN (asm_out_file, 2);
3585 #else
3586 (void) line_func;
3587 #endif
3589 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
3591 write_inlinesite_records (parent_func, die);
3593 /* Write S_INLINESITE_END symbol. */
3595 label_num = ++sym_label_num;
3597 fputs (integer_asm_op (2, false), asm_out_file);
3598 asm_fprintf (asm_out_file,
3599 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
3600 label_num, label_num);
3602 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
3604 fputs (integer_asm_op (2, false), asm_out_file);
3605 fprint_whex (asm_out_file, S_INLINESITE_END);
3606 putc ('\n', asm_out_file);
3608 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
3611 /* Loop through a function, and translate its DW_TAG_inlined_subroutine DIEs
3612 into CodeView S_INLINESITE symbols. */
3614 static void
3615 write_inlinesite_records (dw_die_ref func, dw_die_ref die)
3617 dw_die_ref first_child, c;
3619 first_child = dw_get_die_child (die);
3621 if (!first_child)
3622 return;
3624 c = first_child;
3627 c = dw_get_die_sib (c);
3629 switch (dw_get_die_tag (c))
3631 case DW_TAG_lexical_block:
3632 write_inlinesite_records (func, c);
3633 break;
3635 case DW_TAG_inlined_subroutine:
3636 write_s_inlinesite (func, c);
3637 break;
3639 default:
3640 break;
3643 while (c != first_child);
3646 /* Write an S_GPROC32_ID symbol, representing a global function, or an
3647 S_LPROC32_ID symbol, for a static function. */
3649 static void
3650 write_function (codeview_symbol *s)
3652 unsigned int label_num = ++sym_label_num;
3653 dw_attr_node *loc_low, *loc_high, *frame_base;
3654 const char *label_low, *label_high;
3655 rtx rtx_low, rtx_high;
3656 dw_loc_descr_ref fbloc = NULL;
3658 /* This is struct procsym in binutils and PROCSYM32 in Microsoft's cvinfo.h:
3660 struct procsym
3662 uint16_t size;
3663 uint16_t kind;
3664 uint32_t parent;
3665 uint32_t end;
3666 uint32_t next;
3667 uint32_t proc_len;
3668 uint32_t debug_start;
3669 uint32_t debug_end;
3670 uint32_t type;
3671 uint32_t offset;
3672 uint16_t section;
3673 uint8_t flags;
3674 char name[];
3675 } ATTRIBUTE_PACKED;
3678 loc_low = get_AT (s->function.die, DW_AT_low_pc);
3679 if (!loc_low)
3680 goto end;
3682 if (loc_low->dw_attr_val.val_class != dw_val_class_lbl_id)
3683 goto end;
3685 label_low = loc_low->dw_attr_val.v.val_lbl_id;
3686 if (!label_low)
3687 goto end;
3689 rtx_low = gen_rtx_SYMBOL_REF (Pmode, label_low);
3691 loc_high = get_AT (s->function.die, DW_AT_high_pc);
3692 if (!loc_high)
3693 goto end;
3695 if (loc_high->dw_attr_val.val_class != dw_val_class_high_pc)
3696 goto end;
3698 label_high = loc_high->dw_attr_val.v.val_lbl_id;
3699 if (!label_high)
3700 goto end;
3702 rtx_high = gen_rtx_SYMBOL_REF (Pmode, label_high);
3704 /* Output the S_GPROC32_ID / S_LPROC32_ID record. */
3706 fputs (integer_asm_op (2, false), asm_out_file);
3707 asm_fprintf (asm_out_file,
3708 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
3709 label_num, label_num);
3711 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
3713 fputs (integer_asm_op (2, false), asm_out_file);
3714 fprint_whex (asm_out_file, s->kind);
3715 putc ('\n', asm_out_file);
3717 fputs (integer_asm_op (4, false), asm_out_file);
3718 fprint_whex (asm_out_file, s->function.parent);
3719 putc ('\n', asm_out_file);
3721 fputs (integer_asm_op (4, false), asm_out_file);
3722 fprint_whex (asm_out_file, s->function.end);
3723 putc ('\n', asm_out_file);
3725 fputs (integer_asm_op (4, false), asm_out_file);
3726 fprint_whex (asm_out_file, s->function.next);
3727 putc ('\n', asm_out_file);
3729 fputs (integer_asm_op (4, false), asm_out_file);
3730 output_addr_const (asm_out_file, rtx_high);
3731 fputs (" - ", asm_out_file);
3732 output_addr_const (asm_out_file, rtx_low);
3733 putc ('\n', asm_out_file);
3735 /* FIXME - debug_start should be the end of the prologue, and debug_end
3736 the beginning of the epilogue. Do the whole function for
3737 now. */
3739 fputs (integer_asm_op (4, false), asm_out_file);
3740 fprint_whex (asm_out_file, 0);
3741 putc ('\n', asm_out_file);
3743 fputs (integer_asm_op (4, false), asm_out_file);
3744 output_addr_const (asm_out_file, rtx_high);
3745 fputs (" - ", asm_out_file);
3746 output_addr_const (asm_out_file, rtx_low);
3747 putc ('\n', asm_out_file);
3749 fputs (integer_asm_op (4, false), asm_out_file);
3750 fprint_whex (asm_out_file, s->function.type);
3751 putc ('\n', asm_out_file);
3753 asm_fprintf (asm_out_file, "\t.secrel32 ");
3754 output_addr_const (asm_out_file, rtx_low);
3755 fputc ('\n', asm_out_file);
3757 asm_fprintf (asm_out_file, "\t.secidx ");
3758 output_addr_const (asm_out_file, rtx_low);
3759 fputc ('\n', asm_out_file);
3761 fputs (integer_asm_op (1, false), asm_out_file);
3762 fprint_whex (asm_out_file, s->function.flags);
3763 putc ('\n', asm_out_file);
3765 ASM_OUTPUT_ASCII (asm_out_file, s->function.name,
3766 strlen (s->function.name) + 1);
3768 ASM_OUTPUT_ALIGN (asm_out_file, 2);
3770 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
3772 write_inlinesite_records (s->function.die, s->function.die);
3774 frame_base = get_AT (s->function.die, DW_AT_frame_base);
3776 if (frame_base && frame_base->dw_attr_val.val_class == dw_val_class_loc)
3777 fbloc = frame_base->dw_attr_val.v.val_loc;
3779 if (flag_var_tracking)
3781 write_optimized_function_vars (s->function.die, fbloc, rtx_low,
3782 rtx_high);
3783 write_s_frameproc ();
3784 write_optimized_static_local_vars (s->function.die);
3786 else
3788 write_s_frameproc ();
3789 write_unoptimized_function_vars (s->function.die, fbloc);
3792 /* Output the S_PROC_ID_END record. */
3794 label_num = ++sym_label_num;
3796 fputs (integer_asm_op (2, false), asm_out_file);
3797 asm_fprintf (asm_out_file,
3798 "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
3799 label_num, label_num);
3801 targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
3803 fputs (integer_asm_op (2, false), asm_out_file);
3804 fprint_whex (asm_out_file, S_PROC_ID_END);
3805 putc ('\n', asm_out_file);
3807 targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
3809 end:
3810 free (s->function.name);
3813 /* Write the CodeView symbols into the .debug$S section. */
3815 static void
3816 write_codeview_symbols (void)
3818 fputs (integer_asm_op (4, false), asm_out_file);
3819 fprint_whex (asm_out_file, DEBUG_S_SYMBOLS);
3820 putc ('\n', asm_out_file);
3822 fputs (integer_asm_op (4, false), asm_out_file);
3823 asm_fprintf (asm_out_file, "%LLcv_syms_end - %LLcv_syms_start\n");
3825 asm_fprintf (asm_out_file, "%LLcv_syms_start:\n");
3827 write_compile3_symbol ();
3829 while (sym)
3831 codeview_symbol *n = sym->next;
3833 switch (sym->kind)
3835 case S_LDATA32:
3836 case S_GDATA32:
3837 write_data_symbol (sym);
3838 break;
3839 case S_LPROC32_ID:
3840 case S_GPROC32_ID:
3841 write_function (sym);
3842 break;
3843 default:
3844 break;
3847 free (sym);
3848 sym = n;
3851 asm_fprintf (asm_out_file, "%LLcv_syms_end:\n");
3854 /* Write an LF_POINTER type. */
3856 static void
3857 write_lf_pointer (codeview_custom_type *t)
3859 /* This is lf_pointer in binutils and lfPointer in Microsoft's cvinfo.h:
3861 struct lf_pointer
3863 uint16_t size;
3864 uint16_t kind;
3865 uint32_t base_type;
3866 uint32_t attributes;
3867 (following only if CV_PTR_MODE_PMEM or CV_PTR_MODE_PMFUNC in attributes)
3868 uint32_t containing_class;
3869 uint16_t ptr_to_mem_type;
3870 uint16_t padding;
3871 } ATTRIBUTE_PACKED;
3874 fputs (integer_asm_op (2, false), asm_out_file);
3875 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
3876 t->num, t->num);
3878 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
3880 fputs (integer_asm_op (2, false), asm_out_file);
3881 fprint_whex (asm_out_file, t->kind);
3882 putc ('\n', asm_out_file);
3884 fputs (integer_asm_op (4, false), asm_out_file);
3885 fprint_whex (asm_out_file, t->lf_pointer.base_type);
3886 putc ('\n', asm_out_file);
3888 fputs (integer_asm_op (4, false), asm_out_file);
3889 fprint_whex (asm_out_file, t->lf_pointer.attributes);
3890 putc ('\n', asm_out_file);
3892 if ((t->lf_pointer.attributes & CV_PTR_MODE_MASK) == CV_PTR_MODE_PMEM
3893 || (t->lf_pointer.attributes & CV_PTR_MODE_MASK) == CV_PTR_MODE_PMFUNC)
3895 fputs (integer_asm_op (4, false), asm_out_file);
3896 fprint_whex (asm_out_file, t->lf_pointer.containing_class);
3897 putc ('\n', asm_out_file);
3899 fputs (integer_asm_op (2, false), asm_out_file);
3900 fprint_whex (asm_out_file, t->lf_pointer.ptr_to_mem_type);
3901 putc ('\n', asm_out_file);
3903 write_cv_padding (2);
3906 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
3909 /* All CodeView type definitions have to be aligned to a four-byte boundary,
3910 so write some padding bytes if necessary. These have to be specific values:
3911 LF_PAD3, LF_PAD2, LF_PAD1. */
3913 static void
3914 write_cv_padding (size_t padding)
3916 if (padding == 4 || padding == 0)
3917 return;
3919 if (padding == 3)
3921 fputs (integer_asm_op (1, false), asm_out_file);
3922 fprint_whex (asm_out_file, LF_PAD3);
3923 putc ('\n', asm_out_file);
3926 if (padding >= 2)
3928 fputs (integer_asm_op (1, false), asm_out_file);
3929 fprint_whex (asm_out_file, LF_PAD2);
3930 putc ('\n', asm_out_file);
3933 fputs (integer_asm_op (1, false), asm_out_file);
3934 fprint_whex (asm_out_file, LF_PAD1);
3935 putc ('\n', asm_out_file);
3938 /* Write an LF_MODIFIER type, representing a const and/or volatile modification
3939 of another type. */
3941 static void
3942 write_lf_modifier (codeview_custom_type *t)
3944 /* This is lf_modifier in binutils and lfModifier in Microsoft's cvinfo.h:
3946 struct lf_modifier
3948 uint16_t size;
3949 uint16_t kind;
3950 uint32_t base_type;
3951 uint16_t modifier;
3952 uint16_t padding;
3953 } ATTRIBUTE_PACKED;
3956 fputs (integer_asm_op (2, false), asm_out_file);
3957 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
3958 t->num, t->num);
3960 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
3962 fputs (integer_asm_op (2, false), asm_out_file);
3963 fprint_whex (asm_out_file, t->kind);
3964 putc ('\n', asm_out_file);
3966 fputs (integer_asm_op (4, false), asm_out_file);
3967 fprint_whex (asm_out_file, t->lf_modifier.base_type);
3968 putc ('\n', asm_out_file);
3970 fputs (integer_asm_op (2, false), asm_out_file);
3971 fprint_whex (asm_out_file, t->lf_modifier.modifier);
3972 putc ('\n', asm_out_file);
3974 write_cv_padding (2);
3976 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
3979 /* Write a CodeView extensible integer. If the value is non-negative and
3980 < 0x8000, the value gets written directly as an uint16_t. Otherwise, we
3981 output two bytes for the integer type (LF_CHAR, LF_SHORT, ...), and the
3982 actual value follows. Returns the total number of bytes written. */
3984 static size_t
3985 write_cv_integer (codeview_integer *i)
3987 if (i->neg)
3989 if (i->num <= 0x80)
3991 fputs (integer_asm_op (2, false), asm_out_file);
3992 fprint_whex (asm_out_file, LF_CHAR);
3993 putc ('\n', asm_out_file);
3995 fputs (integer_asm_op (1, false), asm_out_file);
3996 fprint_whex (asm_out_file, -i->num);
3997 putc ('\n', asm_out_file);
3999 return 3;
4001 else if (i->num <= 0x8000)
4003 fputs (integer_asm_op (2, false), asm_out_file);
4004 fprint_whex (asm_out_file, LF_SHORT);
4005 putc ('\n', asm_out_file);
4007 fputs (integer_asm_op (2, false), asm_out_file);
4008 fprint_whex (asm_out_file, -i->num);
4009 putc ('\n', asm_out_file);
4011 return 4;
4013 else if (i->num <= 0x80000000)
4015 fputs (integer_asm_op (2, false), asm_out_file);
4016 fprint_whex (asm_out_file, LF_LONG);
4017 putc ('\n', asm_out_file);
4019 fputs (integer_asm_op (4, false), asm_out_file);
4020 fprint_whex (asm_out_file, -i->num);
4021 putc ('\n', asm_out_file);
4023 return 6;
4025 else
4027 fputs (integer_asm_op (2, false), asm_out_file);
4028 fprint_whex (asm_out_file, LF_QUADWORD);
4029 putc ('\n', asm_out_file);
4031 fputs (integer_asm_op (8, false), asm_out_file);
4032 fprint_whex (asm_out_file, -i->num);
4033 putc ('\n', asm_out_file);
4035 return 10;
4038 else
4040 if (i->num <= 0x7fff)
4042 fputs (integer_asm_op (2, false), asm_out_file);
4043 fprint_whex (asm_out_file, i->num);
4044 putc ('\n', asm_out_file);
4046 return 2;
4048 else if (i->num <= 0xffff)
4050 fputs (integer_asm_op (2, false), asm_out_file);
4051 fprint_whex (asm_out_file, LF_USHORT);
4052 putc ('\n', asm_out_file);
4054 fputs (integer_asm_op (2, false), asm_out_file);
4055 fprint_whex (asm_out_file, i->num);
4056 putc ('\n', asm_out_file);
4058 return 4;
4060 else if (i->num <= 0xffffffff)
4062 fputs (integer_asm_op (2, false), asm_out_file);
4063 fprint_whex (asm_out_file, LF_ULONG);
4064 putc ('\n', asm_out_file);
4066 fputs (integer_asm_op (4, false), asm_out_file);
4067 fprint_whex (asm_out_file, i->num);
4068 putc ('\n', asm_out_file);
4070 return 6;
4072 else
4074 fputs (integer_asm_op (2, false), asm_out_file);
4075 fprint_whex (asm_out_file, LF_UQUADWORD);
4076 putc ('\n', asm_out_file);
4078 fputs (integer_asm_op (8, false), asm_out_file);
4079 fprint_whex (asm_out_file, i->num);
4080 putc ('\n', asm_out_file);
4082 return 10;
4087 /* Return the extra size needed for an extensible integer. */
4089 static size_t
4090 cv_integer_len (codeview_integer *i)
4092 if (i->neg)
4094 if (i->num <= 0x80)
4095 return sizeof (int8_t);
4096 else if (i->num <= 0x8000)
4097 return sizeof (int16_t);
4098 else if (i->num <= 0x80000000)
4099 return sizeof (int32_t);
4100 else
4101 return sizeof (int64_t);
4103 else
4105 if (i->num <= 0x7fff)
4106 return 0;
4107 else if (i->num <= 0xffff)
4108 return sizeof (uint16_t);
4109 else if (i->num <= 0xffffffff)
4110 return sizeof (uint32_t);
4111 else
4112 return sizeof (uint64_t);
4116 /* Write an LF_FIELDLIST type, which is a container for various subtypes. This
4117 has two uses: for the values in an enum, and for the member, operators etc.
4118 for a struct, class, or union. */
4120 static void
4121 write_lf_fieldlist (codeview_custom_type *t)
4123 fputs (integer_asm_op (2, false), asm_out_file);
4124 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4125 t->num, t->num);
4127 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4129 fputs (integer_asm_op (2, false), asm_out_file);
4130 fprint_whex (asm_out_file, t->kind);
4131 putc ('\n', asm_out_file);
4133 while (t->lf_fieldlist.subtypes)
4135 codeview_subtype *v = t->lf_fieldlist.subtypes;
4136 codeview_subtype *next = v->next;
4137 size_t name_len, leaf_len;
4139 switch (v->kind)
4141 case LF_ENUMERATE:
4142 /* This is lf_enumerate in binutils and lfEnumerate in Microsoft's
4143 cvinfo.h:
4145 struct lf_enumerate
4147 uint16_t kind;
4148 uint16_t attributes;
4149 uint16_t value;
4150 (then actual value if value >= 0x8000)
4151 char name[];
4152 } ATTRIBUTE_PACKED;
4155 fputs (integer_asm_op (2, false), asm_out_file);
4156 fprint_whex (asm_out_file, LF_ENUMERATE);
4157 putc ('\n', asm_out_file);
4159 fputs (integer_asm_op (2, false), asm_out_file);
4160 fprint_whex (asm_out_file, CV_ACCESS_PUBLIC);
4161 putc ('\n', asm_out_file);
4163 leaf_len = 4 + write_cv_integer (&v->lf_enumerate.value);
4165 name_len = strlen (v->lf_enumerate.name) + 1;
4166 ASM_OUTPUT_ASCII (asm_out_file, v->lf_enumerate.name, name_len);
4168 leaf_len += name_len;
4169 write_cv_padding (4 - (leaf_len % 4));
4171 free (v->lf_enumerate.name);
4172 break;
4174 case LF_MEMBER:
4175 /* This is lf_member in binutils and lfMember in Microsoft's
4176 cvinfo.h:
4178 struct lf_member
4180 uint16_t kind;
4181 uint16_t attributes;
4182 uint32_t type;
4183 uint16_t offset;
4184 char name[];
4185 } ATTRIBUTE_PACKED;
4188 fputs (integer_asm_op (2, false), asm_out_file);
4189 fprint_whex (asm_out_file, LF_MEMBER);
4190 putc ('\n', asm_out_file);
4192 fputs (integer_asm_op (2, false), asm_out_file);
4193 fprint_whex (asm_out_file, v->lf_member.attributes);
4194 putc ('\n', asm_out_file);
4196 fputs (integer_asm_op (4, false), asm_out_file);
4197 fprint_whex (asm_out_file, v->lf_member.type);
4198 putc ('\n', asm_out_file);
4200 leaf_len = 8 + write_cv_integer (&v->lf_member.offset);
4202 if (v->lf_member.name)
4204 name_len = strlen (v->lf_member.name) + 1;
4205 ASM_OUTPUT_ASCII (asm_out_file, v->lf_member.name, name_len);
4207 else
4209 name_len = 1;
4210 ASM_OUTPUT_ASCII (asm_out_file, "", name_len);
4213 leaf_len += name_len;
4214 write_cv_padding (4 - (leaf_len % 4));
4216 free (v->lf_member.name);
4217 break;
4219 case LF_INDEX:
4220 /* This is lf_index in binutils and lfIndex in Microsoft's cvinfo.h:
4222 struct lf_index
4224 uint16_t kind;
4225 uint16_t padding;
4226 uint32_t index;
4227 } ATTRIBUTE_PACKED;
4230 fputs (integer_asm_op (2, false), asm_out_file);
4231 fprint_whex (asm_out_file, LF_INDEX);
4232 putc ('\n', asm_out_file);
4234 fputs (integer_asm_op (2, false), asm_out_file);
4235 fprint_whex (asm_out_file, 0);
4236 putc ('\n', asm_out_file);
4238 fputs (integer_asm_op (4, false), asm_out_file);
4239 fprint_whex (asm_out_file, v->lf_index.type_num);
4240 putc ('\n', asm_out_file);
4242 break;
4244 case LF_STMEMBER:
4245 /* This is lf_static_member in binutils and lfSTMember in Microsoft's
4246 cvinfo.h:
4248 struct lf_static_member
4250 uint16_t kind;
4251 uint16_t attributes;
4252 uint32_t type;
4253 char name[];
4254 } ATTRIBUTE_PACKED;
4257 fputs (integer_asm_op (2, false), asm_out_file);
4258 fprint_whex (asm_out_file, LF_STMEMBER);
4259 putc ('\n', asm_out_file);
4261 fputs (integer_asm_op (2, false), asm_out_file);
4262 fprint_whex (asm_out_file, v->lf_static_member.attributes);
4263 putc ('\n', asm_out_file);
4265 fputs (integer_asm_op (4, false), asm_out_file);
4266 fprint_whex (asm_out_file, v->lf_static_member.type);
4267 putc ('\n', asm_out_file);
4269 name_len = strlen (v->lf_static_member.name) + 1;
4270 ASM_OUTPUT_ASCII (asm_out_file, v->lf_static_member.name, name_len);
4272 leaf_len = 8 + name_len;
4273 write_cv_padding (4 - (leaf_len % 4));
4275 free (v->lf_static_member.name);
4276 break;
4278 case LF_ONEMETHOD:
4279 /* This is lf_onemethod in binutils and lfOneMethod in Microsoft's
4280 cvinfo.h:
4282 struct lf_onemethod
4284 uint16_t kind;
4285 uint16_t method_attribute;
4286 uint32_t method_type;
4287 char name[];
4288 } ATTRIBUTE_PACKED;
4291 fputs (integer_asm_op (2, false), asm_out_file);
4292 fprint_whex (asm_out_file, LF_ONEMETHOD);
4293 putc ('\n', asm_out_file);
4295 fputs (integer_asm_op (2, false), asm_out_file);
4296 fprint_whex (asm_out_file, v->lf_onemethod.method_attribute);
4297 putc ('\n', asm_out_file);
4299 fputs (integer_asm_op (4, false), asm_out_file);
4300 fprint_whex (asm_out_file, v->lf_onemethod.method_type);
4301 putc ('\n', asm_out_file);
4303 name_len = strlen (v->lf_onemethod.name) + 1;
4304 ASM_OUTPUT_ASCII (asm_out_file, v->lf_onemethod.name, name_len);
4306 leaf_len = 8 + name_len;
4307 write_cv_padding (4 - (leaf_len % 4));
4309 free (v->lf_onemethod.name);
4310 break;
4312 case LF_METHOD:
4313 /* This is lf_method in binutils and lfMethod in Microsoft's
4314 cvinfo.h:
4316 struct lf_method
4318 uint16_t kind;
4319 uint16_t count;
4320 uint32_t method_list;
4321 char name[];
4322 } ATTRIBUTE_PACKED;
4325 fputs (integer_asm_op (2, false), asm_out_file);
4326 fprint_whex (asm_out_file, LF_METHOD);
4327 putc ('\n', asm_out_file);
4329 fputs (integer_asm_op (2, false), asm_out_file);
4330 fprint_whex (asm_out_file, v->lf_method.count);
4331 putc ('\n', asm_out_file);
4333 fputs (integer_asm_op (4, false), asm_out_file);
4334 fprint_whex (asm_out_file, v->lf_method.method_list);
4335 putc ('\n', asm_out_file);
4337 name_len = strlen (v->lf_method.name) + 1;
4338 ASM_OUTPUT_ASCII (asm_out_file, v->lf_method.name, name_len);
4340 leaf_len = 8 + name_len;
4341 write_cv_padding (4 - (leaf_len % 4));
4343 free (v->lf_method.name);
4344 break;
4346 case LF_BCLASS:
4347 /* This is lf_bclass in binutils and lfBClass in Microsoft's
4348 cvinfo.h:
4350 struct lf_bclass
4352 uint16_t kind;
4353 uint16_t attributes;
4354 uint32_t base_class_type;
4355 uint16_t offset;
4356 } ATTRIBUTE_PACKED;
4359 fputs (integer_asm_op (2, false), asm_out_file);
4360 fprint_whex (asm_out_file, LF_BCLASS);
4361 putc ('\n', asm_out_file);
4363 fputs (integer_asm_op (2, false), asm_out_file);
4364 fprint_whex (asm_out_file, v->lf_bclass.attributes);
4365 putc ('\n', asm_out_file);
4367 fputs (integer_asm_op (4, false), asm_out_file);
4368 fprint_whex (asm_out_file, v->lf_bclass.base_class_type);
4369 putc ('\n', asm_out_file);
4371 leaf_len = 8 + write_cv_integer (&v->lf_bclass.offset);
4373 write_cv_padding (4 - (leaf_len % 4));
4374 break;
4376 case LF_NESTTYPE:
4377 /* This is lf_nest_type in binutils and lfNestType in Microsoft's
4378 cvinfo.h:
4380 struct lf_nest_type
4382 uint16_t kind;
4383 uint16_t padding;
4384 uint32_t type;
4385 char name[];
4386 } ATTRIBUTE_PACKED;
4389 fputs (integer_asm_op (2, false), asm_out_file);
4390 fprint_whex (asm_out_file, LF_NESTTYPE);
4391 putc ('\n', asm_out_file);
4393 fputs (integer_asm_op (2, false), asm_out_file);
4394 fprint_whex (asm_out_file, 0);
4395 putc ('\n', asm_out_file);
4397 fputs (integer_asm_op (4, false), asm_out_file);
4398 fprint_whex (asm_out_file, v->lf_nesttype.type);
4399 putc ('\n', asm_out_file);
4401 name_len = strlen (v->lf_nesttype.name) + 1;
4402 ASM_OUTPUT_ASCII (asm_out_file, v->lf_nesttype.name, name_len);
4404 leaf_len = 8 + name_len;
4405 write_cv_padding (4 - (leaf_len % 4));
4407 free (v->lf_nesttype.name);
4408 break;
4410 default:
4411 break;
4414 t->lf_fieldlist.subtypes = next;
4415 free (v);
4418 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4421 /* Write an LF_ENUM type. */
4423 static void
4424 write_lf_enum (codeview_custom_type *t)
4426 size_t name_len, leaf_len;
4428 /* This is lf_enum in binutils and lfEnum in Microsoft's cvinfo.h:
4430 struct lf_enum
4432 uint16_t size;
4433 uint16_t kind;
4434 uint16_t num_elements;
4435 uint16_t properties;
4436 uint32_t underlying_type;
4437 uint32_t field_list;
4438 char name[];
4439 } ATTRIBUTE_PACKED;
4442 fputs (integer_asm_op (2, false), asm_out_file);
4443 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4444 t->num, t->num);
4446 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4448 fputs (integer_asm_op (2, false), asm_out_file);
4449 fprint_whex (asm_out_file, t->kind);
4450 putc ('\n', asm_out_file);
4452 fputs (integer_asm_op (2, false), asm_out_file);
4453 fprint_whex (asm_out_file, t->lf_enum.count);
4454 putc ('\n', asm_out_file);
4456 fputs (integer_asm_op (2, false), asm_out_file);
4457 fprint_whex (asm_out_file, t->lf_enum.properties);
4458 putc ('\n', asm_out_file);
4460 fputs (integer_asm_op (4, false), asm_out_file);
4461 fprint_whex (asm_out_file, t->lf_enum.underlying_type);
4462 putc ('\n', asm_out_file);
4464 fputs (integer_asm_op (4, false), asm_out_file);
4465 fprint_whex (asm_out_file, t->lf_enum.fieldlist);
4466 putc ('\n', asm_out_file);
4468 name_len = strlen (t->lf_enum.name) + 1;
4469 ASM_OUTPUT_ASCII (asm_out_file, t->lf_enum.name, name_len);
4471 leaf_len = 14 + name_len;
4472 write_cv_padding (4 - (leaf_len % 4));
4474 free (t->lf_enum.name);
4476 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4479 /* Write an LF_STRUCTURE or LF_CLASS type (the two have the same structure). */
4481 static void
4482 write_lf_structure (codeview_custom_type *t)
4484 size_t name_len, leaf_len;
4486 /* This is lf_class in binutils and lfClass in Microsoft's cvinfo.h:
4488 struct lf_class
4490 uint16_t size;
4491 uint16_t kind;
4492 uint16_t num_members;
4493 uint16_t properties;
4494 uint32_t field_list;
4495 uint32_t derived_from;
4496 uint32_t vshape;
4497 uint16_t length;
4498 char name[];
4499 } ATTRIBUTE_PACKED;
4502 fputs (integer_asm_op (2, false), asm_out_file);
4503 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4504 t->num, t->num);
4506 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4508 fputs (integer_asm_op (2, false), asm_out_file);
4509 fprint_whex (asm_out_file, t->kind);
4510 putc ('\n', asm_out_file);
4512 fputs (integer_asm_op (2, false), asm_out_file);
4513 fprint_whex (asm_out_file, t->lf_structure.num_members);
4514 putc ('\n', asm_out_file);
4516 fputs (integer_asm_op (2, false), asm_out_file);
4517 fprint_whex (asm_out_file, t->lf_structure.properties);
4518 putc ('\n', asm_out_file);
4520 fputs (integer_asm_op (4, false), asm_out_file);
4521 fprint_whex (asm_out_file, t->lf_structure.field_list);
4522 putc ('\n', asm_out_file);
4524 fputs (integer_asm_op (4, false), asm_out_file);
4525 fprint_whex (asm_out_file, t->lf_structure.derived_from);
4526 putc ('\n', asm_out_file);
4528 fputs (integer_asm_op (4, false), asm_out_file);
4529 fprint_whex (asm_out_file, t->lf_structure.vshape);
4530 putc ('\n', asm_out_file);
4532 leaf_len = 20 + write_cv_integer (&t->lf_structure.length);
4534 if (t->lf_structure.name)
4536 name_len = strlen (t->lf_structure.name) + 1;
4537 ASM_OUTPUT_ASCII (asm_out_file, t->lf_structure.name, name_len);
4539 else
4541 static const char unnamed_struct[] = "<unnamed-tag>";
4543 name_len = sizeof (unnamed_struct);
4544 ASM_OUTPUT_ASCII (asm_out_file, unnamed_struct, name_len);
4547 leaf_len += name_len;
4548 write_cv_padding (4 - (leaf_len % 4));
4550 free (t->lf_structure.name);
4552 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4555 /* Write an LF_UNION type. */
4557 static void
4558 write_lf_union (codeview_custom_type *t)
4560 size_t name_len, leaf_len;
4562 /* This is lf_union in binutils and lfUnion in Microsoft's cvinfo.h:
4564 struct lf_union
4566 uint16_t size;
4567 uint16_t kind;
4568 uint16_t num_members;
4569 uint16_t properties;
4570 uint32_t field_list;
4571 uint16_t length;
4572 char name[];
4573 } ATTRIBUTE_PACKED;
4576 fputs (integer_asm_op (2, false), asm_out_file);
4577 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4578 t->num, t->num);
4580 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4582 fputs (integer_asm_op (2, false), asm_out_file);
4583 fprint_whex (asm_out_file, t->kind);
4584 putc ('\n', asm_out_file);
4586 fputs (integer_asm_op (2, false), asm_out_file);
4587 fprint_whex (asm_out_file, t->lf_structure.num_members);
4588 putc ('\n', asm_out_file);
4590 fputs (integer_asm_op (2, false), asm_out_file);
4591 fprint_whex (asm_out_file, t->lf_structure.properties);
4592 putc ('\n', asm_out_file);
4594 fputs (integer_asm_op (4, false), asm_out_file);
4595 fprint_whex (asm_out_file, t->lf_structure.field_list);
4596 putc ('\n', asm_out_file);
4598 leaf_len = 12 + write_cv_integer (&t->lf_structure.length);
4600 if (t->lf_structure.name)
4602 name_len = strlen (t->lf_structure.name) + 1;
4603 ASM_OUTPUT_ASCII (asm_out_file, t->lf_structure.name, name_len);
4605 else
4607 static const char unnamed_struct[] = "<unnamed-tag>";
4609 name_len = sizeof (unnamed_struct);
4610 ASM_OUTPUT_ASCII (asm_out_file, unnamed_struct, name_len);
4613 leaf_len += name_len;
4614 write_cv_padding (4 - (leaf_len % 4));
4616 free (t->lf_structure.name);
4618 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4621 /* Write an LF_ARRAY type. */
4623 static void
4624 write_lf_array (codeview_custom_type *t)
4626 size_t leaf_len;
4628 /* This is lf_array in binutils and lfArray in Microsoft's cvinfo.h:
4630 struct lf_array
4632 uint16_t size;
4633 uint16_t kind;
4634 uint32_t element_type;
4635 uint32_t index_type;
4636 uint16_t length_in_bytes;
4637 char name[];
4638 } ATTRIBUTE_PACKED;
4641 fputs (integer_asm_op (2, false), asm_out_file);
4642 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4643 t->num, t->num);
4645 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4647 fputs (integer_asm_op (2, false), asm_out_file);
4648 fprint_whex (asm_out_file, t->kind);
4649 putc ('\n', asm_out_file);
4651 fputs (integer_asm_op (4, false), asm_out_file);
4652 fprint_whex (asm_out_file, t->lf_array.element_type);
4653 putc ('\n', asm_out_file);
4655 fputs (integer_asm_op (4, false), asm_out_file);
4656 fprint_whex (asm_out_file, t->lf_array.index_type);
4657 putc ('\n', asm_out_file);
4659 leaf_len = 13 + write_cv_integer (&t->lf_array.length_in_bytes);
4661 ASM_OUTPUT_ASCII (asm_out_file, "", 1);
4663 write_cv_padding (4 - (leaf_len % 4));
4665 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4668 /* Write an LF_BITFIELD type. */
4670 static void
4671 write_lf_bitfield (codeview_custom_type *t)
4673 /* This is lf_bitfield in binutils and lfBitfield in Microsoft's cvinfo.h:
4675 struct lf_bitfield
4677 uint16_t size;
4678 uint16_t kind;
4679 uint32_t base_type;
4680 uint8_t length;
4681 uint8_t position;
4682 } ATTRIBUTE_PACKED;
4685 fputs (integer_asm_op (2, false), asm_out_file);
4686 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4687 t->num, t->num);
4689 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4691 fputs (integer_asm_op (2, false), asm_out_file);
4692 fprint_whex (asm_out_file, t->kind);
4693 putc ('\n', asm_out_file);
4695 fputs (integer_asm_op (4, false), asm_out_file);
4696 fprint_whex (asm_out_file, t->lf_bitfield.base_type);
4697 putc ('\n', asm_out_file);
4699 fputs (integer_asm_op (1, false), asm_out_file);
4700 fprint_whex (asm_out_file, t->lf_bitfield.length);
4701 putc ('\n', asm_out_file);
4703 fputs (integer_asm_op (1, false), asm_out_file);
4704 fprint_whex (asm_out_file, t->lf_bitfield.position);
4705 putc ('\n', asm_out_file);
4707 write_cv_padding (2);
4709 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4712 /* Write an LF_PROCEDURE type. Function pointers are implemented as pointers
4713 to one of these. */
4715 static void
4716 write_lf_procedure (codeview_custom_type *t)
4718 /* This is lf_procedure in binutils and lfProc in Microsoft's cvinfo.h:
4720 struct lf_procedure
4722 uint16_t size;
4723 uint16_t kind;
4724 uint32_t return_type;
4725 uint8_t calling_convention;
4726 uint8_t attributes;
4727 uint16_t num_parameters;
4728 uint32_t arglist;
4729 } ATTRIBUTE_PACKED;
4732 fputs (integer_asm_op (2, false), asm_out_file);
4733 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4734 t->num, t->num);
4736 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4738 fputs (integer_asm_op (2, false), asm_out_file);
4739 fprint_whex (asm_out_file, t->kind);
4740 putc ('\n', asm_out_file);
4742 fputs (integer_asm_op (4, false), asm_out_file);
4743 fprint_whex (asm_out_file, t->lf_procedure.return_type);
4744 putc ('\n', asm_out_file);
4746 fputs (integer_asm_op (1, false), asm_out_file);
4747 fprint_whex (asm_out_file, t->lf_procedure.calling_convention);
4748 putc ('\n', asm_out_file);
4750 fputs (integer_asm_op (1, false), asm_out_file);
4751 fprint_whex (asm_out_file, t->lf_procedure.attributes);
4752 putc ('\n', asm_out_file);
4754 fputs (integer_asm_op (2, false), asm_out_file);
4755 fprint_whex (asm_out_file, t->lf_procedure.num_parameters);
4756 putc ('\n', asm_out_file);
4758 fputs (integer_asm_op (4, false), asm_out_file);
4759 fprint_whex (asm_out_file, t->lf_procedure.arglist);
4760 putc ('\n', asm_out_file);
4762 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4765 /* Write an LF_ARGLIST type. This is just a list of other types. LF_PROCEDURE
4766 entries point to one of these. */
4768 static void
4769 write_lf_arglist (codeview_custom_type *t)
4771 /* This is lf_arglist in binutils and lfArgList in Microsoft's cvinfo.h:
4773 struct lf_arglist
4775 uint16_t size;
4776 uint16_t kind;
4777 uint32_t num_entries;
4778 uint32_t args[];
4779 } ATTRIBUTE_PACKED;
4782 fputs (integer_asm_op (2, false), asm_out_file);
4783 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4784 t->num, t->num);
4786 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4788 fputs (integer_asm_op (2, false), asm_out_file);
4789 fprint_whex (asm_out_file, t->kind);
4790 putc ('\n', asm_out_file);
4792 fputs (integer_asm_op (4, false), asm_out_file);
4793 fprint_whex (asm_out_file, t->lf_arglist.num_entries);
4794 putc ('\n', asm_out_file);
4796 for (uint32_t i = 0; i < t->lf_arglist.num_entries; i++)
4798 fputs (integer_asm_op (4, false), asm_out_file);
4799 fprint_whex (asm_out_file, t->lf_arglist.args[i]);
4800 putc ('\n', asm_out_file);
4803 free (t->lf_arglist.args);
4805 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4808 /* Write an LF_FUNC_ID type, which marries together a function type with its
4809 name. This will end up in the alternative types stream in the final PDB,
4810 but we can just stick it in the normal .debug$T section. */
4812 static void
4813 write_lf_func_id (codeview_custom_type *t)
4815 size_t name_len;
4817 /* This is lf_func_id in binutils and lfFuncId in Microsoft's cvinfo.h:
4819 struct lf_func_id
4821 uint16_t size;
4822 uint16_t kind;
4823 uint32_t parent_scope;
4824 uint32_t function_type;
4825 char name[];
4826 } ATTRIBUTE_PACKED;
4829 fputs (integer_asm_op (2, false), asm_out_file);
4830 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4831 t->num, t->num);
4833 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4835 fputs (integer_asm_op (2, false), asm_out_file);
4836 fprint_whex (asm_out_file, t->kind);
4837 putc ('\n', asm_out_file);
4839 fputs (integer_asm_op (4, false), asm_out_file);
4840 fprint_whex (asm_out_file, t->lf_func_id.parent_scope);
4841 putc ('\n', asm_out_file);
4843 fputs (integer_asm_op (4, false), asm_out_file);
4844 fprint_whex (asm_out_file, t->lf_func_id.function_type);
4845 putc ('\n', asm_out_file);
4847 name_len = strlen (t->lf_func_id.name) + 1;
4849 ASM_OUTPUT_ASCII (asm_out_file, t->lf_func_id.name, name_len);
4851 write_cv_padding (4 - (name_len % 4));
4853 free (t->lf_func_id.name);
4855 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4858 /* Write an LF_MFUNC_ID type, which is the version of LF_FUNC_ID for struct
4859 functions. Instead of an LF_STRING_ID for the parent scope, we write the
4860 type number of the parent struct. */
4862 static void
4863 write_lf_mfunc_id (codeview_custom_type *t)
4865 size_t name_len;
4867 /* This is lf_mfunc_id in binutils and lfMFuncId in Microsoft's cvinfo.h:
4869 struct lf_mfunc_id
4871 uint16_t size;
4872 uint16_t kind;
4873 uint32_t parent_type;
4874 uint32_t function_type;
4875 char name[];
4876 } ATTRIBUTE_PACKED
4879 fputs (integer_asm_op (2, false), asm_out_file);
4880 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4881 t->num, t->num);
4883 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4885 fputs (integer_asm_op (2, false), asm_out_file);
4886 fprint_whex (asm_out_file, t->kind);
4887 putc ('\n', asm_out_file);
4889 fputs (integer_asm_op (4, false), asm_out_file);
4890 fprint_whex (asm_out_file, t->lf_mfunc_id.parent_type);
4891 putc ('\n', asm_out_file);
4893 fputs (integer_asm_op (4, false), asm_out_file);
4894 fprint_whex (asm_out_file, t->lf_mfunc_id.function_type);
4895 putc ('\n', asm_out_file);
4897 name_len = strlen (t->lf_mfunc_id.name) + 1;
4899 ASM_OUTPUT_ASCII (asm_out_file, t->lf_mfunc_id.name, name_len);
4901 write_cv_padding (4 - (name_len % 4));
4903 free (t->lf_mfunc_id.name);
4905 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4908 /* Write an LF_STRING_ID type, which provides a deduplicated string that other
4909 types can reference. */
4911 static void
4912 write_lf_string_id (codeview_custom_type *t)
4914 size_t string_len;
4916 /* This is lf_string_id in binutils and lfStringId in Microsoft's cvinfo.h:
4918 struct lf_string_id
4920 uint16_t size;
4921 uint16_t kind;
4922 uint32_t substring;
4923 char string[];
4924 } ATTRIBUTE_PACKED;
4927 fputs (integer_asm_op (2, false), asm_out_file);
4928 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4929 t->num, t->num);
4931 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4933 fputs (integer_asm_op (2, false), asm_out_file);
4934 fprint_whex (asm_out_file, t->kind);
4935 putc ('\n', asm_out_file);
4937 fputs (integer_asm_op (4, false), asm_out_file);
4938 fprint_whex (asm_out_file, t->lf_string_id.substring);
4939 putc ('\n', asm_out_file);
4941 string_len = strlen (t->lf_string_id.string) + 1;
4943 ASM_OUTPUT_ASCII (asm_out_file, t->lf_string_id.string, string_len);
4945 write_cv_padding (4 - (string_len % 4));
4947 free (t->lf_string_id.string);
4949 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
4952 /* Write an LF_MFUNCTION type, representing a member function. This is the
4953 struct-scoped equivalent of the LF_PROCEDURE type. */
4955 static void
4956 write_lf_mfunction (codeview_custom_type *t)
4958 /* This is lf_mfunction in binutils and lfMFunc in Microsoft's cvinfo.h:
4960 struct lf_mfunction
4962 uint16_t size;
4963 uint16_t kind;
4964 uint32_t return_type;
4965 uint32_t containing_class_type;
4966 uint32_t this_type;
4967 uint8_t calling_convention;
4968 uint8_t attributes;
4969 uint16_t num_parameters;
4970 uint32_t arglist;
4971 int32_t this_adjustment;
4972 } ATTRIBUTE_PACKED;
4975 fputs (integer_asm_op (2, false), asm_out_file);
4976 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
4977 t->num, t->num);
4979 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
4981 fputs (integer_asm_op (2, false), asm_out_file);
4982 fprint_whex (asm_out_file, t->kind);
4983 putc ('\n', asm_out_file);
4985 fputs (integer_asm_op (4, false), asm_out_file);
4986 fprint_whex (asm_out_file, t->lf_mfunction.return_type);
4987 putc ('\n', asm_out_file);
4989 fputs (integer_asm_op (4, false), asm_out_file);
4990 fprint_whex (asm_out_file, t->lf_mfunction.containing_class_type);
4991 putc ('\n', asm_out_file);
4993 fputs (integer_asm_op (4, false), asm_out_file);
4994 fprint_whex (asm_out_file, t->lf_mfunction.this_type);
4995 putc ('\n', asm_out_file);
4997 fputs (integer_asm_op (1, false), asm_out_file);
4998 fprint_whex (asm_out_file, t->lf_mfunction.calling_convention);
4999 putc ('\n', asm_out_file);
5001 fputs (integer_asm_op (1, false), asm_out_file);
5002 fprint_whex (asm_out_file, t->lf_mfunction.attributes);
5003 putc ('\n', asm_out_file);
5005 fputs (integer_asm_op (2, false), asm_out_file);
5006 fprint_whex (asm_out_file, t->lf_mfunction.num_parameters);
5007 putc ('\n', asm_out_file);
5009 fputs (integer_asm_op (4, false), asm_out_file);
5010 fprint_whex (asm_out_file, t->lf_mfunction.arglist);
5011 putc ('\n', asm_out_file);
5013 fputs (integer_asm_op (4, false), asm_out_file);
5014 fprint_whex (asm_out_file, t->lf_mfunction.this_adjustment);
5015 putc ('\n', asm_out_file);
5017 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
5020 /* Write an LF_METHODLIST type, which is an array of type numbers for
5021 LF_MFUNCTION types. Overloaded functions are represented by a LF_METHOD
5022 subtype in the field list, which points to a LF_METHODLIST type for the
5023 function's various forms. */
5025 static void
5026 write_lf_methodlist (codeview_custom_type *t)
5028 /* This is lf_methodlist in binutils and lMethodList in Microsoft's cvinfo.h:
5030 struct lf_methodlist_entry
5032 uint16_t method_attribute;
5033 uint16_t padding;
5034 uint32_t method_type;
5035 } ATTRIBUTE_PACKED;
5037 struct lf_methodlist
5039 uint16_t size;
5040 uint16_t kind;
5041 struct lf_methodlist_entry entries[];
5042 } ATTRIBUTE_PACKED;
5045 fputs (integer_asm_op (2, false), asm_out_file);
5046 asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
5047 t->num, t->num);
5049 asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
5051 fputs (integer_asm_op (2, false), asm_out_file);
5052 fprint_whex (asm_out_file, t->kind);
5053 putc ('\n', asm_out_file);
5055 for (unsigned int i = 0; i < t->lf_methodlist.count; i++)
5057 fputs (integer_asm_op (2, false), asm_out_file);
5058 fprint_whex (asm_out_file, t->lf_methodlist.entries[i].method_attribute);
5059 putc ('\n', asm_out_file);
5061 fputs (integer_asm_op (2, false), asm_out_file);
5062 fprint_whex (asm_out_file, 0);
5063 putc ('\n', asm_out_file);
5065 fputs (integer_asm_op (4, false), asm_out_file);
5066 fprint_whex (asm_out_file, t->lf_methodlist.entries[i].method_type);
5067 putc ('\n', asm_out_file);
5070 free (t->lf_methodlist.entries);
5072 asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
5075 /* Write the .debug$T section, which contains all of our custom type
5076 definitions. */
5078 static void
5079 write_custom_types (void)
5081 targetm.asm_out.named_section (".debug$T", SECTION_DEBUG, NULL);
5083 fputs (integer_asm_op (4, false), asm_out_file);
5084 fprint_whex (asm_out_file, CV_SIGNATURE_C13);
5085 putc ('\n', asm_out_file);
5087 while (custom_types)
5089 codeview_custom_type *n = custom_types->next;
5091 switch (custom_types->kind)
5093 case LF_POINTER:
5094 write_lf_pointer (custom_types);
5095 break;
5097 case LF_MODIFIER:
5098 write_lf_modifier (custom_types);
5099 break;
5101 case LF_FIELDLIST:
5102 write_lf_fieldlist (custom_types);
5103 break;
5105 case LF_ENUM:
5106 write_lf_enum (custom_types);
5107 break;
5109 case LF_STRUCTURE:
5110 case LF_CLASS:
5111 write_lf_structure (custom_types);
5112 break;
5114 case LF_UNION:
5115 write_lf_union (custom_types);
5116 break;
5118 case LF_ARRAY:
5119 write_lf_array (custom_types);
5120 break;
5122 case LF_BITFIELD:
5123 write_lf_bitfield (custom_types);
5124 break;
5126 case LF_PROCEDURE:
5127 write_lf_procedure (custom_types);
5128 break;
5130 case LF_ARGLIST:
5131 write_lf_arglist (custom_types);
5132 break;
5134 case LF_FUNC_ID:
5135 write_lf_func_id (custom_types);
5136 break;
5138 case LF_MFUNC_ID:
5139 write_lf_mfunc_id (custom_types);
5140 break;
5142 case LF_STRING_ID:
5143 write_lf_string_id (custom_types);
5144 break;
5146 case LF_MFUNCTION:
5147 write_lf_mfunction (custom_types);
5148 break;
5150 case LF_METHODLIST:
5151 write_lf_methodlist (custom_types);
5152 break;
5154 default:
5155 break;
5158 free (custom_types);
5159 custom_types = n;
5163 /* Finish CodeView debug info emission. */
5165 void
5166 codeview_debug_finish (void)
5168 targetm.asm_out.named_section (".debug$S", SECTION_DEBUG, NULL);
5170 fputs (integer_asm_op (4, false), asm_out_file);
5171 fprint_whex (asm_out_file, CV_SIGNATURE_C13);
5172 putc ('\n', asm_out_file);
5174 write_strings_table ();
5175 write_source_files ();
5176 write_line_numbers ();
5178 if (inlinee_lines_htab)
5179 write_inlinee_lines ();
5181 write_codeview_symbols ();
5183 /* If we reference a nested struct but not its parent, add_deferred_type
5184 gets called if we create a forward reference for this, even though we've
5185 already flushed this in codeview_debug_early_finish. In this case we will
5186 need to flush this list again. */
5187 flush_deferred_types ();
5189 if (custom_types)
5190 write_custom_types ();
5192 while (funcs)
5194 codeview_function *next_func = funcs->next;
5196 while (funcs->blocks)
5198 codeview_line_block *next_block = funcs->blocks->next;
5200 while (funcs->blocks->lines)
5202 codeview_line *next_line = funcs->blocks->lines->next;
5204 free (funcs->blocks->lines);
5205 funcs->blocks->lines = next_line;
5208 free (funcs->blocks);
5209 funcs->blocks = next_block;
5212 free (funcs);
5213 funcs = next_func;
5216 if (types_htab)
5217 delete types_htab;
5219 if (func_htab)
5220 delete func_htab;
5222 if (string_id_htab)
5223 delete string_id_htab;
5225 if (inlinee_lines_htab)
5226 delete inlinee_lines_htab;
5228 if (cv_func_htab)
5229 delete cv_func_htab;
5232 /* Translate a DWARF base type (DW_TAG_base_type) into its CodeView
5233 equivalent. */
5235 static uint32_t
5236 get_type_num_base_type (dw_die_ref type)
5238 unsigned int size = get_AT_unsigned (type, DW_AT_byte_size);
5240 switch (get_AT_unsigned (type, DW_AT_encoding))
5242 case DW_ATE_signed_char:
5244 const char *name = get_AT_string (type, DW_AT_name);
5246 if (size != 1)
5247 return 0;
5249 if (name && !strcmp (name, "signed char"))
5250 return T_CHAR;
5251 else
5252 return T_RCHAR;
5255 case DW_ATE_unsigned_char:
5256 if (size != 1)
5257 return 0;
5259 return T_UCHAR;
5261 case DW_ATE_signed:
5262 switch (size)
5264 case 2:
5265 return T_SHORT;
5267 case 4:
5269 const char *name = get_AT_string (type, DW_AT_name);
5271 if (name && !strcmp (name, "int"))
5272 return T_INT4;
5273 else
5274 return T_LONG;
5277 case 8:
5278 return T_QUAD;
5280 default:
5281 return 0;
5284 case DW_ATE_unsigned:
5285 switch (size)
5287 case 2:
5289 const char *name = get_AT_string (type, DW_AT_name);
5291 if (name && !strcmp (name, "wchar_t"))
5292 return T_WCHAR;
5293 else
5294 return T_USHORT;
5297 case 4:
5299 const char *name = get_AT_string (type, DW_AT_name);
5301 if (name && !strcmp (name, "unsigned int"))
5302 return T_UINT4;
5303 else
5304 return T_ULONG;
5307 case 8:
5308 return T_UQUAD;
5310 default:
5311 return 0;
5314 case DW_ATE_UTF:
5315 switch (size)
5317 case 1:
5318 return T_CHAR8;
5320 case 2:
5321 return T_CHAR16;
5323 case 4:
5324 return T_CHAR32;
5326 default:
5327 return 0;
5330 case DW_ATE_float:
5331 switch (size)
5333 case 4:
5334 return T_REAL32;
5336 case 8:
5337 return T_REAL64;
5339 case 12:
5340 return T_REAL80;
5342 case 16:
5343 return T_REAL128;
5345 default:
5346 return 0;
5349 case DW_ATE_boolean:
5350 if (size == 1)
5351 return T_BOOL08;
5352 else
5353 return 0;
5355 default:
5356 return 0;
5360 /* Add a new codeview_custom_type to our singly-linked custom_types list. */
5362 static void
5363 add_custom_type (codeview_custom_type *ct)
5365 uint32_t num;
5367 if (last_custom_type)
5369 num = last_custom_type->num + 1;
5370 last_custom_type->next = ct;
5372 else
5374 num = FIRST_TYPE;
5375 custom_types = ct;
5378 last_custom_type = ct;
5380 ct->num = num;
5383 /* Process a DW_TAG_pointer_type DIE. If this is a pointer to a builtin
5384 type, return the predefined constant for this. Otherwise, add a new
5385 LF_POINTER type and return its number. */
5387 static uint32_t
5388 get_type_num_pointer_type (dw_die_ref type, bool in_struct)
5390 uint32_t base_type_num, byte_size;
5391 dw_die_ref base_type;
5392 codeview_custom_type *ct;
5394 byte_size = get_AT_unsigned (type, DW_AT_byte_size);
5395 if (byte_size != 4 && byte_size != 8)
5396 return 0;
5398 base_type = get_AT_ref (type, DW_AT_type);
5400 /* If DW_AT_type is not set, this must be a void pointer. */
5401 if (!base_type)
5402 return byte_size == 4 ? T_32PVOID : T_64PVOID;
5404 base_type_num = get_type_num (base_type, in_struct, false);
5405 if (base_type_num == 0)
5406 return 0;
5408 /* Pointers to builtin types have predefined type numbers, with the top byte
5409 determining the pointer size - 0x0400 for a 32-bit pointer and 0x0600
5410 for 64-bit. */
5411 if (base_type_num < FIRST_TYPE && !(base_type_num & 0xff00))
5413 if (byte_size == 4)
5414 return CV_POINTER_32 | base_type_num;
5415 else
5416 return CV_POINTER_64 | base_type_num;
5419 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
5421 ct->next = NULL;
5422 ct->kind = LF_POINTER;
5423 ct->lf_pointer.base_type = base_type_num;
5425 if (byte_size == 4)
5426 ct->lf_pointer.attributes = CV_PTR_NEAR32;
5427 else
5428 ct->lf_pointer.attributes = CV_PTR_64;
5430 ct->lf_pointer.attributes |= byte_size << 13;
5432 add_custom_type (ct);
5434 return ct->num;
5437 /* Process a DW_TAG_reference_type or DW_TAG_rvalue_reference_type DIE, add a
5438 new LF_POINTER type, and return its number. */
5440 static uint32_t
5441 get_type_num_reference_type (dw_die_ref type, bool in_struct, bool rvref)
5443 uint32_t base_type_num, byte_size;
5444 dw_die_ref base_type;
5445 codeview_custom_type *ct;
5447 byte_size = get_AT_unsigned (type, DW_AT_byte_size);
5448 if (byte_size != 4 && byte_size != 8)
5449 return 0;
5451 base_type = get_AT_ref (type, DW_AT_type);
5453 base_type_num = get_type_num (base_type, in_struct, false);
5454 if (base_type_num == 0)
5455 return 0;
5457 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
5459 ct->next = NULL;
5460 ct->kind = LF_POINTER;
5461 ct->lf_pointer.base_type = base_type_num;
5462 ct->lf_pointer.attributes = rvref ? CV_PTR_MODE_RVREF : CV_PTR_MODE_LVREF;
5464 if (byte_size == 4)
5465 ct->lf_pointer.attributes |= CV_PTR_NEAR32;
5466 else
5467 ct->lf_pointer.attributes |= CV_PTR_64;
5469 ct->lf_pointer.attributes |= byte_size << 13;
5471 add_custom_type (ct);
5473 return ct->num;
5476 /* Process a DW_TAG_const_type DIE, adding an LF_MODIFIER type and returning
5477 its number. */
5479 static uint32_t
5480 get_type_num_const_type (dw_die_ref type, bool in_struct)
5482 dw_die_ref base_type;
5483 uint32_t base_type_num;
5484 codeview_custom_type *ct;
5485 bool is_volatile = false;
5487 base_type = get_AT_ref (type, DW_AT_type);
5489 /* Handle case when this is a const volatile type - we only need one
5490 LF_MODIFIER for this. */
5491 if (base_type && dw_get_die_tag (base_type) == DW_TAG_volatile_type)
5493 is_volatile = true;
5495 base_type = get_AT_ref (base_type, DW_AT_type);
5498 if (!base_type)
5500 base_type_num = T_VOID;
5502 else
5504 base_type_num = get_type_num (base_type, in_struct, false);
5505 if (base_type_num == 0)
5506 return 0;
5509 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
5511 ct->next = NULL;
5512 ct->kind = LF_MODIFIER;
5513 ct->lf_modifier.base_type = base_type_num;
5514 ct->lf_modifier.modifier = MOD_const;
5516 if (is_volatile)
5517 ct->lf_modifier.modifier |= MOD_volatile;
5519 add_custom_type (ct);
5521 return ct->num;
5524 /* Process a DW_TAG_volatile_type DIE, adding an LF_MODIFIER type and
5525 returning its number. */
5527 static uint32_t
5528 get_type_num_volatile_type (dw_die_ref type, bool in_struct)
5530 dw_die_ref base_type;
5531 uint32_t base_type_num;
5532 codeview_custom_type *ct;
5534 base_type = get_AT_ref (type, DW_AT_type);
5536 if (base_type)
5538 base_type_num = get_type_num (base_type, in_struct, false);
5539 if (base_type_num == 0)
5540 return 0;
5542 else
5544 base_type_num = T_VOID;
5547 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
5549 ct->next = NULL;
5550 ct->kind = LF_MODIFIER;
5551 ct->lf_modifier.base_type = base_type_num;
5552 ct->lf_modifier.modifier = MOD_volatile;
5554 add_custom_type (ct);
5556 return ct->num;
5559 /* Return the name of a DIE, traversing its parents in order to construct a
5560 C++-style name if necessary. */
5561 static char *
5562 get_name (dw_die_ref die)
5564 dw_die_ref decl = get_AT_ref (die, DW_AT_specification);
5565 dw_die_ref parent;
5566 const char *name;
5567 char *str;
5568 size_t len;
5570 static const char anon[] = "<unnamed-tag>";
5571 static const char sep[] = "::";
5573 if (decl)
5574 die = decl;
5576 name = get_AT_string (die, DW_AT_name);
5578 if (!name)
5579 return NULL;
5581 parent = dw_get_die_parent (die);
5583 if (!parent || dw_get_die_tag (parent) == DW_TAG_compile_unit)
5584 return xstrdup (name);
5586 len = strlen (name);
5587 while (parent && dw_get_die_tag (parent) != DW_TAG_compile_unit)
5589 const char *ns_name = get_AT_string (parent, DW_AT_name);
5591 len += sizeof (sep) - 1;
5593 if (ns_name)
5594 len += strlen (ns_name);
5595 else
5596 len += sizeof (anon) - 1;
5598 parent = dw_get_die_parent (parent);
5601 str = (char *) xmalloc (len + 1);
5602 str[len] = 0;
5604 len -= strlen (name);
5605 memcpy (str + len, name, strlen (name));
5607 parent = dw_get_die_parent (die);
5608 while (parent && dw_get_die_tag (parent) != DW_TAG_compile_unit)
5610 const char *ns_name = get_AT_string (parent, DW_AT_name);
5612 len -= sizeof (sep) - 1;
5613 memcpy (str + len, sep, sizeof (sep) - 1);
5615 if (ns_name)
5617 len -= strlen (ns_name);
5618 memcpy (str + len, ns_name, strlen (ns_name));
5620 else
5622 len -= sizeof (anon) - 1;
5623 memcpy (str + len, anon, sizeof (anon) - 1);
5626 parent = dw_get_die_parent (parent);
5629 return str;
5632 /* Add a forward declaration for an enum. This is legal from C++11 onwards. */
5634 static uint32_t
5635 add_enum_forward_def (dw_die_ref type)
5637 codeview_custom_type *ct;
5639 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
5641 ct->next = NULL;
5642 ct->kind = LF_ENUM;
5644 ct->lf_enum.count = 0;
5645 ct->lf_enum.properties = CV_PROP_FWDREF;
5646 ct->lf_enum.underlying_type = get_type_num (get_AT_ref (type, DW_AT_type),
5647 false, false);
5648 ct->lf_enum.fieldlist = 0;
5649 ct->lf_enum.name = get_name (type);
5651 add_custom_type (ct);
5653 return ct->num;
5656 /* Process a DW_TAG_enumeration_type DIE, adding an LF_FIELDLIST and an LF_ENUM
5657 type, returning the number of the latter. */
5659 static uint32_t
5660 get_type_num_enumeration_type (dw_die_ref type, bool in_struct)
5662 dw_die_ref first_child;
5663 codeview_custom_type *ct;
5664 uint16_t count = 0;
5665 uint32_t last_type = 0;
5667 if (get_AT_flag (type, DW_AT_declaration))
5668 return add_enum_forward_def (type);
5670 /* First, add an LF_FIELDLIST for the enum's values. We don't need to worry
5671 about deduplication here, as ld will take care of that for us. If there's
5672 a lot of entries, add more LF_FIELDLISTs with LF_INDEXes pointing to
5673 the overflow lists. */
5675 first_child = dw_get_die_child (type);
5677 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
5679 ct->next = NULL;
5680 ct->kind = LF_FIELDLIST;
5681 ct->lf_fieldlist.length = 0;
5682 ct->lf_fieldlist.subtypes = NULL;
5683 ct->lf_fieldlist.last_subtype = NULL;
5685 if (first_child)
5687 dw_die_ref c;
5689 c = first_child;
5692 dw_attr_node *att;
5693 codeview_subtype *el;
5694 size_t el_len;
5696 c = dw_get_die_sib (c);
5698 if (dw_get_die_tag (c) != DW_TAG_enumerator)
5699 continue;
5701 att = get_AT (c, DW_AT_const_value);
5702 if (!att)
5703 continue;
5705 el = (codeview_subtype *) xmalloc (sizeof (*el));
5706 el->next = NULL;
5707 el->kind = LF_ENUMERATE;
5709 switch (AT_class (att))
5711 case dw_val_class_unsigned_const:
5712 case dw_val_class_unsigned_const_implicit:
5713 el->lf_enumerate.value.neg = false;
5714 el->lf_enumerate.value.num = att->dw_attr_val.v.val_unsigned;
5715 break;
5717 case dw_val_class_const:
5718 case dw_val_class_const_implicit:
5719 if (att->dw_attr_val.v.val_int < 0)
5721 el->lf_enumerate.value.neg = true;
5722 el->lf_enumerate.value.num = -att->dw_attr_val.v.val_int;
5724 else
5726 el->lf_enumerate.value.neg = false;
5727 el->lf_enumerate.value.num = att->dw_attr_val.v.val_int;
5729 break;
5731 default:
5732 free (el);
5733 continue;
5736 el->lf_enumerate.name = xstrdup (get_AT_string (c, DW_AT_name));
5738 el_len = 7 + strlen (el->lf_enumerate.name);
5739 el_len += cv_integer_len (&el->lf_enumerate.value);
5741 if (el_len % 4)
5742 el_len += 4 - (el_len % 4);
5744 if (ct->lf_fieldlist.length + el_len > MAX_FIELDLIST_SIZE)
5746 codeview_subtype *idx;
5747 codeview_custom_type *ct2;
5749 idx = (codeview_subtype *) xmalloc (sizeof (*idx));
5750 idx->next = NULL;
5751 idx->kind = LF_INDEX;
5752 idx->lf_index.type_num = 0;
5754 ct->lf_fieldlist.last_subtype->next = idx;
5755 ct->lf_fieldlist.last_subtype = idx;
5757 ct2 = (codeview_custom_type *)
5758 xmalloc (sizeof (codeview_custom_type));
5760 ct2->next = ct;
5761 ct2->kind = LF_FIELDLIST;
5762 ct2->lf_fieldlist.length = 0;
5763 ct2->lf_fieldlist.subtypes = NULL;
5764 ct2->lf_fieldlist.last_subtype = NULL;
5766 ct = ct2;
5769 ct->lf_fieldlist.length += el_len;
5771 if (ct->lf_fieldlist.last_subtype)
5772 ct->lf_fieldlist.last_subtype->next = el;
5773 else
5774 ct->lf_fieldlist.subtypes = el;
5776 ct->lf_fieldlist.last_subtype = el;
5777 count++;
5779 while (c != first_child);
5782 while (ct)
5784 codeview_custom_type *ct2;
5786 ct2 = ct->next;
5787 ct->next = NULL;
5789 if (ct->lf_fieldlist.last_subtype->kind == LF_INDEX)
5790 ct->lf_fieldlist.last_subtype->lf_index.type_num = last_type;
5792 add_custom_type (ct);
5793 last_type = ct->num;
5795 ct = ct2;
5798 /* Now add an LF_ENUM, pointing to the LF_FIELDLIST we just added. */
5800 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
5802 ct->next = NULL;
5803 ct->kind = LF_ENUM;
5804 ct->lf_enum.count = count;
5805 ct->lf_enum.properties = 0;
5806 ct->lf_enum.underlying_type = get_type_num (get_AT_ref (type, DW_AT_type),
5807 in_struct, false);
5808 ct->lf_enum.fieldlist = last_type;
5809 ct->lf_enum.name = get_name (type);
5811 add_custom_type (ct);
5813 return ct->num;
5816 /* Add a DIE to our deferred_types list. This happens when we have a struct
5817 with a pointer to a type that hasn't been defined yet, but which gets
5818 defined later on. */
5820 static void
5821 add_deferred_type (dw_die_ref type)
5823 codeview_deferred_type *def;
5825 def = (codeview_deferred_type *) xmalloc (sizeof (codeview_deferred_type));
5827 def->next = NULL;
5828 def->type = type;
5830 if (!deferred_types)
5831 deferred_types = def;
5832 else
5833 last_deferred_type->next = def;
5835 last_deferred_type = def;
5838 /* Flush the contents of our deferred_types list. This happens after everything
5839 else has been written. We call get_type_num to ensure that a type gets
5840 added to custom_types, if it hasn't been already. */
5842 static void
5843 flush_deferred_types (void)
5845 while (deferred_types)
5847 codeview_deferred_type *next;
5849 next = deferred_types->next;
5851 get_type_num (deferred_types->type, false, true);
5853 free (deferred_types);
5854 deferred_types = next;
5857 last_deferred_type = NULL;
5860 /* Add a forward definition for a struct, class, or union. */
5862 static uint32_t
5863 add_struct_forward_def (dw_die_ref type)
5865 codeview_custom_type *ct;
5867 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
5869 ct->next = NULL;
5871 switch (dw_get_die_tag (type))
5873 case DW_TAG_class_type:
5874 ct->kind = LF_CLASS;
5875 break;
5877 case DW_TAG_structure_type:
5878 ct->kind = LF_STRUCTURE;
5879 break;
5881 case DW_TAG_union_type:
5882 ct->kind = LF_UNION;
5883 break;
5885 default:
5886 break;
5889 ct->lf_structure.num_members = 0;
5890 ct->lf_structure.properties = CV_PROP_FWDREF;
5891 ct->lf_structure.field_list = 0;
5892 ct->lf_structure.derived_from = 0;
5893 ct->lf_structure.vshape = 0;
5894 ct->lf_structure.length.neg = false;
5895 ct->lf_structure.length.num = 0;
5896 ct->lf_structure.name = get_name (type);
5898 add_custom_type (ct);
5900 if (!get_AT_flag (type, DW_AT_declaration))
5901 add_deferred_type (type);
5903 return ct->num;
5906 /* Add a new subtype to an LF_FIELDLIST type, and handle overflows if
5907 necessary. */
5909 static void
5910 add_to_fieldlist (codeview_custom_type **ct, uint16_t *num_members,
5911 codeview_subtype *el, size_t el_len)
5913 /* Add an LF_INDEX subtype if everything's too big for one
5914 LF_FIELDLIST. */
5916 if ((*ct)->lf_fieldlist.length + el_len > MAX_FIELDLIST_SIZE)
5918 codeview_subtype *idx;
5919 codeview_custom_type *ct2;
5921 idx = (codeview_subtype *) xmalloc (sizeof (*idx));
5922 idx->next = NULL;
5923 idx->kind = LF_INDEX;
5924 idx->lf_index.type_num = 0;
5926 (*ct)->lf_fieldlist.last_subtype->next = idx;
5927 (*ct)->lf_fieldlist.last_subtype = idx;
5929 ct2 = (codeview_custom_type *)
5930 xmalloc (sizeof (codeview_custom_type));
5932 ct2->next = *ct;
5933 ct2->kind = LF_FIELDLIST;
5934 ct2->lf_fieldlist.length = 0;
5935 ct2->lf_fieldlist.subtypes = NULL;
5936 ct2->lf_fieldlist.last_subtype = NULL;
5938 *ct = ct2;
5941 (*ct)->lf_fieldlist.length += el_len;
5943 if ((*ct)->lf_fieldlist.last_subtype)
5944 (*ct)->lf_fieldlist.last_subtype->next = el;
5945 else
5946 (*ct)->lf_fieldlist.subtypes = el;
5948 (*ct)->lf_fieldlist.last_subtype = el;
5949 (*num_members)++;
5952 /* Add an LF_BITFIELD type, returning its number. DWARF represents bitfields
5953 as members in a struct with a DW_AT_data_bit_offset attribute, whereas in
5954 CodeView they're a distinct type. */
5956 static uint32_t
5957 create_bitfield (dw_die_ref c)
5959 codeview_custom_type *ct;
5960 uint32_t base_type;
5962 base_type = get_type_num (get_AT_ref (c, DW_AT_type), true, false);
5963 if (base_type == 0)
5964 return 0;
5966 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
5968 ct->next = NULL;
5969 ct->kind = LF_BITFIELD;
5970 ct->lf_bitfield.base_type = base_type;
5971 ct->lf_bitfield.length = get_AT_unsigned (c, DW_AT_bit_size);
5972 ct->lf_bitfield.position = get_AT_unsigned (c, DW_AT_data_bit_offset);
5974 add_custom_type (ct);
5976 return ct->num;
5979 /* Create an LF_MEMBER field list subtype for a struct member, returning its
5980 pointer in el and its size in el_len. */
5982 static void
5983 add_struct_member (dw_die_ref c, uint16_t accessibility,
5984 codeview_custom_type **ct, uint16_t *num_members,
5985 unsigned int base_offset)
5987 codeview_subtype *el;
5988 size_t el_len;
5989 dw_die_ref type = get_AT_ref (c, DW_AT_type);
5990 unsigned int offset;
5992 offset = base_offset + get_AT_unsigned (c, DW_AT_data_member_location);
5994 /* If the data member is actually an anonymous struct, class, or union,
5995 follow MSVC by flattening this into its parent. */
5996 if (!get_AT_string (c, DW_AT_name) && type
5997 && (dw_get_die_tag (type) == DW_TAG_structure_type
5998 || dw_get_die_tag (type) == DW_TAG_class_type
5999 || dw_get_die_tag (type) == DW_TAG_union_type))
6001 dw_die_ref c2, first_child;
6003 first_child = dw_get_die_child (type);
6004 c2 = first_child;
6008 c2 = dw_get_die_sib (c2);
6010 if (dw_get_die_tag (c2) == DW_TAG_member)
6011 add_struct_member (c2, accessibility, ct, num_members, offset);
6013 while (c2 != first_child);
6015 return;
6018 el = (codeview_subtype *) xmalloc (sizeof (*el));
6019 el->next = NULL;
6020 el->kind = LF_MEMBER;
6021 el->lf_member.attributes = accessibility;
6023 if (get_AT (c, DW_AT_data_bit_offset))
6024 el->lf_member.type = create_bitfield (c);
6025 else
6026 el->lf_member.type = get_type_num (type, true, false);
6028 el->lf_member.offset.neg = false;
6029 el->lf_member.offset.num = offset;
6031 el_len = 11 + cv_integer_len (&el->lf_member.offset);
6033 if (get_AT_string (c, DW_AT_name))
6035 el->lf_member.name = xstrdup (get_AT_string (c, DW_AT_name));
6036 el_len += strlen (el->lf_member.name);
6038 else
6040 el->lf_member.name = NULL;
6043 if (el_len % 4)
6044 el_len += 4 - (el_len % 4);
6046 add_to_fieldlist (ct, num_members, el, el_len);
6049 /* Create an LF_STMEMBER field list subtype for a static struct member,
6050 returning its pointer in el and its size in el_len. */
6052 static void
6053 add_struct_static_member (dw_die_ref c, uint16_t accessibility,
6054 codeview_custom_type **ct, uint16_t *num_members)
6056 codeview_subtype *el;
6057 size_t el_len;
6059 el = (codeview_subtype *) xmalloc (sizeof (*el));
6060 el->next = NULL;
6061 el->kind = LF_STMEMBER;
6062 el->lf_static_member.attributes = accessibility;
6063 el->lf_static_member.type = get_type_num (get_AT_ref (c, DW_AT_type),
6064 true, false);
6065 el->lf_static_member.name = xstrdup (get_AT_string (c, DW_AT_name));
6067 el_len = 9 + strlen (el->lf_static_member.name);
6069 if (el_len % 4)
6070 el_len += 4 - (el_len % 4);
6072 add_to_fieldlist (ct, num_members, el, el_len);
6075 /* Create a field list subtype for a struct function, returning its pointer in
6076 el and its size in el_len. If the function is not overloaded, create an
6077 LF_ONEMETHOD subtype pointing to the LF_MFUNCTION. Otherwise, add an
6078 LF_METHODLIST type of the function's forms, and create an LF_METHOD subtype
6079 pointing to this. */
6081 static void
6082 add_struct_function (dw_die_ref c, hash_table<method_hasher> *method_htab,
6083 codeview_custom_type **ct, uint16_t *num_members)
6085 const char *name = get_AT_string (c, DW_AT_name);
6086 codeview_method **slot, *meth;
6087 codeview_subtype *el;
6088 size_t el_len;
6090 slot = method_htab->find_slot_with_hash (name, htab_hash_string (name),
6091 NO_INSERT);
6092 if (!slot)
6093 return;
6095 meth = *slot;
6097 el = (codeview_subtype *) xmalloc (sizeof (*el));
6098 el->next = NULL;
6100 if (meth->count == 1)
6102 el->kind = LF_ONEMETHOD;
6103 el->lf_onemethod.method_attribute = meth->attribute;
6104 el->lf_onemethod.method_type = meth->type;
6105 el->lf_onemethod.name = xstrdup (name);
6107 el_len = 9 + strlen (el->lf_onemethod.name);
6109 else
6111 codeview_custom_type *ct;
6112 lf_methodlist_entry *ent;
6114 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
6116 ct->next = NULL;
6117 ct->kind = LF_METHODLIST;
6118 ct->lf_methodlist.count = meth->count;
6119 ct->lf_methodlist.entries = (lf_methodlist_entry *)
6120 xmalloc (meth->count * sizeof (lf_methodlist_entry));
6122 ent = ct->lf_methodlist.entries;
6123 for (codeview_method *m = meth; m; m = m->next)
6125 ent->method_attribute = m->attribute;
6126 ent->method_type = m->type;
6127 ent++;
6130 add_custom_type (ct);
6132 el->kind = LF_METHOD;
6133 el->lf_method.count = meth->count;
6134 el->lf_method.method_list = ct->num;
6135 el->lf_method.name = xstrdup (name);
6137 el_len = 9 + strlen (el->lf_method.name);
6140 if (el_len % 4)
6141 el_len += 4 - (el_len % 4);
6143 add_to_fieldlist (ct, num_members, el, el_len);
6145 method_htab->remove_elt_with_hash (name, htab_hash_string (name));
6147 while (meth)
6149 codeview_method *next = meth->next;
6151 free (meth->name);
6152 free (meth);
6153 meth = next;
6157 /* Create a field list subtype that records the base class that a struct
6158 inherits from. */
6160 static void
6161 add_struct_inheritance (dw_die_ref c, uint16_t accessibility,
6162 codeview_custom_type **ct, uint16_t *num_members)
6164 codeview_subtype *el;
6165 size_t el_len;
6167 /* FIXME: if DW_AT_virtuality is DW_VIRTUALITY_virtual this is a virtual
6168 base class, and we should be issuing an LF_VBCLASS record
6169 instead. */
6170 if (get_AT_unsigned (c, DW_AT_virtuality) == DW_VIRTUALITY_virtual)
6171 return;
6173 el = (codeview_subtype *) xmalloc (sizeof (*el));
6174 el->next = NULL;
6175 el->kind = LF_BCLASS;
6176 el->lf_bclass.attributes = accessibility;
6177 el->lf_bclass.base_class_type = get_type_num (get_AT_ref (c, DW_AT_type),
6178 true, false);
6179 el->lf_bclass.offset.neg = false;
6180 el->lf_bclass.offset.num = get_AT_unsigned (c, DW_AT_data_member_location);
6182 el_len = 10 + cv_integer_len (&el->lf_bclass.offset);
6184 if (el_len % 4)
6185 el_len += 4 - (el_len % 4);
6187 add_to_fieldlist (ct, num_members, el, el_len);
6190 /* Create a new LF_MFUNCTION type for a struct function, add it to the
6191 types_htab hash table, and return its type number. */
6193 static uint32_t
6194 get_mfunction_type (dw_die_ref c)
6196 uint32_t containing_class_type, this_type, mfunction_type;
6197 dw_die_ref obj_pointer;
6198 codeview_type **slot, *t;
6200 containing_class_type = get_type_num (dw_get_die_parent (c), true, false);
6202 obj_pointer = get_AT_ref (c, DW_AT_object_pointer);
6203 if (obj_pointer && dw_get_die_tag (obj_pointer) == DW_TAG_formal_parameter)
6205 this_type = get_type_num (get_AT_ref (obj_pointer, DW_AT_type),
6206 true, false);
6208 else
6210 this_type = 0;
6213 mfunction_type = get_type_num_subroutine_type (c, true, containing_class_type,
6214 this_type, 0);
6216 slot = types_htab->find_slot_with_hash (c, htab_hash_pointer (c), INSERT);
6218 t = (codeview_type *) xmalloc (sizeof (codeview_type));
6220 t->die = c;
6221 t->num = mfunction_type;
6222 t->is_fwd_ref = false;
6224 *slot = t;
6226 return mfunction_type;
6229 /* Translate a DWARF DW_AT_accessibility constant into its CodeView
6230 equivalent. If implicit, follow the C++ rules. */
6232 static uint16_t
6233 get_accessibility (dw_die_ref c)
6235 switch (get_AT_unsigned (c, DW_AT_accessibility))
6237 case DW_ACCESS_private:
6238 return CV_ACCESS_PRIVATE;
6240 case DW_ACCESS_protected:
6241 return CV_ACCESS_PROTECTED;
6243 case DW_ACCESS_public:
6244 return CV_ACCESS_PUBLIC;
6246 /* Members in a C++ struct or union are public by default, members
6247 in a class are private. */
6248 default:
6249 if (dw_get_die_tag (dw_get_die_parent (c)) == DW_TAG_class_type)
6250 return CV_ACCESS_PRIVATE;
6251 else
6252 return CV_ACCESS_PUBLIC;
6256 /* Returns true if the struct function pointed to by die is an instantiated
6257 template function. These are skipped in CodeView struct definitions, as
6258 otherwise the same type might not be deduplicated across different TUs. */
6260 static bool
6261 is_templated_func (dw_die_ref die)
6263 dw_die_ref c = dw_get_die_child (die);
6265 if (!c)
6266 return false;
6270 c = dw_get_die_sib (c);
6272 if (dw_get_die_tag (c) == DW_TAG_template_type_param)
6273 return true;
6275 while (c != dw_get_die_child (die));
6277 return false;
6280 /* Create a field list subtype that records that a struct has a nested type
6281 contained within it. */
6283 static void
6284 add_struct_nested_type (dw_die_ref c, codeview_custom_type **ct,
6285 uint16_t *num_members)
6287 const char *name = get_AT_string (c, DW_AT_name);
6288 codeview_subtype *el;
6289 size_t name_len, el_len;
6291 if (!name)
6292 return;
6294 name_len = strlen (name);
6296 el = (codeview_subtype *) xmalloc (sizeof (*el));
6297 el->next = NULL;
6298 el->kind = LF_NESTTYPE;
6299 el->lf_nesttype.type = get_type_num (c, true, false);
6300 el->lf_nesttype.name = xstrdup (name);
6302 el_len = 9 + name_len;
6304 if (el_len % 4)
6305 el_len += 4 - (el_len % 4);
6307 add_to_fieldlist (ct, num_members, el, el_len);
6310 /* Process a DW_TAG_structure_type, DW_TAG_class_type, or DW_TAG_union_type
6311 DIE, add an LF_FIELDLIST and an LF_STRUCTURE / LF_CLASS / LF_UNION type,
6312 and return the number of the latter. */
6314 static uint32_t
6315 get_type_num_struct (dw_die_ref type, bool in_struct, bool *is_fwd_ref)
6317 dw_die_ref parent, first_child;
6318 codeview_custom_type *ct;
6319 uint16_t num_members = 0;
6320 uint32_t last_type = 0;
6322 parent = dw_get_die_parent(type);
6324 if (parent && (dw_get_die_tag (parent) == DW_TAG_structure_type
6325 || dw_get_die_tag (parent) == DW_TAG_class_type
6326 || dw_get_die_tag (parent) == DW_TAG_union_type))
6327 get_type_num (parent, true, false);
6329 if ((in_struct && get_AT_string (type, DW_AT_name))
6330 || get_AT_flag (type, DW_AT_declaration))
6332 *is_fwd_ref = true;
6333 return add_struct_forward_def (type);
6336 *is_fwd_ref = false;
6338 /* First, add an LF_FIELDLIST for the structure's members. We don't need to
6339 worry about deduplication here, as ld will take care of that for us.
6340 If there's a lot of entries, add more LF_FIELDLISTs with LF_INDEXes
6341 pointing to the overflow lists. */
6343 first_child = dw_get_die_child (type);
6345 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
6347 ct->next = NULL;
6348 ct->kind = LF_FIELDLIST;
6349 ct->lf_fieldlist.length = 0;
6350 ct->lf_fieldlist.subtypes = NULL;
6351 ct->lf_fieldlist.last_subtype = NULL;
6353 if (first_child)
6355 hash_table<method_hasher> *method_htab = NULL;
6356 dw_die_ref c;
6358 /* First, loop through and record any non-templated member functions.
6359 This is because overloaded and non-overloaded functions are expressed
6360 differently in CodeView, so we need to have a hash table on the name
6361 to know how to record it later on. */
6363 c = first_child;
6366 c = dw_get_die_sib (c);
6368 if (dw_get_die_tag (c) == DW_TAG_subprogram)
6370 const char *name = get_AT_string (c, DW_AT_name);
6371 codeview_method *meth, **slot;
6373 if (is_templated_func (c))
6374 continue;
6376 if (!method_htab)
6377 method_htab = new hash_table<method_hasher> (10);
6379 meth = (codeview_method *) xmalloc (sizeof (*meth));
6381 slot = method_htab->find_slot_with_hash (name,
6382 htab_hash_string (name),
6383 INSERT);
6385 meth->attribute = get_accessibility (c);
6387 if (!get_AT_ref (c, DW_AT_object_pointer))
6388 meth->attribute |= CV_METHOD_STATIC;
6390 meth->type = get_mfunction_type (c);
6391 meth->next = NULL;
6393 if (*slot)
6395 if ((*slot)->last)
6396 (*slot)->last->next = meth;
6397 else
6398 (*slot)->next = meth;
6400 (*slot)->last = meth;
6401 (*slot)->count++;
6403 meth->name = NULL;
6405 else
6407 meth->name = xstrdup (name);
6408 meth->last = NULL;
6409 meth->count = 1;
6410 *slot = meth;
6414 while (c != first_child);
6416 /* Now loop through again and record the actual members. */
6418 c = first_child;
6421 uint16_t accessibility;
6423 c = dw_get_die_sib (c);
6425 accessibility = get_accessibility (c);
6427 switch (dw_get_die_tag (c))
6429 case DW_TAG_member:
6430 add_struct_member (c, accessibility, &ct, &num_members, 0);
6431 break;
6433 case DW_TAG_variable:
6434 add_struct_static_member (c, accessibility, &ct, &num_members);
6435 break;
6437 case DW_TAG_subprogram:
6438 if (!is_templated_func (c))
6439 add_struct_function (c, method_htab, &ct, &num_members);
6440 break;
6442 case DW_TAG_inheritance:
6443 add_struct_inheritance (c, accessibility, &ct, &num_members);
6444 break;
6446 case DW_TAG_structure_type:
6447 case DW_TAG_class_type:
6448 case DW_TAG_union_type:
6449 case DW_TAG_enumeration_type:
6450 add_struct_nested_type (c, &ct, &num_members);
6451 break;
6453 default:
6454 break;
6457 while (c != first_child);
6459 if (method_htab)
6460 delete method_htab;
6463 while (ct)
6465 codeview_custom_type *ct2;
6467 ct2 = ct->next;
6468 ct->next = NULL;
6470 if (ct->lf_fieldlist.last_subtype
6471 && ct->lf_fieldlist.last_subtype->kind == LF_INDEX)
6473 ct->lf_fieldlist.last_subtype->lf_index.type_num = last_type;
6476 add_custom_type (ct);
6477 last_type = ct->num;
6479 ct = ct2;
6482 /* Now add an LF_STRUCTURE / LF_CLASS / LF_UNION, pointing to the
6483 LF_FIELDLIST we just added. */
6485 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
6487 ct->next = NULL;
6489 switch (dw_get_die_tag (type))
6491 case DW_TAG_class_type:
6492 ct->kind = LF_CLASS;
6493 break;
6495 case DW_TAG_structure_type:
6496 ct->kind = LF_STRUCTURE;
6497 break;
6499 case DW_TAG_union_type:
6500 ct->kind = LF_UNION;
6501 break;
6503 default:
6504 break;
6507 ct->lf_structure.num_members = num_members;
6508 ct->lf_structure.properties = 0;
6509 ct->lf_structure.field_list = last_type;
6510 ct->lf_structure.derived_from = 0;
6511 ct->lf_structure.vshape = 0;
6512 ct->lf_structure.length.neg = false;
6513 ct->lf_structure.length.num = get_AT_unsigned (type, DW_AT_byte_size);
6514 ct->lf_structure.name = get_name (type);
6516 add_custom_type (ct);
6518 return ct->num;
6521 /* Process a DW_TAG_subroutine_type DIE, adding an LF_ARGLIST and an
6522 LF_PROCEDURE or LF_MFUNCTION type, and returning the number of the
6523 latter. */
6525 static uint32_t
6526 get_type_num_subroutine_type (dw_die_ref type, bool in_struct,
6527 uint32_t containing_class_type,
6528 uint32_t this_type, int32_t this_adjustment)
6530 codeview_custom_type *ct;
6531 uint32_t return_type, arglist_type;
6532 uint16_t num_args;
6533 dw_die_ref first_child;
6535 /* Find the return type. */
6537 if (get_AT_ref (type, DW_AT_type))
6539 return_type = get_type_num (get_AT_ref (type, DW_AT_type), in_struct,
6540 false);
6541 if (return_type == 0)
6542 return 0;
6544 else
6546 return_type = T_VOID;
6549 /* Handle pointer to member function. */
6550 if (containing_class_type == 0)
6552 dw_die_ref obj_ptr = get_AT_ref (type, DW_AT_object_pointer);
6554 if (obj_ptr)
6556 dw_die_ref obj_ptr_type = get_AT_ref (obj_ptr, DW_AT_type);
6558 if (obj_ptr_type
6559 && dw_get_die_tag (obj_ptr_type) == DW_TAG_pointer_type)
6561 dw_die_ref cont_class = get_AT_ref (obj_ptr_type, DW_AT_type);
6563 if (dw_get_die_tag (cont_class) == DW_TAG_const_type)
6564 cont_class = get_AT_ref (cont_class, DW_AT_type);
6566 containing_class_type = get_type_num (cont_class, in_struct,
6567 false);
6568 this_type = get_type_num (obj_ptr_type, in_struct, false);
6573 /* Count the arguments. */
6575 first_child = dw_get_die_child (type);
6576 num_args = 0;
6578 if (first_child)
6580 dw_die_ref c;
6582 c = first_child;
6585 c = dw_get_die_sib (c);
6587 if (dw_get_die_tag (c) != DW_TAG_formal_parameter
6588 && dw_get_die_tag (c) != DW_TAG_unspecified_parameters)
6589 continue;
6591 /* We ignore "this" params here. */
6592 if (get_AT_flag (c, DW_AT_artificial) != 0)
6593 continue;
6595 num_args++;
6597 while (c != first_child);
6600 /* Create an LF_ARGLIST for the arguments. If this is a duplicate, ld
6601 will take care of this for us. */
6603 first_child = dw_get_die_child (type);
6605 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
6607 ct->next = NULL;
6608 ct->kind = LF_ARGLIST;
6609 ct->lf_arglist.num_entries = num_args;
6611 if (num_args > 0)
6613 dw_die_ref c;
6614 uint32_t *argptr;
6616 ct->lf_arglist.args = (uint32_t *) xmalloc (sizeof (uint32_t) * num_args);
6617 argptr = ct->lf_arglist.args;
6619 c = first_child;
6622 c = dw_get_die_sib (c);
6624 if (get_AT_flag (c, DW_AT_artificial) != 0)
6625 continue;
6627 switch (dw_get_die_tag (c))
6629 case DW_TAG_formal_parameter:
6630 *argptr = get_type_num (get_AT_ref (c, DW_AT_type), in_struct,
6631 false);
6632 argptr++;
6633 break;
6635 case DW_TAG_unspecified_parameters:
6636 *argptr = 0;
6637 argptr++;
6638 break;
6640 default:
6641 break;
6644 while (c != first_child);
6646 else
6648 ct->lf_arglist.args = NULL;
6651 add_custom_type (ct);
6653 arglist_type = ct->num;
6655 /* Finally, create an LF_PROCEDURE or LF_MFUNCTION type. */
6657 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
6659 ct->next = NULL;
6661 if (containing_class_type != 0)
6663 ct->kind = LF_MFUNCTION;
6664 ct->lf_mfunction.return_type = return_type;
6665 ct->lf_mfunction.containing_class_type = containing_class_type;
6666 ct->lf_mfunction.this_type = this_type;
6667 ct->lf_mfunction.calling_convention = 0;
6668 ct->lf_mfunction.attributes = 0;
6669 ct->lf_mfunction.num_parameters = num_args;
6670 ct->lf_mfunction.arglist = arglist_type;
6671 ct->lf_mfunction.this_adjustment = this_adjustment;
6673 else
6675 ct->kind = LF_PROCEDURE;
6676 ct->lf_procedure.return_type = return_type;
6677 ct->lf_procedure.calling_convention = 0;
6678 ct->lf_procedure.attributes = 0;
6679 ct->lf_procedure.num_parameters = num_args;
6680 ct->lf_procedure.arglist = arglist_type;
6683 add_custom_type (ct);
6685 return ct->num;
6688 /* Process a DW_TAG_array_type DIE, adding an LF_ARRAY type and returning its
6689 number. */
6691 static uint32_t
6692 get_type_num_array_type (dw_die_ref type, bool in_struct)
6694 dw_die_ref base_type, t, first_child, c, *dimension_arr;
6695 uint64_t size = 0;
6696 unsigned int dimensions, i;
6697 uint32_t element_type;
6699 base_type = get_AT_ref (type, DW_AT_type);
6700 if (!base_type)
6701 return 0;
6703 /* We need to know the size of our base type. Loop through until we find
6704 it. */
6705 t = base_type;
6706 while (t && size == 0)
6708 switch (dw_get_die_tag (t))
6710 case DW_TAG_const_type:
6711 case DW_TAG_volatile_type:
6712 case DW_TAG_typedef:
6713 case DW_TAG_enumeration_type:
6714 t = get_AT_ref (t, DW_AT_type);
6715 break;
6717 case DW_TAG_base_type:
6718 case DW_TAG_structure_type:
6719 case DW_TAG_class_type:
6720 case DW_TAG_union_type:
6721 case DW_TAG_pointer_type:
6722 case DW_TAG_reference_type:
6723 case DW_TAG_rvalue_reference_type:
6724 size = get_AT_unsigned (t, DW_AT_byte_size);
6725 break;
6727 default:
6728 return 0;
6732 if (size == 0)
6733 return 0;
6735 first_child = dw_get_die_child (type);
6736 if (!first_child)
6737 return 0;
6739 element_type = get_type_num (base_type, in_struct, false);
6740 if (element_type == 0)
6741 return 0;
6743 /* Create an array of our DW_TAG_subrange_type children, in reverse order.
6744 We have to do this because unlike DWARF CodeView doesn't have
6745 multidimensional arrays, so instead we do arrays of arrays. */
6747 dimensions = 0;
6748 c = first_child;
6751 c = dw_get_die_sib (c);
6752 if (dw_get_die_tag (c) != DW_TAG_subrange_type)
6753 continue;
6755 dimensions++;
6757 while (c != first_child);
6759 if (dimensions == 0)
6760 return 0;
6762 dimension_arr = (dw_die_ref *) xmalloc (sizeof (dw_die_ref) * dimensions);
6764 c = first_child;
6765 i = 0;
6768 c = dw_get_die_sib (c);
6769 if (dw_get_die_tag (c) != DW_TAG_subrange_type)
6770 continue;
6772 dimension_arr[dimensions - i - 1] = c;
6773 i++;
6775 while (c != first_child);
6777 /* Record an LF_ARRAY entry for each array dimension. If this leads to
6778 duplicate types, ld will take care of it for us. */
6780 for (i = 0; i < dimensions; i++)
6782 codeview_custom_type *ct;
6783 dw_die_ref index;
6785 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
6787 size *= get_AT_unsigned (dimension_arr[i], DW_AT_upper_bound) + 1;
6789 index = get_AT_ref (dimension_arr[i], DW_AT_type);
6791 ct->next = NULL;
6792 ct->kind = LF_ARRAY;
6793 ct->lf_array.element_type = element_type;
6794 ct->lf_array.index_type = get_type_num (index, in_struct, false);
6795 ct->lf_array.length_in_bytes.neg = false;
6796 ct->lf_array.length_in_bytes.num = size;
6798 add_custom_type (ct);
6800 element_type = ct->num;
6803 free (dimension_arr);
6805 return element_type;
6808 /* Translate a DW_TAG_ptr_to_member_type DIE, that is a pointer to member
6809 function or field, into an LF_POINTER record. */
6811 static uint32_t
6812 get_type_num_ptr_to_member_type (dw_die_ref type, bool in_struct)
6814 uint32_t base_type_num;
6815 uint32_t containing_class;
6816 dw_die_ref base_type;
6817 codeview_custom_type *ct;
6819 base_type = get_AT_ref (type, DW_AT_type);
6821 base_type_num = get_type_num (base_type, in_struct, false);
6822 if (base_type_num == 0)
6823 return 0;
6825 containing_class = get_type_num (get_AT_ref (type, DW_AT_containing_type),
6826 in_struct, false);
6828 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
6830 ct->next = NULL;
6831 ct->kind = LF_POINTER;
6832 ct->lf_pointer.base_type = base_type_num;
6834 if (TARGET_64BIT)
6836 ct->lf_pointer.attributes = CV_PTR_64;
6837 ct->lf_pointer.attributes |= 8 << 13;
6839 else
6841 ct->lf_pointer.attributes = CV_PTR_NEAR32;
6842 ct->lf_pointer.attributes |= 4 << 13;
6845 ct->lf_pointer.containing_class = containing_class;
6847 if (base_type && dw_get_die_tag (base_type) == DW_TAG_subroutine_type)
6849 ct->lf_pointer.attributes |= CV_PTR_MODE_PMFUNC;
6850 ct->lf_pointer.ptr_to_mem_type = CV_PMTYPE_F_Single;
6852 else
6854 ct->lf_pointer.attributes |= CV_PTR_MODE_PMEM;
6855 ct->lf_pointer.ptr_to_mem_type = CV_PMTYPE_D_Single;
6858 add_custom_type (ct);
6860 return ct->num;
6863 /* Return the type number that corresponds to a DW_TAG_typedef DIE: either the
6864 type number of the base type, or follow MSVC in having a special value
6865 for the HRESULT used by COM. */
6867 static uint32_t
6868 get_type_num_typedef (dw_die_ref type, bool in_struct)
6870 uint32_t num;
6872 num = get_type_num (get_AT_ref (type, DW_AT_type), in_struct, false);
6874 if (num == T_LONG)
6876 const char *name = get_AT_string (type, DW_AT_name);
6878 /* longs typedef'd as "HRESULT" get their own type */
6879 if (name && !strcmp (name, "HRESULT"))
6880 num = T_HRESULT;
6883 return num;
6886 /* Process a DIE representing a type definition, add a CodeView type if
6887 necessary, and return its number. If it's something we can't handle, return
6888 0. We keep a hash table so that we're not adding the same type multiple
6889 times - though if we do it's not disastrous, as ld will deduplicate
6890 everything for us. */
6892 static uint32_t
6893 get_type_num (dw_die_ref type, bool in_struct, bool no_fwd_ref)
6895 codeview_type **slot, *t;
6896 uint32_t num;
6897 bool is_fwd_ref;
6899 if (!type)
6900 return 0;
6902 if (!types_htab)
6903 types_htab = new hash_table<die_hasher> (10);
6905 slot = types_htab->find_slot_with_hash (type, htab_hash_pointer (type),
6906 NO_INSERT);
6908 if (slot && *slot && (!no_fwd_ref || !(*slot)->is_fwd_ref))
6909 return (*slot)->num;
6911 is_fwd_ref = false;
6913 switch (dw_get_die_tag (type))
6915 case DW_TAG_base_type:
6916 num = get_type_num_base_type (type);
6917 break;
6919 case DW_TAG_typedef:
6920 num = get_type_num_typedef (type, in_struct);
6921 break;
6923 case DW_TAG_pointer_type:
6924 num = get_type_num_pointer_type (type, in_struct);
6925 break;
6927 case DW_TAG_reference_type:
6928 num = get_type_num_reference_type (type, in_struct, false);
6929 break;
6931 case DW_TAG_rvalue_reference_type:
6932 num = get_type_num_reference_type (type, in_struct, true);
6933 break;
6935 case DW_TAG_const_type:
6936 num = get_type_num_const_type (type, in_struct);
6937 break;
6939 case DW_TAG_volatile_type:
6940 num = get_type_num_volatile_type (type, in_struct);
6941 break;
6943 case DW_TAG_enumeration_type:
6944 num = get_type_num_enumeration_type (type, in_struct);
6945 break;
6947 case DW_TAG_structure_type:
6948 case DW_TAG_class_type:
6949 case DW_TAG_union_type:
6950 num = get_type_num_struct (type, in_struct, &is_fwd_ref);
6951 break;
6953 case DW_TAG_array_type:
6954 num = get_type_num_array_type (type, in_struct);
6955 break;
6957 case DW_TAG_subroutine_type:
6958 num = get_type_num_subroutine_type (type, in_struct, 0, 0, 0);
6959 break;
6961 case DW_TAG_ptr_to_member_type:
6962 num = get_type_num_ptr_to_member_type (type, in_struct);
6963 break;
6965 default:
6966 num = 0;
6967 break;
6970 /* Check hash table again, and account for the fact that self-referential
6971 structs will have created a forward reference to themselves. */
6973 slot = types_htab->find_slot_with_hash (type, htab_hash_pointer (type),
6974 INSERT);
6976 if (*slot && (*slot)->is_fwd_ref && !is_fwd_ref)
6978 (*slot)->num = num;
6979 (*slot)->is_fwd_ref = false;
6980 return num;
6983 t = (codeview_type *) xmalloc (sizeof (codeview_type));
6984 t->die = type;
6985 t->num = num;
6986 t->is_fwd_ref = is_fwd_ref;
6988 *slot = t;
6990 return t->num;
6993 /* Process a DW_TAG_variable DIE, and add an S_GDATA32 or S_LDATA32 symbol for
6994 this. */
6996 static void
6997 add_variable (dw_die_ref die)
6999 codeview_symbol *s;
7000 const char *name;
7002 name = get_AT_string (die, DW_AT_name);
7003 if (!name)
7004 return;
7006 s = (codeview_symbol *) xmalloc (sizeof (codeview_symbol));
7008 s->next = NULL;
7009 s->kind = get_AT (die, DW_AT_external) ? S_GDATA32 : S_LDATA32;
7010 s->data_symbol.type = get_type_num (get_AT_ref (die, DW_AT_type), false,
7011 false);
7012 s->data_symbol.name = get_name (die);
7013 s->data_symbol.die = die;
7015 if (last_sym)
7016 last_sym->next = s;
7017 else
7018 sym = s;
7020 last_sym = s;
7023 /* Return the type number of the LF_STRING_ID entry corresponding to the given
7024 string, creating a new one if necessary. */
7026 static uint32_t
7027 add_string_id (const char *s)
7029 codeview_custom_type **slot;
7030 codeview_custom_type *ct;
7032 if (!string_id_htab)
7033 string_id_htab = new hash_table<string_id_hasher> (10);
7035 slot = string_id_htab->find_slot_with_hash (s, htab_hash_string (s),
7036 INSERT);
7037 if (*slot)
7038 return (*slot)->num;
7040 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
7042 ct->next = NULL;
7043 ct->kind = LF_STRING_ID;
7044 ct->lf_string_id.substring = 0;
7045 ct->lf_string_id.string = xstrdup (s);
7047 add_custom_type (ct);
7049 *slot = ct;
7051 return ct->num;
7054 /* Return the type number of the LF_STRING_ID corresponding to the given DIE's
7055 parent, or 0 if it is in the global scope. */
7057 static uint32_t
7058 get_scope_string_id (dw_die_ref die)
7060 dw_die_ref decl = get_AT_ref (die, DW_AT_specification);
7061 char *name;
7062 uint32_t ret;
7064 if (decl)
7065 die = decl;
7067 die = dw_get_die_parent (die);
7068 if (!die)
7069 return 0;
7071 if (dw_get_die_tag (die) == DW_TAG_compile_unit)
7072 return 0;
7074 name = get_name (die);
7075 if (!name)
7076 return 0;
7078 ret = add_string_id (name);
7079 free (name);
7081 return ret;
7084 /* Add an LF_FUNC_ID type and return its number (see write_lf_func_id). */
7086 static uint32_t
7087 add_lf_func_id (dw_die_ref die, const char *name)
7089 uint32_t function_type, scope_type;
7090 codeview_custom_type *ct;
7092 function_type = get_type_num_subroutine_type (die, false, 0, 0, 0);
7093 scope_type = get_scope_string_id (die);
7095 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
7097 ct->next = NULL;
7098 ct->kind = LF_FUNC_ID;
7099 ct->lf_func_id.parent_scope = scope_type;
7100 ct->lf_func_id.function_type = function_type;
7101 ct->lf_func_id.name = xstrdup (name);
7103 add_custom_type (ct);
7105 return ct->num;
7108 /* Add an LF_MFUNC_ID type and return its number (see write_lf_mfunc_id). */
7110 static uint32_t
7111 add_lf_mfunc_id (dw_die_ref die, const char *name)
7113 uint32_t function_type = 0, parent_type;
7114 codeview_custom_type *ct;
7115 dw_die_ref spec = get_AT_ref (die, DW_AT_specification);
7117 parent_type = get_type_num (dw_get_die_parent (spec), false, false);
7119 if (types_htab)
7121 codeview_type **slot;
7123 slot = types_htab->find_slot_with_hash (spec, htab_hash_pointer (spec),
7124 NO_INSERT);
7126 if (slot && *slot)
7127 function_type = (*slot)->num;
7130 if (function_type == 0)
7132 function_type = get_type_num_subroutine_type (die, false, parent_type,
7133 0, 0);
7136 ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
7138 ct->next = NULL;
7139 ct->kind = LF_MFUNC_ID;
7140 ct->lf_mfunc_id.parent_type = parent_type;
7141 ct->lf_mfunc_id.function_type = function_type;
7142 ct->lf_mfunc_id.name = xstrdup (name);
7144 add_custom_type (ct);
7146 return ct->num;
7149 /* Generate a new LF_FUNC_ID or LF_MFUNC_ID type for a DW_TAG_subprogram DIE
7150 and return its number, or return the existing type number if already
7151 present. */
7153 static uint32_t
7154 get_func_id (dw_die_ref die)
7156 const char *name = get_AT_string (die, DW_AT_name);
7157 dw_die_ref spec = get_AT_ref (die, DW_AT_specification);
7158 bool do_mfunc_id = false;
7159 codeview_type **slot, *t;
7160 uint32_t num;
7162 if (!name)
7163 return 0;
7165 if (!func_htab)
7166 func_htab = new hash_table<die_hasher> (10);
7168 slot = func_htab->find_slot_with_hash (die, htab_hash_pointer (die), INSERT);
7170 if (slot && *slot)
7171 return (*slot)->num;
7173 if (spec && dw_get_die_parent (spec))
7175 switch (dw_get_die_tag (dw_get_die_parent (spec)))
7177 case DW_TAG_class_type:
7178 case DW_TAG_structure_type:
7179 case DW_TAG_union_type:
7180 do_mfunc_id = true;
7181 break;
7183 default:
7184 break;
7188 if (do_mfunc_id)
7189 num = add_lf_mfunc_id (die, name);
7190 else
7191 num = add_lf_func_id (die, name);
7193 t = (codeview_type *) xmalloc (sizeof (codeview_type));
7195 t->die = die;
7196 t->num = num;
7197 t->is_fwd_ref = false;
7199 *slot = t;
7201 return num;
7204 /* Process a DW_TAG_subprogram DIE, and add an S_GPROC32_ID or S_LPROC32_ID
7205 symbol for this. */
7207 static void
7208 add_function (dw_die_ref die)
7210 uint32_t func_id_type;
7211 codeview_symbol *s;
7213 func_id_type = get_func_id (die);
7214 if (func_id_type == 0)
7215 return;
7217 /* Add an S_GPROC32_ID / S_LPROC32_ID symbol. */
7219 s = (codeview_symbol *) xmalloc (sizeof (codeview_symbol));
7221 s->next = NULL;
7222 s->kind = get_AT (die, DW_AT_external) ? S_GPROC32_ID : S_LPROC32_ID;
7223 s->function.parent = 0;
7224 s->function.end = 0;
7225 s->function.next = 0;
7226 s->function.type = func_id_type;
7227 s->function.flags = 0;
7228 s->function.name = get_name (die);
7229 s->function.die = die;
7231 if (last_sym)
7232 last_sym->next = s;
7233 else
7234 sym = s;
7236 last_sym = s;
7239 /* If we have encountered a new inlined function, add this to
7240 inlinee_lines_htab so that it can be output to the S_INLINEELINES subsection
7241 of .debug$S. */
7243 void
7244 codeview_abstract_function (tree decl)
7246 codeview_inlinee_lines *il, **slot;
7247 dw_die_ref die;
7248 uint32_t func_id;
7249 struct dwarf_file_data *file;
7251 if (!DECL_DECLARED_INLINE_P (decl))
7252 return;
7254 die = lookup_decl_die (decl);
7255 if (!die)
7256 return;
7258 func_id = get_func_id (die);
7259 if (func_id == 0)
7260 return;
7262 file = get_AT_file (die, DW_AT_decl_file);
7263 if (!file)
7264 return;
7266 if (!inlinee_lines_htab)
7267 inlinee_lines_htab = new hash_table<inlinee_lines_hasher> (10);
7269 slot = inlinee_lines_htab->find_slot_with_hash (func_id, func_id, INSERT);
7270 if (*slot)
7271 return;
7273 il = (codeview_inlinee_lines *) xmalloc (sizeof (codeview_inlinee_lines));
7275 il->next = NULL;
7276 il->func_id = func_id;
7277 il->file_id = get_file_id (file->filename);
7278 il->starting_line = get_AT_unsigned (die, DW_AT_decl_line);
7280 *slot = il;
7283 /* Loop through the DIEs that have been output for our TU, and add CodeView
7284 symbols for them. */
7286 void
7287 codeview_debug_early_finish (dw_die_ref die)
7289 dw_die_ref first_child, c;
7291 first_child = dw_get_die_child (die);
7293 if (!first_child)
7294 return;
7296 c = first_child;
7300 switch (dw_get_die_tag (c))
7302 case DW_TAG_variable:
7303 add_variable (c);
7304 break;
7305 case DW_TAG_subprogram:
7306 add_function (c);
7307 break;
7308 default:
7309 break;
7312 c = dw_get_die_sib (c);
7314 while (c != first_child);
7316 flush_deferred_types ();
7319 #endif