Make gas parse '__tls_get_addr(foo@tlsgd)'.
Corresponds to 727fc41e077139570ea8b8ddfd6c546b2a55627c. This allows us to use -no-integrated-as with clang, if we prefer. Obtained from: binutils-gdb (Relicensed from Alan Modra as GPLv2) MFC after: 2 weeks X-MFC-with: r275718
This commit is contained in:
parent
d13ccc6ac2
commit
e5701220a8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=275873
@ -2509,108 +2509,156 @@ md_assemble (char *str)
|
||||
(char *) NULL, 0);
|
||||
}
|
||||
#ifdef OBJ_ELF
|
||||
else if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
|
||||
else
|
||||
{
|
||||
/* Some TLS tweaks. */
|
||||
switch (reloc)
|
||||
if (ex.X_op == O_symbol && str[0] == '(')
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case BFD_RELOC_PPC_TLS:
|
||||
insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2,
|
||||
(char *) NULL, 0);
|
||||
break;
|
||||
/* We'll only use the 32 (or 64) bit form of these relocations
|
||||
in constants. Instructions get the 16 bit form. */
|
||||
case BFD_RELOC_PPC_DTPREL:
|
||||
reloc = BFD_RELOC_PPC_DTPREL16;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL:
|
||||
reloc = BFD_RELOC_PPC_TPREL16;
|
||||
break;
|
||||
}
|
||||
const char *sym_name = S_GET_NAME (ex.X_add_symbol);
|
||||
if (sym_name[0] == '.')
|
||||
++sym_name;
|
||||
|
||||
/* For the absolute forms of branches, convert the PC
|
||||
relative form back into the absolute. */
|
||||
if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
|
||||
{
|
||||
switch (reloc)
|
||||
if (strcasecmp (sym_name, "__tls_get_addr") == 0)
|
||||
{
|
||||
case BFD_RELOC_PPC_B26:
|
||||
reloc = BFD_RELOC_PPC_BA26;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16:
|
||||
reloc = BFD_RELOC_PPC_BA16;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16_BRTAKEN:
|
||||
reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16_BRNTAKEN:
|
||||
reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
expressionS tls_exp;
|
||||
|
||||
hold = input_line_pointer;
|
||||
input_line_pointer = str + 1;
|
||||
expression (&tls_exp);
|
||||
if (tls_exp.X_op == O_symbol)
|
||||
{
|
||||
reloc = BFD_RELOC_UNUSED;
|
||||
if (strncasecmp (input_line_pointer, "@tlsgd)", 7) == 0)
|
||||
{
|
||||
reloc = BFD_RELOC_PPC_TLSGD;
|
||||
input_line_pointer += 7;
|
||||
}
|
||||
else if (strncasecmp (input_line_pointer, "@tlsld)", 7) == 0)
|
||||
{
|
||||
reloc = BFD_RELOC_PPC_TLSLD;
|
||||
input_line_pointer += 7;
|
||||
}
|
||||
if (reloc != BFD_RELOC_UNUSED)
|
||||
{
|
||||
SKIP_WHITESPACE ();
|
||||
str = input_line_pointer;
|
||||
|
||||
if (fc >= MAX_INSN_FIXUPS)
|
||||
as_fatal (_("too many fixups"));
|
||||
fixups[fc].exp = tls_exp;
|
||||
fixups[fc].opindex = *opindex_ptr;
|
||||
fixups[fc].reloc = reloc;
|
||||
++fc;
|
||||
}
|
||||
}
|
||||
input_line_pointer = hold;
|
||||
}
|
||||
}
|
||||
|
||||
if (ppc_obj64
|
||||
&& (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
|
||||
if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
|
||||
{
|
||||
/* Some TLS tweaks. */
|
||||
switch (reloc)
|
||||
{
|
||||
case BFD_RELOC_16:
|
||||
reloc = BFD_RELOC_PPC64_ADDR16_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16:
|
||||
reloc = BFD_RELOC_PPC64_ADDR16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_16_GOTOFF:
|
||||
reloc = BFD_RELOC_PPC64_GOT16_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_GOTOFF:
|
||||
reloc = BFD_RELOC_PPC64_GOT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_PLTOFF:
|
||||
reloc = BFD_RELOC_PPC64_PLT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_16_BASEREL:
|
||||
reloc = BFD_RELOC_PPC64_SECTOFF_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_BASEREL:
|
||||
reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TOC16:
|
||||
reloc = BFD_RELOC_PPC64_TOC16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_TOC16_LO:
|
||||
reloc = BFD_RELOC_PPC64_TOC16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_PLTGOT16:
|
||||
reloc = BFD_RELOC_PPC64_PLTGOT16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_PLTGOT16_LO:
|
||||
reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_DTPREL16:
|
||||
reloc = BFD_RELOC_PPC64_DTPREL16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_DTPREL16_LO:
|
||||
reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL16:
|
||||
reloc = BFD_RELOC_PPC64_TPREL16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL16_LO:
|
||||
reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16:
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16_LO:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16_LO:
|
||||
break;
|
||||
default:
|
||||
as_bad (_("unsupported relocation for DS offset field"));
|
||||
break;
|
||||
|
||||
case BFD_RELOC_PPC_TLS:
|
||||
insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2,
|
||||
(char *) NULL, 0);
|
||||
break;
|
||||
|
||||
/* We'll only use the 32 (or 64) bit form of these relocations
|
||||
in constants. Instructions get the 16 bit form. */
|
||||
case BFD_RELOC_PPC_DTPREL:
|
||||
reloc = BFD_RELOC_PPC_DTPREL16;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL:
|
||||
reloc = BFD_RELOC_PPC_TPREL16;
|
||||
break;
|
||||
}
|
||||
|
||||
/* For the absolute forms of branches, convert the PC
|
||||
relative form back into the absolute. */
|
||||
if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
|
||||
{
|
||||
switch (reloc)
|
||||
{
|
||||
case BFD_RELOC_PPC_B26:
|
||||
reloc = BFD_RELOC_PPC_BA26;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16:
|
||||
reloc = BFD_RELOC_PPC_BA16;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16_BRTAKEN:
|
||||
reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16_BRNTAKEN:
|
||||
reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ppc_obj64
|
||||
&& (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
|
||||
{
|
||||
switch (reloc)
|
||||
{
|
||||
case BFD_RELOC_16:
|
||||
reloc = BFD_RELOC_PPC64_ADDR16_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16:
|
||||
reloc = BFD_RELOC_PPC64_ADDR16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_16_GOTOFF:
|
||||
reloc = BFD_RELOC_PPC64_GOT16_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_GOTOFF:
|
||||
reloc = BFD_RELOC_PPC64_GOT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_PLTOFF:
|
||||
reloc = BFD_RELOC_PPC64_PLT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_16_BASEREL:
|
||||
reloc = BFD_RELOC_PPC64_SECTOFF_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_BASEREL:
|
||||
reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TOC16:
|
||||
reloc = BFD_RELOC_PPC64_TOC16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_TOC16_LO:
|
||||
reloc = BFD_RELOC_PPC64_TOC16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_PLTGOT16:
|
||||
reloc = BFD_RELOC_PPC64_PLTGOT16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_PLTGOT16_LO:
|
||||
reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_DTPREL16:
|
||||
reloc = BFD_RELOC_PPC64_DTPREL16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_DTPREL16_LO:
|
||||
reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL16:
|
||||
reloc = BFD_RELOC_PPC64_TPREL16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL16_LO:
|
||||
reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16:
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16_LO:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16_LO:
|
||||
break;
|
||||
default:
|
||||
as_bad (_("unsupported relocation for DS offset field"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2618,12 +2666,11 @@ md_assemble (char *str)
|
||||
if (fc >= MAX_INSN_FIXUPS)
|
||||
as_fatal (_("too many fixups"));
|
||||
fixups[fc].exp = ex;
|
||||
fixups[fc].opindex = 0;
|
||||
fixups[fc].opindex = *opindex_ptr;
|
||||
fixups[fc].reloc = reloc;
|
||||
++fc;
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
#else /* OBJ_ELF */
|
||||
else
|
||||
{
|
||||
/* We need to generate a fixup for this expression. */
|
||||
@ -2634,6 +2681,7 @@ md_assemble (char *str)
|
||||
fixups[fc].reloc = BFD_RELOC_UNUSED;
|
||||
++fc;
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
if (need_paren)
|
||||
{
|
||||
@ -5908,6 +5956,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
||||
break;
|
||||
|
||||
case BFD_RELOC_PPC_TLS:
|
||||
case BFD_RELOC_PPC_TLSLD:
|
||||
case BFD_RELOC_PPC_TLSGD:
|
||||
break;
|
||||
|
||||
case BFD_RELOC_PPC_DTPMOD:
|
||||
|
Loading…
Reference in New Issue
Block a user