Message ID | 1489087698-34807-1-git-send-email-dmalcolm@redhat.com |
---|---|
State | New |
Headers | show |
On 03/09/2017 08:28 PM, David Malcolm wrote: > The root cause is an out-of-bounds memory write in the RTL dump > reader when handling SYMBOL_REFs with SYMBOL_FLAG_HAS_BLOCK_INFO set. > > Such SYMBOL_REFs are normally created by varasm.c:create_block_symbol, > which has: Hmm, I don't actually recall seeing this stuff. It's for section anchors apparently. > OK for trunk in stage 4? > > gcc/ChangeLog: > PR bootstrap/79952 > * read-rtl-function.c (function_reader::read_rtx_operand): Update > x with result of extra_parsing_for_operand_code_0. > (function_reader::extra_parsing_for_operand_code_0): Convert > return type from void to rtx, returning x. When reading > SYMBOL_REF with SYMBOL_FLAG_HAS_BLOCK_INFO, reallocate x to the > larger size containing struct block_symbol. Looks OK for now, but longer term I think we should make it possible to reconstruct this data. Bernd
On Fri, 2017-03-10 at 00:36 +0100, Bernd Schmidt wrote: > On 03/09/2017 08:28 PM, David Malcolm wrote: > > The root cause is an out-of-bounds memory write in the RTL dump > > reader when handling SYMBOL_REFs with SYMBOL_FLAG_HAS_BLOCK_INFO > > set. > > > > Such SYMBOL_REFs are normally created by > > varasm.c:create_block_symbol, > > which has: > > Hmm, I don't actually recall seeing this stuff. It's for section > anchors > apparently. > > > OK for trunk in stage 4? > > > > gcc/ChangeLog: > > PR bootstrap/79952 > > * read-rtl-function.c (function_reader::read_rtx_operand): > > Update > > x with result of extra_parsing_for_operand_code_0. > > (function_reader::extra_parsing_for_operand_code_0): Convert > > return type from void to rtx, returning x. When reading > > SYMBOL_REF with SYMBOL_FLAG_HAS_BLOCK_INFO, reallocate x to the > > larger size containing struct block_symbol. > > Looks OK for now, but longer term I think we should make it possible > to > reconstruct this data. Thanks; fix committed to trunk as r246044. I'm also not very familiar with this part of RTL. print-rtl.c:rtx_writer::print_rtx_operand_code_0 has some special -casing for SYMBOL_REF, but if I'm reading things right we don't yet dump SYMBOL_REF_BLOCK and SYMBOL_REF_BLOCK_OFFSET, so we'd need to dump these somehow.
On 03/10/2017 08:03 PM, David Malcolm wrote: > print-rtl.c:rtx_writer::print_rtx_operand_code_0 has some special > -casing for SYMBOL_REF, but if I'm reading things right we don't yet > dump SYMBOL_REF_BLOCK and SYMBOL_REF_BLOCK_OFFSET, so we'd need to dump > these somehow. Yeah. Perhaps as an extra table or so to show the various blocks and the symbols in them sorted by offset - could be useful information for RTL dumps too. Bernd
diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c index 8552cd2..c5027971 100644 --- a/gcc/read-rtl-function.c +++ b/gcc/read-rtl-function.c @@ -103,7 +103,7 @@ class function_reader : public rtx_reader void read_rtx_operand_u (rtx x, int idx); void read_rtx_operand_i_or_n (rtx x, int idx, char format_char); rtx read_rtx_operand_r (rtx x); - void extra_parsing_for_operand_code_0 (rtx x, int idx); + rtx extra_parsing_for_operand_code_0 (rtx x, int idx); void add_fixup_insn_uid (file_location loc, rtx insn, int operand_idx, int insn_uid); @@ -923,7 +923,7 @@ function_reader::read_rtx_operand (rtx x, int idx) switch (format_char) { case '0': - extra_parsing_for_operand_code_0 (x, idx); + x = extra_parsing_for_operand_code_0 (x, idx); break; case 'w': @@ -1116,9 +1116,10 @@ function_reader::read_rtx_operand_r (rtx x) } /* Additional parsing for format code '0' in dumps, handling a variety - of special-cases in print_rtx, when parsing operand IDX of X. */ + of special-cases in print_rtx, when parsing operand IDX of X. + Return X, or possibly a reallocated copy of X. */ -void +rtx function_reader::extra_parsing_for_operand_code_0 (rtx x, int idx) { RTX_CODE code = GET_CODE (x); @@ -1137,9 +1138,26 @@ function_reader::extra_parsing_for_operand_code_0 (rtx x, int idx) read_name (&name); SYMBOL_REF_FLAGS (x) = strtol (name.string, NULL, 16); - /* We can't reconstruct SYMBOL_REF_BLOCK; set it to NULL. */ + /* The standard RTX_CODE_SIZE (SYMBOL_REF) used when allocating + x doesn't have space for the block_symbol information, so + we must reallocate it if this flag is set. */ if (SYMBOL_REF_HAS_BLOCK_INFO_P (x)) - SYMBOL_REF_BLOCK (x) = NULL; + { + /* Emulate the allocation normally done by + varasm.c:create_block_symbol. */ + unsigned int size = RTX_HDR_SIZE + sizeof (struct block_symbol); + rtx new_x = (rtx) ggc_internal_alloc (size); + + /* Copy data over from the smaller SYMBOL_REF. */ + memcpy (new_x, x, RTX_CODE_SIZE (SYMBOL_REF)); + x = new_x; + + /* We can't reconstruct SYMBOL_REF_BLOCK; set it to NULL. */ + SYMBOL_REF_BLOCK (x) = NULL; + + /* Zero the offset. */ + SYMBOL_REF_BLOCK_OFFSET (x) = 0; + } require_char (']'); } @@ -1185,6 +1203,8 @@ function_reader::extra_parsing_for_operand_code_0 (rtx x, int idx) else unread_char (c); } + + return x; } /* Implementation of rtx_reader::handle_any_trailing_information.