mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
include/elf/
* spu.h (R_SPU_PPU32, R_SPU_PPU64): Define. bfd/ * reloc.c (BFD_RELOC_SPU_PPU32, BFD_RELOC_SPU_PPU64): Define. * elf-bfd.h (struct elf_backend_data): Change return type of elf_backend_relocate_section to int. * elf32-spu.c (elf_howto_table): Add howtos for R_SPU_PPU32 and R_SPU_PPU64. (spu_elf_bfd_to_reloc_type): Convert new relocs. (spu_elf_count_relocs): New function. (elf_backend_count_relocs): Define. (spu_elf_relocate_section): Arrange to emit R_SPU_PPU32 and R_SPU_PPU64 relocs. * elflink.c (elf_link_input_bfd): Emit relocs if relocate_section returns 2. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. gas/ * config/tc-spu.c (md_pseudo_table): Add int, long, quad. Call spu_cons for word. (md_assemble): Tidy use of insn.flag. (get_imm): Likewise. Handle uppercase input too. (spu_cons): New function. * config/tc-spu.h (tc_fix_adjustable): Don't adjust SPU_PPU relocs. (TC_FORCE_RELOCATION): Don't resolve them either. binutils/ * embedspu.sh (find_prog): Prefer prog in same dir as embedspu over one found on the users path. (main): Generate .reloc for each R_SPU_PPU* reloc.
This commit is contained in:
parent
88b131f3ce
commit
ece5ef6079
@ -1,3 +1,20 @@
|
||||
2007-05-11 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* reloc.c (BFD_RELOC_SPU_PPU32, BFD_RELOC_SPU_PPU64): Define.
|
||||
* elf-bfd.h (struct elf_backend_data): Change return type of
|
||||
elf_backend_relocate_section to int.
|
||||
* elf32-spu.c (elf_howto_table): Add howtos for R_SPU_PPU32 and
|
||||
R_SPU_PPU64.
|
||||
(spu_elf_bfd_to_reloc_type): Convert new relocs.
|
||||
(spu_elf_count_relocs): New function.
|
||||
(elf_backend_count_relocs): Define.
|
||||
(spu_elf_relocate_section): Arrange to emit R_SPU_PPU32 and
|
||||
R_SPU_PPU64 relocs.
|
||||
* elflink.c (elf_link_input_bfd): Emit relocs if relocate_section
|
||||
returns 2.
|
||||
* bfd-in2.h: Regenerate.
|
||||
* libbfd.h: Regenerate.
|
||||
|
||||
2007-05-10 Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
* elf32-arm.c (elf32_arm_check_relocs): Don't create PLT entries
|
||||
|
@ -2513,6 +2513,8 @@ relocation types already defined. */
|
||||
BFD_RELOC_SPU_PCREL16,
|
||||
BFD_RELOC_SPU_LO16,
|
||||
BFD_RELOC_SPU_HI16,
|
||||
BFD_RELOC_SPU_PPU32,
|
||||
BFD_RELOC_SPU_PPU64,
|
||||
|
||||
/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or
|
||||
"addend" in some special way.
|
||||
|
@ -792,8 +792,11 @@ struct elf_backend_data
|
||||
STB_LOCAL/STT_SECTION symbols specially. The output symbol is
|
||||
going to be the section symbol corresponding to the output
|
||||
section, which means that the addend must be adjusted
|
||||
accordingly. */
|
||||
bfd_boolean (*elf_backend_relocate_section)
|
||||
accordingly.
|
||||
|
||||
Returns FALSE on error, TRUE on success, 2 if successful and
|
||||
relocations should be written for this section. */
|
||||
int (*elf_backend_relocate_section)
|
||||
(bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
|
||||
asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs,
|
||||
Elf_Internal_Sym *local_syms, asection **local_sections);
|
||||
|
@ -78,6 +78,12 @@ static reloc_howto_type elf_howto_table[] = {
|
||||
HOWTO (R_SPU_REL32, 0, 2, 32, TRUE, 0, complain_overflow_dont,
|
||||
bfd_elf_generic_reloc, "SPU_REL32",
|
||||
FALSE, 0, 0xffffffff, TRUE),
|
||||
HOWTO (R_SPU_PPU32, 0, 2, 32, FALSE, 0, complain_overflow_dont,
|
||||
bfd_elf_generic_reloc, "SPU_PPU32",
|
||||
FALSE, 0, 0xffffffff, FALSE),
|
||||
HOWTO (R_SPU_PPU64, 0, 4, 64, FALSE, 0, complain_overflow_dont,
|
||||
bfd_elf_generic_reloc, "SPU_PPU64",
|
||||
FALSE, 0, -1, FALSE),
|
||||
};
|
||||
|
||||
static struct bfd_elf_special_section const spu_elf_special_sections[] = {
|
||||
@ -120,6 +126,10 @@ spu_elf_bfd_to_reloc_type (bfd_reloc_code_real_type code)
|
||||
return R_SPU_ADDR32;
|
||||
case BFD_RELOC_32_PCREL:
|
||||
return R_SPU_REL32;
|
||||
case BFD_RELOC_SPU_PPU32:
|
||||
return R_SPU_PPU32;
|
||||
case BFD_RELOC_SPU_PPU64:
|
||||
return R_SPU_PPU64;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2627,6 +2637,26 @@ spu_elf_final_link (bfd *output_bfd, struct bfd_link_info *info)
|
||||
return bfd_elf_final_link (output_bfd, info);
|
||||
}
|
||||
|
||||
/* Called when not normally emitting relocs, ie. !info->relocatable
|
||||
and !info->emitrelocations. Returns a count of special relocs
|
||||
that need to be emitted. */
|
||||
|
||||
static unsigned int
|
||||
spu_elf_count_relocs (asection *sec, Elf_Internal_Rela *relocs)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
Elf_Internal_Rela *relend = relocs + sec->reloc_count;
|
||||
|
||||
for (; relocs < relend; relocs++)
|
||||
{
|
||||
int r_type = ELF32_R_TYPE (relocs->r_info);
|
||||
if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD. */
|
||||
|
||||
static bfd_boolean
|
||||
@ -2644,6 +2674,7 @@ spu_elf_relocate_section (bfd *output_bfd,
|
||||
Elf_Internal_Rela *rel, *relend;
|
||||
struct spu_link_hash_table *htab;
|
||||
bfd_boolean ret = TRUE;
|
||||
bfd_boolean emit_these_relocs = FALSE;
|
||||
|
||||
htab = spu_hash_table (info);
|
||||
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||||
@ -2669,10 +2700,15 @@ spu_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
|
||||
{
|
||||
emit_these_relocs = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
howto = elf_howto_table + r_type;
|
||||
unresolved_reloc = FALSE;
|
||||
warned = FALSE;
|
||||
|
||||
h = NULL;
|
||||
sym = NULL;
|
||||
sec = NULL;
|
||||
@ -2796,6 +2832,31 @@ spu_elf_relocate_section (bfd *output_bfd,
|
||||
}
|
||||
}
|
||||
|
||||
if (ret
|
||||
&& emit_these_relocs
|
||||
&& !info->relocatable
|
||||
&& !info->emitrelocations)
|
||||
{
|
||||
Elf_Internal_Rela *wrel;
|
||||
Elf_Internal_Shdr *rel_hdr;
|
||||
|
||||
wrel = rel = relocs;
|
||||
relend = relocs + input_section->reloc_count;
|
||||
for (; rel < relend; rel++)
|
||||
{
|
||||
int r_type;
|
||||
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
|
||||
*wrel++ = *rel;
|
||||
}
|
||||
input_section->reloc_count = wrel - relocs;
|
||||
/* Backflips for _bfd_elf_link_output_relocs. */
|
||||
rel_hdr = &elf_section_data (input_section)->rel_hdr;
|
||||
rel_hdr->sh_size = input_section->reloc_count * rel_hdr->sh_entsize;
|
||||
ret = 2;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3059,6 +3120,7 @@ spu_elf_modify_program_headers (bfd *abfd, struct bfd_link_info *info)
|
||||
#define bfd_elf32_bfd_reloc_type_lookup spu_elf_reloc_type_lookup
|
||||
#define bfd_elf32_bfd_reloc_name_lookup spu_elf_reloc_name_lookup
|
||||
#define elf_info_to_howto spu_elf_info_to_howto
|
||||
#define elf_backend_count_relocs spu_elf_count_relocs
|
||||
#define elf_backend_relocate_section spu_elf_relocate_section
|
||||
#define elf_backend_symbol_processing spu_elf_backend_symbol_processing
|
||||
#define elf_backend_link_output_symbol_hook spu_elf_output_symbol_hook
|
||||
|
@ -8198,7 +8198,7 @@ _bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info)
|
||||
static bfd_boolean
|
||||
elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
{
|
||||
bfd_boolean (*relocate_section)
|
||||
int (*relocate_section)
|
||||
(bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
|
||||
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
|
||||
bfd *output_bfd;
|
||||
@ -8212,7 +8212,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
asection **ppsection;
|
||||
asection *o;
|
||||
const struct elf_backend_data *bed;
|
||||
bfd_boolean emit_relocs;
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
|
||||
output_bfd = finfo->output_bfd;
|
||||
@ -8225,9 +8224,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
if ((input_bfd->flags & DYNAMIC) != 0)
|
||||
return TRUE;
|
||||
|
||||
emit_relocs = (finfo->info->relocatable
|
||||
|| finfo->info->emitrelocations);
|
||||
|
||||
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||||
if (elf_bad_symtab (input_bfd))
|
||||
{
|
||||
@ -8443,6 +8439,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
Elf_Internal_Rela *internal_relocs;
|
||||
bfd_vma r_type_mask;
|
||||
int r_sym_shift;
|
||||
int ret;
|
||||
|
||||
/* Get the swapped relocs. */
|
||||
internal_relocs
|
||||
@ -8580,14 +8577,17 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||
corresponding to the output section, which will require
|
||||
the addend to be adjusted. */
|
||||
|
||||
if (! (*relocate_section) (output_bfd, finfo->info,
|
||||
ret = (*relocate_section) (output_bfd, finfo->info,
|
||||
input_bfd, o, contents,
|
||||
internal_relocs,
|
||||
isymbuf,
|
||||
finfo->sections))
|
||||
finfo->sections);
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
if (emit_relocs)
|
||||
if (ret == 2
|
||||
|| finfo->info->relocatable
|
||||
|| finfo->info->emitrelocations)
|
||||
{
|
||||
Elf_Internal_Rela *irela;
|
||||
Elf_Internal_Rela *irelaend;
|
||||
|
@ -919,6 +919,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
||||
"BFD_RELOC_SPU_PCREL16",
|
||||
"BFD_RELOC_SPU_LO16",
|
||||
"BFD_RELOC_SPU_HI16",
|
||||
"BFD_RELOC_SPU_PPU32",
|
||||
"BFD_RELOC_SPU_PPU64",
|
||||
"BFD_RELOC_ALPHA_GPDISP_HI16",
|
||||
"BFD_RELOC_ALPHA_GPDISP_LO16",
|
||||
"BFD_RELOC_ALPHA_GPDISP",
|
||||
|
@ -1972,6 +1972,10 @@ ENUMX
|
||||
BFD_RELOC_SPU_LO16
|
||||
ENUMX
|
||||
BFD_RELOC_SPU_HI16
|
||||
ENUMX
|
||||
BFD_RELOC_SPU_PPU32
|
||||
ENUMX
|
||||
BFD_RELOC_SPU_PPU64
|
||||
ENUMDOC
|
||||
SPU Relocations.
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2007-05-11 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* embedspu.sh (find_prog): Prefer prog in same dir as embedspu
|
||||
over one found on the users path.
|
||||
(main): Generate .reloc for each R_SPU_PPU* reloc.
|
||||
|
||||
2007-04-28 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* prdbg.c (tg_variable): Adjust for changed demangler.
|
||||
|
@ -38,12 +38,12 @@ mydir=`dirname "$0"`
|
||||
find_prog ()
|
||||
{
|
||||
prog=`echo $1 | sed "$program_transform_name"`
|
||||
which $prog > /dev/null 2> /dev/null && return 0
|
||||
prog="$mydir/$prog"
|
||||
test -x "$prog" && return 0
|
||||
prog="$mydir/$1"
|
||||
test -x "$prog" && return 0
|
||||
prog=`echo $1 | sed "$program_transform_name"`
|
||||
which $prog > /dev/null 2> /dev/null && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ main ()
|
||||
CC="$prog"
|
||||
fi
|
||||
|
||||
# Find readelf. Any old readelf should do. We only want to read syms.
|
||||
# Find readelf. Any old readelf should do.
|
||||
find_prog readelf
|
||||
if test $? -ne 0; then
|
||||
if which readelf > /dev/null 2> /dev/null; then
|
||||
@ -119,8 +119,13 @@ main ()
|
||||
toe=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *\([0-9]*\)\] *\.toe *[PROGN]*BITS *\([0-9a-f]*\).*,\1 \2,p'`
|
||||
toe_addr=`echo $toe | sed -n -e 's,.* ,,p'`
|
||||
toe=`echo $toe | sed -n -e 's, .*,,p'`
|
||||
# For loaded sections, pick off section number, address, and file offset
|
||||
sections=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *\([0-9]*\)\] *[^ ]* *PROGBITS *\([0-9a-f]*\) *\([0-9a-f]*\).*,\1 \2 \3,p'`
|
||||
sections=`echo ${sections}`
|
||||
# For relocation sections, pick off file offset and info (points to
|
||||
# section where relocs apply)
|
||||
relas=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *[0-9]*\] *[^ ]* *RELA *[0-9a-f]* *0*\([0-9a-f][0-9a-f]*\) .*\([0-9a-f][0-9a-f]*\) *[0-9a-f][0-9a-f]*$,\1 \2,p'`
|
||||
relas=`echo ${relas}`
|
||||
|
||||
# Build embedded SPU image.
|
||||
# 1. The whole SPU ELF file is written to .rodata.speelf
|
||||
@ -135,8 +140,10 @@ main ()
|
||||
# write the address of the corresponding PowerPC symbol in a table
|
||||
# built in .data.spetoe. For _EAE_ symbols not in .toe, create
|
||||
# .reloc commands to relocate their location directly.
|
||||
# 3. Write a struct spe_program_handle to .data.
|
||||
# 4. Write a table of _SPUEAR_ symbols.
|
||||
# 3. Look for R_SPU_PPU32 and R_SPU_PPU64 relocations in the SPU ELF image
|
||||
# and create .reloc commands for them.
|
||||
# 4. Write a struct spe_program_handle to .data.
|
||||
# 5. Write a table of _SPUEAR_ symbols.
|
||||
${CC} ${FLAGS} -x assembler-with-cpp -nostartfiles -nostdlib \
|
||||
-Wa,-mbig -Wl,-r -Wl,-x -o ${OUTFILE} - <<EOF
|
||||
.section .rodata.speelf,"a",@progbits
|
||||
@ -178,6 +185,35 @@ $7 != "'${toe}'" && $7 in sec_off { \
|
||||
$7 != "'${toe}'" && ! $7 in sec_off { \
|
||||
print "#error Section not found for " $8; \
|
||||
} \
|
||||
'`
|
||||
`test -z "${relas}" || ${READELF} -r -W ${INFILE} | awk \
|
||||
'BEGIN { \
|
||||
split ("'"${sections}"'", s, " "); \
|
||||
for (i = 1; i in s; i += 3) { \
|
||||
sec_off[s[i]] = strtonum ("0x" s[i+2]) - strtonum ("0x" s[i+1]); \
|
||||
} \
|
||||
split ("'"${relas}"'", s, " "); \
|
||||
for (i = 1; i in s; i += 2) { \
|
||||
rela[s[i]] = strtonum (s[i+1]); \
|
||||
} \
|
||||
} \
|
||||
/^Relocation section/ { \
|
||||
sec = substr($6, 3); \
|
||||
} \
|
||||
$3 ~ /R_SPU_PPU/ { \
|
||||
print "#ifdef _LP64"; \
|
||||
print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] ", R_PPC64_ADDR" substr($3, 10) ", " $5 "+0x" $7; \
|
||||
print "#else"; \
|
||||
print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + (substr($3, 10) == "64" ? 4 : 0)", R_PPC_ADDR32, " $5 "+0x" $7; \
|
||||
print "#endif"; \
|
||||
} \
|
||||
$3 ~ /unrecognized:/ { \
|
||||
print "#ifdef _LP64"; \
|
||||
print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] ", R_PPC64_ADDR" ($4 == "f" ? "64" : "32") ", " $6 "+0x" $8; \
|
||||
print "#else"; \
|
||||
print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + ($4 == "f" ? 4 : 0)", R_PPC_ADDR32, " $6 "+0x" $8; \
|
||||
print "#endif"; \
|
||||
} \
|
||||
'`
|
||||
|
||||
.section .data,"aw",@progbits
|
||||
|
@ -1,3 +1,13 @@
|
||||
2007-05-11 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* config/tc-spu.c (md_pseudo_table): Add int, long, quad. Call
|
||||
spu_cons for word.
|
||||
(md_assemble): Tidy use of insn.flag.
|
||||
(get_imm): Likewise. Handle uppercase input too.
|
||||
(spu_cons): New function.
|
||||
* config/tc-spu.h (tc_fix_adjustable): Don't adjust SPU_PPU relocs.
|
||||
(TC_FORCE_RELOCATION): Don't resolve them either.
|
||||
|
||||
2007-05-05 Mark Shinwell <shinwell@codesourcery.com>
|
||||
|
||||
* config/tc-arm.c (md_apply_fix): Generate more accurate
|
||||
|
@ -51,9 +51,9 @@ struct spu_insn
|
||||
static const char *get_imm (const char *param, struct spu_insn *insn, int arg);
|
||||
static const char *get_reg (const char *param, struct spu_insn *insn, int arg,
|
||||
int accept_expr);
|
||||
|
||||
static int calcop (struct spu_opcode *format, const char *param,
|
||||
struct spu_insn *insn);
|
||||
static void spu_cons (int);
|
||||
|
||||
extern char *myname;
|
||||
static struct hash_control *op_hash = NULL;
|
||||
@ -82,14 +82,17 @@ const char FLT_CHARS[] = "dDfF";
|
||||
const pseudo_typeS md_pseudo_table[] =
|
||||
{
|
||||
{"align", s_align_ptwo, 4},
|
||||
{"bss", s_lcomm_bytes, 1},
|
||||
{"def", s_set, 0},
|
||||
{"dfloat", float_cons, 'd'},
|
||||
{"ffloat", float_cons, 'f'},
|
||||
{"global", s_globl, 0},
|
||||
{"half", cons, 2},
|
||||
{"bss", s_lcomm_bytes, 1},
|
||||
{"int", spu_cons, 4},
|
||||
{"long", spu_cons, 4},
|
||||
{"quad", spu_cons, 8},
|
||||
{"string", stringer, 1},
|
||||
{"word", cons, 4},
|
||||
{"word", spu_cons, 4},
|
||||
/* Force set to be treated as an instruction. */
|
||||
{"set", NULL, 0},
|
||||
{".set", s_set, 0},
|
||||
@ -351,13 +354,14 @@ md_assemble (char *op)
|
||||
fixS *fixP;
|
||||
bfd_reloc_code_real_type reloc = arg_encode[insn.reloc_arg[i]].reloc;
|
||||
int pcrel = 0;
|
||||
|
||||
if (reloc == BFD_RELOC_SPU_PCREL9a
|
||||
|| reloc == BFD_RELOC_SPU_PCREL9b
|
||||
|| reloc == BFD_RELOC_SPU_PCREL16)
|
||||
pcrel = 1;
|
||||
if (insn.flag[i] & 1)
|
||||
if (insn.flag[i] == 1)
|
||||
reloc = BFD_RELOC_SPU_HI16;
|
||||
else if (insn.flag[i] & 2)
|
||||
else if (insn.flag[i] == 2)
|
||||
reloc = BFD_RELOC_SPU_LO16;
|
||||
fixP = fix_new_exp (frag_now,
|
||||
thisfrag - frag_now->fr_literal,
|
||||
@ -585,30 +589,30 @@ get_imm (const char *param, struct spu_insn *insn, int arg)
|
||||
int low = 0, high = 0;
|
||||
int reloc_i = insn->reloc_arg[0] >= 0 ? 1 : 0;
|
||||
|
||||
if (strncmp (param, "%lo(", 4) == 0)
|
||||
if (strncasecmp (param, "%lo(", 4) == 0)
|
||||
{
|
||||
param += 3;
|
||||
low = 1;
|
||||
as_warn (_("Using old style, %%lo(expr), please change to PPC style, expr@l."));
|
||||
}
|
||||
else if (strncmp (param, "%hi(", 4) == 0)
|
||||
else if (strncasecmp (param, "%hi(", 4) == 0)
|
||||
{
|
||||
param += 3;
|
||||
high = 1;
|
||||
as_warn (_("Using old style, %%hi(expr), please change to PPC style, expr@h."));
|
||||
}
|
||||
else if (strncmp (param, "%pic(", 5) == 0)
|
||||
else if (strncasecmp (param, "%pic(", 5) == 0)
|
||||
{
|
||||
/* Currently we expect %pic(expr) == expr, so do nothing here.
|
||||
* i.e. for code loaded at address 0 $toc will be 0. */
|
||||
i.e. for code loaded at address 0 $toc will be 0. */
|
||||
param += 4;
|
||||
}
|
||||
|
||||
if (*param == '$')
|
||||
{
|
||||
/* Symbols can start with $, but if this symbol matches a register
|
||||
* name, it's probably a mistake. The only way to avoid this
|
||||
* warning is to rename the symbol. */
|
||||
name, it's probably a mistake. The only way to avoid this
|
||||
warning is to rename the symbol. */
|
||||
struct spu_insn tmp_insn;
|
||||
const char *np = get_reg (param, &tmp_insn, arg, 0);
|
||||
|
||||
@ -623,7 +627,7 @@ get_imm (const char *param, struct spu_insn *insn, int arg)
|
||||
input_line_pointer = save_ptr;
|
||||
|
||||
/* Similar to ppc_elf_suffix in tc-ppc.c. We have so few cases to
|
||||
* handle we do it inlined here. */
|
||||
handle we do it inlined here. */
|
||||
if (param[0] == '@' && !ISALNUM (param[2]) && param[2] != '@')
|
||||
{
|
||||
if (param[1] == 'h' || param[1] == 'H')
|
||||
@ -638,10 +642,10 @@ get_imm (const char *param, struct spu_insn *insn, int arg)
|
||||
}
|
||||
}
|
||||
|
||||
val = insn->exp[reloc_i].X_add_number;
|
||||
|
||||
if (insn->exp[reloc_i].X_op == O_constant)
|
||||
{
|
||||
val = insn->exp[reloc_i].X_add_number;
|
||||
|
||||
if (emulate_apuasm)
|
||||
{
|
||||
/* Convert the value to a format we expect. */
|
||||
@ -691,9 +695,9 @@ get_imm (const char *param, struct spu_insn *insn, int arg)
|
||||
{
|
||||
insn->reloc_arg[reloc_i] = arg;
|
||||
if (high)
|
||||
insn->flag[reloc_i] |= 1;
|
||||
if (low)
|
||||
insn->flag[reloc_i] |= 2;
|
||||
insn->flag[reloc_i] = 1;
|
||||
else if (low)
|
||||
insn->flag[reloc_i] = 2;
|
||||
}
|
||||
|
||||
return param;
|
||||
@ -802,6 +806,52 @@ md_create_long_jump (char *ptr,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Support @ppu on symbols referenced in .int/.long/.word/.quad. */
|
||||
static void
|
||||
spu_cons (int nbytes)
|
||||
{
|
||||
expressionS exp;
|
||||
|
||||
if (is_it_end_of_statement ())
|
||||
{
|
||||
demand_empty_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
expression (&exp);
|
||||
if (exp.X_op == O_symbol
|
||||
&& strncasecmp (input_line_pointer, "@ppu", 4) == 0)
|
||||
{
|
||||
char *p = frag_more (nbytes);
|
||||
enum bfd_reloc_code_real reloc;
|
||||
|
||||
/* Check for identifier@suffix+constant. */
|
||||
input_line_pointer += 4;
|
||||
if (*input_line_pointer == '-' || *input_line_pointer == '+')
|
||||
{
|
||||
expressionS new_exp;
|
||||
|
||||
expression (&new_exp);
|
||||
if (new_exp.X_op == O_constant)
|
||||
exp.X_add_number += new_exp.X_add_number;
|
||||
}
|
||||
|
||||
reloc = nbytes == 4 ? BFD_RELOC_SPU_PPU32 : BFD_RELOC_SPU_PPU64;
|
||||
fix_new_exp (frag_now, p - frag_now->fr_literal, nbytes,
|
||||
&exp, 0, reloc);
|
||||
}
|
||||
else
|
||||
emit_expr (&exp, nbytes);
|
||||
}
|
||||
while (*input_line_pointer++ == ',');
|
||||
|
||||
/* Put terminator back into stream. */
|
||||
input_line_pointer--;
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
int
|
||||
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
|
||||
segT segment_type ATTRIBUTE_UNUSED)
|
||||
|
@ -61,8 +61,12 @@ struct tc_fix_info {
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Don't reduce function symbols to section symbols. */
|
||||
#define tc_fix_adjustable(FIXP) (!S_IS_FUNCTION ((FIXP)->fx_addsy))
|
||||
/* Don't reduce function symbols to section symbols, and don't adjust
|
||||
references to PPU symbols. */
|
||||
#define tc_fix_adjustable(FIXP) \
|
||||
(!(S_IS_FUNCTION ((FIXP)->fx_addsy) \
|
||||
|| (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU32 \
|
||||
|| (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU64))
|
||||
|
||||
/* Keep relocs on calls. Branches to function symbols are tail or
|
||||
sibling calls. */
|
||||
@ -73,6 +77,8 @@ struct tc_fix_info {
|
||||
|| (FIXP)->tc_fix_data.insn_tag == M_BRA) \
|
||||
&& (FIXP)->fx_addsy != NULL \
|
||||
&& S_IS_FUNCTION ((FIXP)->fx_addsy)) \
|
||||
|| (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU32 \
|
||||
|| (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU64 \
|
||||
|| generic_force_reloc (FIXP))
|
||||
|
||||
/* Values passed to md_apply_fix don't include symbol values. */
|
||||
|
@ -1,3 +1,7 @@
|
||||
2007-05-11 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* spu.h (R_SPU_PPU32, R_SPU_PPU64): Define.
|
||||
|
||||
2007-05-02 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* internal.h (ELF_IS_SECTION_IN_SEGMENT): Check both file offset
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPU ELF support for BFD.
|
||||
|
||||
Copyright 2006 Free Software Foundation, Inc.
|
||||
Copyright 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
@ -39,6 +39,8 @@ START_RELOC_NUMBERS (elf_spu_reloc_type)
|
||||
RELOC_NUMBER (R_SPU_ADDR10I, 11)
|
||||
RELOC_NUMBER (R_SPU_ADDR16I, 12)
|
||||
RELOC_NUMBER (R_SPU_REL32, 13)
|
||||
RELOC_NUMBER (R_SPU_PPU32, 14)
|
||||
RELOC_NUMBER (R_SPU_PPU64, 15)
|
||||
END_RELOC_NUMBERS (R_SPU_max)
|
||||
|
||||
/* Program header extensions */
|
||||
|
Loading…
Reference in New Issue
Block a user