aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@cygnus>1993-03-23 13:34:55 +0000
committerKen Raeburn <raeburn@cygnus>1993-03-23 13:34:55 +0000
commit155e7bc479aeebdb1570884abe7b21fa93b0c7fd (patch)
treeb0ca85b3a7274ae3f5672cf941a60d692c00f755 /gas
parent214d840f9ae3d9cf1b273f7886e57243a0faa8b2 (diff)
downloadgdb-155e7bc479aeebdb1570884abe7b21fa93b0c7fd.zip
gdb-155e7bc479aeebdb1570884abe7b21fa93b0c7fd.tar.gz
gdb-155e7bc479aeebdb1570884abe7b21fa93b0c7fd.tar.bz2
(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.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/obj-coffbfd.c141
1 files changed, 77 insertions, 64 deletions
diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c
index c8b7060..2cce1ae 100644
--- a/gas/config/obj-coffbfd.c
+++ b/gas/config/obj-coffbfd.c
@@ -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);
+
+ ext_ptr = external_reloc_vec;
- /* Only output some of the relocations */
- 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
- 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;
-
- /* 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++;
- }
+ 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++;
+ }
#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 */