FUNC_LT_DTP_RELATIVE,
FUNC_LT_TP_RELATIVE,
FUNC_IPLT_RELOC,
+#ifdef TE_VMS
+ FUNC_SLOTCOUNT_RELOC,
+#endif
};
enum reg_symbol
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;
{ 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 } },
symbol_new (".<iplt>", undefined_section, FUNC_IPLT_RELOC,
&zero_address_frag);
+#ifdef TE_VMS
+ pseudo_func[FUNC_SLOTCOUNT_RELOC].u.sym =
+ symbol_new (".<slotcount>", undefined_section, FUNC_SLOTCOUNT_RELOC,
+ &zero_address_frag);
+#endif
+
if (md.tune != itanium1)
{
/* Convert MFI NOPs bundles into MMI NOPs bundles. */
}
/* 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)
}
break;
+#ifdef TE_VMS
+ case FUNC_SLOTCOUNT_RELOC:
+ return DUMMY_RELOC_IA64_SLOTCOUNT;
+#endif
+
default:
abort ();
}
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
char *p;
asection *seg = now_seg;
subsegT subseg = now_subseg;
- Elf_Internal_Note i_note;
asection *secp = NULL;
char *bname;
char buf [256];
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);
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");