1 /* Dwarf2 assembler output helper routines.
2 Copyright (C) 2001-2018 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
29 #include "stringpool.h"
32 #include "dwarf2asm.h"
36 #include "fold-const.h"
38 #ifndef XCOFF_DEBUGGING_INFO
39 #define XCOFF_DEBUGGING_INFO 0
43 /* Output an unaligned integer with the given value and size. Prefer not
44 to print a newline, since the caller may want to add a comment. */
47 dw2_assemble_integer (int size
, rtx x
)
49 const char *op
= integer_asm_op (size
, FALSE
);
53 fputs (op
, asm_out_file
);
55 fprint_whex (asm_out_file
, (unsigned HOST_WIDE_INT
) INTVAL (x
));
57 output_addr_const (asm_out_file
, x
);
60 assemble_integer (x
, size
, BITS_PER_UNIT
, 1);
64 /* Output a value of a given size in target byte order. */
67 dw2_asm_output_data_raw (int size
, unsigned HOST_WIDE_INT value
)
69 unsigned char bytes
[8];
72 for (i
= 0; i
< 8; ++i
)
74 bytes
[i
] = value
& 0xff;
80 for (i
= size
- 1; i
> 0; --i
)
81 fprintf (asm_out_file
, "%#x,", bytes
[i
]);
82 fprintf (asm_out_file
, "%#x", bytes
[0]);
86 for (i
= 0; i
< size
- 1; ++i
)
87 fprintf (asm_out_file
, "%#x,", bytes
[i
]);
88 fprintf (asm_out_file
, "%#x", bytes
[i
]);
92 /* Output an immediate constant in a given SIZE in bytes. */
95 dw2_asm_output_data (int size
, unsigned HOST_WIDE_INT value
,
96 const char *comment
, ...)
99 const char *op
= integer_asm_op (size
, FALSE
);
101 va_start (ap
, comment
);
103 if (size
* 8 < HOST_BITS_PER_WIDE_INT
)
104 value
&= ~(HOST_WIDE_INT_M1U
<< (size
* 8));
108 fputs (op
, asm_out_file
);
109 fprint_whex (asm_out_file
, value
);
112 assemble_integer (GEN_INT (value
), size
, BITS_PER_UNIT
, 1);
114 if (flag_debug_asm
&& comment
)
116 fputs ("\t" ASM_COMMENT_START
" ", asm_out_file
);
117 vfprintf (asm_out_file
, comment
, ap
);
119 putc ('\n', asm_out_file
);
124 /* Output the difference between two symbols in a given size. */
125 /* ??? There appear to be assemblers that do not like such
126 subtraction, but do support ASM_SET_OP. It's unfortunately
127 impossible to do here, since the ASM_SET_OP for the difference
128 symbol must appear after both symbols are defined. */
131 dw2_asm_output_delta (int size
, const char *lab1
, const char *lab2
,
132 const char *comment
, ...)
136 va_start (ap
, comment
);
138 #ifdef ASM_OUTPUT_DWARF_DELTA
139 ASM_OUTPUT_DWARF_DELTA (asm_out_file
, size
, lab1
, lab2
);
141 dw2_assemble_integer (size
,
142 gen_rtx_MINUS (Pmode
,
143 gen_rtx_SYMBOL_REF (Pmode
, lab1
),
144 gen_rtx_SYMBOL_REF (Pmode
, lab2
)));
146 if (flag_debug_asm
&& comment
)
148 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
149 vfprintf (asm_out_file
, comment
, ap
);
151 fputc ('\n', asm_out_file
);
156 #ifdef ASM_OUTPUT_DWARF_VMS_DELTA
157 /* Output the difference between two symbols in instruction units
161 dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED
,
162 const char *lab1
, const char *lab2
,
163 const char *comment
, ...)
167 va_start (ap
, comment
);
169 ASM_OUTPUT_DWARF_VMS_DELTA (asm_out_file
, size
, lab1
, lab2
);
170 if (flag_debug_asm
&& comment
)
172 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
173 vfprintf (asm_out_file
, comment
, ap
);
175 fputc ('\n', asm_out_file
);
181 /* Output a section-relative reference to a LABEL, which was placed in
182 BASE. In general this can only be done for debugging symbols.
183 E.g. on most targets with the GNU linker, this is accomplished with
184 a direct reference and the knowledge that the debugging section
185 will be placed at VMA 0. Some targets have special relocations for
186 this that we must use. */
189 dw2_asm_output_offset (int size
, const char *label
,
190 section
*base ATTRIBUTE_UNUSED
,
191 const char *comment
, ...)
195 va_start (ap
, comment
);
197 #ifdef ASM_OUTPUT_DWARF_OFFSET
198 ASM_OUTPUT_DWARF_OFFSET (asm_out_file
, size
, label
, 0, base
);
200 dw2_assemble_integer (size
, gen_rtx_SYMBOL_REF (Pmode
, label
));
203 if (flag_debug_asm
&& comment
)
205 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
206 vfprintf (asm_out_file
, comment
, ap
);
208 fputc ('\n', asm_out_file
);
214 dw2_asm_output_offset (int size
, const char *label
, HOST_WIDE_INT offset
,
215 section
*base ATTRIBUTE_UNUSED
,
216 const char *comment
, ...)
220 va_start (ap
, comment
);
222 #ifdef ASM_OUTPUT_DWARF_OFFSET
223 ASM_OUTPUT_DWARF_OFFSET (asm_out_file
, size
, label
, offset
, base
);
225 dw2_assemble_integer (size
, gen_rtx_PLUS (Pmode
,
226 gen_rtx_SYMBOL_REF (Pmode
, label
),
227 gen_int_mode (offset
, Pmode
)));
230 if (flag_debug_asm
&& comment
)
232 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
233 vfprintf (asm_out_file
, comment
, ap
);
235 fputc ('\n', asm_out_file
);
242 /* Output a self-relative reference to a label, possibly in a
243 different section or object file. */
246 dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED
,
247 const char *label ATTRIBUTE_UNUSED
,
248 const char *comment
, ...)
252 va_start (ap
, comment
);
254 #ifdef ASM_OUTPUT_DWARF_PCREL
255 ASM_OUTPUT_DWARF_PCREL (asm_out_file
, size
, label
);
257 dw2_assemble_integer (size
,
258 gen_rtx_MINUS (Pmode
,
259 gen_rtx_SYMBOL_REF (Pmode
, label
),
263 if (flag_debug_asm
&& comment
)
265 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
266 vfprintf (asm_out_file
, comment
, ap
);
268 fputc ('\n', asm_out_file
);
274 /* Output an absolute reference to a label. */
277 dw2_asm_output_addr (int size
, const char *label
,
278 const char *comment
, ...)
282 va_start (ap
, comment
);
284 dw2_assemble_integer (size
, gen_rtx_SYMBOL_REF (Pmode
, label
));
286 if (flag_debug_asm
&& comment
)
288 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
289 vfprintf (asm_out_file
, comment
, ap
);
291 fputc ('\n', asm_out_file
);
296 /* Similar, but use an RTX expression instead of a text label. */
299 dw2_asm_output_addr_rtx (int size
, rtx addr
,
300 const char *comment
, ...)
304 va_start (ap
, comment
);
306 dw2_assemble_integer (size
, addr
);
308 if (flag_debug_asm
&& comment
)
310 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
311 vfprintf (asm_out_file
, comment
, ap
);
313 fputc ('\n', asm_out_file
);
318 /* Output the first ORIG_LEN characters of STR as a string.
319 If ORIG_LEN is equal to -1, ignore this parameter and output
320 the entire STR instead.
321 If COMMENT is not NULL and comments in the debug information
322 have been requested by the user, append the given COMMENT
323 to the generated output. */
326 dw2_asm_output_nstring (const char *str
, size_t orig_len
,
327 const char *comment
, ...)
332 va_start (ap
, comment
);
336 if (len
== (size_t) -1)
339 if (flag_debug_asm
&& comment
)
341 if (XCOFF_DEBUGGING_INFO
)
342 fputs ("\t.byte \"", asm_out_file
);
344 fputs ("\t.ascii \"", asm_out_file
);
346 for (i
= 0; i
< len
; i
++)
350 fputc (XCOFF_DEBUGGING_INFO
? '\"' : '\\', asm_out_file
);
352 fputc ('\\', asm_out_file
);
354 fputc (c
, asm_out_file
);
356 fprintf (asm_out_file
, "\\%o", c
);
358 fprintf (asm_out_file
, "\\0\"\t%s ", ASM_COMMENT_START
);
359 vfprintf (asm_out_file
, comment
, ap
);
360 fputc ('\n', asm_out_file
);
364 /* If an explicit length was given, we can't assume there
365 is a null termination in the string buffer. */
366 if (orig_len
== (size_t) -1)
368 ASM_OUTPUT_ASCII (asm_out_file
, str
, len
);
369 if (orig_len
!= (size_t) -1)
370 assemble_integer (const0_rtx
, 1, BITS_PER_UNIT
, 1);
377 /* Return the size of an unsigned LEB128 quantity. */
380 size_of_uleb128 (unsigned HOST_WIDE_INT value
)
394 /* Return the size of a signed LEB128 quantity. */
397 size_of_sleb128 (HOST_WIDE_INT value
)
403 byte
= (value
& 0x7f);
407 while (!((value
== 0 && (byte
& 0x40) == 0)
408 || (value
== -1 && (byte
& 0x40) != 0)));
413 /* Given an encoding, return the number of bytes the format occupies.
414 This is only defined for fixed-size encodings, and so does not
418 size_of_encoded_value (int encoding
)
420 if (encoding
== DW_EH_PE_omit
)
423 switch (encoding
& 0x07)
425 case DW_EH_PE_absptr
:
426 return POINTER_SIZE_UNITS
;
427 case DW_EH_PE_udata2
:
429 case DW_EH_PE_udata4
:
431 case DW_EH_PE_udata8
:
438 /* Yield a name for a given pointer encoding. */
441 eh_data_format_name (int format
)
443 #if HAVE_DESIGNATED_INITIALIZERS
444 #define S(p, v) [p] = v,
446 #define S(p, v) case p: return v;
449 #if HAVE_DESIGNATED_INITIALIZERS
450 __extension__
static const char * const format_names
[256] = {
455 S(DW_EH_PE_absptr
, "absolute")
456 S(DW_EH_PE_omit
, "omit")
457 S(DW_EH_PE_aligned
, "aligned absolute")
459 S(DW_EH_PE_uleb128
, "uleb128")
460 S(DW_EH_PE_udata2
, "udata2")
461 S(DW_EH_PE_udata4
, "udata4")
462 S(DW_EH_PE_udata8
, "udata8")
463 S(DW_EH_PE_sleb128
, "sleb128")
464 S(DW_EH_PE_sdata2
, "sdata2")
465 S(DW_EH_PE_sdata4
, "sdata4")
466 S(DW_EH_PE_sdata8
, "sdata8")
468 S(DW_EH_PE_absptr
| DW_EH_PE_pcrel
, "pcrel")
469 S(DW_EH_PE_uleb128
| DW_EH_PE_pcrel
, "pcrel uleb128")
470 S(DW_EH_PE_udata2
| DW_EH_PE_pcrel
, "pcrel udata2")
471 S(DW_EH_PE_udata4
| DW_EH_PE_pcrel
, "pcrel udata4")
472 S(DW_EH_PE_udata8
| DW_EH_PE_pcrel
, "pcrel udata8")
473 S(DW_EH_PE_sleb128
| DW_EH_PE_pcrel
, "pcrel sleb128")
474 S(DW_EH_PE_sdata2
| DW_EH_PE_pcrel
, "pcrel sdata2")
475 S(DW_EH_PE_sdata4
| DW_EH_PE_pcrel
, "pcrel sdata4")
476 S(DW_EH_PE_sdata8
| DW_EH_PE_pcrel
, "pcrel sdata8")
478 S(DW_EH_PE_absptr
| DW_EH_PE_textrel
, "textrel")
479 S(DW_EH_PE_uleb128
| DW_EH_PE_textrel
, "textrel uleb128")
480 S(DW_EH_PE_udata2
| DW_EH_PE_textrel
, "textrel udata2")
481 S(DW_EH_PE_udata4
| DW_EH_PE_textrel
, "textrel udata4")
482 S(DW_EH_PE_udata8
| DW_EH_PE_textrel
, "textrel udata8")
483 S(DW_EH_PE_sleb128
| DW_EH_PE_textrel
, "textrel sleb128")
484 S(DW_EH_PE_sdata2
| DW_EH_PE_textrel
, "textrel sdata2")
485 S(DW_EH_PE_sdata4
| DW_EH_PE_textrel
, "textrel sdata4")
486 S(DW_EH_PE_sdata8
| DW_EH_PE_textrel
, "textrel sdata8")
488 S(DW_EH_PE_absptr
| DW_EH_PE_datarel
, "datarel")
489 S(DW_EH_PE_uleb128
| DW_EH_PE_datarel
, "datarel uleb128")
490 S(DW_EH_PE_udata2
| DW_EH_PE_datarel
, "datarel udata2")
491 S(DW_EH_PE_udata4
| DW_EH_PE_datarel
, "datarel udata4")
492 S(DW_EH_PE_udata8
| DW_EH_PE_datarel
, "datarel udata8")
493 S(DW_EH_PE_sleb128
| DW_EH_PE_datarel
, "datarel sleb128")
494 S(DW_EH_PE_sdata2
| DW_EH_PE_datarel
, "datarel sdata2")
495 S(DW_EH_PE_sdata4
| DW_EH_PE_datarel
, "datarel sdata4")
496 S(DW_EH_PE_sdata8
| DW_EH_PE_datarel
, "datarel sdata8")
498 S(DW_EH_PE_absptr
| DW_EH_PE_funcrel
, "funcrel")
499 S(DW_EH_PE_uleb128
| DW_EH_PE_funcrel
, "funcrel uleb128")
500 S(DW_EH_PE_udata2
| DW_EH_PE_funcrel
, "funcrel udata2")
501 S(DW_EH_PE_udata4
| DW_EH_PE_funcrel
, "funcrel udata4")
502 S(DW_EH_PE_udata8
| DW_EH_PE_funcrel
, "funcrel udata8")
503 S(DW_EH_PE_sleb128
| DW_EH_PE_funcrel
, "funcrel sleb128")
504 S(DW_EH_PE_sdata2
| DW_EH_PE_funcrel
, "funcrel sdata2")
505 S(DW_EH_PE_sdata4
| DW_EH_PE_funcrel
, "funcrel sdata4")
506 S(DW_EH_PE_sdata8
| DW_EH_PE_funcrel
, "funcrel sdata8")
508 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
, "indirect absolute")
510 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_pcrel
,
512 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_pcrel
,
513 "indirect pcrel uleb128")
514 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_pcrel
,
515 "indirect pcrel udata2")
516 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_pcrel
,
517 "indirect pcrel udata4")
518 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_pcrel
,
519 "indirect pcrel udata8")
520 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_pcrel
,
521 "indirect pcrel sleb128")
522 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_pcrel
,
523 "indirect pcrel sdata2")
524 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_pcrel
,
525 "indirect pcrel sdata4")
526 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_pcrel
,
527 "indirect pcrel sdata8")
529 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_textrel
,
531 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_textrel
,
532 "indirect textrel uleb128")
533 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_textrel
,
534 "indirect textrel udata2")
535 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_textrel
,
536 "indirect textrel udata4")
537 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_textrel
,
538 "indirect textrel udata8")
539 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_textrel
,
540 "indirect textrel sleb128")
541 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_textrel
,
542 "indirect textrel sdata2")
543 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_textrel
,
544 "indirect textrel sdata4")
545 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_textrel
,
546 "indirect textrel sdata8")
548 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_datarel
,
550 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_datarel
,
551 "indirect datarel uleb128")
552 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_datarel
,
553 "indirect datarel udata2")
554 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_datarel
,
555 "indirect datarel udata4")
556 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_datarel
,
557 "indirect datarel udata8")
558 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_datarel
,
559 "indirect datarel sleb128")
560 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_datarel
,
561 "indirect datarel sdata2")
562 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_datarel
,
563 "indirect datarel sdata4")
564 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_datarel
,
565 "indirect datarel sdata8")
567 S(DW_EH_PE_indirect
| DW_EH_PE_absptr
| DW_EH_PE_funcrel
,
569 S(DW_EH_PE_indirect
| DW_EH_PE_uleb128
| DW_EH_PE_funcrel
,
570 "indirect funcrel uleb128")
571 S(DW_EH_PE_indirect
| DW_EH_PE_udata2
| DW_EH_PE_funcrel
,
572 "indirect funcrel udata2")
573 S(DW_EH_PE_indirect
| DW_EH_PE_udata4
| DW_EH_PE_funcrel
,
574 "indirect funcrel udata4")
575 S(DW_EH_PE_indirect
| DW_EH_PE_udata8
| DW_EH_PE_funcrel
,
576 "indirect funcrel udata8")
577 S(DW_EH_PE_indirect
| DW_EH_PE_sleb128
| DW_EH_PE_funcrel
,
578 "indirect funcrel sleb128")
579 S(DW_EH_PE_indirect
| DW_EH_PE_sdata2
| DW_EH_PE_funcrel
,
580 "indirect funcrel sdata2")
581 S(DW_EH_PE_indirect
| DW_EH_PE_sdata4
| DW_EH_PE_funcrel
,
582 "indirect funcrel sdata4")
583 S(DW_EH_PE_indirect
| DW_EH_PE_sdata8
| DW_EH_PE_funcrel
,
584 "indirect funcrel sdata8")
586 #if HAVE_DESIGNATED_INITIALIZERS
589 gcc_assert (format
>= 0 && format
< 0x100 && format_names
[format
]);
591 return format_names
[format
];
598 /* Output an unsigned LEB128 quantity, but only the byte values. */
601 dw2_asm_output_data_uleb128_raw (unsigned HOST_WIDE_INT value
)
605 int byte
= (value
& 0x7f);
608 /* More bytes to follow. */
611 fprintf (asm_out_file
, "%#x", byte
);
614 fputc (',', asm_out_file
);
618 /* Output an unsigned LEB128 quantity. */
621 dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value
,
622 const char *comment
, ...)
626 va_start (ap
, comment
);
630 fputs ("\t.uleb128 ", asm_out_file
);
631 fprint_whex (asm_out_file
, value
);
633 if (flag_debug_asm
&& comment
)
635 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
636 vfprintf (asm_out_file
, comment
, ap
);
641 unsigned HOST_WIDE_INT work
= value
;
642 const char *byte_op
= targetm
.asm_out
.byte_op
;
645 fputs (byte_op
, asm_out_file
);
648 int byte
= (work
& 0x7f);
651 /* More bytes to follow. */
656 fprintf (asm_out_file
, "%#x", byte
);
658 fputc (',', asm_out_file
);
661 assemble_integer (GEN_INT (byte
), 1, BITS_PER_UNIT
, 1);
667 fprintf (asm_out_file
, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX
,
668 ASM_COMMENT_START
, value
);
671 fputs ("; ", asm_out_file
);
672 vfprintf (asm_out_file
, comment
, ap
);
677 putc ('\n', asm_out_file
);
682 /* Output an signed LEB128 quantity, but only the byte values. */
685 dw2_asm_output_data_sleb128_raw (HOST_WIDE_INT value
)
691 byte
= (value
& 0x7f);
693 more
= !((value
== 0 && (byte
& 0x40) == 0)
694 || (value
== -1 && (byte
& 0x40) != 0));
698 fprintf (asm_out_file
, "%#x", byte
);
701 fputc (',', asm_out_file
);
705 /* Output a signed LEB128 quantity. */
708 dw2_asm_output_data_sleb128 (HOST_WIDE_INT value
,
709 const char *comment
, ...)
713 va_start (ap
, comment
);
717 fprintf (asm_out_file
, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC
, value
);
719 if (flag_debug_asm
&& comment
)
721 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
722 vfprintf (asm_out_file
, comment
, ap
);
727 HOST_WIDE_INT work
= value
;
729 const char *byte_op
= targetm
.asm_out
.byte_op
;
732 fputs (byte_op
, asm_out_file
);
735 byte
= (work
& 0x7f);
736 /* arithmetic shift */
738 more
= !((work
== 0 && (byte
& 0x40) == 0)
739 || (work
== -1 && (byte
& 0x40) != 0));
745 fprintf (asm_out_file
, "%#x", byte
);
747 fputc (',', asm_out_file
);
750 assemble_integer (GEN_INT (byte
), 1, BITS_PER_UNIT
, 1);
756 fprintf (asm_out_file
, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC
,
757 ASM_COMMENT_START
, value
);
760 fputs ("; ", asm_out_file
);
761 vfprintf (asm_out_file
, comment
, ap
);
766 fputc ('\n', asm_out_file
);
771 /* Output symbol LAB1 as an unsigned LEB128 quantity. LAB1 should be
772 an assembler-computed constant, e.g. a view number, because we
773 can't have relocations in LEB128 quantities. */
776 dw2_asm_output_symname_uleb128 (const char *lab1 ATTRIBUTE_UNUSED
,
777 const char *comment
, ...)
781 va_start (ap
, comment
);
783 #ifdef HAVE_AS_LEB128
784 fputs ("\t.uleb128 ", asm_out_file
);
785 assemble_name (asm_out_file
, lab1
);
790 if (flag_debug_asm
&& comment
)
792 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
793 vfprintf (asm_out_file
, comment
, ap
);
795 fputc ('\n', asm_out_file
);
801 dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED
,
802 const char *lab2 ATTRIBUTE_UNUSED
,
803 const char *comment
, ...)
807 va_start (ap
, comment
);
809 gcc_assert (HAVE_AS_LEB128
);
811 fputs ("\t.uleb128 ", asm_out_file
);
812 assemble_name (asm_out_file
, lab1
);
813 putc ('-', asm_out_file
);
814 /* dwarf2out.c might give us a label expression (e.g. .LVL548-1)
815 as second argument. If so, make it a subexpression, to make
816 sure the substraction is done in the right order. */
817 if (strchr (lab2
, '-') != NULL
)
819 putc ('(', asm_out_file
);
820 assemble_name (asm_out_file
, lab2
);
821 putc (')', asm_out_file
);
824 assemble_name (asm_out_file
, lab2
);
826 if (flag_debug_asm
&& comment
)
828 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
829 vfprintf (asm_out_file
, comment
, ap
);
831 fputc ('\n', asm_out_file
);
839 dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED
,
840 const char *lab2 ATTRIBUTE_UNUSED
,
841 const char *comment
, ...)
845 va_start (ap
, comment
);
847 gcc_assert (HAVE_AS_LEB128
);
849 fputs ("\t.sleb128 ", asm_out_file
);
850 assemble_name (asm_out_file
, lab1
);
851 putc ('-', asm_out_file
);
852 assemble_name (asm_out_file
, lab2
);
854 if (flag_debug_asm
&& comment
)
856 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
857 vfprintf (asm_out_file
, comment
, ap
);
859 fputc ('\n', asm_out_file
);
865 static GTY(()) hash_map
<const char *, tree
> *indirect_pool
;
867 static GTY(()) int dw2_const_labelno
;
869 #if defined(HAVE_GAS_HIDDEN)
870 # define USE_LINKONCE_INDIRECT (SUPPORTS_ONE_ONLY && !XCOFF_DEBUGGING_INFO)
872 # define USE_LINKONCE_INDIRECT 0
875 /* Compare two std::pair<const char *, tree> by their first element.
877 >0 to indicate whether K1 is less than, equal to, or greater than
881 compare_strings (const void *a
, const void *b
)
883 const char *s1
= ((const std::pair
<const char *, tree
> *) a
)->first
;
884 const char *s2
= ((const std::pair
<const char *, tree
> *) b
)->first
;
890 ret
= strcmp (s1
, s2
);
892 /* The strings are always those from IDENTIFIER_NODEs, and,
893 therefore, we should never have two copies of the same
900 /* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
901 memory. Differs from force_const_mem in that a single pool is used for
902 the entire unit of translation, and the memory is not guaranteed to be
903 "near" the function in any interesting sense. IS_PUBLIC controls whether
904 the symbol can be shared across the entire application (or DSO). */
907 dw2_force_const_mem (rtx x
, bool is_public
)
913 indirect_pool
= hash_map
<const char *, tree
>::create_ggc (64);
915 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
918 tree
*slot
= indirect_pool
->get (key
);
924 const char *str
= targetm
.strip_name_encoding (key
);
926 if (is_public
&& USE_LINKONCE_INDIRECT
)
928 char *ref_name
= XALLOCAVEC (char, strlen (str
) + sizeof "DW.ref.");
930 sprintf (ref_name
, "DW.ref.%s", str
);
931 gcc_assert (!maybe_get_identifier (ref_name
));
932 decl_id
= get_identifier (ref_name
);
933 TREE_PUBLIC (decl_id
) = 1;
939 ASM_GENERATE_INTERNAL_LABEL (label
, "LDFCM", dw2_const_labelno
);
941 gcc_assert (!maybe_get_identifier (label
));
942 decl_id
= get_identifier (label
);
945 id
= maybe_get_identifier (str
);
947 TREE_SYMBOL_REFERENCED (id
) = 1;
949 indirect_pool
->put (key
, decl_id
);
952 return gen_rtx_SYMBOL_REF (Pmode
, IDENTIFIER_POINTER (decl_id
));
955 /* A helper function for dw2_output_indirect_constants. Emit one queued
956 constant to memory. */
959 dw2_output_indirect_constant_1 (const char *sym
, tree id
)
964 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, id
, ptr_type_node
);
965 SET_DECL_ASSEMBLER_NAME (decl
, id
);
966 DECL_ARTIFICIAL (decl
) = 1;
967 DECL_IGNORED_P (decl
) = 1;
968 DECL_INITIAL (decl
) = build_fold_addr_expr (decl
);
969 TREE_READONLY (decl
) = 1;
970 TREE_STATIC (decl
) = 1;
972 if (TREE_PUBLIC (id
))
974 TREE_PUBLIC (decl
) = 1;
975 make_decl_one_only (decl
, DECL_ASSEMBLER_NAME (decl
));
976 if (USE_LINKONCE_INDIRECT
)
977 DECL_VISIBILITY (decl
) = VISIBILITY_HIDDEN
;
980 sym_ref
= gen_rtx_SYMBOL_REF (Pmode
, sym
);
981 /* Disable ASan for decl because redzones cause ABI breakage between GCC and
982 libstdc++ for `.LDFCM*' variables. See PR 78651 for details. */
983 unsigned int save_flag_sanitize
= flag_sanitize
;
984 flag_sanitize
&= ~(SANITIZE_ADDRESS
| SANITIZE_USER_ADDRESS
985 | SANITIZE_KERNEL_ADDRESS
);
986 /* And also temporarily disable -fsection-anchors. These indirect constants
987 are never referenced from code, so it doesn't make any sense to aggregate
989 int save_flag_section_anchors
= flag_section_anchors
;
990 flag_section_anchors
= 0;
991 assemble_variable (decl
, 1, 1, 1);
992 flag_section_anchors
= save_flag_section_anchors
;
993 flag_sanitize
= save_flag_sanitize
;
994 assemble_integer (sym_ref
, POINTER_SIZE_UNITS
, POINTER_SIZE
, 1);
995 /* The following is a hack recognized by use_blocks_for_decl_p to disable
996 section anchor handling of the decl. */
997 DECL_INITIAL (decl
) = decl
;
1002 /* Emit the constants queued through dw2_force_const_mem. */
1005 dw2_output_indirect_constants (void)
1010 auto_vec
<std::pair
<const char *, tree
> > temp (indirect_pool
->elements ());
1011 for (hash_map
<const char *, tree
>::iterator iter
= indirect_pool
->begin ();
1012 iter
!= indirect_pool
->end (); ++iter
)
1013 temp
.quick_push (*iter
);
1015 temp
.qsort (compare_strings
);
1017 for (unsigned int i
= 0; i
< temp
.length (); i
++)
1018 dw2_output_indirect_constant_1 (temp
[i
].first
, temp
[i
].second
);
1021 /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.
1022 If PUBLIC is set and the encoding is DW_EH_PE_indirect, the indirect
1023 reference is shared across the entire application (or DSO). */
1026 dw2_asm_output_encoded_addr_rtx (int encoding
, rtx addr
, bool is_public
,
1027 const char *comment
, ...)
1032 va_start (ap
, comment
);
1034 size
= size_of_encoded_value (encoding
);
1036 if (encoding
== DW_EH_PE_aligned
)
1038 assemble_align (POINTER_SIZE
);
1039 assemble_integer (addr
, size
, POINTER_SIZE
, 1);
1044 /* NULL is _always_ represented as a plain zero, as is 1 for Ada's
1046 if (addr
== const0_rtx
|| addr
== const1_rtx
)
1047 assemble_integer (addr
, size
, BITS_PER_UNIT
, 1);
1051 /* Allow the target first crack at emitting this. Some of the
1052 special relocations require special directives instead of
1053 just ".4byte" or whatever. */
1054 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
1055 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file
, encoding
, size
,
1059 /* Indirection is used to get dynamic relocations out of a
1060 read-only section. */
1061 if (encoding
& DW_EH_PE_indirect
)
1063 /* It is very tempting to use force_const_mem so that we share data
1064 with the normal constant pool. However, we've already emitted
1065 the constant pool for this function. Moreover, we'd like to
1066 share these constants across the entire unit of translation and
1067 even, if possible, across the entire application (or DSO). */
1068 addr
= dw2_force_const_mem (addr
, is_public
);
1069 encoding
&= ~DW_EH_PE_indirect
;
1073 switch (encoding
& 0xF0)
1075 case DW_EH_PE_absptr
:
1076 dw2_assemble_integer (size
, addr
);
1079 #ifdef ASM_OUTPUT_DWARF_DATAREL
1080 case DW_EH_PE_datarel
:
1081 gcc_assert (GET_CODE (addr
) == SYMBOL_REF
);
1082 ASM_OUTPUT_DWARF_DATAREL (asm_out_file
, size
, XSTR (addr
, 0));
1086 case DW_EH_PE_pcrel
:
1087 gcc_assert (GET_CODE (addr
) == SYMBOL_REF
);
1088 #ifdef ASM_OUTPUT_DWARF_PCREL
1089 ASM_OUTPUT_DWARF_PCREL (asm_out_file
, size
, XSTR (addr
, 0));
1091 dw2_assemble_integer (size
, gen_rtx_MINUS (Pmode
, addr
, pc_rtx
));
1096 /* Other encodings should have been handled by
1097 ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */
1101 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
1106 if (flag_debug_asm
&& comment
)
1108 fprintf (asm_out_file
, "\t%s ", ASM_COMMENT_START
);
1109 vfprintf (asm_out_file
, comment
, ap
);
1111 fputc ('\n', asm_out_file
);
1116 #include "gt-dwarf2asm.h"