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