* tc_mips.c (load_address): Reflect change to MAX_GPREL_OFFSET.
[deliverable/binutils-gdb.git] / gas / config / obj-coff.c
index 46a4ca861fe8b04aa421fe7470668946d158d349..9864cc05ef5ae68f976123f42cabf712352edae7 100644 (file)
@@ -1,5 +1,6 @@
 /* coff object file format
-   Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+   Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001
    Free Software Foundation, Inc.
 
    This file is part of GAS.
 #define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
 #endif
 
+/* This is used to hold the symbol built by a sequence of pseudo-ops
+   from .def and .endef.  */
+static symbolS *def_symbol_in_progress;
+
+typedef struct
+  {
+    unsigned long chunk_size;
+    unsigned long element_size;
+    unsigned long size;
+    char *data;
+    unsigned long pointer;
+  }
+stack;
+
+static stack *stack_init PARAMS ((unsigned long, unsigned long));
+static char *stack_push PARAMS ((stack *, char *));
+static char *stack_pop PARAMS ((stack *));
+static void tag_init PARAMS ((void));
+static void tag_insert PARAMS ((const char *, symbolS *));
+static symbolS *tag_find PARAMS ((char *));
+static symbolS *tag_find_or_make PARAMS ((char *));
 static void obj_coff_bss PARAMS ((int));
+static void obj_coff_weak PARAMS ((int));
 const char *s_get_name PARAMS ((symbolS * s));
 static void obj_coff_ln PARAMS ((int));
 static void obj_coff_def PARAMS ((int));
@@ -53,21 +76,8 @@ static void obj_coff_ident PARAMS ((int));
 #ifdef BFD_ASSEMBLER
 static void obj_coff_loc PARAMS((int));
 #endif
-
-/* This is used to hold the symbol built by a sequence of pseudo-ops
-   from .def and .endef.  */
-static symbolS *def_symbol_in_progress;
 \f
 /* stack stuff */
-typedef struct
-  {
-    unsigned long chunk_size;
-    unsigned long element_size;
-    unsigned long size;
-    char *data;
-    unsigned long pointer;
-  }
-stack;
 
 static stack *
 stack_init (chunk_size, element_size)
@@ -245,7 +255,11 @@ obj_coff_weak (ignore)
 
 #ifdef BFD_ASSEMBLER
 
+static segT fetch_coff_debug_section PARAMS ((void));
 static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
+static int S_GET_DATA_TYPE PARAMS ((symbolS *));
+void c_symbol_merge PARAMS ((symbolS *, symbolS *));
+static void add_lineno PARAMS ((fragS *, addressT, int));
 
 #define GET_FILENAME_STRING(X) \
 ((char*) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
@@ -445,12 +459,17 @@ add_lineno (frag, offset, num)
     {
       abort ();
     }
+
+#ifndef OBJ_XCOFF
+  /* The native aix assembler accepts negative line number */
+
   if (num <= 0)
     {
       /* Zero is used as an end marker in the file.  */
       as_warn (_("Line numbers must be positive integers\n"));
       num = 1;
     }
+#endif /* OBJ_XCOFF */
   new_line->next = line_nos;
   new_line->frag = frag;
   new_line->l.line_number = num;
@@ -487,13 +506,13 @@ obj_coff_ln (appline)
     }
 
   l = get_absolute_expression ();
-  if (!appline)
-    {
-      add_lineno (frag_now, frag_now_fix (), l);
-    }
 
-  if (appline)
+  /* If there is no lineno symbol, treat a .ln
+     directive as if it were a .appline directive.  */
+  if (appline || current_lineno_sym == NULL)
     new_logical_line ((char *) NULL, l - 1);
+  else
+    add_lineno (frag_now, frag_now_fix (), l);
 
 #ifndef NO_LISTING
   {
@@ -1168,18 +1187,21 @@ coff_frob_symbol (symp, punt)
 
   if (!SF_GET_DEBUG (symp))
     {
-      symbolS *real;
+      symbolS * real;
+
       if (!SF_GET_LOCAL (symp)
          && !SF_GET_STATICS (symp)
          && S_GET_STORAGE_CLASS (symp) != C_LABEL
          && symbol_constant_p(symp)
          && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
+         && S_GET_STORAGE_CLASS (real) == C_NULL
          && real != symp)
        {
          c_symbol_merge (symp, real);
          *punt = 1;
          return;
        }
+
       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
        {
          assert (S_GET_VALUE (symp) == 0);
@@ -1193,6 +1215,7 @@ coff_frob_symbol (symp, punt)
          else
            S_SET_STORAGE_CLASS (symp, C_STAT);
        }
+
       if (SF_GET_PROCESS (symp))
        {
          if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
@@ -1202,6 +1225,7 @@ coff_frob_symbol (symp, punt)
              else
                {
                  symbolS *begin;
+
                  begin = *(symbolS **) stack_pop (block_stack);
                  if (begin == 0)
                    as_warn (_("mismatched .eb"));
@@ -1209,9 +1233,11 @@ coff_frob_symbol (symp, punt)
                    next_set_end = begin;
                }
            }
+
          if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
            {
              union internal_auxent *auxp;
+
              coff_last_function = symp;
              if (S_GET_NUMBER_AUXILIARY (symp) < 1)
                S_SET_NUMBER_AUXILIARY (symp, 1);
@@ -1219,6 +1245,7 @@ coff_frob_symbol (symp, punt)
              memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
                      sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
            }
+
          if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
            {
              if (coff_last_function == 0)
@@ -1230,6 +1257,7 @@ coff_frob_symbol (symp, punt)
              coff_last_function = 0;
            }
        }
+
       if (S_IS_EXTERNAL (symp))
        S_SET_STORAGE_CLASS (symp, C_EXT);
       else if (SF_GET_LOCAL (symp))
@@ -1487,8 +1515,8 @@ obj_coff_section (ignore)
     {
       /* This section's attributes have already been set. Warn if the
          attributes don't match.  */
-      flagword matchflags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
-                         | SEC_DATA | SEC_SHARED | SEC_NEVER_LOAD;
+      flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
+                            | SEC_DATA | SEC_SHARED | SEC_NEVER_LOAD);
       if ((flags ^ oldflags) & matchflags)
        as_warn (_("Ignoring changed section attributes for %s"), name);
     }
@@ -1818,7 +1846,6 @@ size_section (abfd, idx)
          break;
 #endif
        case rs_space:
-         assert (frag->fr_symbol == 0);
        case rs_fill:
        case rs_org:
          size += frag->fr_fix;
@@ -1971,7 +1998,7 @@ do_relocs_for (abfd, h, file_cursor)
                      /* Turn the segment of the symbol into an offset.  */
                      if (symbol_ptr)
                        {
-                         resolve_symbol_value (symbol_ptr, 1);
+                         resolve_symbol_value (symbol_ptr);
                          if (! symbol_ptr->sy_resolved)
                            {
                              char *file;
@@ -2075,7 +2102,7 @@ fill_section (abfd, h, file_cursor)
       if (s->s_name[0])
        {
          fragS *frag = segment_info[i].frchainP->frch_root;
-         char *buffer;
+         char *buffer = NULL;
 
          if (s->s_size == 0)
            s->s_scnptr = 0;
@@ -2132,7 +2159,6 @@ fill_section (abfd, h, file_cursor)
 
                  break;
                case rs_space:
-                 assert (frag->fr_symbol == 0);
                case rs_fill:
                case rs_align:
                case rs_align_code:
@@ -2952,7 +2978,7 @@ yank_symbols ()
              S_SET_SEGMENT (symbolP, SEG_E0);
            }                   /* push data into text */
 
-         resolve_symbol_value (symbolP, 1);
+         resolve_symbol_value (symbolP);
 
          if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
            {
@@ -3349,12 +3375,13 @@ do_linenos_for (abfd, h, file_cursor)
               line_ptr != (struct lineno_list *) NULL;
               line_ptr = line_ptr->next)
            {
-
              if (line_ptr->line.l_lnno == 0)
                {
-                 /* Turn a pointer to a symbol into the symbols' index */
-                 line_ptr->line.l_addr.l_symndx =
-                   ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
+                 /* Turn a pointer to a symbol into the symbols' index,
+                    provided that it has been initialised.  */
+                 if (line_ptr->line.l_addr.l_symndx)
+                   line_ptr->line.l_addr.l_symndx =
+                     ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
                }
              else
                {
@@ -3466,6 +3493,9 @@ write_object_file ()
       relax_segment (segment_info[i].frchainP->frch_root, i);
     }
 
+  /* Relaxation has completed.  Freeze all syms.  */
+  finalize_syms = 1;
+
   H_SET_NUMBER_OF_SECTIONS (&headers, 0);
 
   /* Find out how big the sections are, and set the addresses.  */
@@ -4184,7 +4214,7 @@ fixup_segment (segP, this_segment_type)
       /* Make sure the symbols have been resolved; this may not have
          happened if these are expression symbols.  */
       if (add_symbolP != NULL && ! add_symbolP->sy_resolved)
-       resolve_symbol_value (add_symbolP, 1);
+       resolve_symbol_value (add_symbolP);
 
       if (add_symbolP != NULL)
        {
@@ -4214,7 +4244,7 @@ fixup_segment (segP, this_segment_type)
        }
 
       if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved)
-       resolve_symbol_value (sub_symbolP, 1);
+       resolve_symbol_value (sub_symbolP);
 
       if (add_symbolP != NULL
          && add_symbolP->sy_mri_common)
This page took 0.027799 seconds and 4 git commands to generate.