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.
This commit is contained in:
parent
8aa2d0236a
commit
6d4d932867
@ -1,3 +1,10 @@
|
||||
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||
|
||||
* 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 <clement.chigot@atos.net>
|
||||
|
||||
* coff64-rs6000.c (xcoff64_create_csect_from_smclas): Add
|
||||
|
||||
@ -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
|
||||
},
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user