mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-28 04:25:10 +08:00
XCOFF64 fixes. For setting arch/mach and for R_BR relocations.
This commit is contained in:
parent
ecac9a4eaf
commit
f1f0d9ab14
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
11
ld/ChangeLog
11
ld/ChangeLog
@ -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.
|
||||
|
@ -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}",
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user