(root)/
binutils-2.41/
gas/
config/
obj-som.c
       1  /* SOM object file format.
       2     Copyright (C) 1993-2023 Free Software Foundation, Inc.
       3  
       4     This file is part of GAS, the GNU Assembler.
       5  
       6     GAS is free software; you can redistribute it and/or modify
       7     it under the terms of the GNU General Public License as
       8     published by the Free Software Foundation; either version 3,
       9     or (at your option) any later version.
      10  
      11     GAS is distributed in the hope that it will be useful, but
      12     WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
      14     the GNU General Public License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with GAS; see the file COPYING.  If not, write to the Free
      18     Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
      19     02110-1301, USA.
      20  
      21     Written by the Center for Software Science at the University of Utah
      22     and by Cygnus Support.  */
      23  
      24  #include "as.h"
      25  #include "subsegs.h"
      26  #include "aout/stab_gnu.h"
      27  
      28  static int version_seen = 0;
      29  static int copyright_seen = 0;
      30  static int compiler_seen = 0;
      31  
      32  /* Unused by SOM.  */
      33  
      34  void
      35  obj_read_begin_hook (void)
      36  {
      37  }
      38  
      39  /* Handle a .compiler directive.   This is intended to create the
      40     compilation unit auxiliary header for MPE such that the linkeditor
      41     can handle SOM extraction from archives. The format of the quoted
      42     string is "sourcefile language version" and is delimited by blanks.  */
      43  
      44  void
      45  obj_som_compiler (int unused ATTRIBUTE_UNUSED)
      46  {
      47    char *buf;
      48    char c;
      49    char *filename;
      50    char *language_name;
      51    char *p;
      52    char *version_id;
      53  
      54    if (compiler_seen)
      55      {
      56        as_bad (_("Only one .compiler pseudo-op per file!"));
      57        ignore_rest_of_line ();
      58        return;
      59      }
      60  
      61    SKIP_WHITESPACE ();
      62    if (*input_line_pointer == '\"')
      63      {
      64        buf = input_line_pointer;
      65        ++input_line_pointer;
      66        while (is_a_char (next_char_of_string ()))
      67  	;
      68        c = *input_line_pointer;
      69        *input_line_pointer = '\000';
      70      }
      71    else
      72      {
      73        as_bad (_("Expected quoted string"));
      74        ignore_rest_of_line ();
      75        return;
      76      }
      77  
      78    /* Parse the quoted string into its component parts.  Skip the
      79       quote.  */
      80    filename = buf + 1;
      81    p = filename;
      82    while (*p != ' ' && *p != '\000')
      83      p++;
      84    if (*p == '\000')
      85      {
      86        as_bad (_(".compiler directive missing language and version"));
      87        return;
      88      }
      89    *p = '\000';
      90  
      91    language_name = ++p;
      92    while (*p != ' ' && *p != '\000')
      93      p++;
      94    if (*p == '\000')
      95      {
      96        as_bad (_(".compiler directive missing version"));
      97        return;
      98      }
      99    *p = '\000';
     100  
     101    version_id = ++p;
     102    while (*p != '\000')
     103      p++;
     104    /* Remove the trailing quote.  */
     105    *(--p) = '\000';
     106  
     107    compiler_seen = 1;
     108    if (! bfd_som_attach_compilation_unit (stdoutput, filename, language_name,
     109  					 "GNU Tools", version_id))
     110      {
     111        bfd_perror (stdoutput->filename);
     112        as_fatal (_("FATAL: Attaching compiler header %s"), stdoutput->filename);
     113      }
     114    *input_line_pointer = c;
     115    demand_empty_rest_of_line ();
     116  }
     117  
     118  /* Handle a .version directive.  */
     119  
     120  void
     121  obj_som_version (int unused ATTRIBUTE_UNUSED)
     122  {
     123    char *version, c;
     124  
     125    if (version_seen)
     126      {
     127        as_bad (_("Only one .version pseudo-op per file!"));
     128        ignore_rest_of_line ();
     129        return;
     130      }
     131  
     132    SKIP_WHITESPACE ();
     133    if (*input_line_pointer == '\"')
     134      {
     135        version = input_line_pointer;
     136        ++input_line_pointer;
     137        while (is_a_char (next_char_of_string ()))
     138  	;
     139        c = *input_line_pointer;
     140        *input_line_pointer = '\000';
     141      }
     142    else
     143      {
     144        as_bad (_("Expected quoted string"));
     145        ignore_rest_of_line ();
     146        return;
     147      }
     148  
     149    version_seen = 1;
     150    if (!bfd_som_attach_aux_hdr (stdoutput, VERSION_AUX_ID, version))
     151      as_fatal (_("attaching version header %s: %s"),
     152  	      stdoutput->filename, bfd_errmsg (bfd_get_error ()));
     153  
     154    *input_line_pointer = c;
     155    demand_empty_rest_of_line ();
     156  }
     157  
     158  /* Handle a .copyright directive.   This probably isn't complete, but
     159     it's of dubious value anyway and (IMHO) not worth the time to finish.
     160     If you care about copyright strings that much, you fix it.  */
     161  
     162  void
     163  obj_som_copyright (int unused ATTRIBUTE_UNUSED)
     164  {
     165    char *copyright, c;
     166  
     167    if (copyright_seen)
     168      {
     169        as_bad (_("Only one .copyright pseudo-op per file!"));
     170        ignore_rest_of_line ();
     171        return;
     172      }
     173  
     174    SKIP_WHITESPACE ();
     175    if (*input_line_pointer == '\"')
     176      {
     177        copyright = input_line_pointer;
     178        ++input_line_pointer;
     179        while (is_a_char (next_char_of_string ()))
     180  	;
     181        c = *input_line_pointer;
     182        *input_line_pointer = '\000';
     183      }
     184    else
     185      {
     186        as_bad (_("Expected quoted string"));
     187        ignore_rest_of_line ();
     188        return;
     189      }
     190  
     191    copyright_seen = 1;
     192    if (!bfd_som_attach_aux_hdr (stdoutput, COPYRIGHT_AUX_ID, copyright))
     193      as_fatal (_("attaching copyright header %s: %s"),
     194  	      stdoutput->filename, bfd_errmsg (bfd_get_error ()));
     195  
     196    *input_line_pointer = c;
     197    demand_empty_rest_of_line ();
     198  }
     199  
     200  /* Perform any initialization necessary for stabs support.
     201  
     202     For SOM we need to create the space which will contain the
     203     two stabs subspaces.  Additionally we need to set up the
     204     space/subspace relationships and set space/subspace attributes
     205     which BFD does not understand.  */
     206  
     207  void
     208  obj_som_init_stab_section (segT seg)
     209  {
     210    segT saved_seg = now_seg;
     211    segT space;
     212    subsegT saved_subseg = now_subseg;
     213    char *p;
     214    const char * file;
     215    unsigned int stroff;
     216  
     217    /* Nothing to do if the section has already been created.  */
     218    if (bfd_get_section_by_name (stdoutput, "$GDB_DEBUG$"))
     219      return;
     220  
     221    /* Make the space which will contain the debug subspaces.  */
     222    space = bfd_make_section_old_way (stdoutput, "$GDB_DEBUG$");
     223  
     224    /* Set SOM specific attributes for the space.  In particular we set
     225       the space "defined", "private", "sort_key", and "spnum" values.
     226  
     227       Due to a bug in pxdb (called by hpux linker), the sort keys
     228       of the various stabs spaces/subspaces need to be "small".  We
     229       reserve range 72/73 which appear to work well.  */
     230    obj_set_section_attributes (space, 1, 1, 72, 2);
     231    bfd_set_section_alignment (space, 2);
     232  
     233    /* Set the containing space for both stab sections to be $GDB_DEBUG$
     234       (just created above).  Also set some attributes which BFD does
     235       not understand.  In particular, access bits, sort keys, and load
     236       quadrant.  */
     237    obj_set_subsection_attributes (seg, space, 0x1f, 73, 0, 0, 0, 0);
     238    bfd_set_section_alignment (seg, 2);
     239  
     240    /* Make some space for the first special stab entry and zero the memory.
     241       It contains information about the length of this file's
     242       stab string and the like.  Using it avoids the need to
     243       relocate the stab strings.
     244  
     245       The $GDB_STRINGS$ space will be created as a side effect of
     246       the call to get_stab_string_offset.  */
     247    p = frag_more (12);
     248    memset (p, 0, 12);
     249    file = as_where ((unsigned int *) NULL);
     250    stroff = get_stab_string_offset (file, "$GDB_STRINGS$", false);
     251    know (stroff == 1);
     252    md_number_to_chars (p, stroff, 4);
     253    seg_info (seg)->stabu.p = p;
     254  
     255    /* Set the containing space for both stab sections to be $GDB_DEBUG$
     256       (just created above).  Also set some attributes which BFD does
     257       not understand.  In particular, access bits, sort keys, and load
     258       quadrant.  */
     259    seg = bfd_get_section_by_name (stdoutput, "$GDB_STRINGS$");
     260    obj_set_subsection_attributes (seg, space, 0x1f, 72, 0, 0, 0, 0);
     261    bfd_set_section_alignment (seg, 2);
     262  
     263    subseg_set (saved_seg, saved_subseg);
     264  }
     265  
     266  /* Fill in the counts in the first entry in a .stabs section.  */
     267  
     268  static void
     269  adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
     270  {
     271    asection *strsec;
     272    char *p;
     273    int strsz, nsyms;
     274  
     275    if (strcmp ("$GDB_SYMBOLS$", sec->name))
     276      return;
     277  
     278    strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$");
     279    if (strsec)
     280      strsz = bfd_section_size (strsec);
     281    else
     282      strsz = 0;
     283    nsyms = bfd_section_size (sec) / 12 - 1;
     284  
     285    p = seg_info (sec)->stabu.p;
     286    gas_assert (p != 0);
     287  
     288    bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
     289    bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
     290  }
     291  
     292  /* Called late in the assembly phase to adjust the special
     293     stab entry and to set the starting address for each code subspace.  */
     294  
     295  void
     296  som_frob_file (void)
     297  {
     298    bfd_map_over_sections (stdoutput, adjust_stab_sections, (void *) 0);
     299  }
     300  
     301  static void
     302  obj_som_weak (int ignore ATTRIBUTE_UNUSED)
     303  {
     304    char *name;
     305    int c;
     306    symbolS *symbolP;
     307  
     308    do
     309      {
     310        c = get_symbol_name (&name);
     311        symbolP = symbol_find_or_make (name);
     312        *input_line_pointer = c;
     313        SKIP_WHITESPACE_AFTER_NAME ();
     314        S_SET_WEAK (symbolP);
     315        if (c == ',')
     316  	{
     317  	  input_line_pointer++;
     318  	  SKIP_WHITESPACE ();
     319  	  if (*input_line_pointer == '\n')
     320  	    c = '\n';
     321  	}
     322      }
     323    while (c == ',');
     324    demand_empty_rest_of_line ();
     325  }
     326  
     327  const pseudo_typeS obj_pseudo_table[] =
     328  {
     329    {"weak", obj_som_weak, 0},
     330    {NULL, NULL, 0}
     331  };