This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[patch] backward .org error handling causes GAS failure
- From: Bob Wilson <bwilson at tensilica dot com>
- To: binutils at sources dot redhat dot com
- Date: Wed, 04 Aug 2004 09:53:11 -0700
- Subject: [patch] backward .org error handling causes GAS failure
- Organization: Tensilica, Inc.
When GAS detects a .org directive that attempts to move the address backward, it
reports an error and then changes the frag to an "align" to avoid further
errors. There is a minor problem with the code to set up these align frags.
The fr_fix field is set to "after - address", where "after" is the address of
the next frag and "address" is for the current frag being modified. The problem
is that "address" has already been incremented by the stretch value but "after"
has not. This can cause the fr_fix field to be set to a negative value, and
that in turn causes GAS to fail when writing the output file. Instead of
detecting that an error occurred and deleting the output file, GAS exits and
leaves the partially written output file, which causes problems for makefiles.
The attached "bkwd.s" testcase will demonstrate the problem.
The patch simply changes the code to use "was_address" (the value before adding
the stretch) when setting fr_fix for the align frag. It fixes the problem and
does not cause any regressions when I run the GAS testsuite on an
i686-pc-linux-gnu target.
OK to commit?
It seems like it might also be a good idea to delete the output file when the
calls to bfd_set_section_contents() from write_contents() fail. I'm not going
to attempt a patch for that right now, though.
2004-08-04 Bob Wilson <bob.wilson@acm.org>
* write.c (relax_segment): Use was_address instead of address when
setting fr_fix field for align frag due to backwards .org.
.org 3
nop
.org 0
.word 0
Index: write.c
===================================================================
RCS file: /cvs/src/src/gas/write.c,v
retrieving revision 1.77
diff -u -p -r1.77 write.c
--- write.c 2 Jul 2004 06:40:19 -0000 1.77
+++ write.c 4 Aug 2004 16:33:27 -0000
@@ -2412,7 +2412,7 @@ relax_segment (struct frag *segment_frag
fragP->fr_type = rs_align;
fragP->fr_subtype = 0;
fragP->fr_offset = 0;
- fragP->fr_fix = after - address;
+ fragP->fr_fix = after - was_address;
growth = stretch;
}