This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Fix arm-pe reloc generations for redefined symbols
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Tue, 09 May 2006 12:46:26 +0100
- Subject: Fix arm-pe reloc generations for redefined symbols
Hi Guys,
Whilst checking my arm-wince-pe toolchain in order to review the
recent patch submissions I found that the redef2.s test was causing
the assembler to abort(). Upon investigation I found that the
problem was that a reloc was being generated against a symbol which
had been cloned, and only the clone was placed into the symbol
table, not the original.
I am going to apply the attached patch to fix this problem. The
patch tells the assembler to adjust an fixups against symbols which
are not on the symbol chain (and which will not therefore be put
into the symbol table).
Cheers
Nick
gas/ChangeLog
2006-05-09 Nick Clifton <nickc@redhat.com>
* config/tc-arm.c (arm_fix_adjustable): For COFF, convert fixups
against symbols which are not going to be placed into the symbol
table.
bfd/ChangeLog
2006-05-09 Nick Clifton <nickc@redhat.com>
* coffcode.h (coff_write_relocs): Produce an error message if a an
out-of-range symbol index is detected in a reloc.
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.265
diff -c -3 -p -r1.265 tc-arm.c
*** gas/config/tc-arm.c 5 May 2006 18:54:44 -0000 1.265
--- gas/config/tc-arm.c 9 May 2006 11:44:57 -0000
*************** arm_force_relocation (struct fix * fixp)
*** 17003,17019 ****
}
#ifdef OBJ_COFF
- /* This is a little hack to help the gas/arm/adrl.s test. It prevents
- local labels from being added to the output symbol table when they
- are used with the ADRL pseudo op. The ADRL relocation should always
- be resolved before the binbary is emitted, so it is safe to say that
- it is adjustable. */
-
bfd_boolean
arm_fix_adjustable (fixS * fixP)
{
if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
return 1;
return 0;
}
#endif
--- 17003,17037 ----
}
#ifdef OBJ_COFF
bfd_boolean
arm_fix_adjustable (fixS * fixP)
{
+ /* This is a little hack to help the gas/arm/adrl.s test. It prevents
+ local labels from being added to the output symbol table when they
+ are used with the ADRL pseudo op. The ADRL relocation should always
+ be resolved before the binbary is emitted, so it is safe to say that
+ it is adjustable. */
if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
return 1;
+
+ /* This is a hack for the gas/all/redef2.s test. This test causes symbols
+ to be cloned, and without this test relocs would still be generated
+ against the original pre-cloned symbol. Such symbols would not appear
+ in the symbol table however, and so a valid reloc could not be
+ generated. So check to see if the fixup is against a symbol which has
+ been removed from the symbol chain, and if it is, then allow it to be
+ adjusted into a reloc against a section symbol. */
+ if (fixP->fx_addsy != NULL)
+ {
+ symbolS * sym;
+
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ if (sym == fixP->fx_addsy)
+ break;
+ if (sym == NULL)
+ return 1;
+ }
+
return 0;
}
#endif
Index: bfd/coffcode.h
===================================================================
RCS file: /cvs/src/src/bfd/coffcode.h,v
retrieving revision 1.131
diff -c -3 -p -r1.131 coffcode.h
*** bfd/coffcode.h 3 May 2006 14:26:40 -0000 1.131
--- bfd/coffcode.h 9 May 2006 11:45:40 -0000
*************** coff_write_relocs (bfd * abfd, int first
*** 2532,2542 ****
else
{
n.r_symndx = get_index ((*(q->sym_ptr_ptr)));
! /* Take notice if the symbol reloc points to a symbol
! we don't have in our symbol table. What should we
! do for this?? */
if (n.r_symndx > obj_conv_table_size (abfd))
! abort ();
}
}
--- 2532,2546 ----
else
{
n.r_symndx = get_index ((*(q->sym_ptr_ptr)));
! /* Check to see if the symbol reloc points to a symbol
! we don't have in our symbol table. */
if (n.r_symndx > obj_conv_table_size (abfd))
! {
! bfd_set_error (bfd_error_bad_value);
! _bfd_error_handler (_("%B: reloc against a non-existant symbol index: %ld"),
! abfd, n.r_symndx);
! return FALSE;
! }
}
}