2011-06-28 Tristan Gingold <gingold@adacore.com>
[deliverable/binutils-gdb.git] / gas / config / tc-alpha.c
index 620f9749a687caca26553a96114578c2205d61fd..9523adaaba67605a638658cde0d0be50e386896b 100644 (file)
@@ -1,6 +1,6 @@
 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
    Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Carnegie Mellon University, 1993.
    Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
@@ -86,7 +86,11 @@ struct alpha_fixup
   /* bfd_reloc_code_real_type reloc; */
   extended_bfd_reloc_code_real_type reloc;
 #ifdef OBJ_EVAX
-  symbolS *xtrasym, *procsym;
+  /* The symbol of the item in the linkage section.  */
+  symbolS *xtrasym;
+
+  /* The symbol of the procedure descriptor.  */
+  symbolS *procsym;
 #endif
 };
 
@@ -289,8 +293,6 @@ size_t md_longopts_size = sizeof (md_longopts);
 #undef AXP_REG_GP
 #define AXP_REG_GP AXP_REG_PV
 
-static struct hash_control *alpha_evax_proc_hash;
-
 #endif /* OBJ_EVAX  */
 
 /* The cpu for which we are generating code.  */
@@ -419,10 +421,13 @@ struct alpha_evax_procs
   int handler_data;
 };
 
+/* Linked list of .linkage fixups.  */
 struct alpha_linkage_fixups *alpha_linkage_fixup_root;
 static struct alpha_linkage_fixups *alpha_linkage_fixup_tail;
 
+/* Current procedure descriptor.  */
 static struct alpha_evax_procs *alpha_evax_proc;
+static struct alpha_evax_procs alpha_evax_proc_data;
 
 static int alpha_flag_hash_long_names = 0;             /* -+ */
 static int alpha_flag_show_after_trunc = 0;            /* -H */
@@ -495,8 +500,8 @@ struct alpha_reloc_tag
 {
   fixS *master;                        /* The literal reloc.  */
 #ifdef OBJ_EVAX
-  struct symbol *sym;
-  struct symbol *psym;
+  struct symbol *sym;          /* Linkage section item symbol.  */
+  struct symbol *psym;         /* Pdesc symbol.  */
 #endif
   fixS *slaves;                        /* Head of linked list of lituses.  */
   segT segment;                        /* Segment relocs are in or undefined_section.  */
@@ -576,7 +581,7 @@ static void emit_insn (struct alpha_insn *);
 static void assemble_tokens (const char *, const expressionS *, int, int);
 #ifdef OBJ_EVAX
 static char *s_alpha_section_name (void);
-static symbolS *add_to_link_pool (symbolS *, symbolS *, offsetT);
+static symbolS *add_to_link_pool (symbolS *, offsetT);
 #endif
 \f
 static struct alpha_reloc_tag *
@@ -1333,21 +1338,20 @@ load_expression (int targreg,
 
        if (exp->X_add_symbol == alpha_evax_proc->symbol)
          {
+            /* Linkage-relative expression.  */
+            set_tok_reg (newtok[0], targreg);
+
            if (range_signed_16 (addend))
              {
-               set_tok_reg (newtok[0], targreg);
                set_tok_const (newtok[1], addend);
-               set_tok_preg (newtok[2], basereg);
-               assemble_tokens_to_insn ("lda", newtok, 3, &insn);
                addend = 0;
              }
            else
              {
-               set_tok_reg (newtok[0], targreg);
                set_tok_const (newtok[1], 0);
-               set_tok_preg (newtok[2], basereg);
-               assemble_tokens_to_insn ("lda", newtok, 3, &insn);
              }
+            set_tok_preg (newtok[2], basereg);
+            assemble_tokens_to_insn ("lda", newtok, 3, &insn);
          }
        else
          {
@@ -1358,6 +1362,8 @@ load_expression (int targreg,
            if ((symlen > 4 &&
                 strcmp (ptr2 = &symname [symlen - 4], "..lk") == 0))
              {
+                /* Access to an item whose address is stored in the linkage
+                   section.  Just read the address.  */
                set_tok_reg (newtok[0], targreg);
 
                newtok[1] = *exp;
@@ -1373,14 +1379,15 @@ load_expression (int targreg,
 
                if (alpha_flag_replace && targreg == 26)
                  {
+                    /* Add a NOP fixup for 'ldX $26,YYY..NAME..lk'.  */
                    char *ensymname;
                    symbolS *ensym;
-                   volatile asymbol *dummy;
 
+                    /* Build the entry name as 'NAME..en'.  */
                    ptr1 = strstr (symname, "..") + 2;
                    if (ptr1 > ptr2)
                      ptr1 = symname;
-                   ensymname = (char *) xmalloc (ptr2 - ptr1 + 5);
+                   ensymname = (char *) alloca (ptr2 - ptr1 + 5);
                    memcpy (ensymname, ptr1, ptr2 - ptr1);
                    memcpy (ensymname + (ptr2 - ptr1), "..en", 5);
 
@@ -1400,19 +1407,22 @@ load_expression (int targreg,
 
                    /* ??? Force bsym to be instantiated now, as it will be
                       too late to do so in tc_gen_reloc.  */
-                   dummy = symbol_get_bfdsym (exp->X_add_symbol);
+                   symbol_get_bfdsym (exp->X_add_symbol);
                  }
                else if (alpha_flag_replace && targreg == 27)
                  {
+                    /* Add a lda fixup for 'ldX $27,YYY.NAME..lk+8'.  */
                    char *psymname;
                    symbolS *psym;
 
+                    /* Extract NAME.  */
                    ptr1 = strstr (symname, "..") + 2;
                    if (ptr1 > ptr2)
                      ptr1 = symname;
-                   psymname = (char *) xmalloc (ptr2 - ptr1 + 1);
+                   psymname = (char *) alloca (ptr2 - ptr1 + 1);
                    memcpy (psymname, ptr1, ptr2 - ptr1);
                    psymname [ptr2 - ptr1] = 0;
+
                    gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
                    insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_LDA;
                    psym = symbol_find_or_make (psymname);
@@ -1426,17 +1436,18 @@ load_expression (int targreg,
                    insn.nfixups++;
                  }
 
-               emit_insn(&insn);
+               emit_insn (&insn);
                return 0;
              }
            else
              {
+                /* Not in the linkage section.  Put the value into the linkage
+                   section.  */
                symbolS *linkexp;
 
                if (!range_signed_32 (addend))
                  addend = sign_extend_32 (addend);
-               linkexp = add_to_link_pool (alpha_evax_proc->symbol,
-                                           exp->X_add_symbol, 0);
+               linkexp = add_to_link_pool (exp->X_add_symbol, 0);
                set_tok_reg (newtok[0], targreg);
                set_tok_sym (newtok[1], linkexp, 0);
                set_tok_preg (newtok[2], basereg);
@@ -1503,8 +1514,7 @@ load_expression (int targreg,
       /* For 64-bit addends, just put it in the literal pool.  */
 #ifdef OBJ_EVAX
       /* Emit "ldq targreg, lit(basereg)".  */
-      litexp = add_to_link_pool (alpha_evax_proc->symbol,
-                                section_symbol (absolute_section), addend);
+      litexp = add_to_link_pool (section_symbol (absolute_section), addend);
       set_tok_reg (newtok[0], targreg);
       set_tok_sym (newtok[1], litexp, 0);
       set_tok_preg (newtok[2], alpha_gp_register);
@@ -2868,11 +2878,13 @@ emit_jsrjmp (const expressionS *tok,
       && tok[tokidx].X_add_symbol
       && alpha_linkage_symbol)
     {
+      /* Create a BOH reloc for 'jsr $27,NAME'.  */
       const char *symname = S_GET_NAME (tok[tokidx].X_add_symbol);
       int symlen = strlen (symname);
       char *ensymname;
 
-      ensymname = (char *) xmalloc (symlen + 5);
+      /* Build the entry name as 'NAME..en'.  */
+      ensymname = (char *) alloca (symlen + 5);
       memcpy (ensymname, symname, symlen);
       memcpy (ensymname + symlen, "..en", 5);
 
@@ -2938,7 +2950,7 @@ emit_retjcr (const expressionS *tok,
 /* Implement the ldgp macro.  */
 
 static void
-emit_ldgp (const expressionS *tok,
+emit_ldgp (const expressionS *tok ATTRIBUTE_UNUSED,
           int ntok ATTRIBUTE_UNUSED,
           const void * unused ATTRIBUTE_UNUSED)
 {
@@ -2993,10 +3005,7 @@ FIXME
   insn.sequence = next_sequence_num--;
 
   emit_insn (&insn);
-#else /* OBJ_ECOFF || OBJ_ELF */
-  /* Avoid warning.  */
-  tok = NULL;
-#endif
+#endif /* OBJ_ECOFF || OBJ_ELF */
 }
 
 /* The macro table.  */
@@ -3360,26 +3369,24 @@ assemble_tokens (const char *opname,
 \f
 #ifdef OBJ_EVAX
 
-/* Add symbol+addend to link pool.
-   Return offset from basesym to entry in link pool.
+/* Add sym+addend to link pool.
+   Return offset from curent procedure value (pv) to entry in link pool.
 
    Add new fixup only if offset isn't 16bit.  */
 
 static symbolS *
-add_to_link_pool (symbolS *basesym,
-                 symbolS *sym,
-                 offsetT addend)
+add_to_link_pool (symbolS *sym, offsetT addend)
 {
+  symbolS *basesym;
   segT current_section = now_seg;
   int current_subsec = now_subseg;
-  valueT offset;
   char *p;
   segment_info_type *seginfo = seg_info (alpha_link_section);
   fixS *fixp;
   symbolS *linksym, *expsym;
   expressionS e;
   
-  offset = 0; /* ??? DBR */
+  basesym = alpha_evax_proc->symbol;
 
   /* @@ This assumes all entries in a given section will be of the same
      size...  Probably correct, but unwise to rely on.  */
@@ -3390,11 +3397,6 @@ add_to_link_pool (symbolS *basesym,
         fixp != (fixS *) NULL;
         fixp = fixp->fx_next)
       {
-       if (fixp->tc_fix_data.info
-           && fixp->tc_fix_data.info->sym
-           && fixp->tc_fix_data.info->sym->sy_value.X_op_symbol == basesym)
-         offset += 8;
-       
        if (fixp->fx_addsy == sym
            && fixp->fx_offset == (valueT)addend
            && fixp->tc_fix_data.info
@@ -3403,14 +3405,14 @@ add_to_link_pool (symbolS *basesym,
          return fixp->tc_fix_data.info->sym;
       }
 
-  /* Not found in 16bit signed range.  */
-
+  /* Not found, add a new entry.  */
   subseg_set (alpha_link_section, 0);
   linksym = symbol_new
     (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
   p = frag_more (8);
   memset (p, 0, 8);
 
+  /* Create the basesym - linksym expression (offset of the added entry).  */
   e.X_op = O_subtract;
   e.X_add_symbol = linksym;
   e.X_op_symbol = basesym;
@@ -3418,12 +3420,11 @@ add_to_link_pool (symbolS *basesym,
   expsym = make_expr_symbol (&e);
 
   fixp = fix_new
-    (frag_now, p-frag_now->fr_literal, 8, sym, addend, 0, BFD_RELOC_64);
+    (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0, BFD_RELOC_64);
   fixp->tc_fix_data.info = get_alpha_reloc_tag (next_sequence_num--);
   fixp->tc_fix_data.info->sym = expsym;
 
   subseg_set (current_section, current_subsec);
-  seginfo->literal_pool_size += 8;
   return expsym;
 }
 #endif /* OBJ_EVAX */
@@ -3641,9 +3642,7 @@ s_alpha_comm (int ignore ATTRIBUTE_UNUSED)
 static void
 s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
 {
-  int temp;
-
-  temp = get_absolute_expression ();
+  get_absolute_expression ();
   subseg_new (".rdata", 0);
   demand_empty_rest_of_line ();
   alpha_insn_label = NULL;
@@ -3661,9 +3660,7 @@ s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
 static void
 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
 {
-  int temp;
-
-  temp = get_absolute_expression ();
+  get_absolute_expression ();
   subseg_new (".sdata", 0);
   demand_empty_rest_of_line ();
   alpha_insn_label = NULL;
@@ -4286,7 +4283,6 @@ static char *section_name[EVAX_SECTION_COUNT + 1] =
 static void
 s_alpha_section (int secid)
 {
-  int temp;
   char *name, *beg;
   segT sec;
   flagword vms_flags = 0;
@@ -4331,7 +4327,7 @@ s_alpha_section (int secid)
     }
   else
     {
-      temp = get_absolute_expression ();
+      get_absolute_expression ();
       subseg_new (section_name[secid], 0);
     }
 
@@ -4359,8 +4355,10 @@ s_alpha_ent (int ignore ATTRIBUTE_UNUSED)
   symbolS *symbol;
   expressionS symexpr;
 
-  alpha_evax_proc
-    = (struct alpha_evax_procs *) xmalloc (sizeof (struct alpha_evax_procs));
+  if (alpha_evax_proc != NULL)
+    as_bad (_("previous .ent not closed by a .end"));
+
+  alpha_evax_proc = &alpha_evax_proc_data;
 
   alpha_evax_proc->pdsckind = 0;
   alpha_evax_proc->framereg = -1;
@@ -4388,10 +4386,6 @@ s_alpha_ent (int ignore ATTRIBUTE_UNUSED)
   symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
   alpha_evax_proc->symbol = symbol;
 
-  (void) hash_insert
-    (alpha_evax_proc_hash,
-     symbol_get_bfdsym (alpha_evax_proc->symbol)->name, (PTR)alpha_evax_proc);
-
   demand_empty_rest_of_line ();
 }
 
@@ -4457,17 +4451,20 @@ s_alpha_frame (int ignore ATTRIBUTE_UNUSED)
   alpha_evax_proc->rsa_offset = get_absolute_expression ();
 }
 
+/* Parse .prologue.  */
+
 static void
 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
 {
-  int arg;
-
-  arg = get_absolute_expression ();
+  get_absolute_expression ();
   demand_empty_rest_of_line ();
   alpha_prologue_label = symbol_new
     (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
 }
 
+/* Parse .pdesc <entry_name>.
+   Insert a procedure descriptor.  */
+
 static void
 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
 {
@@ -4476,49 +4473,48 @@ s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
   register char *p;
   expressionS exp;
   symbolS *entry_sym;
-  fixS *fixp;
-  segment_info_type *seginfo = seg_info (alpha_link_section);
   const char *entry_sym_name;
-  char *sym_name;
-  int len;
+  const char *pdesc_sym_name;
+  fixS *fixp;
+  size_t len;
 
   if (now_seg != alpha_link_section)
     {
       as_bad (_(".pdesc directive not in link (.link) section"));
-      demand_empty_rest_of_line ();
       return;
     }
 
   expression (&exp);
   if (exp.X_op != O_symbol)
     {
-      as_warn (_(".pdesc directive has no entry symbol"));
-      demand_empty_rest_of_line ();
+      as_bad (_(".pdesc directive has no entry symbol"));
       return;
     }
   
   entry_sym = make_expr_symbol (&exp);
-  entry_sym_name = symbol_get_bfdsym (entry_sym)->name;
+  entry_sym_name = S_GET_NAME (entry_sym);
  
+  /* Strip "..en".  */
   len = strlen (entry_sym_name);
-  sym_name = (char *) xmalloc (len - 4 + 1);
-  strncpy (sym_name, entry_sym_name, len - 4);
-  sym_name [len - 4] = 0;
-  
-  alpha_evax_proc = (struct alpha_evax_procs *)
-    hash_find (alpha_evax_proc_hash, sym_name);
-  if (!alpha_evax_proc || !S_IS_DEFINED (alpha_evax_proc->symbol))
+  if (len < 4 || strcmp (entry_sym_name + len - 4, "..en") != 0)
     {
-      as_fatal (_(".pdesc has no matching .ent"));
-      demand_empty_rest_of_line ();
+      as_bad (_(".pdesc has a bad entry symbol"));
       return;
     }
+  len -= 4;
+  pdesc_sym_name = S_GET_NAME (alpha_evax_proc->symbol);
 
-  *symbol_get_obj (alpha_evax_proc->symbol) =
-    (valueT) seginfo->literal_pool_size;
+  if (!alpha_evax_proc
+      || !S_IS_DEFINED (alpha_evax_proc->symbol)
+      || strlen (pdesc_sym_name) != len
+      || memcmp (entry_sym_name, pdesc_sym_name, len) != 0)
+    {
+      as_fatal (_(".pdesc doesn't match with last .ent"));
+      return;
+    }
 
-  alpha_evax_proc->symbol->sy_obj = (valueT)seginfo->literal_pool_size;
+  /* Define pdesc symbol.  */
+  symbol_set_value_now (alpha_evax_proc->symbol);
  
   /* Save bfd symbol of proc entry in function symbol.  */
   ((struct evax_private_udata_struct *)
@@ -4564,7 +4560,6 @@ s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
   p = frag_more (16);
   fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
   fixp->fx_done = 1;
-  seginfo->literal_pool_size += 16;
 
   *p = alpha_evax_proc->pdsckind
     | ((alpha_evax_proc->framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0)
@@ -4595,20 +4590,15 @@ s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
   /* Signature offset.  */
   md_number_to_chars (p + 6, (valueT) 0, 2);
 
-  fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
+  fix_new_exp (frag_now, p - frag_now->fr_literal + 8,
+               8, &exp, 0, BFD_RELOC_64);
 
   if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_NULL)
     return;
 
-  /* Add dummy fix to make add_to_link_pool work.  */
-  p = frag_more (6);
-  fixp = fix_new (frag_now, p - frag_now->fr_literal, 6, 0, 0, 0, 0);
-  fixp->fx_done = 1;
-  seginfo->literal_pool_size += 6;
-  
   /* pdesc+16: Size.  */
+  p = frag_more (6);
   md_number_to_chars (p, (valueT) alpha_evax_proc->framesize, 4);
-
   md_number_to_chars (p + 4, (valueT) 0, 2);
 
   /* Entry length.  */
@@ -4620,14 +4610,8 @@ s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
   if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_FP_REGISTER)
     return;
 
-  /* Add dummy fix to make add_to_link_pool work.  */
-  p = frag_more (8);
-  fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
-  fixp->fx_done = 1;
-  seginfo->literal_pool_size += 8;
-
   /* pdesc+24: register masks.  */
-
+  p = frag_more (8);
   md_number_to_chars (p, alpha_evax_proc->imask, 4);
   md_number_to_chars (p + 4, alpha_evax_proc->fmask, 4);
 
@@ -4640,11 +4624,7 @@ s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
 
   if (alpha_evax_proc->handler_data)
     {
-      /* Add dummy fix to make add_to_link_pool work.  */
       p = frag_more (8);
-      fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
-      fixp->fx_done = 1;
-      seginfo->literal_pool_size += 8;
       md_number_to_chars (p, alpha_evax_proc->handler_data, 8);
     }
 }
@@ -4656,7 +4636,6 @@ s_alpha_name (int ignore ATTRIBUTE_UNUSED)
 {
   char *p;
   expressionS exp;
-  segment_info_type *seginfo = seg_info (alpha_link_section);
 
   if (now_seg != alpha_link_section)
     {
@@ -4681,11 +4660,13 @@ s_alpha_name (int ignore ATTRIBUTE_UNUSED)
 
   frag_align (3, 0, 0);
   p = frag_more (8);
-  seginfo->literal_pool_size += 8;
 
   fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
 }
 
+/* Parse .linkage <symbol>.
+   Create a linkage pair relocation.  */
+
 static void
 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
 {
@@ -4738,6 +4719,9 @@ s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
+/* Parse .code_address <symbol>.
+   Create a code address relocation.  */
+
 static void
 s_alpha_code_address (int ignore ATTRIBUTE_UNUSED)
 {
@@ -4814,7 +4798,7 @@ s_alpha_end (int ignore ATTRIBUTE_UNUSED)
   c = get_symbol_end ();
   *input_line_pointer = c;
   demand_empty_rest_of_line ();
-  alpha_evax_proc = 0;
+  alpha_evax_proc = NULL;
 }
 
 static void
@@ -4963,6 +4947,7 @@ s_alpha_proc (int is_static ATTRIBUTE_UNUSED)
       temp = get_absolute_expression ();
     }
   /*  *symbol_get_obj (symbolP) = (signed char) temp; */
+  (void) symbolP;
   as_warn (_("unhandled: .proc %s,%d"), name, temp);
   demand_empty_rest_of_line ();
 }
@@ -5064,12 +5049,13 @@ s_alpha_align (int ignore ATTRIBUTE_UNUSED)
   if (align != 0)
     {
       alpha_auto_align_on = 1;
-      alpha_align (align, pfill, alpha_insn_label, 1);
+      alpha_align (align, pfill, NULL, 1);
     }
   else
     {
       alpha_auto_align_on = 0;
     }
+  alpha_insn_label = NULL;
 
   demand_empty_rest_of_line ();
 }
@@ -5347,7 +5333,7 @@ alpha_elf_section_letter (int letter, char **ptr_msg)
   if (letter == 's')
     return SHF_ALPHA_GPREL;
 
-  *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
+  *ptr_msg = _("bad .section directive: want a,s,w,x,M,S,G,T in string");
   return -1;
 }
 
@@ -5516,7 +5502,6 @@ md_begin (void)
 
 #ifdef OBJ_EVAX
   create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
-  alpha_evax_proc_hash = hash_new ();
 #endif
 
 #ifdef OBJ_ELF
@@ -6252,26 +6237,14 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
 
   gas_assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
 
+  reloc->addend = fixp->fx_offset;
+
 #ifdef OBJ_ECOFF
+  /* Fake out bfd_perform_relocation. sigh.  */
+  /* ??? Better would be to use the special_function hook.  */
   if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
-    /* Fake out bfd_perform_relocation. sigh.  */
     reloc->addend = -alpha_gp_value;
-  else
-#endif
-    {
-      reloc->addend = fixp->fx_offset;
-#ifdef OBJ_ELF
-      /* Ohhh, this is ugly.  The problem is that if this is a local global
-         symbol, the relocation will entirely be performed at link time, not
-         at assembly time.  bfd_perform_reloc doesn't know about this sort
-         of thing, and as a result we need to fake it out here.  */
-      if ((S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
-          || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
-          || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
-         && !S_IS_COMMON (fixp->fx_addsy))
-       reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
 #endif
-    }
 
 #ifdef OBJ_EVAX
   switch (fixp->fx_r_type)
@@ -6281,6 +6254,7 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
       int pname_len;
 
     case BFD_RELOC_ALPHA_LINKAGE:
+      /* Copy the linkage index.  */
       reloc->addend = fixp->fx_addnumber;
       break;
 
@@ -6296,11 +6270,14 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
       if (pname_len > 4 && strcmp (pname + pname_len - 4, "..en") == 0)
        {
          symbolS *sym;
-         char *my_pname = xstrdup (pname);
+         char *my_pname = (char *) alloca (pname_len - 4 + 1);
+
+         memcpy (my_pname, pname, pname_len - 4);
          my_pname [pname_len - 4] = 0;
          sym = symbol_find (my_pname);
          if (sym == NULL)
            abort ();
+
          while (symbol_equated_reloc_p (sym))
            {
              symbolS *n = symbol_get_value_expression (sym)->X_add_symbol;
This page took 0.031867 seconds and 4 git commands to generate.