(do_relocs_for): Don't allocate storage or process relocs if there aren't any

relocs to process.  Avoids malloc/free bug on SCO too.
This commit is contained in:
Ken Raeburn 1993-03-23 13:34:55 +00:00
parent 214d840f9a
commit 155e7bc479

View File

@ -364,95 +364,108 @@ DEFUN (do_relocs_for, (abfd, h, file_cursor),
fixS *fix_ptr = segment_info[idx].fix_root;
nrelocs = count_entries_in_chain (idx);
external_reloc_size = nrelocs * RELSZ;
external_reloc_vec =
(struct external_reloc *) malloc (external_reloc_size);
ext_ptr = external_reloc_vec;
/* Fill in the internal coff style reloc struct from the
internal fix list. */
while (fix_ptr)
if (nrelocs)
/* Bypass this stuff if no relocs. This also incidentally
avoids a SCO bug, where free(malloc(0)) tends to crash. */
{
symbolS *symbol_ptr;
struct internal_reloc intr;
external_reloc_size = nrelocs * RELSZ;
external_reloc_vec =
(struct external_reloc *) malloc (external_reloc_size);
/* Only output some of the relocations */
if (TC_COUNT_RELOC (fix_ptr))
ext_ptr = external_reloc_vec;
/* Fill in the internal coff style reloc struct from the
internal fix list. */
while (fix_ptr)
{
symbolS *symbol_ptr;
struct internal_reloc intr;
/* Only output some of the relocations */
if (TC_COUNT_RELOC (fix_ptr))
{
#ifdef TC_RELOC_MANGLE
TC_RELOC_MANGLE (fix_ptr, &intr, base);
TC_RELOC_MANGLE (fix_ptr, &intr, base);
#else
symbolS *dot;
symbol_ptr = fix_ptr->fx_addsy;
symbolS *dot;
symbol_ptr = fix_ptr->fx_addsy;
intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
intr.r_vaddr =
base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
intr.r_vaddr =
base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
intr.r_offset = fix_ptr->fx_offset;
intr.r_offset = fix_ptr->fx_offset;
intr.r_offset = 0;
intr.r_offset = 0;
/* Turn the segment of the symbol into an offset. */
if (symbol_ptr)
{
dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
if (dot)
/* Turn the segment of the symbol into an offset. */
if (symbol_ptr)
{
intr.r_symndx = dot->sy_number;
dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
if (dot)
{
intr.r_symndx = dot->sy_number;
}
else
{
intr.r_symndx = symbol_ptr->sy_number;
}
}
else
{
intr.r_symndx = symbol_ptr->sy_number;
intr.r_symndx = -1;
}
}
else
{
intr.r_symndx = -1;
}
#endif
(void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
ext_ptr++;
(void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
ext_ptr++;
#if defined(TC_A29K)
/* The 29k has a special kludge for the high 16 bit
reloc. Two relocations are emited, R_IHIHALF,
and R_IHCONST. The second one doesn't contain a
symbol, but uses the value for offset. */
/* The 29k has a special kludge for the high 16 bit
reloc. Two relocations are emited, R_IHIHALF,
and R_IHCONST. The second one doesn't contain a
symbol, but uses the value for offset. */
if (intr.r_type == R_IHIHALF)
{
/* now emit the second bit */
intr.r_type = R_IHCONST;
intr.r_symndx = fix_ptr->fx_addnumber;
if (intr.r_type == R_IHIHALF)
{
/* now emit the second bit */
intr.r_type = R_IHCONST;
intr.r_symndx = fix_ptr->fx_addnumber;
/* The offset to the segment holding the symbol
has already been counted in the R_IHIHALF.
We don't want to add it in again for the
R_IHCONST. */
if (symbol_ptr)
intr.r_symndx -=
segment_info[S_GET_SEGMENT (symbol_ptr)].scnhdr.s_paddr;
(void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
ext_ptr++;
}
/* The offset to the segment holding the symbol
has already been counted in the R_IHIHALF.
We don't want to add it in again for the
R_IHCONST. */
if (symbol_ptr)
intr.r_symndx -=
segment_info[S_GET_SEGMENT (symbol_ptr)].scnhdr.s_paddr;
(void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
ext_ptr++;
}
#endif
}
fix_ptr = fix_ptr->fx_next;
}
fix_ptr = fix_ptr->fx_next;
}
/* Write out the reloc table */
bfd_write ((PTR) external_reloc_vec, 1, external_reloc_size,
abfd);
free (external_reloc_vec);
/* Write out the reloc table */
segment_info[idx].scnhdr.s_relptr = nrelocs ? *file_cursor : 0;
segment_info[idx].scnhdr.s_nreloc = nrelocs;
bfd_write ((PTR) external_reloc_vec, 1, external_reloc_size, abfd);
*file_cursor += external_reloc_size;
free (external_reloc_vec);
/* Fill in section header info. */
segment_info[idx].scnhdr.s_relptr = *file_cursor;
*file_cursor += external_reloc_size;
}
else
{
/* No relocs */
segment_info[idx].scnhdr.s_relptr = 0;
}
segment_info[idx].scnhdr.s_nreloc = 0;
}
}
/* Set relocation_size field in file headers */