X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-ia64.c;h=a9126ab74d917534a6ff42bdd53a93281b7c8605;hb=13aa5ceb01cc94a0e617f397c0c5434fc22bb1e5;hp=dcaa416178b36562ae334477cd39d808c41fdd36;hpb=91d6fa6a035cc7d0b7be5c99c194a64cb80924b0;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index dcaa416178..a9126ab74d 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -1,6 +1,5 @@ /* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture. - Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1998-2020 Free Software Foundation, Inc. Contributed by David Mosberger-Tang This file is part of GAS, the GNU Assembler. @@ -103,6 +102,9 @@ enum reloc_func FUNC_LT_DTP_RELATIVE, FUNC_LT_TP_RELATIVE, FUNC_IPLT_RELOC, +#ifdef TE_VMS + FUNC_SLOTCOUNT_RELOC, +#endif }; enum reg_symbol @@ -111,7 +113,8 @@ enum reg_symbol REG_FR = (REG_GR + 128), REG_AR = (REG_FR + 128), REG_CR = (REG_AR + 128), - REG_P = (REG_CR + 128), + REG_DAHR = (REG_CR + 128), + REG_P = (REG_DAHR + 8), REG_BR = (REG_P + 64), REG_IP = (REG_BR + 8), REG_CFM, @@ -130,6 +133,7 @@ enum reg_symbol IND_PKR, IND_PMC, IND_PMD, + IND_DAHR, IND_RR, /* The following pseudo-registers are used for unwind directives only: */ REG_PSP, @@ -163,6 +167,11 @@ struct label_fix bfd_boolean dw2_mark_labels; }; +#ifdef TE_VMS +/* An internally used relocation. */ +#define DUMMY_RELOC_IA64_SLOTCOUNT (BFD_RELOC_UNUSED + 1) +#endif + /* This is the endianness of the current section. */ extern int target_big_endian; @@ -225,7 +234,7 @@ static struct struct hash_control *const_hash; /* constant hash table */ struct hash_control *entry_hash; /* code entry hint hash table */ - /* If X_op is != O_absent, the registername for the instruction's + /* If X_op is != O_absent, the register name for the instruction's qualifying predicate. If NULL, p0 is assumed for instructions that are predictable. */ expressionS qp; @@ -293,7 +302,7 @@ static struct struct label_fix *tag_fixups; struct unw_rec_list *unwind_record; /* Unwind directive. */ expressionS opnd[6]; - char *src_file; + const char *src_file; unsigned int src_line; struct dwarf2_line_info debug_line; } @@ -531,6 +540,7 @@ indirect_reg[] = { "pkr", IND_PKR }, { "pmc", IND_PMC }, { "pmd", IND_PMD }, + { "dahr", IND_DAHR }, { "rr", IND_RR }, }; @@ -575,6 +585,9 @@ pseudo_func[] = { NULL, 0, { 0 } }, /* placeholder for FUNC_LT_DTP_RELATIVE */ { NULL, 0, { 0 } }, /* placeholder for FUNC_LT_TP_RELATIVE */ { "iplt", PSEUDO_FUNC_RELOC, { 0 } }, +#ifdef TE_VMS + { "slotcount", PSEUDO_FUNC_RELOC, { 0 } }, +#endif /* mbtype4 constants: */ { "alt", PSEUDO_FUNC_CONST, { 0xa } }, @@ -598,12 +611,18 @@ pseudo_func[] = /* hint constants: */ { "pause", PSEUDO_FUNC_CONST, { 0x0 } }, + { "priority", PSEUDO_FUNC_CONST, { 0x1 } }, + + /* tf constants: */ + { "clz", PSEUDO_FUNC_CONST, { 32 } }, + { "mpy", PSEUDO_FUNC_CONST, { 33 } }, + { "datahints", PSEUDO_FUNC_CONST, { 34 } }, /* unwind-related constants: */ { "svr4", PSEUDO_FUNC_CONST, { ELFOSABI_NONE } }, { "hpux", PSEUDO_FUNC_CONST, { ELFOSABI_HPUX } }, { "nt", PSEUDO_FUNC_CONST, { 2 } }, /* conflicts w/ELFOSABI_NETBSD */ - { "linux", PSEUDO_FUNC_CONST, { ELFOSABI_LINUX } }, + { "linux", PSEUDO_FUNC_CONST, { ELFOSABI_GNU } }, { "freebsd", PSEUDO_FUNC_CONST, { ELFOSABI_FREEBSD } }, { "openvms", PSEUDO_FUNC_CONST, { ELFOSABI_OPENVMS } }, { "nsk", PSEUDO_FUNC_CONST, { ELFOSABI_NSK } }, @@ -653,7 +672,7 @@ static struct rsrc { int insn_srlz; /* current insn serialization state */ int data_srlz; /* current data serialization state */ int qp_regno; /* qualifying predicate for this usage */ - char *file; /* what file marked this dependency */ + const char *file; /* what file marked this dependency */ unsigned int line; /* what line marked this dependency */ struct mem_offset mem_offset; /* optional memory offset hint */ enum { CMP_NONE, CMP_OR, CMP_AND } cmp_type; /* OR or AND compare? */ @@ -810,7 +829,7 @@ ar_is_only_in_integer_unit (int reg) return reg >= 64 && reg <= 111; } -/* Determine if application register REGNUM resides only in the memory +/* Determine if application register REGNUM resides only in the memory unit (as opposed to the integer unit). */ static int ar_is_only_in_memory_unit (int reg) @@ -837,7 +856,7 @@ set_section (char *name) /* Map 's' to SHF_IA_64_SHORT. */ bfd_vma -ia64_elf_section_letter (int letter, char **ptr_msg) +ia64_elf_section_letter (int letter, const char **ptr_msg) { if (letter == 's') return SHF_IA_64_SHORT; @@ -850,7 +869,7 @@ ia64_elf_section_letter (int letter, char **ptr_msg) return SHF_IA_64_VMS_GLOBAL; #endif - *ptr_msg = _("Bad .section directive: want a,o,s,w,x,M,S,G,T in string"); + *ptr_msg = _("bad .section directive: want a,o,s,w,x,M,S,G,T in string"); return -1; } @@ -1006,28 +1025,153 @@ ia64_flush_insns (void) as_bad (_("qualifying predicate not followed by instruction")); } -static void -ia64_do_align (int nbytes) -{ - char *saved_input_line_pointer = input_line_pointer; - - input_line_pointer = ""; - s_align_bytes (nbytes); - input_line_pointer = saved_input_line_pointer; -} - void ia64_cons_align (int nbytes) { if (md.auto_align) { - char *saved_input_line_pointer = input_line_pointer; - input_line_pointer = ""; - s_align_bytes (nbytes); - input_line_pointer = saved_input_line_pointer; + int log; + for (log = 0; (nbytes & 1) != 1; nbytes >>= 1) + log++; + + do_align (log, NULL, 0, 0); + } +} + +#ifdef TE_VMS + +/* .vms_common section, symbol, size, alignment */ + +static void +obj_elf_vms_common (int ignore ATTRIBUTE_UNUSED) +{ + const char *sec_name; + char *sym_name; + char c; + offsetT size; + offsetT cur_size; + offsetT temp; + symbolS *symbolP; + segT current_seg = now_seg; + subsegT current_subseg = now_subseg; + offsetT log_align; + + /* Section name. */ + sec_name = obj_elf_section_name (); + if (sec_name == NULL) + return; + + /* Symbol name. */ + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + input_line_pointer++; + SKIP_WHITESPACE (); + } + else + { + as_bad (_("expected ',' after section name")); + ignore_rest_of_line (); + return; + } + + c = get_symbol_name (&sym_name); + + if (input_line_pointer == sym_name) + { + (void) restore_line_pointer (c); + as_bad (_("expected symbol name")); + ignore_rest_of_line (); + return; + } + + symbolP = symbol_find_or_make (sym_name); + (void) restore_line_pointer (c); + + if ((S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) + && !S_IS_COMMON (symbolP)) + { + as_bad (_("Ignoring attempt to re-define symbol")); + ignore_rest_of_line (); + return; + } + + /* Symbol size. */ + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + input_line_pointer++; + SKIP_WHITESPACE (); + } + else + { + as_bad (_("expected ',' after symbol name")); + ignore_rest_of_line (); + return; + } + + temp = get_absolute_expression (); + size = temp; + size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1; + if (temp != size) + { + as_warn (_("size (%ld) out of range, ignored"), (long) temp); + ignore_rest_of_line (); + return; } + + /* Alignment. */ + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + input_line_pointer++; + SKIP_WHITESPACE (); + } + else + { + as_bad (_("expected ',' after symbol size")); + ignore_rest_of_line (); + return; + } + + log_align = get_absolute_expression (); + + demand_empty_rest_of_line (); + + obj_elf_change_section + (sec_name, SHT_NOBITS, + SHF_ALLOC | SHF_WRITE | SHF_IA_64_VMS_OVERLAID | SHF_IA_64_VMS_GLOBAL, + 0, NULL, 1, 0); + + S_SET_VALUE (symbolP, 0); + S_SET_SIZE (symbolP, size); + S_SET_EXTERNAL (symbolP); + S_SET_SEGMENT (symbolP, now_seg); + + symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; + + record_alignment (now_seg, log_align); + + cur_size = bfd_section_size (now_seg); + if ((int) size > cur_size) + { + char *pfrag + = frag_var (rs_fill, 1, 1, (relax_substateT)0, NULL, + (valueT)size - (valueT)cur_size, NULL); + *pfrag = 0; + bfd_set_section_size (now_seg, size); + } + + /* Switch back to current segment. */ + subseg_set (current_seg, current_subseg); + +#ifdef md_elf_section_change_hook + md_elf_section_change_hook (); +#endif } +#endif /* TE_VMS */ + /* Output COUNT bytes to a memory location. */ static char *vbyte_mem_ptr = NULL; @@ -1597,7 +1741,7 @@ static unw_rec_list * alloc_record (unw_record_type t) { unw_rec_list *ptr; - ptr = xmalloc (sizeof (*ptr)); + ptr = XNEW (unw_rec_list); memset (ptr, 0, sizeof (*ptr)); ptr->slot_number = SLOT_NUM_NOT_SET; ptr->r.type = t; @@ -2506,8 +2650,7 @@ set_imask (unw_rec_list *region, if (!imask) { imask_size = (region->r.record.r.rlen * 2 + 7) / 8 + 1; - imask = xmalloc (imask_size); - memset (imask, 0, imask_size); + imask = XCNEWVEC (unsigned char, imask_size); region->r.record.r.imask_size = imask_size; region->r.record.r.mask.i = imask; @@ -2595,6 +2738,7 @@ slot_index (unsigned long slot_addr, as_fatal (_("Only constant offsets are supported")); break; } + /* Fall through. */ case rs_fill: s_index += 3 * (first_frag->fr_offset >> 4); break; @@ -2657,7 +2801,7 @@ fixup_unw_records (unw_rec_list *list, int before_relax) for (ptr = list; ptr; ptr = ptr->next) { if (ptr->slot_number == SLOT_NUM_NOT_SET) - as_bad (_(" Insn slot not set in unwind record.")); + as_bad (_("Insn slot not set in unwind record.")); t = slot_index (ptr->slot_number, ptr->slot_frag, first_addr, first_frag, before_relax); switch (ptr->r.type) @@ -2823,7 +2967,7 @@ ia64_estimate_size_before_relax (fragS *frag, } /* This function converts a rs_machine_dependent variant frag into a - normal fill frag with the unwind image from the the record list. */ + normal fill frag with the unwind image from the record list. */ void ia64_convert_frag (fragS *frag) { @@ -3013,12 +3157,11 @@ dot_radix (int dummy ATTRIBUTE_UNUSED) if (is_it_end_of_statement ()) return; - radix = input_line_pointer; - ch = get_symbol_end (); + ch = get_symbol_name (&radix); ia64_canonicalize_symbol_name (radix); if (strcasecmp (radix, "C")) as_bad (_("Radix `%s' unsupported or invalid"), radix); - *input_line_pointer = ch; + (void) restore_line_pointer (ch); demand_empty_rest_of_line (); } @@ -3125,11 +3268,12 @@ add_unwind_entry (unw_rec_list *ptr, int sep) if (sep == ',') { + char *name; /* Parse a tag permitted for the current directive. */ int ch; SKIP_WHITESPACE (); - ch = get_symbol_end (); + ch = get_symbol_name (&name); /* FIXME: For now, just issue a warning that this isn't implemented. */ { static int warned; @@ -3140,7 +3284,7 @@ add_unwind_entry (unw_rec_list *ptr, int sep) as_warn (_("Tags on unwind pseudo-ops aren't supported, yet")); } } - *input_line_pointer = ch; + (void) restore_line_pointer (ch); } if (sep != NOT_A_CHAR) demand_empty_rest_of_line (); @@ -3186,7 +3330,7 @@ dot_vframe (int dummy ATTRIBUTE_UNUSED) if (! (unwind.prologue_mask & 2)) add_unwind_entry (output_psp_gr (reg), NOT_A_CHAR); else if (reg != unwind.prologue_gr - + (unsigned) popcount (unwind.prologue_mask & (-2 << 1))) + + (unsigned) popcount (unwind.prologue_mask & -(2 << 1))) as_warn (_("Operand of .vframe contradicts .prologue")); } @@ -3229,7 +3373,7 @@ dot_save (int dummy ATTRIBUTE_UNUSED) e2.X_op = O_absent; reg1 = e1.X_add_number; - /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */ + /* Make sure it's a valid ar.xxx reg, OR its br0, aka 'rp'. */ if (e1.X_op != O_register) { as_bad (_("First operand to .save not a register")); @@ -3268,7 +3412,7 @@ dot_save (int dummy ATTRIBUTE_UNUSED) if (! (unwind.prologue_mask & 4)) add_unwind_entry (output_pfs_gr (reg2), NOT_A_CHAR); else if (reg2 != unwind.prologue_gr - + (unsigned) popcount (unwind.prologue_mask & (-4 << 1))) + + (unsigned) popcount (unwind.prologue_mask & -(4 << 1))) as_warn (_("Second operand of .save contradicts .prologue")); break; case REG_AR + AR_LC: @@ -3287,7 +3431,7 @@ dot_save (int dummy ATTRIBUTE_UNUSED) if (! (unwind.prologue_mask & 1)) add_unwind_entry (output_preds_gr (reg2), NOT_A_CHAR); else if (reg2 != unwind.prologue_gr - + (unsigned) popcount (unwind.prologue_mask & (-1 << 1))) + + (unsigned) popcount (unwind.prologue_mask & -(1 << 1))) as_warn (_("Second operand of .save contradicts .prologue")); break; case REG_PRIUNAT: @@ -3368,7 +3512,7 @@ dot_restorereg (int pred) add_unwind_entry (output_spill_reg (ab, reg, 0, 0, qp), sep); } -static char *special_linkonce_name[] = +static const char *special_linkonce_name[] = { ".gnu.linkonce.ia64unw.", ".gnu.linkonce.ia64unwi." }; @@ -3413,7 +3557,6 @@ start_unwind_section (const segT text_seg, int sec_index) char *sec_name; const char *prefix = special_section_name [sec_index]; const char *suffix; - size_t prefix_len, suffix_len, sec_name_len; sec_text_name = segment_name (text_seg); text_name = sec_text_name; @@ -3437,20 +3580,13 @@ start_unwind_section (const segT text_seg, int sec_index) suffix += sizeof (".gnu.linkonce.t.") - 1; } - prefix_len = strlen (prefix); - suffix_len = strlen (suffix); - sec_name_len = prefix_len + suffix_len; - sec_name = alloca (sec_name_len + 1); - memcpy (sec_name, prefix, prefix_len); - memcpy (sec_name + prefix_len, suffix, suffix_len); - sec_name [sec_name_len] = '\0'; + sec_name = concat (prefix, suffix, NULL); /* Handle COMDAT group. */ if ((text_seg->flags & SEC_LINK_ONCE) != 0 && (elf_section_flags (text_seg) & SHF_GROUP) != 0) { char *section; - size_t len, group_name_len; const char *group_name = elf_group_name (text_seg); if (group_name == NULL) @@ -3458,31 +3594,23 @@ start_unwind_section (const segT text_seg, int sec_index) as_bad (_("Group section `%s' has no group signature"), sec_text_name); ignore_rest_of_line (); + free (sec_name); return; } - /* We have to construct a fake section directive. */ - group_name_len = strlen (group_name); - len = (sec_name_len - + 16 /* ,"aG",@progbits, */ - + group_name_len /* ,group_name */ - + 7); /* ,comdat */ - - section = alloca (len + 1); - memcpy (section, sec_name, sec_name_len); - memcpy (section + sec_name_len, ",\"aG\",@progbits,", 16); - memcpy (section + sec_name_len + 16, group_name, group_name_len); - memcpy (section + len - 7, ",comdat", 7); - section [len] = '\0'; + + /* We have to construct a fake section directive. */ + section = concat (sec_name, ",\"aG\",@progbits,", group_name, ",comdat", NULL); set_section (section); + free (section); } else { set_section (sec_name); - bfd_set_section_flags (stdoutput, now_seg, - SEC_LOAD | SEC_ALLOC | SEC_READONLY); + bfd_set_section_flags (now_seg, SEC_LOAD | SEC_ALLOC | SEC_READONLY); } elf_linked_to_section (now_seg) = text_seg; + free (sec_name); } static void @@ -3533,7 +3661,7 @@ generate_unwind_image (const segT text_seg) /* Set expression which points to start of unwind descriptor area. */ unwind.info = expr_build_dot (); - + frag_var (rs_machine_dependent, size, size, 0, 0, (offsetT) (long) unwind.personality_routine, (char *) list); @@ -3636,7 +3764,7 @@ dot_savemem (int psprel) reg1 = e1.X_add_number; val = e2.X_add_number; - /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */ + /* Make sure it's a valid ar.xxx reg, OR its br0, aka 'rp'. */ if (e1.X_op != O_register) { as_bad (_("First operand to .%s not a register"), po); @@ -3981,7 +4109,7 @@ save_prologue_count (unsigned long lbl, unsigned int count) lpc->prologue_count = count; else { - label_prologue_count *new_lpc = xmalloc (sizeof (* new_lpc)); + label_prologue_count *new_lpc = XNEW (label_prologue_count); new_lpc->next = unwind.saved_prologue_counts; new_lpc->label_number = lbl; @@ -3991,7 +4119,7 @@ save_prologue_count (unsigned long lbl, unsigned int count) } static void -free_saved_prologue_counts () +free_saved_prologue_counts (void) { label_prologue_count *lpc = unwind.saved_prologue_counts; label_prologue_count *next; @@ -4078,16 +4206,16 @@ static void dot_personality (int dummy ATTRIBUTE_UNUSED) { char *name, *p, c; + if (!in_procedure ("personality")) return; SKIP_WHITESPACE (); - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); p = input_line_pointer; unwind.personality_routine = symbol_find_or_make (name); unwind.force_unwind_entry = 1; *p = c; - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); demand_empty_rest_of_line (); } @@ -4117,8 +4245,7 @@ dot_proc (int dummy ATTRIBUTE_UNUSED) while (1) { SKIP_WHITESPACE (); - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); p = input_line_pointer; if (!*name) as_bad (_("Empty argument of .proc")); @@ -4134,14 +4261,14 @@ dot_proc (int dummy ATTRIBUTE_UNUSED) } else { - pending = xmalloc (sizeof (*pending)); + pending = XNEW (proc_pending); pending->sym = sym; last_pending = last_pending->next = pending; } symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; } *p = c; - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); if (*input_line_pointer != ',') break; ++input_line_pointer; @@ -4153,7 +4280,7 @@ dot_proc (int dummy ATTRIBUTE_UNUSED) } last_pending->next = NULL; demand_empty_rest_of_line (); - ia64_do_align (16); + do_align (4, NULL, 0, 0); unwind.prologue = 0; unwind.prologue_count = 0; @@ -4208,12 +4335,14 @@ dot_prologue (int dummy ATTRIBUTE_UNUSED) as_warn (_("Pointless use of zero first operand to .prologue")); else mask = e.X_add_number; - n = popcount (mask); + + n = popcount (mask); if (sep == ',') parse_operand_and_eval (&e, 0); else e.X_op = O_absent; + if (e.X_op == O_constant && e.X_add_number >= 0 && e.X_add_number < 128) @@ -4233,7 +4362,6 @@ dot_prologue (int dummy ATTRIBUTE_UNUSED) as_bad (_("Second operand to .prologue must be the first of %d general registers"), n); grsave = 0; } - } if (mask) @@ -4312,14 +4440,15 @@ dot_endp (int dummy ATTRIBUTE_UNUSED) symbol_get_frag (unwind.proc_pending.sym)); else e.X_add_symbol = unwind.proc_pending.sym; - ia64_cons_fix_new (frag_now, where, bytes_per_address, &e); + ia64_cons_fix_new (frag_now, where, bytes_per_address, &e, + BFD_RELOC_NONE); e.X_op = O_pseudo_fixup; e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym; e.X_add_number = 0; e.X_add_symbol = proc_end; ia64_cons_fix_new (frag_now, where + bytes_per_address, - bytes_per_address, &e); + bytes_per_address, &e, BFD_RELOC_NONE); if (unwind.info) { @@ -4328,7 +4457,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED) e.X_add_number = 0; e.X_add_symbol = unwind.info; ia64_cons_fix_new (frag_now, where + (bytes_per_address * 2), - bytes_per_address, &e); + bytes_per_address, &e, BFD_RELOC_NONE); } } subseg_set (saved_seg, saved_subseg); @@ -4354,8 +4483,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED) S_SET_SIZE (sym, frag_now_fix () - S_GET_VALUE (sym)); else { - symbol_get_obj (sym)->size = - (expressionS *) xmalloc (sizeof (expressionS)); + symbol_get_obj (sym)->size = XNEW (expressionS); symbol_get_obj (sym)->size->X_op = O_subtract; symbol_get_obj (sym)->size->X_add_symbol = symbol_new (FAKE_LABEL_NAME, now_seg, @@ -4374,8 +4502,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED) char *name, *p, c; SKIP_WHITESPACE (); - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); p = input_line_pointer; if (!*name) (md.unwind_check == unwind_check_warning @@ -4397,7 +4524,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED) as_warn (_("`%s' was not specified with previous .proc"), name); } *p = c; - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); if (*input_line_pointer != ',') break; ++input_line_pointer; @@ -4483,12 +4610,11 @@ dot_rot (int type) drpp = &md.dynreg[type]; while (1) { - start = input_line_pointer; - ch = get_symbol_end (); + ch = get_symbol_name (&start); len = strlen (ia64_canonicalize_symbol_name (start)); *input_line_pointer = ch; - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); if (*input_line_pointer != '[') { as_bad (_("Expected '['")); @@ -4542,11 +4668,11 @@ dot_rot (int type) if (!*drpp) { - *drpp = obstack_alloc (¬es, sizeof (*dr)); + *drpp = XOBNEW (¬es, struct dynreg); memset (*drpp, 0, sizeof (*dr)); } - name = obstack_alloc (¬es, len + 1); + name = XOBNEWVEC (¬es, char, len + 1); memcpy (name, start, len); name[len] = '\0'; @@ -4614,8 +4740,7 @@ dot_psr (int dummy ATTRIBUTE_UNUSED) while (1) { - option = input_line_pointer; - ch = get_symbol_end (); + ch = get_symbol_name (&option); if (strcmp (option, "lsb") == 0) md.flags &= ~EF_IA_64_BE; else if (strcmp (option, "msb") == 0) @@ -4628,7 +4753,7 @@ dot_psr (int dummy ATTRIBUTE_UNUSED) as_bad (_("Unknown psr option `%s'"), option); *input_line_pointer = ch; - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); if (*input_line_pointer != ',') break; @@ -4651,36 +4776,21 @@ cross_section (int ref, void (*builder) (int), int ua) char *start, *end; int saved_auto_align; unsigned int section_count; + char *name; + char c; SKIP_WHITESPACE (); start = input_line_pointer; - if (*start == '"') - { - int len; - char *name; - - name = demand_copy_C_string (&len); - obstack_free(¬es, name); - if (!name) - { - ignore_rest_of_line (); - return; - } - } - else + c = get_symbol_name (&name); + if (input_line_pointer == start) { - char c = get_symbol_end (); - - if (input_line_pointer == start) - { - as_bad (_("Missing section name")); - ignore_rest_of_line (); - return; - } - *input_line_pointer = c; + as_bad (_("Missing section name")); + ignore_rest_of_line (); + return; } + * input_line_pointer = c; + SKIP_WHITESPACE_AFTER_NAME (); end = input_line_pointer; - SKIP_WHITESPACE (); if (*input_line_pointer != ',') { as_bad (_("Comma expected after section name")); @@ -4722,20 +4832,20 @@ stmt_float_cons (int kind) switch (kind) { case 'd': - alignment = 8; + alignment = 3; break; case 'x': case 'X': - alignment = 16; + alignment = 4; break; case 'f': default: - alignment = 4; + alignment = 2; break; } - ia64_do_align (alignment); + do_align (alignment, NULL, 0, 0); float_cons (kind); } @@ -4871,7 +4981,7 @@ static void print_prmask (valueT mask) { int regno; - char *comma = ""; + const char *comma = ""; for (regno = 0; regno < 64; regno++) { if (mask & ((valueT) 1 << regno)) @@ -4913,8 +5023,11 @@ dot_pred_rel (int type) } else if (*input_line_pointer == '@') { - char *form = ++input_line_pointer; - char c = get_symbol_end(); + char *form; + char c; + + ++input_line_pointer; + c = get_symbol_name (&form); if (strcmp (form, "mutex") == 0) type = 'm'; @@ -4922,7 +5035,7 @@ dot_pred_rel (int type) type = 'c'; else if (strcmp (form, "imply") == 0) type = 'i'; - *input_line_pointer = c; + (void) restore_line_pointer (c); } else { @@ -5060,8 +5173,7 @@ dot_entry (int dummy ATTRIBUTE_UNUSED) do { - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); symbolP = symbol_find_or_make (name); err = hash_insert (md.entry_hash, S_GET_NAME (symbolP), (void *) symbolP); @@ -5070,7 +5182,7 @@ dot_entry (int dummy ATTRIBUTE_UNUSED) name, err); *input_line_pointer = c; - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); c = *input_line_pointer; if (c == ',') { @@ -5221,6 +5333,10 @@ const pseudo_typeS md_pseudo_table[] = {"4byte", stmt_cons_ua, 4}, {"8byte", stmt_cons_ua, 8}, +#ifdef TE_VMS + {"vms_common", obj_elf_vms_common, 0}, +#endif + { NULL, 0, 0 } }; @@ -5417,6 +5533,12 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e) return OPERAND_MATCH; break; + case IA64_OPND_DAHR3: + if (e->X_op == O_register && e->X_add_number >= REG_DAHR + && e->X_add_number < REG_DAHR + 8) + return OPERAND_MATCH; + break; + case IA64_OPND_F1: case IA64_OPND_F2: case IA64_OPND_F3: @@ -5461,6 +5583,7 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e) case IA64_OPND_PKR_R3: case IA64_OPND_PMC_R3: case IA64_OPND_PMD_R3: + case IA64_OPND_DAHR_R3: case IA64_OPND_RR_R3: if (e->X_op == O_index && e->X_op_symbol && (S_GET_VALUE (e->X_op_symbol) - IND_CPUID @@ -5512,6 +5635,7 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e) /* SOR must be an integer multiple of 8 */ if (e->X_op == O_constant && e->X_add_number & 0x7) return OPERAND_OUT_OF_RANGE; + /* Fall through. */ case IA64_OPND_SOF: case IA64_OPND_SOL: if (e->X_op == O_constant) @@ -5581,6 +5705,8 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e) case IA64_OPND_IMMU2: case IA64_OPND_IMMU7a: case IA64_OPND_IMMU7b: + case IA64_OPND_IMMU16: + case IA64_OPND_IMMU19: case IA64_OPND_IMMU21: case IA64_OPND_IMMU24: case IA64_OPND_MBTYPE4: @@ -5665,6 +5791,7 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e) case IA64_OPND_IMM14: case IA64_OPND_IMM22: relocatable = 1; + /* Fall through. */ case IA64_OPND_IMM1: case IA64_OPND_IMM8: case IA64_OPND_IMM8U4: @@ -5712,9 +5839,8 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e) /* Sign-extend 32-bit unsigned numbers, so that the following range checks will work. */ val = e->X_add_number; - if (((val & (~(bfd_vma) 0 << 32)) == 0) - && ((val & ((bfd_vma) 1 << 31)) != 0)) - val = ((val << 32) >> 32); + if ((val & (~(bfd_vma) 0 << 32)) == 0) + val = (val ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31); /* Check for 0x100000000. This is valid because 0x100000000-1 is the same as ((uint32_t) -1). */ @@ -5752,9 +5878,8 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e) /* Sign-extend 32-bit unsigned numbers, so that the following range checks will work. */ val = e->X_add_number; - if (((val & (~(bfd_vma) 0 << 32)) == 0) - && ((val & ((bfd_vma) 1 << 31)) != 0)) - val = ((val << 32) >> 32); + if ((val & (~(bfd_vma) 0 << 32)) == 0) + val = (val ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31); } else val = e->X_add_number; @@ -5804,6 +5929,7 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e) ++CURR_SLOT.num_fixups; return OPERAND_MATCH; } + /* Fall through. */ case IA64_OPND_TAG13: case IA64_OPND_TAG13b: switch (e->X_op) @@ -5837,6 +5963,39 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e) ++CURR_SLOT.num_fixups; return OPERAND_MATCH; + case IA64_OPND_STRD5b: + if (e->X_op == O_constant) + { + /* 5-bit signed scaled by 64 */ + if ((e->X_add_number <= ( 0xf << 6 )) + && (e->X_add_number >= -( 0x10 << 6 ))) + { + + /* Must be a multiple of 64 */ + if ((e->X_add_number & 0x3f) != 0) + as_warn (_("stride must be a multiple of 64; lower 6 bits ignored")); + + e->X_add_number &= ~ 0x3f; + return OPERAND_MATCH; + } + else + return OPERAND_OUT_OF_RANGE; + } + break; + case IA64_OPND_CNT6a: + if (e->X_op == O_constant) + { + /* 6-bit unsigned biased by 1 -- count 0 is meaningless */ + if ((e->X_add_number <= 64) + && (e->X_add_number > 0) ) + { + return OPERAND_MATCH; + } + else + return OPERAND_OUT_OF_RANGE; + } + break; + default: break; } @@ -5942,7 +6101,7 @@ parse_operands (struct ia64_opcode *idesc) for (; ; ++i) { - if (i < NELEMS (CURR_SLOT.opnd)) + if (i < NELEMS (CURR_SLOT.opnd)) { sep = parse_operand_maybe_eval (CURR_SLOT.opnd + i, '=', idesc->operands[i]); @@ -6287,6 +6446,10 @@ build_insn (struct slot *slot, bfd_vma *insnp) val -= REG_CR; break; + case IA64_OPND_DAHR3: + val -= REG_DAHR; + break; + case IA64_OPND_F1: case IA64_OPND_F2: case IA64_OPND_F3: @@ -6313,6 +6476,7 @@ build_insn (struct slot *slot, bfd_vma *insnp) case IA64_OPND_PKR_R3: case IA64_OPND_PMC_R3: case IA64_OPND_PMD_R3: + case IA64_OPND_DAHR_R3: case IA64_OPND_RR_R3: val -= REG_GR; break; @@ -6728,15 +6892,6 @@ emit_one_bundle (void) md.slot[curr].unwind_record = NULL; } - if (required_unit == IA64_UNIT_L) - { - know (i == 1); - /* skip one slot for long/X-unit instructions */ - ++i; - } - --md.num_slots_in_use; - last_slot = i; - for (j = 0; j < md.slot[curr].num_fixups; ++j) { ifix = md.slot[curr].fixup + j; @@ -6749,6 +6904,17 @@ emit_one_bundle (void) end_of_insn_group = md.slot[curr].end_of_insn_group; + /* This adjustment to "i" must occur after the fix, otherwise the fix + is assigned to the wrong slot, and the VMS linker complains. */ + if (required_unit == IA64_UNIT_L) + { + know (i == 1); + /* skip one slot for long/X-unit instructions */ + ++i; + } + --md.num_slots_in_use; + last_slot = i; + /* clear slot: */ ia64_free_opcode (md.slot[curr].idesc); memset (md.slot + curr, 0, sizeof (md.slot[curr])); @@ -6803,7 +6969,7 @@ emit_one_bundle (void) as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line, _("Missing '}' at end of file")); } - + know (md.num_slots_in_use < NUM_SLOTS); t0 = end_of_insn_group | (template_val << 1) | (insn[0] << 5) | (insn[1] << 46); @@ -6814,7 +6980,7 @@ emit_one_bundle (void) } int -md_parse_option (int c, char *arg) +md_parse_option (int c, const char *arg) { switch (c) @@ -6990,7 +7156,9 @@ IA-64 options:\n\ unwind directive check (default -munwind-check=warning)\n\ -mhint.b=[ok|warning|error]\n\ hint.b check (default -mhint.b=error)\n\ - -x | -xexplicit turn on dependency violation checking\n\ + -x | -xexplicit turn on dependency violation checking\n"), stream); + /* Note for translators: "automagically" can be translated as "automatically" here. */ + fputs (_("\ -xauto automagically remove dependency violations (default)\n\ -xnone turn off dependency violation checking\n\ -xdebug debug dependency violation checker\n\ @@ -7079,7 +7247,7 @@ md_begin (void) md.auto_align = 1; md.explicit_mode = md.default_explicit_mode; - bfd_set_section_alignment (stdoutput, text_section, 4); + bfd_set_section_alignment (text_section, 4); /* Make sure function pointers get initialized. */ target_big_endian = -1; @@ -7158,6 +7326,12 @@ md_begin (void) symbol_new (".", undefined_section, FUNC_IPLT_RELOC, &zero_address_frag); +#ifdef TE_VMS + pseudo_func[FUNC_SLOTCOUNT_RELOC].u.sym = + symbol_new (".", undefined_section, FUNC_SLOTCOUNT_RELOC, + &zero_address_frag); +#endif + if (md.tune != itanium1) { /* Convert MFI NOPs bundles into MMI NOPs bundles. */ @@ -7277,6 +7451,9 @@ md_begin (void) for (i = 0; i < NELEMS (cr); ++i) declare_register (cr[i].name, REG_CR + cr[i].regnum); + /* dahr registers: */ + declare_register_set ("dahr", 8, REG_DAHR); + declare_register ("ip", REG_IP); declare_register ("cfm", REG_CFM); declare_register ("psr", REG_PSR); @@ -7529,8 +7706,7 @@ ia64_unrecognized_line (int ch) recognize labels. */ if (is_name_beginner (*input_line_pointer)) { - s = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&s); } else if (LOCAL_LABELS_FB && ISDIGIT (*input_line_pointer)) @@ -7590,7 +7766,7 @@ ia64_frob_label (struct symbol *sym) labels. */ if (defining_tag) { - fix = obstack_alloc (¬es, sizeof (*fix)); + fix = XOBNEW (¬es, struct label_fix); fix->sym = sym; fix->next = CURR_SLOT.tag_fixups; fix->dw2_mark_labels = FALSE; @@ -7599,10 +7775,10 @@ ia64_frob_label (struct symbol *sym) return; } - if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) + if (bfd_section_flags (now_seg) & SEC_CODE) { md.last_text_seg = now_seg; - fix = obstack_alloc (¬es, sizeof (*fix)); + fix = XOBNEW (¬es, struct label_fix); fix->sym = sym; fix->next = CURR_SLOT.label_fixups; fix->dw2_mark_labels = dwarf2_loc_mark_labels; @@ -7612,9 +7788,8 @@ ia64_frob_label (struct symbol *sym) if (md.path == md.maxpaths) { md.maxpaths += 20; - md.entry_labels = (const char **) - xrealloc ((void *) md.entry_labels, - md.maxpaths * sizeof (char *)); + md.entry_labels = XRESIZEVEC (const char *, md.entry_labels, + md.maxpaths); } md.entry_labels[md.path++] = S_GET_NAME (sym); } @@ -7627,9 +7802,9 @@ ia64_frob_label (struct symbol *sym) int ia64_frob_symbol (struct symbol *sym) { - if ((S_GET_SEGMENT (sym) == &bfd_und_section && ! symbol_used_p (sym) && + if ((S_GET_SEGMENT (sym) == bfd_und_section_ptr && ! symbol_used_p (sym) && ELF_ST_VISIBILITY (S_GET_OTHER (sym)) == STV_DEFAULT) - || (S_GET_SEGMENT (sym) == &bfd_abs_section + || (S_GET_SEGMENT (sym) == bfd_abs_section_ptr && ! S_IS_EXTERNAL (sym))) return 1; return 0; @@ -7640,7 +7815,7 @@ void ia64_flush_pending_output (void) { if (!md.keep_pending_output - && bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) + && bfd_section_flags (now_seg) & SEC_CODE) { /* ??? This causes many unnecessary stop bits to be emitted. Unfortunately, it isn't clear if it is safe to remove this. */ @@ -7744,6 +7919,15 @@ ia64_parse_name (char *name, expressionS *e, char *nextcharP) } /* Skip ')'. */ ++input_line_pointer; +#ifdef TE_VMS + if (idx == FUNC_SLOTCOUNT_RELOC) + { + /* @slotcount can accept any expression. Canonicalize. */ + e->X_add_symbol = make_expr_symbol (e); + e->X_op = O_symbol; + e->X_add_number = 0; + } +#endif if (e->X_op != O_symbol) { if (e->X_op != O_pseudo_fixup) @@ -7868,8 +8052,7 @@ ia64_parse_name (char *name, expressionS *e, char *nextcharP) } } - end = alloca (strlen (name) + 1); - strcpy (end, name); + end = xstrdup (name); name = ia64_canonicalize_symbol_name (end); if ((dr = hash_find (md.dynreg_hash, name))) { @@ -7879,8 +8062,10 @@ ia64_parse_name (char *name, expressionS *e, char *nextcharP) bits. */ e->X_op = O_register; e->X_add_number = dr->base | (dr->num_regs << 16); + free (end); return 1; } + free (end); return 0; } @@ -8521,6 +8706,22 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) } break; + case IA64_RS_DAHR: + if (note == 0) + { + if (idesc->operands[!rsrc_write] == IA64_OPND_DAHR3) + { + specs[count] = tmpl; + specs[count++].index = + CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_DAHR; + } + } + else + { + UNHANDLED; + } + break; + case IA64_RS_FR: case IA64_RS_FRb: if (note != 1) @@ -8595,6 +8796,7 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) || idesc->operands[i] == IA64_OPND_PKR_R3 || idesc->operands[i] == IA64_OPND_PMC_R3 || idesc->operands[i] == IA64_OPND_PMD_R3 + || idesc->operands[i] == IA64_OPND_DAHR_R3 || idesc->operands[i] == IA64_OPND_RR_R3 || ((i >= idesc->num_outputs) && (idesc->operands[i] == IA64_OPND_R1 @@ -9080,6 +9282,7 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) { specs[count++] = tmpl; } + /* Fall through. */ case AR_RSC: if (!rsrc_write && (regno == AR_BSPSTORE @@ -9408,7 +9611,7 @@ update_qp_mutex (valueT mask) print_prmask (qp_mutexes[i].prmask); fprintf (stderr, "\n"); } - + /* Deal with the old mutex with more than 3+ PRs only if the new mutex on the same execution path with it. @@ -9421,7 +9624,7 @@ update_qp_mutex (valueT mask) if (add == 0 && (qp_mutexes[i].prmask & mask) == mask) add = 1; - + qp_mutexes[i].prmask &= ~mask; if (qp_mutexes[i].prmask & (qp_mutexes[i].prmask - 1)) { @@ -9431,7 +9634,7 @@ update_qp_mutex (valueT mask) i++; } } - + if (keep == 0) /* Remove the mutex. */ qp_mutexes[i] = qp_mutexes[--qp_mutexeslen]; @@ -9528,9 +9731,7 @@ add_qp_imply (int p1, int p2) if (qp_implieslen == qp_impliestotlen) { qp_impliestotlen += 20; - qp_implies = (struct qp_imply *) - xrealloc ((void *) qp_implies, - qp_impliestotlen * sizeof (struct qp_imply)); + qp_implies = XRESIZEVEC (struct qp_imply, qp_implies, qp_impliestotlen); } if (md.debug_dv) fprintf (stderr, " Registering PR%d implies PR%d\n", p1, p2); @@ -9573,9 +9774,7 @@ add_qp_mutex (valueT mask) if (qp_mutexeslen == qp_mutexestotlen) { qp_mutexestotlen += 20; - qp_mutexes = (struct qpmutex *) - xrealloc ((void *) qp_mutexes, - qp_mutexestotlen * sizeof (struct qpmutex)); + qp_mutexes = XRESIZEVEC (struct qpmutex, qp_mutexes, qp_mutexestotlen); } if (md.debug_dv) { @@ -9989,9 +10188,7 @@ mark_resource (struct ia64_opcode *idesc ATTRIBUTE_UNUSED, if (regdepslen == regdepstotlen) { regdepstotlen += 20; - regdeps = (struct rsrc *) - xrealloc ((void *) regdeps, - regdepstotlen * sizeof (struct rsrc)); + regdeps = XRESIZEVEC (struct rsrc, regdeps, regdepstotlen); } regdeps[regdepslen] = *spec; @@ -10068,7 +10265,7 @@ remove_marked_resource (struct rsrc *rs) case IA64_DVS_SPECIFIC: if (md.debug_dv) fprintf (stderr, "Implementation-specific, assume worst case...\n"); - /* ...fall through... */ + /* Fall through. */ case IA64_DVS_INSTR: if (md.debug_dv) fprintf (stderr, "Inserting instr serialization\n"); @@ -10463,7 +10660,8 @@ check_dv (struct ia64_opcode *idesc) void md_assemble (char *str) { - char *saved_input_line_pointer, *mnemonic; + char *saved_input_line_pointer, *temp; + const char *mnemonic; const struct pseudo_opcode *pdesc; struct ia64_opcode *idesc; unsigned char qp_regno; @@ -10475,12 +10673,12 @@ md_assemble (char *str) /* extract the opcode (mnemonic): */ - mnemonic = input_line_pointer; - ch = get_symbol_end (); + ch = get_symbol_name (&temp); + mnemonic = temp; pdesc = (struct pseudo_opcode *) hash_find (md.pseudo_hash, mnemonic); if (pdesc) { - *input_line_pointer = ch; + (void) restore_line_pointer (ch); (*pdesc->handler) (pdesc->arg); goto done; } @@ -10488,7 +10686,7 @@ md_assemble (char *str) /* Find the instruction descriptor matching the arguments. */ idesc = ia64_find_opcode (mnemonic); - *input_line_pointer = ch; + (void) restore_line_pointer (ch); if (!idesc) { as_bad (_("Unknown opcode `%s'"), mnemonic); @@ -10552,7 +10750,7 @@ md_assemble (char *str) { enum ia64_opnd opnd1, opnd2; int rop; - + opnd1 = idesc->operands[0]; opnd2 = idesc->operands[1]; if (opnd1 == IA64_OPND_AR3) @@ -10630,7 +10828,7 @@ md_assemble (char *str) /* Build the instruction. */ CURR_SLOT.qp_regno = qp_regno; CURR_SLOT.idesc = idesc; - as_where (&CURR_SLOT.src_file, &CURR_SLOT.src_line); + CURR_SLOT.src_file = as_where (&CURR_SLOT.src_line); dwarf2_where (&CURR_SLOT.debug_line); dwarf2_consume_line_info (); @@ -10788,7 +10986,7 @@ ia64_pcrel_from_section (fixS *fix, segT sec) { unsigned long off = fix->fx_frag->fr_address + fix->fx_where; - if (bfd_get_section_flags (stdoutput, sec) & SEC_CODE) + if (bfd_section_flags (sec) & SEC_CODE) off &= ~0xfUL; return off; @@ -10812,9 +11010,9 @@ ia64_dwarf2_emit_offset (symbolS *symbol, unsigned int size) fixup. We pick the right reloc code depending on the byteorder currently in effect. */ void -ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp) +ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp, + bfd_reloc_code_real_type code) { - bfd_reloc_code_real_type code; fixS *fix; switch (nbytes) @@ -11109,6 +11307,11 @@ ia64_gen_real_reloc_type (struct symbol *sym, bfd_reloc_code_real_type r_type) } break; +#ifdef TE_VMS + case FUNC_SLOTCOUNT_RELOC: + return DUMMY_RELOC_IA64_SLOTCOUNT; +#endif + default: abort (); } @@ -11255,7 +11458,7 @@ md_apply_fix (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED) } if (fix->fx_addsy) { - switch (fix->fx_r_type) + switch ((unsigned) fix->fx_r_type) { case BFD_RELOC_UNUSED: /* This must be a TAG13 or TAG13b operand. There are no external @@ -11278,12 +11481,48 @@ md_apply_fix (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED) S_SET_THREAD_LOCAL (fix->fx_addsy); break; +#ifdef TE_VMS + case DUMMY_RELOC_IA64_SLOTCOUNT: + as_bad_where (fix->fx_file, fix->fx_line, + _("cannot resolve @slotcount parameter")); + fix->fx_done = 1; + return; +#endif + default: break; } } else if (fix->tc_fix_data.opnd == IA64_OPND_NIL) { +#ifdef TE_VMS + if (fix->fx_r_type == DUMMY_RELOC_IA64_SLOTCOUNT) + { + /* For @slotcount, convert an addresses difference to a slots + difference. */ + valueT v; + + v = (value >> 4) * 3; + switch (value & 0x0f) + { + case 0: + case 1: + case 2: + v += value & 0x0f; + break; + case 0x0f: + v += 2; + break; + case 0x0e: + v += 1; + break; + default: + as_bad (_("invalid @slotcount value")); + } + value = v; + } +#endif + if (fix->tc_fix_data.bigendian) number_to_chars_bigendian (fixpos, value, fix->fx_size); else @@ -11305,8 +11544,8 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixp) { arelent *reloc; - reloc = xmalloc (sizeof (*reloc)); - reloc->sym_ptr_ptr = (asymbol **) 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; reloc->addend = fixp->fx_offset; @@ -11328,9 +11567,7 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixp) of LITTLENUMS emitted is stored in *SIZE. An error message is returned, or NULL on OK. */ -#define MAX_LITTLENUMS 5 - -char * +const char * md_atof (int type, char *lit, int *size) { LITTLENUM_TYPE words[MAX_LITTLENUMS]; @@ -11414,7 +11651,7 @@ ia64_handle_align (fragS *fragp) bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix; p = fragp->fr_literal + fragp->fr_fix; - /* If no paddings are needed, we check if we need a stop bit. */ + /* If no paddings are needed, we check if we need a stop bit. */ if (!bytes && fragp->tc_frag_data) { if (fragp->fr_fix < 16) @@ -11499,7 +11736,7 @@ ia64_check_label (symbolS *label) the relocatable file. */ struct alias { - char *file; /* The file where the directive is seen. */ + const char *file; /* The file where the directive is seen. */ unsigned int line; /* The line number the directive is at. */ const char *name; /* The original name of the symbol. */ }; @@ -11519,8 +11756,7 @@ dot_alias (int section) struct hash_control *ahash, *nhash; const char *kind; - name = input_line_pointer; - delim = get_symbol_end (); + delim = get_symbol_name (&name); end_name = input_line_pointer; *end_name = delim; @@ -11531,7 +11767,7 @@ dot_alias (int section) return; } - SKIP_WHITESPACE (); + SKIP_WHITESPACE_AFTER_NAME (); if (*input_line_pointer != ',') { @@ -11592,10 +11828,10 @@ dot_alias (int section) goto out; } - h = (struct alias *) xmalloc (sizeof (struct alias)); - as_where (&h->file, &h->line); + h = XNEW (struct alias); + h->file = as_where (&h->line); h->name = name; - + error_string = hash_jam (ahash, alias, (void *) h); if (error_string) { @@ -11609,7 +11845,7 @@ dot_alias (int section) { as_fatal (_("inserting \"%s\" into %s name hash table failed: %s"), alias, kind, error_string); -out: + out: obstack_free (¬es, name); obstack_free (¬es, alias); } @@ -11699,7 +11935,6 @@ ia64_vms_note (void) char *p; asection *seg = now_seg; subsegT subseg = now_subseg; - Elf_Internal_Note i_note; asection *secp = NULL; char *bname; char buf [256]; @@ -11708,43 +11943,29 @@ ia64_vms_note (void) /* Create the .note section. */ secp = subseg_new (".note", 0); - bfd_set_section_flags (stdoutput, - secp, - SEC_HAS_CONTENTS | SEC_READONLY); + bfd_set_section_flags (secp, SEC_HAS_CONTENTS | SEC_READONLY); - /* Module header note. */ + /* Module header note (MHD). */ bname = xstrdup (lbasename (out_file_name)); if ((p = strrchr (bname, '.'))) *p = '\0'; - i_note.namesz = 8; - i_note.descsz = 40 + strlen (bname); - i_note.type = NT_VMS_MHD; - - p = frag_more (sizeof (i_note.namesz)); - number_to_chars_littleendian (p, i_note.namesz, 8); - - p = frag_more (sizeof (i_note.descsz)); - number_to_chars_littleendian (p, i_note.descsz, 8); - - p = frag_more (sizeof (i_note.type)); - number_to_chars_littleendian (p, i_note.type, 8); + /* VMS note header is 24 bytes long. */ + p = frag_more (8 + 8 + 8); + number_to_chars_littleendian (p + 0, 8, 8); + number_to_chars_littleendian (p + 8, 40 + strlen (bname), 8); + number_to_chars_littleendian (p + 16, NT_VMS_MHD, 8); p = frag_more (8); strcpy (p, "IPF/VMS"); - get_vms_time (buf); - p = frag_more (17); - strcpy (p, buf); - - p = frag_more (17); - strcpy (p, "24-FEB-2005 15:00"); - - p = frag_more (strlen (bname) + 1); + p = frag_more (17 + 17 + strlen (bname) + 1 + 5); + get_vms_time (p); + strcpy (p + 17, "24-FEB-2005 15:00"); + p += 17 + 17; strcpy (p, bname); + p += strlen (bname) + 1; free (bname); - - p = frag_more (5); strcpy (p, "V1.0"); frag_align (3, 0, 0); @@ -11753,18 +11974,10 @@ ia64_vms_note (void) sprintf (buf, "GNU assembler version %s (%s) using BFD version %s", VERSION, TARGET_ALIAS, BFD_VERSION_STRING); - i_note.namesz = 8; - i_note.descsz = 1 + strlen (buf); - i_note.type = NT_VMS_LNM; - - p = frag_more (sizeof (i_note.namesz)); - number_to_chars_littleendian (p, i_note.namesz, 8); - - p = frag_more (sizeof (i_note.descsz)); - number_to_chars_littleendian (p, i_note.descsz, 8); - - p = frag_more (sizeof (i_note.type)); - number_to_chars_littleendian (p, i_note.type, 8); + p = frag_more (8 + 8 + 8); + number_to_chars_littleendian (p + 0, 8, 8); + number_to_chars_littleendian (p + 8, strlen (buf) + 1, 8); + number_to_chars_littleendian (p + 16, NT_VMS_LNM, 8); p = frag_more (8); strcpy (p, "IPF/VMS"); @@ -11775,9 +11988,7 @@ ia64_vms_note (void) frag_align (3, 0, 0); secp = subseg_new (".vms_display_name_info", 0); - bfd_set_section_flags (stdoutput, - secp, - SEC_HAS_CONTENTS | SEC_READONLY); + bfd_set_section_flags (secp, SEC_HAS_CONTENTS | SEC_READONLY); /* This symbol should be passed on the command line and be variable according to language. */