From 6d4d932867fa8b3c685b3a358bf81f7f6c6ea7d6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Cl=C3=A9ment=20Chigot?= Date: Thu, 11 Mar 2021 11:08:18 +0100 Subject: [PATCH] bfd: use default coff_write_object_contents for XCOFF64 There is no need for XCOFF64 to have is own write_object_contents. * coff64-rs6000.c (xcoff64_write_object_contents): Remove. * coffcode.h (coff_write_object_contents): Add bfd_mach_ppc_620 support for o_cputype field. Avoid creating an empty a.out header for XCOFF64. --- bfd/ChangeLog | 7 + bfd/coff64-rs6000.c | 352 +------------------------------------------- bfd/coffcode.h | 6 +- 3 files changed, 14 insertions(+), 351 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bf28d8a2414..95dcc5718ef 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2021-03-12 Clément Chigot + + * coff64-rs6000.c (xcoff64_write_object_contents): Remove. + * coffcode.h (coff_write_object_contents): Add bfd_mach_ppc_620 + support for o_cputype field. Avoid creating an empty a.out header + for XCOFF64. + 2021-03-12 Clément Chigot * coff64-rs6000.c (xcoff64_create_csect_from_smclas): Add diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 21287c73c1b..a31a6fb91a9 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -147,8 +147,6 @@ static void xcoff64_swap_ldrel_in (bfd *, const void *, struct internal_ldrel *); static void xcoff64_swap_ldrel_out (bfd *, const struct internal_ldrel *, void *d); -static bfd_boolean xcoff64_write_object_contents - (bfd *); static bfd_boolean xcoff64_ppc_relocate_section (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, struct internal_reloc *, struct internal_syment *, @@ -711,352 +709,6 @@ xcoff64_swap_ldrel_out (bfd *abfd, const struct internal_ldrel *src, void *d) bfd_put_32 (abfd, src->l_symndx, dst->l_symndx); } -static bfd_boolean -xcoff64_write_object_contents (bfd *abfd) -{ - asection *current; - bfd_boolean hasrelocs = FALSE; - bfd_boolean haslinno = FALSE; - file_ptr scn_base; - file_ptr reloc_base; - file_ptr lineno_base; - file_ptr sym_base; - unsigned long reloc_size = 0; - unsigned long lnno_size = 0; - asection *text_sec = NULL; - asection *data_sec = NULL; - asection *bss_sec = NULL; - struct internal_filehdr internal_f; - struct internal_aouthdr internal_a; - - bfd_set_error (bfd_error_system_call); - - if (! abfd->output_has_begun) - { - if (! bfd_coff_compute_section_file_positions (abfd)) - return FALSE; - } - - /* Work out the size of the reloc and linno areas. */ - reloc_base = obj_relocbase (abfd); - - for (current = abfd->sections; current != NULL; current = current->next) - reloc_size += current->reloc_count * bfd_coff_relsz (abfd); - - lineno_base = reloc_base + reloc_size; - - /* Make a pass through the symbol table to count line number entries and - put them into the correct asections. */ - lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd); - - sym_base = lineno_base + lnno_size; - - /* Indicate in each section->line_filepos its actual file address. */ - for (current = abfd->sections; current != NULL; current = current->next) - { - if (current->lineno_count) - { - current->line_filepos = lineno_base; - current->moving_line_filepos = lineno_base; - lineno_base += current->lineno_count * bfd_coff_linesz (abfd); - } - else - { - current->line_filepos = 0; - } - - if (current->reloc_count) - { - current->rel_filepos = reloc_base; - reloc_base += current->reloc_count * bfd_coff_relsz (abfd); - } - else - { - current->rel_filepos = 0; - } - } - - if ((abfd->flags & EXEC_P) != 0) - { - scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd); - internal_f.f_opthdr = bfd_coff_aoutsz (abfd); - } - else - { - scn_base = bfd_coff_filhsz (abfd); - internal_f.f_opthdr = 0; - } - - internal_f.f_nscns = 0; - - if (bfd_seek (abfd, scn_base, SEEK_SET) != 0) - return FALSE; - - for (current = abfd->sections; current != NULL; current = current->next) - { - struct internal_scnhdr section; - struct external_scnhdr buff; - bfd_size_type amount; - - internal_f.f_nscns++; - - strncpy (section.s_name, current->name, SCNNMLEN); - - section.s_vaddr = current->vma; - section.s_paddr = current->lma; - section.s_size = current->size; - - /* If this section has no size or is unloadable then the scnptr - will be 0 too. */ - if (current->size == 0 - || (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) - { - section.s_scnptr = 0; - } - else - { - section.s_scnptr = current->filepos; - } - - section.s_relptr = current->rel_filepos; - section.s_lnnoptr = current->line_filepos; - section.s_nreloc = current->reloc_count; - - section.s_nlnno = current->lineno_count; - if (current->reloc_count != 0) - hasrelocs = TRUE; - if (current->lineno_count != 0) - haslinno = TRUE; - - section.s_flags = sec_to_styp_flags (current->name, current->flags); - - if (!strcmp (current->name, _TEXT)) - { - text_sec = current; - } - else if (!strcmp (current->name, _DATA)) - { - data_sec = current; - } - else if (!strcmp (current->name, _BSS)) - { - bss_sec = current; - } - - amount = bfd_coff_scnhsz (abfd); - if (bfd_coff_swap_scnhdr_out (abfd, §ion, &buff) == 0 - || bfd_bwrite (&buff, amount, abfd) != amount) - return FALSE; - } - - internal_f.f_timdat = 0; - - internal_f.f_flags = 0; - - if (!hasrelocs) - internal_f.f_flags |= F_RELFLG; - if (!haslinno) - internal_f.f_flags |= F_LNNO; - if (abfd->flags & EXEC_P) - internal_f.f_flags |= F_EXEC; - - /* FIXME: this is wrong for PPC_PE! */ - if (bfd_little_endian (abfd)) - internal_f.f_flags |= F_AR32WR; - else - internal_f.f_flags |= F_AR32W; - - if ((abfd->flags & DYNAMIC) != 0) - internal_f.f_flags |= F_SHROBJ; - if (bfd_get_section_by_name (abfd, _LOADER) != NULL) - internal_f.f_flags |= F_DYNLOAD; - - memset (&internal_a, 0, sizeof internal_a); - - internal_f.f_magic = bfd_xcoff_magic_number (abfd); - internal_a.magic = (abfd->flags & D_PAGED - ? RS6K_AOUTHDR_ZMAGIC - : (abfd->flags & WP_TEXT - ? RS6K_AOUTHDR_NMAGIC - : RS6K_AOUTHDR_OMAGIC)); - - /* FIXME: Does anybody ever set this to another value? */ - internal_a.vstamp = 0; - - /* Now should write relocs, strings, syms. */ - obj_sym_filepos (abfd) = sym_base; - - internal_f.f_symptr = 0; - internal_f.f_nsyms = 0; - - /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF - backend linker, and obj_raw_syment_count is not valid until after - coff_write_symbols is called. */ - if (bfd_get_symcount (abfd) != 0) - { - int firstundef; - - if (!coff_renumber_symbols (abfd, &firstundef)) - return FALSE; - coff_mangle_symbols (abfd); - if (! coff_write_symbols (abfd)) - return FALSE; - if (! coff_write_linenumbers (abfd)) - return FALSE; - if (! coff_write_relocs (abfd, firstundef)) - return FALSE; - - internal_f.f_symptr = sym_base; - internal_f.f_nsyms = bfd_get_symcount (abfd); - } - else if (obj_raw_syment_count (abfd) != 0) - { - internal_f.f_symptr = sym_base; - - /* AIX appears to require that F_RELFLG not be set if there are - local symbols but no relocations. */ - internal_f.f_flags &=~ F_RELFLG; - } - else - { - internal_f.f_flags |= F_LSYMS; - } - - if (text_sec) - { - internal_a.tsize = text_sec->size; - internal_a.text_start = internal_a.tsize ? text_sec->vma : 0; - } - - if (data_sec) - { - internal_a.dsize = data_sec->size; - internal_a.data_start = internal_a.dsize ? data_sec->vma : 0; - } - - if (bss_sec) - { - internal_a.bsize = bss_sec->size; - if (internal_a.bsize && bss_sec->vma < internal_a.data_start) - internal_a.data_start = bss_sec->vma; - } - - internal_a.entry = bfd_get_start_address (abfd); - internal_f.f_nsyms = obj_raw_syment_count (abfd); - - if (xcoff_data (abfd)->full_aouthdr) - { - bfd_vma toc; - asection *loader_sec; - - internal_a.vstamp = 1; - - internal_a.o_snentry = xcoff_data (abfd)->snentry; - if (internal_a.o_snentry == 0) - internal_a.entry = (bfd_vma) -1; - - if (text_sec != NULL) - { - internal_a.o_sntext = text_sec->target_index; - internal_a.o_algntext = bfd_section_alignment (text_sec); - } - else - { - internal_a.o_sntext = 0; - internal_a.o_algntext = 0; - } - - if (data_sec != NULL) - { - internal_a.o_sndata = data_sec->target_index; - internal_a.o_algndata = bfd_section_alignment (data_sec); - } - else - { - internal_a.o_sndata = 0; - internal_a.o_algndata = 0; - } - - loader_sec = bfd_get_section_by_name (abfd, ".loader"); - if (loader_sec != NULL) - internal_a.o_snloader = loader_sec->target_index; - else - internal_a.o_snloader = 0; - if (bss_sec != NULL) - internal_a.o_snbss = bss_sec->target_index; - else - internal_a.o_snbss = 0; - - toc = xcoff_data (abfd)->toc; - internal_a.o_toc = toc; - internal_a.o_sntoc = xcoff_data (abfd)->sntoc; - - internal_a.o_modtype = xcoff_data (abfd)->modtype; - if (xcoff_data (abfd)->cputype != -1) - internal_a.o_cputype = xcoff_data (abfd)->cputype; - else - { - switch (bfd_get_arch (abfd)) - { - case bfd_arch_rs6000: - internal_a.o_cputype = 4; - break; - case bfd_arch_powerpc: - if (bfd_get_mach (abfd) == bfd_mach_ppc) - internal_a.o_cputype = 3; - else if (bfd_get_mach (abfd) == bfd_mach_ppc_620) - internal_a.o_cputype = 2; - else - internal_a.o_cputype = 1; - break; - default: - abort (); - } - } - internal_a.o_maxstack = xcoff_data (abfd)->maxstack; - internal_a.o_maxdata = xcoff_data (abfd)->maxdata; - } - - if (bfd_seek (abfd, (file_ptr) 0, 0) != 0) - return FALSE; - - { - char * buff; - bfd_size_type amount = bfd_coff_filhsz (abfd); - - buff = bfd_malloc (amount); - if (buff == NULL) - return FALSE; - - bfd_coff_swap_filehdr_out (abfd, &internal_f, buff); - amount = bfd_bwrite (buff, amount, abfd); - - free (buff); - - if (amount != bfd_coff_filhsz (abfd)) - return FALSE; - } - - if (abfd->flags & EXEC_P) - { - char * buff; - bfd_size_type amount = bfd_coff_aoutsz (abfd); - - buff = bfd_malloc (amount); - if (buff == NULL) - return FALSE; - - bfd_coff_swap_aouthdr_out (abfd, &internal_a, buff); - amount = bfd_bwrite (buff, amount, abfd); - - free (buff); - - if (amount != bfd_coff_aoutsz (abfd)) - return FALSE; - } - - return TRUE; -} static bfd_boolean xcoff64_reloc_type_br (bfd *input_bfd, @@ -2702,7 +2354,7 @@ const bfd_target rs6000_xcoff64_vec = {/* bfd_write_contents */ _bfd_bool_bfd_false_error, - xcoff64_write_object_contents, + coff_write_object_contents, _bfd_xcoff_write_archive_contents, _bfd_bool_bfd_false_error }, @@ -2966,7 +2618,7 @@ const bfd_target rs6000_xcoff64_aix_vec = {/* bfd_write_contents */ _bfd_bool_bfd_false_error, - xcoff64_write_object_contents, + coff_write_object_contents, _bfd_xcoff_write_archive_contents, _bfd_bool_bfd_false_error }, diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 814922ee11d..b0ca266fa0d 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -4058,6 +4058,8 @@ coff_write_object_contents (bfd * abfd) case bfd_arch_powerpc: if (bfd_get_mach (abfd) == bfd_mach_ppc) internal_a.o_cputype = 3; + else if (bfd_get_mach (abfd) == bfd_mach_ppc_620) + internal_a.o_cputype = 2; else internal_a.o_cputype = 1; break; @@ -4127,12 +4129,13 @@ coff_write_object_contents (bfd * abfd) #endif } #ifdef RS6000COFF_C +#ifndef XCOFF64 else { AOUTHDR buff; size_t size; - /* XCOFF seems to always write at least a small a.out header. */ + /* XCOFF32 seems to always write at least a small a.out header. */ coff_swap_aouthdr_out (abfd, & internal_a, & buff); if (xcoff_data (abfd)->full_aouthdr) size = bfd_coff_aoutsz (abfd); @@ -4141,6 +4144,7 @@ coff_write_object_contents (bfd * abfd) if (bfd_bwrite (& buff, (bfd_size_type) size, abfd) != size) return FALSE; } +#endif #endif return TRUE; -- 2.30.2