This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] New port @GOTOFF, @GOT, @PLT relocation token for target m32r
- From: Kazuhiro Inaoka <inaoka dot kazuhiro at renesas dot com>
- To: Nick Clifton <nickc at redhat dot com>
- Cc: "binutils at sources dot redhat dot com" <binutils at sources dot redhat dot com>
- Date: Tue, 22 Jun 2004 21:10:59 +0900
- Subject: [PATCH] New port @GOTOFF, @GOT, @PLT relocation token for target m32r
Hi Nick,
This is a patch to support R_M32R_GOTOFF relocation and new token
(@GOTOFF, @GOT, @PLT).
Please commit it.
Regards,
Kauhiro Inaoka
bfd/ChangeLog
2004-06-22 Kazuhiro Inaoka <inaoka dot kazuhiro at renesas dot com>
* elf32-m32r.c (m32r_elf_howto_table): Support R_M32R_GOTOFF.
(m32r_elf_relocate_section): Changed for R_M32R_GOTOFF.
(m32r_elf_gcsweep_hook): Ditto.
(m32r_elf_check_relocs): Ditto.
gas/ChangeLog
2004-06-22 Kazuhiro Inaoka <inaoka dot kazuhiro at renesas dot com>
* config/tc-m32r.c (md_convert_frag): Changed for @PLT.
(m32r_cgen_record_fixup_exp): Changed for @GOTOFF, @GOT.
(m32r_fix_adjustable): Changed for @GOTOFF, @GOT, @PLT.
(tc_gen_reloc): Ditto.
(m32r_end_of_match): Add for @GOTOFF, @GOT, @PLT.
(m32r_parse_name): Ditto.
(m32r_cgen_parse_fix_exp): Ditto.
* config/tc-m32r.h (md_parse_name): Define for @GOTOFF,
@GOT, @PLT.
(O_PIC_reloc): Ditto
(TC_CGEN_PARSE_FIX_EXP): Ditto.
* cgen.c (gas_cgen_parse_operand): Add TC_CGEN_PARSE_FIX_EXP
for @GOTOFF, @GOT, @PLT.
Index: bfd/elf32-m32r.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m32r.c,v
retrieving revision 1.44
diff -c -r1.44 elf32-m32r.c
*** bfd/elf32-m32r.c 27 Mar 2004 10:58:06 -0000 1.44
--- bfd/elf32-m32r.c 22 Jun 2004 11:32:26 -0000
***************
*** 685,692 ****
bfd_elf_generic_reloc, /* special_function */
"R_M32R_GOTOFF", /* name */
FALSE, /* partial_inplace */
! 0xffffffff, /* src_mask */
! 0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An PC Relative 24-bit relocation used when setting PIC offset
--- 685,692 ----
bfd_elf_generic_reloc, /* special_function */
"R_M32R_GOTOFF", /* name */
FALSE, /* partial_inplace */
! 0xffffff, /* src_mask */
! 0xffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An PC Relative 24-bit relocation used when setting PIC offset
***************
*** 2787,2792 ****
--- 2787,2806 ----
switch ((int) r_type)
{
+ case R_M32R_GOTOFF:
+ /* Relocation is relative to the start of the global offset
+ table. (for ld24 rx,#uimm24)
+ ex) access at label+addend
+ ld24 rx.#label@GOTOFF + addend
+ sub rx,r12
+ */
+
+ BFD_ASSERT (sgot != NULL);
+
+ relocation = -(relocation - sgot->output_section->vma);
+ rel->r_addend = -rel->r_addend;
+ break;
+
case R_M32R_GOTPC24:
/* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
ld24 rx,#_GLOBAL_OFFSET_TABLE_
***************
*** 4314,4319 ****
--- 4328,4334 ----
case R_M32R_GOT16_HI_SLO:
case R_M32R_GOT16_LO:
case R_M32R_GOT24:
+ case R_M32R_GOTOFF:
case R_M32R_GOTPC_HI_ULO:
case R_M32R_GOTPC_HI_SLO:
case R_M32R_GOTPC_LO:
***************
*** 4443,4448 ****
--- 4458,4464 ----
case R_M32R_GOT16_HI_ULO:
case R_M32R_GOT16_HI_SLO:
case R_M32R_GOT16_LO:
+ case R_M32R_GOTOFF:
case R_M32R_GOTPC24:
case R_M32R_GOTPC_HI_ULO:
case R_M32R_GOTPC_HI_SLO:
Index: gas/cgen.c
===================================================================
RCS file: /cvs/src/src/gas/cgen.c,v
retrieving revision 1.23
diff -c -r1.23 cgen.c
*** gas/cgen.c 21 Nov 2003 01:52:16 -0000 1.23
--- gas/cgen.c 22 Jun 2004 11:32:27 -0000
***************
*** 355,360 ****
--- 355,364 ----
*strP = input_line_pointer;
input_line_pointer = hold;
+ #ifdef TC_CGEN_PARSE_FIX_EXP
+ opinfo = TC_CGEN_PARSE_FIX_EXP (opinfo, &exp);
+ #endif
+
/* FIXME: Need to check `want'. */
switch (exp.X_op)
Index: gas/config/tc-m32r.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m32r.c,v
retrieving revision 1.36
diff -c -r1.36 tc-m32r.c
*** gas/config/tc-m32r.c 13 Apr 2004 16:47:57 -0000 1.36
--- gas/config/tc-m32r.c 22 Jun 2004 11:32:27 -0000
***************
*** 489,494 ****
--- 489,557 ----
{ NULL, NULL, 0 }
};
+ #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
+ symbolS *GOT_symbol;
+
+ static inline int
+ m32r_PIC_related_p (symbolS *sym)
+ {
+ expressionS *exp;
+
+ if (! sym)
+ return 0;
+
+ if (sym == GOT_symbol)
+ return 1;
+
+ exp = symbol_get_value_expression (sym);
+
+ return (exp->X_op == O_PIC_reloc
+ || exp->X_md == BFD_RELOC_M32R_26_PLTREL
+ || m32r_PIC_related_p (exp->X_add_symbol)
+ || m32r_PIC_related_p (exp->X_op_symbol));
+ }
+
+ static inline int
+ m32r_check_fixup (expressionS *main_exp, bfd_reloc_code_real_type *r_type_p)
+ {
+ expressionS *exp = main_exp;
+
+ if (exp->X_op == O_add && m32r_PIC_related_p (exp->X_op_symbol))
+ return 1;
+
+ if (exp->X_op == O_symbol && exp->X_add_symbol)
+ {
+ if (exp->X_add_symbol == GOT_symbol)
+ {
+ *r_type_p = BFD_RELOC_M32R_GOTPC24;
+ return 0;
+ }
+ }
+ else if (exp->X_op == O_add)
+ {
+ exp = symbol_get_value_expression (exp->X_add_symbol);
+ if (! exp)
+ return 0;
+ }
+
+ if (exp->X_op == O_PIC_reloc || exp->X_md != BFD_RELOC_UNUSED)
+ {
+ *r_type_p = exp->X_md;
+ if (exp == main_exp)
+ exp->X_op = O_symbol;
+ else
+ {
+ main_exp->X_add_symbol = exp->X_add_symbol;
+ main_exp->X_add_number += exp->X_add_number;
+ }
+ }
+ else
+ return (m32r_PIC_related_p (exp->X_add_symbol)
+ || m32r_PIC_related_p (exp->X_op_symbol));
+
+ return 0;
+ }
+
/* FIXME: Should be machine generated. */
#define NOP_INSN 0x7000
#define PAR_NOP_INSN 0xf000 /* Can only be used in 2nd slot. */
***************
*** 1888,1895 ****
--- 1951,1961 ----
|| S_IS_EXTERNAL (fragP->fr_symbol)
|| S_IS_WEAK (fragP->fr_symbol))
{
+ fixS *fixP;
assert (fragP->fr_subtype != 1);
assert (fragP->fr_cgen.insn != 0);
+
+ fixP =
gas_cgen_record_fixup (fragP,
/* Offset of branch insn in frag. */
fragP->fr_fix + extension - 4,
***************
*** 1905,1910 ****
--- 1971,1978 ----
#endif
fragP->fr_cgen.opinfo,
fragP->fr_symbol, fragP->fr_offset);
+ if (fragP->fr_cgen.opinfo)
+ fixP->fx_r_type = fragP->fr_cgen.opinfo;
}
#define SIZE_FROM_RELAX_STATE(n) ((n) == 1 ? 1 : 3)
***************
*** 2006,2013 ****
int opinfo;
expressionS *exp;
{
! fixS *fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
! operand, opinfo, exp);
switch (operand->type)
{
--- 2074,2087 ----
int opinfo;
expressionS *exp;
{
! fixS *fixP;
! bfd_reloc_code_real_type r_type = BFD_RELOC_UNUSED;
!
! if (m32r_check_fixup (exp, &r_type))
! as_bad (_("Invalid PIC expression."));
!
! fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
! operand, opinfo, exp);
switch (operand->type)
{
***************
*** 2022,2027 ****
--- 2096,2131 ----
break;
}
+ switch(r_type)
+ {
+ case BFD_RELOC_UNUSED:
+ default:
+ return fixP;
+ case BFD_RELOC_M32R_GOTPC24:
+ if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_SLO)
+ r_type = BFD_RELOC_M32R_GOTPC_HI_SLO;
+ else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)
+ r_type = BFD_RELOC_M32R_GOTPC_HI_ULO;
+ else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_LO16)
+ r_type = BFD_RELOC_M32R_GOTPC_LO;
+ break;
+ case BFD_RELOC_M32R_GOT24:
+ if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_SLO)
+ r_type = BFD_RELOC_M32R_GOT16_HI_SLO;
+ else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)
+ r_type = BFD_RELOC_M32R_GOT16_HI_ULO;
+ else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_LO16)
+ r_type = BFD_RELOC_M32R_GOT16_LO;
+ break;
+ case BFD_RELOC_M32R_GOTOFF:
+ break;
+ case BFD_RELOC_M32R_26_PLTREL:
+ as_bad (_("Invalid PIC expression."));
+ break;
+ }
+
+ fixP->fx_r_type = r_type;
+
return fixP;
}
***************
*** 2261,2266 ****
--- 2365,2380 ----
|| reloc_type == BFD_RELOC_M32R_LO16))
return 0;
+ if (reloc_type == BFD_RELOC_M32R_GOT24
+ || reloc_type == BFD_RELOC_M32R_26_PLTREL
+ || reloc_type == BFD_RELOC_M32R_GOTPC_HI_SLO
+ || reloc_type == BFD_RELOC_M32R_GOTPC_HI_ULO
+ || reloc_type == BFD_RELOC_M32R_GOTPC_LO
+ || reloc_type == BFD_RELOC_M32R_GOT16_HI_SLO
+ || reloc_type == BFD_RELOC_M32R_GOT16_HI_ULO
+ || reloc_type == BFD_RELOC_M32R_GOT16_LO)
+ return 0;
+
/* We need the symbol name for the VTABLE entries. */
if (reloc_type == BFD_RELOC_VTABLE_INHERIT
|| reloc_type == BFD_RELOC_VTABLE_ENTRY)
***************
*** 2277,2284 ****
elf_elfheader (stdoutput)->e_flags |= m32r_flags;
}
- #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
-
/* Translate internal representation of relocation info to BFD target
format. */
arelent *
--- 2391,2396 ----
***************
*** 2358,2364 ****
if ( fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
|| fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
reloc->addend = fixP->fx_offset;
! else if (!pic_code
&& fixP->fx_pcrel
&& fixP->fx_addsy != NULL
&& (S_GET_SEGMENT(fixP->fx_addsy) != section)
--- 2470,2477 ----
if ( fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
|| fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
reloc->addend = fixP->fx_offset;
! else if ((!pic_code
! && code != BFD_RELOC_M32R_26_PLTREL)
&& fixP->fx_pcrel
&& fixP->fx_addsy != NULL
&& (S_GET_SEGMENT(fixP->fx_addsy) != section)
***************
*** 2372,2374 ****
--- 2485,2589 ----
return reloc;
}
+
+ inline static char *
+ m32r_end_of_match (char *cont, char *what)
+ {
+ int len = strlen (what);
+
+ if (strncasecmp (cont, what, strlen (what)) == 0
+ && ! is_part_of_name (cont[len]))
+ return cont + len;
+
+ return NULL;
+ }
+
+ int
+ m32r_parse_name (char const *name, expressionS *exprP, char *nextcharP)
+ {
+ char *next = input_line_pointer;
+ char *next_end;
+ int reloc_type;
+ operatorT op_type;
+ segT segment;
+
+ exprP->X_op_symbol = NULL;
+ exprP->X_md = BFD_RELOC_UNUSED;
+
+ if (strcmp (name, GOT_NAME) == 0)
+ {
+ if (! GOT_symbol)
+ GOT_symbol = symbol_find_or_make (name);
+
+ exprP->X_add_symbol = GOT_symbol;
+ no_suffix:
+ /* If we have an absolute symbol or a reg, then we know its
+ value now. */
+ segment = S_GET_SEGMENT (exprP->X_add_symbol);
+ if (segment == absolute_section)
+ {
+ exprP->X_op = O_constant;
+ exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
+ exprP->X_add_symbol = NULL;
+ }
+ else if (segment == reg_section)
+ {
+ exprP->X_op = O_register;
+ exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
+ exprP->X_add_symbol = NULL;
+ }
+ else
+ {
+ exprP->X_op = O_symbol;
+ exprP->X_add_number = 0;
+ }
+
+ return 1;
+ }
+
+ exprP->X_add_symbol = symbol_find_or_make (name);
+
+ if (*nextcharP != '@')
+ goto no_suffix;
+ else if ((next_end = m32r_end_of_match (next + 1, "GOTOFF")))
+ {
+ reloc_type = BFD_RELOC_M32R_GOTOFF;
+ op_type = O_PIC_reloc;
+ }
+ else if ((next_end = m32r_end_of_match (next + 1, "GOT")))
+ {
+ reloc_type = BFD_RELOC_M32R_GOT24;
+ op_type = O_PIC_reloc;
+ }
+ else if ((next_end = m32r_end_of_match (next + 1, "PLT")))
+ {
+ reloc_type = BFD_RELOC_M32R_26_PLTREL;
+ op_type = O_PIC_reloc;
+ }
+ else
+ goto no_suffix;
+
+ *input_line_pointer = *nextcharP;
+ input_line_pointer = next_end;
+ *nextcharP = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ exprP->X_op = op_type;
+ exprP->X_add_number = 0;
+ exprP->X_md = reloc_type;
+
+ return 1;
+ }
+
+ int
+ m32r_cgen_parse_fix_exp(int opinfo, expressionS *exp)
+ {
+ if (exp->X_op == O_PIC_reloc
+ && exp->X_md == BFD_RELOC_M32R_26_PLTREL)
+ {
+ exp->X_op = O_symbol;
+ opinfo = exp->X_md;
+ }
+
+ return opinfo;
+ }
Index: gas/config/tc-m32r.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m32r.h,v
retrieving revision 1.11
diff -c -r1.11 tc-m32r.h
*** gas/config/tc-m32r.h 19 Dec 2003 11:43:37 -0000 1.11
--- gas/config/tc-m32r.h 22 Jun 2004 11:32:27 -0000
***************
*** 131,133 ****
--- 131,145 ----
#define elf_tc_final_processing m32r_elf_final_processing
extern void m32r_elf_final_processing PARAMS ((void));
+
+ #define md_parse_name(name, exprP, nextcharP) \
+ m32r_parse_name ((name), (exprP), (nextcharP))
+ int m32r_parse_name (char const *name, expressionS *exprP, char *nextchar);
+
+ /* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
+ symbols. The relocation type is stored in X_md. */
+ #define O_PIC_reloc O_md1
+
+ #define TC_CGEN_PARSE_FIX_EXP(opinfo, exp) \
+ m32r_cgen_parse_fix_exp(opinfo, exp)
+ int m32r_cgen_parse_fix_exp(int opinfo, expressionS *exp);