This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Fixes for spu @ppu expressions
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Tue, 5 Jun 2007 09:54:07 +0930
- Subject: Fixes for spu @ppu expressions
".long foo@ppu" is supposed to always refer to the ppu symbol foo,
even if foo is also used as an spu symbol. Unfortunately, if foo was
a local defined symbol, its value was substitued in the generic gas
expression code and spu gas never saw it as a symbol. Fixed by
spu_cons asking for deferred expression evaluation.
This patch also add support for ".long @ppu" and ".long 0@ppu"),
which, like _EAR_ with a NULL suffix, resolve to the address of the
embedded spu image.
binutils/
* embedspu.sh: Handle R_SPU_PPU* relocs with no symbol.
gas/
* config/tc-spu.c (spu_cons): Use deferred_expression. Handle
number@ppu.
(tc_gen_reloc): Abort if neither addsy or subsy is set.
(md_apply_fix): Don't attempt to resolve SPU_PPU relocs.
* config/tc-spu.h (md_operand): Handle @ppu without sym.
Index: binutils/embedspu.sh
===================================================================
RCS file: /cvs/src/src/binutils/embedspu.sh,v
retrieving revision 1.7
diff -u -p -r1.7 embedspu.sh
--- binutils/embedspu.sh 29 May 2007 13:10:10 -0000 1.7
+++ binutils/embedspu.sh 4 Jun 2007 08:02:09 -0000
@@ -198,17 +198,17 @@ $7 != "'${toe}'" && ! $7 in sec_off { \
} \
$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 " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] ", R_PPC64_ADDR" substr($3, 10) ", " ($5 != "" ? $5 "+0x" $7 : "__speelf__ + 0x" $4); \
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 " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + (substr($3, 10) == "64" ? 4 : 0)", R_PPC_ADDR32, " ($5 != "" ? $5 "+0x" $7 : "__speelf__ + 0x" $4); \
print "#endif"; \
if (!donedef) { print "#define HAS_RELOCS 1"; donedef = 1; }; \
} \
$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 " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] ", R_PPC64_ADDR" ($4 == "f" ? "64" : "32") ", " ($6 != "" ? $6 "+0x" $8 : "__speelf__ + 0x" $5); \
print "#else"; \
- print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + ($4 == "f" ? 4 : 0)", R_PPC_ADDR32, " $6 "+0x" $8; \
+ print " .reloc __speelf__+" strtonum ("0x" $1) + sec_off[rela[sec]] + ($4 == "f" ? 4 : 0)", R_PPC_ADDR32, " ($6 != "" ? $6 "+0x" $8 : "__speelf__ + 0x" $5); \
print "#endif"; \
if (!donedef) { print "#define HAS_RELOCS 1"; donedef = 1; }; \
} \
Index: gas/config/tc-spu.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-spu.c,v
retrieving revision 1.5
diff -u -p -r1.5 tc-spu.c
--- gas/config/tc-spu.c 11 May 2007 03:10:11 -0000 1.5
+++ gas/config/tc-spu.c 4 Jun 2007 23:59:31 -0000
@@ -820,8 +820,9 @@ spu_cons (int nbytes)
do
{
- expression (&exp);
- if (exp.X_op == O_symbol
+ deferred_expression (&exp);
+ if ((exp.X_op == O_symbol
+ || exp.X_op == O_constant)
&& strncasecmp (input_line_pointer, "@ppu", 4) == 0)
{
char *p = frag_more (nbytes);
@@ -873,6 +874,8 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UN
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
else if (fixp->fx_subsy)
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
+ else
+ abort ();
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
if (reloc->howto == (reloc_howto_type *) NULL)
@@ -987,6 +990,10 @@ md_apply_fix (fixS *fixP, valueT *valP,
fixP->fx_addnumber = val;
+ if (fixP->fx_r_type == BFD_RELOC_SPU_PPU32
+ || fixP->fx_r_type == BFD_RELOC_SPU_PPU64)
+ return;
+
if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
{
fixP->fx_done = 1;
Index: gas/config/tc-spu.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-spu.h,v
retrieving revision 1.5
diff -u -p -r1.5 tc-spu.h
--- gas/config/tc-spu.h 29 May 2007 02:10:09 -0000 1.5
+++ gas/config/tc-spu.h 4 Jun 2007 23:59:31 -0000
@@ -85,8 +85,18 @@ struct tc_fix_info {
/* We don't need to do anything special for undefined symbols. */
#define md_undefined_symbol(s) 0
-/* We have no special operand handling. */
-#define md_operand(e)
+extern symbolS *section_symbol (asection *);
+#define md_operand(e) \
+ do { \
+ if (strncasecmp (input_line_pointer, "@ppu", 4) == 0) \
+ { \
+ e->X_op = O_symbol; \
+ if (abs_section_sym == NULL) \
+ abs_section_sym = section_symbol (absolute_section); \
+ e->X_add_symbol = abs_section_sym; \
+ e->X_add_number = 0; \
+ } \
+ } while (0)
/* Fill in rs_align_code fragments. */
extern void spu_handle_align PARAMS ((fragS *));
--
Alan Modra
IBM OzLabs - Linux Technology Centre