gas bug: out-of-order .file directives do not work
This happens on x86-linux in gas 2.14 and 2.16, and the bug is still in the source code in the latest CVS version. .file directives do not work unless they are emitted in numerical order. For example, this fails: .file 2 "/something_else" .loc2 402 1 .file 1 "/something" .loc2 402 1 $ as bar.s bar.s: Assembler messages: bar.s:4: Error: unassigned file number 2 It looks like a 'get_filenum' bug. 'get_filenum' tries to correctly handle file numbers being declared out of order, e.g. it understands there may be "holes" in the numbering space containing NULL filenames. But it always sets files_in_use to one beyond the latest number it has seen, effectively forgetting about any higher-numbered file that was already declared. Fortunately, the patch is trivial. --- dwarf2dbg.c.orig2006-01-11 11:16:47.0 -0500 +++ dwarf2dbg.c 2006-02-22 13:38:53.0 -0500 @@ -415,19 +415,20 @@ files_allocated = i + 32; files = (struct file_entry *) xrealloc (files, (i + 32) * sizeof (struct file_entry)); memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry)); } files[i].filename = num ? file : xstrdup (file); files[i].dir = dir; - files_in_use = i + 1; + if (i + 1 > files_in_use) +files_in_use = i + 1; last_used = i; last_used_dir_len = dir_len; return i; } /* Handle two forms of .file directive: - Pass .file "source.c" to s_app_file - Handle .file 1 "source.c" by adding an entry to the DWARF-2 file table Of course, if the assembler really wants to require .files to appear in order, it should report an error rather than silently dropping entries. But I think it's supposed to work. -Mat ___ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils
gas SEGV reporting an error + patch
gas 2.14 and 2.16 can SEGV trying to report an error assembling this erroneous code: .set bar,5f+text1 5: text1: The bug is that 'report_op_error' incorrectly uses 'file' and 'line' in the 'else' case where they are not initialized. Because the value of 'file' is garbage, it is of course somewhat random whether you will see a crash. The fix is trivial: since there is no location information available, use 'as_bad' instead of 'as_bad_where', as it was already doing for other errors in the 'else' case. --- tools/gnu/gas/symbols.c~2006-01-11 11:16:48.0 -0500 +++ tools/gnu/gas/symbols.c 2006-07-11 15:16:59.0 -0400 @@ -863,25 +863,23 @@ as_bad (_("undefined symbol `%s' in operation setting `%s'"), S_GET_NAME (left), S_GET_NAME (symp)); if (seg_right == undefined_section) as_bad (_("undefined symbol `%s' in operation setting `%s'"), S_GET_NAME (right), S_GET_NAME (symp)); if (seg_left != undefined_section && seg_right != undefined_section) { if (right) - as_bad_where (file, line, - _("invalid sections for operation on `%s' and `%s' setting `%s'"), - S_GET_NAME (left), S_GET_NAME (right), S_GET_NAME (symp)); + as_bad (_("invalid sections for operation on `%s' and `%s' setting `%s'"), +S_GET_NAME (left), S_GET_NAME (right), S_GET_NAME (symp)); else - as_bad_where (file, line, - _("invalid section for operation on `%s' setting `%s'"), - S_GET_NAME (left), S_GET_NAME (symp)); + as_bad (_("invalid section for operation on `%s' setting `%s'"), +S_GET_NAME (left), S_GET_NAME (symp)); } } } /* Resolve the value of a symbol. This is called during the final pass over the symbol table to resolve any symbols with complex values. */ valueT ___ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils
PATCH: fix incorrect PC-relative relocations with '.word'
This is for gas 2.18, but it looks like the same bug is present in 2.19. emit_expr, used by '.word' and others, grabs dot_value for the current frag, does some processing, and later calls frag_more. Unfortunately, the frag_more call can realize the frag is not big enough and switch to a new frag. That's bad because the dot_value already recorded an offset into the old frag, which is completely wrong for the new frag. The result is that you can get PC-relative relocations with incorrect offsets if they happen to span the byte boundary where a frag fills up. I saw this with a PC-relative relocation at a large odd byte offset, which is probably the only time this can happen. Unaligned PC-relative offsets are an unusual case, which is why this probably hasn't been reported before. My fix is simply to reserve enough space before calling frag_now_fix that the frag won't run out of room if frag_more is called later. --- gas/read.c~ 2008-08-18 12:56:22.864271000 -0400 +++ gas/read.c 2008-11-11 15:00:33.487833000 -0500 @@ -3891,30 +3891,33 @@ /* Put the contents of expression EXP into the object file using NBYTES bytes. If need_pass_2 is 1, this does nothing. */ void emit_expr (expressionS *exp, unsigned int nbytes) { operatorT op; register char *p; valueT extra_digit = 0; /* Don't do anything if we are going to make another pass. */ if (need_pass_2) return; + /* Grow the current frag now so that dot_value does not get invalidated + if the frag were to fill up in the frag_more() call below. */ + frag_grow (nbytes); dot_value = frag_now_fix (); #ifndef NO_LISTING #ifdef OBJ_ELF /* When gcc emits DWARF 1 debugging pseudo-ops, a line number will appear as a four byte positive constant in the .line section, followed by a 2 byte 0x. Look for that case here. */ { static int dwarf_line = -1; if (strcmp (segment_name (now_seg), ".line") != 0) dwarf_line = -1; else if (dwarf_line >= 0 && nbytes == 2 && exp->X_op == O_constant ___ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils