gas line buffer handling

This fixes a segfault when macro definitions end on the last line of a
file, and that line isn't properly terminated with a newline.  gas
used to throw away the last line in cases like this, whereas in other
cases gas added the missing newline.  So I've also made gas
consistently provide a missing newline.

	PR gas/18687
	* input-scrub.c (input_scrub_next_buffer): Rearrange and simplify
	loop.  Don't drop lines at end of file lacking a newline, add a
	newline instead.  Ensure partial_size is zero whenever
	partial_where is NULL.  Adjust buffer size for extra char.
	(input_scrub_push, input_scrub_begin): Adjust buffer size here too.
This commit is contained in:
Alan Modra
2015-07-22 21:58:50 +09:30
parent 5b2af7dd40
commit 511b1657d2
2 changed files with 53 additions and 54 deletions

View File

@ -1,3 +1,12 @@
2015-07-22 Alan Modra <amodra@gmail.com>
PR gas/18687
* input-scrub.c (input_scrub_next_buffer): Rearrange and simplify
loop. Don't drop lines at end of file lacking a newline, add a
newline instead. Ensure partial_size is zero whenever
partial_where is NULL. Adjust buffer size for extra char.
(input_scrub_push, input_scrub_begin): Adjust buffer size here too.
2015-07-20 Matthew Wahab <matthew.wahab@arm.com>
* NEWS: Mention corrected spelling of armv6kz.

View File

@ -164,7 +164,7 @@ input_scrub_push (char *saved_position)
sb_index = -1;
buffer_start = (char *) xmalloc ((BEFORE_SIZE + buffer_length
+ buffer_length + AFTER_SIZE));
+ buffer_length + AFTER_SIZE + 1));
memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
return saved;
@ -209,7 +209,7 @@ input_scrub_begin (void)
buffer_length = input_file_buffer_size ();
buffer_start = (char *) xmalloc ((BEFORE_SIZE + buffer_length
+ buffer_length + AFTER_SIZE));
+ buffer_length + AFTER_SIZE + 1));
memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
/* Line number things. */
@ -329,6 +329,7 @@ input_scrub_next_buffer (char **bufp)
}
--macro_nest;
partial_where = NULL;
partial_size = 0;
if (next_saved_file != NULL)
*bufp = input_scrub_pop (next_saved_file);
return partial_where;
@ -341,79 +342,68 @@ input_scrub_next_buffer (char **bufp)
return partial_where;
}
*bufp = buffer_start + BEFORE_SIZE;
if (partial_size)
{
memmove (buffer_start + BEFORE_SIZE, partial_where,
(unsigned int) partial_size);
memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE);
}
limit = input_file_give_next_buffer (buffer_start
+ BEFORE_SIZE
+ partial_size);
if (limit)
while (1)
{
char *p; /* Find last newline. */
/* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */
*limit = '\0';
for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p)
;
++p;
char *p;
while (p <= buffer_start + BEFORE_SIZE)
*bufp = buffer_start + BEFORE_SIZE;
limit = input_file_give_next_buffer (buffer_start
+ BEFORE_SIZE
+ partial_size);
if (!limit)
{
int limoff;
limoff = limit - buffer_start;
buffer_length += input_file_buffer_size ();
buffer_start = (char *) xrealloc (buffer_start,
(BEFORE_SIZE
+ 2 * buffer_length
+ AFTER_SIZE));
*bufp = buffer_start + BEFORE_SIZE;
limit = input_file_give_next_buffer (buffer_start + limoff);
if (limit == NULL)
{
as_warn (_("partial line at end of file ignored"));
partial_where = NULL;
if (next_saved_file)
*bufp = input_scrub_pop (next_saved_file);
return NULL;
}
if (partial_size == 0)
break;
as_warn (_("end of file not at end of a line; newline inserted"));
p = buffer_start + BEFORE_SIZE + partial_size;
*p++ = '\n';
limit = p;
}
else
{
/* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */
*limit = '\0';
/* Find last newline. */
for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p)
;
++p;
}
partial_where = p;
partial_size = limit - p;
memcpy (save_source, partial_where, (int) AFTER_SIZE);
memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE);
}
else
{
partial_where = 0;
if (partial_size > 0)
if (p != buffer_start + BEFORE_SIZE)
{
as_warn (_("partial line at end of file ignored"));
partial_where = p;
partial_size = limit - p;
memcpy (save_source, partial_where, (int) AFTER_SIZE);
memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE);
return partial_where;
}
/* Tell the listing we've finished the file. */
LISTING_EOF ();
/* If we should pop to another file at EOF, do it. */
if (next_saved_file)
{
*bufp = input_scrub_pop (next_saved_file); /* Pop state */
/* partial_where is now correct to return, since we popped it. */
}
partial_size = limit - (buffer_start + BEFORE_SIZE);
buffer_length += input_file_buffer_size ();
buffer_start = (char *) xrealloc (buffer_start,
(BEFORE_SIZE
+ 2 * buffer_length
+ AFTER_SIZE + 1));
}
return (partial_where);
/* Tell the listing we've finished the file. */
LISTING_EOF ();
/* If we should pop to another file at EOF, do it. */
partial_where = NULL;
if (next_saved_file)
*bufp = input_scrub_pop (next_saved_file);
return partial_where;
}
/* The remaining part of this file deals with line numbers, error