Fix PR 8255

This commit is contained in:
Michael Meissner 1995-10-24 18:59:05 +00:00
parent cb016f0140
commit 96fe71e1d5
4 changed files with 106 additions and 47 deletions

View File

@ -1,3 +1,22 @@
Tue Oct 24 14:50:38 1995 Michael Meissner <meissner@tiktok.cygnus.com>
* config/tc-ppc.h (TC_FORCE_RELOCATION_SECTION): Rename from
TC_FORCE_RELOCATION, taking an additional section argument. If
the section of the target symbol is not the same as the current
section, always force the relocation to be used.
(MD_PCREL_FROM_SECTION): New macro to call md_pcrel_from_section.
* config/tc-ppc.c (md_pcrel_from_section): Rename from the
md_pcrel_from function, taking an additional section argument.
Invoke TC_FORCE_RELOCATION_SECTION instead of TC_FORCE_RELOCATION.
* write.c (TC_FORCE_RELOCATION_SECTION): Define in terms of the
older TC_FORCE_RELOCATION if not defined.
(MD_PCREL_FROM_SECTION): If not defined, invoke md_pcrel_from.
(fixup_segment): Use MD_PCREL_FROM_SECTION instead of
md_pcrel_from, and TC_FORCE_RELOCATION_SECTION instead of
TC_FORCE_RELOCATION.
Mon Oct 23 16:20:04 1995 Ken Raeburn <raeburn@cygnus.com>
* input-scrub.c (as_where): Set name to null pointer if we don't

View File

@ -561,10 +561,8 @@ md_parse_option (c, arg)
/* -mpwr means to assemble for the IBM POWER (RIOS1). */
else if (strcmp (arg, "pwr") == 0)
ppc_cpu = PPC_OPCODE_POWER;
/* -m601 means to assemble for the Motorola PowerPC 601. FIXME: We
ignore the option for now, but we should really use it to permit
instructions defined on the 601 that are not part of the standard
PowerPC architecture (mostly holdovers from the POWER). */
/* -m601 means to assemble for the Motorola PowerPC 601, which includes
instructions that are holdovers from the Power. */
else if (strcmp (arg, "601") == 0)
ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_601;
/* -mppc, -mppc32, -m603, and -m604 mean to assemble for the
@ -586,10 +584,10 @@ md_parse_option (c, arg)
and PowerPC. At present, we just allow the union, rather
than the intersection. */
else if (strcmp (arg, "com") == 0)
ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_PPC;
ppc_cpu = PPC_OPCODE_COMMON;
/* -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;
ppc_cpu = PPC_OPCODE_ANY;
#ifdef OBJ_ELF
/* -mrelocatable/-mrelocatable-lib -- warn about initializations that require relocation */
@ -700,17 +698,24 @@ ppc_set_cpu ()
enum bfd_architecture
ppc_arch ()
{
const char *default_cpu = TARGET_CPU;
ppc_set_cpu ();
if ((ppc_cpu & PPC_OPCODE_PPC) != 0)
return bfd_arch_powerpc;
else if ((ppc_cpu & PPC_OPCODE_POWER) != 0)
return bfd_arch_rs6000;
else
else if ((ppc_cpu & (PPC_OPCODE_COMMON | PPC_OPCODE_ANY)) != 0)
{
as_fatal ("Neither Power nor PowerPC opcodes were selected.");
return bfd_arch_unknown;
if (strcmp (default_cpu, "rs6000") == 0)
return bfd_arch_rs6000;
else if (strcmp (default_cpu, "powerpc") == 0
|| strcmp (default_cpu, "powerpcle") == 0)
return bfd_arch_powerpc;
}
as_fatal ("Neither Power nor PowerPC opcodes were selected.");
return bfd_arch_unknown;
}
/* This function is called when the assembler starts up. It is called
@ -724,6 +729,7 @@ md_begin ()
const struct powerpc_opcode *op_end;
const struct powerpc_macro *macro;
const struct powerpc_macro *macro_end;
boolean dup_insn = false;
ppc_set_cpu ();
@ -750,28 +756,13 @@ md_begin ()
retval = hash_insert (ppc_hash, op->name, (PTR) op);
if (retval != (const char *) NULL)
{
/* We permit a duplication of the mfdec instruction on
the 601, because it seems to have one value on the
601 and a different value on other PowerPC
processors. It's easier to permit a duplication than
to define a new instruction type flag. When using
-many/-mcom, the comparison instructions are a harmless
special case. */
if (strcmp (retval, "exists") != 0
|| ((((ppc_cpu & PPC_OPCODE_601) == 0
&& ((ppc_cpu & ~PPC_OPCODE_POWER2)
== (PPC_OPCODE_POWER | PPC_OPCODE_PPC)))
|| strcmp (op->name, "mfdec") != 0)
&& (((ppc_cpu & ~PPC_OPCODE_POWER2)
!= (PPC_OPCODE_POWER | PPC_OPCODE_PPC))
|| (strcmp (op->name, "cmpli") != 0
&& strcmp (op->name, "cmpi") != 0
&& strcmp (op->name, "cmp") != 0
&& strcmp (op->name, "cmpl") != 0))))
{
as_bad ("Internal assembler error for instruction %s", op->name);
abort ();
}
/* Ignore Power duplicates for -m601 */
if ((ppc_cpu & PPC_OPCODE_601) != 0
&& (op->flags & PPC_OPCODE_POWER) != 0)
continue;
as_bad ("Internal assembler error for instruction %s", op->name);
dup_insn = true;
}
}
}
@ -788,10 +779,16 @@ md_begin ()
retval = hash_insert (ppc_macro_hash, macro->name, (PTR) macro);
if (retval != (const char *) NULL)
abort ();
{
as_bad ("Internal assembler error for macro %s", macro->name);
dup_insn = true;
}
}
}
if (dup_insn)
abort ();
/* Tell the main code what the endianness is if it is not overidden by the user. */
if (!set_target_endian)
{
@ -3756,13 +3753,14 @@ md_undefined_symbol (name)
given a PC relative reloc. */
long
md_pcrel_from (fixp)
md_pcrel_from_section (fixp, sec)
fixS *fixp;
segT sec;
{
#ifdef OBJ_ELF
if (fixp->fx_addsy != (symbolS *) NULL
&& (! S_IS_DEFINED (fixp->fx_addsy)
|| TC_FORCE_RELOCATION (fixp)))
|| TC_FORCE_RELOCATION_SECTION (fixp, sec)))
return 0;
#endif

View File

@ -102,6 +102,10 @@ extern int target_big_endian;
/* Question marks are permitted in symbol names. */
#define LEX_QM 1
/* Don't adjust TOC relocs. */
#define tc_fix_adjustable(fixp) ppc_pe_fix_adjustable (fixp)
extern int ppc_pe_fix_adjustable PARAMS ((struct fix *));
#endif
#ifdef OBJ_XCOFF
@ -187,15 +191,20 @@ extern void ppc_frob_file PARAMS ((void));
#endif
/* Branch prediction relocations must force relocation */
#define TC_FORCE_RELOCATION(FIXP) \
#define TC_FORCE_RELOCATION_SECTION(FIXP,SEC) \
((FIXP)->fx_r_type == BFD_RELOC_PPC_B16_BRTAKEN \
|| (FIXP)->fx_r_type == BFD_RELOC_PPC_B16_BRNTAKEN \
|| (FIXP)->fx_r_type == BFD_RELOC_PPC_BA16_BRTAKEN \
|| (FIXP)->fx_r_type == BFD_RELOC_PPC_BA16_BRNTAKEN)
|| (FIXP)->fx_r_type == BFD_RELOC_PPC_BA16_BRNTAKEN \
|| ((FIXP)->fx_addsy && !(FIXP)->fx_subsy && (FIXP)->fx_addsy->bsym \
&& (FIXP)->fx_addsy->bsym->section != SEC))
#endif /* OBJ_ELF */
/* call md_apply_fix3 with segment instead of md_apply_fix */
#define MD_APPLY_FIX3
/* call md_pcrel_from_section, not md_pcrel_from */
#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC)
#define md_operand(x)

View File

@ -43,6 +43,14 @@
#define TC_FORCE_RELOCATION(FIXP) 0
#endif
#ifndef TC_FORCE_RELOCATION_SECTION
#define TC_FORCE_RELOCATION_SECTION(FIXP,SEG) TC_FORCE_RELOCATION(FIXP)
#endif
#ifndef MD_PCREL_FROM_SECTION
#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from(FIXP)
#endif
#ifndef WORKING_DOT_WORD
extern CONST int md_short_jump_size;
extern CONST int md_long_jump_size;
@ -235,7 +243,7 @@ fix_new_exp (frag, where, size, exp, pcrel, r_type)
symbolS *add = NULL;
symbolS *sub = NULL;
offsetT off = 0;
switch (exp->X_op)
{
case O_absent:
@ -254,6 +262,19 @@ fix_new_exp (frag, where, size, exp, pcrel, r_type)
return fix_new_exp (frag, where, size, exp, pcrel, r_type);
}
case O_symbol_rva:
add = exp->X_add_symbol;
off = exp->X_add_number;
#if defined(BFD_ASSEMBLER)
r_type = BFD_RELOC_RVA;
#elif defined(TC_RVA_RELOC)
r_type = TC_RVA_RELOC;
#else
as_fatal("rva not supported");
#endif
break;
case O_uminus:
sub = exp->X_add_symbol;
off = exp->X_add_number;
@ -355,6 +376,7 @@ chain_frchains_together_1 (section, frchp)
{
prev_frag->fr_next = frchp->frch_root;
prev_frag = frchp->frch_last;
assert (prev_frag->fr_type != 0);
#ifdef BFD_ASSEMBLER
if (frchp->fix_root != (fixS *) NULL)
{
@ -366,6 +388,7 @@ chain_frchains_together_1 (section, frchp)
}
#endif
}
assert (prev_frag->fr_type != 0);
prev_frag->fr_next = 0;
return prev_frag;
}
@ -2183,11 +2206,21 @@ fixup_segment (fixP, this_segment_type)
if (sub_symbolP)
{
resolve_symbol_value (sub_symbolP);
if (!add_symbolP)
if (add_symbolP == NULL || add_symbol_segment == absolute_section)
{
/* Its just -sym */
if (add_symbolP != NULL)
{
add_number += S_GET_VALUE (add_symbolP);
add_symbolP = NULL;
fixP->fx_addsy = NULL;
}
/* It's just -sym */
if (S_GET_SEGMENT (sub_symbolP) == absolute_section)
add_number -= S_GET_VALUE (sub_symbolP);
{
add_number -= S_GET_VALUE (sub_symbolP);
fixP->fx_subsy = NULL;
}
else if (pcrel
&& S_GET_SEGMENT (sub_symbolP) == this_segment_type)
{
@ -2200,9 +2233,8 @@ fixup_segment (fixP, this_segment_type)
"Negative of non-absolute symbol %s",
S_GET_NAME (sub_symbolP));
}
else if ((S_GET_SEGMENT (sub_symbolP) == add_symbol_segment)
&& (SEG_NORMAL (add_symbol_segment)
|| (add_symbol_segment == absolute_section)))
else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
&& SEG_NORMAL (add_symbol_segment))
{
/* Difference of 2 symbols from same segment.
Can't make difference of 2 undefineds: 'value' means
@ -2223,10 +2255,11 @@ fixup_segment (fixP, this_segment_type)
/* Let the target machine make the final determination
as to whether or not a relocation will be needed to
handle this fixup. */
if (!TC_FORCE_RELOCATION (fixP))
if (!TC_FORCE_RELOCATION_SECTION (fixP, this_segment_type))
{
fixP->fx_pcrel = 0;
fixP->fx_addsy = NULL;
fixP->fx_subsy = NULL;
}
}
else
@ -2248,7 +2281,7 @@ fixup_segment (fixP, this_segment_type)
)
{
/* Make it pc-relative. */
add_number += (md_pcrel_from (fixP)
add_number += (MD_PCREL_FROM_SECTION (fixP, this_segment_type)
- S_GET_VALUE (sub_symbolP));
pcrel = 1;
fixP->fx_pcrel = 1;
@ -2304,7 +2337,7 @@ fixup_segment (fixP, this_segment_type)
#endif /* TC_I960 */
add_number += S_GET_VALUE (add_symbolP);
add_number -= md_pcrel_from (fixP);
add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment_type);
pcrel = 0; /* Lie. Don't want further pcrel processing. */
/* Let the target machine make the final determination
@ -2378,7 +2411,7 @@ fixup_segment (fixP, this_segment_type)
if (pcrel)
{
add_number -= md_pcrel_from (fixP);
add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment_type);
if (add_symbolP == 0)
{
#ifndef BFD_ASSEMBLER