This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
bad assumption in gas/stabs.c?
- To: binutils at sources dot redhat dot com
- Subject: bad assumption in gas/stabs.c?
- From: DJ Delorie <dj at redhat dot com>
- Date: Wed, 14 Mar 2001 18:00:42 -0500
In s_stab_generic, we see code like this:
string = demand_copy_C_string (&length);
...
#ifdef md_flush_pending_output
md_flush_pending_output ();
#endif
...
obstack_free (¬es, string);
Now, in at least one case I saw, md_flush_pending_output called
symbol_new(), which used the notes obstack to allocate something, and
the obstack_free() freed more than just the string, which caused
memory corruption, and eventually an abort.
The documentation doesn't say md_flush_pending_output can't do that.
The attached patch guards against this case, but is there some better
solution?
2001-03-14 DJ Delorie <dj@redhat.com>
* stabs.c (s_stab_generic): Don't free the string if it's no
longer at the top of the obstack.
Index: stabs.c
===================================================================
RCS file: /cvs/src/src/gas/stabs.c,v
retrieving revision 1.11
diff -p -3 -r1.11 stabs.c
*** stabs.c 2001/03/08 23:24:22 1.11
--- stabs.c 2001/03/14 22:54:01
*************** s_stab_generic (what, stab_secname, stab
*** 185,191 ****
char *stabstr_secname;
{
long longint;
! char *string;
int type;
int other;
int desc;
--- 185,191 ----
char *stabstr_secname;
{
long longint;
! char *string, *saved_string_obstack_end;
int type;
int other;
int desc;
*************** s_stab_generic (what, stab_secname, stab
*** 199,210 ****
'd' indicating which type of .stab this is. */
if (what != 's')
! string = "";
else
{
int length;
string = demand_copy_C_string (&length);
SKIP_WHITESPACE ();
if (*input_line_pointer == ',')
input_line_pointer++;
--- 199,214 ----
'd' indicating which type of .stab this is. */
if (what != 's')
! {
! string = "";
! saved_string_obstack_end = 0;
! }
else
{
int length;
string = demand_copy_C_string (&length);
+ saved_string_obstack_end = notes.next_free;
SKIP_WHITESPACE ();
if (*input_line_pointer == ',')
input_line_pointer++;
*************** s_stab_generic (what, stab_secname, stab
*** 335,342 ****
stroff = get_stab_string_offset (string, stabstr_secname);
if (what == 's')
{
! /* release the string */
! obstack_free (¬es, string);
}
/* At least for now, stabs in a special stab section are always
--- 339,347 ----
stroff = get_stab_string_offset (string, stabstr_secname);
if (what == 's')
{
! /* Release the string, if nobody else has used the obstack. */
! if (saved_string_obstack_end == notes.next_free)
! obstack_free (¬es, string);
}
/* At least for now, stabs in a special stab section are always