From: Richard Sandiford Date: Sat, 23 Jan 2010 12:05:33 +0000 (+0000) Subject: bfd/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c865e45b1b6d482d20b3f6096d5227216db0e451;p=binutils-gdb.git bfd/ * coff-rs6000.c (xcoff_howto_table): Change size to 0 and bitsize to 1. (_bfd_xcoff_reloc_type_lookup): Handle BFD_RELOC_NONE. * coff64-rs6000.c (xcoff64_howto_table): Change size to 0 and bitsize to 1. (xcoff64_reloc_type_lookup): Handle BFD_RELOC_NONE. gas/ * write.h (fix_at_start): Declare. * write.c (fix_new_internal): Add at_beginning parameter. Use it instead of REVERSE_SORT_RELOCS. Fix the handling of seg_fix_tailP for the at_beginning/REVERSE_SORT_RELOCS case. (fix_new, fix_new_exp): Update accordingly. (fix_at_start): New function. * config/tc-ppc.c (md_pseudo_table): Add .ref to the OBJ_XCOFF section. (ppc_ref): New function, for OBJ_XCOFF. (md_apply_fix): Handle BFD_RELOC_NONE for OBJ_XCOFF. * config/te-i386aix.h (REVERSE_SORT_RELOCS): Remove #undef. gas/testsuite/ * gas/ppc/xcoff-ref-1.s, gas/ppc/xcoff-ref-1.l: New test. * gas/ppc/aix.exp: Run it. ld/testsuite/ * ld-powerpc/aix-ref-1-32.od, ld-powerpc/aix-ref-1-64.od, ld-powerpc/aix-ref-1.s: New tests. * ld-powerpc/aix52.exp: Run them. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b292f45662f..714f03fe7db 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2010-01-23 Richard Sandiford + + * coff-rs6000.c (xcoff_howto_table): Change size to 0 and bitsize to 1. + (_bfd_xcoff_reloc_type_lookup): Handle BFD_RELOC_NONE. + * coff64-rs6000.c (xcoff64_howto_table): Change size to 0 and + bitsize to 1. + (xcoff64_reloc_type_lookup): Handle BFD_RELOC_NONE. + 2010-01-21 Nick Clifton * elflink.c (elf_link_add_object_symbols): Look up name of diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 2ee74ecf574..2f13f489bb5 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -896,11 +896,11 @@ reloc_howto_type xcoff_howto_table[] = EMPTY_HOWTO (0xe), - /* Non-relocating reference. */ + /* Non-relocating reference. Bitsize is 1 so that r_rsize is 0. */ HOWTO (R_REF, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 1, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ @@ -1162,6 +1162,8 @@ _bfd_xcoff_reloc_type_lookup (abfd, code) case BFD_RELOC_32: case BFD_RELOC_CTOR: return &xcoff_howto_table[0]; + case BFD_RELOC_NONE: + return &xcoff_howto_table[0xf]; default: return NULL; } diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 4d618c1acc2..15e636e50e6 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -1594,11 +1594,11 @@ reloc_howto_type xcoff64_howto_table[] = EMPTY_HOWTO (0xe), - /* Non-relocating reference. */ + /* Non-relocating reference. Bitsize is 1 so that r_rsize is 0. */ HOWTO (R_REF, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 1, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ @@ -1882,6 +1882,8 @@ xcoff64_reloc_type_lookup (abfd, code) return &xcoff64_howto_table[0x1c]; case BFD_RELOC_64: return &xcoff64_howto_table[0]; + case BFD_RELOC_NONE: + return &xcoff64_howto_table[0xf]; default: return NULL; } diff --git a/gas/ChangeLog b/gas/ChangeLog index 78640a54576..f21a21e09e4 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2010-01-23 Richard Sandiford + + * write.h (fix_at_start): Declare. + * write.c (fix_new_internal): Add at_beginning parameter. + Use it instead of REVERSE_SORT_RELOCS. Fix the handling of + seg_fix_tailP for the at_beginning/REVERSE_SORT_RELOCS case. + (fix_new, fix_new_exp): Update accordingly. + (fix_at_start): New function. + * config/tc-ppc.c (md_pseudo_table): Add .ref to the OBJ_XCOFF section. + (ppc_ref): New function, for OBJ_XCOFF. + (md_apply_fix): Handle BFD_RELOC_NONE for OBJ_XCOFF. + * config/te-i386aix.h (REVERSE_SORT_RELOCS): Remove #undef. + 2010-01-21 Rainer Orth * config/te-solaris.h (DWARF2_EH_FRAME_READ_ONLY): Make read-only diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 327f3c15734..212f822510a 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -108,6 +108,7 @@ static void ppc_change_csect (symbolS *, offsetT); static void ppc_function (int); static void ppc_extern (int); static void ppc_lglobl (int); +static void ppc_ref (int); static void ppc_section (int); static void ppc_named_section (int); static void ppc_stabx (int); @@ -212,6 +213,7 @@ const pseudo_typeS md_pseudo_table[] = { "extern", ppc_extern, 0 }, { "function", ppc_function, 0 }, { "lglobl", ppc_lglobl, 0 }, + { "ref", ppc_ref, 0 }, { "rename", ppc_rename, 0 }, { "section", ppc_named_section, 0 }, { "stabx", ppc_stabx, 0 }, @@ -3559,6 +3561,58 @@ ppc_lglobl (int ignore ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } +/* The .ref pseudo-op. It takes a list of symbol names and inserts R_REF + relocations at the beginning of the current csect. + + (In principle, there's no reason why the relocations _have_ to be at + the beginning. Anywhere in the csect would do. However, inserting + at the beginning is what the native assmebler does, and it helps to + deal with cases where the .ref statements follow the section contents.) + + ??? .refs don't work for empty .csects. However, the native assembler + doesn't report an error in this case, and neither yet do we. */ + +static void +ppc_ref (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + char c; + + if (ppc_current_csect == NULL) + { + as_bad (_(".ref outside .csect")); + ignore_rest_of_line (); + return; + } + + do + { + name = input_line_pointer; + c = get_symbol_end (); + + fix_at_start (symbol_get_frag (ppc_current_csect), 0, + symbol_find_or_make (name), 0, FALSE, BFD_RELOC_NONE); + + *input_line_pointer = c; + SKIP_WHITESPACE (); + c = *input_line_pointer; + if (c == ',') + { + input_line_pointer++; + SKIP_WHITESPACE (); + if (is_end_of_line[(unsigned char) *input_line_pointer]) + { + as_bad (_("missing symbol name")); + ignore_rest_of_line (); + return; + } + } + } + while (c == ','); + + demand_empty_rest_of_line (); +} + /* The .rename pseudo-op. The RS/6000 assembler can rename symbols, although I don't know why it bothers. */ @@ -6032,6 +6086,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) PPC_HA (value), 2); break; +#ifdef OBJ_XCOFF + case BFD_RELOC_NONE: + break; +#endif + #ifdef OBJ_ELF case BFD_RELOC_PPC64_HIGHER: if (fixP->fx_pcrel) diff --git a/gas/config/te-i386aix.h b/gas/config/te-i386aix.h index 04ce4643b9a..2b174a90020 100644 --- a/gas/config/te-i386aix.h +++ b/gas/config/te-i386aix.h @@ -24,10 +24,6 @@ #include "obj-format.h" -/* Undefine REVERSE_SORT_RELOCS to keep the relocation entries sorted - in ascending vaddr. */ -#undef REVERSE_SORT_RELOCS - /* Define KEEP_RELOC_INFO so that the strip reloc info flag F_RELFLG is not used in the filehdr for COFF output. */ #define KEEP_RELOC_INFO diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index c14187d0ae2..a2b65e62946 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-01-23 Richard Sandiford + + * gas/ppc/xcoff-ref-1.s, gas/ppc/xcoff-ref-1.l: New test. + * gas/ppc/aix.exp: Run it. + 2010-01-21 H.J. Lu * gas/i386/x86-64-xsave.s: Add tests for xsave64 and xrstor64. diff --git a/gas/testsuite/gas/ppc/aix.exp b/gas/testsuite/gas/ppc/aix.exp index bed4237f42a..917f0d95678 100644 --- a/gas/testsuite/gas/ppc/aix.exp +++ b/gas/testsuite/gas/ppc/aix.exp @@ -65,4 +65,6 @@ if [istarget powerpc-ibm-aix*] then { run_dump_test "textalign-xcoff-002" run_dump_test "xcoff-branch-1-32" run_dump_test "xcoff-branch-1-64" + + run_list_test "xcoff-ref-1" } diff --git a/gas/testsuite/gas/ppc/xcoff-ref-1.l b/gas/testsuite/gas/ppc/xcoff-ref-1.l new file mode 100644 index 00000000000..2120a2015cb --- /dev/null +++ b/gas/testsuite/gas/ppc/xcoff-ref-1.l @@ -0,0 +1,5 @@ +.*: Assembler messages: +.*:1: Error: .ref outside .csect +.*:3: Error: junk at end of line, first unrecognized character is `1' +.*:4: Error: missing symbol name +.*:5: Error: missing symbol name diff --git a/gas/testsuite/gas/ppc/xcoff-ref-1.s b/gas/testsuite/gas/ppc/xcoff-ref-1.s new file mode 100644 index 00000000000..74e264f4002 --- /dev/null +++ b/gas/testsuite/gas/ppc/xcoff-ref-1.s @@ -0,0 +1,6 @@ + .ref foo + .csect bar[rw] + .ref 1234 + .ref a, + .ref , + .ref diff --git a/gas/write.c b/gas/write.c index 1ded21f94fb..a148b248d20 100644 --- a/gas/write.c +++ b/gas/write.c @@ -150,7 +150,8 @@ fix_new_internal (fragS *frag, /* Which frag? */ symbolS *sub_symbol, /* X_op_symbol. */ offsetT offset, /* X_add_number. */ int pcrel, /* TRUE if PC-relative relocation. */ - RELOC_ENUM r_type ATTRIBUTE_UNUSED /* Relocation type. */) + RELOC_ENUM r_type ATTRIBUTE_UNUSED /* Relocation type. */, + int at_beginning) /* Add to the start of the list? */ { fixS *fixP; @@ -194,10 +195,6 @@ fix_new_internal (fragS *frag, /* Which frag? */ as_where (&fixP->fx_file, &fixP->fx_line); - /* Usually, we want relocs sorted numerically, but while - comparing to older versions of gas that have relocs - reverse sorted, it is convenient to have this compile - time option. xoxorich. */ { fixS **seg_fix_rootP = (frags_chained @@ -207,22 +204,22 @@ fix_new_internal (fragS *frag, /* Which frag? */ ? &seg_info (now_seg)->fix_tail : &frchain_now->fix_tail); -#ifdef REVERSE_SORT_RELOCS - - fixP->fx_next = *seg_fix_rootP; - *seg_fix_rootP = fixP; - -#else /* REVERSE_SORT_RELOCS */ - - fixP->fx_next = NULL; - - if (*seg_fix_tailP) - (*seg_fix_tailP)->fx_next = fixP; + if (at_beginning) + { + fixP->fx_next = *seg_fix_rootP; + *seg_fix_rootP = fixP; + if (fixP->fx_next == NULL) + *seg_fix_tailP = fixP; + } else - *seg_fix_rootP = fixP; - *seg_fix_tailP = fixP; - -#endif /* REVERSE_SORT_RELOCS */ + { + fixP->fx_next = NULL; + if (*seg_fix_tailP) + (*seg_fix_tailP)->fx_next = fixP; + else + *seg_fix_rootP = fixP; + *seg_fix_tailP = fixP; + } } return fixP; @@ -240,7 +237,7 @@ fix_new (fragS *frag, /* Which frag? */ RELOC_ENUM r_type /* Relocation type. */) { return fix_new_internal (frag, where, size, add_symbol, - (symbolS *) NULL, offset, pcrel, r_type); + (symbolS *) NULL, offset, pcrel, r_type, FALSE); } /* Create a fixup for an expression. Currently we only support fixups @@ -308,7 +305,19 @@ fix_new_exp (fragS *frag, /* Which frag? */ break; } - return fix_new_internal (frag, where, size, add, sub, off, pcrel, r_type); + return fix_new_internal (frag, where, size, add, sub, off, pcrel, + r_type, FALSE); +} + +/* Create a fixup at the beginning of FRAG. The arguments are the same + as for fix_new, except that WHERE is implicitly 0. */ + +fixS * +fix_at_start (fragS *frag, int size, symbolS *add_symbol, + offsetT offset, int pcrel, RELOC_ENUM r_type) +{ + return fix_new_internal (frag, 0, size, add_symbol, + (symbolS *) NULL, offset, pcrel, r_type, TRUE); } /* Generic function to determine whether a fixup requires a relocation. */ diff --git a/gas/write.h b/gas/write.h index d5fe6791d0b..8303f1be98b 100644 --- a/gas/write.h +++ b/gas/write.h @@ -176,6 +176,9 @@ extern void number_to_chars_bigendian (char *, valueT, int); extern fixS *fix_new (fragS * frag, int where, int size, symbolS * add_symbol, offsetT offset, int pcrel, bfd_reloc_code_real_type r_type); +extern fixS *fix_at_start + (fragS * frag, int size, symbolS * add_symbol, + offsetT offset, int pcrel, bfd_reloc_code_real_type r_type); extern fixS *fix_new_exp (fragS * frag, int where, int size, expressionS *exp, int pcrel, bfd_reloc_code_real_type r_type); diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 767747c3edb..3a2dc34bb16 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-01-23 Richard Sandiford + + * ld-powerpc/aix-ref-1-32.od, ld-powerpc/aix-ref-1-64.od, + ld-powerpc/aix-ref-1.s: New tests. + * ld-powerpc/aix52.exp: Run them. + 2010-01-14 H.J. Lu * ld-elf/orphan4.d: Support 64bit targets. diff --git a/ld/testsuite/ld-powerpc/aix-ref-1-32.od b/ld/testsuite/ld-powerpc/aix-ref-1-32.od new file mode 100644 index 00000000000..1ba90ec0a8b --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-ref-1-32.od @@ -0,0 +1,30 @@ + +.* + + +Disassembly of section \.text: + +.* : +.*: 60 00 00 00 oril r0,r0,0 + .*: R_REF foo2\+.* +.*: 80 22 00 00 l r1,0\(r2\) + .*: R_TOC stuff\+.* +.*: 4e 80 00 20 br + +.* : +.*: 60 00 00 00 oril r0,r0,0 + .*: R_REF foo6\+.* + .*: R_REF foo4\+.* +.*: 80 22 00 00 l r1,0\(r2\) + .*: R_TOC stuff\+.* + +.* : +.*: 60 00 00 00 oril r0,r0,0 +.*: 80 22 00 00 l r1,0\(r2\) + .*: R_TOC stuff\+.* + +.* : +.*: 60 00 00 00 oril r0,r0,0 +.*: 80 22 00 00 l r1,0\(r2\) + .*: R_TOC stuff\+.* + \.\.\. diff --git a/ld/testsuite/ld-powerpc/aix-ref-1-64.od b/ld/testsuite/ld-powerpc/aix-ref-1-64.od new file mode 100644 index 00000000000..9cc6e9dc418 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-ref-1-64.od @@ -0,0 +1,30 @@ + +.* + + +Disassembly of section \.text: + +.* : + .*: 60 00 00 00 nop + .*: R_REF foo2\+.* + .*: e8 22 00 00 ld r1,0\(r2\) + .*: R_TOC stuff\+.* + .*: 4e 80 00 20 blr + +.* : + .*: 60 00 00 00 nop + .*: R_REF foo6\+.* + .*: R_REF foo4\+.* + .*: e8 22 00 00 ld r1,0\(r2\) + .*: R_TOC stuff\+.* + +.* : + .*: 60 00 00 00 nop + .*: e8 22 00 00 ld r1,0\(r2\) + .*: R_TOC stuff\+.* + +.* : + .*: 60 00 00 00 nop + .*: e8 22 00 00 ld r1,0\(r2\) + .*: R_TOC stuff\+.* + \.\.\. diff --git a/ld/testsuite/ld-powerpc/aix-ref-1.s b/ld/testsuite/ld-powerpc/aix-ref-1.s new file mode 100644 index 00000000000..33445a6d006 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-ref-1.s @@ -0,0 +1,57 @@ + .macro loadtoc,sym + .if size == 32 + lwz 1,\sym(2) + .else + ld 1,\sym(2) + .endif + .endm + + .toc +LC01: .tc stuff[TC],stuff[RW] + + .globl foo1 + .csect foo1[pr] +foo1: + .align 8 + nop + loadtoc LC01 + + .globl foo2 + .csect foo2[pr] +foo2: + nop + loadtoc LC01 + .ref foo4 , foo6 + + .globl foo3 + .csect foo3[pr] +foo3: + nop + loadtoc LC01 + + .globl foo4 + .csect foo4[pr] +foo4: + nop + loadtoc LC01 + + .globl foo5 + .csect foo5[pr] +foo5: + nop + loadtoc LC01 + .ref foo3 + + .globl foo6 + .csect foo6[pr] +foo6: + nop + loadtoc LC01 + + .csect foo1[pr] + blr + .ref foo2 + + .csect stuff[rw] +stuff: + .long 1 diff --git a/ld/testsuite/ld-powerpc/aix52.exp b/ld/testsuite/ld-powerpc/aix52.exp index d608490259d..2f00cff2c48 100644 --- a/ld/testsuite/ld-powerpc/aix52.exp +++ b/ld/testsuite/ld-powerpc/aix52.exp @@ -196,6 +196,11 @@ set aix52tests { "" {aix-rel-1.s} {{objdump -hr aix-rel-1.od}} "aix-rel-1.ro"} + {".ref test 1" "-efoo1" + "" {aix-ref-1.s} + {{objdump -dr aix-ref-1-SIZE.od}} + "aix-ref-1"} + {"Weak test 1 (rel)" "-r" "" {aix-weak-1a.s aix-weak-1b.s} {{nm {} aix-weak-1-rel.nd} {objdump -h aix-weak-1-rel.hd}}