So far it was impossible to force use of R_X86_64_32S from data allocation directives, making it impossible to do certain things e.g. in the Linux kernel. This patch adds support for this through the new .slong directive. At the same time this eliminates the potential of duplicate conflicting definitions of TC_CONS_FIX_NEW. Built and tested on i686-pc-linux-gnu, x86_64-unknown-linux-gnu, and i686-pc-cygwin. Jan gas/ 2005-09-13 Jan Beulich * config/tc-i386.h (x86_cons_fix_new): Declare unconditionally. (TC_CONS_FIX_NEW): Define unconditionally. (x86_pe_cons_fix_new): Remove. * config/tc-i386.c (signed_cons): New. (md_pseudo_table): Add slong. (x86_cons_fix_new): Declare unconditionally. (x86_pe_cons_fix_new): Merge into x86_cons_fix_new. (tc_gen_reloc): Also consider BFD_RELOC_X86_64_32S for gotpc conversion. gas/testsuite/ 2005-09-13 Jan Beulich * gas/i386/reloc64.s: Also test .slong. * gas/i386/reloc64.l: Adjust. * gas/i386/reloc64.d: Adjust. --- /home/jbeulich/src/binutils/mainline/2005-09-13/gas/config/tc-i386.c 2005-08-23 16:13:12.000000000 +0200 +++ 2005-09-13/gas/config/tc-i386.c 2005-09-13 15:56:07.381895208 +0200 @@ -80,6 +80,7 @@ static void set_cpu_arch PARAMS ((int)); #ifdef TE_PE static void pe_directive_secrel PARAMS ((int)); #endif +static void signed_cons PARAMS ((int)); static char *output_invalid PARAMS ((int c)); static int i386_operand PARAMS ((char *operand_string)); static int i386_intel_operand PARAMS ((char *operand_string, int got_a_float)); @@ -461,6 +462,7 @@ const pseudo_typeS md_pseudo_table[] = {"dfloat", float_cons, 'd'}, {"tfloat", float_cons, 'x'}, {"value", cons, 2}, + {"slong", signed_cons, 4}, {"noopt", s_ignore, 0}, {"optim", s_ignore, 0}, {"code16gcc", set_16bit_gcc_code_flag, CODE_16BIT}, @@ -3762,6 +3764,32 @@ output_imm (insn_start_frag, insn_start_ } } +/* x86_cons_fix_new is called via the expression parsing code when a + reloc is needed. We use this hook to get the correct .got reloc. */ +static enum bfd_reloc_code_real got_reloc = NO_RELOC; +static int cons_sign = -1; + +void +x86_cons_fix_new (fragS *frag, + unsigned int off, + unsigned int len, + expressionS *exp) +{ + enum bfd_reloc_code_real r = reloc (len, 0, cons_sign, got_reloc); + + got_reloc = NO_RELOC; + +#ifdef TE_PE + if (exp->X_op == O_secrel) + { + exp->X_op = O_symbol; + r = BFD_RELOC_32_SECREL; + } +#endif + + fix_new_exp (frag, off, len, exp, 0, r); +} + #if (!defined (OBJ_ELF) && !defined (OBJ_MAYBE_ELF)) || defined (LEX_AT) # define lex_got(reloc, adjust, types) NULL #else @@ -3869,22 +3897,6 @@ lex_got (enum bfd_reloc_code_real *reloc return NULL; } -/* x86_cons_fix_new is called via the expression parsing code when a - reloc is needed. We use this hook to get the correct .got reloc. */ -static enum bfd_reloc_code_real got_reloc = NO_RELOC; - -void -x86_cons_fix_new (frag, off, len, exp) - fragS *frag; - unsigned int off; - unsigned int len; - expressionS *exp; -{ - enum bfd_reloc_code_real r = reloc (len, 0, -1, got_reloc); - got_reloc = NO_RELOC; - fix_new_exp (frag, off, len, exp, 0, r); -} - void x86_cons (exp, size) expressionS *exp; @@ -3920,26 +3932,15 @@ x86_cons (exp, size) } #endif -#ifdef TE_PE - -void -x86_pe_cons_fix_new (frag, off, len, exp) - fragS *frag; - unsigned int off; - unsigned int len; - expressionS *exp; +static void signed_cons (int size) { - enum bfd_reloc_code_real r = reloc (len, 0, -1, NO_RELOC); - - if (exp->X_op == O_secrel) - { - exp->X_op = O_symbol; - r = BFD_RELOC_32_SECREL; - } - - fix_new_exp (frag, off, len, exp, 0, r); + if (flag_code == CODE_64BIT) + cons_sign = 1; + cons (size); + cons_sign = -1; } +#ifdef TE_PE static void pe_directive_secrel (dummy) int dummy ATTRIBUTE_UNUSED; @@ -3959,7 +3960,6 @@ pe_directive_secrel (dummy) input_line_pointer--; demand_empty_rest_of_line (); } - #endif static int i386_immediate PARAMS ((char *)); @@ -5563,7 +5563,9 @@ tc_gen_reloc (section, fixp) break; } - if ((code == BFD_RELOC_32 || code == BFD_RELOC_32_PCREL) + if ((code == BFD_RELOC_32 + || code == BFD_RELOC_32_PCREL + || code == BFD_RELOC_X86_64_32S) && GOT_symbol && fixp->fx_addsy == GOT_symbol) { --- /home/jbeulich/src/binutils/mainline/2005-09-13/gas/config/tc-i386.h 2005-08-18 08:51:27.000000000 +0200 +++ 2005-09-13/gas/config/tc-i386.h 2005-09-13 13:58:50.000000000 +0200 @@ -390,17 +390,11 @@ arch_entry; #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) && !defined (LEX_AT) #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) x86_cons (EXP, NBYTES) extern void x86_cons PARAMS ((expressionS *, int)); +#endif #define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_cons_fix_new(FRAG, OFF, LEN, EXP) extern void x86_cons_fix_new PARAMS ((fragS *, unsigned int, unsigned int, expressionS *)); -#endif - -#ifdef TE_PE -#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_pe_cons_fix_new(FRAG, OFF, LEN, EXP) -extern void x86_pe_cons_fix_new - PARAMS ((fragS *, unsigned int, unsigned int, expressionS *)); -#endif #define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */ --- /home/jbeulich/src/binutils/mainline/2005-09-13/gas/testsuite/gas/i386/reloc64.d 2005-06-16 12:44:57.000000000 +0200 +++ 2005-09-13/gas/testsuite/gas/i386/reloc64.d 2005-09-13 14:14:15.000000000 +0200 @@ -65,6 +65,18 @@ Disassembly of section \.data: .*[ ]+R_X86_64_TLSLD[ ]+xtrn .*[ ]+R_X86_64_DTPOFF32[ ]+xtrn .*[ ]+R_X86_64_TPOFF32[ ]+xtrn +.*[ ]+R_X86_64_32S[ ]+xtrn +.*[ ]+R_X86_64_PC32[ ]+xtrn +.*[ ]+R_X86_64_GOT32[ ]+xtrn +.*[ ]+R_X86_64_GOTPCREL[ ]+xtrn +.*[ ]+R_X86_64_GOTPC32[ ]+_GLOBAL_OFFSET_TABLE_ +.*[ ]+R_X86_64_GOTPC32[ ]+_GLOBAL_OFFSET_TABLE_ +.*[ ]+R_X86_64_PLT32[ ]+xtrn +.*[ ]+R_X86_64_TLSGD[ ]+xtrn +.*[ ]+R_X86_64_GOTTPOFF[ ]+xtrn +.*[ ]+R_X86_64_TLSLD[ ]+xtrn +.*[ ]+R_X86_64_DTPOFF32[ ]+xtrn +.*[ ]+R_X86_64_TPOFF32[ ]+xtrn .*[ ]+R_X86_64_16[ ]+xtrn .*[ ]+R_X86_64_PC16[ ]+xtrn .*[ ]+R_X86_64_8[ ]+xtrn --- /home/jbeulich/src/binutils/mainline/2005-09-13/gas/testsuite/gas/i386/reloc64.l 2005-06-16 12:47:27.000000000 +0200 +++ 2005-09-13/gas/testsuite/gas/i386/reloc64.l 2005-09-13 14:13:14.000000000 +0200 @@ -57,15 +57,7 @@ .*:138: Error: .* .*:139: Error: .* .*:146: Error: .* -.*:159: Error: .* .*:160: Error: .* -.*:161: Error: .* -.*:164: Error: .* -.*:165: Error: .* -.*:166: Error: .* -.*:167: Error: .* -.*:168: Error: .* -.*:169: Error: .* .*:173: Error: .* .*:174: Error: .* .*:175: Error: .* @@ -75,3 +67,12 @@ .*:181: Error: .* .*:182: Error: .* .*:183: Error: .* +.*:187: Error: .* +.*:188: Error: .* +.*:189: Error: .* +.*:192: Error: .* +.*:193: Error: .* +.*:194: Error: .* +.*:195: Error: .* +.*:196: Error: .* +.*:197: Error: .* --- /home/jbeulich/src/binutils/mainline/2005-09-13/gas/testsuite/gas/i386/reloc64.s 2005-06-16 12:43:35.000000000 +0200 +++ 2005-09-13/gas/testsuite/gas/i386/reloc64.s 2005-09-13 14:10:26.000000000 +0200 @@ -154,6 +154,20 @@ bad .long xtrn@gotoff .long xtrn@dtpoff .long xtrn@tpoff + .slong xtrn + .slong xtrn - . + .slong xtrn@got +bad .slong xtrn@gotoff + .slong xtrn@gotpcrel + .slong _GLOBAL_OFFSET_TABLE_ + .slong _GLOBAL_OFFSET_TABLE_ - . + .slong xtrn@plt + .slong xtrn@tlsgd + .slong xtrn@gottpoff + .slong xtrn@tlsld + .slong xtrn@dtpoff + .slong xtrn@tpoff + .word xtrn .word xtrn - . bad .word xtrn@got