summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2004-06-25 16:11:09 +0000
committerNick Clifton <nickc@redhat.com>2004-06-25 16:11:09 +0000
commit097f809a197dcb5f2c1b878c0604be5c185c4db8 (patch)
tree3531995e73afe46e124efafd42dfcf3ff11c86d4
parente19f872c5bec6fbb9476abdc4ea5cee44da598e2 (diff)
downloadbinutils-gdb-097f809a197dcb5f2c1b878c0604be5c185c4db8.tar.gz
Add support for M32R GOT relocs
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/elf32-m32r.c88
-rw-r--r--bfd/libbfd.h3
-rw-r--r--bfd/reloc.c6
-rw-r--r--gas/ChangeLog15
-rw-r--r--gas/cgen.c6
-rw-r--r--gas/config/tc-m32r.c266
-rw-r--r--gas/config/tc-m32r.h14
-rw-r--r--include/elf/ChangeLog5
-rw-r--r--include/elf/m32r.h5
11 files changed, 393 insertions, 29 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7aebb9f0dea..830c32e198f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2004-06-25 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.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): Likewise.
+ (m32r_elf_check_relocs): Likewise.
+ (m32r_elf_howto_table): Added R_M32R_GOTOFF_HI_ULO,
+ R_M32R_GOTOFF_HI_SLO and R_M32R_GOTOFF_LO.
+ * reloc.c: Added BFD_RELOC_M32R_GOTOFF_HI_ULO,
+ BFD_RELOC_M32R_GOTOFF_HI_SLO and BFD_RELOC_M32R_GOTOFF_LO.
+
2004-06-24 H.J. Lu <hongjiu.lu@intel.com>
* elf64-x86-64.c (elf64_x86_64_check_relocs): Warn overflow
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 5001cf87b51..3b9d78cf937 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2821,6 +2821,9 @@ add3, load, and store instructions. */
BFD_RELOC_M32R_JMP_SLOT,
BFD_RELOC_M32R_RELATIVE,
BFD_RELOC_M32R_GOTOFF,
+ BFD_RELOC_M32R_GOTOFF_HI_ULO,
+ BFD_RELOC_M32R_GOTOFF_HI_SLO,
+ BFD_RELOC_M32R_GOTOFF_LO,
BFD_RELOC_M32R_GOTPC24,
BFD_RELOC_M32R_GOT16_HI_ULO,
BFD_RELOC_M32R_GOT16_HI_SLO,
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
index 14aec619ef3..c6bc2bee843 100644
--- a/bfd/elf32-m32r.c
+++ b/bfd/elf32-m32r.c
@@ -669,7 +669,7 @@ static reloc_howto_type m32r_elf_howto_table[] =
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_M32R_RELATIVE", /* name */
+ "R_M32R_RELATIVE", /* name */
FALSE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
@@ -678,15 +678,15 @@ static reloc_howto_type m32r_elf_howto_table[] =
HOWTO (R_M32R_GOTOFF, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
+ 24, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_M32R_GOTOFF", /* name */
+ "R_M32R_GOTOFF", /* name */
FALSE, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
FALSE), /* pcrel_offset */
/* An PC Relative 24-bit relocation used when setting PIC offset
@@ -803,6 +803,48 @@ static reloc_howto_type m32r_elf_howto_table[] =
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
TRUE), /* pcrel_offset */
+
+ HOWTO (R_M32R_GOTOFF_HI_ULO, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTOFF_HI_ULO",/* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32R_GOTOFF_HI_SLO, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTOFF_HI_SLO",/* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32R_GOTOFF_LO, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTOFF_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
};
/* Handle the R_M32R_10_PCREL reloc. */
@@ -1269,6 +1311,9 @@ static const struct m32r_reloc_map m32r_reloc_map[] =
{ BFD_RELOC_M32R_GOTPC_HI_ULO, R_M32R_GOTPC_HI_ULO },
{ BFD_RELOC_M32R_GOTPC_HI_SLO, R_M32R_GOTPC_HI_SLO },
{ BFD_RELOC_M32R_GOTPC_LO, R_M32R_GOTPC_LO },
+ { BFD_RELOC_M32R_GOTOFF_HI_ULO, R_M32R_GOTOFF_HI_ULO },
+ { BFD_RELOC_M32R_GOTOFF_HI_SLO, R_M32R_GOTOFF_HI_SLO },
+ { BFD_RELOC_M32R_GOTOFF_LO, R_M32R_GOTOFF_LO },
};
static reloc_howto_type *
@@ -2796,6 +2841,31 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
switch ((int) r_type)
{
+ case R_M32R_GOTOFF:
+ /* Relocation is relative to the start of the global offset
+ table (for ld24 rx, #uimm24). eg 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_GOTOFF_HI_ULO:
+ case R_M32R_GOTOFF_HI_SLO:
+ case R_M32R_GOTOFF_LO:
+ BFD_ASSERT (sgot != NULL);
+
+ relocation -= sgot->output_section->vma;
+
+ if ((r_type == R_M32R_GOTOFF_HI_SLO)
+ && ((relocation + rel->r_addend) & 0x8000))
+ rel->r_addend += 0x10000;
+ break;
+
case R_M32R_GOTPC24:
/* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
ld24 rx,#_GLOBAL_OFFSET_TABLE_
@@ -4306,6 +4376,10 @@ m32r_elf_gc_sweep_hook (abfd, info, sec, relocs)
case R_M32R_GOT16_HI_ULO:
case R_M32R_GOT16_HI_SLO:
case R_M32R_GOT16_LO:
+ case R_M32R_GOTOFF:
+ case R_M32R_GOTOFF_HI_ULO:
+ case R_M32R_GOTOFF_HI_SLO:
+ case R_M32R_GOTOFF_LO:
case R_M32R_GOT24:
case R_M32R_GOTPC_HI_ULO:
case R_M32R_GOTPC_HI_SLO:
@@ -4435,6 +4509,10 @@ m32r_elf_check_relocs (abfd, info, sec, relocs)
{
case R_M32R_GOT16_HI_ULO:
case R_M32R_GOT16_HI_SLO:
+ case R_M32R_GOTOFF:
+ case R_M32R_GOTOFF_HI_ULO:
+ case R_M32R_GOTOFF_HI_SLO:
+ case R_M32R_GOTOFF_LO:
case R_M32R_GOT16_LO:
case R_M32R_GOTPC24:
case R_M32R_GOTPC_HI_ULO:
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index c17c4f3f83c..2e3be87b151 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1222,6 +1222,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_M32R_JMP_SLOT",
"BFD_RELOC_M32R_RELATIVE",
"BFD_RELOC_M32R_GOTOFF",
+ "BFD_RELOC_M32R_GOTOFF_HI_ULO",
+ "BFD_RELOC_M32R_GOTOFF_HI_SLO",
+ "BFD_RELOC_M32R_GOTOFF_LO",
"BFD_RELOC_M32R_GOTPC24",
"BFD_RELOC_M32R_GOT16_HI_ULO",
"BFD_RELOC_M32R_GOT16_HI_SLO",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 12cbb7ad396..df50af47a7a 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2955,6 +2955,12 @@ ENUMX
ENUMX
BFD_RELOC_M32R_GOTOFF
ENUMX
+ BFD_RELOC_M32R_GOTOFF_HI_ULO
+ENUMX
+ BFD_RELOC_M32R_GOTOFF_HI_SLO
+ENUMX
+ BFD_RELOC_M32R_GOTOFF_LO
+ENUMX
BFD_RELOC_M32R_GOTPC24
ENUMX
BFD_RELOC_M32R_GOT16_HI_ULO
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 523134a7cde..6cedeed2252 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,18 @@
+2004-06-25 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.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): Likewise.
+ (m32r_end_of_match): Add for @GOTOFF, @GOT, @PLT.
+ (m32r_parse_name): Likewise.
+ (m32r_cgen_parse_fix_exp): Likewise.
+ * config/tc-m32r.h (md_parse_name): Define for @GOTOFF, @GOT, @PLT.
+ (O_PIC_reloc): Likewise.
+ (TC_CGEN_PARSE_FIX_EXP): Likewise..
+ * cgen.c (gas_cgen_parse_operand): Add TC_CGEN_PARSE_FIX_EXP
+ for @GOTOFF, @GOT, @PLT.
+
2004-06-21 Jan Beulich <jbeulich@novell.com>
* gas/symbols.c: While discarding ordinary local absolute symbols
diff --git a/gas/cgen.c b/gas/cgen.c
index 5ce7f4c99ec..384618ef8cd 100644
--- a/gas/cgen.c
+++ b/gas/cgen.c
@@ -1,5 +1,5 @@
/* GAS interface for targets using CGEN: Cpu tools GENerator.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -355,6 +355,10 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
*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)
diff --git a/gas/config/tc-m32r.c b/gas/config/tc-m32r.c
index e990d9d941c..207ac019433 100644
--- a/gas/config/tc-m32r.c
+++ b/gas/config/tc-m32r.c
@@ -489,6 +489,69 @@ const pseudo_typeS md_pseudo_table[] =
{ 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,23 +1951,28 @@ md_convert_frag (abfd, sec, fragP)
|| 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);
- gas_cgen_record_fixup (fragP,
- /* Offset of branch insn in frag. */
- fragP->fr_fix + extension - 4,
- fragP->fr_cgen.insn,
- 4 /* Length. */,
- /* FIXME: quick hack. */
+
+ fixP = gas_cgen_record_fixup (fragP,
+ /* Offset of branch insn in frag. */
+ fragP->fr_fix + extension - 4,
+ fragP->fr_cgen.insn,
+ 4 /* Length. */,
+ /* FIXME: quick hack. */
#if 0
- cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
- fragP->fr_cgen.opindex),
+ cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
+ fragP->fr_cgen.opindex),
#else
- cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
- M32R_OPERAND_DISP24),
+ cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
+ M32R_OPERAND_DISP24),
#endif
- fragP->fr_cgen.opinfo,
- fragP->fr_symbol, fragP->fr_offset);
+ 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,8 +2074,14 @@ m32r_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
int opinfo;
expressionS *exp;
{
- fixS *fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
- operand, opinfo, 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)
{
@@ -2017,11 +2091,49 @@ m32r_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
|| fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)
m32r_record_hi16 (fixP->fx_cgen.opinfo, fixP, now_seg);
break;
+
default:
- /* Avoid -Wall warning */
+ /* Avoid -Wall warning. */
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:
+ if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_SLO)
+ r_type = BFD_RELOC_M32R_GOTOFF_HI_SLO;
+ else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)
+ r_type = BFD_RELOC_M32R_GOTOFF_HI_ULO;
+ else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_LO16)
+ r_type = BFD_RELOC_M32R_GOTOFF_LO;
+ break;
+ case BFD_RELOC_M32R_26_PLTREL:
+ as_bad (_("Invalid PIC expression."));
+ break;
+ }
+
+ fixP->fx_r_type = r_type;
+
return fixP;
}
@@ -2261,6 +2373,16 @@ m32r_fix_adjustable (fixP)
|| 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)
@@ -2270,17 +2392,16 @@ m32r_fix_adjustable (fixP)
}
void
-m32r_elf_final_processing ()
+m32r_elf_final_processing (void)
{
if (use_parallel)
m32r_flags |= E_M32R_HAS_PARALLEL;
elf_elfheader (stdoutput)->e_flags |= m32r_flags;
}
-#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
-
/* Translate internal representation of relocation info to BFD target
format. */
+
arelent *
tc_gen_reloc (section, fixP)
asection * section;
@@ -2354,21 +2475,124 @@ printf(" => %s\n",reloc->howto->name);
return NULL;
}
- /* Use fx_offset for these cases */
+ /* Use fx_offset for these cases. */
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
+ else if ((!pic_code
+ && code != BFD_RELOC_M32R_26_PLTREL)
&& fixP->fx_pcrel
&& fixP->fx_addsy != NULL
&& (S_GET_SEGMENT(fixP->fx_addsy) != section)
&& S_IS_DEFINED (fixP->fx_addsy)
&& ! S_IS_EXTERNAL(fixP->fx_addsy)
&& ! S_IS_WEAK(fixP->fx_addsy))
- /* already used fx_offset in the opcode field itseld. */
+ /* Already used fx_offset in the opcode field itseld. */
reloc->addend = 0;
else
reloc->addend = fixP->fx_addnumber;
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;
+}
diff --git a/gas/config/tc-m32r.h b/gas/config/tc-m32r.h
index 47692146418..7fb73ec6df7 100644
--- a/gas/config/tc-m32r.h
+++ b/gas/config/tc-m32r.h
@@ -1,5 +1,5 @@
/* tc-m32r.h -- Header file for tc-m32r.c.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -131,3 +131,15 @@ extern void m32r_flush_pending_output PARAMS ((void));
#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))
+extern int m32r_parse_name (char const *, expressionS *, char *);
+
+/* 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)
+extern int m32r_cgen_parse_fix_exp(int, expressionS *);
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index 1783b5b6928..9873532801e 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -1,3 +1,8 @@
+2004-06-25 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * m32r.h: Add defintions of R_M32R_GOTOFF_HI_ULO,
+ R_M32R_GOTOFF_HI_SLO and R_M32R_GOTOFF_LO.
+
2004-06-19 Alan Modra <amodra@bigpond.net.au>
* common.h (ELF64_R_INFO): Warning fix.
diff --git a/include/elf/m32r.h b/include/elf/m32r.h
index 709d7923446..6441efe27e8 100644
--- a/include/elf/m32r.h
+++ b/include/elf/m32r.h
@@ -1,5 +1,5 @@
/* M32R ELF support for BFD.
- Copyright 1996, 1997, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -67,6 +67,9 @@ START_RELOC_NUMBERS (elf_m32r_reloc_type)
RELOC_NUMBER (R_M32R_GOTPC_HI_ULO, 59)
RELOC_NUMBER (R_M32R_GOTPC_HI_SLO, 60)
RELOC_NUMBER (R_M32R_GOTPC_LO, 61)
+ RELOC_NUMBER (R_M32R_GOTOFF_HI_ULO, 62)
+ RELOC_NUMBER (R_M32R_GOTOFF_HI_SLO, 63)
+ RELOC_NUMBER (R_M32R_GOTOFF_LO, 64)
END_RELOC_NUMBERS (R_M32R_max)
/* Processor specific section indices. These sections do not actually