X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fsb.c;h=76d555e34024d2fe40ba2db28535479ff135fa4a;hb=134c0c8bf4a258ba10e72b724eadf40f731bb7ec;hp=f345fe13a9a95a8f9fe870ecbe37697a4ef53eba;hpb=39a45edc073226e748566b497c216830cec119c4;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/sb.c b/gas/sb.c index f345fe13a9..76d555e340 100644 --- a/gas/sb.c +++ b/gas/sb.c @@ -1,6 +1,5 @@ /* sb.c - string buffer manipulation routines - Copyright 1994, 1995, 2000, 2003, 2005, 2006, 2007, 2009, 2012 - Free Software Foundation, Inc. + Copyright (C) 1994-2016 Free Software Foundation, Inc. Written by Steve and Judy Chamberlain of Cygnus Support, sac@cygnus.com @@ -25,6 +24,13 @@ #include "as.h" #include "sb.h" +#ifdef HAVE_LIMITS_H +#include +#endif +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + /* These routines are about manipulating strings. They are managed in things called `sb's which is an abbreviation @@ -39,15 +45,21 @@ use foo->ptr[*]; sb_kill (&foo); */ -static size_t dsize = 32; +/* Buffers start at INIT_ALLOC size, and roughly double each time we + go over the current allocation. MALLOC_OVERHEAD is a guess at the + system malloc overhead. We aim to not waste any memory in the + underlying page/chunk allocated by the system malloc. */ +#define MALLOC_OVERHEAD (2 * sizeof (size_t)) +#define INIT_ALLOC (64 - MALLOC_OVERHEAD - 1) + 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); + ptr->ptr = XNEWVEC (char, size + 1); ptr->max = size; ptr->len = 0; } @@ -55,7 +67,7 @@ sb_build (sb *ptr, size_t size) void sb_new (sb *ptr) { - sb_build (ptr, dsize); + sb_build (ptr, INIT_ALLOC); } /* Deallocate the sb at ptr. */ @@ -100,7 +112,7 @@ sb_scrub_and_add_sb (sb *ptr, sb *s) { sb_to_scrub = s; scrub_position = s->ptr; - + sb_check (ptr, s->len); ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, s->len); @@ -114,18 +126,28 @@ sb_scrub_and_add_sb (sb *ptr, sb *s) static void sb_check (sb *ptr, size_t len) { - size_t max = ptr->max; + size_t want = ptr->len + len; - while (ptr->len + len >= max) + if (want > ptr->max) { - max <<= 1; - if (max == 0) + size_t max; + + want += MALLOC_OVERHEAD + 1; + if ((ssize_t) want < 0) as_fatal ("string buffer overflow"); - } - if (max != ptr->max) - { +#if GCC_VERSION >= 3004 + max = (size_t) 1 << (CHAR_BIT * sizeof (want) + - (sizeof (want) <= sizeof (long) + ? __builtin_clzl ((long) want) + : __builtin_clzll ((long long) want))); +#else + max = 128; + while (want > max) + max <<= 1; +#endif + max -= MALLOC_OVERHEAD + 1; ptr->max = max; - ptr->ptr = xrealloc (ptr->ptr, max + 1); + ptr->ptr = XRESIZEVEC (char, ptr->ptr, max + 1); } } @@ -167,13 +189,12 @@ sb_add_buffer (sb *ptr, const char *s, size_t len) ptr->len += len; } -/* Like sb_name, but don't include the null byte in the string. */ +/* Write terminating NUL and return string. */ char * sb_terminate (sb *in) { - sb_add_char (in, 0); - --in->len; + in->ptr[in->len] = 0; return in->ptr; }