diff options
author | Paul Brook <paul@codesourcery.com> | 2006-05-02 13:09:18 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2006-05-02 13:09:18 +0000 |
commit | a8bc6c780e54b1dad7c356c815965f87df0314c7 (patch) | |
tree | 76bd0fd7da2825c7b9a1f69be8ac0e03935cb634 /gas | |
parent | 7cc27f03b90c3fad20b4fc535f448c4ee42932d0 (diff) | |
download | gdb-a8bc6c780e54b1dad7c356c815965f87df0314c7.zip gdb-a8bc6c780e54b1dad7c356c815965f87df0314c7.tar.gz gdb-a8bc6c780e54b1dad7c356c815965f87df0314c7.tar.bz2 |
2006-05-02 Paul Brook <paul@codesourcery.com>
bfd/
* elf32-arm.c (elf32_arm_final_link_relocate): Set thumb funciton bit
for R_ARM_REL32.
gas/
* config/tc-arm.c (arm_optimize_expr): New function.
* config/tc-arm.h (md_optimize_expr): Define
(arm_optimize_expr): Add prototype.
(TC_FORCE_RELOCATION_SUB_SAME): Define.
ld/testsuite/
* ld-arm/arm-elf.exp: Add thumb-rel32.
* ld-arm/thumb-rel32.d: New test.
* ld-arm/thumb-rel32.s: New test.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 7 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 23 | ||||
-rw-r--r-- | gas/config/tc-arm.h | 9 |
3 files changed, 39 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 718197b..8ab4b75 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2006-05-02 Paul Brook <paul@codesourcery.com> + + * config/tc-arm.c (arm_optimize_expr): New function. + * config/tc-arm.h (md_optimize_expr): Define + (arm_optimize_expr): Add prototype. + (TC_FORCE_RELOCATION_SUB_SAME): Define. + 2006-05-02 Ben Elliston <bje@au.ibm.com> * config/obj-elf.h (ELF_TARGET_SYMBOL_FIELDS): Make single bit diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index ff66a1d..3b588ac 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -15811,6 +15811,29 @@ get_thumb32_insn (char * buf) return insn; } + +/* We usually want to set the low bit on the address of thumb function + symbols. In particular .word foo - . should have the low bit set. + Generic code tries to fold the difference of two symbols to + a constant. Prevent this and force a relocation when the first symbols + is a thumb function. */ +int +arm_optimize_expr (expressionS *l, operatorT op, expressionS *r) +{ + if (op == O_subtract + && l->X_op == O_symbol + && r->X_op == O_symbol + && THUMB_IS_FUNC (l->X_add_symbol)) + { + l->X_op = O_subtract; + l->X_op_symbol = r->X_add_symbol; + l->X_add_number -= r->X_add_number; + return 1; + } + /* Process as normal. */ + return 0; +} + void md_apply_fix (fixS * fixP, valueT * valP, diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h index 3b33324..f261577 100644 --- a/gas/config/tc-arm.h +++ b/gas/config/tc-arm.h @@ -83,6 +83,9 @@ struct fix; arm_relax_frag(segment, fragp, stretch) extern int arm_relax_frag (asection *, struct frag *, long); +#define md_optimize_expr(l,o,r) arm_optimize_expr (l, o, r) +extern int arm_optimize_expr (expressionS *, operatorT, expressionS *); + #define md_cleanup() arm_cleanup () #define md_start_line_hook() arm_start_line_hook () @@ -148,6 +151,12 @@ extern void arm_md_end (void); || (FIX)->fx_r_type == BFD_RELOC_32 \ || TC_FORCE_RELOCATION (FIX)) +/* Force output of R_ARM_REL32 relocations against thumb function symbols. + This is needed to ensure the low bit is handled correctly. */ +#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \ + (THUMB_IS_FUNC ((FIX)->fx_addsy) \ + || !SEG_NORMAL (SEG)) + #define TC_CONS_FIX_NEW cons_fix_new_arm #define MAX_MEM_FOR_RS_ALIGN_CODE 31 |