PATCH: Allocate sufficient space for string buffer
H.J. Lu
hjl.tools@gmail.com
Fri Jun 8 03:08:00 GMT 2012
On Thu, Jun 7, 2012 at 7:36 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Jun 7, 2012 at 7:09 PM, Alan Modra <amodra@gmail.com> wrote:
>> On Thu, Jun 07, 2012 at 11:58:45AM -0700, H.J. Lu wrote:
>>> * input-scrub.c (input_scrub_include_sb): Use sb_build to
>>> allocate sufficient space for from_sb.
>>> * read.c (do_repeat): Use sb_build to allocate sufficient space
>>> for many.
>>> * sb.c (sb_build): Remove static.
>>> * sb.h (sb_build): New prototype.
>>
>> Seems a reasonable optimisation. OK, but
>>
>>> - sb_new (&many);
>>> + sb_build (&many, count * one.len + 1);
>>
>> looks wrong to me. sb_build already adds one to account for the
>> string terminator.
>
> We have
>
> static void
> sb_check (sb *ptr, size_t len)
> {
> size_t max = ptr->max;
>
> while (ptr->len + len >= max)
> {
> max <<= 1;
> if (max == 0)
> as_fatal ("string buffer overflow");
> }
> if (max != ptr->max)
> {
> ptr->max = max;
> ptr->ptr = xrealloc (ptr->ptr, max + 1);
> }
> }
>
> If ptr->len + len == ptr->max, we double the size.
> Should it be changed to
>
> while (ptr->len + len > max)
>
Here is a new patch. It increases max size by
dsize at a time instead of double only if needed. OK
to install?
--
H.J.
--
2012-06-07 H.J. Lu <hongjiu.lu@intel.com>
* input-scrub.c (input_scrub_include_sb): Use sb_build to
allocate sufficient space for from_sb.
* read.c (do_repeat): Use sb_build to allocate sufficient space
for many.
* sb.c (sb_build): Remove static.
(sb_check): Increase max size by dsize only if needed.
* sb.h (sb_build): New prototype.
diff --git a/gas/input-scrub.c b/gas/input-scrub.c
index 46dd244..1b09b73 100644
--- a/gas/input-scrub.c
+++ b/gas/input-scrub.c
@@ -264,6 +264,8 @@ input_scrub_include_file (char *filename, char *position)
void
input_scrub_include_sb (sb *from, char *position, int is_expansion)
{
+ int newline;
+
if (macro_nest > max_macro_nest)
as_fatal (_("macros nested too deeply"));
++macro_nest;
@@ -277,9 +279,11 @@ input_scrub_include_sb (sb *from, char *position,
int is_expansion)
next_saved_file = input_scrub_push (position);
- sb_new (&from_sb);
+ /* Allocate sufficient space: from->len + optional newline + '\0'. */
+ newline = from->len >= 1 && from->ptr[0] != '\n';
+ sb_build (&from_sb, from->len + newline + 1);
from_sb_is_expansion = is_expansion;
- if (from->len >= 1 && from->ptr[0] != '\n')
+ if (newline)
{
/* Add the sentinel required by read.c. */
sb_add_char (&from_sb, '\n');
diff --git a/gas/read.c b/gas/read.c
index 2b37173..c52c6eb 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -3207,7 +3207,7 @@ do_repeat (int count, const char *start, const char *end)
return;
}
- sb_new (&many);
+ sb_build (&many, count * one.len);
while (count-- > 0)
sb_add_sb (&many, &one);
diff --git a/gas/sb.c b/gas/sb.c
index f345fe1..62ec7cc 100644
--- a/gas/sb.c
+++ b/gas/sb.c
@@ -44,7 +44,7 @@ static void sb_check (sb *, size_t);
/* Initializes an sb. */
-static void
+void
sb_build (sb *ptr, size_t size)
{
ptr->ptr = xmalloc (size + 1);
@@ -116,10 +116,10 @@ sb_check (sb *ptr, size_t len)
{
size_t max = ptr->max;
- while (ptr->len + len >= max)
+ while (ptr->len + len > max)
{
- max <<= 1;
- if (max == 0)
+ max += dsize;
+ if (max <= ptr->max)
as_fatal ("string buffer overflow");
}
if (max != ptr->max)
diff --git a/gas/sb.h b/gas/sb.h
index cc11ef6..ea010ee 100644
--- a/gas/sb.h
+++ b/gas/sb.h
@@ -53,6 +53,7 @@ typedef struct sb
sb;
extern void sb_new (sb *);
+extern void sb_build (sb *, size_t);
extern void sb_kill (sb *);
extern void sb_add_sb (sb *, sb *);
extern void sb_scrub_and_add_sb (sb *, sb *);
More information about the Binutils
mailing list