* config/tc-sparc.c (tc_gen_reloc): If PIC, only change PCREL_S2

to WPLT30 for an undefined or external symbol.  Don't consider
	PC10 or PC22 to be a PC relative reloc when choosing between
	fx_addnumber and fx_offset.
This commit is contained in:
Ian Lance Taylor 1995-08-16 20:21:49 +00:00
parent 51c7f8f3c2
commit 4c67b523a3
2 changed files with 102 additions and 13 deletions

View file

@ -1,5 +1,10 @@
Wed Aug 16 12:49:17 1995 Ian Lance Taylor <ian@cygnus.com>
* config/tc-sparc.c (tc_gen_reloc): If PIC, only change PCREL_S2
to WPLT30 for an undefined or external symbol. Don't consider
PC10 or PC22 to be a PC relative reloc when choosing between
fx_addnumber and fx_offset.
* config/tc-z8k.c (md_number_to_chars): Don't do it here, call
number_to_chars_bigendian.
* config/tc-z8k.h (TARGET_BYTES_BIG_ENDIAN): Define.

View file

@ -1,5 +1,5 @@
/* tc-sparc.c -- Assemble for the SPARC
Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1989, 90, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -36,6 +36,9 @@ static enum sparc_architecture current_architecture = v6;
static int architecture_requested;
static int warn_on_bump;
/* Non-zero if we are generating PIC code. */
int sparc_pic_code;
extern int target_big_endian;
/* handle of the OPCODE hash table */
@ -1882,7 +1885,8 @@ md_apply_fix (fixP, value)
don't want to include the value of an externally visible symbol. */
if (fixP->fx_addsy != NULL)
{
if (S_IS_EXTERN (fixP->fx_addsy)
if ((S_IS_EXTERN (fixP->fx_addsy)
|| (sparc_pic_code && ! fixP->fx_pcrel))
&& S_GET_SEGMENT (fixP->fx_addsy) != absolute_section
&& S_GET_SEGMENT (fixP->fx_addsy) != undefined_section
&& ! bfd_is_com_section (S_GET_SEGMENT (fixP->fx_addsy)))
@ -1908,6 +1912,17 @@ md_apply_fix (fixP, value)
if (fixP->fx_addsy != NULL
&& fixP->fx_r_type != BFD_RELOC_32_PCREL_S2)
val = 0;
/* When generating PIC code, we do not want an addend for a reloc
against a local symbol. We adjust fx_addnumber to cancel out the
value already included in val, and to also cancel out the
adjustment which bfd_install_relocation will create. */
if (sparc_pic_code
&& fixP->fx_r_type != BFD_RELOC_32_PCREL_S2
&& fixP->fx_addsy != NULL
&& ! S_IS_COMMON (fixP->fx_addsy)
&& (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) == 0)
fixP->fx_addnumber -= 2 * S_GET_VALUE (fixP->fx_addsy);
#endif
switch (fixP->fx_r_type)
@ -1925,7 +1940,11 @@ md_apply_fix (fixP, value)
break;
case BFD_RELOC_32_PCREL_S2:
val = (val >>= 2) + 1;
val = (val >>= 2);
if (! sparc_pic_code
|| fixP->fx_addsy == NULL
|| (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
++val;
buf[0] |= (val >> 24) & 0x3f;
buf[1] = (val >> 16);
buf[2] = val >> 8;
@ -2115,6 +2134,49 @@ tc_gen_reloc (section, fixp)
default:
abort ();
}
#if defined (OBJ_ELF) || defined (OBJ_AOUT)
/* If we are generating PIC code, we need to generate a different
set of relocs. */
#ifdef OBJ_ELF
#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
#else
#define GOT_NAME "__GLOBAL_OFFSET_TABLE_"
#endif
if (sparc_pic_code)
{
switch (code)
{
case BFD_RELOC_32_PCREL_S2:
if (! S_IS_DEFINED (fixp->fx_addsy)
|| S_IS_EXTERNAL (fixp->fx_addsy))
code = BFD_RELOC_SPARC_WPLT30;
break;
case BFD_RELOC_HI22:
if (fixp->fx_addsy != NULL
&& strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
code = BFD_RELOC_SPARC_PC22;
else
code = BFD_RELOC_SPARC_GOT22;
break;
case BFD_RELOC_LO10:
if (fixp->fx_addsy != NULL
&& strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
code = BFD_RELOC_SPARC_PC10;
else
code = BFD_RELOC_SPARC_GOT10;
break;
case BFD_RELOC_SPARC13:
code = BFD_RELOC_SPARC_GOT13;
break;
default:
break;
}
}
#endif /* defined (OBJ_ELF) || defined (OBJ_AOUT) */
reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
if (reloc->howto == 0)
{
@ -2123,19 +2185,22 @@ tc_gen_reloc (section, fixp)
fixp->fx_r_type, bfd_get_reloc_code_name (code));
return 0;
}
assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
/* @@ Why fx_addnumber sometimes and fx_offset other times? */
#ifdef OBJ_AOUT
if (reloc->howto->pc_relative == 0)
if (reloc->howto->pc_relative == 0
|| code == BFD_RELOC_SPARC_PC10
|| code == BFD_RELOC_SPARC_PC22)
reloc->addend = fixp->fx_addnumber;
else
reloc->addend = fixp->fx_offset - reloc->address;
#else /* elf or coff */
if (reloc->howto->pc_relative == 0)
if (reloc->howto->pc_relative == 0
|| code == BFD_RELOC_SPARC_PC10
|| code == BFD_RELOC_SPARC_PC22)
reloc->addend = fixp->fx_addnumber;
else if ((fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
reloc->addend = (section->vma
@ -2143,7 +2208,6 @@ tc_gen_reloc (section, fixp)
+ md_pcrel_from (fixp));
else
reloc->addend = fixp->fx_offset;
#endif
return reloc;
@ -2241,8 +2305,12 @@ print_insn (insn)
#ifdef OBJ_ELF
CONST char *md_shortopts = "A:K:VQ:sq";
#else
#ifdef OBJ_AOUT
CONST char *md_shortopts = "A:k";
#else
CONST char *md_shortopts = "A:";
#endif
#endif
struct option md_longopts[] = {
#define OPTION_BUMP (OPTION_MD_BASE)
{"bump", no_argument, NULL, OPTION_BUMP},
@ -2299,6 +2367,12 @@ md_parse_option (c, arg)
/* Ignore -sparc, used by SunOS make default .s.o rule. */
break;
#ifdef OBJ_AOUT
case 'k':
sparc_pic_code = 1;
break;
#endif
#ifdef OBJ_ELF
case 'V':
print_version_id ();
@ -2321,10 +2395,8 @@ md_parse_option (c, arg)
if (strcmp (arg, "PIC") != 0)
as_warn ("Unrecognized option following -K");
else
{
as_warn ("gas does not currently support PIC code for the SPARC");
as_fatal ("use /usr/ccs/bin/as instead");
}
sparc_pic_code = 1;
break;
#endif
default:
@ -2350,8 +2422,13 @@ md_show_usage (stream)
specify variant of SPARC architecture\n\
-bump warn when assembler switches architectures\n\
-sparc ignored\n");
#ifdef OBJ_AOUT
fprintf (stream, "\
-k generate PIC\n");
#endif
#ifdef OBJ_ELF
fprintf(stream, "\
fprintf (stream, "\
-KPIC generate PIC\n\
-V print assembler version number\n\
-q ignored\n\
-Qy, -Qn ignored\n\
@ -2398,7 +2475,14 @@ long
md_pcrel_from (fixP)
fixS *fixP;
{
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
long ret;
ret = fixP->fx_where + fixP->fx_frag->fr_address;
if (! sparc_pic_code
|| fixP->fx_addsy == NULL
|| (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
ret += fixP->fx_size;
return ret;
}
/* end of tc-sparc.c */