/* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
- Copyright (C) 1989-2015 Free Software Foundation, Inc.
+ Copyright (C) 1989-2019 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.
#include "as.h"
#include "subsegs.h"
-#include "struc-symbol.h"
#include "ecoff.h"
#include "opcode/alpha.h"
/* 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:";
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 const char *s_alpha_section_name (void);
static symbolS *add_to_link_pool (symbolS *, offsetT);
#endif
\f
present. Not implemented.
Also suppress the optimization if the !literals/!lituses are spread
- in different segments. This can happen with "intersting" uses of
+ in different segments. This can happen with "interesting" uses of
inline assembly; examples are present in the Linux kernel semaphores. */
for (fixp = seginfo->fix_root; fixp; fixp = next)
/* ... then fall through to plain expression. */
input_line_pointer = hold;
}
+ /* Fall through. */
default:
if (saw_arg && !saw_comma)
*secp = new_sec = subseg_new (name, 0);
subseg_set (current_section, current_subsec);
- bfd_set_section_alignment (stdoutput, new_sec, 4);
- bfd_set_section_flags (stdoutput, new_sec,
- SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
- | SEC_DATA);
+ bfd_set_section_alignment (new_sec, 4);
+ bfd_set_section_flags (new_sec, (SEC_RELOC | SEC_ALLOC | SEC_LOAD
+ | SEC_READONLY | SEC_DATA));
S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
}
ptr1 = strstr (symname, "..") + 2;
if (ptr1 > ptr2)
ptr1 = symname;
- ensymname = (char *) alloca (ptr2 - ptr1 + 5);
+ ensymname = XNEWVEC (char, ptr2 - ptr1 + 5);
memcpy (ensymname, ptr1, ptr2 - ptr1);
memcpy (ensymname + (ptr2 - ptr1), "..en", 5);
gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_NOP;
ensym = symbol_find_or_make (ensymname);
+ 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
ptr1 = strstr (symname, "..") + 2;
if (ptr1 > ptr2)
ptr1 = symname;
- psymname = (char *) alloca (ptr2 - ptr1 + 1);
- memcpy (psymname, ptr1, ptr2 - ptr1);
- psymname [ptr2 - ptr1] = 0;
+ 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);
+ free (psymname);
symbol_mark_used (psym);
insn.fixups[insn.nfixups].exp.X_op = O_subtract;
insn.fixups[insn.nfixups].exp.X_add_symbol = psym;
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))
char *ensymname;
/* Build the entry name as 'NAME..en'. */
- ensymname = (char *) alloca (symlen + 5);
+ ensymname = XNEWVEC (char, symlen + 5);
memcpy (ensymname, symname, symlen);
memcpy (ensymname + symlen, "..en", 5);
insn.fixups[0].procsym = alpha_evax_proc->symbol;
insn.nfixups++;
alpha_linkage_symbol = 0;
+ free (ensymname);
}
#endif
#ifdef OBJ_EVAX
/* Add sym+addend to link pool.
- Return offset from curent procedure value (pv) to entry in link pool.
+ Return offset from current procedure value (pv) to entry in link pool.
Add new fixup only if offset isn't 16bit. */
&& fixp->fx_offset == (valueT)addend
&& fixp->tc_fix_data.info
&& fixp->tc_fix_data.info->sym
- && fixp->tc_fix_data.info->sym->sy_value.X_op_symbol == basesym)
+ && symbol_symbolS (fixp->tc_fix_data.info->sym)
+ && (symbol_get_value_expression (fixp->tc_fix_data.info->sym)
+ ->X_op_symbol == basesym))
return fixp->tc_fix_data.info->sym;
}
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;
}
#ifndef OBJ_EVAX
- know (symbolP->sy_frag == &zero_address_frag);
+ know (symbol_get_frag (symbolP) == &zero_address_frag);
#endif
demand_empty_rest_of_line ();
}
sym = symbol_find_or_make (name);
symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
- cur_frame_data = (struct alpha_elf_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. */
if (sym && cur_frame_data)
{
OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
- expressionS *exp = (expressionS *) xmalloc (sizeof (expressionS));
+ expressionS *exp = XNEW (expressionS);
obj->size = exp;
exp->X_op = O_subtract;
discard_rest_of_line ();
len = input_line_pointer - start;
- first_file_directive = (char *) xmalloc (len + 1);
- memcpy (first_file_directive, start, len);
- first_file_directive[len] = '\0';
+ first_file_directive = xmemdup0 (start, len);
input_line_pointer = start;
}
if (alpha_flag_mdebug < 0)
{
segT sec = subseg_new (".mdebug", 0);
- bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
- bfd_set_section_alignment (stdoutput, sec, 3);
+ bfd_set_section_flags (sec, SEC_HAS_CONTENTS | SEC_READONLY);
+ bfd_set_section_alignment (sec, 3);
ecoff_read_begin_hook ();
#ifdef OBJ_EVAX
/* Get name of section. */
-static char *
+static const char *
s_alpha_section_name (void)
{
char *name;
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 ();
#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)
{
- char *name, *beg;
+ const char *name;
+ char *beg;
segT sec;
flagword vms_flags = 0;
symbolS *symbol;
(FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
/* Create a linkage element. */
- linkage_fixup = (struct alpha_linkage_fixups *)
- xmalloc (sizeof (struct alpha_linkage_fixups));
+ linkage_fixup = XNEW (struct alpha_linkage_fixups);
linkage_fixup->fixp = fixp;
linkage_fixup->next = NULL;
linkage_fixup->label = alpha_insn_label;
}
/* Handle floating point allocation pseudo-ops. This is like the
- generic vresion, but it makes sure the current label, if any, is
+ generic version, but it makes sure the current label, if any, is
correctly aligned. */
static void
if (!sec)
return;
- vma = bfd_get_section_vma (sec->owner, sec);
+ vma = bfd_section_vma (sec);
if (vma && vma < alpha_gp_value)
alpha_gp_value = vma;
}
/* 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;
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
if ((slash = strchr (name, '/')) != NULL)
{
- char *p = (char *) xmalloc (strlen (name));
+ char *p = XNEWVEC (char, strlen (name));
memcpy (p, name, slash - name);
strcpy (p + (slash - name), slash + 1);
if (ECOFF_DEBUGGING)
{
segT sec = subseg_new (".mdebug", (subsegT) 0);
- bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
- bfd_set_section_alignment (stdoutput, sec, 3);
+ bfd_set_section_flags (sec, SEC_HAS_CONTENTS | SEC_READONLY);
+ bfd_set_section_alignment (sec, 3);
}
#endif
valueT
md_section_align (segT seg, valueT size)
{
- int align = bfd_get_section_alignment (stdoutput, seg);
+ int align = bfd_section_alignment (seg);
valueT mask = ((valueT) 1 << align) - 1;
return (size + mask) & ~mask;
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)
{
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);
/* 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)
{
md_number_to_chars (fixpos, value, 2);
break;
+ case BFD_RELOC_8:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_8_PCREL;
+ size = 1;
+ goto do_reloc_xx;
+
case BFD_RELOC_16:
if (fixP->fx_pcrel)
fixP->fx_r_type = BFD_RELOC_16_PCREL;
return;
}
- if ((abs (value) >> 2) & ~0xfffff)
+ if (value + (1u << 22) >= (1u << 23))
goto done;
else
{
return;
}
- if ((abs (value)) & ~0x7fff)
+ if (value + (1u << 15) >= (1u << 16))
goto done;
else
{
return;
}
- if ((abs (value) >> 2) & ~0xfffff)
+ if (value + (1u << 22) >= (1u << 23))
{
/* Out of range. */
if (fixP->fx_r_type == BFD_RELOC_ALPHA_BOH)
{
arelent *reloc;
- reloc = (arelent *) 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;
if (pname_len > 4 && strcmp (pname + pname_len - 4, "..en") == 0)
{
symbolS *sym;
- char *my_pname = (char *) alloca (pname_len - 4 + 1);
-
- memcpy (my_pname, pname, pname_len - 4);
- 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 ();
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;