Add support for M32R GOT relocs
authorNick Clifton <nickc@redhat.com>
Fri, 25 Jun 2004 16:11:09 +0000 (16:11 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 25 Jun 2004 16:11:09 +0000 (16:11 +0000)
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-m32r.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/cgen.c
gas/config/tc-m32r.c
gas/config/tc-m32r.h
include/elf/ChangeLog
include/elf/m32r.h

index 7aebb9f0deaad691dffa4549266583e4f7fa80d2..830c32e198f87e9c0a53ba7ad8693cbbd1630ecd 100644 (file)
@@ -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
index 5001cf87b510eec32efb362c33344937d2898245..3b9d78cf937a0e4384e70f422178df626aac6bfb 100644 (file)
@@ -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,
index 14aec619ef3cc39e34edb71cf1af957435df4e3c..c6bc2bee843487af5c45fbceb96fd9a6c77caf67 100644 (file)
@@ -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 */
 };
 \f
 /* 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:
index c17c4f3f83c92a65e9b0a932d3000d8c21621503..2e3be87b151c5fed782b4d59bcc0d3581a13fa1e 100644 (file)
@@ -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",
index 12cbb7ad396b3911b0024db729af3045e20d0b69..df50af47a7af9e012f16b8bdfa86b99a5c763bda 100644 (file)
@@ -2954,6 +2954,12 @@ ENUMX
   BFD_RELOC_M32R_RELATIVE
 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
index 523134a7cdecba182db8bec71ca0be5aeb2fd9df..6cedeed2252fa571685094cc0a6ed5222210646c 100644 (file)
@@ -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
index 5ce7f4c99ecba6c155913414f8c36a95b8b99f88..384618ef8cd95f5d8cc25c41d57c9908ac79c208 100644 (file)
@@ -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)
index e990d9d941c691bb8a52af5a715b0b71c9eac8c0..207ac0194335843729c1c9db5ccbade3295bf098 100644 (file)
@@ -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;
+}
index 4769214641805f52e6f84b2e28dee243138a34f7..7fb73ec6df727affb22b2ac63b241e3a5cf6b7c6 100644 (file)
@@ -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 *);
index 1783b5b69286a7fcce58b90384c057529254c93b..9873532801e556a02bc21548ab133ab05b92592a 100644 (file)
@@ -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.
index 709d7923446105e2d1d12d304dbf8d1ca82b9443..6441efe27e87f4e1a40b0de190a0d1e9c5313088 100644 (file)
@@ -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