diff options
author | Ken Raeburn <raeburn@cygnus> | 1995-06-06 17:59:06 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@cygnus> | 1995-06-06 17:59:06 +0000 |
commit | d5263ab42614d8c28eab1aea09ccba5a86d80866 (patch) | |
tree | f22fc4bcd2cbda64943682e69c09f63f11b7c687 /gas/config/obj-vms.c | |
parent | 5c172b4bfde5f6aab86afa5441ef849b3e95ab2e (diff) | |
download | gdb-d5263ab42614d8c28eab1aea09ccba5a86d80866.zip gdb-d5263ab42614d8c28eab1aea09ccba5a86d80866.tar.gz gdb-d5263ab42614d8c28eab1aea09ccba5a86d80866.tar.bz2 |
* 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.
Diffstat (limited to 'gas/config/obj-vms.c')
-rw-r--r-- | gas/config/obj-vms.c | 138 |
1 files changed, 121 insertions, 17 deletions
diff --git a/gas/config/obj-vms.c b/gas/config/obj-vms.c index 1aee7a7..70819a2 100644 --- a/gas/config/obj-vms.c +++ b/gas/config/obj-vms.c @@ -200,6 +200,14 @@ static int struct_number; 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 @@ -3656,9 +3664,10 @@ VMS_Modify_Psect_Attributes (Name, Attribute_Pointer) #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) @@ -3679,9 +3688,10 @@ 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 */ @@ -3695,18 +3705,23 @@ VMS_Global_Symbol_Spec (Name, Psect_Number, Psect_Offset, Flags) * 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); } @@ -3727,8 +3742,40 @@ VMS_Global_Symbol_Spec (Name, Psect_Number, Psect_Offset, Flags) /* * 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 (); } @@ -3792,7 +3839,9 @@ VMS_Psect_Spec (Name, Size, Type, vsp) /* * 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. @@ -3951,7 +4000,7 @@ VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment) int Size; int Psect_Attributes; int globalvalue; - int typ; + int typ, abstyp; /* * Scan the symbol table for globalvalues, and emit def/ref when @@ -3961,10 +4010,12 @@ VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment) 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; /* @@ -3972,18 +4023,39 @@ VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment) */ 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; @@ -4197,6 +4269,7 @@ VMS_Store_PIC_Symbol_Reference (Symbol, Offset, PC_Relative, { register struct VMS_Symbol *vsp = Symbol->sy_obj; char Local[32]; + int local_sym = 0; /* * We are writing a "Record_Type" record @@ -4238,6 +4311,10 @@ VMS_Store_PIC_Symbol_Reference (Symbol, Offset, PC_Relative, /* * 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: @@ -4251,7 +4328,16 @@ VMS_Store_PIC_Symbol_Reference (Symbol, Offset, PC_Relative, /* * 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) { @@ -4857,7 +4943,7 @@ vms_write_object_file (text_siz, data_siz, bss_siz, text_frag_root, 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. @@ -4946,6 +5032,24 @@ vms_write_object_file (text_siz, data_siz, bss_siz, text_frag_root, 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 */ default: |