X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-alpha.c;h=f7656ec7ee253bb5ee71eb323b43cac0065b0f9c;hb=feb4bea70a297eb6316d1b0685bbbb8095b7fb29;hp=bc355b860a63c510bf0663f9805eb4a334ba4337;hpb=198f1251457bf99a3f3aec2d2db1977b99e6f519;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c index bc355b860a..f7656ec7ee 100644 --- a/gas/config/tc-alpha.c +++ b/gas/config/tc-alpha.c @@ -1,6 +1,5 @@ /* 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 Free Software Foundation, Inc. + Copyright (C) 1989-2016 Free Software Foundation, Inc. Contributed by Carnegie Mellon University, 1993. Written by Alessandro Forin, based on earlier gas-1.38 target CPU files. Modified by Ken Raeburn for gas-2.x and ECOFF support. @@ -61,6 +60,7 @@ #ifdef OBJ_EVAX #include "vms.h" +#include "vms/egps.h" #endif #include "dwarf2dbg.h" @@ -74,12 +74,21 @@ #define MAX_INSN_FIXUPS 2 #define MAX_INSN_ARGS 5 +/* Used since new relocation types are introduced in this + file (DUMMY_RELOC_LITUSE_*) */ +typedef int extended_bfd_reloc_code_real_type; + struct alpha_fixup { expressionS exp; - bfd_reloc_code_real_type reloc; + /* 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 }; @@ -232,7 +241,7 @@ const char EXP_CHARS[] = "eE"; /* Characters which mean that a number is a floating point constant, as in 0d1.0. */ /* XXX: Do all of these really get used on the alpha?? */ -char FLT_CHARS[] = "rRsSfFdDxXpP"; +const char FLT_CHARS[] = "rRsSfFdDxXpP"; #ifdef OBJ_EVAX const char *md_shortopts = "Fm:g+1h:HG:"; @@ -256,7 +265,7 @@ struct option md_longopts[] = #define OPTION_REPLACE (OPTION_RELAX + 1) #define OPTION_NOREPLACE (OPTION_REPLACE+1) { "replace", no_argument, NULL, OPTION_REPLACE }, - { "noreplace", no_argument, NULL, OPTION_NOREPLACE }, + { "noreplace", no_argument, NULL, OPTION_NOREPLACE }, #endif { NULL, no_argument, NULL, 0 } }; @@ -282,8 +291,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. */ @@ -355,7 +362,9 @@ static int alpha_addr32_on = 0; and the section happens to not be on an eight byte boundary, it will align both the symbol and the .quad to an eight byte boundary. */ static symbolS *alpha_insn_label; +#if defined(OBJ_ELF) || defined (OBJ_EVAX) static symbolS *alpha_prologue_label; +#endif #ifdef OBJ_EVAX /* Symbol associate with the current jsr instruction. */ @@ -410,10 +419,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 */ @@ -441,7 +453,7 @@ static const struct alpha_reloc_op_tag const char *name; /* String to lookup. */ size_t length; /* Size of the string. */ operatorT op; /* Which operator to use. */ - bfd_reloc_code_real_type reloc; /* Relocation before frob. */ + extended_bfd_reloc_code_real_type reloc; unsigned int require_seq : 1; /* Require a sequence number. */ unsigned int allow_seq : 1; /* Allow a sequence number. */ } @@ -486,8 +498,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. */ @@ -562,12 +574,12 @@ static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" }; static const char * const stX_op[] = { "stb", "stw", "stl", "stq" }; static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL }; -static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, bfd_reloc_code_real_type); +static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, extended_bfd_reloc_code_real_type); 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 const char *s_alpha_section_name (void); +static symbolS *add_to_link_pool (symbolS *, offsetT); #endif static struct alpha_reloc_tag * @@ -584,14 +596,15 @@ get_alpha_reloc_tag (long sequence) size_t len = strlen (buffer); const char *errmsg; - info = xcalloc (sizeof (struct alpha_reloc_tag) + len, 1); + info = (struct alpha_reloc_tag *) + xcalloc (sizeof (struct alpha_reloc_tag) + len, 1); info->segment = now_seg; info->sequence = sequence; strcpy (info->string, buffer); errmsg = hash_insert (alpha_literal_hash, info->string, (void *) info); if (errmsg) - as_fatal (errmsg); + as_fatal ("%s", errmsg); #ifdef OBJ_EVAX info->sym = 0; info->psym = 0; @@ -908,8 +921,7 @@ tokenize_arguments (char *str, ++input_line_pointer; SKIP_WHITESPACE (); - p = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&p); /* Parse !relocation_type. */ len = input_line_pointer - p; @@ -930,7 +942,7 @@ tokenize_arguments (char *str, } *input_line_pointer = c; - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); if (*input_line_pointer != '!') { if (r->require_seq) @@ -993,6 +1005,7 @@ tokenize_arguments (char *str, /* ... then fall through to plain expression. */ input_line_pointer = hold; } + /* Fall through. */ default: if (saw_arg && !saw_comma) @@ -1278,7 +1291,7 @@ load_expression (int targreg, assemble_tokens_to_insn ("ldq", newtok, 3, &insn); - assert (insn.nfixups == 1); + gas_assert (insn.nfixups == 1); insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL; insn.sequence = emit_lituse = next_sequence_num--; #endif /* OBJ_ECOFF */ @@ -1314,7 +1327,7 @@ load_expression (int targreg, assemble_tokens_to_insn ("ldq", newtok, 3, &insn); - assert (insn.nfixups == 1); + gas_assert (insn.nfixups == 1); insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL; insn.sequence = emit_lituse = next_sequence_num--; #endif /* OBJ_ELF */ @@ -1323,21 +1336,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 { @@ -1348,6 +1360,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; @@ -1363,21 +1377,23 @@ 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 = XNEWVEC (char, ptr2 - ptr1 + 5); memcpy (ensymname, ptr1, ptr2 - ptr1); memcpy (ensymname + (ptr2 - ptr1), "..en", 5); - assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS); + gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_NOP; ensym = symbol_find_or_make (ensymname); - ensym->sy_used = 1; + free (ensymname); + symbol_mark_used (ensym); /* The fixup must be the same as the BFD_RELOC_ALPHA_BOH case in emit_jsrjmp. See B.4.5.2 of the OpenVMS Linker Utility Manual. */ @@ -1390,23 +1406,25 @@ 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); - memcpy (psymname, ptr1, ptr2 - ptr1); - psymname [ptr2 - ptr1] = 0; - assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS); + psymname = xmemdup0 (ptr1, ptr2 - ptr1); + + gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_LDA; psym = symbol_find_or_make (psymname); - psym->sy_used = 1; + free (psymname); + symbol_mark_used (psym); insn.fixups[insn.nfixups].exp.X_op = O_subtract; insn.fixups[insn.nfixups].exp.X_add_symbol = psym; insn.fixups[insn.nfixups].exp.X_op_symbol = alpha_evax_proc->symbol; @@ -1416,17 +1434,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); @@ -1493,8 +1512,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); @@ -1542,7 +1560,7 @@ load_expression (int targreg, assemble_tokens_to_insn ("ldq", newtok, 3, &insn); - assert (insn.nfixups == 1); + gas_assert (insn.nfixups == 1); #ifdef OBJ_ECOFF insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL; #endif @@ -1560,7 +1578,7 @@ load_expression (int targreg, assemble_tokens_to_insn ("ldq", newtok, 3, &insn); - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; insn.fixups[insn.nfixups].exp.X_op = O_absent; insn.nfixups++; @@ -1761,9 +1779,10 @@ emit_insn (struct alpha_insn *insn) } else { - reloc_howto_type *reloc_howto - = bfd_reloc_type_lookup (stdoutput, fixup->reloc); - assert (reloc_howto); + reloc_howto_type *reloc_howto = + bfd_reloc_type_lookup (stdoutput, + (bfd_reloc_code_real_type) fixup->reloc); + gas_assert (reloc_howto); size = bfd_get_reloc_size (reloc_howto); @@ -1777,14 +1796,14 @@ emit_insn (struct alpha_insn *insn) break; #endif default: - assert (size >= 1 && size <= 4); + gas_assert (size >= 1 && size <= 4); } - + pcrel = reloc_howto->pc_relative; } fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size, - &fixup->exp, pcrel, fixup->reloc); + &fixup->exp, pcrel, (bfd_reloc_code_real_type) fixup->reloc); /* Turn off complaints that the addend is too large for some fixups, and copy in the sequence number for the explicit relocations. */ @@ -1955,7 +1974,7 @@ static unsigned insert_operand (unsigned insn, const struct alpha_operand *operand, offsetT val, - char *file, + const char *file, unsigned line) { if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW)) @@ -1974,7 +1993,7 @@ insert_operand (unsigned insn, } if (val < min || val > max) - as_warn_value_out_of_range (_("operand"), val, min, max, file, line); + as_bad_value_out_of_range (_("operand"), val, min, max, file, line); } if (operand->insert) @@ -1983,7 +2002,7 @@ insert_operand (unsigned insn, insn = (*operand->insert) (insn, val, &errmsg); if (errmsg) - as_warn (errmsg); + as_warn ("%s", errmsg); } else insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift); @@ -1999,7 +2018,7 @@ assemble_insn (const struct alpha_opcode *opcode, const expressionS *tok, int ntok, struct alpha_insn *insn, - bfd_reloc_code_real_type reloc) + extended_bfd_reloc_code_real_type reloc) { const struct alpha_operand *reloc_operand = NULL; const expressionS *reloc_exp = NULL; @@ -2058,7 +2077,7 @@ assemble_insn (const struct alpha_opcode *opcode, case O_constant: image = insert_operand (image, operand, t->X_add_number, NULL, 0); - assert (reloc_operand == NULL); + gas_assert (reloc_operand == NULL); reloc_operand = operand; reloc_exp = t; break; @@ -2088,7 +2107,7 @@ assemble_insn (const struct alpha_opcode *opcode, if (reloc == BFD_RELOC_UNUSED) reloc = operand->default_reloc; - assert (reloc_operand == NULL); + gas_assert (reloc_operand == NULL); reloc_operand = operand; reloc_exp = t; } @@ -2118,11 +2137,12 @@ assemble_insn (const struct alpha_opcode *opcode, /* If this is a real relocation (as opposed to a lituse hint), then the relocation width should match the operand width. - Take care of -MDISP in operand table. */ + Take care of -MDISP in operand table. */ else if (reloc < BFD_RELOC_UNUSED && reloc > 0) { reloc_howto_type *reloc_howto - = bfd_reloc_type_lookup (stdoutput, reloc); + = bfd_reloc_type_lookup (stdoutput, + (bfd_reloc_code_real_type) reloc); if (reloc_operand == NULL || reloc_howto->bitsize != reloc_operand->bits) { @@ -2165,12 +2185,12 @@ emit_ir_load (const expressionS *tok, basereg = tok[2].X_add_number; lituse = load_expression (tok[0].X_add_number, &tok[1], - &basereg, &newtok[1], opname); + &basereg, &newtok[1], (const char *) opname); if (basereg == alpha_gp_register && (symlen > 4 && strcmp (&symname [symlen - 4], "..lk") == 0)) return; - + newtok[0] = tok[0]; set_tok_preg (newtok[2], basereg); @@ -2178,7 +2198,7 @@ emit_ir_load (const expressionS *tok, if (lituse) { - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; insn.fixups[insn.nfixups].exp.X_op = O_absent; insn.nfixups++; @@ -2211,8 +2231,8 @@ emit_loadstore (const expressionS *tok, if (alpha_noat_on) as_bad (_("macro requires $at register while noat in effect")); - lituse = load_expression (AXP_REG_AT, &tok[1], - &basereg, &newtok[1], opname); + lituse = load_expression (AXP_REG_AT, &tok[1], + &basereg, &newtok[1], (const char *) opname); } else { @@ -2227,7 +2247,7 @@ emit_loadstore (const expressionS *tok, if (lituse) { - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; insn.fixups[insn.nfixups].exp.X_op = O_absent; insn.nfixups++; @@ -2273,7 +2293,7 @@ emit_ldXu (const expressionS *tok, if (lituse) { - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; insn.fixups[insn.nfixups].exp.X_op = O_absent; insn.nfixups++; @@ -2289,7 +2309,7 @@ emit_ldXu (const expressionS *tok, if (lituse) { - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; insn.fixups[insn.nfixups].exp.X_op = O_absent; insn.nfixups++; @@ -2425,7 +2445,7 @@ emit_stX (const expressionS *tok, if (lituse) { - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; insn.fixups[insn.nfixups].exp.X_op = O_absent; insn.nfixups++; @@ -2442,7 +2462,7 @@ emit_stX (const expressionS *tok, if (lituse) { - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; insn.fixups[insn.nfixups].exp.X_op = O_absent; insn.nfixups++; @@ -2458,7 +2478,7 @@ emit_stX (const expressionS *tok, if (lituse) { - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF; insn.fixups[insn.nfixups].exp.X_op = O_absent; insn.nfixups++; @@ -2478,7 +2498,7 @@ emit_stX (const expressionS *tok, if (lituse) { - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE; insn.fixups[insn.nfixups].exp.X_op = O_absent; insn.nfixups++; @@ -2843,7 +2863,7 @@ emit_jsrjmp (const expressionS *tok, if (lituse) { - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR; insn.fixups[insn.nfixups].exp.X_op = O_absent; insn.nfixups++; @@ -2856,15 +2876,17 @@ 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 = XNEWVEC (char, symlen + 5); memcpy (ensymname, symname, symlen); memcpy (ensymname + symlen, "..en", 5); - assert (insn.nfixups < MAX_INSN_FIXUPS); + gas_assert (insn.nfixups < MAX_INSN_FIXUPS); if (insn.nfixups > 0) { memmove (&insn.fixups[1], &insn.fixups[0], @@ -2882,6 +2904,7 @@ emit_jsrjmp (const expressionS *tok, insn.fixups[0].procsym = alpha_evax_proc->symbol; insn.nfixups++; alpha_linkage_symbol = 0; + free (ensymname); } #endif @@ -2926,7 +2949,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) { @@ -2981,10 +3004,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. */ @@ -3287,7 +3307,7 @@ assemble_tokens (const char *opname, const struct alpha_opcode *opcode; const struct alpha_macro *macro; int cpumatch = 1; - bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED; + extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED; #ifdef RELOC_OP_P /* If a user-specified relocation is present, this is not a macro. */ @@ -3348,26 +3368,24 @@ assemble_tokens (const char *opname, #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. */ @@ -3378,11 +3396,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 @@ -3391,27 +3404,29 @@ 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 a symbol for 'basesym - linksym' (offset of the added entry). */ e.X_op = O_subtract; e.X_add_symbol = linksym; e.X_op_symbol = basesym; e.X_add_number = 0; expsym = make_expr_symbol (&e); + /* Create a fixup for the entry. */ 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 the symbol. */ return expsym; } #endif /* OBJ_EVAX */ @@ -3473,18 +3488,20 @@ s_alpha_comm (int ignore ATTRIBUTE_UNUSED) char *name; char c; char *p; - offsetT temp, size; + offsetT size; symbolS *symbolP; +#ifdef OBJ_EVAX + offsetT temp; int log_align = 0; +#endif - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); /* Just after name is now '\0'. */ p = input_line_pointer; *p = c; - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */ if (*input_line_pointer == ',') @@ -3534,12 +3551,12 @@ s_alpha_comm (int ignore ATTRIBUTE_UNUSED) The symbol is effectively an alias for the section name. */ segT sec; - char *sec_name; + const char *sec_name; symbolS *sec_symbol; segT current_seg = now_seg; subsegT current_subseg = now_subseg; int cur_size; - + input_line_pointer++; SKIP_WHITESPACE (); sec_name = s_alpha_section_name (); @@ -3547,8 +3564,8 @@ s_alpha_comm (int ignore ATTRIBUTE_UNUSED) sec = subseg_new (sec_name, 0); S_SET_SEGMENT (sec_symbol, sec); symbol_get_bfdsym (sec_symbol)->flags |= BSF_SECTION_SYM; - bfd_vms_set_section_flags (stdoutput, sec, - EGPS_S_V_OVR | EGPS_S_V_GBL | EGPS_S_V_NOMOD); + bfd_vms_set_section_flags (stdoutput, sec, 0, + EGPS__V_OVR | EGPS__V_GBL | EGPS__V_NOMOD); record_alignment (sec, log_align); /* Reuse stab_string_size to store the size of the section. */ @@ -3583,7 +3600,7 @@ s_alpha_comm (int ignore ATTRIBUTE_UNUSED) frag_align (log_align, 0, 0); record_alignment (bss_section, log_align); - symbolP->sy_frag = frag_now; + symbol_set_frag (symbolP, frag_now); pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP, size, NULL); *pfrag = 0; @@ -3593,11 +3610,11 @@ s_alpha_comm (int ignore ATTRIBUTE_UNUSED) subseg_set (current_seg, current_subseg); } #endif - + if (S_GET_VALUE (symbolP)) { if (S_GET_VALUE (symbolP) != (valueT) size) - as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.", + as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."), S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), (long) size); @@ -3609,7 +3626,7 @@ s_alpha_comm (int ignore ATTRIBUTE_UNUSED) #endif S_SET_EXTERNAL (symbolP); } - + #ifndef OBJ_EVAX know (symbolP->sy_frag == &zero_address_frag); #endif @@ -3626,9 +3643,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; @@ -3646,9 +3661,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; @@ -3678,6 +3691,8 @@ static struct alpha_elf_frame_data *all_frame_data; static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data; static struct alpha_elf_frame_data *cur_frame_data; +extern int all_cfi_sections; + /* Handle the .section pseudo-op. This is like the usual one, but it clears alpha_insn_label and restores auto alignment. */ @@ -3699,13 +3714,15 @@ s_alpha_ent (int dummy ATTRIBUTE_UNUSED) else { char *name, name_end; - name = input_line_pointer; - name_end = get_symbol_end (); + + name_end = get_symbol_name (&name); + /* CFI_EMIT_eh_frame is the default. */ + all_cfi_sections = CFI_EMIT_eh_frame; if (! is_name_beginner (*name)) { as_warn (_(".ent directive has no name")); - *input_line_pointer = name_end; + (void) restore_line_pointer (name_end); } else { @@ -3717,7 +3734,7 @@ s_alpha_ent (int dummy ATTRIBUTE_UNUSED) sym = symbol_find_or_make (name); symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; - cur_frame_data = calloc (1, sizeof (*cur_frame_data)); + cur_frame_data = XCNEW (struct alpha_elf_frame_data); cur_frame_data->func_sym = sym; /* Provide sensible defaults. */ @@ -3730,7 +3747,7 @@ s_alpha_ent (int dummy ATTRIBUTE_UNUSED) /* The .ent directive is sometimes followed by a number. Not sure what it really means, but ignore it. */ *input_line_pointer = name_end; - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); if (*input_line_pointer == ',') { input_line_pointer++; @@ -3751,13 +3768,12 @@ s_alpha_end (int dummy ATTRIBUTE_UNUSED) else { char *name, name_end; - name = input_line_pointer; - name_end = get_symbol_end (); + + name_end = get_symbol_name (&name); if (! is_name_beginner (*name)) { as_warn (_(".end directive has no name")); - *input_line_pointer = name_end; } else { @@ -3773,7 +3789,7 @@ s_alpha_end (int dummy ATTRIBUTE_UNUSED) if (sym && cur_frame_data) { OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym); - expressionS *exp = xmalloc (sizeof (expressionS)); + expressionS *exp = XNEW (expressionS); obj->size = exp; exp->X_op = O_subtract; @@ -3785,9 +3801,9 @@ s_alpha_end (int dummy ATTRIBUTE_UNUSED) } cur_frame_data = NULL; - - *input_line_pointer = name_end; } + + (void) restore_line_pointer (name_end); demand_empty_rest_of_line (); } } @@ -3941,9 +3957,7 @@ s_alpha_file (int ignore ATTRIBUTE_UNUSED) discard_rest_of_line (); len = input_line_pointer - start; - first_file_directive = xmalloc (len + 1); - memcpy (first_file_directive, start, len); - first_file_directive[len] = '\0'; + first_file_directive = xmemdup0 (start, len); input_line_pointer = start; } @@ -4003,7 +4017,7 @@ s_alpha_coff_wrapper (int which) ecoff_directive_val, }; - assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns))); + gas_assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns))); if (ECOFF_DEBUGGING) (*fns[which]) (0); @@ -4029,6 +4043,14 @@ alpha_elf_md_end (void) if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL) return; + /* ??? In theory we could look for functions for which we have + generated unwind info via CFI directives, and those we have not. + Those we have not could still get their unwind info from here. + For now, do nothing if we've seen any CFI directives. Note that + the above test will not trigger, as we've not emitted data yet. */ + if (all_fde_data != NULL) + return; + /* Generate .eh_frame data for the unwind directives specified. */ for (p = all_frame_data; p ; p = p->next) if (p->prologue_sym) @@ -4039,6 +4061,7 @@ alpha_elf_md_end (void) S_GET_VALUE (p->func_sym), symbol_get_frag (p->func_sym))); + cfi_set_sections (); cfi_set_return_column (p->ra_regno); cfi_add_CFA_def_cfa_register (30); if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size) @@ -4103,19 +4126,20 @@ s_alpha_usepv (int unused ATTRIBUTE_UNUSED) symbolS *sym; int other; - name = input_line_pointer; - name_end = get_symbol_end (); + name_end = get_symbol_name (&name); if (! is_name_beginner (*name)) { as_bad (_(".usepv directive has no name")); - *input_line_pointer = name_end; + (void) restore_line_pointer (name_end); ignore_rest_of_line (); return; } sym = symbol_find_or_make (name); - *input_line_pointer++ = name_end; + name_end = restore_line_pointer (name_end); + if (! is_end_of_line[(unsigned char) name_end]) + input_line_pointer++; if (name_end != ',') { @@ -4125,8 +4149,8 @@ s_alpha_usepv (int unused ATTRIBUTE_UNUSED) } SKIP_WHITESPACE (); - which = input_line_pointer; - which_end = get_symbol_end (); + + which_end = get_symbol_name (&which); if (strcmp (which, "no") == 0) other = STO_ALPHA_NOPV; @@ -4138,7 +4162,7 @@ s_alpha_usepv (int unused ATTRIBUTE_UNUSED) other = 0; } - *input_line_pointer = which_end; + (void) restore_line_pointer (which_end); demand_empty_rest_of_line (); S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD)); @@ -4156,7 +4180,7 @@ alpha_cfi_frame_initial_instructions (void) #ifdef OBJ_EVAX /* Get name of section. */ -static char * +static const char * s_alpha_section_name (void) { char *name; @@ -4186,15 +4210,21 @@ s_alpha_section_name (void) return NULL; } - name = xmalloc (end - input_line_pointer + 1); - memcpy (name, input_line_pointer, end - input_line_pointer); - name[end - input_line_pointer] = '\0'; + name = xmemdup0 (input_line_pointer, end - input_line_pointer); input_line_pointer = end; } SKIP_WHITESPACE (); return name; } +/* Put clear/set flags in one flagword. The LSBs are flags to be set, + the MSBs are the flags to be cleared. */ + +#define EGPS__V_NO_SHIFT 16 +#define EGPS__V_MASK 0xffff + +/* Parse one VMS section flag. */ + static flagword s_alpha_section_word (char *str, size_t len) { @@ -4205,36 +4235,36 @@ s_alpha_section_word (char *str, size_t len) { no = 1; str += 2; - len -= 2; + len -= 2; } if (len == 3) { if (strncmp (str, "PIC", 3) == 0) - flag = EGPS_S_V_PIC; + flag = EGPS__V_PIC; else if (strncmp (str, "LIB", 3) == 0) - flag = EGPS_S_V_LIB; + flag = EGPS__V_LIB; else if (strncmp (str, "OVR", 3) == 0) - flag = EGPS_S_V_OVR; + flag = EGPS__V_OVR; else if (strncmp (str, "REL", 3) == 0) - flag = EGPS_S_V_REL; + flag = EGPS__V_REL; else if (strncmp (str, "GBL", 3) == 0) - flag = EGPS_S_V_GBL; + flag = EGPS__V_GBL; else if (strncmp (str, "SHR", 3) == 0) - flag = EGPS_S_V_SHR; + flag = EGPS__V_SHR; else if (strncmp (str, "EXE", 3) == 0) - flag = EGPS_S_V_EXE; + flag = EGPS__V_EXE; else if (strncmp (str, "WRT", 3) == 0) - flag = EGPS_S_V_WRT; + flag = EGPS__V_WRT; else if (strncmp (str, "VEC", 3) == 0) - flag = EGPS_S_V_VEC; + flag = EGPS__V_VEC; else if (strncmp (str, "MOD", 3) == 0) { - flag = no ? EGPS_S_V_NOMOD : EGPS_S_V_NOMOD << EGPS_S_V_NO_SHIFT; + flag = no ? EGPS__V_NOMOD : EGPS__V_NOMOD << EGPS__V_NO_SHIFT; no = 0; } else if (strncmp (str, "COM", 3) == 0) - flag = EGPS_S_V_COM; + flag = EGPS__V_COM; } if (flag == 0) @@ -4247,7 +4277,7 @@ s_alpha_section_word (char *str, size_t len) } if (no) - return flag << EGPS_S_V_NO_SHIFT; + return flag << EGPS__V_NO_SHIFT; else return flag; } @@ -4256,14 +4286,14 @@ s_alpha_section_word (char *str, size_t len) #define EVAX_SECTION_COUNT 5 -static char *section_name[EVAX_SECTION_COUNT + 1] = +static const char *section_name[EVAX_SECTION_COUNT + 1] = { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" }; static void s_alpha_section (int secid) { - int temp; - char *name, *beg; + const char *name; + char *beg; segT sec; flagword vms_flags = 0; symbolS *symbol; @@ -4285,26 +4315,29 @@ s_alpha_section (int secid) char c; SKIP_WHITESPACE (); - beg = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&beg); *input_line_pointer = c; vms_flags |= s_alpha_section_word (beg, input_line_pointer - beg); - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); } while (*input_line_pointer++ == ','); + --input_line_pointer; } symbol = symbol_find_or_make (name); S_SET_SEGMENT (symbol, sec); symbol_get_bfdsym (symbol)->flags |= BSF_SECTION_SYM; - bfd_vms_set_section_flags (stdoutput, sec, vms_flags); + bfd_vms_set_section_flags + (stdoutput, sec, + (vms_flags >> EGPS__V_NO_SHIFT) & EGPS__V_MASK, + vms_flags & EGPS__V_MASK); } else { - temp = get_absolute_expression (); + get_absolute_expression (); subseg_new (section_name[secid], 0); } @@ -4332,8 +4365,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; @@ -4361,10 +4396,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 (); } @@ -4376,13 +4407,12 @@ s_alpha_handler (int is_data) else { char *name, name_end; - name = input_line_pointer; - name_end = get_symbol_end (); + + name_end = get_symbol_name (&name); if (! is_name_beginner (*name)) { as_warn (_(".handler directive has no name")); - *input_line_pointer = name_end; } else { @@ -4391,9 +4421,11 @@ s_alpha_handler (int is_data) sym = symbol_find_or_make (name); symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; alpha_evax_proc->handler = sym; - *input_line_pointer = name_end; } - } + + (void) restore_line_pointer (name_end); + } + demand_empty_rest_of_line (); } @@ -4403,6 +4435,7 @@ static void s_alpha_frame (int ignore ATTRIBUTE_UNUSED) { long val; + int ra; alpha_evax_proc->framereg = tc_get_register (1); @@ -4418,7 +4451,10 @@ s_alpha_frame (int ignore ATTRIBUTE_UNUSED) alpha_evax_proc->framesize = val; - (void) tc_get_register (1); + ra = tc_get_register (1); + if (ra != AXP_REG_RA) + as_warn (_("Bad RA (%d) register for .frame"), ra); + SKIP_WHITESPACE (); if (*input_line_pointer++ != ',') { @@ -4430,74 +4466,75 @@ 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 (); demand_empty_rest_of_line (); alpha_prologue_label = symbol_new (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now); } +/* Parse .pdesc ,{null|stack|reg} + Insert a procedure descriptor. */ + static void s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED) { char *name; char name_end; - register char *p; + 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); + + 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; } - *symbol_get_obj (alpha_evax_proc->symbol) = - (valueT) seginfo->literal_pool_size; + /* Define pdesc symbol. */ + symbol_set_value_now (alpha_evax_proc->symbol); - alpha_evax_proc->symbol->sy_obj = (valueT)seginfo->literal_pool_size; - /* Save bfd symbol of proc entry in function symbol. */ ((struct evax_private_udata_struct *) symbol_get_bfdsym (alpha_evax_proc->symbol)->udata.p)->enbsym = symbol_get_bfdsym (entry_sym); - + SKIP_WHITESPACE (); if (*input_line_pointer++ != ',') { @@ -4507,8 +4544,7 @@ s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED) } SKIP_WHITESPACE (); - name = input_line_pointer; - name_end = get_symbol_end (); + name_end = get_symbol_name (&name); if (strncmp (name, "stack", 5) == 0) alpha_evax_proc->pdsckind = PDSC_S_K_KIND_FP_STACK; @@ -4521,12 +4557,13 @@ s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED) else { + (void) restore_line_pointer (name_end); as_fatal (_("unknown procedure kind")); demand_empty_rest_of_line (); return; } - *input_line_pointer = name_end; + (void) restore_line_pointer (name_end); demand_empty_rest_of_line (); #ifdef md_flush_pending_output @@ -4537,7 +4574,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) @@ -4568,20 +4604,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. */ @@ -4593,14 +4624,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); @@ -4613,11 +4638,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); } } @@ -4629,7 +4650,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) { @@ -4654,11 +4674,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 . + Create a linkage pair relocation. */ + static void s_alpha_linkage (int ignore ATTRIBUTE_UNUSED) { @@ -4678,39 +4700,36 @@ s_alpha_linkage (int ignore ATTRIBUTE_UNUSED) else { struct alpha_linkage_fixups *linkage_fixup; - + p = frag_more (LKP_S_K_SIZE); memset (p, 0, LKP_S_K_SIZE); fixp = fix_new_exp - (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\ + (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0, BFD_RELOC_ALPHA_LINKAGE); - linkage_fixup = (struct alpha_linkage_fixups *) - xmalloc (sizeof (struct alpha_linkage_fixups)); - - linkage_fixup->fixp = fixp; - linkage_fixup->next = 0; - - if (alpha_insn_label == 0) + if (alpha_insn_label == NULL) alpha_insn_label = symbol_new (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now); + + /* Create a linkage element. */ + linkage_fixup = XNEW (struct alpha_linkage_fixups); + linkage_fixup->fixp = fixp; + linkage_fixup->next = NULL; linkage_fixup->label = alpha_insn_label; - if (alpha_linkage_fixup_root == 0) - { - alpha_linkage_fixup_root = alpha_linkage_fixup_tail = linkage_fixup; - alpha_linkage_fixup_tail->next = 0; - } + /* Append it to the list. */ + if (alpha_linkage_fixup_root == NULL) + alpha_linkage_fixup_root = linkage_fixup; else - { - alpha_linkage_fixup_tail->next = linkage_fixup; - alpha_linkage_fixup_tail = linkage_fixup; - alpha_linkage_fixup_tail->next = 0; - } + alpha_linkage_fixup_tail->next = linkage_fixup; + alpha_linkage_fixup_tail = linkage_fixup; } demand_empty_rest_of_line (); } +/* Parse .code_address . + Create a code address relocation. */ + static void s_alpha_code_address (int ignore ATTRIBUTE_UNUSED) { @@ -4737,7 +4756,6 @@ s_alpha_code_address (int ignore ATTRIBUTE_UNUSED) static void s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED) { - alpha_evax_proc->fp_save = tc_get_register (1); demand_empty_rest_of_line (); @@ -4782,12 +4800,13 @@ s_alpha_fmask (int ignore ATTRIBUTE_UNUSED) static void s_alpha_end (int ignore ATTRIBUTE_UNUSED) { + char *name; char c; - c = get_symbol_end (); - *input_line_pointer = c; + c = get_symbol_name (&name); + (void) restore_line_pointer (c); demand_empty_rest_of_line (); - alpha_evax_proc = 0; + alpha_evax_proc = NULL; } static void @@ -4916,12 +4935,11 @@ s_alpha_proc (int is_static ATTRIBUTE_UNUSED) /* Takes ".proc name,nargs". */ SKIP_WHITESPACE (); - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); p = input_line_pointer; symbolP = symbol_find_or_make (name); *p = c; - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); if (*input_line_pointer != ',') { *p = 0; @@ -4936,6 +4954,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 (); } @@ -4950,9 +4969,8 @@ s_alpha_set (int x ATTRIBUTE_UNUSED) int yesno = 1; SKIP_WHITESPACE (); - name = input_line_pointer; - ch = get_symbol_end (); + ch = get_symbol_name (&name); s = name; if (s[0] == 'n' && s[1] == 'o') { @@ -4972,7 +4990,7 @@ s_alpha_set (int x ATTRIBUTE_UNUSED) else as_warn (_("Tried to .set unrecognized mode `%s'"), name); - *input_line_pointer = ch; + (void) restore_line_pointer (ch); demand_empty_rest_of_line (); } @@ -5037,12 +5055,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 (); } @@ -5106,8 +5125,8 @@ s_alpha_arch (int ignored ATTRIBUTE_UNUSED) const struct cpu_type *p; SKIP_WHITESPACE (); - name = input_line_pointer; - ch = get_symbol_end (); + + ch = get_symbol_name (&name); for (p = cpu_types; p->name; ++p) if (strcmp (name, p->name) == 0) @@ -5115,10 +5134,10 @@ s_alpha_arch (int ignored ATTRIBUTE_UNUSED) alpha_target_name = p->name, alpha_target = p->flags; goto found; } - as_warn ("Unknown CPU identifier `%s'", name); + as_warn (_("Unknown CPU identifier `%s'"), name); found: - *input_line_pointer = ch; + (void) restore_line_pointer (ch); demand_empty_rest_of_line (); } @@ -5281,7 +5300,7 @@ maybe_set_gp (asection *sec) if (!sec) return; - vma = bfd_get_section_vma (foo, sec); + vma = bfd_get_section_vma (sec->owner, sec); if (vma && vma < alpha_gp_value) alpha_gp_value = vma; } @@ -5289,7 +5308,7 @@ maybe_set_gp (asection *sec) static void select_gp_value (void) { - assert (alpha_gp_value == 0); + gas_assert (alpha_gp_value == 0); /* Get minus-one in whatever width... */ alpha_gp_value = 0; @@ -5315,12 +5334,12 @@ select_gp_value (void) /* Map 's' to SHF_ALPHA_GPREL. */ bfd_vma -alpha_elf_section_letter (int letter, char **ptr_msg) +alpha_elf_section_letter (int letter, const 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; } @@ -5341,8 +5360,8 @@ alpha_elf_section_flags (flagword flags, bfd_vma attr, int type ATTRIBUTE_UNUSED void alpha_handle_align (fragS *fragp) { - static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f }; - static char const nopunop[8] = + static unsigned char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f }; + static unsigned char const nopunop[8] = { 0x1f, 0x04, 0xff, 0x47, 0x00, 0x00, 0xfe, 0x2f @@ -5396,7 +5415,7 @@ md_begin (void) expressionS e; e.X_op = O_max; - assert (e.X_op == O_max); + gas_assert (e.X_op == O_max); } /* Create the opcode hash table. */ @@ -5419,7 +5438,7 @@ md_begin (void) if ((slash = strchr (name, '/')) != NULL) { - char *p = xmalloc (strlen (name)); + char *p = XNEWVEC (char, strlen (name)); memcpy (p, name, slash - name); strcpy (p + (slash - name), slash + 1); @@ -5489,7 +5508,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 @@ -5555,10 +5573,10 @@ md_section_align (segT seg, valueT size) of LITTLENUMS emitted is stored in *SIZEP. An error message is returned, or NULL on OK. */ -char * +const char * md_atof (int type, char *litP, int *sizeP) { - extern char *vax_md_atof (int, char *, int *); + extern const char *vax_md_atof (int, char *, int *); switch (type) { @@ -5566,6 +5584,7 @@ md_atof (int type, char *litP, int *sizeP) case 'G': /* vax_md_atof() doesn't like "G" for some reason. */ type = 'g'; + /* Fall through. */ case 'F': case 'D': return vax_md_atof (type, litP, sizeP); @@ -5578,7 +5597,7 @@ md_atof (int type, char *litP, int *sizeP) /* Take care of the target-specific command-line options. */ int -md_parse_option (int c, char *arg) +md_parse_option (int c, const char *arg) { switch (c) { @@ -5777,7 +5796,7 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg) #ifdef OBJ_ECOFF case BFD_RELOC_GPREL32: - assert (fixP->fx_subsy == alpha_gp_symbol); + gas_assert (fixP->fx_subsy == alpha_gp_symbol); fixP->fx_subsy = 0; /* FIXME: inherited this obliviousness of `value' -- why? */ md_number_to_chars (fixpos, -alpha_gp_value, 4); @@ -5923,7 +5942,7 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg) as_fatal (_("unhandled relocation type %s"), bfd_get_reloc_code_name (fixP->fx_r_type)); - assert (-(int) fixP->fx_r_type < (int) alpha_num_operands); + gas_assert (-(int) fixP->fx_r_type < (int) alpha_num_operands); operand = &alpha_operands[-(int) fixP->fx_r_type]; /* The rest of these fixups only exist internally during symbol @@ -6201,14 +6220,14 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, { arelent *reloc; - reloc = xmalloc (sizeof (* reloc)); - reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + reloc = XNEW (arelent); + reloc->sym_ptr_ptr = XNEW (asymbol *); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; /* Make sure none of our internal relocations make it this far. They'd better have been fully resolved by this point. */ - assert ((int) fixp->fx_r_type > 0); + gas_assert ((int) fixp->fx_r_type > 0); reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); if (reloc->howto == NULL) @@ -6223,28 +6242,16 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, as_fatal (_("internal error? cannot generate `%s' relocation"), bfd_get_reloc_code_name (fixp->fx_r_type)); - assert (!fixp->fx_pcrel == !reloc->howto->pc_relative); + 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) @@ -6254,6 +6261,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; @@ -6269,11 +6277,12 @@ 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); - my_pname [pname_len - 4] = 0; + char *my_pname = xmemdup0 (pname, pname_len - 4); sym = symbol_find (my_pname); + free (my_pname); if (sym == NULL) abort (); + while (symbol_equated_reloc_p (sym)) { symbolS *n = symbol_get_value_expression (sym)->X_add_symbol; @@ -6287,8 +6296,7 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, pname = symbol_get_bfdsym (sym)->name; } - udata = (struct evax_private_udata_struct *) - xmalloc (sizeof (struct evax_private_udata_struct)); + udata = XNEW (struct evax_private_udata_struct); udata->enbsym = symbol_get_bfdsym (fixp->fx_addsy); udata->bsym = symbol_get_bfdsym (fixp->tc_fix_data.info->psym); udata->origname = (char *)pname; @@ -6319,8 +6327,8 @@ tc_get_register (int frame ATTRIBUTE_UNUSED) SKIP_WHITESPACE (); if (*input_line_pointer == '$') { - char *s = input_line_pointer; - char c = get_symbol_end (); + char *s; + char c = get_symbol_name (&s); symbolS *sym = md_undefined_symbol (s); *strchr (s, '\0') = c;