+Tue Jun 6 13:53:06 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-vms.c (vms_write_object_file, case N_DATA): Use
+ strcmp against FAKE_LABEL_NAME instead of checking third
+ character. (Suggested by Pat Rankin.)
+
+Mon 5 Jun 20:10:46 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ Add support for N_ABS and N_ABS|N_EXT type symbols.
+
+ * config/obj-vms.h (LSY_S_M_{DEF,REL}, ENV_S_M_{DEF,NESTED}):
+ New macros for local symbols (from <lsydef.h> and <envdef.h>).
+ * config/obj-vms.c (Current_Environment): New file-scope variable.
+ (VMS_Local_Environment_Setup): New routine.
+ (GBLSYM_LCL): New macro.
+ (VMS_Global_Symbol_Spec): Handle local symbols too.
+ (VMS_Psect_Spec): Set GLOBALVALUE_BIT for absolute symbols.
+ (VMS_Emit_Globalvalues): Handle local and global absolute symbols.
+ (VMS_Store_PIC_Symbol_Reference): Ditto.
+ (vms_write_object_file: GSD symbol loop): Ditto.
+
+Mon Jun 5 16:10:40 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config/tc-arm.h (LOCAL_LABELS_FB): Define.
+
Mon Jun 5 02:17:58 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
* configure.in (i386-*-gnu*): Always use GNU ELF config.
static int vax_g_doubles = 0;
+/* Local symbol references (used to handle N_ABS symbols; gcc does not
+ generate those, but they're possible with hand-coded assembler input)
+ are always made relative to some particular environment. If the current
+ input has any such symbols, then we expect this to get incremented
+ exactly once and end up having all of them be in environment #0. */
+
+static int Current_Environment = -1;
+
/*
* Variable descriptors are used tell the debugger the data types of certain
#define GBLSYM_REF 0
#define GBLSYM_DEF 1
#define GBLSYM_VAL 2
+#define GBLSYM_LCL 4 /* not GBL after all... */
/*
- * Define a global symbol
+ * Define a global symbol (or possibly a local one).
*/
static void
VMS_Global_Symbol_Spec (Name, Psect_Number, Psect_Offset, Flags)
if (Object_Record_Offset == 0)
PUT_CHAR (OBJ_S_C_GSD);
/*
- * We are writing a Global symbol definition subrecord
+ * We are writing a Global (or local) symbol definition subrecord.
*/
- PUT_CHAR (((unsigned) Psect_Number <= 255) ? GSD_S_C_SYM : GSD_S_C_SYMW);
+ PUT_CHAR ((Flags & GBLSYM_LCL) != 0 ? GSD_S_C_LSY :
+ ((unsigned) Psect_Number <= 255) ? GSD_S_C_SYM : GSD_S_C_SYMW);
/*
* Data type is undefined
*/
* Reference
*/
PUT_SHORT (((Flags & GBLSYM_VAL) == 0) ? GSY_S_M_REL : 0);
+ if ((Flags & GBLSYM_LCL) != 0) /* local symbols have extra field */
+ PUT_SHORT (Current_Environment);
}
else
{
/*
* Definition
+ *[ assert (LSY_S_M_DEF == GSY_S_M_DEF && LSY_S_M_REL == GSY_S_M_REL); ]
*/
PUT_SHORT (((Flags & GBLSYM_VAL) == 0) ?
GSY_S_M_DEF | GSY_S_M_REL : GSY_S_M_DEF);
+ if ((Flags & GBLSYM_LCL) != 0) /* local symbols have extra field */
+ PUT_SHORT (Current_Environment);
/*
* Psect Number
*/
- if ((unsigned) Psect_Number <= 255)
+ if ((Flags & GBLSYM_LCL) == 0 && (unsigned) Psect_Number <= 255)
{
PUT_CHAR (Psect_Number);
}
/*
* Flush the buffer if it is more than 75% full
*/
- if (Object_Record_Offset >
- (sizeof (Object_Record_Buffer) * 3 / 4))
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+/*
+ * Define an environment to support local symbol references.
+ * This is just to mollify the linker; we don't actually do
+ * anything useful with it.
+ */
+static void
+VMS_Local_Environment_Setup (Env_Name)
+ const char *Env_Name;
+{
+ /* We are writing a GSD record. */
+ Set_VMS_Object_File_Record (OBJ_S_C_GSD);
+ /* If the buffer is empty we must insert the GSD record type. */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_GSD);
+ /* We are writing an ENV subrecord. */
+ PUT_CHAR (GSD_S_C_ENV);
+
+ ++Current_Environment; /* index of environment being defined */
+
+ /* ENV$W_FLAGS: we are defining the next environment. It's not nested. */
+ PUT_SHORT (ENV_S_M_DEF);
+ /* ENV$W_ENVINDX: index is always 0 for non-nested definitions. */
+ PUT_SHORT (0);
+
+ /* ENV$B_NAMLNG + ENV$T_NAME: environment name in ASCIC format. */
+ if (!Env_Name) Env_Name = "";
+ PUT_COUNTED_STRING ((char *)Env_Name);
+
+ /* Flush the buffer if it is more than 75% full. */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
Flush_VMS_Object_Record_Buffer ();
}
\f
/*
* Modify the psect attributes according to any attribute string
*/
- if (HAS_PSECT_ATTRIBUTES (Name))
+ if (vsp && S_GET_TYPE (vsp->Symbol) == N_ABS)
+ Psect_Attributes |= GLOBALVALUE_BIT;
+ else if (HAS_PSECT_ATTRIBUTES (Name))
VMS_Modify_Psect_Attributes (Name, &Psect_Attributes);
/*
* Check for globalref/def/val.
int Size;
int Psect_Attributes;
int globalvalue;
- int typ;
+ int typ, abstyp;
/*
* Scan the symbol table for globalvalues, and emit def/ref when
for (sp = symbol_rootP; sp; sp = sp->sy_next)
{
typ = S_GET_RAW_TYPE (sp);
+ abstyp = ((typ & ~N_EXT) == N_ABS);
/*
* See if this is something we want to look at.
*/
- if (typ != (N_DATA | N_EXT) &&
+ if (!abstyp &&
+ typ != (N_DATA | N_EXT) &&
typ != (N_UNDF | N_EXT))
continue;
/*
*/
Name = S_GET_NAME (sp);
- if (!HAS_PSECT_ATTRIBUTES (Name))
+ if (abstyp)
+ {
+ stripped_name = 0;
+ Psect_Attributes = GLOBALVALUE_BIT;
+ }
+ else if (HAS_PSECT_ATTRIBUTES (Name))
+ {
+ stripped_name = (char *) xmalloc (strlen (Name) + 1);
+ strcpy (stripped_name, Name);
+ Psect_Attributes = 0;
+ VMS_Modify_Psect_Attributes (stripped_name, &Psect_Attributes);
+ }
+ else
continue;
- stripped_name = (char *) xmalloc (strlen (Name) + 1);
- strcpy (stripped_name, Name);
- Psect_Attributes = 0;
- VMS_Modify_Psect_Attributes (stripped_name, &Psect_Attributes);
-
if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
{
switch (typ)
{
+ case N_ABS:
+ /* Local symbol references will want
+ to have an environment defined. */
+ if (Current_Environment < 0)
+ VMS_Local_Environment_Setup (".N_ABS");
+ VMS_Global_Symbol_Spec (Name, 0,
+ S_GET_VALUE(sp),
+ GBLSYM_DEF|GBLSYM_VAL|GBLSYM_LCL);
+ break;
+ case N_ABS | N_EXT:
+ VMS_Global_Symbol_Spec (Name, 0,
+ S_GET_VALUE(sp),
+ GBLSYM_DEF|GBLSYM_VAL);
+ break;
case N_UNDF | N_EXT:
VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL);
break;
{
register struct VMS_Symbol *vsp = Symbol->sy_obj;
char Local[32];
+ int local_sym = 0;
/*
* We are writing a "Record_Type" record
/*
* Global symbol
*/
+ case N_ABS:
+ local_sym = 1;
+ /*FALLTHRU*/
+ case N_ABS | N_EXT:
#ifdef NOT_VAX_11_C_COMPATIBLE
case N_UNDF | N_EXT:
case N_DATA | N_EXT:
/*
* Stack the global symbol value
*/
- PUT_CHAR (TIR_S_C_STA_GBL);
+ if (!local_sym)
+ {
+ PUT_CHAR (TIR_S_C_STA_GBL);
+ }
+ else
+ {
+ /* Local symbols have an extra field. */
+ PUT_CHAR (TIR_S_C_STA_LSY);
+ PUT_SHORT (Current_Environment);
+ }
PUT_COUNTED_STRING (Local);
if (Offset)
{
char *sym_name = S_GET_NAME (sp);
/* Always suppress local numeric labels. */
- if (!sym_name || strlen (sym_name) <= 2 || sym_name[2] != '\001')
+ if (!sym_name || strcmp (sym_name, FAKE_LABEL_NAME) != 0)
{
/*
* Make a VMS data symbol entry.
0,
GBLSYM_REF);
break;
+ /*
+ * Absolute symbol
+ */
+ case N_ABS:
+ case N_ABS | N_EXT:
+ /*
+ * gcc doesn't generate these;
+ * VMS_Emit_Globalvalue handles them though.
+ */
+ vsp = (struct VMS_Symbol *) xmalloc (sizeof (*vsp));
+ vsp->Symbol = sp;
+ vsp->Size = 4;
+ vsp->Psect_Index = 0;
+ vsp->Psect_Offset = S_GET_VALUE (sp);
+ vsp->Next = VMS_Symbols;
+ VMS_Symbols = vsp;
+ sp->sy_obj = vsp;
+ break;
/*
* Anything else
*/