bfd: move xcoff64_ppc_relocate_section after the HOWTO table
This will be needed for later commits, as xcoff64_ppc_relocate_section will use the HOWTO table unlike now. * coff64-rs6000.c (xcoff64_ppc_relocate_section): Move.
This commit is contained in:
parent
6d4d932867
commit
0c929e83c1
@ -1,3 +1,7 @@
|
||||
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||
|
||||
* coff64-rs6000.c (xcoff64_ppc_relocate_section): Move.
|
||||
|
||||
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||
|
||||
* coff64-rs6000.c (xcoff64_write_object_contents): Remove.
|
||||
|
@ -814,194 +814,6 @@ xcoff64_reloc_type_br (bfd *input_bfd,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* This is the relocation function for the PowerPC64.
|
||||
See xcoff_ppc_relocation_section for more information. */
|
||||
|
||||
bfd_boolean
|
||||
xcoff64_ppc_relocate_section (bfd *output_bfd,
|
||||
struct bfd_link_info *info,
|
||||
bfd *input_bfd,
|
||||
asection *input_section,
|
||||
bfd_byte *contents,
|
||||
struct internal_reloc *relocs,
|
||||
struct internal_syment *syms,
|
||||
asection **sections)
|
||||
{
|
||||
struct internal_reloc *rel;
|
||||
struct internal_reloc *relend;
|
||||
|
||||
rel = relocs;
|
||||
relend = rel + input_section->reloc_count;
|
||||
for (; rel < relend; rel++)
|
||||
{
|
||||
long symndx;
|
||||
struct xcoff_link_hash_entry *h;
|
||||
struct internal_syment *sym;
|
||||
bfd_vma addend;
|
||||
bfd_vma val;
|
||||
struct reloc_howto_struct howto;
|
||||
bfd_vma relocation;
|
||||
bfd_vma value_to_relocate;
|
||||
bfd_vma address;
|
||||
bfd_byte *location;
|
||||
|
||||
/* Relocation type R_REF is a special relocation type which is
|
||||
merely used to prevent garbage collection from occurring for
|
||||
the csect including the symbol which it references. */
|
||||
if (rel->r_type == R_REF)
|
||||
continue;
|
||||
|
||||
/* howto */
|
||||
howto.type = rel->r_type;
|
||||
howto.rightshift = 0;
|
||||
howto.bitsize = (rel->r_size & 0x3f) + 1;
|
||||
howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
|
||||
howto.pc_relative = FALSE;
|
||||
howto.bitpos = 0;
|
||||
howto.complain_on_overflow = (rel->r_size & 0x80
|
||||
? complain_overflow_signed
|
||||
: complain_overflow_bitfield);
|
||||
howto.special_function = NULL;
|
||||
howto.name = "internal";
|
||||
howto.partial_inplace = TRUE;
|
||||
howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
|
||||
howto.pcrel_offset = FALSE;
|
||||
|
||||
/* symbol */
|
||||
val = 0;
|
||||
addend = 0;
|
||||
h = NULL;
|
||||
sym = NULL;
|
||||
symndx = rel->r_symndx;
|
||||
|
||||
if (-1 != symndx)
|
||||
{
|
||||
asection *sec;
|
||||
|
||||
h = obj_xcoff_sym_hashes (input_bfd)[symndx];
|
||||
sym = syms + symndx;
|
||||
addend = - sym->n_value;
|
||||
|
||||
if (NULL == h)
|
||||
{
|
||||
sec = sections[symndx];
|
||||
/* Hack to make sure we use the right TOC anchor value
|
||||
if this reloc is against the TOC anchor. */
|
||||
if (sec->name[3] == '0'
|
||||
&& strcmp (sec->name, ".tc0") == 0)
|
||||
val = xcoff_data (output_bfd)->toc;
|
||||
else
|
||||
val = (sec->output_section->vma
|
||||
+ sec->output_offset
|
||||
+ sym->n_value
|
||||
- sec->vma);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->unresolved_syms_in_objects != RM_IGNORE
|
||||
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0)
|
||||
info->callbacks->undefined_symbol
|
||||
(info, h->root.root.string, input_bfd, input_section,
|
||||
rel->r_vaddr - input_section->vma,
|
||||
info->unresolved_syms_in_objects == RM_DIAGNOSE
|
||||
&& !info->warn_unresolved_syms);
|
||||
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
sec = h->root.u.def.section;
|
||||
val = (h->root.u.def.value
|
||||
+ sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
else if (h->root.type == bfd_link_hash_common)
|
||||
{
|
||||
sec = h->root.u.c.p->section;
|
||||
val = (sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (bfd_link_relocatable (info)
|
||||
|| (h->flags & XCOFF_DEF_DYNAMIC) != 0
|
||||
|| (h->flags & XCOFF_IMPORT) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
|
||||
|| !((*xcoff64_calculate_relocation[rel->r_type])
|
||||
(input_bfd, input_section, output_bfd, rel, sym, &howto, val,
|
||||
addend, &relocation, contents)))
|
||||
return FALSE;
|
||||
|
||||
/* address */
|
||||
address = rel->r_vaddr - input_section->vma;
|
||||
location = contents + address;
|
||||
|
||||
if (address > input_section->size)
|
||||
abort ();
|
||||
|
||||
/* Get the value we are going to relocate. */
|
||||
if (1 == howto.size)
|
||||
value_to_relocate = bfd_get_16 (input_bfd, location);
|
||||
else if (2 == howto.size)
|
||||
value_to_relocate = bfd_get_32 (input_bfd, location);
|
||||
else
|
||||
value_to_relocate = bfd_get_64 (input_bfd, location);
|
||||
|
||||
/* overflow.
|
||||
|
||||
FIXME: We may drop bits during the addition
|
||||
which we don't check for. We must either check at every single
|
||||
operation, which would be tedious, or we must do the computations
|
||||
in a type larger than bfd_vma, which would be inefficient. */
|
||||
|
||||
if (((*xcoff_complain_overflow[howto.complain_on_overflow])
|
||||
(input_bfd, value_to_relocate, relocation, &howto)))
|
||||
{
|
||||
const char *name;
|
||||
char buf[SYMNMLEN + 1];
|
||||
char reloc_type_name[10];
|
||||
|
||||
if (symndx == -1)
|
||||
{
|
||||
name = "*ABS*";
|
||||
}
|
||||
else if (h != NULL)
|
||||
{
|
||||
name = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
|
||||
if (name == NULL)
|
||||
name = "UNKNOWN";
|
||||
}
|
||||
sprintf (reloc_type_name, "0x%02x", rel->r_type);
|
||||
|
||||
(*info->callbacks->reloc_overflow)
|
||||
(info, (h ? &h->root : NULL), name, reloc_type_name,
|
||||
(bfd_vma) 0, input_bfd, input_section,
|
||||
rel->r_vaddr - input_section->vma);
|
||||
}
|
||||
|
||||
/* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
|
||||
value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
|
||||
| (((value_to_relocate & howto.src_mask)
|
||||
+ relocation) & howto.dst_mask));
|
||||
|
||||
/* Put the value back in the object file. */
|
||||
if (1 == howto.size)
|
||||
bfd_put_16 (input_bfd, value_to_relocate, location);
|
||||
else if (2 == howto.size)
|
||||
bfd_put_32 (input_bfd, value_to_relocate, location);
|
||||
else
|
||||
bfd_put_64 (input_bfd, value_to_relocate, location);
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* The XCOFF reloc table. Actually, XCOFF relocations specify the
|
||||
@ -1496,6 +1308,196 @@ xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This is the relocation function for the PowerPC64.
|
||||
See xcoff_ppc_relocation_section for more information. */
|
||||
|
||||
bfd_boolean
|
||||
xcoff64_ppc_relocate_section (bfd *output_bfd,
|
||||
struct bfd_link_info *info,
|
||||
bfd *input_bfd,
|
||||
asection *input_section,
|
||||
bfd_byte *contents,
|
||||
struct internal_reloc *relocs,
|
||||
struct internal_syment *syms,
|
||||
asection **sections)
|
||||
{
|
||||
struct internal_reloc *rel;
|
||||
struct internal_reloc *relend;
|
||||
|
||||
rel = relocs;
|
||||
relend = rel + input_section->reloc_count;
|
||||
for (; rel < relend; rel++)
|
||||
{
|
||||
long symndx;
|
||||
struct xcoff_link_hash_entry *h;
|
||||
struct internal_syment *sym;
|
||||
bfd_vma addend;
|
||||
bfd_vma val;
|
||||
struct reloc_howto_struct howto;
|
||||
bfd_vma relocation;
|
||||
bfd_vma value_to_relocate;
|
||||
bfd_vma address;
|
||||
bfd_byte *location;
|
||||
|
||||
/* Relocation type R_REF is a special relocation type which is
|
||||
merely used to prevent garbage collection from occurring for
|
||||
the csect including the symbol which it references. */
|
||||
if (rel->r_type == R_REF)
|
||||
continue;
|
||||
|
||||
/* howto */
|
||||
howto.type = rel->r_type;
|
||||
howto.rightshift = 0;
|
||||
howto.bitsize = (rel->r_size & 0x3f) + 1;
|
||||
howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
|
||||
howto.pc_relative = FALSE;
|
||||
howto.bitpos = 0;
|
||||
howto.complain_on_overflow = (rel->r_size & 0x80
|
||||
? complain_overflow_signed
|
||||
: complain_overflow_bitfield);
|
||||
howto.special_function = NULL;
|
||||
howto.name = "internal";
|
||||
howto.partial_inplace = TRUE;
|
||||
howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
|
||||
howto.pcrel_offset = FALSE;
|
||||
|
||||
/* symbol */
|
||||
val = 0;
|
||||
addend = 0;
|
||||
h = NULL;
|
||||
sym = NULL;
|
||||
symndx = rel->r_symndx;
|
||||
|
||||
if (-1 != symndx)
|
||||
{
|
||||
asection *sec;
|
||||
|
||||
h = obj_xcoff_sym_hashes (input_bfd)[symndx];
|
||||
sym = syms + symndx;
|
||||
addend = - sym->n_value;
|
||||
|
||||
if (NULL == h)
|
||||
{
|
||||
sec = sections[symndx];
|
||||
/* Hack to make sure we use the right TOC anchor value
|
||||
if this reloc is against the TOC anchor. */
|
||||
if (sec->name[3] == '0'
|
||||
&& strcmp (sec->name, ".tc0") == 0)
|
||||
val = xcoff_data (output_bfd)->toc;
|
||||
else
|
||||
val = (sec->output_section->vma
|
||||
+ sec->output_offset
|
||||
+ sym->n_value
|
||||
- sec->vma);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->unresolved_syms_in_objects != RM_IGNORE
|
||||
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0)
|
||||
info->callbacks->undefined_symbol
|
||||
(info, h->root.root.string, input_bfd, input_section,
|
||||
rel->r_vaddr - input_section->vma,
|
||||
info->unresolved_syms_in_objects == RM_DIAGNOSE
|
||||
&& !info->warn_unresolved_syms);
|
||||
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
sec = h->root.u.def.section;
|
||||
val = (h->root.u.def.value
|
||||
+ sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
else if (h->root.type == bfd_link_hash_common)
|
||||
{
|
||||
sec = h->root.u.c.p->section;
|
||||
val = (sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (bfd_link_relocatable (info)
|
||||
|| (h->flags & XCOFF_DEF_DYNAMIC) != 0
|
||||
|| (h->flags & XCOFF_IMPORT) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
|
||||
|| !((*xcoff64_calculate_relocation[rel->r_type])
|
||||
(input_bfd, input_section, output_bfd, rel, sym, &howto, val,
|
||||
addend, &relocation, contents)))
|
||||
return FALSE;
|
||||
|
||||
/* address */
|
||||
address = rel->r_vaddr - input_section->vma;
|
||||
location = contents + address;
|
||||
|
||||
if (address > input_section->size)
|
||||
abort ();
|
||||
|
||||
/* Get the value we are going to relocate. */
|
||||
if (1 == howto.size)
|
||||
value_to_relocate = bfd_get_16 (input_bfd, location);
|
||||
else if (2 == howto.size)
|
||||
value_to_relocate = bfd_get_32 (input_bfd, location);
|
||||
else
|
||||
value_to_relocate = bfd_get_64 (input_bfd, location);
|
||||
|
||||
/* overflow.
|
||||
|
||||
FIXME: We may drop bits during the addition
|
||||
which we don't check for. We must either check at every single
|
||||
operation, which would be tedious, or we must do the computations
|
||||
in a type larger than bfd_vma, which would be inefficient. */
|
||||
|
||||
if (((*xcoff_complain_overflow[howto.complain_on_overflow])
|
||||
(input_bfd, value_to_relocate, relocation, &howto)))
|
||||
{
|
||||
const char *name;
|
||||
char buf[SYMNMLEN + 1];
|
||||
char reloc_type_name[10];
|
||||
|
||||
if (symndx == -1)
|
||||
{
|
||||
name = "*ABS*";
|
||||
}
|
||||
else if (h != NULL)
|
||||
{
|
||||
name = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
|
||||
if (name == NULL)
|
||||
name = "UNKNOWN";
|
||||
}
|
||||
sprintf (reloc_type_name, "0x%02x", rel->r_type);
|
||||
|
||||
(*info->callbacks->reloc_overflow)
|
||||
(info, (h ? &h->root : NULL), name, reloc_type_name,
|
||||
(bfd_vma) 0, input_bfd, input_section,
|
||||
rel->r_vaddr - input_section->vma);
|
||||
}
|
||||
|
||||
/* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
|
||||
value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
|
||||
| (((value_to_relocate & howto.src_mask)
|
||||
+ relocation) & howto.dst_mask));
|
||||
|
||||
/* Put the value back in the object file. */
|
||||
if (1 == howto.size)
|
||||
bfd_put_16 (input_bfd, value_to_relocate, location);
|
||||
else if (2 == howto.size)
|
||||
bfd_put_32 (input_bfd, value_to_relocate, location);
|
||||
else
|
||||
bfd_put_64 (input_bfd, value_to_relocate, location);
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* PR 21786: The PE/COFF standard does not require NUL termination for any of
|
||||
the ASCII fields in the archive headers. So in order to be able to extract
|
||||
numerical values we provide our own versions of strtol and strtoll which
|
||||
|
Loading…
x
Reference in New Issue
Block a user