dwarf2asm.cc revision 1.1 1 1.1 mrg /* Dwarf2 assembler output helper routines.
2 1.1 mrg Copyright (C) 2001-2022 Free Software Foundation, Inc.
3 1.1 mrg
4 1.1 mrg This file is part of GCC.
5 1.1 mrg
6 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
7 1.1 mrg the terms of the GNU General Public License as published by the Free
8 1.1 mrg Software Foundation; either version 3, or (at your option) any later
9 1.1 mrg version.
10 1.1 mrg
11 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 1.1 mrg for more details.
15 1.1 mrg
16 1.1 mrg You should have received a copy of the GNU General Public License
17 1.1 mrg along with GCC; see the file COPYING3. If not see
18 1.1 mrg <http://www.gnu.org/licenses/>. */
19 1.1 mrg
20 1.1 mrg
21 1.1 mrg #include "config.h"
22 1.1 mrg #include "system.h"
23 1.1 mrg #include "coretypes.h"
24 1.1 mrg #include "target.h"
25 1.1 mrg #include "rtl.h"
26 1.1 mrg #include "tree.h"
27 1.1 mrg #include "memmodel.h"
28 1.1 mrg #include "tm_p.h"
29 1.1 mrg #include "stringpool.h"
30 1.1 mrg #include "varasm.h"
31 1.1 mrg #include "output.h"
32 1.1 mrg #include "dwarf2asm.h"
33 1.1 mrg #include "dwarf2.h"
34 1.1 mrg #include "function.h"
35 1.1 mrg #include "emit-rtl.h"
36 1.1 mrg #include "fold-const.h"
37 1.1 mrg
38 1.1 mrg #ifndef XCOFF_DEBUGGING_INFO
39 1.1 mrg #define XCOFF_DEBUGGING_INFO 0
40 1.1 mrg #endif
41 1.1 mrg
42 1.1 mrg
43 1.1 mrg /* Output an unaligned integer with the given value and size. Prefer not
45 1.1 mrg to print a newline, since the caller may want to add a comment. */
46 1.1 mrg
47 1.1 mrg void
48 1.1 mrg dw2_assemble_integer (int size, rtx x)
49 1.1 mrg {
50 1.1 mrg if (size == 2 * (int) DWARF2_ADDR_SIZE && !CONST_SCALAR_INT_P (x))
51 1.1 mrg {
52 1.1 mrg /* On 32-bit targets with -gdwarf64, DImode values with
53 1.1 mrg relocations usually result in assembler errors. Assume
54 1.1 mrg all such values are positive and emit the relocation only
55 1.1 mrg in the least significant half. */
56 1.1 mrg const char *op = integer_asm_op (DWARF2_ADDR_SIZE, FALSE);
57 1.1 mrg if (BYTES_BIG_ENDIAN)
58 1.1 mrg {
59 1.1 mrg if (op)
60 1.1 mrg {
61 1.1 mrg fputs (op, asm_out_file);
62 1.1 mrg fprint_whex (asm_out_file, 0);
63 1.1 mrg fputs (", ", asm_out_file);
64 1.1 mrg output_addr_const (asm_out_file, x);
65 1.1 mrg }
66 1.1 mrg else
67 1.1 mrg {
68 1.1 mrg assemble_integer (const0_rtx, DWARF2_ADDR_SIZE,
69 1.1 mrg BITS_PER_UNIT, 1);
70 1.1 mrg putc ('\n', asm_out_file);
71 1.1 mrg assemble_integer (x, DWARF2_ADDR_SIZE,
72 1.1 mrg BITS_PER_UNIT, 1);
73 1.1 mrg }
74 1.1 mrg }
75 1.1 mrg else
76 1.1 mrg {
77 1.1 mrg if (op)
78 1.1 mrg {
79 1.1 mrg fputs (op, asm_out_file);
80 1.1 mrg output_addr_const (asm_out_file, x);
81 1.1 mrg fputs (", ", asm_out_file);
82 1.1 mrg fprint_whex (asm_out_file, 0);
83 1.1 mrg }
84 1.1 mrg else
85 1.1 mrg {
86 1.1 mrg assemble_integer (x, DWARF2_ADDR_SIZE,
87 1.1 mrg BITS_PER_UNIT, 1);
88 1.1 mrg putc ('\n', asm_out_file);
89 1.1 mrg assemble_integer (const0_rtx, DWARF2_ADDR_SIZE,
90 1.1 mrg BITS_PER_UNIT, 1);
91 1.1 mrg }
92 1.1 mrg }
93 1.1 mrg return;
94 1.1 mrg }
95 1.1 mrg
96 1.1 mrg const char *op = integer_asm_op (size, FALSE);
97 1.1 mrg
98 1.1 mrg if (op)
99 1.1 mrg {
100 1.1 mrg fputs (op, asm_out_file);
101 1.1 mrg if (CONST_INT_P (x))
102 1.1 mrg fprint_whex (asm_out_file, (unsigned HOST_WIDE_INT) INTVAL (x));
103 1.1 mrg else
104 1.1 mrg output_addr_const (asm_out_file, x);
105 1.1 mrg }
106 1.1 mrg else
107 1.1 mrg assemble_integer (x, size, BITS_PER_UNIT, 1);
108 1.1 mrg }
109 1.1 mrg
110 1.1 mrg
111 1.1 mrg /* Output a value of a given size in target byte order. */
112 1.1 mrg
113 1.1 mrg void
114 1.1 mrg dw2_asm_output_data_raw (int size, unsigned HOST_WIDE_INT value)
115 1.1 mrg {
116 1.1 mrg unsigned char bytes[8];
117 1.1 mrg int i;
118 1.1 mrg
119 1.1 mrg for (i = 0; i < 8; ++i)
120 1.1 mrg {
121 1.1 mrg bytes[i] = value & 0xff;
122 1.1 mrg value >>= 8;
123 1.1 mrg }
124 1.1 mrg
125 1.1 mrg if (BYTES_BIG_ENDIAN)
126 1.1 mrg {
127 1.1 mrg for (i = size - 1; i > 0; --i)
128 1.1 mrg fprintf (asm_out_file, "%#x,", bytes[i]);
129 1.1 mrg fprintf (asm_out_file, "%#x", bytes[0]);
130 1.1 mrg }
131 1.1 mrg else
132 1.1 mrg {
133 1.1 mrg for (i = 0; i < size - 1; ++i)
134 1.1 mrg fprintf (asm_out_file, "%#x,", bytes[i]);
135 1.1 mrg fprintf (asm_out_file, "%#x", bytes[i]);
136 1.1 mrg }
137 1.1 mrg }
138 1.1 mrg
139 1.1 mrg /* Output an immediate constant in a given SIZE in bytes. */
140 1.1 mrg
141 1.1 mrg void
142 1.1 mrg dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value,
143 1.1 mrg const char *comment, ...)
144 1.1 mrg {
145 1.1 mrg va_list ap;
146 1.1 mrg const char *op = integer_asm_op (size, FALSE);
147 1.1 mrg
148 1.1 mrg va_start (ap, comment);
149 1.1 mrg
150 1.1 mrg if (size * 8 < HOST_BITS_PER_WIDE_INT)
151 1.1 mrg value &= ~(HOST_WIDE_INT_M1U << (size * 8));
152 1.1 mrg
153 1.1 mrg if (op)
154 1.1 mrg {
155 1.1 mrg fputs (op, asm_out_file);
156 1.1 mrg fprint_whex (asm_out_file, value);
157 1.1 mrg }
158 1.1 mrg else
159 1.1 mrg assemble_integer (GEN_INT (value), size, BITS_PER_UNIT, 1);
160 1.1 mrg
161 1.1 mrg if (flag_debug_asm && comment)
162 1.1 mrg {
163 1.1 mrg fputs ("\t" ASM_COMMENT_START " ", asm_out_file);
164 1.1 mrg vfprintf (asm_out_file, comment, ap);
165 1.1 mrg }
166 1.1 mrg putc ('\n', asm_out_file);
167 1.1 mrg
168 1.1 mrg va_end (ap);
169 1.1 mrg }
170 1.1 mrg
171 1.1 mrg /* Output the difference between two symbols in a given size. */
172 1.1 mrg /* ??? There appear to be assemblers that do not like such
173 1.1 mrg subtraction, but do support ASM_SET_OP. It's unfortunately
174 1.1 mrg impossible to do here, since the ASM_SET_OP for the difference
175 1.1 mrg symbol must appear after both symbols are defined. */
176 1.1 mrg
177 1.1 mrg void
178 1.1 mrg dw2_asm_output_delta (int size, const char *lab1, const char *lab2,
179 1.1 mrg const char *comment, ...)
180 1.1 mrg {
181 1.1 mrg va_list ap;
182 1.1 mrg
183 1.1 mrg va_start (ap, comment);
184 1.1 mrg
185 1.1 mrg #ifdef ASM_OUTPUT_DWARF_DELTA
186 1.1 mrg ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
187 1.1 mrg #else
188 1.1 mrg dw2_assemble_integer (size,
189 1.1 mrg gen_rtx_MINUS (Pmode,
190 1.1 mrg gen_rtx_SYMBOL_REF (Pmode, lab1),
191 1.1 mrg gen_rtx_SYMBOL_REF (Pmode, lab2)));
192 1.1 mrg #endif
193 1.1 mrg if (flag_debug_asm && comment)
194 1.1 mrg {
195 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
196 1.1 mrg vfprintf (asm_out_file, comment, ap);
197 1.1 mrg }
198 1.1 mrg fputc ('\n', asm_out_file);
199 1.1 mrg
200 1.1 mrg va_end (ap);
201 1.1 mrg }
202 1.1 mrg
203 1.1 mrg #ifdef ASM_OUTPUT_DWARF_VMS_DELTA
204 1.1 mrg /* Output the difference between two symbols in instruction units
205 1.1 mrg in a given size. */
206 1.1 mrg
207 1.1 mrg void
208 1.1 mrg dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED,
209 1.1 mrg const char *lab1, const char *lab2,
210 1.1 mrg const char *comment, ...)
211 1.1 mrg {
212 1.1 mrg va_list ap;
213 1.1 mrg
214 1.1 mrg va_start (ap, comment);
215 1.1 mrg
216 1.1 mrg ASM_OUTPUT_DWARF_VMS_DELTA (asm_out_file, size, lab1, lab2);
217 1.1 mrg if (flag_debug_asm && comment)
218 1.1 mrg {
219 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
220 1.1 mrg vfprintf (asm_out_file, comment, ap);
221 1.1 mrg }
222 1.1 mrg fputc ('\n', asm_out_file);
223 1.1 mrg
224 1.1 mrg va_end (ap);
225 1.1 mrg }
226 1.1 mrg #endif
227 1.1 mrg
228 1.1 mrg /* Output a section-relative reference to a LABEL, which was placed in
229 1.1 mrg BASE. In general this can only be done for debugging symbols.
230 1.1 mrg E.g. on most targets with the GNU linker, this is accomplished with
231 1.1 mrg a direct reference and the knowledge that the debugging section
232 1.1 mrg will be placed at VMA 0. Some targets have special relocations for
233 1.1 mrg this that we must use. */
234 1.1 mrg
235 1.1 mrg void
236 1.1 mrg dw2_asm_output_offset (int size, const char *label,
237 1.1 mrg section *base ATTRIBUTE_UNUSED,
238 1.1 mrg const char *comment, ...)
239 1.1 mrg {
240 1.1 mrg va_list ap;
241 1.1 mrg
242 1.1 mrg va_start (ap, comment);
243 1.1 mrg
244 1.1 mrg #ifdef ASM_OUTPUT_DWARF_OFFSET
245 1.1 mrg ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, 0, base);
246 1.1 mrg #else
247 1.1 mrg dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
248 1.1 mrg #endif
249 1.1 mrg
250 1.1 mrg if (flag_debug_asm && comment)
251 1.1 mrg {
252 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
253 1.1 mrg vfprintf (asm_out_file, comment, ap);
254 1.1 mrg }
255 1.1 mrg fputc ('\n', asm_out_file);
256 1.1 mrg
257 1.1 mrg va_end (ap);
258 1.1 mrg }
259 1.1 mrg
260 1.1 mrg void
261 1.1 mrg dw2_asm_output_offset (int size, const char *label, HOST_WIDE_INT offset,
262 1.1 mrg section *base ATTRIBUTE_UNUSED,
263 1.1 mrg const char *comment, ...)
264 1.1 mrg {
265 1.1 mrg va_list ap;
266 1.1 mrg
267 1.1 mrg va_start (ap, comment);
268 1.1 mrg
269 1.1 mrg #ifdef ASM_OUTPUT_DWARF_OFFSET
270 1.1 mrg ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, offset, base);
271 1.1 mrg #else
272 1.1 mrg dw2_assemble_integer (size, gen_rtx_PLUS (Pmode,
273 1.1 mrg gen_rtx_SYMBOL_REF (Pmode, label),
274 1.1 mrg gen_int_mode (offset, Pmode)));
275 1.1 mrg #endif
276 1.1 mrg
277 1.1 mrg if (flag_debug_asm && comment)
278 1.1 mrg {
279 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
280 1.1 mrg vfprintf (asm_out_file, comment, ap);
281 1.1 mrg }
282 1.1 mrg fputc ('\n', asm_out_file);
283 1.1 mrg
284 1.1 mrg va_end (ap);
285 1.1 mrg }
286 1.1 mrg
287 1.1 mrg #if 0
288 1.1 mrg
289 1.1 mrg /* Output a self-relative reference to a label, possibly in a
290 1.1 mrg different section or object file. */
291 1.1 mrg
292 1.1 mrg void
293 1.1 mrg dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED,
294 1.1 mrg const char *label ATTRIBUTE_UNUSED,
295 1.1 mrg const char *comment, ...)
296 1.1 mrg {
297 1.1 mrg va_list ap;
298 1.1 mrg
299 1.1 mrg va_start (ap, comment);
300 1.1 mrg
301 1.1 mrg #ifdef ASM_OUTPUT_DWARF_PCREL
302 1.1 mrg ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
303 1.1 mrg #else
304 1.1 mrg dw2_assemble_integer (size,
305 1.1 mrg gen_rtx_MINUS (Pmode,
306 1.1 mrg gen_rtx_SYMBOL_REF (Pmode, label),
307 1.1 mrg pc_rtx));
308 1.1 mrg #endif
309 1.1 mrg
310 1.1 mrg if (flag_debug_asm && comment)
311 1.1 mrg {
312 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
313 1.1 mrg vfprintf (asm_out_file, comment, ap);
314 1.1 mrg }
315 1.1 mrg fputc ('\n', asm_out_file);
316 1.1 mrg
317 1.1 mrg va_end (ap);
318 1.1 mrg }
319 1.1 mrg #endif /* 0 */
320 1.1 mrg
321 1.1 mrg /* Output an absolute reference to a label. */
322 1.1 mrg
323 1.1 mrg void
324 1.1 mrg dw2_asm_output_addr (int size, const char *label,
325 1.1 mrg const char *comment, ...)
326 1.1 mrg {
327 1.1 mrg va_list ap;
328 1.1 mrg
329 1.1 mrg va_start (ap, comment);
330 1.1 mrg
331 1.1 mrg dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
332 1.1 mrg
333 1.1 mrg if (flag_debug_asm && comment)
334 1.1 mrg {
335 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
336 1.1 mrg vfprintf (asm_out_file, comment, ap);
337 1.1 mrg }
338 1.1 mrg fputc ('\n', asm_out_file);
339 1.1 mrg
340 1.1 mrg va_end (ap);
341 1.1 mrg }
342 1.1 mrg
343 1.1 mrg /* Similar, but use an RTX expression instead of a text label. */
344 1.1 mrg
345 1.1 mrg void
346 1.1 mrg dw2_asm_output_addr_rtx (int size, rtx addr,
347 1.1 mrg const char *comment, ...)
348 1.1 mrg {
349 1.1 mrg va_list ap;
350 1.1 mrg
351 1.1 mrg va_start (ap, comment);
352 1.1 mrg
353 1.1 mrg dw2_assemble_integer (size, addr);
354 1.1 mrg
355 1.1 mrg if (flag_debug_asm && comment)
356 1.1 mrg {
357 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
358 1.1 mrg vfprintf (asm_out_file, comment, ap);
359 1.1 mrg }
360 1.1 mrg fputc ('\n', asm_out_file);
361 1.1 mrg
362 1.1 mrg va_end (ap);
363 1.1 mrg }
364 1.1 mrg
365 1.1 mrg /* Output the first ORIG_LEN characters of STR as a string.
366 1.1 mrg If ORIG_LEN is equal to -1, ignore this parameter and output
367 1.1 mrg the entire STR instead.
368 1.1 mrg If COMMENT is not NULL and comments in the debug information
369 1.1 mrg have been requested by the user, append the given COMMENT
370 1.1 mrg to the generated output. */
371 1.1 mrg
372 1.1 mrg void
373 1.1 mrg dw2_asm_output_nstring (const char *str, size_t orig_len,
374 1.1 mrg const char *comment, ...)
375 1.1 mrg {
376 1.1 mrg size_t i, len;
377 1.1 mrg va_list ap;
378 1.1 mrg
379 1.1 mrg va_start (ap, comment);
380 1.1 mrg
381 1.1 mrg len = orig_len;
382 1.1 mrg
383 1.1 mrg if (len == (size_t) -1)
384 1.1 mrg len = strlen (str);
385 1.1 mrg
386 1.1 mrg if (flag_debug_asm && comment)
387 1.1 mrg {
388 1.1 mrg if (XCOFF_DEBUGGING_INFO)
389 1.1 mrg fputs ("\t.byte \"", asm_out_file);
390 1.1 mrg else
391 1.1 mrg fputs ("\t.ascii \"", asm_out_file);
392 1.1 mrg
393 1.1 mrg for (i = 0; i < len; i++)
394 1.1 mrg {
395 1.1 mrg int c = str[i];
396 1.1 mrg if (c == '\"')
397 1.1 mrg fputc (XCOFF_DEBUGGING_INFO ? '\"' : '\\', asm_out_file);
398 1.1 mrg else if (c == '\\')
399 1.1 mrg fputc ('\\', asm_out_file);
400 1.1 mrg if (ISPRINT (c))
401 1.1 mrg fputc (c, asm_out_file);
402 1.1 mrg else
403 1.1 mrg fprintf (asm_out_file, "\\%o", c);
404 1.1 mrg }
405 1.1 mrg fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
406 1.1 mrg vfprintf (asm_out_file, comment, ap);
407 1.1 mrg fputc ('\n', asm_out_file);
408 1.1 mrg }
409 1.1 mrg else
410 1.1 mrg {
411 1.1 mrg /* If an explicit length was given, we can't assume there
412 1.1 mrg is a null termination in the string buffer. */
413 1.1 mrg if (orig_len == (size_t) -1)
414 1.1 mrg len += 1;
415 1.1 mrg ASM_OUTPUT_ASCII (asm_out_file, str, len);
416 1.1 mrg if (orig_len != (size_t) -1)
417 1.1 mrg assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
418 1.1 mrg }
419 1.1 mrg
420 1.1 mrg va_end (ap);
421 1.1 mrg }
422 1.1 mrg
423 1.1 mrg
425 1.1 mrg /* Return the size of an unsigned LEB128 quantity. */
426 1.1 mrg
427 1.1 mrg int
428 1.1 mrg size_of_uleb128 (unsigned HOST_WIDE_INT value)
429 1.1 mrg {
430 1.1 mrg int size = 0;
431 1.1 mrg
432 1.1 mrg do
433 1.1 mrg {
434 1.1 mrg value >>= 7;
435 1.1 mrg size += 1;
436 1.1 mrg }
437 1.1 mrg while (value != 0);
438 1.1 mrg
439 1.1 mrg return size;
440 1.1 mrg }
441 1.1 mrg
442 1.1 mrg /* Return the size of a signed LEB128 quantity. */
443 1.1 mrg
444 1.1 mrg int
445 1.1 mrg size_of_sleb128 (HOST_WIDE_INT value)
446 1.1 mrg {
447 1.1 mrg int size = 0, byte;
448 1.1 mrg
449 1.1 mrg do
450 1.1 mrg {
451 1.1 mrg byte = (value & 0x7f);
452 1.1 mrg value >>= 7;
453 1.1 mrg size += 1;
454 1.1 mrg }
455 1.1 mrg while (!((value == 0 && (byte & 0x40) == 0)
456 1.1 mrg || (value == -1 && (byte & 0x40) != 0)));
457 1.1 mrg
458 1.1 mrg return size;
459 1.1 mrg }
460 1.1 mrg
461 1.1 mrg /* Given an encoding, return the number of bytes the format occupies.
462 1.1 mrg This is only defined for fixed-size encodings, and so does not
463 1.1 mrg include leb128. */
464 1.1 mrg
465 1.1 mrg int
466 1.1 mrg size_of_encoded_value (int encoding)
467 1.1 mrg {
468 1.1 mrg if (encoding == DW_EH_PE_omit)
469 1.1 mrg return 0;
470 1.1 mrg
471 1.1 mrg switch (encoding & 0x07)
472 1.1 mrg {
473 1.1 mrg case DW_EH_PE_absptr:
474 1.1 mrg return POINTER_SIZE_UNITS;
475 1.1 mrg case DW_EH_PE_udata2:
476 1.1 mrg return 2;
477 1.1 mrg case DW_EH_PE_udata4:
478 1.1 mrg return 4;
479 1.1 mrg case DW_EH_PE_udata8:
480 1.1 mrg return 8;
481 1.1 mrg default:
482 1.1 mrg gcc_unreachable ();
483 1.1 mrg }
484 1.1 mrg }
485 1.1 mrg
486 1.1 mrg /* Yield a name for a given pointer encoding. */
487 1.1 mrg
488 1.1 mrg const char *
489 1.1 mrg eh_data_format_name (int format)
490 1.1 mrg {
491 1.1 mrg #if HAVE_DESIGNATED_INITIALIZERS
492 1.1 mrg #define S(p, v) [p] = v,
493 1.1 mrg #else
494 1.1 mrg #define S(p, v) case p: return v;
495 1.1 mrg #endif
496 1.1 mrg
497 1.1 mrg #if HAVE_DESIGNATED_INITIALIZERS
498 1.1 mrg __extension__ static const char * const format_names[256] = {
499 1.1 mrg #else
500 1.1 mrg switch (format) {
501 1.1 mrg #endif
502 1.1 mrg
503 1.1 mrg S(DW_EH_PE_absptr, "absolute")
504 1.1 mrg S(DW_EH_PE_omit, "omit")
505 1.1 mrg S(DW_EH_PE_aligned, "aligned absolute")
506 1.1 mrg
507 1.1 mrg S(DW_EH_PE_uleb128, "uleb128")
508 1.1 mrg S(DW_EH_PE_udata2, "udata2")
509 1.1 mrg S(DW_EH_PE_udata4, "udata4")
510 1.1 mrg S(DW_EH_PE_udata8, "udata8")
511 1.1 mrg S(DW_EH_PE_sleb128, "sleb128")
512 1.1 mrg S(DW_EH_PE_sdata2, "sdata2")
513 1.1 mrg S(DW_EH_PE_sdata4, "sdata4")
514 1.1 mrg S(DW_EH_PE_sdata8, "sdata8")
515 1.1 mrg
516 1.1 mrg S(DW_EH_PE_absptr | DW_EH_PE_pcrel, "pcrel")
517 1.1 mrg S(DW_EH_PE_uleb128 | DW_EH_PE_pcrel, "pcrel uleb128")
518 1.1 mrg S(DW_EH_PE_udata2 | DW_EH_PE_pcrel, "pcrel udata2")
519 1.1 mrg S(DW_EH_PE_udata4 | DW_EH_PE_pcrel, "pcrel udata4")
520 1.1 mrg S(DW_EH_PE_udata8 | DW_EH_PE_pcrel, "pcrel udata8")
521 1.1 mrg S(DW_EH_PE_sleb128 | DW_EH_PE_pcrel, "pcrel sleb128")
522 1.1 mrg S(DW_EH_PE_sdata2 | DW_EH_PE_pcrel, "pcrel sdata2")
523 1.1 mrg S(DW_EH_PE_sdata4 | DW_EH_PE_pcrel, "pcrel sdata4")
524 1.1 mrg S(DW_EH_PE_sdata8 | DW_EH_PE_pcrel, "pcrel sdata8")
525 1.1 mrg
526 1.1 mrg S(DW_EH_PE_absptr | DW_EH_PE_textrel, "textrel")
527 1.1 mrg S(DW_EH_PE_uleb128 | DW_EH_PE_textrel, "textrel uleb128")
528 1.1 mrg S(DW_EH_PE_udata2 | DW_EH_PE_textrel, "textrel udata2")
529 1.1 mrg S(DW_EH_PE_udata4 | DW_EH_PE_textrel, "textrel udata4")
530 1.1 mrg S(DW_EH_PE_udata8 | DW_EH_PE_textrel, "textrel udata8")
531 1.1 mrg S(DW_EH_PE_sleb128 | DW_EH_PE_textrel, "textrel sleb128")
532 1.1 mrg S(DW_EH_PE_sdata2 | DW_EH_PE_textrel, "textrel sdata2")
533 1.1 mrg S(DW_EH_PE_sdata4 | DW_EH_PE_textrel, "textrel sdata4")
534 1.1 mrg S(DW_EH_PE_sdata8 | DW_EH_PE_textrel, "textrel sdata8")
535 1.1 mrg
536 1.1 mrg S(DW_EH_PE_absptr | DW_EH_PE_datarel, "datarel")
537 1.1 mrg S(DW_EH_PE_uleb128 | DW_EH_PE_datarel, "datarel uleb128")
538 1.1 mrg S(DW_EH_PE_udata2 | DW_EH_PE_datarel, "datarel udata2")
539 1.1 mrg S(DW_EH_PE_udata4 | DW_EH_PE_datarel, "datarel udata4")
540 1.1 mrg S(DW_EH_PE_udata8 | DW_EH_PE_datarel, "datarel udata8")
541 1.1 mrg S(DW_EH_PE_sleb128 | DW_EH_PE_datarel, "datarel sleb128")
542 1.1 mrg S(DW_EH_PE_sdata2 | DW_EH_PE_datarel, "datarel sdata2")
543 1.1 mrg S(DW_EH_PE_sdata4 | DW_EH_PE_datarel, "datarel sdata4")
544 1.1 mrg S(DW_EH_PE_sdata8 | DW_EH_PE_datarel, "datarel sdata8")
545 1.1 mrg
546 1.1 mrg S(DW_EH_PE_absptr | DW_EH_PE_funcrel, "funcrel")
547 1.1 mrg S(DW_EH_PE_uleb128 | DW_EH_PE_funcrel, "funcrel uleb128")
548 1.1 mrg S(DW_EH_PE_udata2 | DW_EH_PE_funcrel, "funcrel udata2")
549 1.1 mrg S(DW_EH_PE_udata4 | DW_EH_PE_funcrel, "funcrel udata4")
550 1.1 mrg S(DW_EH_PE_udata8 | DW_EH_PE_funcrel, "funcrel udata8")
551 1.1 mrg S(DW_EH_PE_sleb128 | DW_EH_PE_funcrel, "funcrel sleb128")
552 1.1 mrg S(DW_EH_PE_sdata2 | DW_EH_PE_funcrel, "funcrel sdata2")
553 1.1 mrg S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
554 1.1 mrg S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
555 1.1 mrg
556 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_absptr, "indirect absolute")
557 1.1 mrg
558 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
559 1.1 mrg "indirect pcrel")
560 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
561 1.1 mrg "indirect pcrel uleb128")
562 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel,
563 1.1 mrg "indirect pcrel udata2")
564 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel,
565 1.1 mrg "indirect pcrel udata4")
566 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel,
567 1.1 mrg "indirect pcrel udata8")
568 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel,
569 1.1 mrg "indirect pcrel sleb128")
570 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel,
571 1.1 mrg "indirect pcrel sdata2")
572 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel,
573 1.1 mrg "indirect pcrel sdata4")
574 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel,
575 1.1 mrg "indirect pcrel sdata8")
576 1.1 mrg
577 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_textrel,
578 1.1 mrg "indirect textrel")
579 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel,
580 1.1 mrg "indirect textrel uleb128")
581 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel,
582 1.1 mrg "indirect textrel udata2")
583 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel,
584 1.1 mrg "indirect textrel udata4")
585 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel,
586 1.1 mrg "indirect textrel udata8")
587 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel,
588 1.1 mrg "indirect textrel sleb128")
589 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel,
590 1.1 mrg "indirect textrel sdata2")
591 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel,
592 1.1 mrg "indirect textrel sdata4")
593 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel,
594 1.1 mrg "indirect textrel sdata8")
595 1.1 mrg
596 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_datarel,
597 1.1 mrg "indirect datarel")
598 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel,
599 1.1 mrg "indirect datarel uleb128")
600 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel,
601 1.1 mrg "indirect datarel udata2")
602 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel,
603 1.1 mrg "indirect datarel udata4")
604 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel,
605 1.1 mrg "indirect datarel udata8")
606 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel,
607 1.1 mrg "indirect datarel sleb128")
608 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel,
609 1.1 mrg "indirect datarel sdata2")
610 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel,
611 1.1 mrg "indirect datarel sdata4")
612 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel,
613 1.1 mrg "indirect datarel sdata8")
614 1.1 mrg
615 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_funcrel,
616 1.1 mrg "indirect funcrel")
617 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel,
618 1.1 mrg "indirect funcrel uleb128")
619 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel,
620 1.1 mrg "indirect funcrel udata2")
621 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel,
622 1.1 mrg "indirect funcrel udata4")
623 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel,
624 1.1 mrg "indirect funcrel udata8")
625 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel,
626 1.1 mrg "indirect funcrel sleb128")
627 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel,
628 1.1 mrg "indirect funcrel sdata2")
629 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel,
630 1.1 mrg "indirect funcrel sdata4")
631 1.1 mrg S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel,
632 1.1 mrg "indirect funcrel sdata8")
633 1.1 mrg
634 1.1 mrg #if HAVE_DESIGNATED_INITIALIZERS
635 1.1 mrg };
636 1.1 mrg
637 1.1 mrg gcc_assert (format >= 0 && format < 0x100 && format_names[format]);
638 1.1 mrg
639 1.1 mrg return format_names[format];
640 1.1 mrg #else
641 1.1 mrg }
642 1.1 mrg gcc_unreachable ();
643 1.1 mrg #endif
644 1.1 mrg }
645 1.1 mrg
646 1.1 mrg /* Output an unsigned LEB128 quantity, but only the byte values. */
647 1.1 mrg
648 1.1 mrg void
649 1.1 mrg dw2_asm_output_data_uleb128_raw (unsigned HOST_WIDE_INT value)
650 1.1 mrg {
651 1.1 mrg while (1)
652 1.1 mrg {
653 1.1 mrg int byte = (value & 0x7f);
654 1.1 mrg value >>= 7;
655 1.1 mrg if (value != 0)
656 1.1 mrg /* More bytes to follow. */
657 1.1 mrg byte |= 0x80;
658 1.1 mrg
659 1.1 mrg fprintf (asm_out_file, "%#x", byte);
660 1.1 mrg if (value == 0)
661 1.1 mrg break;
662 1.1 mrg fputc (',', asm_out_file);
663 1.1 mrg }
664 1.1 mrg }
665 1.1 mrg
666 1.1 mrg /* Output an unsigned LEB128 quantity. */
667 1.1 mrg
668 1.1 mrg void
669 1.1 mrg dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value,
670 1.1 mrg const char *comment, ...)
671 1.1 mrg {
672 1.1 mrg va_list ap;
673 1.1 mrg
674 1.1 mrg va_start (ap, comment);
675 1.1 mrg
676 1.1 mrg if (HAVE_AS_LEB128)
677 1.1 mrg {
678 1.1 mrg fputs ("\t.uleb128 ", asm_out_file);
679 1.1 mrg fprint_whex (asm_out_file, value);
680 1.1 mrg
681 1.1 mrg if (flag_debug_asm && comment)
682 1.1 mrg {
683 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
684 1.1 mrg vfprintf (asm_out_file, comment, ap);
685 1.1 mrg }
686 1.1 mrg }
687 1.1 mrg else
688 1.1 mrg {
689 1.1 mrg unsigned HOST_WIDE_INT work = value;
690 1.1 mrg const char *byte_op = targetm.asm_out.byte_op;
691 1.1 mrg
692 1.1 mrg if (byte_op)
693 1.1 mrg fputs (byte_op, asm_out_file);
694 1.1 mrg do
695 1.1 mrg {
696 1.1 mrg int byte = (work & 0x7f);
697 1.1 mrg work >>= 7;
698 1.1 mrg if (work != 0)
699 1.1 mrg /* More bytes to follow. */
700 1.1 mrg byte |= 0x80;
701 1.1 mrg
702 1.1 mrg if (byte_op)
703 1.1 mrg {
704 1.1 mrg fprintf (asm_out_file, "%#x", byte);
705 1.1 mrg if (work != 0)
706 1.1 mrg fputc (',', asm_out_file);
707 1.1 mrg }
708 1.1 mrg else
709 1.1 mrg assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
710 1.1 mrg }
711 1.1 mrg while (work != 0);
712 1.1 mrg
713 1.1 mrg if (flag_debug_asm)
714 1.1 mrg {
715 1.1 mrg fprintf (asm_out_file, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX,
716 1.1 mrg ASM_COMMENT_START, value);
717 1.1 mrg if (comment)
718 1.1 mrg {
719 1.1 mrg fputs ("; ", asm_out_file);
720 1.1 mrg vfprintf (asm_out_file, comment, ap);
721 1.1 mrg }
722 1.1 mrg }
723 1.1 mrg }
724 1.1 mrg
725 1.1 mrg putc ('\n', asm_out_file);
726 1.1 mrg
727 1.1 mrg va_end (ap);
728 1.1 mrg }
729 1.1 mrg
730 1.1 mrg /* Output an signed LEB128 quantity, but only the byte values. */
731 1.1 mrg
732 1.1 mrg void
733 1.1 mrg dw2_asm_output_data_sleb128_raw (HOST_WIDE_INT value)
734 1.1 mrg {
735 1.1 mrg int byte, more;
736 1.1 mrg
737 1.1 mrg while (1)
738 1.1 mrg {
739 1.1 mrg byte = (value & 0x7f);
740 1.1 mrg value >>= 7;
741 1.1 mrg more = !((value == 0 && (byte & 0x40) == 0)
742 1.1 mrg || (value == -1 && (byte & 0x40) != 0));
743 1.1 mrg if (more)
744 1.1 mrg byte |= 0x80;
745 1.1 mrg
746 1.1 mrg fprintf (asm_out_file, "%#x", byte);
747 1.1 mrg if (!more)
748 1.1 mrg break;
749 1.1 mrg fputc (',', asm_out_file);
750 1.1 mrg }
751 1.1 mrg }
752 1.1 mrg
753 1.1 mrg /* Output a signed LEB128 quantity. */
754 1.1 mrg
755 1.1 mrg void
756 1.1 mrg dw2_asm_output_data_sleb128 (HOST_WIDE_INT value,
757 1.1 mrg const char *comment, ...)
758 1.1 mrg {
759 1.1 mrg va_list ap;
760 1.1 mrg
761 1.1 mrg va_start (ap, comment);
762 1.1 mrg
763 1.1 mrg if (HAVE_AS_LEB128)
764 1.1 mrg {
765 1.1 mrg fprintf (asm_out_file, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC, value);
766 1.1 mrg
767 1.1 mrg if (flag_debug_asm && comment)
768 1.1 mrg {
769 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
770 1.1 mrg vfprintf (asm_out_file, comment, ap);
771 1.1 mrg }
772 1.1 mrg }
773 1.1 mrg else
774 1.1 mrg {
775 1.1 mrg HOST_WIDE_INT work = value;
776 1.1 mrg int more, byte;
777 1.1 mrg const char *byte_op = targetm.asm_out.byte_op;
778 1.1 mrg
779 1.1 mrg if (byte_op)
780 1.1 mrg fputs (byte_op, asm_out_file);
781 1.1 mrg do
782 1.1 mrg {
783 1.1 mrg byte = (work & 0x7f);
784 1.1 mrg /* arithmetic shift */
785 1.1 mrg work >>= 7;
786 1.1 mrg more = !((work == 0 && (byte & 0x40) == 0)
787 1.1 mrg || (work == -1 && (byte & 0x40) != 0));
788 1.1 mrg if (more)
789 1.1 mrg byte |= 0x80;
790 1.1 mrg
791 1.1 mrg if (byte_op)
792 1.1 mrg {
793 1.1 mrg fprintf (asm_out_file, "%#x", byte);
794 1.1 mrg if (more)
795 1.1 mrg fputc (',', asm_out_file);
796 1.1 mrg }
797 1.1 mrg else
798 1.1 mrg assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
799 1.1 mrg }
800 1.1 mrg while (more);
801 1.1 mrg
802 1.1 mrg if (flag_debug_asm)
803 1.1 mrg {
804 1.1 mrg fprintf (asm_out_file, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC,
805 1.1 mrg ASM_COMMENT_START, value);
806 1.1 mrg if (comment)
807 1.1 mrg {
808 1.1 mrg fputs ("; ", asm_out_file);
809 1.1 mrg vfprintf (asm_out_file, comment, ap);
810 1.1 mrg }
811 1.1 mrg }
812 1.1 mrg }
813 1.1 mrg
814 1.1 mrg fputc ('\n', asm_out_file);
815 1.1 mrg
816 1.1 mrg va_end (ap);
817 1.1 mrg }
818 1.1 mrg
819 1.1 mrg /* Output symbol LAB1 as an unsigned LEB128 quantity. LAB1 should be
820 1.1 mrg an assembler-computed constant, e.g. a view number, because we
821 1.1 mrg can't have relocations in LEB128 quantities. */
822 1.1 mrg
823 1.1 mrg void
824 1.1 mrg dw2_asm_output_symname_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
825 1.1 mrg const char *comment, ...)
826 1.1 mrg {
827 1.1 mrg va_list ap;
828 1.1 mrg
829 1.1 mrg va_start (ap, comment);
830 1.1 mrg
831 1.1 mrg #ifdef HAVE_AS_LEB128
832 1.1 mrg fputs ("\t.uleb128 ", asm_out_file);
833 1.1 mrg assemble_name (asm_out_file, lab1);
834 1.1 mrg #else
835 1.1 mrg gcc_unreachable ();
836 1.1 mrg #endif
837 1.1 mrg
838 1.1 mrg if (flag_debug_asm && comment)
839 1.1 mrg {
840 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
841 1.1 mrg vfprintf (asm_out_file, comment, ap);
842 1.1 mrg }
843 1.1 mrg fputc ('\n', asm_out_file);
844 1.1 mrg
845 1.1 mrg va_end (ap);
846 1.1 mrg }
847 1.1 mrg
848 1.1 mrg void
849 1.1 mrg dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
850 1.1 mrg const char *lab2 ATTRIBUTE_UNUSED,
851 1.1 mrg const char *comment, ...)
852 1.1 mrg {
853 1.1 mrg va_list ap;
854 1.1 mrg
855 1.1 mrg va_start (ap, comment);
856 1.1 mrg
857 1.1 mrg gcc_assert (HAVE_AS_LEB128);
858 1.1 mrg
859 1.1 mrg fputs ("\t.uleb128 ", asm_out_file);
860 1.1 mrg assemble_name (asm_out_file, lab1);
861 1.1 mrg putc ('-', asm_out_file);
862 1.1 mrg /* dwarf2out.cc might give us a label expression (e.g. .LVL548-1)
863 1.1 mrg as second argument. If so, make it a subexpression, to make
864 1.1 mrg sure the substraction is done in the right order. */
865 1.1 mrg if (strchr (lab2, '-') != NULL)
866 1.1 mrg {
867 1.1 mrg putc ('(', asm_out_file);
868 1.1 mrg assemble_name (asm_out_file, lab2);
869 1.1 mrg putc (')', asm_out_file);
870 1.1 mrg }
871 1.1 mrg else
872 1.1 mrg assemble_name (asm_out_file, lab2);
873 1.1 mrg
874 1.1 mrg if (flag_debug_asm && comment)
875 1.1 mrg {
876 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
877 1.1 mrg vfprintf (asm_out_file, comment, ap);
878 1.1 mrg }
879 1.1 mrg fputc ('\n', asm_out_file);
880 1.1 mrg
881 1.1 mrg va_end (ap);
882 1.1 mrg }
883 1.1 mrg
884 1.1 mrg #if 0
885 1.1 mrg
886 1.1 mrg void
887 1.1 mrg dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED,
888 1.1 mrg const char *lab2 ATTRIBUTE_UNUSED,
889 1.1 mrg const char *comment, ...)
890 1.1 mrg {
891 1.1 mrg va_list ap;
892 1.1 mrg
893 1.1 mrg va_start (ap, comment);
894 1.1 mrg
895 1.1 mrg gcc_assert (HAVE_AS_LEB128);
896 1.1 mrg
897 1.1 mrg fputs ("\t.sleb128 ", asm_out_file);
898 1.1 mrg assemble_name (asm_out_file, lab1);
899 1.1 mrg putc ('-', asm_out_file);
900 1.1 mrg assemble_name (asm_out_file, lab2);
901 1.1 mrg
902 1.1 mrg if (flag_debug_asm && comment)
903 1.1 mrg {
904 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
905 1.1 mrg vfprintf (asm_out_file, comment, ap);
906 1.1 mrg }
907 1.1 mrg fputc ('\n', asm_out_file);
908 1.1 mrg
909 1.1 mrg va_end (ap);
910 1.1 mrg }
911 1.1 mrg #endif /* 0 */
912 1.1 mrg
913 1.1 mrg static GTY(()) hash_map<const char *, tree> *indirect_pool;
915 1.1 mrg
916 1.1 mrg static GTY(()) int dw2_const_labelno;
917 1.1 mrg
918 1.1 mrg #if defined(HAVE_GAS_HIDDEN)
919 1.1 mrg # define USE_LINKONCE_INDIRECT (SUPPORTS_ONE_ONLY && !XCOFF_DEBUGGING_INFO)
920 1.1 mrg #else
921 1.1 mrg # define USE_LINKONCE_INDIRECT 0
922 1.1 mrg #endif
923 1.1 mrg
924 1.1 mrg /* Compare two std::pair<const char *, tree> by their first element.
925 1.1 mrg Returns <0, 0, or
926 1.1 mrg >0 to indicate whether K1 is less than, equal to, or greater than
927 1.1 mrg K2, respectively. */
928 1.1 mrg
929 1.1 mrg static int
930 1.1 mrg compare_strings (const void *a, const void *b)
931 1.1 mrg {
932 1.1 mrg const char *s1 = ((const std::pair<const char *, tree> *) a)->first;
933 1.1 mrg const char *s2 = ((const std::pair<const char *, tree> *) b)->first;
934 1.1 mrg int ret;
935 1.1 mrg
936 1.1 mrg if (s1 == s2)
937 1.1 mrg return 0;
938 1.1 mrg
939 1.1 mrg ret = strcmp (s1, s2);
940 1.1 mrg
941 1.1 mrg /* The strings are always those from IDENTIFIER_NODEs, and,
942 1.1 mrg therefore, we should never have two copies of the same
943 1.1 mrg string. */
944 1.1 mrg gcc_assert (ret);
945 1.1 mrg
946 1.1 mrg return ret;
947 1.1 mrg }
948 1.1 mrg
949 1.1 mrg /* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
950 1.1 mrg memory. Differs from force_const_mem in that a single pool is used for
951 1.1 mrg the entire unit of translation, and the memory is not guaranteed to be
952 1.1 mrg "near" the function in any interesting sense. IS_PUBLIC controls whether
953 1.1 mrg the symbol can be shared across the entire application (or DSO). */
954 1.1 mrg
955 1.1 mrg rtx
956 1.1 mrg dw2_force_const_mem (rtx x, bool is_public)
957 1.1 mrg {
958 1.1 mrg const char *key;
959 1.1 mrg tree decl_id;
960 1.1 mrg
961 1.1 mrg if (! indirect_pool)
962 1.1 mrg indirect_pool = hash_map<const char *, tree>::create_ggc (64);
963 1.1 mrg
964 1.1 mrg gcc_assert (GET_CODE (x) == SYMBOL_REF);
965 1.1 mrg
966 1.1 mrg key = XSTR (x, 0);
967 1.1 mrg tree *slot = indirect_pool->get (key);
968 1.1 mrg if (slot)
969 1.1 mrg decl_id = *slot;
970 1.1 mrg else
971 1.1 mrg {
972 1.1 mrg tree id;
973 1.1 mrg const char *str = targetm.strip_name_encoding (key);
974 1.1 mrg
975 1.1 mrg if (is_public && USE_LINKONCE_INDIRECT)
976 1.1 mrg {
977 1.1 mrg char *ref_name = XALLOCAVEC (char, strlen (str) + sizeof "DW.ref.");
978 1.1 mrg
979 1.1 mrg sprintf (ref_name, "DW.ref.%s", str);
980 1.1 mrg gcc_assert (!maybe_get_identifier (ref_name));
981 1.1 mrg decl_id = get_identifier (ref_name);
982 1.1 mrg TREE_PUBLIC (decl_id) = 1;
983 1.1 mrg }
984 1.1 mrg else
985 1.1 mrg {
986 1.1 mrg char label[32];
987 1.1 mrg
988 1.1 mrg ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno);
989 1.1 mrg ++dw2_const_labelno;
990 1.1 mrg gcc_assert (!maybe_get_identifier (label));
991 1.1 mrg decl_id = get_identifier (label);
992 1.1 mrg }
993 1.1 mrg
994 1.1 mrg id = maybe_get_identifier (str);
995 1.1 mrg if (id)
996 1.1 mrg TREE_SYMBOL_REFERENCED (id) = 1;
997 1.1 mrg
998 1.1 mrg indirect_pool->put (key, decl_id);
999 1.1 mrg }
1000 1.1 mrg
1001 1.1 mrg return gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (decl_id));
1002 1.1 mrg }
1003 1.1 mrg
1004 1.1 mrg /* A helper function for dw2_output_indirect_constants. Emit one queued
1005 1.1 mrg constant to memory. */
1006 1.1 mrg
1007 1.1 mrg static int
1008 1.1 mrg dw2_output_indirect_constant_1 (const char *sym, tree id)
1009 1.1 mrg {
1010 1.1 mrg rtx sym_ref;
1011 1.1 mrg tree decl;
1012 1.1 mrg
1013 1.1 mrg decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, ptr_type_node);
1014 1.1 mrg SET_DECL_ASSEMBLER_NAME (decl, id);
1015 1.1 mrg DECL_ARTIFICIAL (decl) = 1;
1016 1.1 mrg DECL_IGNORED_P (decl) = 1;
1017 1.1 mrg DECL_INITIAL (decl) = build_fold_addr_expr (decl);
1018 1.1 mrg TREE_READONLY (decl) = 1;
1019 1.1 mrg TREE_STATIC (decl) = 1;
1020 1.1 mrg
1021 1.1 mrg if (TREE_PUBLIC (id))
1022 1.1 mrg {
1023 1.1 mrg TREE_PUBLIC (decl) = 1;
1024 1.1 mrg make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
1025 1.1 mrg if (USE_LINKONCE_INDIRECT)
1026 1.1 mrg DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
1027 1.1 mrg }
1028 1.1 mrg
1029 1.1 mrg sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
1030 1.1 mrg /* Disable ASan for decl because redzones cause ABI breakage between GCC and
1031 1.1 mrg libstdc++ for `.LDFCM*' variables. See PR 78651 for details. */
1032 1.1 mrg unsigned int save_flag_sanitize = flag_sanitize;
1033 1.1 mrg flag_sanitize &= ~(SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS
1034 1.1 mrg | SANITIZE_KERNEL_ADDRESS);
1035 1.1 mrg /* And also temporarily disable -fsection-anchors. These indirect constants
1036 1.1 mrg are never referenced from code, so it doesn't make any sense to aggregate
1037 1.1 mrg them in blocks. */
1038 1.1 mrg int save_flag_section_anchors = flag_section_anchors;
1039 1.1 mrg flag_section_anchors = 0;
1040 1.1 mrg assemble_variable (decl, 1, 1, 1);
1041 1.1 mrg flag_section_anchors = save_flag_section_anchors;
1042 1.1 mrg flag_sanitize = save_flag_sanitize;
1043 1.1 mrg assemble_integer (sym_ref, POINTER_SIZE_UNITS, POINTER_SIZE, 1);
1044 1.1 mrg /* The following is a hack recognized by use_blocks_for_decl_p to disable
1045 1.1 mrg section anchor handling of the decl. */
1046 1.1 mrg DECL_INITIAL (decl) = decl;
1047 1.1 mrg
1048 1.1 mrg return 0;
1049 1.1 mrg }
1050 1.1 mrg
1051 1.1 mrg /* Emit the constants queued through dw2_force_const_mem. */
1052 1.1 mrg
1053 1.1 mrg void
1054 1.1 mrg dw2_output_indirect_constants (void)
1055 1.1 mrg {
1056 1.1 mrg if (!indirect_pool)
1057 1.1 mrg return;
1058 1.1 mrg
1059 1.1 mrg auto_vec<std::pair<const char *, tree> > temp (indirect_pool->elements ());
1060 1.1 mrg for (hash_map<const char *, tree>::iterator iter = indirect_pool->begin ();
1061 1.1 mrg iter != indirect_pool->end (); ++iter)
1062 1.1 mrg temp.quick_push (*iter);
1063 1.1 mrg
1064 1.1 mrg temp.qsort (compare_strings);
1065 1.1 mrg
1066 1.1 mrg for (unsigned int i = 0; i < temp.length (); i++)
1067 1.1 mrg dw2_output_indirect_constant_1 (temp[i].first, temp[i].second);
1068 1.1 mrg }
1069 1.1 mrg
1070 1.1 mrg /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.
1071 1.1 mrg If PUBLIC is set and the encoding is DW_EH_PE_indirect, the indirect
1072 1.1 mrg reference is shared across the entire application (or DSO). */
1073 1.1 mrg
1074 1.1 mrg void
1075 1.1 mrg dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool is_public,
1076 1.1 mrg const char *comment, ...)
1077 1.1 mrg {
1078 1.1 mrg int size;
1079 1.1 mrg va_list ap;
1080 1.1 mrg
1081 1.1 mrg va_start (ap, comment);
1082 1.1 mrg
1083 1.1 mrg size = size_of_encoded_value (encoding);
1084 1.1 mrg
1085 1.1 mrg if (encoding == DW_EH_PE_aligned)
1086 1.1 mrg {
1087 1.1 mrg assemble_align (POINTER_SIZE);
1088 1.1 mrg assemble_integer (addr, size, POINTER_SIZE, 1);
1089 1.1 mrg va_end (ap);
1090 1.1 mrg return;
1091 1.1 mrg }
1092 1.1 mrg
1093 1.1 mrg /* NULL is _always_ represented as a plain zero, as is 1 for Ada's
1094 1.1 mrg "all others". */
1095 1.1 mrg if (addr == const0_rtx || addr == const1_rtx)
1096 1.1 mrg assemble_integer (addr, size, BITS_PER_UNIT, 1);
1097 1.1 mrg else
1098 1.1 mrg {
1099 1.1 mrg restart:
1100 1.1 mrg /* Allow the target first crack at emitting this. Some of the
1101 1.1 mrg special relocations require special directives instead of
1102 1.1 mrg just ".4byte" or whatever. */
1103 1.1 mrg #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
1104 1.1 mrg ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file, encoding, size,
1105 1.1 mrg addr, done);
1106 1.1 mrg #endif
1107 1.1 mrg
1108 1.1 mrg /* Indirection is used to get dynamic relocations out of a
1109 1.1 mrg read-only section. */
1110 1.1 mrg if (encoding & DW_EH_PE_indirect)
1111 1.1 mrg {
1112 1.1 mrg /* It is very tempting to use force_const_mem so that we share data
1113 1.1 mrg with the normal constant pool. However, we've already emitted
1114 1.1 mrg the constant pool for this function. Moreover, we'd like to
1115 1.1 mrg share these constants across the entire unit of translation and
1116 1.1 mrg even, if possible, across the entire application (or DSO). */
1117 1.1 mrg addr = dw2_force_const_mem (addr, is_public);
1118 1.1 mrg encoding &= ~DW_EH_PE_indirect;
1119 1.1 mrg goto restart;
1120 1.1 mrg }
1121 1.1 mrg
1122 1.1 mrg switch (encoding & 0xF0)
1123 1.1 mrg {
1124 1.1 mrg case DW_EH_PE_absptr:
1125 1.1 mrg dw2_assemble_integer (size, addr);
1126 1.1 mrg break;
1127 1.1 mrg
1128 1.1 mrg #ifdef ASM_OUTPUT_DWARF_DATAREL
1129 1.1 mrg case DW_EH_PE_datarel:
1130 1.1 mrg gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1131 1.1 mrg ASM_OUTPUT_DWARF_DATAREL (asm_out_file, size, XSTR (addr, 0));
1132 1.1 mrg break;
1133 1.1 mrg #endif
1134 1.1 mrg
1135 1.1 mrg case DW_EH_PE_pcrel:
1136 1.1 mrg gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1137 1.1 mrg #ifdef ASM_OUTPUT_DWARF_PCREL
1138 1.1 mrg ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0));
1139 1.1 mrg #else
1140 1.1 mrg dw2_assemble_integer (size, gen_rtx_MINUS (Pmode, addr, pc_rtx));
1141 1.1 mrg #endif
1142 1.1 mrg break;
1143 1.1 mrg
1144 1.1 mrg default:
1145 1.1 mrg /* Other encodings should have been handled by
1146 1.1 mrg ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX. */
1147 1.1 mrg gcc_unreachable ();
1148 1.1 mrg }
1149 1.1 mrg
1150 1.1 mrg #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
1151 1.1 mrg done:;
1152 1.1 mrg #endif
1153 1.1 mrg }
1154 1.1 mrg
1155 1.1 mrg if (flag_debug_asm && comment)
1156 1.1 mrg {
1157 1.1 mrg fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
1158 1.1 mrg vfprintf (asm_out_file, comment, ap);
1159 1.1 mrg }
1160 1.1 mrg fputc ('\n', asm_out_file);
1161 1.1 mrg
1162 1.1 mrg va_end (ap);
1163 }
1164
1165 #include "gt-dwarf2asm.h"
1166