]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/config/obj-aout.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / gas / config / obj-aout.c
index 332a65f4b5186f50a88eb76d22be7dab146273a3..ee8b398750129cfdc6df940e244602e4151b7ae6 100644 (file)
@@ -1,5 +1,5 @@
 /* a.out object file format
-   Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
 
 This file is part of GAS, the GNU Assembler.
 
@@ -62,12 +62,15 @@ const segT N_TYPE_seg[N_TYPE + 2] =
 #endif
 
 static void obj_aout_line PARAMS ((int));
+static void obj_aout_weak PARAMS ((int));
 
 const pseudo_typeS obj_pseudo_table[] =
 {
   {"line", obj_aout_line, 0},  /* source code line number */
   {"ln", obj_aout_line, 0},    /* coff line number that we use anyway */
 
+  {"weak", obj_aout_weak, 0},  /* mark symbol as weak.  */
+
   /* coff debug pseudos (ignored) */
   {"def", s_ignore, 0},
   {"dim", s_ignore, 0},
@@ -113,9 +116,13 @@ obj_aout_frob_symbol (sym, punt)
     {
       if (type == (N_UNDF | N_EXT)
          && sec == &bfd_abs_section)
-       sym->bsym->section = sec = &bfd_und_section;
+       sym->bsym->section = sec = bfd_und_section_ptr;
 
       if ((type & N_TYPE) != N_INDR
+         && (type & N_TYPE) != N_SETA
+         && (type & N_TYPE) != N_SETT
+         && (type & N_TYPE) != N_SETD
+         && (type & N_TYPE) != N_SETB
          && type != N_WARNING
          && (sec == &bfd_abs_section
              || sec == &bfd_und_section))
@@ -132,10 +139,29 @@ obj_aout_frob_symbol (sym, punt)
          /* Set the debugging flag for constructor symbols so that
             BFD leaves them alone.  */
          sym->bsym->flags |= BSF_DEBUGGING;
+
+         /* You can't put a common symbol in a set.  The way a set
+            element works is that the symbol has a definition and a
+            name, and the linker adds the definition to the set of
+            that name.  That does not work for a common symbol,
+            because the linker can't tell which common symbol the
+            user means.  FIXME: Using as_bad here may be
+            inappropriate, since the user may want to force a
+            particular type without regard to the semantics of sets;
+            on the other hand, we certainly don't want anybody to be
+            mislead into thinking that their code will work.  */
+         if (S_IS_COMMON (sym))
+           as_bad ("Attempt to put a common symbol into set %s",
+                   S_GET_NAME (sym));
+         /* Similarly, you can't put an undefined symbol in a set.  */
+         else if (! S_IS_DEFINED (sym))
+           as_bad ("Attempt to put an undefined symbol into set %s",
+                   S_GET_NAME (sym));
+
          break;
        case N_INDR:
          /* Put indirect symbols in the indirect section.  */
-         sym->bsym->section = &bfd_ind_section;
+         sym->bsym->section = bfd_ind_section_ptr;
          sym->bsym->flags |= BSF_INDIRECT;
          if (type & N_EXT)
            {
@@ -155,6 +181,14 @@ obj_aout_frob_symbol (sym, punt)
     }
 
   S_SET_TYPE (sym, type);
+
+  /* Double check weak symbols.  */
+  if (sym->bsym->flags & BSF_WEAK)
+    {
+      if (S_IS_COMMON (sym))
+       as_bad ("Symbol `%s' can not be both weak and common",
+               S_GET_NAME (sym));
+    }
 }
 
 void
@@ -269,6 +303,20 @@ obj_emit_symbols (where, symbol_rootP)
       if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP))
        S_SET_EXTERNAL (symbolP);
 
+      /* Adjust the type of a weak symbol.  */
+      if (S_GET_WEAK (symbolP))
+       {
+         switch (S_GET_TYPE (symbolP))
+           {
+           case N_UNDF: S_SET_TYPE (symbolP, N_WEAKU); break;
+           case N_ABS:  S_SET_TYPE (symbolP, N_WEAKA); break;
+           case N_TEXT: S_SET_TYPE (symbolP, N_WEAKT); break;
+           case N_DATA: S_SET_TYPE (symbolP, N_WEAKD); break;
+           case N_BSS:  S_SET_TYPE (symbolP, N_WEAKB); break;
+           default: as_bad ("%s: bad type for weak symbol", temp); break;
+           }
+       }
+
       obj_symbol_to_chars (where, symbolP);
       S_SET_NAME (symbolP, temp);
     }
@@ -287,6 +335,36 @@ obj_aout_line (ignore)
   demand_empty_rest_of_line ();
 }                              /* obj_aout_line() */
 
+/* Handle .weak.  This is a GNU extension.  */
+
+static void
+obj_aout_weak (ignore)
+     int ignore;
+{
+  char *name;
+  int c;
+  symbolS *symbolP;
+
+  do
+    {
+      name = input_line_pointer;
+      c = get_symbol_end ();
+      symbolP = symbol_find_or_make (name);
+      *input_line_pointer = c;
+      SKIP_WHITESPACE ();
+      S_SET_WEAK (symbolP);
+      if (c == ',')
+       {
+         input_line_pointer++;
+         SKIP_WHITESPACE ();
+         if (*input_line_pointer == '\n')
+           c = '\n';
+       }
+    }
+  while (c == ',');
+  demand_empty_rest_of_line ();
+}
+
 void
 obj_read_begin_hook ()
 {
@@ -307,7 +385,7 @@ obj_crawl_symbol_chain (headers)
   symbolPP = &symbol_rootP;    /*->last symbol chain link. */
   while ((symbolP = *symbolPP) != NULL)
     {
-      if (flagseen['R'] && (S_GET_SEGMENT (symbolP) == SEG_DATA))
+      if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA))
        {
          S_SET_SEGMENT (symbolP, SEG_TEXT);
        }                       /* if pusing data into text */
@@ -336,7 +414,7 @@ obj_crawl_symbol_chain (headers)
              || !S_IS_DEFINED (symbolP)
              || S_IS_EXTERNAL (symbolP)
              || (S_GET_NAME (symbolP)[0] != '\001'
-                 && (flagseen['L'] || !S_LOCAL_NAME (symbolP)))))
+                 && (flag_keep_locals || !S_LOCAL_NAME (symbolP)))))
        {
          symbolP->sy_number = symbol_number++;
 
@@ -457,7 +535,7 @@ DEFUN_VOID (s_sect)
 
   if (strcmp (section_name, ".data") == 0)
     {
-      if (flagseen['R'])
+      if (flag_readonly_data_in_text)
        subseg_set (SEG_TEXT, (subsegT) exp + 1000);
       else
        subseg_set (SEG_DATA, (subsegT) exp);