aboutsummaryrefslogtreecommitdiff
path: root/gas/input-scrub.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-07-22 21:58:50 +0930
committerAlan Modra <amodra@gmail.com>2015-07-22 22:04:28 +0930
commit511b1657d2b251e529a7a0634325bb7d8f3af80d (patch)
tree85f87f4c5a71ab622a62b7e61bebc6d8d0b6c720 /gas/input-scrub.c
parent5b2af7dd40a4f3b570aef71daf11b9dfce9a5d13 (diff)
downloadgdb-511b1657d2b251e529a7a0634325bb7d8f3af80d.zip
gdb-511b1657d2b251e529a7a0634325bb7d8f3af80d.tar.gz
gdb-511b1657d2b251e529a7a0634325bb7d8f3af80d.tar.bz2
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.
Diffstat (limited to 'gas/input-scrub.c')
-rw-r--r--gas/input-scrub.c100
1 files changed, 45 insertions, 55 deletions
diff --git a/gas/input-scrub.c b/gas/input-scrub.c
index b94f4e4..c8e1e29 100644
--- a/gas/input-scrub.c
+++ b/gas/input-scrub.c
@@ -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;
-
- while (p <= buffer_start + BEFORE_SIZE)
+ char *p;
+
+ *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