/* wrstabs.c -- Output stabs debugging information
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@cygnus.com>.
This file is part of GNU Binutils.
struct string_hash_entry
{
struct bfd_hash_entry root;
+ /* Next string in this table. */
+ struct string_hash_entry *next;
/* Index in string table. */
long index;
/* Size of type if this is a typedef. */
bfd_byte *symbols;
size_t symbols_size;
size_t symbols_alloc;
- /* This buffer holds the strings. */
- bfd_byte *strings;
+ /* This is a list of hash table entries for the strings. */
+ struct string_hash_entry *strings;
+ /* The last string hash table entry. */
+ struct string_hash_entry *last_string;
+ /* The size of the strings. */
size_t strings_size;
- size_t strings_alloc;
/* This hash table eliminates duplicate strings. */
struct string_hash_table strhash;
/* The type stack. */
if (ret)
{
/* Initialize the local fields. */
+ ret->next = NULL;
ret->index = -1;
ret->size = 0;
}
{
struct string_hash_entry *h;
- h = string_hash_lookup (&info->strhash, string, true, false);
+ h = string_hash_lookup (&info->strhash, string, true, true);
if (h == NULL)
{
- fprintf (stderr, "string_hash_lookup failed: %s\n",
- bfd_errmsg (bfd_get_error ()));
+ non_fatal (_("string_hash_lookup failed: %s"),
+ bfd_errmsg (bfd_get_error ()));
return false;
}
if (h->index != -1)
strx = h->index;
else
{
- size_t len;
-
strx = info->strings_size;
h->index = strx;
-
- len = strlen (string);
- while (info->strings_size + len + 1 > info->strings_alloc)
- {
- info->strings_alloc *= 2;
- info->strings = (bfd_byte *) xrealloc (info->strings,
- info->strings_alloc);
- }
- strcpy (info->strings + info->strings_size, string);
- info->strings_size += len + 1;
+ if (info->last_string == NULL)
+ info->strings = h;
+ else
+ info->last_string->next = h;
+ info->last_string = h;
+ info->strings_size += strlen (string) + 1;
}
}
bfd_size_type *pstringsize;
{
struct stab_write_handle info;
+ struct string_hash_entry *h;
+ bfd_byte *p;
info.abfd = abfd;
info.symbols_alloc = 500;
info.symbols = (bfd_byte *) xmalloc (info.symbols_alloc);
+ info.strings = NULL;
+ info.last_string = NULL;
+ /* Reserve 1 byte for a null byte. */
info.strings_size = 1;
- info.strings_alloc = 500;
- info.strings = (bfd_byte *) xmalloc (info.strings_alloc);
- info.strings[0] = '\0';
if (! bfd_hash_table_init (&info.strhash.table, string_hash_newfunc)
|| ! bfd_hash_table_init (&info.typedef_hash.table, string_hash_newfunc))
{
- fprintf (stderr, "bfd_hash_table_init_failed: %s\n",
- bfd_errmsg (bfd_get_error ()));
+ non_fatal ("bfd_hash_table_init_failed: %s",
+ bfd_errmsg (bfd_get_error ()));
return false;
}
*psyms = info.symbols;
*psymsize = info.symbols_size;
- *pstrings = info.strings;
*pstringsize = info.strings_size;
+ *pstrings = (bfd_byte *) xmalloc (info.strings_size);
+
+ p = *pstrings;
+ *p++ = '\0';
+ for (h = info.strings; h != NULL; h = h->next)
+ {
+ strcpy ((char *) p, h->root.string);
+ p += strlen ((char *) p) + 1;
+ }
return true;
}
if (size <= 0 || (size > sizeof (long) && size != 8))
{
- fprintf (stderr, "stab_int_type: bad size %u\n", size);
+ non_fatal (_("stab_int_type: bad size %u"), size);
return false;
}
for (pn = names; *pn != NULL; pn++)
len += strlen (*pn) + 20;
+ buf = (char *) xmalloc (len);
+
if (tag == NULL)
strcpy (buf, "e");
else
sprintf (buf, "%s:T%ld=e", tag, index);
}
- buf = (char *) xmalloc (len);
for (pn = names, pv = vals; *pn != NULL; pn++, pv++)
sprintf (buf + strlen (buf), "%s:%ld,", *pn, (long) *pv);
strcat (buf, ";");
}
else
{
- if (targindex >= *cache_alloc)
+ if ((size_t) targindex >= *cache_alloc)
{
size_t alloc;
alloc = *cache_alloc;
if (alloc == 0)
alloc = 10;
- while (targindex >= alloc)
+ while ((size_t) targindex >= alloc)
alloc *= 2;
*cache = (long *) xrealloc (*cache, alloc * sizeof (long));
memset (*cache + *cache_alloc, 0,
}
index = (*cache)[targindex];
- if (index != 0)
+ if (index != 0 && ! info->type_stack->definition)
{
- /* If we have already defined a modification of this type,
- then the entry on the type stack can not be a definition,
- so we can safely discard it. */
- assert (! info->type_stack->definition);
+ /* We have already defined a modification of this type, and
+ the entry on the type stack is not a definition, so we
+ can safely discard it (we may have a definition on the
+ stack, even if we already defined a modification, if it
+ is a struct which we did not define at the time it was
+ referenced). */
free (stab_pop_type (info));
if (! stab_push_defined_type (info, index, size))
return false;
stab_function_type (p, argcount, varargs)
PTR p;
int argcount;
- boolean varargs;
+ boolean varargs ATTRIBUTE_UNUSED;
{
struct stab_write_handle *info = (struct stab_write_handle *) p;
int i;
/* We have no way to represent the argument types, so we just
discard them. However, if they define new types, we must output
- them. We do this by producing meaningless typedefs. */
+ them. We do this by producing empty typedefs. */
for (i = 0; i < argcount; i++)
{
if (! info->type_stack->definition)
else
{
char *s, *buf;
- long index;
s = stab_pop_type (info);
- buf = (char *) xmalloc (strlen (s) + 40);
- index = info->type_index;
- ++info->type_index;
- sprintf (buf, "__fake_type_%ld:t%s", index, s);
-
+ buf = (char *) xmalloc (strlen (s) + 3);
+ sprintf (buf, ":t%s", s);
free (s);
if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
sprintf (buf, "%ld=@S;", index);
}
- sprintf (buf + strlen (buf), "ar%s;%ld;%ld;%s", range, low, high, element);
+ sprintf (buf + strlen (buf), "ar%s;%ld;%ld;%s",
+ range, (long) low, (long) high, element);
free (range);
free (element);
- if (high <= low)
+ if (high < low)
size = 0;
else
size = element_size * ((high - low) + 1);
{
bitsize = size * 8;
if (bitsize == 0)
- fprintf (stderr,
- "%s: warning: unknown size for field `%s' in struct\n",
- bfd_get_filename (info->abfd), name);
+ non_fatal (_("%s: warning: unknown size for field `%s' in struct"),
+ bfd_get_filename (info->abfd), name);
}
sprintf (n, "%s%s:%s%s,%ld,%ld;", info->type_stack->fields, name, vis, s,
{
struct stab_write_handle *info = (struct stab_write_handle *) p;
size_t len;
- unsigned int i;
+ unsigned int i = 0;
char *buf;
assert (info->type_stack != NULL && info->type_stack->fields != NULL);
h = string_hash_lookup (&info->typedef_hash, name, true, false);
if (h == NULL)
{
- fprintf (stderr, "string_hash_lookup failed: %s\n",
- bfd_errmsg (bfd_get_error ()));
+ non_fatal (_("string_hash_lookup failed: %s"),
+ bfd_errmsg (bfd_get_error ()));
return false;
}
kindstr = "";
/* Make sure that this is a type reference or definition. */
- if (! isdigit (*s))
+ if (! isdigit ((unsigned char) *s))
{
char *n;
long index;
break;
case DEBUG_REGISTER:
- stab_type = N_LSYM;
+ stab_type = N_RSYM;
kindstr = "r";
break;
}
/*ARGSUSED*/
static boolean
stab_end_function (p)
- PTR p;
+ PTR p ATTRIBUTE_UNUSED;
{
return true;
}