diff options
author | Jakub Jelinek <jakub@redhat.com> | 2001-12-21 22:35:24 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2001-12-21 22:35:24 +0000 |
commit | bd5e6e7e3a8be60699e596633cd828d3446e75ee (patch) | |
tree | abcf04a60d2166b0d451f2a3d5fa061c36b64a44 /gas | |
parent | 58d370e0e6b0b1cc1df5b587ca39a14e975f5850 (diff) | |
download | gdb-bd5e6e7e3a8be60699e596633cd828d3446e75ee.zip gdb-bd5e6e7e3a8be60699e596633cd828d3446e75ee.tar.gz gdb-bd5e6e7e3a8be60699e596633cd828d3446e75ee.tar.bz2 |
* elf32-sparc.c (_bfd_sparc_elf_howto_table): Fix dst_mask for
R_SPARC_DISP32. Support R_SPARC_PLT32.
(sparc_reloc_map): Add BFD_RELOC_16_PCREL and BFD_RELOC_SPARC_PLT32.
(elf32_sparc_check_relocs): Handle R_SPARC_PLT32.
(elf32_sparc_relocate_section): Likewise.
* elf64-sparc.c (sparc64_elf_howto_table): Fix dst_mask for
R_SPARC_DISP32. Support R_SPARC_PLT32 and R_SPARC_PLT64.
(sparc_reloc_map): Add BFD_RELOC_16_PCREL, BFD_RELOC_64_PCREL
and BFD_RELOC_SPARC_PLT32.
(sparc64_elf_check_relocs): Handle R_SPARC_PLT32 and R_SPARC_PLT64.
(sparc64_elf_relocate_section): Likewise.
* reloc.c (bfd_reloc_code_type): Add BFD_RELOC_SPARC_PLT32.
* bfd-in2.h, libbfd.h: Rebuilt.
* config/tc-sparc.h (TC_PARSE_CONS_EXPRESSION): Define.
(sparc_cons): Provide prototype.
* config/tc-sparc.c (tc_gen_reloc): Handle BFD_RELOC_*_PCREL and
BFD_RELOC_SPARC_PLT{32,64}. Enumerate for which relocs
reloc->addend = fixp->fx_addnumber shouldn't be done instead of
enumarating for which pc relative ones it should be done.
(sparc_cons_special_reloc): New variable.
(sparc_cons): New function.
(cons_fix_new_sparc): Use sparc_cons_special_reloc.
* testsuite/gas/sparc/pcrel.s: New test.
* testsuite/gas/sparc/pcrel.d: Expected output.
* testsuite/gas/sparc/pcrel64.s: New test.
* testsuite/gas/sparc/pcrel64.d: Expected output.
* testsuite/gas/sparc/plt.s: New test.
* testsuite/gas/sparc/plt.d: Expected output.
* testsuite/gas/sparc/plt64.s: New test.
* testsuite/gas/sparc/plt64.d: Expected output.
* testsuite/gas/sparc/sparc.exp: Add pcrel, pcrel64, plt and plt64
tests.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 22 | ||||
-rw-r--r-- | gas/config/tc-sparc.c | 167 | ||||
-rw-r--r-- | gas/config/tc-sparc.h | 5 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/pcrel.d | 34 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/pcrel.s | 26 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/pcrel64.d | 40 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/pcrel64.s | 32 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/plt.d | 23 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/plt.s | 12 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/plt64.d | 26 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/plt64.s | 13 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/sparc.exp | 4 |
12 files changed, 400 insertions, 4 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 08164b3..65cad8c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,25 @@ +2001-12-21 Jakub Jelinek <jakub@redhat.com> + + * config/tc-sparc.h (TC_PARSE_CONS_EXPRESSION): Define. + (sparc_cons): Provide prototype. + * config/tc-sparc.c (tc_gen_reloc): Handle BFD_RELOC_*_PCREL and + BFD_RELOC_SPARC_PLT{32,64}. Enumerate for which relocs + reloc->addend = fixp->fx_addnumber shouldn't be done instead of + enumarating for which pc relative ones it should be done. + (sparc_cons_special_reloc): New variable. + (sparc_cons): New function. + (cons_fix_new_sparc): Use sparc_cons_special_reloc. + * testsuite/gas/sparc/pcrel.s: New test. + * testsuite/gas/sparc/pcrel.d: Expected output. + * testsuite/gas/sparc/pcrel64.s: New test. + * testsuite/gas/sparc/pcrel64.d: Expected output. + * testsuite/gas/sparc/plt.s: New test. + * testsuite/gas/sparc/plt.d: Expected output. + * testsuite/gas/sparc/plt64.s: New test. + * testsuite/gas/sparc/plt64.d: Expected output. + * testsuite/gas/sparc/sparc.exp: Add pcrel, pcrel64, plt and plt64 + tests. + 2001-12-20 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de> Daniel Jacobowitz <drow@mvista.com> diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index 2db2bac..fe9f3f7 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -3313,6 +3313,12 @@ tc_gen_reloc (section, fixp) case BFD_RELOC_SPARC_UA16: case BFD_RELOC_SPARC_UA32: case BFD_RELOC_SPARC_UA64: + case BFD_RELOC_8_PCREL: + case BFD_RELOC_16_PCREL: + case BFD_RELOC_32_PCREL: + case BFD_RELOC_64_PCREL: + case BFD_RELOC_SPARC_PLT32: + case BFD_RELOC_SPARC_PLT64: case BFD_RELOC_VTABLE_ENTRY: case BFD_RELOC_VTABLE_INHERIT: code = fixp->fx_r_type; @@ -3402,9 +3408,11 @@ tc_gen_reloc (section, fixp) #else /* elf or coff */ - if (reloc->howto->pc_relative == 0 - || code == BFD_RELOC_SPARC_PC10 - || code == BFD_RELOC_SPARC_PC22) + if (code != BFD_RELOC_32_PCREL_S2 + && code != BFD_RELOC_SPARC_WDISP22 + && code != BFD_RELOC_SPARC_WDISP16 + && code != BFD_RELOC_SPARC_WDISP19 + && code != BFD_RELOC_SPARC_WPLT30) reloc->addend = fixp->fx_addnumber; else if (symbol_section_p (fixp->fx_addsy)) reloc->addend = (section->vma @@ -3900,6 +3908,11 @@ s_proc (ignore) static int sparc_no_align_cons = 0; +/* This static variable is set by sparc_cons to emit requested types + of relocations in cons_fix_new_sparc. */ + +static const char *sparc_cons_special_reloc; + /* This handles the unaligned space allocation pseudo-ops, such as .uaword. .uaword is just like .word, but the value does not need to be aligned. */ @@ -4172,6 +4185,134 @@ sparc_elf_final_processing () else if (current_architecture == SPARC_OPCODE_ARCH_V9B) elf_elfheader (stdoutput)->e_flags |= EF_SPARC_SUN_US1|EF_SPARC_SUN_US3; } + +void +sparc_cons (exp, size) + expressionS *exp; + int size; +{ + char *save; + + SKIP_WHITESPACE (); + sparc_cons_special_reloc = NULL; + save = input_line_pointer; + if (input_line_pointer[0] == '%' + && input_line_pointer[1] == 'r' + && input_line_pointer[2] == '_') + { + if (strncmp (input_line_pointer + 3, "disp", 4) == 0) + { + input_line_pointer += 7; + sparc_cons_special_reloc = "disp"; + } + else if (strncmp (input_line_pointer + 3, "plt", 3) == 0) + { + if (size != 4 && size != 8) + as_bad (_("Illegal operands: %%r_plt in %d-byte data field"), size); + else + { + input_line_pointer += 6; + sparc_cons_special_reloc = "plt"; + } + } + if (sparc_cons_special_reloc) + { + int bad = 0; + + switch (size) + { + case 1: + if (*input_line_pointer != '8') + bad = 1; + input_line_pointer--; + break; + case 2: + if (input_line_pointer[0] != '1' || input_line_pointer[1] != '6') + bad = 1; + break; + case 4: + if (input_line_pointer[0] != '3' || input_line_pointer[1] != '2') + bad = 1; + break; + case 8: + if (input_line_pointer[0] != '6' || input_line_pointer[1] != '4') + bad = 1; + break; + default: + bad = 1; + break; + } + + if (bad) + { + as_bad (_("Illegal operands: Only %%r_%s%d allowed in %d-byte data fields"), + sparc_cons_special_reloc, size * 8, size); + } + else + { + input_line_pointer += 2; + if (*input_line_pointer != '(') + { + as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"), + sparc_cons_special_reloc, size * 8); + bad = 1; + } + } + + if (bad) + { + input_line_pointer = save; + sparc_cons_special_reloc = NULL; + } + else + { + int c; + char *end = ++input_line_pointer; + int npar = 0; + + while (! is_end_of_line[(c = *end)]) + { + if (c == '(') + npar++; + else if (c == ')') + { + if (!npar) + break; + npar--; + } + end++; + } + + if (c != ')') + as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"), + sparc_cons_special_reloc, size * 8); + else + { + *end = '\0'; + expression (exp); + *end = c; + if (input_line_pointer != end) + { + as_bad (_("Illegal operands: %%r_%s%d requires arguments in ()"), + sparc_cons_special_reloc, size * 8); + } + else + { + input_line_pointer++; + SKIP_WHITESPACE (); + c = *input_line_pointer; + if (! is_end_of_line[c] && c != ',') + as_bad (_("Illegal operands: garbage after %%r_%s%d()"), + sparc_cons_special_reloc, size * 8); + } + } + } + } + } + if (sparc_cons_special_reloc == NULL) + expression (exp); +} + #endif /* This is called by emit_expr via TC_CONS_FIX_NEW when creating a @@ -4196,7 +4337,25 @@ cons_fix_new_sparc (frag, where, nbytes, exp) && now_seg->flags & SEC_ALLOC) r = BFD_RELOC_SPARC_REV32; - if (sparc_no_align_cons) + if (sparc_cons_special_reloc) + { + if (*sparc_cons_special_reloc == 'd') + switch (nbytes) + { + case 1: r = BFD_RELOC_8_PCREL; break; + case 2: r = BFD_RELOC_16_PCREL; break; + case 4: r = BFD_RELOC_32_PCREL; break; + case 8: r = BFD_RELOC_64_PCREL; break; + default: abort (); + } + else + switch (nbytes) + { + case 4: r = BFD_RELOC_SPARC_PLT32; break; + case 8: r = BFD_RELOC_SPARC_PLT64; break; + } + } + else if (sparc_no_align_cons) { switch (nbytes) { diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h index 78653d7..5d545de 100644 --- a/gas/config/tc-sparc.h +++ b/gas/config/tc-sparc.h @@ -166,6 +166,11 @@ extern void sparc_md_end PARAMS ((void)); #endif +#ifdef OBJ_ELF +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) sparc_cons (EXP, NBYTES) +extern void sparc_cons PARAMS ((expressionS *, int)); +#endif + #define TC_CONS_FIX_NEW cons_fix_new_sparc extern void cons_fix_new_sparc PARAMS ((struct frag *, int, unsigned int, struct expressionS *)); diff --git a/gas/testsuite/gas/sparc/pcrel.d b/gas/testsuite/gas/sparc/pcrel.d new file mode 100644 index 0000000..2d37010 --- /dev/null +++ b/gas/testsuite/gas/sparc/pcrel.d @@ -0,0 +1,34 @@ +#as: +#objdump: -Dr +#name: pc relative relocs + +.*: +file format .*sparc.* + +Disassembly of section .text: + +0+ <foo-0x8>: + 0: 01 00 00 00 nop + 4: 01 00 00 00 nop + +0+8 <foo>: + 8: 01 00 00 00 nop +Disassembly of section .data: + +0+ <.data>: + 0: 00 00 00 00 (unimp|illtrap) 0 + 4: 00 00 00 01 (unimp|illtrap) 0x1 + ... + 8: R_SPARC_32 .text\+0x10 + c: R_SPARC_DISP32 .text\+0x10 + 10: R_SPARC_32 .text\+0x10 + 14: R_SPARC_DISP32 .text\+0x10 + 18: R_SPARC_32 foo + 1c: R_SPARC_DISP32 foo + 20: R_SPARC_32 foo\+0x10 + 24: R_SPARC_DISP32 foo\+0x10 + 28: R_SPARC_DISP8 .data\+0x18 + 29: R_SPARC_DISP8 .data\+0x34 + 2a: R_SPARC_DISP16 .data\+0x18 + 2c: R_SPARC_DISP16 .data\+0x34 + 30: 00 02 00 00 (unimp|illtrap) 0x20000 + ... diff --git a/gas/testsuite/gas/sparc/pcrel.s b/gas/testsuite/gas/sparc/pcrel.s new file mode 100644 index 0000000..ac59454 --- /dev/null +++ b/gas/testsuite/gas/sparc/pcrel.s @@ -0,0 +1,26 @@ + .text + .align 4 +1: nop +2: nop + .globl foo +foo: nop + + .data + .align 32 + .word 0 + .word 1 + .word 1b + 16 + .word %r_disp32(1b + 16) + .word 1b + 16 + .word %r_disp32(1b + 16) +3: .word foo + .word %r_disp32(foo) + .word foo + 16 + .word %r_disp32(foo + 16) + .byte %r_disp8(3b) + .byte %r_disp8(4f) + .half %r_disp16(3b) + .half %r_disp16(4f) + .uaword 2 + .half 0 +4: diff --git a/gas/testsuite/gas/sparc/pcrel64.d b/gas/testsuite/gas/sparc/pcrel64.d new file mode 100644 index 0000000..a93ead9 --- /dev/null +++ b/gas/testsuite/gas/sparc/pcrel64.d @@ -0,0 +1,40 @@ +#as: -64 -K PIC +#objdump: -Dr +#name: pc relative 64-bit relocs + +.*: +file format .*sparc.* + +Disassembly of section .text: + +0+ <foo-0x8>: + 0: 01 00 00 00 nop + 4: 01 00 00 00 nop + +0+8 <foo>: + 8: 01 00 00 00 nop +Disassembly of section .data: + +0+ <.data>: + 0: 00 00 00 00 illtrap 0 + 4: 00 00 00 01 illtrap 0x1 + ... + 8: R_SPARC_32 .text\+0x10 + c: R_SPARC_DISP32 .text\+0x10 + 10: R_SPARC_32 .text\+0x10 + 14: R_SPARC_DISP32 .text\+0x10 + 18: R_SPARC_32 foo + 1c: R_SPARC_DISP32 foo + 20: R_SPARC_32 foo\+0x10 + 24: R_SPARC_DISP32 foo\+0x10 + 28: R_SPARC_64 .text\+0x8 + 30: R_SPARC_DISP64 .text\+0x8 + 38: R_SPARC_64 foo + 40: R_SPARC_DISP64 foo + 48: R_SPARC_64 foo\+0x10 + 50: R_SPARC_DISP64 foo\+0x10 + 58: R_SPARC_DISP8 .data\+0x18 + 59: R_SPARC_DISP8 .data\+0x64 + 5a: R_SPARC_DISP16 .data\+0x18 + 5c: R_SPARC_DISP16 .data\+0x64 + 60: 00 02 00 00 illtrap 0x20000 + ... diff --git a/gas/testsuite/gas/sparc/pcrel64.s b/gas/testsuite/gas/sparc/pcrel64.s new file mode 100644 index 0000000..166b119 --- /dev/null +++ b/gas/testsuite/gas/sparc/pcrel64.s @@ -0,0 +1,32 @@ + .text + .align 4 +1: nop +2: nop + .globl foo +foo: nop + + .data + .align 32 + .word 0 + .word 1 + .word 1b + 16 + .word %r_disp32(1b + 16) + .word 1b + 16 + .word %r_disp32(1b + 16) +3: .word foo + .word %r_disp32(foo) + .word foo + 16 + .word %r_disp32(foo + 16) + .xword 2b + 4 + .xword %r_disp64(2b + 4) + .xword foo + .xword %r_disp64(foo) + .xword foo + 16 + .xword %r_disp64(foo + 16) + .byte %r_disp8(3b) + .byte %r_disp8(4f) + .half %r_disp16(3b) + .half %r_disp16(4f) + .uaword 2 + .half 0 +4: diff --git a/gas/testsuite/gas/sparc/plt.d b/gas/testsuite/gas/sparc/plt.d new file mode 100644 index 0000000..6b4ac27 --- /dev/null +++ b/gas/testsuite/gas/sparc/plt.d @@ -0,0 +1,23 @@ +#as: -K PIC +#objdump: -Dr +#name: plt relocs + +.*: +file format .*sparc.* + +Disassembly of section .text: + +0+ <.text>: + 0: 40 00 00 00 call 0x0 + 0: R_SPARC_WPLT30 foo + 4: 01 00 00 00 nop + 8: 40 00 00 00 call 0x8 + 8: R_SPARC_WPLT30 bar\+0x4 +Disassembly of section .data: + +0+ <.data>: + ... + 0: R_SPARC_PLT32 foo + 4: R_SPARC_PLT32 bar\+0x4 + 8: 01 00 00 00 nop + 9: R_SPARC_PLT32 foo + c: 00 02 03 04 (unimp|illtrap) 0x20304 diff --git a/gas/testsuite/gas/sparc/plt.s b/gas/testsuite/gas/sparc/plt.s new file mode 100644 index 0000000..b7b4d09 --- /dev/null +++ b/gas/testsuite/gas/sparc/plt.s @@ -0,0 +1,12 @@ + .text + .align 4 + call foo + nop + call bar + 4 + .data + .align 4 + .word %r_plt32(foo) + .word %r_plt32(bar + 4) + .byte 1 + .uaword %r_plt32(foo) + .byte 2, 3, 4 diff --git a/gas/testsuite/gas/sparc/plt64.d b/gas/testsuite/gas/sparc/plt64.d new file mode 100644 index 0000000..736515b --- /dev/null +++ b/gas/testsuite/gas/sparc/plt64.d @@ -0,0 +1,26 @@ +#as: -K PIC -64 +#objdump: -Dr +#name: plt 64-bit relocs + +.*: +file format .*sparc.* + +Disassembly of section .text: + +0+ <.text>: + 0: 40 00 00 00 call 0x0 + 0: R_SPARC_WPLT30 foo + 4: 01 00 00 00 nop + 8: 40 00 00 00 call 0x8 + 8: R_SPARC_WPLT30 bar\+0x4 +Disassembly of section .data: + +0+ <.data>: + ... + 0: R_SPARC_PLT64 foo + 8: R_SPARC_PLT64 bar\+0x4 + 10: 01 00 00 00 nop + 11: R_SPARC_PLT64 foo + 14: 00 00 00 00 illtrap 0 + 18: 00 02 03 04 illtrap 0x20304 + 1c: 00 00 00 00 illtrap 0 + 1c: R_SPARC_PLT32 bar\+0x4 diff --git a/gas/testsuite/gas/sparc/plt64.s b/gas/testsuite/gas/sparc/plt64.s new file mode 100644 index 0000000..e5faf20 --- /dev/null +++ b/gas/testsuite/gas/sparc/plt64.s @@ -0,0 +1,13 @@ + .text + .align 4 + call foo + nop + call bar + 4 + .data + .align 8 + .xword %r_plt64(foo) + .xword %r_plt64(bar + 4) + .byte 1 + .uaxword %r_plt64(foo) + .byte 2, 3, 4 + .word %r_plt32(bar + 4) diff --git a/gas/testsuite/gas/sparc/sparc.exp b/gas/testsuite/gas/sparc/sparc.exp index 39bf0f9..7298256 100644 --- a/gas/testsuite/gas/sparc/sparc.exp +++ b/gas/testsuite/gas/sparc/sparc.exp @@ -19,6 +19,8 @@ proc gas_64_check { } { if [istarget sparc*-*-*] { run_dump_test "synth" run_dump_test "unalign" + run_dump_test "pcrel" + run_dump_test "plt" if [gas_64_check] { run_dump_test "asi" run_dump_test "membar" @@ -28,6 +30,8 @@ if [istarget sparc*-*-*] { run_dump_test "rdpr" run_dump_test "wrpr" run_dump_test "reloc64" + run_dump_test "pcrel64" + run_dump_test "plt64" } } |