From 1ac4baededff2d76a62f27ae00467ff87f56d674 Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Sun, 26 Mar 2006 01:12:07 +0000 Subject: [PATCH] * 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 . (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 | 25 ++++++ gas/Makefile.am | 12 ++- gas/Makefile.in | 12 ++- gas/config/bfin-defs.h | 1 + gas/config/bfin-lex.l | 2 + gas/config/bfin-parse.y | 26 ++++-- gas/config/tc-bfin.c | 192 +++++++++++++++++++++++++++++----------- 7 files changed, 207 insertions(+), 63 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index b12c4400f5f..b83b26f4b53 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,28 @@ +2006-03-25 Bernd Schmidt + + * 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 . + (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 * config/tc-m68k.c (m68k_cpus): Change cpu_cf5208 entries to use diff --git a/gas/Makefile.am b/gas/Makefile.am index 4cd7e2695da..525ebbbcb7e 100644 --- a/gas/Makefile.am +++ b/gas/Makefile.am @@ -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 \ diff --git a/gas/Makefile.in b/gas/Makefile.in index 9dde01c8ca9..fc2b9b467ac 100644 --- a/gas/Makefile.in +++ b/gas/Makefile.in @@ -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 diff --git a/gas/config/bfin-defs.h b/gas/config/bfin-defs.h index 46ae61e2912..48bacb3ed7d 100644 --- a/gas/config/bfin-defs.h +++ b/gas/config/bfin-defs.h @@ -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; diff --git a/gas/config/bfin-lex.l b/gas/config/bfin-lex.l index c3af8420265..3a0077cd985 100644 --- a/gas/config/bfin-lex.l +++ b/gas/config/bfin-lex.l @@ -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; diff --git a/gas/config/bfin-parse.y b/gas/config/bfin-parse.y index f1e488768c9..917c2d27ba0 100644 --- a/gas/config/bfin-parse.y +++ b/gas/config/bfin-parse.y @@ -21,10 +21,14 @@ %{ #include -#include "bfin-aux.h" #include #include +#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 asm @@ -544,7 +549,7 @@ is_group2 (INSTR_T x) %type got %type got_or_expr %type pltpc - +%type 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); } ; diff --git a/gas/config/tc-bfin.c b/gas/config/tc-bfin.c index d9e88de19d5..43d48d624ea 100644 --- a/gas/config/tc-bfin.c +++ b/gas/config/tc-bfin.c @@ -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 (); - } } -- 2.30.2