* Removed sy_forward and replaced it with an undefined expression
authorIan Lance Taylor <ian@airs.com>
Wed, 14 Jul 1993 22:21:25 +0000 (22:21 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 14 Jul 1993 22:21:25 +0000 (22:21 +0000)
as the value of a symbol.
* struc-symbol.h (struct symbol): Removed sy_forward field.  Added
sy_resolved and sy_resolving single bit fields.
* symbols.c (symbol_new): Don't initialize sy_forward field.
(resolve_symbol_value): New function to adjust symbol value by
fragment address, using recursion to resolve forward symbols.
* symbols.h: Added prototype for new function.
* read.c (pseudo_set): Set symbolP->sy_value to an undefined
expression rather than setting symbolP->sy_forward.
* write.c (write_object_file): Use resolve_symbol_value on
symbols, keeping the common case (the old behaviour) inline.
* config/obj-aout.c (obj_aout_frob_symbol): Removed sy_forward
handling (subsumed by write.c change).
* config/obj-coff.c, config/obj-coffbfd.c (obj_coff_val): Set
sy_value rather than sy_forward.
* config/obj-coffbfd.c (obj_coff_endef, yank_symbols): Check
expression segment rather than sy_forward.
(yank_symbols): Use resolve_symbol_value.
(crawl_symbols): Removed extra pass over symbols.
* config/obj-aout.c, config/obj-bout.c, config/obj-coff.c,
config/obj-vms.c (obj_crawl_symbol_chain): Removed extra pass over
symbols which handled sy_forward; use resolve_symbol_value
instead.
* config/obj-coff.h, config/obj-coffbfd.h (obj_frob_forward_symbol):
Define.
* config/obj-elf.c (obj_elf_stab_generic): Check expression
segment rather than sy_forward.
* config/obj-vms.c (VMS_Check_For_Main): Don't initialize
sy_forward; do initialize sy_resolved and sy_resolving.
* config/tc-hppa.h (STAB_FIXUP): Use sy_value, not sy_forward.

12 files changed:
gas/ChangeLog
gas/config/obj-aout.c
gas/config/obj-bout.c
gas/config/obj-coff.c
gas/config/obj-coffbfd.c
gas/config/obj-coffbfd.h
gas/config/obj-elf.c
gas/config/obj-vms.c
gas/config/tc-hppa.h [new file with mode: 0644]
gas/read.c
gas/symbols.c
gas/write.c

index 6027904b7ba4d2742249247c174903a7fa0b3fb5..87b2827cbe3bd5daf7e9c68e048aaa70322b947e 100644 (file)
@@ -1,5 +1,37 @@
 Wed Jul 14 15:09:32 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
+       * Removed sy_forward and replaced it with an undefined expression
+       as the value of a symbol.
+       * struc-symbol.h (struct symbol): Removed sy_forward field.  Added
+       sy_resolved and sy_resolving single bit fields.
+       * symbols.c (symbol_new): Don't initialize sy_forward field.
+       (resolve_symbol_value): New function to adjust symbol value by
+       fragment address, using recursion to resolve forward symbols.
+       * symbols.h: Added prototype for new function.
+       * read.c (pseudo_set): Set symbolP->sy_value to an undefined
+       expression rather than setting symbolP->sy_forward.
+       * write.c (write_object_file): Use resolve_symbol_value on
+       symbols, keeping the common case (the old behaviour) inline.
+       * config/obj-aout.c (obj_aout_frob_symbol): Removed sy_forward
+       handling (subsumed by write.c change).
+       * config/obj-coff.c, config/obj-coffbfd.c (obj_coff_val): Set
+       sy_value rather than sy_forward.
+       * config/obj-coffbfd.c (obj_coff_endef, yank_symbols): Check
+       expression segment rather than sy_forward.
+       (yank_symbols): Use resolve_symbol_value.
+       (crawl_symbols): Removed extra pass over symbols.
+       * config/obj-aout.c, config/obj-bout.c, config/obj-coff.c,
+       config/obj-vms.c (obj_crawl_symbol_chain): Removed extra pass over
+       symbols which handled sy_forward; use resolve_symbol_value
+       instead.
+       * config/obj-coff.h, config/obj-coffbfd.h (obj_frob_forward_symbol):
+       Define.
+       * config/obj-elf.c (obj_elf_stab_generic): Check expression
+       segment rather than sy_forward.
+       * config/obj-vms.c (VMS_Check_For_Main): Don't initialize
+       sy_forward; do initialize sy_resolved and sy_resolving.
+       * config/tc-hppa.h (STAB_FIXUP): Use sy_value, not sy_forward.
+
        * Changes to keep a full expression as the value of a symbol, not
        just a longword:
        * struc-symbol.h: New field sy_value.
index c074df2cd58d6fedb7caf50c4f4c3845b1768d00..38fead53e6f0cf7c57d266294d1dbdc1a3ed94dc 100644 (file)
@@ -110,17 +110,6 @@ obj_aout_frob_symbol (sym, punt)
   asection *sec;
   int desc, type, other;
 
-  /* Is this part format-dependent?  */
-  if (sym->sy_forward)
-    {
-      S_SET_VALUE (sym,
-                  S_GET_VALUE (sym)
-                  + S_GET_VALUE (sym->sy_forward)
-                  + sym->sy_forward->sy_frag->fr_address
-                  );
-      sym->sy_forward = 0;
-    }
-
   flags = sym->bsym->flags;
   desc = S_GET_DESC (sym);
   type = S_GET_TYPE (sym);
@@ -450,19 +439,6 @@ obj_crawl_symbol_chain (headers)
   symbolS **symbolPP;
   int symbol_number = 0;
 
-  /* JF deal with forward references first... */
-  for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
-    {
-      if (symbolP->sy_forward)
-       {
-         S_SET_VALUE (symbolP, S_GET_VALUE (symbolP)
-                      + S_GET_VALUE (symbolP->sy_forward)
-                      + symbolP->sy_forward->sy_frag->fr_address);
-
-         symbolP->sy_forward = 0;
-       }                       /* if it has a forward reference */
-    }                          /* walk the symbol chain */
-
   tc_crawl_symbol_chain (headers);
 
   symbolPP = &symbol_rootP;    /*->last symbol chain link. */
@@ -473,7 +449,7 @@ obj_crawl_symbol_chain (headers)
          S_SET_SEGMENT (symbolP, SEG_TEXT);
        }                       /* if pusing data into text */
 
-      S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
+      resolve_symbol_value (symbolP);
 
       /* OK, here is how we decide which symbols go out into the brave
         new symtab.  Symbols that do are:
index 3ef289db281f6e36a0aaafa1cbab34bd7fb85000..d467715b1174f76dc22a372c5d9f1018e52c05e0 100644 (file)
@@ -433,19 +433,6 @@ obj_crawl_symbol_chain (headers)
   symbolS *symbolP;
   int symbol_number = 0;
 
-  /* JF deal with forward references first... */
-  for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
-    {
-      if (symbolP->sy_forward)
-       {
-         S_SET_VALUE (symbolP, S_GET_VALUE (symbolP)
-                      + S_GET_VALUE (symbolP->sy_forward)
-                      + symbolP->sy_forward->sy_frag->fr_address);
-
-         symbolP->sy_forward = 0;
-       }                       /* if it has a forward reference */
-    }                          /* walk the symbol chain */
-
   tc_crawl_symbol_chain (headers);
 
   symbolPP = &symbol_rootP;    /*->last symbol chain link. */
@@ -456,7 +443,7 @@ obj_crawl_symbol_chain (headers)
          S_SET_SEGMENT (symbolP, SEG_TEXT);
        }                       /* if pusing data into text */
 
-      S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
+      resolve_symbol_value (symbolP);
 
       /* OK, here is how we decide which symbols go out into the
                   brave new symtab.  Symbols that do are:
index 3bf0e754cab21f1e7ed092bc57b02614811d0be0..e0eca7a815c5cae01d9efeb876be5e69d0d0fb85 100644 (file)
@@ -1620,11 +1620,15 @@ obj_coff_val ()
        }
       else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
        {
-         def_symbol_in_progress->sy_forward = symbol_find_or_make (symbol_name);
-
-         /* If the segment is undefined when the forward
-                          reference is solved, then copy the segment id
-                          from the forward symbol. */
+         def_symbol_in_progress->sy_value.X_add_symbol =
+           symbol_find_or_make (symbol_name);
+         def_symbol_in_progress->sy_value.X_subtract_symbol = NULL;
+         def_symbol_in_progress->sy_value.X_add_number = 0;
+         def_symbol_in_progress->sy_value.X_seg = undefined_section;
+
+         /* If the segment is undefined when the forward reference is
+            resolved, then copy the segment id from the forward
+            symbol.  */
          SF_SET_GET_SEGMENT (def_symbol_in_progress);
        }
       /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
@@ -1720,32 +1724,6 @@ obj_crawl_symbol_chain (headers)
   /* Initialize the stack used to keep track of the matching .bb .be */
   stack *block_stack = stack_init (512, sizeof (symbolS *));
 
-  /* JF deal with forward references first... */
-  for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
-    {
-
-      if (symbolP->sy_forward)
-       {
-         S_SET_VALUE (symbolP, (S_GET_VALUE (symbolP)
-                                + S_GET_VALUE (symbolP->sy_forward)
-                              + symbolP->sy_forward->sy_frag->fr_address));
-
-         if (
-#ifndef TE_I386AIX
-              SF_GET_GET_SEGMENT (symbolP)
-#else
-              SF_GET_GET_SEGMENT (symbolP)
-              && S_GET_SEGMENT (symbolP) == SEG_UNKNOWN
-#endif /* TE_I386AIX */
-           )
-           {
-             S_SET_SEGMENT (symbolP, S_GET_SEGMENT (symbolP->sy_forward));
-           }                   /* forward segment also */
-
-         symbolP->sy_forward = 0;
-       }                       /* if it has a forward reference */
-    }                          /* walk the symbol chain */
-
   tc_crawl_symbol_chain (headers);
 
   /* The symbol list should be ordered according to the following sequence
@@ -1864,7 +1842,7 @@ obj_crawl_symbol_chain (headers)
              S_SET_SEGMENT (symbolP, SEG_TEXT);
            }                   /* push data into text */
 
-         S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
+         resolve_symbol_value (symbolP);
 
          if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
            {
index d2884d376904c1603e84ff3c0c64c1386d6c53c8..d62bea7644588e3fdf9f6a1e641dcaffd7e75bfa 100644 (file)
@@ -990,7 +990,7 @@ DEFUN_VOID (obj_coff_endef)
       || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
          && !SF_GET_TAG (def_symbol_in_progress))
       || S_GET_SEGMENT (def_symbol_in_progress) == SEG_ABSOLUTE
-      || def_symbol_in_progress->sy_forward != NULL
+      || def_symbol_in_progress->sy_value.X_seg != absolute_section
       || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
       || (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
     {
@@ -1238,11 +1238,15 @@ obj_coff_val ()
        }
       else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
        {
-         def_symbol_in_progress->sy_forward = symbol_find_or_make (symbol_name);
-
-         /* If the segment is undefined when the forward
-                          reference is solved, then copy the segment id
-                          from the forward symbol. */
+         def_symbol_in_progress->sy_value.X_add_symbol =
+           symbol_find_or_make (symbol_name);
+         def_symbol_in_progress->sy_value.X_subtract_symbol = NULL;
+         def_symbol_in_progress->sy_value.X_add_number = 0;
+         def_symbol_in_progress->sy_value.X_seg = undefined_section;
+
+         /* If the segment is undefined when the forward reference is
+            resolved, then copy the segment id from the forward
+            symbol.  */
          SF_SET_GET_SEGMENT (def_symbol_in_progress);
 
          /* FIXME: gcc can generate address expressions
@@ -1369,7 +1373,7 @@ DEFUN_VOID (yank_symbols)
          /* L* and C_EFCN symbols never merge. */
          if (!SF_GET_LOCAL (symbolP)
              && S_GET_STORAGE_CLASS (symbolP) != C_LABEL
-             && symbolP->sy_forward == NULL
+             && symbolP->sy_value.X_seg == absolute_section
              && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
              && real_symbolP != symbolP)
            {
@@ -1396,8 +1400,7 @@ DEFUN_VOID (yank_symbols)
              S_SET_SEGMENT (symbolP, SEG_E0);
            }                   /* push data into text */
 
-         S_SET_VALUE (symbolP,
-                      S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
+         resolve_symbol_value (symbolP);
 
          if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
            {
@@ -1612,16 +1615,6 @@ DEFUN (crawl_symbols, (h, abfd),
   /* Initialize the stack used to keep track of the matching .bb .be */
 
   block_stack = stack_init (512, sizeof (symbolS *));
-  /* JF deal with forward references first... */
-  for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
-    if (symbolP->sy_forward)
-      {
-       S_SET_VALUE (symbolP, (S_GET_VALUE (symbolP)
-                              + S_GET_VALUE (symbolP->sy_forward)
-                              + symbolP->sy_forward->sy_frag->fr_address));
-       if (SF_GET_GET_SEGMENT (symbolP))
-         S_SET_SEGMENT (symbolP, S_GET_SEGMENT (symbolP->sy_forward));
-      }
 
   /* The symbol list should be ordered according to the following sequence
    * order :
index 98233400519109e4decb7f6f99edfcfe5f2fd260..9984a72a725cc68a92a0f9a89c5c02ee740408b2 100644 (file)
@@ -518,4 +518,10 @@ extern SCNHDR text_section_header;
 #endif
 #endif
 
+/* Forward the segment of a forwarded symbol.  */
+#define obj_frob_forward_symbol(symp) \
+  (SF_GET_GET_SEGMENT (symp) \
+   ? (S_SET_SEGMENT (symp, S_GET_SEGMENT (symp->sy_value.X_add_symbol)), 0) \
+   : 0)
+
 /* end of obj-coffbfd.h */
index 95ea6df85089a6c619d7efcee7b1b00f545ae585..89e8a244a12a5b0d827f37b24a12bfa18f7f3c0c 100644 (file)
@@ -486,7 +486,7 @@ obj_elf_stab_generic (what, secname)
       subseg_new ((char *) saved_seg->name, subseg);
 
       if ((what == 's' || what == 'n')
-         && symbolP->sy_forward == NULL)
+         && symbolP->sy_value.X_seg == absolute_section)
        {
          /* symbol is not needed in the regular symbol table */
          symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
index 4e4ab8048a440a480547df09e4faee3dcecda76a..3c29d189ae7a46575f91daf79104cf21267d8260 100644 (file)
@@ -546,18 +546,6 @@ obj_crawl_symbol_chain (headers)
   symbolS **symbolPP;
   int symbol_number = 0;
 
-  /* JF deal with forward references first... */
-  for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
-    {
-      if (symbolP->sy_forward)
-       {
-         S_SET_VALUE (symbolP, S_GET_VALUE (symbolP)
-                      + S_GET_VALUE (symbolP->sy_forward)
-                      + symbolP->sy_forward->sy_frag->fr_address);
-         symbolP->sy_forward = 0;
-       }                       /* if it has a forward reference */
-    }                          /* walk the symbol chain */
-
   {                            /* crawl symbol table */
     register int symbol_number = 0;
 
@@ -565,8 +553,7 @@ obj_crawl_symbol_chain (headers)
       symbolPP = &symbol_rootP;        /* -> last symbol chain link. */
       while ((symbolP = *symbolPP) != NULL)
        {
-         S_SET_VALUE (symbolP,
-                      S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
+         resolve_symbol_value (symbolP);
 
          /* OK, here is how we decide which symbols go out into the
             brave new symtab.  Symbols that do are:
@@ -4548,7 +4535,8 @@ VMS_Check_For_Main ()
                      symbolP->sy_name_offset = 0;
                      symbolP->sy_number = 0;
                      symbolP->sy_frag = New_Frag;
-                     symbolP->sy_forward = 0;
+                     symbolP->sy_resolved = 0;
+                     symbolP->sy_resolving = 0;
                      /* this actually inserts at the beginning of the list */
                      symbol_append (symbol_rootP, symbolP, &symbol_rootP, &symbol_lastP);
 
diff --git a/gas/config/tc-hppa.h b/gas/config/tc-hppa.h
new file mode 100644 (file)
index 0000000..308863f
--- /dev/null
@@ -0,0 +1,519 @@
+/* tc-hppa.h -- Header file for the PA */
+
+/* Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+/*
+   HP PA-RISC support was contributed by the Center for Software Science
+   at the University of Utah.
+ */
+
+#ifndef _TC_HPPA_H
+#define _TC_HPPA_H
+
+#ifndef TC_HPPA
+#define TC_HPPA        1
+#endif
+
+#define TARGET_ARCH bfd_arch_hppa
+#define TARGET_FORMAT "elf32-hppa"
+
+#define ASEC_NULL (asection *)0
+
+/* We can do sym1 - sym2 as long as sym2 is $global$ */
+
+#define SEG_DIFF_ALLOWED
+
+typedef enum FPOF
+  {
+    SGL, DBL, ILLEGAL_FMT, QUAD
+  } FP_Operand_Format;
+
+extern char *expr_end;
+
+extern void s_globl (), s_long (), s_short (), s_space (), cons ();
+extern void stringer ();
+extern unsigned int next_char_of_string ();
+
+extern void pa_big_cons ();
+extern void pa_cons ();
+extern void pa_data ();
+extern void pa_desc ();
+extern void pa_float_cons ();
+extern void pa_fill ();
+extern void pa_lcomm ();
+extern void pa_lsym ();
+extern void pa_stringer ();
+extern void pa_text ();
+extern void pa_version ();
+
+int pa_parse_number ();
+
+int pa_parse_fp_cmp_cond ();
+
+FP_Operand_Format pa_parse_fp_format ();
+
+#ifdef __STDC__
+int getExpression (char *str);
+#else
+int getExpression ();
+#endif
+
+int getAbsoluteExpression ();
+
+int evaluateAbsolute ();
+
+int pa_build_arg_reloc ();
+
+unsigned int pa_align_arg_reloc ();
+
+void pa_skip ();
+
+int pa_parse_nullif ();
+
+int pa_parse_nonneg_cmpsub_cmpltr ();
+
+int pa_parse_neg_cmpsub_cmpltr ();
+
+int pa_parse_nonneg_add_cmpltr ();
+
+int pa_parse_neg_add_cmpltr ();
+
+int pa_build_arg_reloc ();
+
+void s_seg (), s_proc (), s_data1 ();
+
+void pa_block (), pa_call (), pa_call_args (), pa_callinfo ();
+void pa_code (), pa_comm (), pa_copyright (), pa_end ();
+void pa_enter ();
+void pa_entry (), pa_equ (), pa_exit (), pa_export ();
+void pa_export_args (), pa_import (), pa_label (), pa_leave ();
+void pa_origin (), pa_proc (), pa_procend (), pa_space ();
+void pa_spnum (), pa_subspace (), pa_version ();
+
+extern const pseudo_typeS md_pseudo_table[];
+
+/*
+  PA-89 floating point registers are arranged like this:
+
+
+  +--------------+--------------+
+  |   0 or 16L   |  16 or 16R   |
+  +--------------+--------------+
+  |   1 or 17L   |  17 or 17R   |
+  +--------------+--------------+
+  |              |              |
+
+  .              .              .
+  .              .              .
+  .              .              .
+
+  |              |              |
+  +--------------+--------------+
+  |  14 or 30L   |  30 or 30R   |
+  +--------------+--------------+
+  |  15 or 31L   |  31 or 31R   |
+  +--------------+--------------+
+
+
+  The following is a version of pa_parse_number that
+  handles the L/R notation and returns the correct
+  value to put into the instruction register field.
+  The correct value to put into the instruction is
+  encoded in the structure 'pa_89_fp_reg_struct'.
+
+ */
+
+struct pa_89_fp_reg_struct
+  {
+    char number_part;
+    char L_R_select;
+  };
+
+int need_89_opcode ();
+int pa_89_parse_number ();
+
+
+/* pa-ctrl-func.h -- Control Structures and Functions for the PA */
+
+extern unsigned int assemble_3 ( /* unsigned int x; */ );
+
+extern void dis_assemble_3 ( /* unsigned int x, *r; */ );
+
+extern unsigned int assemble_12 ( /* unsigned int x,y; */ );
+
+extern void dis_assemble_12 ( /* unsigned int as12, *x,*y */ );
+
+extern unsigned long assemble_17 ( /* unsigned int x,y,z */ );
+
+extern void dis_assemble_17 ( /* unsigned int as17, *x,*y,*z */ );
+
+extern unsigned long assemble_21 ( /* unsigned int x; */ );
+
+extern void dis_assemble_21 ( /* unsigned int as21,*x; */ );
+
+extern void sign_unext ( /* unsigned int x,len; unsigned int *result */ );
+
+extern void low_sign_unext ( /* unsigned int x,len; unsigned int *result */ );
+
+struct call_desc
+  {
+    unsigned int arg_reloc;
+    unsigned int arg_count;
+  };
+
+typedef struct call_desc call_descS;
+
+extern call_descS last_call_desc;
+
+/* GDB debug support */
+
+#if defined(OBJ_SOME)
+#define GDB_DEBUG_SPACE_NAME "$GDB_DEBUG$"
+#define GDB_STRINGS_SUBSPACE_NAME "$GDB_STRINGS$"
+#define GDB_SYMBOLS_SUBSPACE_NAME "$GDB_SYMBOLS$"
+#else
+#define GDB_DEBUG_SPACE_NAME ".stab"
+#define GDB_STRINGS_SUBSPACE_NAME ".stabstr"
+#define GDB_SYMBOLS_SUBSPACE_NAME ".stab"
+#endif
+/* pre-defined subsegments (subspaces) for the HP 9000 Series 800 */
+
+#define SUBSEG_CODE   0
+#define SUBSEG_DATA   0
+#define SUBSEG_LIT    1
+#define SUBSEG_BSS    2
+#define SUBSEG_UNWIND 3
+#define SUBSEG_GDB_STRINGS 0
+#define SUBSEG_GDB_SYMBOLS 1
+
+#define UNWIND_SECTION_NAME    ".hppa_unwind"
+/* subspace dictionary chain entry structure */
+
+struct subspace_dictionary_chain
+  {
+#if defined(OBJ_OSFROSE) | defined(OBJ_ELF)
+#ifdef OBJ_OSFROSE
+    region_command_t *ssd_entry;/* XXX: not sure this is what we need here */
+#else
+    Elf_Internal_Shdr *ssd_entry;
+    unsigned long ssd_vm_addr;
+#endif
+    char *ssd_name;            /* used until time of writing object file       */
+    /* then we use ssd_entry->regc_region_name */
+    unsigned char ssd_quadrant;
+    unsigned char ssd_sort_key;
+    unsigned char ssd_common;
+    unsigned char ssd_dup_common;
+    unsigned char ssd_loadable;
+    unsigned char ssd_code_only;
+#else
+    subspace_dictS *ssd_entry; /* this dictionary */
+#endif
+    int ssd_defined;           /* this subspace has been used */
+    int ssd_space_number;      /* space # this subspace is in */
+    asection *ssd_seg;         /* this subspace =  this seg */
+    int ssd_subseg;            /*                  and subseg */
+    int ssd_zero;
+    int object_file_index;     /* index of this entry within
+                                                     the subspace dictionary of
+                                                     the object file (not used until
+                                                     the object file is written */
+    int ssd_last_align;                /* the size of the last alignment
+                                                     request for this subspace */
+    symbolS *ssd_start_sym;    /* a symbol whose value is the
+                                                     start of this subspace */
+    struct subspace_dictionary_chain *ssd_next;        /* next subspace dict. entry */
+  };
+
+typedef struct subspace_dictionary_chain subspace_dict_chainS;
+
+/* space dictionary chain entry structure */
+
+struct space_dictionary_chain
+  {
+#ifdef OBJ_OSFROSE
+    region_command_t *sd_entry;        /* XXX: not sure this is what we need here */
+    char *sd_name;             /* used until time of writing object file       */
+    /* then we use sd_entry->regc_region_name  */
+    unsigned int sd_loadable;
+    unsigned int sd_private;
+    unsigned int sd_spnum;
+    unsigned char sd_sort_key;
+#else
+#ifdef OBJ_ELF
+    Elf_Internal_Shdr *sd_entry;
+    char *sd_name;             /* used until time of writing object file       */
+    /* then we use sd_entry->sh_name   */
+    unsigned int sd_loadable;
+    unsigned int sd_private;
+    unsigned int sd_spnum;
+    unsigned char sd_sort_key;
+#else
+    space_dictS *sd_entry;     /* this dictionary */
+#endif
+#endif
+    int sd_defined;            /* this space has been used */
+    asection *sd_seg;          /* GAS segment to which this space corresponds */
+    int sd_last_subseg;                /* current subsegment number we are using */
+    subspace_dict_chainS *sd_subspaces;        /* all subspaces in this space */
+    struct space_dictionary_chain *sd_next;    /* the next space dict. entry */
+  };
+
+typedef struct space_dictionary_chain space_dict_chainS;
+
+/*
+    Macros to maintain spaces and subspaces
+ */
+
+#ifdef OBJ_OSFROSE
+#define SPACE_DEFINED(space_chain)     (space_chain)->sd_defined
+#define SPACE_PRIVATE(space_chain)     (space_chain)->sd_private
+#define SPACE_LOADABLE(space_chain)    (space_chain)->sd_loadable
+#define SPACE_SPNUM(space_chain)       (space_chain)->sd_spnum
+#define SPACE_SORT(space_chain)                (space_chain)->sd_sort_key
+#define SPACE_NAME(space_chain)                (space_chain)->sd_name
+
+#define SUBSPACE_QUADRANT(ss_chain)    (ss_chain)->ssd_quadrant
+#define SUBSPACE_ALIGN(ss_chain)       (ss_chain)->ssd_entry->regc_addralign
+#define SUBSPACE_ACCESS(ss_chain)      (ss_chain)->ssd_entry->regc_initprot
+#define SUBSPACE_SORT(ss_chain)                (ss_chain)->ssd_sort_key
+#define SUBSPACE_COMMON(ss_chain)      (ss_chain)->ssd_common
+#define SUBSPACE_ZERO(ss_chain)                (ss_chain)->ssd_zero
+#define SUBSPACE_DUP_COMM(ss_chain)    (ss_chain)->ssd_dup_common
+#define SUBSPACE_CODE_ONLY(ssch)       ((ssch)->ssd_entry->regc_flags & REG_TEXT_T)
+#define SET_SUBSPACE_CODE_ONLY(ssch,val) (ssch)->ssd_entry->regc_flags |= ((val) ? REG_TEXT_T : 0)
+#define SUBSPACE_LOADABLE(ss_chain)    (ss_chain)->ssd_loadable
+#define SUBSPACE_SUBSPACE_START(ss_chain) (ss_chain)->ssd_entry->regc_addr.vm_addr
+#define SUBSPACE_SUBSPACE_LENGTH(ss_chain) (ss_chain)->ssd_entry->regc_vm_size
+#define SUBSPACE_REGION_NAME(ss_chain) (ss_chain)->ssd_entry->regc_region_name
+#define SUBSPACE_NAME(ss_chain)                (ss_chain)->ssd_name
+#endif
+
+#ifdef OBJ_ELF
+#define RELOC_EXPANSION_POSSIBLE
+#define MAX_RELOC_EXPANSION 5
+
+#define SPACE_DEFINED(space_chain)     (space_chain)->sd_defined
+#define SPACE_PRIVATE(space_chain)     (space_chain)->sd_private
+#define SPACE_LOADABLE(space_chain)    (space_chain)->sd_loadable
+#define SPACE_SPNUM(space_chain)       (space_chain)->sd_spnum
+#define SPACE_SORT(space_chain)                (space_chain)->sd_sort_key
+#define SPACE_NAME(space_chain)                (space_chain)->sd_name
+
+#define SUBSPACE_QUADRANT(ss_chain)    (ss_chain)->ssd_quadrant
+#define SUBSPACE_ALIGN(ss_chain)       (ss_chain)->ssd_entry->sh_addralign
+#define SUBSPACE_ACCESS(ss_chain)      (ss_chain)->ssd_entry->sh_flags
+#define SUBSPACE_SORT(ss_chain)                (ss_chain)->ssd_sort_key
+#define SUBSPACE_COMMON(ss_chain)      (ss_chain)->ssd_common
+#define SUBSPACE_ZERO(ss_chain)                (ss_chain)->ssd_zero
+#define SUBSPACE_DUP_COMM(ss_chain)    (ss_chain)->ssd_dup_common
+#define SUBSPACE_CODE_ONLY(ssch) \
+       (((ssch)->ssd_entry->sh_flags & (SHF_ALLOC | SHF_EXECINSTR | SHF_WRITE)) \
+        == (SHF_ALLOC | SHF_EXECINSTR))
+#define SET_SUBSPACE_CODE_ONLY(ssch,val) \
+               (ssch)->ssd_entry->sh_flags &= ((val) ? ~SHF_WRITE : 0xffffffff)
+#define SUBSPACE_LOADABLE(ss_chain)    (ss_chain)->ssd_loadable
+#define SUBSPACE_SUBSPACE_START(ss_chain) (ss_chain)->ssd_vm_addr
+#define SUBSPACE_SUBSPACE_LENGTH(ss_chain) (ss_chain)->ssd_entry->sh_size
+#define SUBSPACE_NAME(ss_chain)                (ss_chain)->ssd_name
+
+#define STAB_FIXUP(frag,toptr,symP,stab_type)  \
+               if ( (stab_type == 's' || stab_type == 'n')     \
+                   && symP->sy_value.X_seg == undefined_section) \
+                 {                                             \
+                    int i = S_GET_TYPE(symP) & N_TYPE;         \
+                    fix_new_hppa(frag,                         \
+                                 toptr-frag->fr_literal, /* where */   \
+                                 4,            /* size */      \
+                                 symP->sy_value.X_add_symbol,  /* addr of sym for this stab */ \
+                                 (asymbol *)NULL,              \
+                                 0,                            \
+                                 i == N_UNDF || i == N_ABS,    /* 1 if internal reloc */       \
+                                 R_HPPA,       /* type */      \
+                                 e_fsel,       /* fixup fld = F% */    \
+                                 32,                           \
+                                 0,            /* arg_reloc */ \
+                                 (char *)0                     \
+                                 );                            \
+                 }                                             \
+               else if ( stab_type == 'd' )                    \
+                 {                                             \
+                    fix_new_hppa (frag,                        \
+                                  toptr-frag->fr_literal, /* where */  \
+                                  4,           /* size */      \
+                                  symP,        /* addr of sym for this stab */ \
+                                  (asymbol *)NULL,             \
+                                  0,                           \
+                                  0,                           \
+                                  R_HPPA,      /* type */      \
+                                  e_fsel,      /* fixup fld = F% */    \
+                                  32,                          \
+                                  0,           /* arg_reloc */ \
+                                  (char *)0                    \
+                                  );                           \
+                 }
+
+#endif
+
+#ifdef OBJ_SOM
+#define SPACE_DEFINED(space_chain)     (space_chain)->sd_entry->is_defined
+#define SPACE_PRIVATE(space_chain)     (space_chain)->sd_entry->is_private
+#define SPACE_LOADABLE(space_chain)    (space_chain)->sd_entry->is_loadable
+#define SPACE_SPNUM(space_chain)       (space_chain)->sd_entry->space_number
+#define SPACE_SORT(space_chain)                (space_chain)->sd_entry->sort_key
+#define SPACE_NAME(space_chain)                (space_chain)->sd_entry->name
+
+#define SUBSPACE_QUADRANT(ss_chain)    (ss_chain)->ssd_entry->quadrant
+#define SUBSPACE_ALIGN(ss_chain)       (ss_chain)->ssd_entry->alignment
+#define SUBSPACE_ACCESS(ss_chain)      (ss_chain)->ssd_entry->access_control_bits
+#define SUBSPACE_SORT(ss_chain)                (ss_chain)->ssd_entry->sort_key
+#define SUBSPACE_COMMON(ss_chain)      (ss_chain)->ssd_entry->is_common
+#define SUBSPACE_ZERO(ss_chain)                (ss_chain)->ssd_zero
+#define SUBSPACE_DUP_COMM(ss_chain)    (ss_chain)->ssd_entry->dup_common
+#define SUBSPACE_CODE_ONLY(ss_chain)   (ss_chain)->ssd_entry->code_only
+#define SUBSPACE_LOADABLE(ss_chain)    (ss_chain)->ssd_entry->is_loadable
+#define SUBSPACE_SUBSPACE_START(ss_chain) (ss_chain)->ssd_entry->subspace_start
+#define SUBSPACE_SUBSPACE_LENGTH(ss_chain) (ss_chain)->ssd_entry->subspace_length
+#define SUBSPACE_NAME(ss_chain)                (ss_chain)->ssd_entry->name
+#endif
+
+extern space_dict_chainS *space_dict_root;
+extern space_dict_chainS *space_dict_last;
+
+extern space_dict_chainS *current_space;
+extern subspace_dict_chainS *current_subspace;
+
+extern space_dict_chainS *create_new_space ();
+
+extern subspace_dict_chainS *create_new_subspace ();
+
+extern subspace_dict_chainS *update_subspace ();
+
+extern space_dict_chainS *is_defined_space ();
+
+extern space_dict_chainS *pa_segment_to_space ();
+
+extern subspace_dict_chainS *is_defined_subspace ();
+
+extern subspace_dict_chainS *pa_subsegment_to_subspace ();
+
+extern space_dict_chainS *pa_find_space_by_number ();
+
+extern unsigned int pa_subspace_start ();
+
+extern int is_last_defined_subspace ();
+
+/* symbol support */
+
+extern symbolS *pa_get_start_symbol ();
+
+extern symbolS *pa_set_start_symbol ();
+
+/* default space and subspace dictionaries */
+
+struct default_subspace_dict
+  {
+    char *name;
+    char defined;
+    char loadable, code_only, common, dup_common, zero, sort;
+    int access, space_index, alignment, quadrant;
+#ifdef OBJ_SOM
+    segT segment;
+#else
+    int def_space_index;       /* this is an index in the default spaces array */
+    char *alias;               /* an alias for this section (or NULL if there isn't one) */
+#endif
+    subsegT subsegment;
+  };
+
+extern struct default_subspace_dict pa_def_subspaces[];
+
+struct default_space_dict
+  {
+    char *name;
+    int spnum;
+    char loadable;
+    char defined;
+    char private;
+    char sort;
+#ifdef OBJ_SOM
+    segT segment;
+#else
+    asection *segment;
+    char *alias;               /* an alias for this section (or NULL if there isn't one) */
+#endif
+  };
+
+extern struct default_space_dict pa_def_spaces[];
+
+/*
+       Support for keeping track of the most recent label in each
+       space.
+ */
+
+typedef struct label_symbol_struct
+  {
+    symbolS *lss_label;                /* the label symbol             */
+    space_dict_chainS *lss_space;      /* the space to which it applies*/
+    struct label_symbol_struct *lss_next;      /* the next label symbol        */
+  } label_symbolS;
+
+extern label_symbolS *label_symbols_rootP;
+
+label_symbolS *pa_get_label ();
+int pa_label_is_defined ();
+void pa_define_label ();
+void pa_undefine_label ();
+int pa_pseudo_op_moves_pc ();
+
+/* end of label symbol support. */
+
+#define is_DP_relative(exp)  ( (exp).X_subtract_symbol         \
+                              && strcmp((exp).X_subtract_symbol->bsym->name,   \
+                                        "$global$") == 0 )
+
+#define is_PC_relative(exp)  ( (exp).X_subtract_symbol         \
+                              && strcmp((exp).X_subtract_symbol->bsym->name,   \
+                                        "$PIC_pcrel$0") == 0 )
+
+#define is_complex(exp) ((exp).X_seg && (exp).X_seg == diff_section)
+
+#define tc_crawl_symbol_chain(headers) {;}     /* Not used. */
+
+#define tc_headers_hook(headers) {;}   /* Not used. */
+
+#define elf_tc_symbol          elf_hppa_tc_symbol
+#define elf_tc_make_sections   elf_hppa_tc_make_sections
+extern void elf_hppa_final_processing ();
+#define elf_tc_final_processing        elf_hppa_final_processing
+
+/* We need to parse field selectors in .byte, etc.  */
+
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  parse_cons_expression_hppa (exp)
+#define TC_CONS_FIX_NEW cons_fix_new_hppa
+
+extern void parse_cons_expression_hppa PARAMS ((expressionS *exp));
+extern void cons_fix_new_hppa PARAMS ((fragS *frag,
+                                      int where,
+                                      int size,
+                                      expressionS *exp));
+
+#endif /* _TC_HPPA_H */
index afe9023214646377b81d254716748b369253c40a..2a5dabee9eaf271be77d3135d8e2774f0f3cd26c 100644 (file)
@@ -1499,13 +1499,19 @@ pseudo_set (symbolP)
     }
   else if (segment == pass1_section)
     {
-      symbolP->sy_forward = exp.X_add_symbol;
+      symbolP->sy_value.X_add_symbol = exp.X_add_symbol;
+      symbolP->sy_value.X_subtract_symbol = NULL;
+      symbolP->sy_value.X_add_number = 0;
+      symbolP->sy_value.X_seg = undefined_section;
       as_bad ("Unknown expression");
       know (need_pass_2 == 1);
     }
   else if (segment == undefined_section)
     {
-      symbolP->sy_forward = exp.X_add_symbol;
+      symbolP->sy_value.X_add_symbol = exp.X_add_symbol;
+      symbolP->sy_value.X_subtract_symbol = NULL;
+      symbolP->sy_value.X_add_number = 0;
+      symbolP->sy_value.X_seg = undefined_section;
     }
   else
     {
index 24fe3d84697a7ba7ffd3466b225a7163b9f7a9d7..05db99a14e15d303e6598c7a32b6baa67ef3c88c 100644 (file)
@@ -118,7 +118,6 @@ symbol_new (name, segment, value, frag)
   symbol_clear_list_pointers(symbolP);
 
   symbolP->sy_frag = frag;
-  symbolP->sy_forward = NULL;
 #ifndef BFD_ASSEMBLER
   symbolP->sy_number = ~0;
   symbolP->sy_name_offset = ~0;
@@ -566,6 +565,53 @@ verify_symbol_chain_2 (sym)
   verify_symbol_chain (p, n);
 }
 
+/* Resolve the value of a symbol.  This is called during the final
+   pass over the symbol table to resolve any symbols with complex
+   values.  */
+
+void
+resolve_symbol_value (symp)
+     symbolS *symp;
+{
+  if (symp->sy_resolved)
+    return;
+
+  if (symp->sy_resolving)
+    {
+      as_bad ("Symbol definition loop encountered at %s",
+             S_GET_NAME (symp));
+      S_SET_VALUE (symp, (valueT) 0);
+    }
+  else
+    {
+      symp->sy_resolving = 1;
+
+      if (symp->sy_value.X_seg == absolute_section)
+       S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address);
+      else if (symp->sy_value.X_seg == undefined_section)
+       {
+         resolve_symbol_value (symp->sy_value.X_add_symbol);
+
+#ifdef obj_frob_forward_symbol
+         /* Some object formats need to forward the segment.  */
+         obj_frob_forward_symbol (symp);
+#endif
+
+         S_SET_VALUE (symp,
+                      (symp->sy_value.X_add_number
+                       + symp->sy_frag->fr_address
+                       + S_GET_VALUE (symp->sy_value.X_add_symbol)));
+       }
+      else
+       {
+         /* More cases need to be added here.  */
+         abort ();
+       }
+    }
+
+  symp->sy_resolved = 1;
+}
+
 #ifdef LOCAL_LABELS_DOLLAR
 
 /* Dollar labels look like a number followed by a dollar sign.  Eg, "42$".
@@ -953,7 +999,7 @@ S_GET_VALUE (s)
      symbolS *s;
 {
   if (s->sy_value.X_seg != absolute_section)
-    as_bad ("Attempt to get value of unresolved symbol");
+    as_bad ("Attempt to get value of unresolved symbol %s", S_GET_NAME (s));
   return (valueT) s->sy_value.X_add_number;
 }
 
index 63353e395a7af3062a66c77a8d9a7d6912b2b2c1..ca7c6253e77c69407112b39c16c07ab9a1aa4e8e 100644 (file)
@@ -1172,18 +1172,30 @@ write_object_file ()
        {
          int keep = 0;
 
-         S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address);
+         if (! symp->sy_resolved)
+           {
+             if (symp->sy_value.X_seg == absolute_section)
+               {
+                 /* This is the normal case; skip the call.  */
+                 S_SET_VALUE (symp,
+                              (S_GET_VALUE (symp)
+                               + symp->sy_frag->fr_address));
+                 symp->sy_resolved = 1;
+               }
+             else
+               resolve_symbol_value (symp);
+           }
+
          /* So far, common symbols have been treated like undefined symbols.
             Put them in the common section now.  */
          if (S_IS_DEFINED (symp) == 0
              && S_GET_VALUE (symp) != 0)
            S_SET_SEGMENT (symp, &bfd_com_section);
 #if 0
-         printf ("symbol `%s'\n\t@%x: value=%d flags=%x forward=%x seg=%s\n",
+         printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n",
                  S_GET_NAME (symp), symp,
                  S_GET_VALUE (symp),
                  symp->bsym->flags,
-                 symp->sy_forward,
                  segment_name (symp->bsym->section));
 #endif
          {