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
14 changed files with 239 additions and 35 deletions
|
@ -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>
|
2007-05-10 Richard Sandiford <richard@codesourcery.com>
|
||||||
|
|
||||||
* elf32-arm.c (elf32_arm_check_relocs): Don't create PLT entries
|
* 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_PCREL16,
|
||||||
BFD_RELOC_SPU_LO16,
|
BFD_RELOC_SPU_LO16,
|
||||||
BFD_RELOC_SPU_HI16,
|
BFD_RELOC_SPU_HI16,
|
||||||
|
BFD_RELOC_SPU_PPU32,
|
||||||
|
BFD_RELOC_SPU_PPU64,
|
||||||
|
|
||||||
/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or
|
/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or
|
||||||
"addend" in some special way.
|
"addend" in some special way.
|
||||||
|
|
|
@ -792,8 +792,11 @@ struct elf_backend_data
|
||||||
STB_LOCAL/STT_SECTION symbols specially. The output symbol is
|
STB_LOCAL/STT_SECTION symbols specially. The output symbol is
|
||||||
going to be the section symbol corresponding to the output
|
going to be the section symbol corresponding to the output
|
||||||
section, which means that the addend must be adjusted
|
section, which means that the addend must be adjusted
|
||||||
accordingly. */
|
accordingly.
|
||||||
bfd_boolean (*elf_backend_relocate_section)
|
|
||||||
|
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,
|
(bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
|
||||||
asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs,
|
asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs,
|
||||||
Elf_Internal_Sym *local_syms, asection **local_sections);
|
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,
|
HOWTO (R_SPU_REL32, 0, 2, 32, TRUE, 0, complain_overflow_dont,
|
||||||
bfd_elf_generic_reloc, "SPU_REL32",
|
bfd_elf_generic_reloc, "SPU_REL32",
|
||||||
FALSE, 0, 0xffffffff, TRUE),
|
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[] = {
|
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;
|
return R_SPU_ADDR32;
|
||||||
case BFD_RELOC_32_PCREL:
|
case BFD_RELOC_32_PCREL:
|
||||||
return R_SPU_REL32;
|
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);
|
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. */
|
/* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
|
@ -2644,6 +2674,7 @@ spu_elf_relocate_section (bfd *output_bfd,
|
||||||
Elf_Internal_Rela *rel, *relend;
|
Elf_Internal_Rela *rel, *relend;
|
||||||
struct spu_link_hash_table *htab;
|
struct spu_link_hash_table *htab;
|
||||||
bfd_boolean ret = TRUE;
|
bfd_boolean ret = TRUE;
|
||||||
|
bfd_boolean emit_these_relocs = FALSE;
|
||||||
|
|
||||||
htab = spu_hash_table (info);
|
htab = spu_hash_table (info);
|
||||||
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
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_symndx = ELF32_R_SYM (rel->r_info);
|
||||||
r_type = ELF32_R_TYPE (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;
|
howto = elf_howto_table + r_type;
|
||||||
unresolved_reloc = FALSE;
|
unresolved_reloc = FALSE;
|
||||||
warned = FALSE;
|
warned = FALSE;
|
||||||
|
|
||||||
h = NULL;
|
h = NULL;
|
||||||
sym = NULL;
|
sym = NULL;
|
||||||
sec = 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;
|
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_type_lookup spu_elf_reloc_type_lookup
|
||||||
#define bfd_elf32_bfd_reloc_name_lookup spu_elf_reloc_name_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_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_relocate_section spu_elf_relocate_section
|
||||||
#define elf_backend_symbol_processing spu_elf_backend_symbol_processing
|
#define elf_backend_symbol_processing spu_elf_backend_symbol_processing
|
||||||
#define elf_backend_link_output_symbol_hook spu_elf_output_symbol_hook
|
#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
|
static bfd_boolean
|
||||||
elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
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 *,
|
(bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
|
||||||
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
|
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
|
||||||
bfd *output_bfd;
|
bfd *output_bfd;
|
||||||
|
@ -8212,7 +8212,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
|
||||||
asection **ppsection;
|
asection **ppsection;
|
||||||
asection *o;
|
asection *o;
|
||||||
const struct elf_backend_data *bed;
|
const struct elf_backend_data *bed;
|
||||||
bfd_boolean emit_relocs;
|
|
||||||
struct elf_link_hash_entry **sym_hashes;
|
struct elf_link_hash_entry **sym_hashes;
|
||||||
|
|
||||||
output_bfd = finfo->output_bfd;
|
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)
|
if ((input_bfd->flags & DYNAMIC) != 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
emit_relocs = (finfo->info->relocatable
|
|
||||||
|| finfo->info->emitrelocations);
|
|
||||||
|
|
||||||
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||||||
if (elf_bad_symtab (input_bfd))
|
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;
|
Elf_Internal_Rela *internal_relocs;
|
||||||
bfd_vma r_type_mask;
|
bfd_vma r_type_mask;
|
||||||
int r_sym_shift;
|
int r_sym_shift;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Get the swapped relocs. */
|
/* Get the swapped relocs. */
|
||||||
internal_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
|
corresponding to the output section, which will require
|
||||||
the addend to be adjusted. */
|
the addend to be adjusted. */
|
||||||
|
|
||||||
if (! (*relocate_section) (output_bfd, finfo->info,
|
ret = (*relocate_section) (output_bfd, finfo->info,
|
||||||
input_bfd, o, contents,
|
input_bfd, o, contents,
|
||||||
internal_relocs,
|
internal_relocs,
|
||||||
isymbuf,
|
isymbuf,
|
||||||
finfo->sections))
|
finfo->sections);
|
||||||
|
if (!ret)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (emit_relocs)
|
if (ret == 2
|
||||||
|
|| finfo->info->relocatable
|
||||||
|
|| finfo->info->emitrelocations)
|
||||||
{
|
{
|
||||||
Elf_Internal_Rela *irela;
|
Elf_Internal_Rela *irela;
|
||||||
Elf_Internal_Rela *irelaend;
|
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_PCREL16",
|
||||||
"BFD_RELOC_SPU_LO16",
|
"BFD_RELOC_SPU_LO16",
|
||||||
"BFD_RELOC_SPU_HI16",
|
"BFD_RELOC_SPU_HI16",
|
||||||
|
"BFD_RELOC_SPU_PPU32",
|
||||||
|
"BFD_RELOC_SPU_PPU64",
|
||||||
"BFD_RELOC_ALPHA_GPDISP_HI16",
|
"BFD_RELOC_ALPHA_GPDISP_HI16",
|
||||||
"BFD_RELOC_ALPHA_GPDISP_LO16",
|
"BFD_RELOC_ALPHA_GPDISP_LO16",
|
||||||
"BFD_RELOC_ALPHA_GPDISP",
|
"BFD_RELOC_ALPHA_GPDISP",
|
||||||
|
|
|
@ -1972,6 +1972,10 @@ ENUMX
|
||||||
BFD_RELOC_SPU_LO16
|
BFD_RELOC_SPU_LO16
|
||||||
ENUMX
|
ENUMX
|
||||||
BFD_RELOC_SPU_HI16
|
BFD_RELOC_SPU_HI16
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_SPU_PPU32
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_SPU_PPU64
|
||||||
ENUMDOC
|
ENUMDOC
|
||||||
SPU Relocations.
|
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>
|
2007-04-28 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* prdbg.c (tg_variable): Adjust for changed demangler.
|
* prdbg.c (tg_variable): Adjust for changed demangler.
|
||||||
|
|
|
@ -38,12 +38,12 @@ mydir=`dirname "$0"`
|
||||||
find_prog ()
|
find_prog ()
|
||||||
{
|
{
|
||||||
prog=`echo $1 | sed "$program_transform_name"`
|
prog=`echo $1 | sed "$program_transform_name"`
|
||||||
which $prog > /dev/null 2> /dev/null && return 0
|
|
||||||
prog="$mydir/$prog"
|
prog="$mydir/$prog"
|
||||||
test -x "$prog" && return 0
|
test -x "$prog" && return 0
|
||||||
prog="$mydir/$1"
|
prog="$mydir/$1"
|
||||||
test -x "$prog" && return 0
|
test -x "$prog" && return 0
|
||||||
prog=`echo $1 | sed "$program_transform_name"`
|
prog=`echo $1 | sed "$program_transform_name"`
|
||||||
|
which $prog > /dev/null 2> /dev/null && return 0
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ main ()
|
||||||
CC="$prog"
|
CC="$prog"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Find readelf. Any old readelf should do. We only want to read syms.
|
# Find readelf. Any old readelf should do.
|
||||||
find_prog readelf
|
find_prog readelf
|
||||||
if test $? -ne 0; then
|
if test $? -ne 0; then
|
||||||
if which readelf > /dev/null 2> /dev/null; 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=`${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_addr=`echo $toe | sed -n -e 's,.* ,,p'`
|
||||||
toe=`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=`${READELF} -S ${INFILE} | sed -n -e 's, *\[ *\([0-9]*\)\] *[^ ]* *PROGBITS *\([0-9a-f]*\) *\([0-9a-f]*\).*,\1 \2 \3,p'`
|
||||||
sections=`echo ${sections}`
|
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.
|
# Build embedded SPU image.
|
||||||
# 1. The whole SPU ELF file is written to .rodata.speelf
|
# 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
|
# write the address of the corresponding PowerPC symbol in a table
|
||||||
# built in .data.spetoe. For _EAE_ symbols not in .toe, create
|
# built in .data.spetoe. For _EAE_ symbols not in .toe, create
|
||||||
# .reloc commands to relocate their location directly.
|
# .reloc commands to relocate their location directly.
|
||||||
# 3. Write a struct spe_program_handle to .data.
|
# 3. Look for R_SPU_PPU32 and R_SPU_PPU64 relocations in the SPU ELF image
|
||||||
# 4. Write a table of _SPUEAR_ symbols.
|
# 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 \
|
${CC} ${FLAGS} -x assembler-with-cpp -nostartfiles -nostdlib \
|
||||||
-Wa,-mbig -Wl,-r -Wl,-x -o ${OUTFILE} - <<EOF
|
-Wa,-mbig -Wl,-r -Wl,-x -o ${OUTFILE} - <<EOF
|
||||||
.section .rodata.speelf,"a",@progbits
|
.section .rodata.speelf,"a",@progbits
|
||||||
|
@ -178,6 +185,35 @@ $7 != "'${toe}'" && $7 in sec_off { \
|
||||||
$7 != "'${toe}'" && ! $7 in sec_off { \
|
$7 != "'${toe}'" && ! $7 in sec_off { \
|
||||||
print "#error Section not found for " $8; \
|
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
|
.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>
|
2007-05-05 Mark Shinwell <shinwell@codesourcery.com>
|
||||||
|
|
||||||
* config/tc-arm.c (md_apply_fix): Generate more accurate
|
* 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_imm (const char *param, struct spu_insn *insn, int arg);
|
||||||
static const char *get_reg (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);
|
int accept_expr);
|
||||||
|
|
||||||
static int calcop (struct spu_opcode *format, const char *param,
|
static int calcop (struct spu_opcode *format, const char *param,
|
||||||
struct spu_insn *insn);
|
struct spu_insn *insn);
|
||||||
|
static void spu_cons (int);
|
||||||
|
|
||||||
extern char *myname;
|
extern char *myname;
|
||||||
static struct hash_control *op_hash = NULL;
|
static struct hash_control *op_hash = NULL;
|
||||||
|
@ -82,14 +82,17 @@ const char FLT_CHARS[] = "dDfF";
|
||||||
const pseudo_typeS md_pseudo_table[] =
|
const pseudo_typeS md_pseudo_table[] =
|
||||||
{
|
{
|
||||||
{"align", s_align_ptwo, 4},
|
{"align", s_align_ptwo, 4},
|
||||||
|
{"bss", s_lcomm_bytes, 1},
|
||||||
{"def", s_set, 0},
|
{"def", s_set, 0},
|
||||||
{"dfloat", float_cons, 'd'},
|
{"dfloat", float_cons, 'd'},
|
||||||
{"ffloat", float_cons, 'f'},
|
{"ffloat", float_cons, 'f'},
|
||||||
{"global", s_globl, 0},
|
{"global", s_globl, 0},
|
||||||
{"half", cons, 2},
|
{"half", cons, 2},
|
||||||
{"bss", s_lcomm_bytes, 1},
|
{"int", spu_cons, 4},
|
||||||
|
{"long", spu_cons, 4},
|
||||||
|
{"quad", spu_cons, 8},
|
||||||
{"string", stringer, 1},
|
{"string", stringer, 1},
|
||||||
{"word", cons, 4},
|
{"word", spu_cons, 4},
|
||||||
/* Force set to be treated as an instruction. */
|
/* Force set to be treated as an instruction. */
|
||||||
{"set", NULL, 0},
|
{"set", NULL, 0},
|
||||||
{".set", s_set, 0},
|
{".set", s_set, 0},
|
||||||
|
@ -351,13 +354,14 @@ md_assemble (char *op)
|
||||||
fixS *fixP;
|
fixS *fixP;
|
||||||
bfd_reloc_code_real_type reloc = arg_encode[insn.reloc_arg[i]].reloc;
|
bfd_reloc_code_real_type reloc = arg_encode[insn.reloc_arg[i]].reloc;
|
||||||
int pcrel = 0;
|
int pcrel = 0;
|
||||||
|
|
||||||
if (reloc == BFD_RELOC_SPU_PCREL9a
|
if (reloc == BFD_RELOC_SPU_PCREL9a
|
||||||
|| reloc == BFD_RELOC_SPU_PCREL9b
|
|| reloc == BFD_RELOC_SPU_PCREL9b
|
||||||
|| reloc == BFD_RELOC_SPU_PCREL16)
|
|| reloc == BFD_RELOC_SPU_PCREL16)
|
||||||
pcrel = 1;
|
pcrel = 1;
|
||||||
if (insn.flag[i] & 1)
|
if (insn.flag[i] == 1)
|
||||||
reloc = BFD_RELOC_SPU_HI16;
|
reloc = BFD_RELOC_SPU_HI16;
|
||||||
else if (insn.flag[i] & 2)
|
else if (insn.flag[i] == 2)
|
||||||
reloc = BFD_RELOC_SPU_LO16;
|
reloc = BFD_RELOC_SPU_LO16;
|
||||||
fixP = fix_new_exp (frag_now,
|
fixP = fix_new_exp (frag_now,
|
||||||
thisfrag - frag_now->fr_literal,
|
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 low = 0, high = 0;
|
||||||
int reloc_i = insn->reloc_arg[0] >= 0 ? 1 : 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;
|
param += 3;
|
||||||
low = 1;
|
low = 1;
|
||||||
as_warn (_("Using old style, %%lo(expr), please change to PPC style, expr@l."));
|
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;
|
param += 3;
|
||||||
high = 1;
|
high = 1;
|
||||||
as_warn (_("Using old style, %%hi(expr), please change to PPC style, expr@h."));
|
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.
|
/* 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;
|
param += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*param == '$')
|
if (*param == '$')
|
||||||
{
|
{
|
||||||
/* Symbols can start with $, but if this symbol matches a register
|
/* Symbols can start with $, but if this symbol matches a register
|
||||||
* name, it's probably a mistake. The only way to avoid this
|
name, it's probably a mistake. The only way to avoid this
|
||||||
* warning is to rename the symbol. */
|
warning is to rename the symbol. */
|
||||||
struct spu_insn tmp_insn;
|
struct spu_insn tmp_insn;
|
||||||
const char *np = get_reg (param, &tmp_insn, arg, 0);
|
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;
|
input_line_pointer = save_ptr;
|
||||||
|
|
||||||
/* Similar to ppc_elf_suffix in tc-ppc.c. We have so few cases to
|
/* 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[0] == '@' && !ISALNUM (param[2]) && param[2] != '@')
|
||||||
{
|
{
|
||||||
if (param[1] == 'h' || param[1] == 'H')
|
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)
|
if (insn->exp[reloc_i].X_op == O_constant)
|
||||||
{
|
{
|
||||||
|
val = insn->exp[reloc_i].X_add_number;
|
||||||
|
|
||||||
if (emulate_apuasm)
|
if (emulate_apuasm)
|
||||||
{
|
{
|
||||||
/* Convert the value to a format we expect. */
|
/* 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;
|
insn->reloc_arg[reloc_i] = arg;
|
||||||
if (high)
|
if (high)
|
||||||
insn->flag[reloc_i] |= 1;
|
insn->flag[reloc_i] = 1;
|
||||||
if (low)
|
else if (low)
|
||||||
insn->flag[reloc_i] |= 2;
|
insn->flag[reloc_i] = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return param;
|
return param;
|
||||||
|
@ -802,6 +806,52 @@ md_create_long_jump (char *ptr,
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
int
|
||||||
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
|
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
|
||||||
segT segment_type ATTRIBUTE_UNUSED)
|
segT segment_type ATTRIBUTE_UNUSED)
|
||||||
|
|
|
@ -61,8 +61,12 @@ struct tc_fix_info {
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
/* Don't reduce function symbols to section symbols. */
|
/* Don't reduce function symbols to section symbols, and don't adjust
|
||||||
#define tc_fix_adjustable(FIXP) (!S_IS_FUNCTION ((FIXP)->fx_addsy))
|
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
|
/* Keep relocs on calls. Branches to function symbols are tail or
|
||||||
sibling calls. */
|
sibling calls. */
|
||||||
|
@ -73,6 +77,8 @@ struct tc_fix_info {
|
||||||
|| (FIXP)->tc_fix_data.insn_tag == M_BRA) \
|
|| (FIXP)->tc_fix_data.insn_tag == M_BRA) \
|
||||||
&& (FIXP)->fx_addsy != NULL \
|
&& (FIXP)->fx_addsy != NULL \
|
||||||
&& S_IS_FUNCTION ((FIXP)->fx_addsy)) \
|
&& 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))
|
|| generic_force_reloc (FIXP))
|
||||||
|
|
||||||
/* Values passed to md_apply_fix don't include symbol values. */
|
/* 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>
|
2007-05-02 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* internal.h (ELF_IS_SECTION_IN_SEGMENT): Check both file offset
|
* internal.h (ELF_IS_SECTION_IN_SEGMENT): Check both file offset
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* SPU ELF support for BFD.
|
/* 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.
|
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_ADDR10I, 11)
|
||||||
RELOC_NUMBER (R_SPU_ADDR16I, 12)
|
RELOC_NUMBER (R_SPU_ADDR16I, 12)
|
||||||
RELOC_NUMBER (R_SPU_REL32, 13)
|
RELOC_NUMBER (R_SPU_REL32, 13)
|
||||||
|
RELOC_NUMBER (R_SPU_PPU32, 14)
|
||||||
|
RELOC_NUMBER (R_SPU_PPU64, 15)
|
||||||
END_RELOC_NUMBERS (R_SPU_max)
|
END_RELOC_NUMBERS (R_SPU_max)
|
||||||
|
|
||||||
/* Program header extensions */
|
/* Program header extensions */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue