From 155e7bc479aeebdb1570884abe7b21fa93b0c7fd Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Tue, 23 Mar 1993 13:34:55 +0000 Subject: [PATCH] (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. --- gas/config/obj-coffbfd.c | 141 +++++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 64 deletions(-) diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c index c8b70603fc7..2cce1aebd88 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 */ -- 2.30.2