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