XCOFF64 fixes. For setting arch/mach and for R_BR relocations.

This commit is contained in:
Tom Rix 2002-05-10 21:20:16 +00:00
parent ecac9a4eaf
commit f1f0d9ab14
8 changed files with 187 additions and 38 deletions

View File

@ -1,3 +1,10 @@
2002-05-10 Tom Rix <trix@redhat.com>
* coff64-rs6000.c (xcoff64_reloc_type_br): New function for
xcoff64_ppc_relocate_section.
* coff-rs6000.c : Extern common xcoff_reloc_type functions.
* libxcoff.h: Common xcoff_reloc_type function declaration.
2002-05-10 Alan Modra <amodra@bigpond.net.au>
* elf32-i386.c (elf_i386_relocate_section): Remove overflow checks

View File

@ -155,15 +155,7 @@ static boolean do_copy PARAMS((bfd *, bfd *));
static boolean do_shared_object_padding PARAMS ((bfd *, bfd *, ufile_ptr *, int));
/* Relocation functions */
static boolean xcoff_reloc_type_noop PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
static boolean xcoff_reloc_type_fail PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
static boolean xcoff_reloc_type_pos PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
static boolean xcoff_reloc_type_neg PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
static boolean xcoff_reloc_type_rel PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
static boolean xcoff_reloc_type_toc PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
static boolean xcoff_reloc_type_ba PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
static boolean xcoff_reloc_type_br PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
static boolean xcoff_reloc_type_crel PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
static boolean xcoff_complain_overflow_dont_func
PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
@ -2726,7 +2718,7 @@ xcoff_swap_ldrel_out (abfd, src, d)
}
static boolean
boolean
xcoff_reloc_type_noop (input_bfd, input_section, output_bfd, rel, sym, howto,
val, addend, relocation, contents)
bfd *input_bfd ATTRIBUTE_UNUSED;
@ -2743,7 +2735,7 @@ xcoff_reloc_type_noop (input_bfd, input_section, output_bfd, rel, sym, howto,
return true;
}
static boolean
boolean
xcoff_reloc_type_fail (input_bfd, input_section, output_bfd, rel, sym, howto,
val, addend, relocation, contents)
bfd *input_bfd;
@ -2764,7 +2756,7 @@ xcoff_reloc_type_fail (input_bfd, input_section, output_bfd, rel, sym, howto,
return false;
}
static boolean
boolean
xcoff_reloc_type_pos (input_bfd, input_section, output_bfd, rel, sym, howto,
val, addend, relocation, contents)
bfd *input_bfd ATTRIBUTE_UNUSED;
@ -2782,7 +2774,7 @@ xcoff_reloc_type_pos (input_bfd, input_section, output_bfd, rel, sym, howto,
return true;
}
static boolean
boolean
xcoff_reloc_type_neg (input_bfd, input_section, output_bfd, rel, sym, howto,
val, addend, relocation, contents)
bfd *input_bfd ATTRIBUTE_UNUSED;
@ -2800,7 +2792,7 @@ xcoff_reloc_type_neg (input_bfd, input_section, output_bfd, rel, sym, howto,
return true;
}
static boolean
boolean
xcoff_reloc_type_rel (input_bfd, input_section, output_bfd, rel, sym, howto,
val, addend, relocation, contents)
bfd *input_bfd ATTRIBUTE_UNUSED;
@ -2824,7 +2816,8 @@ xcoff_reloc_type_rel (input_bfd, input_section, output_bfd, rel, sym, howto,
input_section->output_offset);
return true;
}
static boolean
boolean
xcoff_reloc_type_toc (input_bfd, input_section, output_bfd, rel, sym, howto,
val, addend, relocation, contents)
bfd *input_bfd;
@ -2866,7 +2859,8 @@ xcoff_reloc_type_toc (input_bfd, input_section, output_bfd, rel, sym, howto,
(sym->n_value - xcoff_data (input_bfd)->toc));
return true;
}
static boolean
boolean
xcoff_reloc_type_ba (input_bfd, input_section, output_bfd, rel, sym, howto,
val, addend, relocation, contents)
bfd *input_bfd ATTRIBUTE_UNUSED;
@ -2967,7 +2961,7 @@ xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
return true;
}
static boolean
boolean
xcoff_reloc_type_crel (input_bfd, input_section, output_bfd, rel, sym, howto,
val, addend, relocation, contents)
bfd *input_bfd ATTRIBUTE_UNUSED;

View File

@ -152,6 +152,42 @@ static boolean xcoff64_generate_rtinit
PARAMS ((bfd *, const char *, const char *, boolean));
static boolean xcoff64_bad_format_hook PARAMS ((bfd *, PTR ));
/* Relocation functions */
static boolean xcoff64_reloc_type_br PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
boolean (*xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
(XCOFF_RELOC_FUNCTION_ARGS) =
{
xcoff_reloc_type_pos, /* R_POS (0x00) */
xcoff_reloc_type_neg, /* R_NEG (0x01) */
xcoff_reloc_type_rel, /* R_REL (0x02) */
xcoff_reloc_type_toc, /* R_TOC (0x03) */
xcoff_reloc_type_fail, /* R_RTB (0x04) */
xcoff_reloc_type_toc, /* R_GL (0x05) */
xcoff_reloc_type_toc, /* R_TCL (0x06) */
xcoff_reloc_type_fail, /* (0x07) */
xcoff_reloc_type_ba, /* R_BA (0x08) */
xcoff_reloc_type_fail, /* (0x09) */
xcoff64_reloc_type_br, /* R_BR (0x0a) */
xcoff_reloc_type_fail, /* (0x0b) */
xcoff_reloc_type_pos, /* R_RL (0x0c) */
xcoff_reloc_type_pos, /* R_RLA (0x0d) */
xcoff_reloc_type_fail, /* (0x0e) */
xcoff_reloc_type_noop, /* R_REF (0x0f) */
xcoff_reloc_type_fail, /* (0x10) */
xcoff_reloc_type_fail, /* (0x11) */
xcoff_reloc_type_toc, /* R_TRL (0x12) */
xcoff_reloc_type_toc, /* R_TRLA (0x13) */
xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
xcoff_reloc_type_ba, /* R_CAI (0x16) */
xcoff_reloc_type_crel, /* R_CREL (0x17) */
xcoff_reloc_type_ba, /* R_RBA (0x18) */
xcoff_reloc_type_ba, /* R_RBAC (0x19) */
xcoff64_reloc_type_br, /* R_RBR (0x1a) */
xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
};
/* coffcode.h needs these to be defined. */
/* Internalcoff.h and coffcode.h modify themselves based on these flags. */
#define XCOFF64
@ -1030,6 +1066,84 @@ xcoff64_write_object_contents (abfd)
return true;
}
static boolean
xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
val, addend, relocation, contents)
bfd *input_bfd;
asection *input_section;
bfd *output_bfd ATTRIBUTE_UNUSED;
struct internal_reloc *rel;
struct internal_syment *sym ATTRIBUTE_UNUSED;
struct reloc_howto_struct *howto;
bfd_vma val;
bfd_vma addend;
bfd_vma *relocation;
bfd_byte *contents;
{
struct xcoff_link_hash_entry *h;
if (0 > rel->r_symndx)
return false;
h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
/* If we see an R_BR or R_RBR reloc which is jumping to global
linkage code, and it is followed by an appropriate cror nop
instruction, we replace the cror with ld r2,40(r1). This
restores the TOC after the glink code. Contrariwise, if the
call is followed by a ld r2,40(r1), but the call is not
going to global linkage code, we can replace the load with a
cror. */
if (NULL != h
&& bfd_link_hash_defined == h->root.type
&& (rel->r_vaddr - input_section->vma + 8 <=
input_section->_cooked_size))
{
bfd_byte *pnext;
unsigned long next;
pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
next = bfd_get_32 (input_bfd, pnext);
/* The _ptrgl function is magic. It is used by the AIX compiler to call
a function through a pointer. */
if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
{
if (next == 0x4def7b82 /* cror 15,15,15 */
|| next == 0x4ffffb82 /* cror 31,31,31 */
|| next == 0x60000000) /* ori r0,r0,0 */
bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
}
else
{
if (next == 0xe8410028) /* ld r2,40(r1) */
bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
}
}
else if (NULL != h && bfd_link_hash_undefined == h->root.type)
{
/* Normally, this relocation is against a defined symbol. In the
case where this is a partial link and the output section offset
is greater than 2^25, the linker will return an invalid error
message that the relocation has been truncated. Yes it has been
truncated but no it not important. For this case, disable the
overflow checking. */
howto->complain_on_overflow = complain_overflow_dont;
}
howto->pc_relative = true;
howto->src_mask &= ~3;
howto->dst_mask = howto->src_mask;
/* A PC relative reloc includes the section address. */
addend += input_section->vma;
*relocation = val + addend;
*relocation -= (input_section->output_section->vma +
input_section->output_offset);
return true;
}
/* This is the relocation function for the PowerPC64.
See xcoff_ppc_relocation_section for more information. */
@ -1146,7 +1260,7 @@ xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
}
if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
|| (false == xcoff_calculate_relocation[rel->r_type]
|| (false == xcoff64_calculate_relocation[rel->r_type]
(input_bfd, input_section, output_bfd, rel, sym, &howto, val,
addend, &relocation, contents)))
return false;

View File

@ -222,4 +222,14 @@ extern boolean (*xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
extern boolean (*xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW])
(XCOFF_COMPLAIN_FUNCTION_ARGS);
/* Relocation functions */
boolean xcoff_reloc_type_noop PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
boolean xcoff_reloc_type_fail PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
boolean xcoff_reloc_type_pos PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
boolean xcoff_reloc_type_neg PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
boolean xcoff_reloc_type_rel PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
boolean xcoff_reloc_type_toc PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
boolean xcoff_reloc_type_ba PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
boolean xcoff_reloc_type_crel PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
#endif /* LIBXCOFF_H */

View File

@ -1,3 +1,14 @@
2002-05-10 Tom Rix <trix@redhat.com>
* emultempl/aix.em: (gld*_set_output_arch): New function. Use
architecture and machine information in the output bfd.
(gld*_before_parse): Remove old arch and machine code.
(choose_target): Rename to gld*_choose_target.
(rtld): Change type to int.
* ldfile.c (ldfile_try_open_bfd): Disable compatiblity check for
objects in XCOFF archives.
* ldfile.h: Update copyright date.
2002-05-10 Jakub Jelinek <jakub@redhat.com>
* ldmain.c (main): Enable -z combreloc by default.

View File

@ -53,11 +53,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "coff/internal.h"
#include "coff/xcoff.h"
#include "libcoff.h"
#include "libxcoff.h"
static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
static int gld${EMULATION_NAME}_parse_args PARAMS ((int, char **));
static void gld${EMULATION_NAME}_after_open PARAMS ((void));
static char *choose_target PARAMS ((int, char **));
static char *gld${EMULATION_NAME}_choose_target PARAMS ((int, char **));
static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
static void gld${EMULATION_NAME}_read_file PARAMS ((const char *, boolean));
static void gld${EMULATION_NAME}_free PARAMS ((PTR));
@ -68,7 +70,9 @@ static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
static boolean gld${EMULATION_NAME}_unrecognized_file
PARAMS ((lang_input_statement_type *));
static void gld${EMULATION_NAME}_create_output_section_statements
PARAMS((void));
PARAMS ((void));
static void gld${EMULATION_NAME}_set_output_arch PARAMS ((void));
static int is_syscall PARAMS ((char *, unsigned int *));
static int change_symbol_mode PARAMS ((char *));
@ -132,7 +136,7 @@ static unsigned int syscall_mask = 0x77;
static lang_input_statement_type *initfini_file;
/* Whether to do run time linking */
static boolean rtld;
static int rtld;
/* Explicit command line library path, -blibpath */
static char *command_line_blibpath = NULL;
@ -142,17 +146,7 @@ static char *command_line_blibpath = NULL;
static void
gld${EMULATION_NAME}_before_parse ()
{
#ifndef TARGET_ /* I.e., if not generic. */
const bfd_arch_info_type *arch = bfd_scan_arch ("${OUTPUT_ARCH}");
if (arch)
{
ldfile_output_architecture = arch->arch;
ldfile_output_machine = arch->mach;
ldfile_output_machine_name = arch->printable_name;
}
else
ldfile_output_architecture = bfd_arch_${ARCH};
#endif /* not TARGET_ */
config.has_shared = true;
/* The link_info.[init|fini]_functions are initialized in ld/lexsup.c.
@ -687,7 +681,8 @@ gld${EMULATION_NAME}_before_allocation ()
if (!bfd_xcoff_size_dynamic_sections
(output_bfd, &link_info, libpath, entry_symbol, file_align,
maxstack, maxdata, gc && !unix_ld ? true : false,
modtype, textro ? true : false, unix_ld, special_sections, rtld))
modtype, textro ? true : false, unix_ld, special_sections,
rtld ? true : false))
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
/* Look through the special sections, and put them in the right
@ -806,7 +801,7 @@ gld${EMULATION_NAME}_before_allocation ()
}
static char *
choose_target (argc, argv)
gld${EMULATION_NAME}_choose_target (argc, argv)
int argc;
char **argv;
{
@ -1304,7 +1299,7 @@ fi
cat >>e${EMULATION_NAME}.c <<EOF
static void
gld${EMULATION_NAME}_create_output_section_statements()
gld${EMULATION_NAME}_create_output_section_statements ()
{
/* __rtinit */
if ((bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour)
@ -1342,6 +1337,18 @@ gld${EMULATION_NAME}_create_output_section_statements()
}
}
static void
gld${EMULATION_NAME}_set_output_arch ()
{
bfd_set_arch_mach (output_bfd,
bfd_xcoff_architecture (output_bfd),
bfd_xcoff_machine (output_bfd));
ldfile_output_architecture = bfd_get_arch (output_bfd);
ldfile_output_machine = bfd_get_mach (output_bfd);
ldfile_output_machine_name = bfd_printable_name (output_bfd);
}
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
gld${EMULATION_NAME}_before_parse,
syslib_default,
@ -1349,8 +1356,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
after_parse_default,
gld${EMULATION_NAME}_after_open,
after_allocation_default,
set_output_arch_default,
choose_target,
gld${EMULATION_NAME}_set_output_arch,
gld${EMULATION_NAME}_choose_target,
gld${EMULATION_NAME}_before_allocation,
gld${EMULATION_NAME}_get_script,
"${EMULATION_NAME}",

View File

@ -132,7 +132,13 @@ ldfile_try_open_bfd (attempt, entry)
{
if (! bfd_check_format (check, bfd_object))
return true;
if (bfd_arch_get_compatible (check, output_bfd) == NULL)
if ((bfd_arch_get_compatible (check, output_bfd) == NULL)
/* XCOFF archives can have 32 and 64 bit objects */
&& ! (bfd_get_flavour (check) == bfd_target_xcoff_flavour
&& bfd_get_flavour (output_bfd) ==
bfd_target_xcoff_flavour
&& bfd_check_format (entry->the_bfd, bfd_archive)))
{
einfo (_("%P: skipping incompatible %s when searching for %s\n"),
attempt, entry->local_sym_name);

View File

@ -1,5 +1,5 @@
/* ldfile.h -
Copyright 1991, 1992, 1993, 1994, 1995, 2000
Copyright 1991, 1992, 1993, 1994, 1995, 2000, 2002
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.