Mon Feb 12 15:16:29 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>

Support for OBJ_ELF on m68k, mostly inside #ifdef OBJ_ELF:
	* config/m68k-parse.h (enum pic_relocation): Define.
	(struct m68k_exp): Add pic_reloc field.
	* config/tc-m68k.h (TC_RELOC_RTSYM_LOC_FIXUP): Define.
	(tc_fix_adjustable): Define to call tc_m68k_fix_adjustable.
	(NO_RELOC): Define to BFD_RELOC_NONE if BFD_ASSEMBLER, to zero
	otherwise.
	* config/tc-m68k.c: Delete definition of NO_RELOC.
 	(struct m68k_it): Add pic_reloc field.
	(add_fix): Copy over pic_reloc field.
	(md_pseudo_table): Interpret .align parameter as byte count.
	(mote_pseudo_table): Likewise.
	(tc_m68k_fix_adjustable): New function.
	(get_reloc_code): New function.
	(md_assemble): Use it as last argument to fix_new_exp.
	(md_apply_fix_2): For a relocation against a symbol don't put the
	addend into the data.
	(tc_gen_reloc): Different addend computation for OBJ_ELF.
	(m68k_ip): Don't relax an operand that requires pic relocation.
	(md_begin): Align .text, .data and .bss on 4 byte boundary by
	default.
	* write.c (fixup_segment): Don't add symbol value to addend if
 	TC_M68K and OBJ_ELF.
	* config/m68k-parse.y (yylex): Handle @PLTPC, etc.
	(motorola_operand): Add rule for `(zapc, EXPR)'.
This commit is contained in:
Ian Lance Taylor 1996-02-12 20:33:06 +00:00
parent 0e1ad456ce
commit a043f579df
4 changed files with 383 additions and 32 deletions

View File

@ -1,3 +1,31 @@
Mon Feb 12 15:16:29 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
Support for OBJ_ELF on m68k, mostly inside #ifdef OBJ_ELF:
* config/m68k-parse.h (enum pic_relocation): Define.
(struct m68k_exp): Add pic_reloc field.
* config/tc-m68k.h (TC_RELOC_RTSYM_LOC_FIXUP): Define.
(tc_fix_adjustable): Define to call tc_m68k_fix_adjustable.
(NO_RELOC): Define to BFD_RELOC_NONE if BFD_ASSEMBLER, to zero
otherwise.
* config/tc-m68k.c: Delete definition of NO_RELOC.
(struct m68k_it): Add pic_reloc field.
(add_fix): Copy over pic_reloc field.
(md_pseudo_table): Interpret .align parameter as byte count.
(mote_pseudo_table): Likewise.
(tc_m68k_fix_adjustable): New function.
(get_reloc_code): New function.
(md_assemble): Use it as last argument to fix_new_exp.
(md_apply_fix_2): For a relocation against a symbol don't put the
addend into the data.
(tc_gen_reloc): Different addend computation for OBJ_ELF.
(m68k_ip): Don't relax an operand that requires pic relocation.
(md_begin): Align .text, .data and .bss on 4 byte boundary by
default.
* write.c (fixup_segment): Don't add symbol value to addend if
TC_M68K and OBJ_ELF.
* config/m68k-parse.y (yylex): Handle @PLTPC, etc.
(motorola_operand): Add rule for `(zapc, EXPR)'.
Mon Feb 12 10:07:33 1996 David Mosberger-Tang <davidm@azstarnet.com>
* ecoff.c (ecoff_directive_weakext): Fixed so that whitespace

View File

@ -19,7 +19,6 @@
02111-1307, USA. */
#include <ctype.h>
#define NO_RELOC 0
#include "as.h"
#include "obstack.h"
#include "subsegs.h"
@ -62,7 +61,8 @@ const int md_reloc_size = 8; /* Size of relocation record */
/* Are we trying to generate PIC code? If so, absolute references
ought to be made into linkage table references or pc-relative
references. */
references. Not implemented. For ELF there are other means
to denote pic relocations. */
int flag_want_pic;
static int flag_short_refs; /* -l option */
@ -199,6 +199,11 @@ struct m68k_it
significance of some values (in the branch instruction, for
example). */
int pcrel_fix;
#ifdef OBJ_ELF
/* Whether this expression needs special pic relocation, and if
so, which. */
enum pic_relocation pic_reloc;
#endif
}
reloc[5]; /* Five is enough??? */
};
@ -252,6 +257,9 @@ add_fix (width, exp, pc_rel, pc_fix)
the_ins.reloc[the_ins.nrel].exp = exp->exp;
the_ins.reloc[the_ins.nrel].wid = width;
the_ins.reloc[the_ins.nrel].pcrel_fix = pc_fix;
#ifdef OBJ_ELF
the_ins.reloc[the_ins.nrel].pic_reloc = exp->pic_reloc;
#endif
the_ins.reloc[the_ins.nrel++].pcrel = pc_rel;
}
@ -428,7 +436,7 @@ const pseudo_typeS md_pseudo_table[] =
{"even", s_even, 0},
{"skip", s_space, 0},
{"proc", s_proc, 0},
#ifdef TE_SUN3
#if defined (TE_SUN3) || defined (OBJ_ELF)
{"align", s_align_bytes, 0},
#endif
#ifdef OBJ_ELF
@ -500,7 +508,11 @@ CONST pseudo_typeS mote_pseudo_table[] =
{"dsb", s_space, 1},
{"xdef", s_globl, 0},
#ifdef OBJ_ELF
{"align", s_align_bytes, 0},
#else
{"align", s_align_ptwo, 0},
#endif
#ifdef M68KCOFF
{"sect", obj_coff_section, 0},
{"section", obj_coff_section, 0},
@ -585,6 +597,145 @@ tc_coff_fix2rtype (fixP)
#endif
#ifdef OBJ_ELF
/* Compute the relocation code for a fixup of SIZE bytes, using pc
relative relocation if PCREL is non-zero. PIC says whether a special
pic relocation was requested. */
static bfd_reloc_code_real_type get_reloc_code
PARAMS ((int, int, enum pic_relocation));
static bfd_reloc_code_real_type
get_reloc_code (size, pcrel, pic)
int size;
int pcrel;
enum pic_relocation pic;
{
switch (pic)
{
case pic_got_pcrel:
switch (size)
{
case 1:
return BFD_RELOC_8_GOT_PCREL;
case 2:
return BFD_RELOC_16_GOT_PCREL;
case 4:
return BFD_RELOC_32_GOT_PCREL;
}
break;
case pic_got_off:
switch (size)
{
case 1:
return BFD_RELOC_8_GOTOFF;
case 2:
return BFD_RELOC_16_GOTOFF;
case 4:
return BFD_RELOC_32_GOTOFF;
}
break;
case pic_plt_pcrel:
switch (size)
{
case 1:
return BFD_RELOC_8_PLT_PCREL;
case 2:
return BFD_RELOC_16_PLT_PCREL;
case 4:
return BFD_RELOC_32_PLT_PCREL;
}
break;
case pic_plt_off:
switch (size)
{
case 1:
return BFD_RELOC_8_PLTOFF;
case 2:
return BFD_RELOC_16_PLTOFF;
case 4:
return BFD_RELOC_32_PLTOFF;
}
break;
case pic_none:
if (pcrel)
{
switch (size)
{
case 1:
return BFD_RELOC_8_PCREL;
case 2:
return BFD_RELOC_16_PCREL;
case 4:
return BFD_RELOC_32_PCREL;
}
}
else
{
switch (size)
{
case 1:
return BFD_RELOC_8;
case 2:
return BFD_RELOC_16;
case 4:
return BFD_RELOC_32;
}
}
}
as_bad ("Can not do %d byte %s%srelocation", size,
pcrel ? "pc-relative " : "",
pic == pic_none ? "" : "pic ");
return BFD_RELOC_NONE;
}
/* Here we decide which fixups can be adjusted to make them relative
to the beginning of the section instead of the symbol. Basically
we need to make sure that the dynamic relocations are done
correctly, so in some cases we force the original symbol to be
used. */
int
tc_m68k_fix_adjustable (fixP)
fixS *fixP;
{
/* Prevent all adjustments to global symbols. */
if (S_IS_EXTERNAL (fixP->fx_addsy))
return 0;
/* adjust_reloc_syms doesn't know about the GOT */
switch (fixP->fx_r_type)
{
case BFD_RELOC_8_GOT_PCREL:
case BFD_RELOC_16_GOT_PCREL:
case BFD_RELOC_32_GOT_PCREL:
case BFD_RELOC_8_GOTOFF:
case BFD_RELOC_16_GOTOFF:
case BFD_RELOC_32_GOTOFF:
case BFD_RELOC_8_PLT_PCREL:
case BFD_RELOC_16_PLT_PCREL:
case BFD_RELOC_32_PLT_PCREL:
case BFD_RELOC_8_PLTOFF:
case BFD_RELOC_16_PLTOFF:
case BFD_RELOC_32_PLTOFF:
return 0;
default:
return 1;
}
}
#else /* !OBJ_ELF */
#define get_reloc_code(SIZE,PCREL,OTHER) NO_RELOC
#endif /* OBJ_ELF */
#ifdef BFD_ASSEMBLER
arelent *
@ -598,28 +749,50 @@ tc_gen_reloc (section, fixp)
if (fixp->fx_tcbit)
abort ();
#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
switch (F (fixp->fx_size, fixp->fx_pcrel))
if (fixp->fx_r_type != BFD_RELOC_NONE)
code = fixp->fx_r_type;
else
{
#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
switch (F (fixp->fx_size, fixp->fx_pcrel))
{
#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
MAP (1, 0, BFD_RELOC_8);
MAP (2, 0, BFD_RELOC_16);
MAP (4, 0, BFD_RELOC_32);
MAP (1, 1, BFD_RELOC_8_PCREL);
MAP (2, 1, BFD_RELOC_16_PCREL);
MAP (4, 1, BFD_RELOC_32_PCREL);
default:
abort ();
MAP (1, 0, BFD_RELOC_8);
MAP (2, 0, BFD_RELOC_16);
MAP (4, 0, BFD_RELOC_32);
MAP (1, 1, BFD_RELOC_8_PCREL);
MAP (2, 1, BFD_RELOC_16_PCREL);
MAP (4, 1, BFD_RELOC_32_PCREL);
default:
abort ();
}
}
#undef F
#undef MAP
reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
assert (reloc != 0);
reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
#ifndef OBJ_ELF
if (fixp->fx_pcrel)
reloc->addend = fixp->fx_addnumber;
else
reloc->addend = 0;
#else
if (!fixp->fx_pcrel)
reloc->addend = fixp->fx_addnumber;
else if ((fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
reloc->addend = (section->vma
+ (fixp->fx_pcrel_adjust == 64
? -1 : fixp->fx_pcrel_adjust)
+ fixp->fx_addnumber
+ md_pcrel_from (fixp));
else
reloc->addend = (fixp->fx_offset
+ (fixp->fx_pcrel_adjust == 64
? -1 : fixp->fx_pcrel_adjust));
#endif
reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
assert (reloc->howto != 0);
@ -1575,16 +1748,24 @@ m68k_ip (instring)
{
if (opP->reg == PC)
{
#if 0
addword (0x0170);
add_fix ('l', &opP->disp, 1, 2);
addword (0), addword (0);
#else
add_frag (adds (&opP->disp),
offs (&opP->disp),
TAB (PCLEA, SZ_UNDEF));
if (opP->disp.size == SIZE_LONG
#ifdef OBJ_ELF
/* If the displacement needs pic
relocation it cannot be relaxed. */
|| opP->disp.pic_reloc != pic_none
#endif
break;
)
{
addword (0x0170);
add_fix ('l', &opP->disp, 1, 2);
}
else
{
add_frag (adds (&opP->disp),
offs (&opP->disp),
TAB (PCLEA, SZ_UNDEF));
break;
}
}
else
{
@ -1730,7 +1911,13 @@ m68k_ip (instring)
else if (siz1 == SIZE_UNSPEC
&& opP->reg == PC
&& isvar (&opP->disp)
&& subs (&opP->disp) == NULL)
&& subs (&opP->disp) == NULL
#ifdef OBJ_ELF
/* If the displacement needs pic
relocation it cannot be relaxed. */
&& opP->disp.pic_reloc == pic_none
#endif
)
{
nextword += baseo & 0xff;
addword (nextword);
@ -1866,6 +2053,11 @@ m68k_ip (instring)
if (isvar (&opP->disp)
&& !subs (&opP->disp)
&& adds (&opP->disp)
#ifdef OBJ_ELF
/* If the displacement needs pic relocation it
cannot be relaxed. */
&& opP->disp.pic_reloc == pic_none
#endif
&& S_GET_SEGMENT (adds (&opP->disp)) == now_seg
&& cpu_of_arch (current_architecture) >= m68020
&& !flag_long_jumps
@ -2005,6 +2197,13 @@ m68k_ip (instring)
if (subs (&opP->disp)) /* We can't relax it */
goto long_branch;
#ifdef OBJ_ELF
/* If the displacement needs pic relocation it cannot be
relaxed. */
if (opP->disp.pic_reloc != pic_none)
goto long_branch;
#endif
/* This could either be a symbol, or an absolute
address. No matter, the frag hacking will finger it
out. Not quite: it can't switch from BRANCH to
@ -2938,7 +3137,8 @@ md_assemble (str)
n,
&the_ins.reloc[m].exp,
the_ins.reloc[m].pcrel,
NO_RELOC);
get_reloc_code (n, the_ins.reloc[m].pcrel,
the_ins.reloc[m].pic_reloc));
fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
}
return;
@ -2982,7 +3182,8 @@ md_assemble (str)
wid,
&the_ins.reloc[m].exp,
the_ins.reloc[m].pcrel,
NO_RELOC);
get_reloc_code (wid, the_ins.reloc[m].pcrel,
the_ins.reloc[m].pic_reloc));
fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
}
(void) frag_var (rs_machine_dependent, 10, 0,
@ -3018,7 +3219,8 @@ md_assemble (str)
wid,
&the_ins.reloc[m].exp,
the_ins.reloc[m].pcrel,
NO_RELOC);
get_reloc_code (wid, the_ins.reloc[m].pcrel,
the_ins.reloc[m].pic_reloc));
fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
}
}
@ -3185,6 +3387,12 @@ md_begin ()
#endif
init_regtable ();
#ifdef OBJ_ELF
record_alignment (text_section, 2);
record_alignment (data_section, 2);
record_alignment (bss_section, 2);
#endif
}
void
@ -3371,6 +3579,15 @@ md_apply_fix_2 (fixP, val)
else
val &= 0x7fffffff;
#ifdef OBJ_ELF
if (fixP->fx_addsy)
{
memset (buf, 0, fixP->fx_size);
fixP->fx_addnumber = val; /* Remember value for emit_reloc */
return;
}
#endif
switch (fixP->fx_size)
{
/* The cast to offsetT below are necessary to make code correct for
@ -5974,8 +6191,14 @@ md_parse_option (c, arg)
flag_reg_prefix_optional = 1;
break;
case 'Q':
/* -V: SVR4 argument to print version ID. */
case 'V':
print_version_id ();
break;
/* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
should be emitted or not. FIXME: Not implemented. */
case 'Q':
break;
default:

View File

@ -1,6 +1,7 @@
/* This file is tc-m68k.h
Copyright (C) 1987-1992 Free Software Foundation, Inc.
Copyright (C) 1987, 89, 90, 91, 92, 93, 94, 95, 1996
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -16,12 +17,26 @@
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define TC_M68K 1
#define TARGET_BYTES_BIG_ENDIAN 1
#ifdef OBJ_AOUT
#ifdef TE_SUN3
#define TARGET_FORMAT "a.out-sunos-big"
#else
#ifdef TE_NetBSD
#define TARGET_FORMAT "a.out-m68k-netbsd"
#else
#define TARGET_FORMAT "a.out-zero-big"
#endif
#endif
#endif
#ifdef OBJ_ELF
#define TARGET_FORMAT "elf32-m68k"
#endif
#ifdef TE_APOLLO
@ -33,16 +48,21 @@
#ifdef TE_LYNX
#define TARGET_FORMAT "coff-m68k-lynx"
#endif
#ifdef TE_AUX
#define TARGET_FORMAT "coff-m68k-aux"
#endif
#ifndef COFF_MAGIC
#define COFF_MAGIC MC68MAGIC
#endif
#define BFD_ARCH bfd_arch_m68k
#define BFD_ARCH bfd_arch_m68k /* for non-BFD_ASSEMBLER */
#define TARGET_ARCH bfd_arch_m68k /* BFD_ASSEMBLER */
#define COFF_FLAGS F_AR32W
#define TC_COUNT_RELOC(x) ((x)->fx_addsy||(x)->fx_subsy)
#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP)
#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag)
extern int tc_coff_sizemachdep PARAMS ((struct frag *));
#ifdef TE_SUN3
/* This variable contains the value to write out at the beginning of
the a.out file. The 2<<16 means that this is a 68020 file instead
@ -77,7 +97,7 @@ extern int m68k_aout_machtype;
#endif
#if !defined (REGISTER_PREFIX_OPTIONAL)
#ifdef M68KCOFF
#if defined (M68KCOFF) || defined (OBJ_ELF)
#define LOCAL_LABEL(name) (name[0] == '.' \
&& (name[1] == 'L' || name[1] == '.'))
#define FAKE_LABEL_NAME ".L0\001"
@ -92,11 +112,36 @@ extern int m68k_aout_machtype;
can't be used as the initial character. If that's not true, more
work will be needed to fix this up. */
#define LEX_PCT 1
/* On the Delta, dots are not required before pseudo-ops. */
#define NO_PSEUDO_DOT
#endif
#ifdef BFD_ASSEMBLER
#define tc_frob_symbol(sym,punt) \
if (S_GET_SEGMENT (sym) == reg_section) punt = 1
#define NO_RELOC BFD_RELOC_NONE
#ifdef OBJ_ELF
/* This expression evaluates to false if the relocation is for a local object
for which we still want to do the relocation at runtime. True if we
are willing to perform this relocation while building the .o file. */
#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
((FIX)->fx_r_type != BFD_RELOC_8_PLT_PCREL \
&& (FIX)->fx_r_type != BFD_RELOC_16_PLT_PCREL \
&& (FIX)->fx_r_type != BFD_RELOC_32_PLT_PCREL \
&& (FIX)->fx_r_type != BFD_RELOC_8_GOT_PCREL \
&& (FIX)->fx_r_type != BFD_RELOC_16_GOT_PCREL \
&& (FIX)->fx_r_type != BFD_RELOC_32_GOT_PCREL)
#define tc_fix_adjustable(X) tc_m68k_fix_adjustable(X)
#endif
#else
#define NO_RELOC 0
#endif
#define DIFF_EXPR_OK
@ -107,4 +152,12 @@ extern void m68k_init_after_args PARAMS ((void));
extern int m68k_parse_long_option PARAMS ((char *));
#define md_parse_long_option m68k_parse_long_option
#define md_operand(x)
#define TARGET_WORD_SIZE 32
#define TARGET_ARCH bfd_arch_m68k
extern struct relax_type md_relax_table[];
#define TC_GENERIC_RELAX_TABLE md_relax_table
/* end of tc-m68k.h */

View File

@ -1,5 +1,5 @@
/* write.c - emit .o file
Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 1995
Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 1996
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -94,6 +94,8 @@ int magic_number_for_object_file = DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE;
#endif /* BFD_ASSEMBLER */
static int n_fixups;
#ifdef BFD_ASSEMBLER
static fixS *fix_new_internal PARAMS ((fragS *, int where, int size,
symbolS *add, symbolS *sub,
@ -133,6 +135,8 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
{
fixS *fixP;
n_fixups++;
fixP = (fixS *) obstack_alloc (&notes, sizeof (fixS));
fixP->fx_frag = frag;
@ -799,12 +803,23 @@ write_relocs (abfd, sec, xxx)
{
arelent *reloc;
bfd_reloc_status_type s;
symbolS *sym;
if (fixp->fx_done)
{
n--;
continue;
}
/* If this is an undefined symbol which was equated to another
symbol, then use generate the reloc against the latter symbol
rather than the former. */
sym = fixp->fx_addsy;
while (sym->sy_value.X_op == O_symbol
&& (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
sym = sym->sy_value.X_add_symbol;
fixp->fx_addsy = sym;
reloc = tc_gen_reloc (sec, fixp);
if (!reloc)
{
@ -844,6 +859,7 @@ write_relocs (abfd, sec, xxx)
arelent **reloc;
char *data;
bfd_reloc_status_type s;
symbolS *sym;
int j;
if (fixp->fx_done)
@ -851,6 +867,16 @@ write_relocs (abfd, sec, xxx)
n--;
continue;
}
/* If this is an undefined symbol which was equated to another
symbol, then use generate the reloc against the latter symbol
rather than the former. */
sym = fixp->fx_addsy;
while (sym->sy_value.X_op == O_symbol
&& (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
sym = sym->sy_value.X_add_symbol;
fixp->fx_addsy = sym;
reloc = tc_gen_reloc (sec, fixp);
for (j = 0; reloc[j]; j++)
@ -1642,6 +1668,15 @@ write_object_file ()
resolve_symbol_value (symp);
}
/* Skip symbols which were equated to undefined or common
symbols. */
if (symp->sy_value.X_op == O_symbol
&& (! S_IS_DEFINED (symp) || S_IS_COMMON (symp)))
{
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
continue;
}
/* So far, common symbols have been treated like undefined symbols.
Put them in the common section now. */
if (S_IS_DEFINED (symp) == 0
@ -1703,6 +1738,9 @@ write_object_file ()
/* Now do any format-specific adjustments to the symbol table, such
as adding file symbols. */
#ifdef tc_adjust_symtab
tc_adjust_symtab ();
#endif
#ifdef obj_adjust_symtab
obj_adjust_symtab ();
#endif
@ -2402,8 +2440,10 @@ fixup_segment (fixP, this_segment_type)
else
{
seg_reloc_count++;
#if !(defined (TC_M68K) && defined (OBJ_ELF))
#if !defined (TC_I386) || !(defined (OBJ_ELF) || defined (OBJ_COFF))
add_number += S_GET_VALUE (add_symbolP);
#endif
#endif
}
}
@ -2531,6 +2571,13 @@ number_to_chars_littleendian (buf, val, n)
}
}
void
write_print_statistics (file)
FILE *file;
{
fprintf (stderr, "fixups: %d\n", n_fixups);
}
/* for debugging */
extern int indent_level;
extern void print_symbol_value_1 ();