+Fri Mar 3 16:26:19 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * tc.h (md_apply_fix3): If MD_APPLY_FIX3 is defined, declare
+ md_apply_fix3.
+
+ * write.c (fixup_segment): If MD_APPLY_FIX3 is defined, call
+ md_apply_fix3 with the normal 2 arguments and the current segment
+ pointer instead of md_apply_fix.
+
+ * config/tc-ppc.h (MD_APPLY_FIX3): Define.
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Warn if -mrelocatable
+ and a non PC relative relocation that isn't in the .got2 segment
+ was performed.
+ (md_apply_fix3): Rename from md_apply_fix and take segment pointer
+ as third argument. If ELF object format, call ppc_elf_validate_fix
+ for normal relocations.
+ (md_parse_option): If ELF object format, recognize the
+ -mrelocatable switch.
+
+Thu Mar 2 16:34:44 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.h (AOUT_MACHTYPE): Define as 100, not 0.
+
Tue Feb 28 18:29:27 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
* config/tc-arm.c, config/tc-arm.h (md_operand): Replaced empty
Wed Nov 23 19:36:09 1994 Steve Chamberlain (sac@jonny.cygnus.com)
- * config/obj-coff.h (TARGET_FORMAT): Select between coff-shl and coff-sh.
+ * config/obj-coff.h (TARGET_FORMAT): Select between coff-shl and
+ coff-sh.
* config/sh.mh (TARG_CPU_DEPENDENTS): Get it right.
* config/tc-sh.c (little): New function.
(md_parse_option): Notice new option.
#ifdef OBJ_ELF
static bfd_reloc_code_real_type ppc_elf_suffix PARAMS ((char **));
static void ppc_elf_cons PARAMS ((int));
+static void ppc_elf_validate_fix (fixS *, segT);
#endif
\f
/* Generic assembler global variables which must be defined by all
{ "long", ppc_elf_cons, 4 },
{ "word", ppc_elf_cons, 2 },
{ "short", ppc_elf_cons, 2 },
- { "byte", ppc_elf_cons, 1 },
#endif
/* This pseudo-op is used even when not generating XCOFF output. */
/* Macro hash table. */
static struct hash_control *ppc_macro_hash;
+#ifdef OBJ_ELF
+/* Whether to warn about non PC relative relocations that aren't
+ in the .got2 section. */
+static int mrelocatable = 0;
+#endif
+
#ifdef OBJ_COFF
/* The RS/6000 assembler uses the .csect pseudo-op to generate code
/* -many means to assemble for any architecture (PWR/PWRX/PPC). */
else if (strcmp (arg, "any") == 0)
ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_PPC;
+#ifdef OBJ_ELF
+ /* -mrelocatable -- warn about initializations that require relocation */
+ else if (strcmp (arg, "relocatable") == 0)
+ mrelocatable = 1;
+#endif
else
{
as_bad ("invalid architecture -m%s", arg);
-many generate code for any architecture (PWR/PWRX/PPC)\n");
#ifdef OBJ_ELF
fprintf(stream, "\
+-mrelocatable warn incompatible with GCC's -mrelocatble option\n\
-V print assembler version number\n\
-Qy, -Qn ignored\n");
#endif
*str_p += 2;
return BFD_RELOC_HI16;
}
- else if (strncmp (str, "@PCREL", 6) == 0 || strncmp (str, "@pcrel", 6) == 0)
- { /* this is a hack */
- *str_p += 6;
- return BFD_RELOC_32_PCREL;
- }
return BFD_RELOC_UNUSED;
}
-/* Like normal .long, except support @got, etc. */
-/* worker to do .byte etc statements */
+/* Like normal .long/.short/.word, except support @got, etc. */
/* clobbers input_line_pointer, checks */
/* end-of-line. */
static void
demand_empty_rest_of_line ();
}
+/* Validate any relocations emitted for -mrelocatable */
+static void
+ppc_elf_validate_fix (fixS *fixp, segT seg)
+{
+ if (mrelocatable
+ && !fixp->fx_done
+ && !fixp->fx_pcrel
+ && fixp->fx_r_type <= BFD_RELOC_UNUSED
+ && strcmp (segment_name (seg), ".got2") != 0)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ "Relocation cannot be done when using -mrelocatable");
+ }
+}
+
#endif /* OBJ_ELF */
/* We need to keep a list of fixups. We can't simply generate them as
abort ();
}
-/* Parse an operand that is machine-specific. We just return without
- modifying the expression if we have nothing to do. */
-
-/*ARGSUSED*/
-void
-md_operand (expressionP)
- expressionS *expressionP;
-{
-}
-
/* We have no need to default values of symbols. */
/*ARGSUSED*/
fixup. */
int
-md_apply_fix (fixp, valuep)
+md_apply_fix3 (fixp, valuep, seg)
fixS *fixp;
valueT *valuep;
+ segT seg;
{
valueT value;
}
else
{
+#ifdef OBJ_ELF
+ ppc_elf_validate_fix (fixp, seg);
+#endif
switch (fixp->fx_r_type)
{
case BFD_RELOC_32:
+ if (fixp->fx_pcrel)
+ {
+ fixp->fx_r_type = BFD_RELOC_32_PCREL;
+ value += fixp->fx_frag->fr_address + fixp->fx_where;
+ } /* fall through */
+
case BFD_RELOC_32_PCREL:
md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
value, 4);
case BFD_RELOC_HI16_S:
case BFD_RELOC_PPC_TOC16:
case BFD_RELOC_16:
+ if (fixp->fx_pcrel)
+ abort ();
+
md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
value, 2);
break;
+
case BFD_RELOC_8:
+ if (fixp->fx_pcrel)
+ abort ();
+
md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
value, 1);
break;
#ifndef BFD
static object_headers headers;
-static char *the_object_file;
#endif
long string_byte_count;
offsetT offset, int pcrel,
int r_type));
#endif
-#if defined (BFD_ASSEMBLER) || !defined (BFD)
+#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))
static long fixup_segment PARAMS ((fixS * fixP, segT this_segment_type));
#endif
static relax_addressT relax_align PARAMS ((relax_addressT addr, int align));
struct frchain *frchp;
{
fragS dummy, *prev_frag = &dummy;
- fixS fix_dummy;
#ifdef BFD_ASSEMBLER
- fixS *prev_fix = &fix_dummy;
+ fixS fix_dummy, *prev_fix = &fix_dummy;
#endif
for (; frchp && frchp->frch_seg == section; frchp = frchp->frch_next)
fragS *fragP;
#else
static void
-cvt_frag_to_fill (headers, fragP)
- object_headers *headers;
+cvt_frag_to_fill (headersP, fragP)
+ object_headers *headersP;
fragS *fragP;
#endif
{
#ifdef BFD_ASSEMBLER
md_convert_frag (stdoutput, sec, fragP);
#else
- md_convert_frag (headers, fragP);
+ md_convert_frag (headersP, fragP);
#endif
assert (fragP->fr_next == NULL || (fragP->fr_next->fr_address - fragP->fr_address == fragP->fr_fix));
a routine to check for the definition of the procedure "_main",
and if so -- fix it up so that it can be program entry point. */
vms_check_for_main ();
-#endif /* VMS */
+#endif /* OBJ_VMS */
/* After every sub-segment, we fake an ".align ...". This conforms to
BSD4.2 brane-damage. We then fake ".fill 0" because that is the kind of
#ifndef BFD_ASSEMBLER
#ifndef OBJ_VMS
{ /* not vms */
+ char *the_object_file;
long object_file_size;
/*
* Scan every FixS performing fixups. We had to wait until now to do
/* Write the data to the file */
output_file_append (the_object_file, object_file_size, out_file_name);
+ free (the_object_file);
#endif
} /* non vms output */
-#else /* VMS */
+#else /* OBJ_VMS */
/*
* Now do the VMS-dependent part of writing the object file
*/
H_GET_DATA_SIZE (&headers),
H_GET_BSS_SIZE (&headers),
text_frag_root, data_frag_root);
-#endif /* VMS */
+#endif /* OBJ_VMS */
#else /* BFD_ASSEMBLER */
/* Resolve symbol values. This needs to be done before processing
*/
} /* relax_segment() */
-#if defined (BFD_ASSEMBLER) || !defined (BFD)
+#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))
#ifndef TC_RELOC_RTSYM_LOC_FIXUP
#define TC_RELOC_RTSYM_LOC_FIXUP(X) (1)
if (!fixP->fx_done)
{
+#ifdef MD_APPLY_FIX3
+ md_apply_fix3 (fixP, &add_number, this_segment_type);
+#else
#ifdef BFD_ASSEMBLER
md_apply_fix (fixP, &add_number);
#else
md_apply_fix (fixP, add_number);
#endif
+#endif
#ifndef TC_HANDLES_FX_DONE
/* If the tc-* files haven't been converted, assume it's handling
return seg_reloc_count;
}
-#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */
+#endif /* defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS)) */
void
number_to_chars_bigendian (buf, val, n)