X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-rx.c;h=6b19f2f397152860d8423fb80fce7f1453060f1e;hb=d69cd47e7e9884f7b3a319936f70b8d93347e9e0;hp=05fa4da032346051262d7ed58434e9a76e2bd38d;hpb=33eaf5de31b248f84ae108cf0cf4e1664db9ee51;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-rx.c b/gas/config/tc-rx.c index 05fa4da032..6b19f2f397 100644 --- a/gas/config/tc-rx.c +++ b/gas/config/tc-rx.c @@ -1,5 +1,5 @@ /* tc-rx.c -- Assembler for the Renesas RX - Copyright (C) 2008-2017 Free Software Foundation, Inc. + Copyright (C) 2008-2019 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -19,7 +19,6 @@ 02110-1301, USA. */ #include "as.h" -#include "struc-symbol.h" #include "safe-ctype.h" #include "dwarf2dbg.h" #include "elf/common.h" @@ -45,7 +44,11 @@ const char FLT_CHARS[] = "dD"; /* ELF flags to set in the output file header. */ static int elf_flags = E_FLAG_RX_ABI; +#ifndef TE_LINUX bfd_boolean rx_use_conventional_section_names = FALSE; +#else +bfd_boolean rx_use_conventional_section_names = TRUE; +#endif static bfd_boolean rx_use_small_data_limit = FALSE; static bfd_boolean rx_pid_mode = FALSE; @@ -109,15 +112,18 @@ struct cpu_type { const char *cpu_name; enum rx_cpu_types type; + int flag; }; struct cpu_type cpu_type_list[] = { - {"rx100",RX100}, - {"rx200",RX200}, - {"rx600",RX600}, - {"rx610",RX610}, - {"rxv2",RXV2} + {"rx100", RX100, 0}, + {"rx200", RX200, 0}, + {"rx600", RX600, 0}, + {"rx610", RX610, 0}, + {"rxv2", RXV2, E_FLAG_RX_V2}, + {"rxv3", RXV3, E_FLAG_RX_V3}, + {"rxv3-dfpu", RXV3FPU, E_FLAG_RX_V3}, }; int @@ -182,8 +188,7 @@ md_parse_option (int c ATTRIBUTE_UNUSED, const char * arg ATTRIBUTE_UNUSED) if (strcasecmp (arg, cpu_type_list[i].cpu_name) == 0) { rx_cpu = cpu_type_list[i].type; - if (rx_cpu == RXV2) - elf_flags |= E_FLAG_RX_V2; + elf_flags |= cpu_type_list[i].flag; return 1; } } @@ -213,7 +218,7 @@ md_show_usage (FILE * stream) fprintf (stream, _(" --mrelax\n")); fprintf (stream, _(" --mpid\n")); fprintf (stream, _(" --mint-register=\n")); - fprintf (stream, _(" --mcpu=\n")); + fprintf (stream, _(" --mcpu=\n")); fprintf (stream, _(" --mno-allow-string-insns")); } @@ -486,7 +491,7 @@ parse_rx_section (char * name) else type = SHT_NOBITS; - obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE); + obj_elf_change_section (name, type, 0, attr, 0, NULL, FALSE, FALSE); } else /* Try not to redefine a section, especially B_1. */ { @@ -501,7 +506,7 @@ parse_rx_section (char * name) | ((flags & SEC_STRINGS) ? SHF_STRINGS : 0) | ((flags & SEC_THREAD_LOCAL) ? SHF_TLS : 0); - obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE); + obj_elf_change_section (name, type, 0, attr, 0, NULL, FALSE, FALSE); } bfd_set_section_alignment (stdoutput, now_seg, align); @@ -560,7 +565,7 @@ rx_list (int ignore ATTRIBUTE_UNUSED) static void rx_rept (int ignore ATTRIBUTE_UNUSED) { - int count = get_absolute_expression (); + size_t count = get_absolute_expression (); do_repeat_with_expander (count, "MREPEAT", "ENDR", "..MACREP"); } @@ -724,6 +729,8 @@ typedef struct rx_bytesT fixS * fixP; } fixups[2]; int n_fixups; + char post[1]; + int n_post; struct { char type; @@ -733,8 +740,8 @@ typedef struct rx_bytesT int n_relax; int link_relax; fixS *link_relax_fixP; - char times_grown; - char times_shrank; + unsigned long times_grown; + unsigned long times_shrank; } rx_bytesT; static rx_bytesT rx_bytes; @@ -948,6 +955,24 @@ rx_field5s2 (expressionS exp) rx_bytes.base[1] |= (val ) & 0x0f; } +void +rx_bfield(expressionS s, expressionS d, expressionS w) +{ + int slsb = s.X_add_number; + int dlsb = d.X_add_number; + int width = w.X_add_number; + unsigned int imm = + (((dlsb + width) & 0x1f) << 10 | (dlsb << 5) | + ((dlsb - slsb) & 0x1f)); + if ((slsb + width) > 32) + as_warn (_("Value %d and %d out of range"), slsb, width); + if ((dlsb + width) > 32) + as_warn (_("Value %d and %d out of range"), dlsb, width); + rx_bytes.ops[0] = imm & 0xff; + rx_bytes.ops[1] = (imm >> 8); + rx_bytes.n_ops = 2; +} + #define OP(x) rx_bytes.ops[rx_bytes.n_ops++] = (x) #define F_PRECISION 2 @@ -1009,6 +1034,11 @@ rx_op (expressionS exp, int nbytes, int type) } } +void rx_post(char byte) +{ + rx_bytes.post[rx_bytes.n_post++] = byte; +} + int rx_wrap (void) { @@ -1134,21 +1164,22 @@ md_assemble (char * str) 0 /* offset */, 0 /* opcode */); frag_then->fr_opcode = bytes; - frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops; - frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops; + frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post; + frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post; } else { - bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops); + bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post); frag_then = frag_now; if (fetchalign_bytes) - fetchalign_bytes->n_ops = rx_bytes.n_base + rx_bytes.n_ops; + fetchalign_bytes->n_ops = rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post; } fetchalign_bytes = NULL; APPEND (base, n_base); APPEND (ops, n_ops); + APPEND (post, n_post); if (rx_bytes.link_relax && rx_bytes.n_fixups) { @@ -1197,7 +1228,6 @@ md_assemble (char * str) if (frag_then->tc_frag_data) frag_then->tc_frag_data->fixups[i].fixP = f; } - dwarf2_emit_insn (idx); } @@ -1528,7 +1558,7 @@ rx_next_opcode (fragS *fragP) fr_subtype to calculate the difference. */ int -rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch) +rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch, unsigned long max_iterations) { addressT addr0, sym_addr; addressT mypc; @@ -1725,9 +1755,16 @@ rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch) /* This prevents infinite loops in align-heavy sources. */ if (newsize < oldsize) { - if (fragP->tc_frag_data->times_shrank > 10 - && fragP->tc_frag_data->times_grown > 10) - newsize = oldsize; + /* Make sure that our iteration limit is no bigger than the one being + used inside write.c:relax_segment(). Otherwise we can end up + iterating for too long, and triggering a fatal error there. See + PR 24464 for more details. */ + unsigned long limit = max_iterations > 10 ? 10 : max_iterations; + + if (fragP->tc_frag_data->times_shrank > limit + && fragP->tc_frag_data->times_grown > limit) + newsize = oldsize; + if (fragP->tc_frag_data->times_shrank < 20) fragP->tc_frag_data->times_shrank ++; } @@ -2149,8 +2186,7 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, fragP->fr_var = 0; if (fragP->fr_next != NULL - && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address) - != fragP->fr_fix)) + && fragP->fr_next->fr_address - fragP->fr_address != fragP->fr_fix) as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP, (long) fragP->fr_fix, (long) fragP->fr_address, (long) fragP->fr_next->fr_address); @@ -2681,6 +2717,7 @@ rx_start_line (void) int in_single_quote = 0; int done = 0; char * p = input_line_pointer; + char prev_char = 0; /* Scan the line looking for question marks. Skip past quote enclosed regions. */ do @@ -2693,7 +2730,9 @@ rx_start_line (void) break; case '"': - in_double_quote = ! in_double_quote; + /* Handle escaped double quote \" inside a string. */ + if (prev_char != '\\') + in_double_quote = ! in_double_quote; break; case '\'': @@ -2722,7 +2761,7 @@ rx_start_line (void) break; } - p ++; + prev_char = *p++; } while (! done); }