file_ptr where));
/* Obstack allocation and deallocation routines. */
-#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
\f
/* The minimum amount of data to allocate. */
newbuf = (char *) realloc (*buf, have + want);
if (newbuf == NULL)
{
- bfd_error = no_memory;
+ bfd_set_error (bfd_error_no_memory);
return false;
}
*buf = newbuf;
if (ret == (struct string_hash_entry *) NULL)
ret = ((struct string_hash_entry *)
bfd_hash_allocate (table, sizeof (struct string_hash_entry)));
+ if (ret == (struct string_hash_entry *) NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
/* Call the allocation method of the superclass. */
ret = ((struct string_hash_entry *)
bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
- /* Initialize the local fields. */
- ret->val = -1;
- ret->next = NULL;
+ if (ret)
+ {
+ /* Initialize the local fields. */
+ ret->val = -1;
+ ret->next = NULL;
+ }
return (struct bfd_hash_entry *) ret;
}
/* Add a file entry to a shuffle list. */
-static void add_file_shuffle PARAMS ((struct accumulate *,
+static boolean add_file_shuffle PARAMS ((struct accumulate *,
struct shuffle **,
struct shuffle **, bfd *, file_ptr,
unsigned long));
-static void
+static boolean
add_file_shuffle (ainfo, head, tail, input_bfd, offset, size)
struct accumulate *ainfo;
struct shuffle **head;
(*tail)->size += size;
if ((*tail)->size > ainfo->largest_file_shuffle)
ainfo->largest_file_shuffle = (*tail)->size;
- return;
+ return true;
}
n = (struct shuffle *) obstack_alloc (&ainfo->memory,
sizeof (struct shuffle));
+ if (!n)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
n->next = NULL;
n->size = size;
n->filep = true;
*tail = n;
if (size > ainfo->largest_file_shuffle)
ainfo->largest_file_shuffle = size;
+ return true;
}
/* Add a memory entry to a shuffle list. */
-static void add_memory_shuffle PARAMS ((struct accumulate *,
- struct shuffle **head,
- struct shuffle **tail,
- bfd_byte *data, unsigned long size));
+static boolean add_memory_shuffle PARAMS ((struct accumulate *,
+ struct shuffle **head,
+ struct shuffle **tail,
+ bfd_byte *data, unsigned long size));
-static void
+static boolean
add_memory_shuffle (ainfo, head, tail, data, size)
struct accumulate *ainfo;
struct shuffle **head;
n = (struct shuffle *) obstack_alloc (&ainfo->memory,
sizeof (struct shuffle));
+ if (!n)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
n->next = NULL;
n->size = size;
n->filep = false;
if (*tail != (struct shuffle *) NULL)
(*tail)->next = n;
*tail = n;
+ return true;
}
/* Initialize the FDR hash table. This returns a handle which is then
{
struct accumulate *ainfo;
- ainfo = (struct accumulate *) bfd_xmalloc (sizeof (struct accumulate));
+ ainfo = (struct accumulate *) malloc (sizeof (struct accumulate));
+ if (!ainfo)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
if (! bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc,
1021))
return NULL;
output_debug->symbolic_header.issMax = 1;
}
- obstack_begin (&ainfo->memory, 4050);
+ if (!obstack_begin (&ainfo->memory, 4050))
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
return (PTR) ainfo;
}
sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size;
rfd_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
- add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz);
+ if (!input_debug->ifdmap || !rfd_out)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (!add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz))
+ return false;
copied = 0;
hash reduces the chance that we will merge symbol
information that should not be merged. */
name = input_debug->ss + fdr.issBase + fdr.rss;
- lookup = (char *) alloca (strlen (name) + 20);
+
+ lookup = (char *) malloc (strlen (name) + 20);
+ if (lookup == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
sprintf (lookup, "%s %lx", name, fdr.csym);
fh = string_hash_lookup (&ainfo->fdr_hash, lookup, true, true);
+ free (lookup);
if (fh == (struct string_hash_entry *) NULL)
return false;
information. */
sz = copied * external_fdr_size;
fdr_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
- add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz);
+ if (!fdr_out)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz))
+ return false;
for (fdr_ptr = fdr_start, i = 0;
fdr_ptr < fdr_end;
fdr_ptr += fdr_add, i++)
{
FDR fdr;
+ bfd_vma fdr_adr;
bfd_byte *sym_out;
bfd_byte *lraw_src;
bfd_byte *lraw_end;
else
(*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
+ fdr_adr = fdr.adr;
+
+ /* Adjust the FDR address for any changes that may have been
+ made by relaxing. */
+ if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
+ {
+ struct ecoff_value_adjust *adjust;
+
+ for (adjust = input_debug->adjust;
+ adjust != (struct ecoff_value_adjust *) NULL;
+ adjust = adjust->next)
+ if (fdr_adr >= adjust->start
+ && fdr_adr < adjust->end)
+ fdr.adr += adjust->adjust;
+ }
+
/* FIXME: It is conceivable that this FDR points to the .init or
.fini section, in which case this will not do the right
thing. */
fgotfilename = false;
sz = fdr.csym * external_sym_size;
sym_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
- add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out, sz);
+ if (!sym_out)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out,
+ sz))
+ return false;
lraw_src = ((bfd_byte *) input_debug->external_sym
+ fdr.isymBase * input_swap->external_sym_size);
lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size;
case stLabel:
case stProc:
case stStaticProc:
+ if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
+ {
+ bfd_vma value;
+ struct ecoff_value_adjust *adjust;
+
+ value = internal_sym.value;
+ for (adjust = input_debug->adjust;
+ adjust != (struct ecoff_value_adjust *) NULL;
+ adjust = adjust->next)
+ if (value >= adjust->start
+ && value < adjust->end)
+ internal_sym.value += adjust->adjust;
+ }
internal_sym.value += section_adjust[internal_sym.sc];
break;
output_symhdr->isymMax += fdr.csym;
/* Copy the information that does not need swapping. */
+
+ /* FIXME: If we are relaxing, we need to adjust the line
+ numbers. Frankly, forget it. Anybody using stabs debugging
+ information will not use this line number information, and
+ stabs are adjusted correctly. */
if (fdr.cbLine > 0)
{
- add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
- input_bfd,
- input_symhdr->cbLineOffset + fdr.cbLineOffset,
- fdr.cbLine);
+ if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
+ input_bfd,
+ input_symhdr->cbLineOffset + fdr.cbLineOffset,
+ fdr.cbLine))
+ return false;
fdr.ilineBase = output_symhdr->ilineMax;
fdr.cbLineOffset = output_symhdr->cbLine;
output_symhdr->ilineMax += fdr.cline;
}
if (fdr.caux > 0)
{
- add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
- input_bfd,
- (input_symhdr->cbAuxOffset
- + fdr.iauxBase * sizeof (union aux_ext)),
- fdr.caux * sizeof (union aux_ext));
+ if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
+ input_bfd,
+ (input_symhdr->cbAuxOffset
+ + fdr.iauxBase * sizeof (union aux_ext)),
+ fdr.caux * sizeof (union aux_ext)))
+ return false;
fdr.iauxBase = output_symhdr->iauxMax;
output_symhdr->iauxMax += fdr.caux;
}
}
else if (fdr.cbSs > 0)
{
- add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
- input_bfd,
- input_symhdr->cbSsOffset + fdr.issBase,
- fdr.cbSs);
+ if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
+ input_bfd,
+ input_symhdr->cbSsOffset + fdr.issBase,
+ fdr.cbSs))
+ return false;
fdr.issBase = output_symhdr->issMax;
output_symhdr->issMax += fdr.cbSs;
}
- if (output_bfd->xvec->header_byteorder_big_p
- == input_bfd->xvec->header_byteorder_big_p)
+ if ((output_bfd->xvec->header_byteorder_big_p
+ == input_bfd->xvec->header_byteorder_big_p)
+ && input_debug->adjust == (struct ecoff_value_adjust *) NULL)
{
- /* The two BFD's have the same endianness, so simply copying
- the information will suffice. */
+ /* The two BFD's have the same endianness, and we don't have
+ to adjust the PDR addresses, so simply copying the
+ information will suffice. */
BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);
if (fdr.cpd > 0)
- add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
- input_bfd,
- (input_symhdr->cbPdOffset
- + fdr.ipdFirst * external_pdr_size),
- fdr.cpd * external_pdr_size);
+ {
+ if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
+ input_bfd,
+ (input_symhdr->cbPdOffset
+ + fdr.ipdFirst * external_pdr_size),
+ fdr.cpd * external_pdr_size))
+ return false;
+ }
BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
if (fdr.copt > 0)
- add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
- input_bfd,
- (input_symhdr->cbOptOffset
- + fdr.ioptBase * external_opt_size),
- fdr.copt * external_opt_size);
+ {
+ if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
+ input_bfd,
+ (input_symhdr->cbOptOffset
+ + fdr.ioptBase * external_opt_size),
+ fdr.copt * external_opt_size))
+ return false;
+ }
}
else
{
end = in + fdr.cpd * insz;
sz = fdr.cpd * outsz;
out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
- add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out, sz);
+ if (!out)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out,
+ sz))
+ return false;
for (; in < end; in += insz, out += outsz)
{
PDR pdr;
(*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr);
+
+ /* If we have been relaxing, we may have to adjust the
+ address. */
+ if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
+ {
+ bfd_vma adr;
+ struct ecoff_value_adjust *adjust;
+
+ adr = fdr_adr + pdr.adr;
+ for (adjust = input_debug->adjust;
+ adjust != (struct ecoff_value_adjust *) NULL;
+ adjust = adjust->next)
+ if (adr >= adjust->start
+ && adr < adjust->end)
+ pdr.adr += adjust->adjust;
+ }
+
(*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out);
}
end = in + fdr.copt * insz;
sz = fdr.copt * outsz;
out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
- add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out, sz);
+ if (!out)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out,
+ sz))
+ return false;
for (; in < end; in += insz, out += outsz)
{
OPTR opt;
len = strlen (string);
if (info->relocateable)
{
- add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string,
- len + 1);
+ if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string,
+ len + 1))
+ return -1;
ret = symhdr->issMax;
symhdr->issMax += len + 1;
fdr->cbSs += len + 1;
sh = string_hash_lookup (&ainfo->str_hash, string, true, true);
if (sh == (struct string_hash_entry *) NULL)
- return (bfd_size_type) -1;
+ return -1;
if (sh->val == -1)
{
sh->val = symhdr->issMax;
asymbol **symbols;
asymbol **sym_ptr;
asymbol **sym_end;
+ long symsize;
+ long symcount;
PTR external_fdr;
- memset (&fdr, 0, sizeof fdr);
+ memset ((PTR) &fdr, 0, sizeof fdr);
sec = bfd_get_section_by_name (input_bfd, ".text");
if (sec != NULL)
fdr.isymBase = output_symhdr->isymMax;
/* Get the local symbols from the input BFD. */
- symbols = (asymbol **) bfd_alloc (output_bfd,
- get_symtab_upper_bound (input_bfd));
+ symsize = bfd_get_symtab_upper_bound (input_bfd);
+ if (symsize < 0)
+ return false;
+ symbols = (asymbol **) bfd_alloc (output_bfd, symsize);
if (symbols == (asymbol **) NULL)
{
- bfd_error = no_memory;
+ bfd_set_error (bfd_error_no_memory);
return false;
}
- sym_end = symbols + bfd_canonicalize_symtab (input_bfd, symbols);
+ symcount = bfd_canonicalize_symtab (input_bfd, symbols);
+ if (symcount < 0)
+ return false;
+ sym_end = symbols + symcount;
/* Handle the local symbols. Any external symbols are handled
separately. */
if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
continue;
- memset (&internal_sym, 0, sizeof internal_sym);
+ memset ((PTR) &internal_sym, 0, sizeof internal_sym);
internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,
(*sym_ptr)->name);
external_sym = (PTR) obstack_alloc (&ainfo->memory,
output_swap->external_sym_size);
+ if (!external_sym)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
(*swap_sym_out) (output_bfd, &internal_sym, external_sym);
add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,
external_sym, output_swap->external_sym_size);
it only applies to aux fields and there are none. */
external_fdr = (PTR) obstack_alloc (&ainfo->memory,
output_swap->external_fdr_size);
+ if (!external_fdr)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
(*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);
add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,
external_fdr, output_swap->external_fdr_size);
if (add != debug_align)
{
if (debug->line != (unsigned char *) NULL)
- memset (debug->line + symhdr->cbLine, 0, add);
+ memset ((PTR) (debug->line + symhdr->cbLine), 0, add);
symhdr->cbLine += add;
}
if (add != debug_align)
{
if (debug->ss != (char *) NULL)
- memset (debug->ss + symhdr->issMax, 0, add);
+ memset ((PTR) (debug->ss + symhdr->issMax), 0, add);
symhdr->issMax += add;
}
if (add != debug_align)
{
if (debug->ssext != (char *) NULL)
- memset (debug->ssext + symhdr->issExtMax, 0, add);
+ memset ((PTR) (debug->ssext + symhdr->issExtMax), 0, add);
symhdr->issExtMax += add;
}
if (add != aux_align)
{
if (debug->external_aux != (union aux_ext *) NULL)
- memset (debug->external_aux + symhdr->iauxMax, 0,
+ memset ((PTR) (debug->external_aux + symhdr->iauxMax), 0,
add * sizeof (union aux_ext));
symhdr->iauxMax += add;
}
if (add != rfd_align)
{
if (debug->external_rfd != (PTR) NULL)
- memset (((char *) debug->external_rfd
- + symhdr->crfd * swap->external_rfd_size),
+ memset ((PTR) ((char *) debug->external_rfd
+ + symhdr->crfd * swap->external_rfd_size),
0, add * swap->external_rfd_size);
symhdr->crfd += add;
}
file_ptr where;
{
HDRR * const symhdr = &debug->symbolic_header;
- char *buff;
+ char *buff = NULL;
ecoff_align_debug (abfd, debug, swap);
where += swap->external_hdr_size;
+ symhdr->magic = swap->sym_magic;
+
/* Fill in the file offsets. */
#define SET(offset, count, size) \
if (symhdr->count == 0) \
SET (cbExtOffset, iextMax, swap->external_ext_size);
#undef SET
- buff = (PTR) alloca (swap->external_hdr_size);
+ buff = (PTR) malloc (swap->external_hdr_size);
+ if (buff == NULL && swap->external_hdr_size != 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ goto error_return;
+ }
+
(*swap->swap_hdr_out) (abfd, symhdr, buff);
if (bfd_write (buff, 1, swap->external_hdr_size, abfd)
!= swap->external_hdr_size)
- return false;
+ goto error_return;
+ if (buff != NULL)
+ free (buff);
return true;
+ error_return:
+ if (buff != NULL)
+ free (buff);
+ return false;
}
/* Write out the ECOFF debugging information. This function assumes
bfd_byte *s;
i = swap->debug_align - (total & (swap->debug_align - 1));
- s = (bfd_byte *) alloca (i);
- memset (s, 0, i);
+ s = (bfd_byte *) malloc (i);
+ if (s == NULL && i != 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+
+ memset ((PTR) s, 0, i);
if (bfd_write ((PTR) s, 1, i, abfd) != i)
- return false;
+ {
+ free (s);
+ return false;
+ }
+ free (s);
}
return true;
file_ptr where;
{
struct accumulate *ainfo = (struct accumulate *) handle;
- PTR space;
+ PTR space = NULL;
if (! ecoff_write_symhdr (abfd, debug, swap, where))
- return false;
+ goto error_return;
- space = (PTR) alloca (ainfo->largest_file_shuffle);
+ space = (PTR) malloc (ainfo->largest_file_shuffle);
+ if (space == NULL && ainfo->largest_file_shuffle != 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ goto error_return;
+ }
if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
|| ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
|| ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
|| ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
|| ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
- return false;
+ goto error_return;
/* The string table is written out from the hash table if this is a
final link. */
{
BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
- return false;
+ goto error_return;
}
else
{
BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
null = 0;
if (bfd_write ((PTR) &null, 1, 1, abfd) != 1)
- return false;
+ goto error_return;
total = 1;
BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
for (sh = ainfo->ss_hash;
len = strlen (sh->root.string);
if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1)
- return false;
+ goto error_return;
total += len + 1;
}
bfd_byte *s;
i = swap->debug_align - (total & (swap->debug_align - 1));
- s = (bfd_byte *) alloca (i);
- memset (s, 0, i);
+ s = (bfd_byte *) malloc (i);
+ if (s == NULL && i != 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ goto error_return;
+ }
+ memset ((PTR) s, 0, i);
if (bfd_write ((PTR) s, 1, i, abfd) != i)
- return false;
+ {
+ free (s);
+ goto error_return;
+ }
+ free (s);
}
}
shuffles. FIXME: They probably should be. */
if (bfd_write (debug->ssext, 1, debug->symbolic_header.issExtMax, abfd)
!= debug->symbolic_header.issExtMax)
- return false;
+ goto error_return;
if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
{
int i;
i = (swap->debug_align
- (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
- s = (bfd_byte *) alloca (i);
- memset (s, 0, i);
+ s = (bfd_byte *) malloc (i);
+ if (s == NULL && i != 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ goto error_return;
+ }
+ memset ((PTR) s, 0, i);
if (bfd_write ((PTR) s, 1, i, abfd) != i)
- return false;
+ {
+ free (s);
+ goto error_return;
+ }
+ free (s);
}
if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
|| ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
- return false;
+ goto error_return;
BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
|| debug->symbolic_header.cbExtOffset == bfd_tell (abfd));
if (bfd_write (debug->external_ext, swap->external_ext_size,
debug->symbolic_header.iextMax, abfd)
!= debug->symbolic_header.iextMax * swap->external_ext_size)
- return false;
+ goto error_return;
+ if (space != NULL)
+ free (space);
return true;
+
+ error_return:
+ if (space != NULL)
+ free (space);
+ return false;
}