OSDN Git Service

* config/bfin-defs.h (Expr_Node_Type enum): Add Expr_Node_GOT_Reloc.
authorbernds <bernds>
Sun, 26 Mar 2006 01:12:06 +0000 (01:12 +0000)
committerbernds <bernds>
Sun, 26 Mar 2006 01:12:06 +0000 (01:12 +0000)
* config/bfin-lex.l: Recognize GOT17M4 and FUNCDESC_GOT17M4.
* config/bfin-parse.y: Include "libbfd.h", "elf/common.h" and
"elf/bfin.h".
(GOT17M4, FUNCDESC_GOT17M4): New tokens of type <value>.
(any_gotrel): New rule.
(got): Use it, and create Expr_Node_GOT_Reloc nodes.
* config/tc-bfin.c: Include "libbfd.h", "elf/common.h" and
"elf/bfin.h".
(DEFAULT_FLAGS, bfin_flags, bfin_pic_flag): New.
(bfin_pic_ptr): New function.
(md_pseudo_table): Add it for ".picptr".
(OPTION_FDPIC): New macro.
(md_longopts): Add -mfdpic.
(md_parse_option): Handle it.
(md_begin): Set BFD flags.
(md_apply_fix3, bfin_fix_adjustable): Handle new relocs.
(bfin_gen_ldstidxi): Adjust to match the trees that the parser gives
us for GOT relocs.
* Makefile.am (bfin-parse.o): Update dependencies.
(DEPTC_bfin_elf): Likewise.
* Makefile.in: Regenerate.

gas/ChangeLog
gas/Makefile.am
gas/Makefile.in
gas/config/bfin-defs.h
gas/config/bfin-lex.l
gas/config/bfin-parse.y
gas/config/tc-bfin.c

index b12c440..b83b26f 100644 (file)
@@ -1,3 +1,28 @@
+2006-03-25  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+       * config/bfin-defs.h (Expr_Node_Type enum): Add Expr_Node_GOT_Reloc.
+       * config/bfin-lex.l: Recognize GOT17M4 and FUNCDESC_GOT17M4.
+       * config/bfin-parse.y: Include "libbfd.h", "elf/common.h" and
+       "elf/bfin.h".
+       (GOT17M4, FUNCDESC_GOT17M4): New tokens of type <value>.
+       (any_gotrel): New rule.
+       (got): Use it, and create Expr_Node_GOT_Reloc nodes.
+       * config/tc-bfin.c: Include "libbfd.h", "elf/common.h" and
+       "elf/bfin.h".
+       (DEFAULT_FLAGS, bfin_flags, bfin_pic_flag): New.
+       (bfin_pic_ptr): New function.
+       (md_pseudo_table): Add it for ".picptr".
+       (OPTION_FDPIC): New macro.
+       (md_longopts): Add -mfdpic.
+       (md_parse_option): Handle it.
+       (md_begin): Set BFD flags.
+       (md_apply_fix3, bfin_fix_adjustable): Handle new relocs.
+       (bfin_gen_ldstidxi): Adjust to match the trees that the parser gives
+       us for GOT relocs.
+       * Makefile.am (bfin-parse.o): Update dependencies.
+       (DEPTC_bfin_elf): Likewise.
+       * Makefile.in: Regenerate.
+
 2006-03-25  Richard Sandiford  <richard@codesourcery.com>
 
        * config/tc-m68k.c (m68k_cpus): Change cpu_cf5208 entries to use
index 4cd7e26..525ebbb 100644 (file)
@@ -613,7 +613,8 @@ $(srcdir)/config/m68k-parse.h: ; @true
 bfin-parse.c: $(srcdir)/config/bfin-parse.y
        $(SHELL) $(YLWRAP) $(srcdir)/config/bfin-parse.y y.tab.c bfin-parse.c y.tab.h bfin-parse.h -- $(YACCCOMPILE) -d ;
 bfin-parse.h: bfin-parse.c
-bfin-parse.o: bfin-parse.c bfin-parse.h $(srcdir)/config/bfin-defs.h
+bfin-parse.o: bfin-parse.c bfin-parse.h $(srcdir)/config/bfin-defs.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/bfin.h $(BFDDIR)/libbfd.h
 
 bfin-defs.h: ; @true
 $(srcdir)/config/bfin-defs.h: ; @true
@@ -1021,14 +1022,17 @@ DEPTC_bfin_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
   $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h struc-symbol.h \
   $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
   $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h dwarf2dbg.h \
-  $(srcdir)/config/bfin-defs.h $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h \
-  $(srcdir)/config/bfin-aux.h $(INCDIR)/opcode/bfin.h
+  $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h \
+  $(srcdir)/config/bfin-aux.h $(INCDIR)/opcode/bfin.h \
+  $(srcdir)/config/bfin-defs.h $(INCDIR)/elf/common.h \
+  $(INCDIR)/elf/bfin.h $(BFDDIR)/libbfd.h
 DEPTC_bfin_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
   $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-bfin.h \
   dwarf2dbg.h struc-symbol.h $(srcdir)/config/bfin-defs.h \
   $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h $(srcdir)/config/bfin-aux.h \
-  $(INCDIR)/opcode/bfin.h
+  $(INCDIR)/opcode/bfin.h $(srcdir)/config/bfin-defs.h $(INCDIR)/elf/common.h \
+  $(INCDIR)/elf/bfin.h $(BFDDIR)/libbfd.h
 DEPTC_cris_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
   $(srcdir)/config/tc-cris.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
   $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
index 9dde01c..fc2b9b4 100644 (file)
@@ -802,15 +802,18 @@ DEPTC_bfin_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
   $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h struc-symbol.h \
   $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h \
   $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h dwarf2dbg.h \
-  $(srcdir)/config/bfin-defs.h $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h \
-  $(srcdir)/config/bfin-aux.h $(INCDIR)/opcode/bfin.h
+  $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h \
+  $(srcdir)/config/bfin-aux.h $(INCDIR)/opcode/bfin.h \
+  $(srcdir)/config/bfin-defs.h $(INCDIR)/elf/common.h \
+  $(INCDIR)/elf/bfin.h $(BFDDIR)/libbfd.h
 
 DEPTC_bfin_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
   $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-bfin.h \
   dwarf2dbg.h struc-symbol.h $(srcdir)/config/bfin-defs.h \
   $(INCDIR)/obstack.h $(INCDIR)/safe-ctype.h $(srcdir)/config/bfin-aux.h \
-  $(INCDIR)/opcode/bfin.h
+  $(INCDIR)/opcode/bfin.h $(srcdir)/config/bfin-defs.h $(INCDIR)/elf/common.h \
+  $(INCDIR)/elf/bfin.h $(BFDDIR)/libbfd.h
 
 DEPTC_cris_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
   $(srcdir)/config/tc-cris.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
@@ -2966,7 +2969,8 @@ $(srcdir)/config/m68k-parse.h: ; @true
 bfin-parse.c: $(srcdir)/config/bfin-parse.y
        $(SHELL) $(YLWRAP) $(srcdir)/config/bfin-parse.y y.tab.c bfin-parse.c y.tab.h bfin-parse.h -- $(YACCCOMPILE) -d ;
 bfin-parse.h: bfin-parse.c
-bfin-parse.o: bfin-parse.c bfin-parse.h $(srcdir)/config/bfin-defs.h
+bfin-parse.o: bfin-parse.c bfin-parse.h $(srcdir)/config/bfin-defs.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/bfin.h $(BFDDIR)/libbfd.h
 
 bfin-defs.h: ; @true
 $(srcdir)/config/bfin-defs.h: ; @true
index 46ae61e..48bacb3 100644 (file)
@@ -263,6 +263,7 @@ typedef enum
   Expr_Node_Binop,             /* Binary operator.  */
   Expr_Node_Unop,              /* Unary operator.  */
   Expr_Node_Reloc,             /* Symbol to be relocated.  */
+  Expr_Node_GOT_Reloc,         /* Symbol to be relocated using the GOT.  */
   Expr_Node_Constant           /* Constant.  */
 } Expr_Node_Type;
 
index c3af842..3a0077c 100644 (file)
@@ -241,6 +241,8 @@ abort                                   return ABORT;
 [aA]0"."[wW]    _REG.regno = REG_A0w; return REG;
 [aA]0           _REG.regno = REG_A0;  return REG_A_DOUBLE_ZERO;
 [Gg][Oo][Tt]   return GOT;
+[Gg][Oo][Tt]"17"[Mm]"4" return GOT17M4;
+[Ff][Uu][Nn][Cc][Dd][Ee][Ss][Cc]"_"[Gg][Oo][Tt]"17"[Mm]"4" return FUNCDESC_GOT17M4;
 [Pp][Ll][Tt][Pp][Cc]   return PLTPC;
 
 
index f1e4887..917c2d2 100644 (file)
 %{
 
 #include <stdio.h>
-#include "bfin-aux.h"
 #include <stdarg.h>
 #include <obstack.h>
 
+#include "bfin-aux.h"  // opcode generating auxiliaries
+#include "libbfd.h"
+#include "elf/common.h"
+#include "elf/bfin.h"
+
 #define DSP32ALU(aopcde, HL, dst1, dst0, src0, src1, s, x, aop) \
        bfin_gen_dsp32alu (HL, aopcde, aop, s, x, dst0, dst1, src0, src1)
 
@@ -485,7 +489,8 @@ is_group2 (INSTR_T x)
 %token STATUS_REG
 %token MNOP
 %token SYMBOL NUMBER
-%token GOT AT PLTPC
+%token GOT GOT17M4 FUNCDESC_GOT17M4
+%token AT PLTPC
 
 /* Types.  */
 %type <instr> asm
@@ -544,7 +549,7 @@ is_group2 (INSTR_T x)
 %type <expr> got
 %type <expr> got_or_expr
 %type <expr> pltpc
-
+%type <value> any_gotrel GOT GOT17M4 FUNCDESC_GOT17M4
 
 /* Precedence rules.  */
 %left BAR
@@ -4111,9 +4116,20 @@ symbol: SYMBOL
        }
        ;
 
-got:   symbol AT GOT
+any_gotrel:
+       GOT
+       { $$ = BFD_RELOC_BFIN_GOT; }
+       | GOT17M4
+       { $$ = BFD_RELOC_BFIN_GOT17M4; }
+       | FUNCDESC_GOT17M4
+       { $$ = BFD_RELOC_BFIN_FUNCDESC_GOT17M4; }
+       ;
+
+got:   symbol AT any_gotrel
        {
-       $$ = $1;
+       Expr_Node_Value val;
+       val.i_value = $3;
+       $$ = Expr_Node_Create (Expr_Node_GOT_Reloc, val, $1, NULL);
        }
        ;
 
index d9e88de..43d48d6 100644 (file)
@@ -28,6 +28,9 @@
 #ifdef OBJ_ELF
 #include "dwarf2dbg.h"
 #endif
+#include "libbfd.h"
+#include "elf/common.h"
+#include "elf/bfin.h"
 
 extern int yyparse (void);
 struct yy_buffer_state;
@@ -45,6 +48,12 @@ int last_insn_size;
 extern struct obstack mempool;
 FILE *errorf;
 
+/* Flags to set in the elf header */
+#define DEFAULT_FLAGS 0
+
+static flagword bfin_flags = DEFAULT_FLAGS;
+static const char *bfin_pic_flag = (const char *)0;
+
 /* Registers list.  */
 struct bfin_reg_entry
 {
@@ -202,11 +211,73 @@ static const struct bfin_reg_entry bfin_reg_info[] = {
   {0, 0}
 };
 
+/* Blackfin specific function to handle FD-PIC pointer initializations.  */
+
+static void
+bfin_pic_ptr (int nbytes)
+{
+  expressionS exp;
+  char *p;
+
+  if (nbytes != 4)
+    abort ();
+
+#ifdef md_flush_pending_output
+  md_flush_pending_output ();
+#endif
+
+  if (is_it_end_of_statement ())
+    {
+      demand_empty_rest_of_line ();
+      return;
+    }
+
+#ifdef md_cons_align
+  md_cons_align (nbytes);
+#endif
+
+  do
+    {
+      bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
+      
+      if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
+       {
+         input_line_pointer += 9;
+         expression (&exp);
+         if (*input_line_pointer == ')')
+           input_line_pointer++;
+         else
+           as_bad ("missing ')'");
+       }
+      else
+       error ("missing funcdesc in picptr");
+
+      p = frag_more (4);
+      memset (p, 0, 4);
+      fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
+                  reloc_type);
+    }
+  while (*input_line_pointer++ == ',');
+
+  input_line_pointer--;                        /* Put terminator back into stream. */
+  demand_empty_rest_of_line ();
+}
+
+static void
+bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
+{
+  register int temp;
+
+  temp = get_absolute_expression ();
+  subseg_set (bss_section, (subsegT) temp);
+  demand_empty_rest_of_line ();
+}
 
 const pseudo_typeS md_pseudo_table[] = {
   {"align", s_align_bytes, 0},
   {"byte2", cons, 2},
   {"byte4", cons, 4},
+  {"picptr", bfin_pic_ptr, 4},
   {"code", obj_elf_section, 0},
   {"db", cons, 1},
   {"dd", cons, 4},
@@ -218,17 +289,6 @@ const pseudo_typeS md_pseudo_table[] = {
   {0, 0, 0}
 };
 
-static void
-bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
-{
-  register int temp;
-
-  temp = get_absolute_expression ();
-  subseg_set (bss_section, (subsegT) temp);
-  demand_empty_rest_of_line ();
-}
-
-
 /* Characters that are used to denote comments and line separators. */
 const char comment_chars[] = "";
 const char line_comment_chars[] = "#";
@@ -245,16 +305,32 @@ const char FLT_CHARS[] = "fFdDxX";
 /* Define bfin-specific command-line options (there are none). */
 const char *md_shortopts = "";
 
-struct option md_longopts[] = {
-  {NULL, no_argument, NULL, 0}
+#define OPTION_FDPIC           (OPTION_MD_BASE)
+
+struct option md_longopts[] =
+{
+  { "mfdpic",          no_argument,            NULL, OPTION_FDPIC         },
+  { NULL,              no_argument,            NULL, 0                 },
 };
+
 size_t md_longopts_size = sizeof (md_longopts);
 
 
 int
 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
 {
-  return 0;
+  switch (c)
+    {
+    default:
+      return 0;
+
+    case OPTION_FDPIC:
+      bfin_flags |= EF_BFIN_FDPIC;
+      bfin_pic_flag = "-mfdpic";
+      break;
+    }
+
+  return 1;
 }
 
 void
@@ -267,6 +343,10 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
 void
 md_begin ()
 {
+  /* Set the ELF flags if desired. */
+  if (bfin_flags)
+    bfd_set_private_flags (stdoutput, bfin_flags);
+
   /* Set the default machine type. */
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
     as_warn ("Could not set architecture and machine.");
@@ -476,6 +556,8 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
   switch (fixP->fx_r_type)
     {
     case BFD_RELOC_BFIN_GOT:
+    case BFD_RELOC_BFIN_GOT17M4:
+    case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
       fixP->fx_no_overflow = 1;
       newval = md_chars_to_number (where, 2);
       newval |= 0x0 & 0x7f;
@@ -579,6 +661,7 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
       md_number_to_chars (where, value, 2);
       break;
 
+    case BFD_RELOC_BFIN_FUNCDESC:
     case BFD_RELOC_VTABLE_INHERIT:
     case BFD_RELOC_VTABLE_ENTRY:
       fixP->fx_done = FALSE;
@@ -725,8 +808,10 @@ bfin_fix_adjustable (fixS *fixP)
   switch (fixP->fx_r_type)
     {     
   /* Adjust_reloc_syms doesn't know about the GOT.  */
-    case BFD_RELOC_BFIN_GOT :
-    case BFD_RELOC_BFIN_PLTPC :
+    case BFD_RELOC_BFIN_GOT:
+    case BFD_RELOC_BFIN_GOT17M4:
+    case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
+    case BFD_RELOC_BFIN_PLTPC:
   /* We need the symbol name for the VTABLE entries.  */
     case BFD_RELOC_VTABLE_INHERIT:
     case BFD_RELOC_VTABLE_ENTRY:
@@ -982,6 +1067,8 @@ Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
          break;
        case BFD_RELOC_16:
        case BFD_RELOC_BFIN_GOT:
+       case BFD_RELOC_BFIN_GOT17M4:
+       case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
          note1 = conscode (gencode (value), NULL_CODE);
          pcrel = 0;
          break;
@@ -1356,8 +1443,6 @@ bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int relo
 INSTR_T
 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
 {
-  int offset;
-  int value = 0;
   INIT (LDSTidxI);
 
   if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
@@ -1370,44 +1455,51 @@ bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffs
   ASSIGN_R (reg);
   ASSIGN (W);
   ASSIGN (sz);
-  switch (sz)
-    {
-    case 0:
-      value = EXPR_VALUE (poffset) >> 2;
-      break;
-    case 1:
-      value = EXPR_VALUE (poffset) >> 1;
-      break;
-    case 2:
-      value = EXPR_VALUE (poffset);
-      break;
-    }
-
 
   ASSIGN (Z);
 
-  offset = (value & 0xffff);
-  ASSIGN (offset);
-  /* TODO : test if you need to check this here.
-     The reloc case should automatically generate instruction
-     if constant.  */
-  if(poffset->type != Expr_Node_Constant){
-    /* A GOT relocation such as R0 = [P5 + symbol@GOT].
-       Distinguish between R0 = [P5 + symbol@GOT] and
-       P5 = [P5 + _current_shared_library_p5_offset_].  */
-    if(!strcmp(poffset->value.s_value, "_current_shared_library_p5_offset_")){
-      return  conscode (gencode (HI (c_code.opcode)),
-                       Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
+  if (poffset->type != Expr_Node_Constant)
+    {
+      /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
+      /* distinguish between R0 = [P5 + symbol@GOT] and
+        P5 = [P5 + _current_shared_library_p5_offset_]
+      */
+      if (poffset->type == Expr_Node_Reloc
+         && !strcmp (poffset->value.s_value,
+                     "_current_shared_library_p5_offset_"))
+       {
+         return  conscode (gencode (HI (c_code.opcode)),
+                           Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
+       }
+      else if (poffset->type != Expr_Node_GOT_Reloc)
+       abort ();
+
+      return conscode (gencode (HI (c_code.opcode)),
+                      Expr_Node_Gen_Reloc(poffset->Left_Child,
+                                          poffset->value.i_value));
     }
-    else
+  else
     {
-      return  conscode (gencode (HI (c_code.opcode)),
-                       Expr_Node_Gen_Reloc(poffset, BFD_RELOC_BFIN_GOT));
+      int value, offset;
+      switch (sz)
+       {                               // load/store access size
+       case 0:                 // 32 bit
+         value = EXPR_VALUE (poffset) >> 2;
+         break;
+       case 1:                 // 16 bit
+         value = EXPR_VALUE (poffset) >> 1;
+         break;
+       case 2:                 // 8 bit
+         value = EXPR_VALUE (poffset);
+         break;
+       default:
+         abort ();
+       }
+
+      offset = (value & 0xffff);
+      ASSIGN (offset);
+      return GEN_OPCODE32 ();
     }
-  }
-  else{
-    return GEN_OPCODE32 ();
-  }
 }