X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=gas%2Fread.c;h=a940ff3af9291669a63cca10249d2564988fe7ba;hb=4179a6a209f22354a605413e0de9ac10331c108b;hp=b25ab8dee1a4ef1e29504b4fafd1ac328553b749;hpb=ec9ab52c3217835113f22431911fda3474598fcd;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/read.c b/gas/read.c index b25ab8dee1..a940ff3af9 100644 --- a/gas/read.c +++ b/gas/read.c @@ -1,5 +1,5 @@ /* read.c - read a source file - - Copyright (C) 1986-2015 Free Software Foundation, Inc. + Copyright (C) 1986-2016 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -166,7 +166,7 @@ int target_big_endian = TARGET_BYTES_BIG_ENDIAN; /* Variables for handling include file directory table. */ /* Table of pointers to directories to search for .include's. */ -char **include_dirs; +const char **include_dirs; /* How many are in the table. */ int include_dir_count; @@ -238,7 +238,6 @@ static unsigned int bundle_lock_depth; #endif static void do_s_func (int end_p, const char *default_prefix); -static void do_align (int, char *, int, int); static void s_align (int, int); static void s_altmacro (int); static void s_bad_end (int); @@ -487,6 +486,7 @@ static offsetT get_absolute_expr (expressionS *exp) { expression_and_evaluate (exp); + if (exp->X_op != O_constant) { if (exp->X_op != O_absent) @@ -685,7 +685,8 @@ finish_bundle (fragS *frag, unsigned int size) /* We do this every time rather than just in s_bundle_align_mode so that we catch any affected section without needing hooks all over for all paths that do section changes. It's cheap enough. */ - record_alignment (now_seg, bundle_align_p2 - OCTETS_PER_BYTE_POWER); + if (bundle_align_p2 > OCTETS_PER_BYTE_POWER) + record_alignment (now_seg, bundle_align_p2 - OCTETS_PER_BYTE_POWER); } /* Assemble one instruction. This takes care of the bundle features @@ -736,10 +737,79 @@ single instruction is %u bytes long but .bundle_align_mode limit is %u"), #endif /* HANDLE_BUNDLE */ +static bfd_boolean +in_bss (void) +{ + flagword flags = bfd_get_section_flags (stdoutput, now_seg); + + return (flags & SEC_ALLOC) && !(flags & (SEC_LOAD | SEC_HAS_CONTENTS)); +} + +/* Guts of .align directive: + N is the power of two to which to align. A value of zero is accepted but + ignored: the default alignment of the section will be at least this. + FILL may be NULL, or it may point to the bytes of the fill pattern. + LEN is the length of whatever FILL points to, if anything. If LEN is zero + but FILL is not NULL then LEN is treated as if it were one. + MAX is the maximum number of characters to skip when doing the alignment, + or 0 if there is no maximum. */ + +void +do_align (unsigned int n, char *fill, unsigned int len, unsigned int max) +{ + if (now_seg == absolute_section || in_bss ()) + { + if (fill != NULL) + while (len-- > 0) + if (*fill++ != '\0') + { + if (now_seg == absolute_section) + as_warn (_("ignoring fill value in absolute section")); + else + as_warn (_("ignoring fill value in section `%s'"), + segment_name (now_seg)); + break; + } + fill = NULL; + len = 0; + } + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + +#ifdef md_do_align + md_do_align (n, fill, len, max, just_record_alignment); +#endif + + /* Only make a frag if we HAVE to... */ + if ((n > OCTETS_PER_BYTE_POWER) && !need_pass_2) + { + if (fill == NULL) + { + if (subseg_text_p (now_seg)) + frag_align_code (n, max); + else + frag_align (n, 0, max); + } + else if (len <= 1) + frag_align (n, *fill, max); + else + frag_align_pattern (n, fill, len, max); + } + +#ifdef md_do_align + just_record_alignment: ATTRIBUTE_UNUSED_LABEL +#endif + + if (n > OCTETS_PER_BYTE_POWER) + record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER); +} + /* We read the file, putting things into a web that represents what we have been reading. */ void -read_a_source_file (char *name) +read_a_source_file (const char *name) { char nul_char; char next_char; @@ -809,7 +879,7 @@ read_a_source_file (char *name) /* Copy it for safe keeping. Also give an indication of how much macro nesting is involved at this point. */ len = s - input_line_pointer; - copy = (char *) xmalloc (len + macro_nest + 2); + copy = XNEWVEC (char, len + macro_nest + 2); memset (copy, '>', macro_nest); copy[macro_nest] = ' '; memcpy (copy + macro_nest + 1, input_line_pointer, len); @@ -1106,6 +1176,11 @@ read_a_source_file (char *name) assemble_one (s); /* Assemble 1 instruction. */ + /* PR 19630: The backend may have set ilp to NULL + if it encountered a catastrophic failure. */ + if (input_line_pointer == NULL) + as_fatal (_("unable to continue with assembly.")); + *input_line_pointer++ = nul_char; /* We resume loop AFTER the end-of-line from @@ -1196,7 +1271,7 @@ read_a_source_file (char *name) that goes with this #APP There is one. The specs guarantee it... */ tmp_len = buffer_limit - s; - tmp_buf = (char *) xmalloc (tmp_len + 1); + tmp_buf = XNEWVEC (char, tmp_len + 1); memcpy (tmp_buf, s, tmp_len); do { @@ -1212,7 +1287,7 @@ read_a_source_file (char *name) else num = buffer_limit - buffer; - tmp_buf = (char *) xrealloc (tmp_buf, tmp_len + num); + tmp_buf = XRESIZEVEC (char, tmp_buf, tmp_len + num); memcpy (tmp_buf + tmp_len, buffer, num); tmp_len += num; } @@ -1233,7 +1308,7 @@ read_a_source_file (char *name) scrub_string_end = ends; new_length = ends - s; - new_buf = (char *) xmalloc (new_length); + new_buf = XNEWVEC (char, new_length); new_tmp = new_buf; for (;;) { @@ -1249,7 +1324,7 @@ read_a_source_file (char *name) break; } - new_buf = (char *) xrealloc (new_buf, new_length + 100); + new_buf = XRESIZEVEC (char, new_buf, new_length + 100); new_tmp = new_buf + new_length; new_length += 100; } @@ -1337,14 +1412,6 @@ convert_to_bignum (expressionS *exp, int sign) exp->X_add_number = i; } -static bfd_boolean -in_bss (void) -{ - flagword flags = bfd_get_section_flags (stdoutput, now_seg); - - return (flags & SEC_ALLOC) && !(flags & (SEC_LOAD | SEC_HAS_CONTENTS)); -} - /* For most MRI pseudo-ops, the line actually ends at the first nonquoted space. This function looks for that point, stuffs a null in, and sets *STOPCP to the character that used to be there, and @@ -1401,62 +1468,6 @@ s_abort (int ignore ATTRIBUTE_UNUSED) as_fatal (_(".abort detected. Abandoning ship.")); } -/* Guts of .align directive. N is the power of two to which to align. - FILL may be NULL, or it may point to the bytes of the fill pattern. - LEN is the length of whatever FILL points to, if anything. MAX is - the maximum number of characters to skip when doing the alignment, - or 0 if there is no maximum. */ - -static void -do_align (int n, char *fill, int len, int max) -{ - if (now_seg == absolute_section || in_bss ()) - { - if (fill != NULL) - while (len-- > 0) - if (*fill++ != '\0') - { - if (now_seg == absolute_section) - as_warn (_("ignoring fill value in absolute section")); - else - as_warn (_("ignoring fill value in section `%s'"), - segment_name (now_seg)); - break; - } - fill = NULL; - len = 0; - } - -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif -#ifdef md_do_align - md_do_align (n, fill, len, max, just_record_alignment); -#endif - - /* Only make a frag if we HAVE to... */ - if (n != 0 && !need_pass_2) - { - if (fill == NULL) - { - if (subseg_text_p (now_seg)) - frag_align_code (n, max); - else - frag_align (n, 0, max); - } - else if (len <= 1) - frag_align (n, *fill, max); - else - frag_align_pattern (n, fill, len, max); - } - -#ifdef md_do_align - just_record_alignment: ATTRIBUTE_UNUSED_LABEL -#endif - - record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER); -} - /* Handle the .align pseudo-op. A positive ARG is a default alignment (in bytes). A negative ARG is the negative of the length of the fill pattern. BYTES_P is non-zero if the alignment value should be @@ -1466,14 +1477,14 @@ do_align (int n, char *fill, int len, int max) #endif static void -s_align (int arg, int bytes_p) +s_align (signed int arg, int bytes_p) { unsigned int align_limit = TC_ALIGN_LIMIT; unsigned int align; char *stop = NULL; char stopc = 0; offsetT fill = 0; - int max; + unsigned int max; int fill_p; if (flag_mri) @@ -1553,15 +1564,16 @@ s_align (int arg, int bytes_p) } else { - int fill_len; + unsigned int fill_len; if (arg >= 0) fill_len = 1; else fill_len = -arg; + if (fill_len <= 1) { - char fill_char; + char fill_char = 0; fill_char = fill; do_align (align, &fill_char, fill_len, max); @@ -1571,7 +1583,12 @@ s_align (int arg, int bytes_p) char ab[16]; if ((size_t) fill_len > sizeof ab) - abort (); + { + as_warn (_("fill pattern too long, truncating to %u"), + (unsigned) sizeof ab); + fill_len = sizeof ab; + } + md_number_to_chars (ab, fill, fill_len); do_align (align, ab, fill_len, max); } @@ -1640,7 +1657,7 @@ read_symbol_name (void) char * name_end; unsigned int C; - start = name = xmalloc (len + 1); + start = name = XNEWVEC (char, len + 1); name_end = name + SYM_NAME_CHUNK_LEN; @@ -1652,7 +1669,7 @@ read_symbol_name (void) sofar = name - start; len += SYM_NAME_CHUNK_LEN; - start = xrealloc (start, len + 1); + start = XRESIZEVEC (char, start, len + 1); name_end = start + len; name = start + sofar; } @@ -1680,7 +1697,7 @@ read_symbol_name (void) ; len = (input_line_pointer - name) - 1; - start = xmalloc (len + 1); + start = XNEWVEC (char, len + 1); memcpy (start, name, len); start[len] = 0; @@ -1833,9 +1850,8 @@ s_mri_common (int small ATTRIBUTE_UNUSED) if (line_label != NULL) { - alc = (char *) xmalloc (strlen (S_GET_NAME (line_label)) - + (input_line_pointer - name) - + 1); + alc = XNEWVEC (char, strlen (S_GET_NAME (line_label)) + + (input_line_pointer - name) + 1); sprintf (alc, "%s%s", name, S_GET_NAME (line_label)); name = alc; } @@ -2120,7 +2136,7 @@ s_errwarn (int err) self-contained message, one that can be passed like the demand_copy_C_string return value, and with no assumption on the location of the name of the directive within the message. */ - char *msg + const char *msg = (err ? _(".error directive invoked in source file") : _(".warning directive invoked in source file")); @@ -2331,13 +2347,14 @@ s_globl (int ignore ATTRIBUTE_UNUSED) void s_irp (int irpc) { - char *file, *eol; + char * eol; + const char * file; unsigned int line; sb s; const char *err; sb out; - as_where (&file, &line); + file = as_where (&line); eol = find_end_of_line (input_line_pointer, 0); sb_build (&s, eol - input_line_pointer); @@ -2429,7 +2446,7 @@ s_linkonce (int ignore ATTRIBUTE_UNUSED) } void -bss_alloc (symbolS *symbolP, addressT size, int align) +bss_alloc (symbolS *symbolP, addressT size, unsigned int align) { char *pfrag; segT current_seg = now_seg; @@ -2453,7 +2470,7 @@ bss_alloc (symbolS *symbolP, addressT size, int align) #endif subseg_set (bss_seg, 1); - if (align) + if (align > OCTETS_PER_BYTE_POWER) { record_alignment (bss_seg, align); frag_align (align, 0, 0); @@ -2666,13 +2683,14 @@ get_macro_line_sb (sb *line) void s_macro (int ignore ATTRIBUTE_UNUSED) { - char *file, *eol; + char *eol; + const char * file; unsigned int line; sb s; const char *err; const char *name; - as_where (&file, &line); + file = as_where (&line); eol = find_end_of_line (input_line_pointer, 0); sb_build (&s, eol - input_line_pointer); @@ -2907,7 +2925,7 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED) if (c == ',') { - int align; + unsigned int align; ++input_line_pointer; align = get_absolute_expression (); @@ -3006,7 +3024,7 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED) } else if (strcasecmp (seccmd, "align") == 0) { - int align; + unsigned int align; (void) restore_line_pointer (c); align = get_absolute_expression (); @@ -3219,7 +3237,7 @@ assign_symbol (char *name, int mode) if (listing & LISTING_SYMBOLS) { extern struct list_info_struct *listing_tail; - fragS *dummy_frag = (fragS *) xcalloc (1, sizeof (fragS)); + fragS *dummy_frag = XCNEW (fragS); dummy_frag->line = listing_tail; dummy_frag->fr_symbol = symbolP; symbol_set_frag (symbolP, dummy_frag); @@ -3237,7 +3255,9 @@ assign_symbol (char *name, int mode) && !S_CAN_BE_REDEFINED (symbolP)) { as_bad (_("symbol `%s' is already defined"), name); - symbolP = symbol_clone (symbolP, 0); + ignore_rest_of_line (); + input_line_pointer--; + return; } /* If the symbol is volatile, copy the symbol and replace the original with the copy, so that previous uses of the symbol will @@ -3523,7 +3543,7 @@ s_float_space (int float_type) } else { - char *err; + const char *err; err = md_atof (float_type, temp, &flen); know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); @@ -4038,16 +4058,17 @@ s_reloc (int ignore ATTRIBUTE_UNUSED) char *r_name; int c; struct reloc_list *reloc; - struct _bfd_rel { char *name; bfd_reloc_code_real_type code; }; - static struct _bfd_rel bfd_relocs[] = { + struct _bfd_rel { const char * name; bfd_reloc_code_real_type code; }; + static struct _bfd_rel bfd_relocs[] = + { { "NONE", BFD_RELOC_NONE }, - { "8", BFD_RELOC_8 }, + { "8", BFD_RELOC_8 }, { "16", BFD_RELOC_16 }, { "32", BFD_RELOC_32 }, { "64", BFD_RELOC_64 } }; - reloc = (struct reloc_list *) xmalloc (sizeof (*reloc)); + reloc = XNEW (struct reloc_list); if (flag_mri) stop = mri_comment_field (&stopc); @@ -4145,7 +4166,7 @@ s_reloc (int ignore ATTRIBUTE_UNUSED) break; } - as_where (&reloc->file, &reloc->line); + reloc->file = as_where (&reloc->line); reloc->next = reloc_list; reloc_list = reloc; @@ -4327,7 +4348,7 @@ emit_expr_with_reloc (expressionS *exp, { struct broken_word *x; - x = (struct broken_word *) xmalloc (sizeof (struct broken_word)); + x = XNEW (struct broken_word); x->next_broken_word = broken_words; broken_words = x; x->seg = now_seg; @@ -4391,7 +4412,8 @@ emit_expr_with_reloc (expressionS *exp, if ((get & mask) != 0 && ((get & mask) != mask || (get & hibit) == 0)) - { /* Leading bits contain both 0s & 1s. */ + { + /* Leading bits contain both 0s & 1s. */ #if defined (BFD64) && BFD_HOST_64BIT_LONG_LONG #ifndef __MSVCRT__ as_warn (_("value 0x%llx truncated to 0x%llx"), @@ -4417,16 +4439,34 @@ emit_expr_with_reloc (expressionS *exp, if (nbytes < size) { int i = nbytes / CHARS_PER_LITTLENUM; + if (i != 0) { LITTLENUM_TYPE sign = 0; if ((generic_bignum[--i] & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) != 0) sign = ~(LITTLENUM_TYPE) 0; + while (++i < exp->X_add_number) if (generic_bignum[i] != sign) break; } + else if (nbytes == 1) + { + /* We have nbytes == 1 and CHARS_PER_LITTLENUM == 2 (probably). + Check that bits 8.. of generic_bignum[0] match bit 7 + and that they match all of generic_bignum[1..exp->X_add_number]. */ + LITTLENUM_TYPE sign = (generic_bignum[0] & (1 << 7)) ? -1 : 0; + LITTLENUM_TYPE himask = LITTLENUM_MASK & ~ 0xFF; + + if ((generic_bignum[0] & himask) == (sign & himask)) + { + while (++i < exp->X_add_number) + if (generic_bignum[i] != sign) + break; + } + } + if (i < exp->X_add_number) as_warn (_("bignum truncated to %d bytes"), nbytes); size = nbytes; @@ -4555,9 +4595,7 @@ emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p, BITFIELD_CONS_EXPRESSIONS. */ static void -parse_bitfield_cons (exp, nbytes) - expressionS *exp; - unsigned int nbytes; +parse_bitfield_cons (expressionS *exp, unsigned int nbytes) { unsigned int bits_available = BITS_PER_CHAR * nbytes; char *hold = input_line_pointer; @@ -4742,9 +4780,7 @@ parse_mri_cons (expressionS *exp, unsigned int nbytes) To use this for a target, define REPEAT_CONS_EXPRESSIONS. */ static void -parse_repeat_cons (exp, nbytes) - expressionS *exp; - unsigned int nbytes; +parse_repeat_cons (expressionS *exp, unsigned int nbytes) { expressionS count; int i; @@ -4886,7 +4922,7 @@ float_cons (/* Clobbers input_line-pointer, checks end-of-line. */ { char *p; int length; /* Number of chars in an object. */ - char *err; /* Error from scanning floating literal. */ + const char *err; /* Error from scanning floating literal. */ char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT]; if (is_it_end_of_statement ()) @@ -4993,9 +5029,25 @@ float_cons (/* Clobbers input_line-pointer, checks end-of-line. */ demand_empty_rest_of_line (); } -/* Return the size of a LEB128 value. */ +/* LEB128 Encoding. -static inline int + Note - we are using the DWARF standard's definition of LEB128 encoding + where each 7-bit value is a stored in a byte, *not* an octet. This + means that on targets where a byte contains multiple octets there is + a *huge waste of space*. (This also means that we do not have to + have special versions of these functions for when OCTETS_PER_BYTE_POWER + is non-zero). + + If the 7-bit values were to be packed into N-bit bytes (where N > 8) + we would then have to consider whether multiple, successive LEB128 + values should be packed into the bytes without padding (bad idea) or + whether each LEB128 number is padded out to a whole number of bytes. + Plus you have to decide on the endianness of packing octets into a + byte. */ + +/* Return the size of a LEB128 value in bytes. */ + +static inline unsigned int sizeof_sleb128 (offsetT value) { int size = 0; @@ -5016,7 +5068,7 @@ sizeof_sleb128 (offsetT value) return size; } -static inline int +static inline unsigned int sizeof_uleb128 (valueT value) { int size = 0; @@ -5031,7 +5083,7 @@ sizeof_uleb128 (valueT value) return size; } -int +unsigned int sizeof_leb128 (valueT value, int sign) { if (sign) @@ -5040,9 +5092,9 @@ sizeof_leb128 (valueT value, int sign) return sizeof_uleb128 (value); } -/* Output a LEB128 value. */ +/* Output a LEB128 value. Returns the number of bytes used. */ -static inline int +static inline unsigned int output_sleb128 (char *p, offsetT value) { char *orig = p; @@ -5069,7 +5121,7 @@ output_sleb128 (char *p, offsetT value) return p - orig; } -static inline int +static inline unsigned int output_uleb128 (char *p, valueT value) { char *orig = p; @@ -5077,6 +5129,7 @@ output_uleb128 (char *p, valueT value) do { unsigned byte = (value & 0x7f); + value >>= 7; if (value != 0) /* More bytes to follow. */ @@ -5089,7 +5142,7 @@ output_uleb128 (char *p, valueT value) return p - orig; } -int +unsigned int output_leb128 (char *p, valueT value, int sign) { if (sign) @@ -5100,10 +5153,11 @@ output_leb128 (char *p, valueT value, int sign) /* Do the same for bignums. We combine sizeof with output here in that we don't output for NULL values of P. It isn't really as critical as - for "normal" values that this be streamlined. */ + for "normal" values that this be streamlined. Returns the number of + bytes used. */ -static inline int -output_big_sleb128 (char *p, LITTLENUM_TYPE *bignum, int size) +static inline unsigned int +output_big_sleb128 (char *p, LITTLENUM_TYPE *bignum, unsigned int size) { char *orig = p; valueT val = 0; @@ -5157,8 +5211,8 @@ output_big_sleb128 (char *p, LITTLENUM_TYPE *bignum, int size) return p - orig; } -static inline int -output_big_uleb128 (char *p, LITTLENUM_TYPE *bignum, int size) +static inline unsigned int +output_big_uleb128 (char *p, LITTLENUM_TYPE *bignum, unsigned int size) { char *orig = p; valueT val = 0; @@ -5196,8 +5250,8 @@ output_big_uleb128 (char *p, LITTLENUM_TYPE *bignum, int size) return p - orig; } -static int -output_big_leb128 (char *p, LITTLENUM_TYPE *bignum, int size, int sign) +static unsigned int +output_big_leb128 (char *p, LITTLENUM_TYPE *bignum, unsigned int size, int sign) { if (sign) return output_big_sleb128 (p, bignum, size); @@ -5270,23 +5324,25 @@ emit_leb128_expr (expressionS *exp, int sign) /* If we've got a constant, emit the thing directly right now. */ valueT value = exp->X_add_number; - int size; + unsigned int size; char *p; size = sizeof_leb128 (value, sign); p = frag_more (size); - output_leb128 (p, value, sign); + if (output_leb128 (p, value, sign) > size) + abort (); } else if (op == O_big) { /* O_big is a different sort of constant. */ - int size; + unsigned int size; char *p; size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign); p = frag_more (size); - output_big_leb128 (p, generic_bignum, exp->X_add_number, sign); + if (output_big_leb128 (p, generic_bignum, exp->X_add_number, sign) > size) + abort (); } else { @@ -5799,7 +5855,7 @@ s_incbin (int x ATTRIBUTE_UNUSED) { int i; - path = (char *) xmalloc ((unsigned long) len + include_dir_maxlen + 5); + path = XNEWVEC (char, (unsigned long) len + include_dir_maxlen + 5); for (i = 0; i < include_dir_count; i++) { @@ -5902,8 +5958,8 @@ s_include (int arg ATTRIBUTE_UNUSED) } demand_empty_rest_of_line (); - path = (char *) xmalloc ((unsigned long) i - + include_dir_maxlen + 5 /* slop */ ); + path = XNEWVEC (char, (unsigned long) i + + include_dir_maxlen + 5 /* slop */ ); for (i = 0; i < include_dir_count; i++) { @@ -5932,16 +5988,15 @@ add_include_dir (char *path) if (include_dir_count == 0) { - include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs)); + include_dirs = XNEWVEC (const char *, 2); include_dirs[0] = "."; /* Current dir. */ include_dir_count = 2; } else { include_dir_count++; - include_dirs = - (char **) xrealloc (include_dirs, - include_dir_count * sizeof (*include_dirs)); + include_dirs = XRESIZEVEC (const char *, include_dirs, + include_dir_count); } include_dirs[include_dir_count - 1] = path; /* New one. */