home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / binutils-2.7-src.tgz / tar.out / fsf / binutils / gas / config / obj-elf.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  30KB  |  1,283 lines

  1. /* ELF object file format
  2.    Copyright (C) 1992, 1993, 1994, 1995, 1996 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 2,
  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, 59 Temple Place - Suite 330, Boston, MA
  19.    02111-1307, USA. */
  20.  
  21. #define OBJ_HEADER "obj-elf.h"
  22. #include "as.h"
  23. #include "subsegs.h"
  24. #include "obstack.h"
  25.  
  26. #ifndef ECOFF_DEBUGGING
  27. #define ECOFF_DEBUGGING 0
  28. #else
  29. #define NEED_ECOFF_DEBUG
  30. #endif
  31.  
  32. #ifdef NEED_ECOFF_DEBUG
  33. #include "ecoff.h"
  34. #endif
  35.  
  36. #ifdef TC_MIPS
  37. #include "elf/mips.h"
  38. #endif
  39.  
  40. #ifdef TC_PPC
  41. #include "elf/ppc.h"
  42. #endif
  43.  
  44. #ifdef NEED_ECOFF_DEBUG
  45. static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
  46. static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
  47. #endif
  48.  
  49. static void obj_elf_line PARAMS ((int));
  50. void obj_elf_version PARAMS ((int));
  51. static void obj_elf_size PARAMS ((int));
  52. static void obj_elf_type PARAMS ((int));
  53. static void obj_elf_ident PARAMS ((int));
  54. static void obj_elf_weak PARAMS ((int));
  55. static void obj_elf_local PARAMS ((int));
  56. static void obj_elf_common PARAMS ((int));
  57. static void obj_elf_data PARAMS ((int));
  58. static void obj_elf_text PARAMS ((int));
  59.  
  60. static const pseudo_typeS elf_pseudo_table[] =
  61. {
  62.   {"comm", obj_elf_common, 0},
  63.   {"ident", obj_elf_ident, 0},
  64.   {"local", obj_elf_local, 0},
  65.   {"previous", obj_elf_previous, 0},
  66.   {"section", obj_elf_section, 0},
  67.   {"section.s", obj_elf_section, 0},
  68.   {"sect", obj_elf_section, 0},
  69.   {"sect.s", obj_elf_section, 0},
  70.   {"size", obj_elf_size, 0},
  71.   {"type", obj_elf_type, 0},
  72.   {"version", obj_elf_version, 0},
  73.   {"weak", obj_elf_weak, 0},
  74.  
  75. /* These are used for stabs-in-elf configurations.  */
  76.   {"line", obj_elf_line, 0},
  77.  
  78.   /* These are used for dwarf. */
  79.   {"2byte", cons, 2},
  80.   {"4byte", cons, 4},
  81.   {"8byte", cons, 8},
  82.  
  83.   /* We need to trap the section changing calls to handle .previous.  */
  84.   {"data", obj_elf_data, 0},
  85.   {"text", obj_elf_text, 0},
  86.  
  87.   /* End sentinel.  */
  88.   {NULL},
  89. };
  90.  
  91. static const pseudo_typeS ecoff_debug_pseudo_table[] =
  92. {
  93. #ifdef NEED_ECOFF_DEBUG
  94.   /* COFF style debugging information for ECOFF. .ln is not used; .loc
  95.      is used instead.  */
  96.   { "def",    ecoff_directive_def,    0 },
  97.   { "dim",    ecoff_directive_dim,    0 },
  98.   { "endef",    ecoff_directive_endef,    0 },
  99.   { "file",    ecoff_directive_file,    0 },
  100.   { "scl",    ecoff_directive_scl,    0 },
  101.   { "tag",    ecoff_directive_tag,    0 },
  102.   { "val",    ecoff_directive_val,    0 },
  103.  
  104.   /* COFF debugging requires pseudo-ops .size and .type, but ELF
  105.      already has meanings for those.  We use .esize and .etype
  106.      instead.  These are only generated by gcc anyhow.  */
  107.   { "esize",    ecoff_directive_size,    0 },
  108.   { "etype",    ecoff_directive_type,    0 },
  109.  
  110.   /* ECOFF specific debugging information.  */
  111.   { "begin",    ecoff_directive_begin,    0 },
  112.   { "bend",    ecoff_directive_bend,    0 },
  113.   { "end",    ecoff_directive_end,    0 },
  114.   { "ent",    ecoff_directive_ent,    0 },
  115.   { "fmask",    ecoff_directive_fmask,    0 },
  116.   { "frame",    ecoff_directive_frame,    0 },
  117.   { "loc",    ecoff_directive_loc,    0 },
  118.   { "mask",    ecoff_directive_mask,    0 },
  119.  
  120.   /* Other ECOFF directives.  */
  121.   { "extern",    ecoff_directive_extern,    0 },
  122.  
  123.   /* These are used on Irix.  I don't know how to implement them.  */
  124.   { "alias",    s_ignore,        0 },
  125.   { "bgnb",    s_ignore,        0 },
  126.   { "endb",    s_ignore,        0 },
  127.   { "lab",    s_ignore,        0 },
  128.   { "noalias",    s_ignore,        0 },
  129.   { "verstamp",    s_ignore,        0 },
  130.   { "vreg",    s_ignore,        0 },
  131. #endif
  132.  
  133.   {NULL}            /* end sentinel */
  134. };
  135.  
  136. #undef NO_RELOC
  137. #include "aout/aout64.h"
  138.  
  139. void
  140. elf_pop_insert ()
  141. {
  142.   pop_insert (elf_pseudo_table);
  143.   if (ECOFF_DEBUGGING)
  144.     pop_insert (ecoff_debug_pseudo_table);
  145. }
  146.  
  147. static bfd_vma
  148. elf_s_get_size (sym)
  149.      symbolS *sym;
  150. {
  151.   return S_GET_SIZE (sym);
  152. }
  153.  
  154. static void
  155. elf_s_set_size (sym, sz)
  156.      symbolS *sym;
  157.      bfd_vma sz;
  158. {
  159.   S_SET_SIZE (sym, sz);
  160. }
  161.  
  162. static bfd_vma
  163. elf_s_get_align (sym)
  164.      symbolS *sym;
  165. {
  166.   return S_GET_ALIGN (sym);
  167. }
  168.  
  169. static void
  170. elf_s_set_align (sym, align)
  171.      symbolS *sym;
  172.      bfd_vma align;
  173. {
  174.   S_SET_ALIGN (sym, align);
  175. }
  176.  
  177. static void
  178. elf_copy_symbol_attributes (dest, src)
  179.      symbolS *dest, *src;
  180. {
  181.   OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
  182. }
  183.  
  184. static int
  185. elf_sec_sym_ok_for_reloc (sec)
  186.      asection *sec;
  187. {
  188.   return obj_sec_sym_ok_for_reloc (sec);
  189. }
  190.  
  191. void
  192. elf_file_symbol (s)
  193.      char *s;
  194. {
  195.   symbolS *sym;
  196.  
  197.   sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
  198.   sym->sy_frag = &zero_address_frag;
  199.   sym->bsym->flags |= BSF_FILE;
  200.  
  201.   if (symbol_rootP != sym)
  202.     {
  203.       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
  204.       symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
  205. #ifdef DEBUG
  206.       verify_symbol_chain (symbol_rootP, symbol_lastP);
  207. #endif
  208.     }
  209. }
  210.  
  211. static void
  212. obj_elf_common (ignore)
  213.      int ignore;
  214. {
  215.   char *name;
  216.   char c;
  217.   char *p;
  218.   int temp, size;
  219.   symbolS *symbolP;
  220.   int have_align;
  221.  
  222.   name = input_line_pointer;
  223.   c = get_symbol_end ();
  224.   /* just after name is now '\0' */
  225.   p = input_line_pointer;
  226.   *p = c;
  227.   SKIP_WHITESPACE ();
  228.   if (*input_line_pointer != ',')
  229.     {
  230.       as_bad ("Expected comma after symbol-name");
  231.       ignore_rest_of_line ();
  232.       return;
  233.     }
  234.   input_line_pointer++;        /* skip ',' */
  235.   if ((temp = get_absolute_expression ()) < 0)
  236.     {
  237.       as_bad (".COMMon length (%d.) <0! Ignored.", temp);
  238.       ignore_rest_of_line ();
  239.       return;
  240.     }
  241.   size = temp;
  242.   *p = 0;
  243.   symbolP = symbol_find_or_make (name);
  244.   *p = c;
  245.   if (S_IS_DEFINED (symbolP))
  246.     {
  247.       as_bad ("Ignoring attempt to re-define symbol");
  248.       ignore_rest_of_line ();
  249.       return;
  250.     }
  251.   if (S_GET_VALUE (symbolP) != 0)
  252.     {
  253.       if (S_GET_VALUE (symbolP) != size)
  254.     {
  255.       as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
  256.            S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
  257.     }
  258.     }
  259.   know (symbolP->sy_frag == &zero_address_frag);
  260.   if (*input_line_pointer != ',')
  261.     have_align = 0;
  262.   else
  263.     {
  264.       have_align = 1;
  265.       input_line_pointer++;
  266.       SKIP_WHITESPACE ();
  267.     }
  268.   if (! have_align || *input_line_pointer != '"')
  269.     {
  270.       if (! have_align)
  271.     temp = 0;
  272.       else
  273.     {
  274.       temp = get_absolute_expression ();
  275.       if (temp < 0)
  276.         {
  277.           temp = 0;
  278.           as_warn ("Common alignment negative; 0 assumed");
  279.         }
  280.     }
  281.       if (symbolP->local)
  282.     {
  283.       segT old_sec;
  284.       int old_subsec;
  285.       char *pfrag;
  286.       int align;
  287.  
  288.     /* allocate_bss: */
  289.       old_sec = now_seg;
  290.       old_subsec = now_subseg;
  291.       if (temp)
  292.         {
  293.           /* convert to a power of 2 alignment */
  294.           for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
  295.           if (temp != 1)
  296.         {
  297.           as_bad ("Common alignment not a power of 2");
  298.           ignore_rest_of_line ();
  299.           return;
  300.         }
  301.         }
  302.       else
  303.         align = 0;
  304.       record_alignment (bss_section, align);
  305.       subseg_set (bss_section, 0);
  306.       if (align)
  307.         frag_align (align, 0);
  308.       if (S_GET_SEGMENT (symbolP) == bss_section)
  309.         symbolP->sy_frag->fr_symbol = 0;
  310.       symbolP->sy_frag = frag_now;
  311.       pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
  312.                 (char *) 0);
  313.       *pfrag = 0;
  314.       S_SET_SIZE (symbolP, size);
  315.       S_SET_SEGMENT (symbolP, bss_section);
  316.       S_CLEAR_EXTERNAL (symbolP);
  317.       subseg_set (old_sec, old_subsec);
  318.     }
  319.       else
  320.     {
  321.     allocate_common:
  322.       S_SET_VALUE (symbolP, (valueT) size);
  323.       S_SET_ALIGN (symbolP, temp);
  324.       S_SET_EXTERNAL (symbolP);
  325.       /* should be common, but this is how gas does it for now */
  326.       S_SET_SEGMENT (symbolP, bfd_und_section_ptr);
  327.     }
  328.     }
  329.   else
  330.     {
  331.       input_line_pointer++;
  332.       /* @@ Some use the dot, some don't.  Can we get some consistency??  */
  333.       if (*input_line_pointer == '.')
  334.     input_line_pointer++;
  335.       /* @@ Some say data, some say bss.  */
  336.       if (strncmp (input_line_pointer, "bss\"", 4)
  337.       && strncmp (input_line_pointer, "data\"", 5))
  338.     {
  339.       while (*--input_line_pointer != '"')
  340.         ;
  341.       input_line_pointer--;
  342.       goto bad_common_segment;
  343.     }
  344.       while (*input_line_pointer++ != '"')
  345.     ;
  346.       goto allocate_common;
  347.     }
  348.   demand_empty_rest_of_line ();
  349.   return;
  350.  
  351.   {
  352.   bad_common_segment:
  353.     p = input_line_pointer;
  354.     while (*p && *p != '\n')
  355.       p++;
  356.     c = *p;
  357.     *p = '\0';
  358.     as_bad ("bad .common segment %s", input_line_pointer + 1);
  359.     *p = c;
  360.     input_line_pointer = p;
  361.     ignore_rest_of_line ();
  362.     return;
  363.   }
  364. }
  365.  
  366. static void 
  367. obj_elf_local (ignore)
  368.      int ignore;
  369. {
  370.   char *name;
  371.   int c;
  372.   symbolS *symbolP;
  373.  
  374.   do
  375.     {
  376.       name = input_line_pointer;
  377.       c = get_symbol_end ();
  378.       symbolP = symbol_find_or_make (name);
  379.       *input_line_pointer = c;
  380.       SKIP_WHITESPACE ();
  381.       S_CLEAR_EXTERNAL (symbolP);
  382.       symbolP->local = 1;
  383.       if (c == ',')
  384.     {
  385.       input_line_pointer++;
  386.       SKIP_WHITESPACE ();
  387.       if (*input_line_pointer == '\n')
  388.         c = '\n';
  389.     }
  390.     }
  391.   while (c == ',');
  392.   demand_empty_rest_of_line ();
  393. }
  394.  
  395. static void 
  396. obj_elf_weak (ignore)
  397.      int ignore;
  398. {
  399.   char *name;
  400.   int c;
  401.   symbolS *symbolP;
  402.  
  403.   do
  404.     {
  405.       name = input_line_pointer;
  406.       c = get_symbol_end ();
  407.       symbolP = symbol_find_or_make (name);
  408.       *input_line_pointer = c;
  409.       SKIP_WHITESPACE ();
  410.       S_SET_WEAK (symbolP);
  411.       symbolP->local = 1;
  412.       if (c == ',')
  413.     {
  414.       input_line_pointer++;
  415.       SKIP_WHITESPACE ();
  416.       if (*input_line_pointer == '\n')
  417.         c = '\n';
  418.     }
  419.     }
  420.   while (c == ',');
  421.   demand_empty_rest_of_line ();
  422. }
  423.  
  424. static segT previous_section;
  425. static int previous_subsection;
  426.  
  427. /* Handle the .section pseudo-op.  This code supports two different
  428.    syntaxes.  
  429.  
  430.    The first is found on Solaris, and looks like
  431.        .section ".sec1",#alloc,#execinstr,#write
  432.    Here the names after '#' are the SHF_* flags to turn on for the
  433.    section.  I'm not sure how it determines the SHT_* type (BFD
  434.    doesn't really give us control over the type, anyhow).
  435.  
  436.    The second format is found on UnixWare, and probably most SVR4
  437.    machines, and looks like
  438.        .section .sec1,"a",@progbits
  439.    The quoted string may contain any combination of a, w, x, and
  440.    represents the SHF_* flags to turn on for the section.  The string
  441.    beginning with '@' can be progbits or nobits.  There should be
  442.    other possibilities, but I don't know what they are.  In any case,
  443.    BFD doesn't really let us set the section type.  */
  444.  
  445. /* Certain named sections have particular defined types, listed on p.
  446.    4-19 of the ABI.  */
  447. struct special_section
  448. {
  449.   const char *name;
  450.   int type;
  451.   int attributes;
  452. };
  453.  
  454. static struct special_section special_sections[] =
  455. {
  456.   { ".bss",    SHT_NOBITS,    SHF_ALLOC + SHF_WRITE        },
  457.   { ".comment",    SHT_PROGBITS,    0                },
  458.   { ".data",    SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE        },
  459.   { ".data1",    SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE        },
  460.   { ".debug",    SHT_PROGBITS,    0                },
  461.   { ".fini",    SHT_PROGBITS,    SHF_ALLOC + SHF_EXECINSTR    },
  462.   { ".init",    SHT_PROGBITS,    SHF_ALLOC + SHF_EXECINSTR    },
  463.   { ".line",    SHT_PROGBITS,    0                },
  464.   { ".note",    SHT_NOTE,    0                },
  465.   { ".rodata",    SHT_PROGBITS,    SHF_ALLOC            },
  466.   { ".rodata1",    SHT_PROGBITS,    SHF_ALLOC            },
  467.   { ".text",    SHT_PROGBITS,    SHF_ALLOC + SHF_EXECINSTR    },
  468.  
  469. #ifdef ELF_TC_SPECIAL_SECTIONS
  470.   ELF_TC_SPECIAL_SECTIONS
  471. #endif
  472.  
  473. #if 0
  474.   /* The following section names are special, but they can not
  475.      reasonably appear in assembler code.  Some of the attributes are
  476.      processor dependent.  */
  477.   { ".dynamic",    SHT_DYNAMIC,    SHF_ALLOC /* + SHF_WRITE */     },
  478.   { ".dynstr",    SHT_STRTAB,    SHF_ALLOC            },
  479.   { ".dynsym",    SHT_DYNSYM,    SHF_ALLOC            },
  480.   { ".got",    SHT_PROGBITS,    0                },
  481.   { ".hash",    SHT_HASH,    SHF_ALLOC            },
  482.   { ".interp",    SHT_PROGBITS,    /* SHF_ALLOC */            },
  483.   { ".plt",    SHT_PROGBITS,    0                },
  484.   { ".shstrtab",SHT_STRTAB,    0                },
  485.   { ".strtab",    SHT_STRTAB,    /* SHF_ALLOC */            },
  486.   { ".symtab",    SHT_SYMTAB,    /* SHF_ALLOC */            },
  487. #endif
  488.  
  489.   { NULL,    0,        0                }
  490. };
  491.  
  492. void
  493. obj_elf_section (xxx)
  494.      int xxx;
  495. {
  496.   char *string;
  497.   int new_sec;
  498.   segT sec;
  499.   int type, attr;
  500.   int i;
  501.   flagword flags;
  502.  
  503. #ifdef md_flush_pending_output
  504.   md_flush_pending_output ();
  505. #endif
  506.  
  507.   if (flag_mri)
  508.     {
  509.       char mri_type;
  510.  
  511.       previous_section = now_seg;
  512.       previous_subsection = now_subseg;
  513.  
  514.       s_mri_sect (&mri_type);
  515.  
  516. #ifdef md_elf_section_change_hook
  517.       md_elf_section_change_hook ();
  518. #endif
  519.  
  520.       return;
  521.     }
  522.  
  523.   /* Get name of section.  */
  524.   SKIP_WHITESPACE ();
  525.   if (*input_line_pointer == '"')
  526.     {
  527.       string = demand_copy_C_string (&xxx);
  528.       if (string == NULL)
  529.     {
  530.       ignore_rest_of_line ();
  531.       return;
  532.     }
  533.     }
  534.   else
  535.     {
  536.       char *p = input_line_pointer;
  537.       char c;
  538.       while (0 == strchr ("\n\t,; ", *p))
  539.     p++;
  540.       if (p == input_line_pointer)
  541.     {
  542.       as_warn ("Missing section name");
  543.       ignore_rest_of_line ();
  544.       return;
  545.     }
  546.       c = *p;
  547.       *p = 0;
  548.       string = xmalloc ((unsigned long) (p - input_line_pointer + 1));
  549.       strcpy (string, input_line_pointer);
  550.       *p = c;
  551.       input_line_pointer = p;
  552.     }
  553.  
  554.   /* Switch to the section, creating it if necessary.  */
  555.   previous_section = now_seg;
  556.   previous_subsection = now_subseg;
  557.  
  558.   new_sec = bfd_get_section_by_name (stdoutput, string) == NULL;
  559.   sec = subseg_new (string, 0);
  560.  
  561.   /* If this section already existed, we don't bother to change the
  562.      flag values.  */
  563.   if (! new_sec)
  564.     {
  565.       while (! is_end_of_line[(unsigned char) *input_line_pointer])
  566.     ++input_line_pointer;
  567.       ++input_line_pointer;
  568.  
  569. #ifdef md_elf_section_change_hook
  570.       md_elf_section_change_hook ();
  571. #endif
  572.  
  573.       return;
  574.     }
  575.  
  576.   SKIP_WHITESPACE ();
  577.  
  578.   type = SHT_NULL;
  579.   attr = 0;
  580.  
  581.   if (*input_line_pointer == ',')
  582.     {
  583.       /* Skip the comma.  */
  584.       ++input_line_pointer;
  585.  
  586.       SKIP_WHITESPACE ();
  587.       if (*input_line_pointer == '"')
  588.     {
  589.       /* Pick up a string with a combination of a, w, x.  */
  590.       ++input_line_pointer;
  591.       while (*input_line_pointer != '"')
  592.         {
  593.           switch (*input_line_pointer)
  594.         {
  595.         case 'a':
  596.           attr |= SHF_ALLOC;
  597.           break;
  598.         case 'w':
  599.           attr |= SHF_WRITE;
  600.           break;
  601.         case 'x':
  602.           attr |= SHF_EXECINSTR;
  603.           break;
  604.         default:
  605.           {
  606.             char *bad_msg = "Bad .section directive: want a,w,x in string";
  607. #ifdef md_elf_section_letter
  608.             int md_attr = md_elf_section_letter (*input_line_pointer, &bad_msg);
  609.             if (md_attr)
  610.               attr |= md_attr;
  611.             else
  612. #endif
  613.               {
  614.             as_warn (bad_msg);
  615.             ignore_rest_of_line ();
  616.             return;
  617.               }
  618.           }
  619.         }
  620.           ++input_line_pointer;
  621.         }
  622.  
  623.       /* Skip the closing quote.  */
  624.       ++input_line_pointer;
  625.  
  626.       SKIP_WHITESPACE ();
  627.       if (*input_line_pointer == ',')
  628.         {
  629.           ++input_line_pointer;
  630.           SKIP_WHITESPACE ();
  631.           if (*input_line_pointer == '@')
  632.         {
  633.           ++input_line_pointer;
  634.           if (strncmp (input_line_pointer, "progbits",
  635.                    sizeof "progbits" - 1) == 0)
  636.             {
  637.               type = SHT_PROGBITS;
  638.               input_line_pointer += sizeof "progbits" - 1;
  639.             }
  640.           else if (strncmp (input_line_pointer, "nobits",
  641.                     sizeof "nobits" - 1) == 0)
  642.             {
  643.               type = SHT_NOBITS;
  644.               input_line_pointer += sizeof "nobits" - 1;
  645.             }
  646.           else
  647.             {
  648. #ifdef md_elf_section_type
  649.             int md_type = md_elf_section_type (&input_line_pointer);
  650.             if (md_type)
  651.               type = md_type;
  652.             else
  653. #endif
  654.               {
  655.             as_warn ("Unrecognized section type");
  656.             ignore_rest_of_line ();
  657.               }
  658.             }
  659.         }
  660.         }
  661.     }
  662.       else
  663.     {
  664.       do
  665.         {
  666.           SKIP_WHITESPACE ();
  667.           if (*input_line_pointer != '#')
  668.         {
  669.           as_warn ("Bad .section directive");
  670.           ignore_rest_of_line ();
  671.           return;
  672.         }
  673.           ++input_line_pointer;
  674.           if (strncmp (input_line_pointer, "write",
  675.                sizeof "write" - 1) == 0)
  676.         {
  677.           attr |= SHF_WRITE;
  678.           input_line_pointer += sizeof "write" - 1;
  679.         }
  680.           else if (strncmp (input_line_pointer, "alloc",
  681.                 sizeof "alloc" - 1) == 0)
  682.         {
  683.           attr |= SHF_ALLOC;
  684.           input_line_pointer += sizeof "alloc" - 1;
  685.         }
  686.           else if (strncmp (input_line_pointer, "execinstr",
  687.                 sizeof "execinstr" - 1) == 0)
  688.         {
  689.           attr |= SHF_EXECINSTR;
  690.           input_line_pointer += sizeof "execinstr" - 1;
  691.         }
  692.           else
  693.         {
  694. #ifdef md_elf_section_word
  695.           int md_attr = md_elf_section_word (&input_line_pointer);
  696.           if (md_attr)
  697.             attr |= md_attr;
  698.           else
  699. #endif
  700.             {
  701.               as_warn ("Unrecognized section attribute");
  702.               ignore_rest_of_line ();
  703.               return;
  704.             }
  705.         }
  706.           SKIP_WHITESPACE ();
  707.         }
  708.       while (*input_line_pointer++ == ',');
  709.       --input_line_pointer;
  710.     }
  711.     }
  712.  
  713.   /* See if this is one of the special sections.  */
  714.   for (i = 0; special_sections[i].name != NULL; i++)
  715.     {
  716.       if (string[1] == special_sections[i].name[1]
  717.       && strcmp (string, special_sections[i].name) == 0)
  718.     {
  719.       if (type == SHT_NULL)
  720.         type = special_sections[i].type;
  721.       else if (type != special_sections[i].type)
  722.         as_warn ("Setting incorrect section type for %s", string);
  723.  
  724.       if ((attr &~ special_sections[i].attributes) != 0)
  725.         as_warn ("Setting incorrect section attributes for %s", string);
  726.       attr |= special_sections[i].attributes;
  727.  
  728.       break;
  729.     }
  730.     }
  731.  
  732.   flags = (SEC_RELOC
  733.        | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
  734.        | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
  735.        | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
  736.        | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0));
  737.   if (special_sections[i].name == NULL)
  738.     {
  739.       if (type == SHT_PROGBITS)
  740.     flags |= SEC_ALLOC | SEC_LOAD;
  741.       else if (type == SHT_NOBITS)
  742.     {
  743.       flags |= SEC_ALLOC;
  744.       flags &=~ SEC_LOAD;
  745.     }
  746.  
  747. #ifdef md_elf_section_flags
  748.       flags = md_elf_section_flags (flags, attr, type);
  749. #endif
  750.     }
  751.  
  752.   bfd_set_section_flags (stdoutput, sec, flags);
  753.  
  754. #ifdef md_elf_section_change_hook
  755.   md_elf_section_change_hook ();
  756. #endif
  757.  
  758.   demand_empty_rest_of_line ();
  759. }
  760.  
  761. /* Change to the .data section.  */
  762.  
  763. static void
  764. obj_elf_data (i)
  765.      int i;
  766. {
  767.   previous_section = now_seg;
  768.   previous_subsection = now_subseg;
  769.   s_data (i);
  770. }
  771.  
  772. /* Change to the .text section.  */
  773.  
  774. static void
  775. obj_elf_text (i)
  776.      int i;
  777. {
  778.   previous_section = now_seg;
  779.   previous_subsection = now_subseg;
  780.   s_text (i);
  781. }
  782.  
  783. void
  784. obj_elf_previous (ignore)
  785.      int ignore;
  786. {
  787.   if (previous_section == 0)
  788.     {
  789.       as_bad (".previous without corresponding .section; ignored");
  790.       return;
  791.     }
  792.   subseg_set (previous_section, previous_subsection);
  793.   previous_section = 0;
  794. }
  795.  
  796. static void
  797. obj_elf_line (ignore)
  798.      int ignore;
  799. {
  800.   /* Assume delimiter is part of expression.  BSD4.2 as fails with
  801.      delightful bug, so we are not being incompatible here. */
  802.   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
  803.   demand_empty_rest_of_line ();
  804. }
  805.  
  806. void 
  807. obj_read_begin_hook ()
  808. {
  809. #ifdef NEED_ECOFF_DEBUG
  810.   if (ECOFF_DEBUGGING)
  811.     ecoff_read_begin_hook ();
  812. #endif
  813. }
  814.  
  815. void 
  816. obj_symbol_new_hook (symbolP)
  817.      symbolS *symbolP;
  818. {
  819.   symbolP->sy_obj = 0;
  820.  
  821. #ifdef NEED_ECOFF_DEBUG
  822.   if (ECOFF_DEBUGGING)
  823.     ecoff_symbol_new_hook (symbolP);
  824. #endif
  825. }
  826.  
  827. void 
  828. obj_elf_version (ignore)
  829.      int ignore;
  830. {
  831.   char *name;
  832.   unsigned int c;
  833.   char ch;
  834.   char *p;
  835.   asection *seg = now_seg;
  836.   subsegT subseg = now_subseg;
  837.   Elf_Internal_Note i_note;
  838.   Elf_External_Note e_note;
  839.   asection *note_secp = (asection *) NULL;
  840.   int i, len;
  841.  
  842.   SKIP_WHITESPACE ();
  843.   if (*input_line_pointer == '\"')
  844.     {
  845.       ++input_line_pointer;    /* -> 1st char of string. */
  846.       name = input_line_pointer;
  847.  
  848.       while (is_a_char (c = next_char_of_string ()))
  849.     ;
  850.       c = *input_line_pointer;
  851.       *input_line_pointer = '\0';
  852.       *(input_line_pointer - 1) = '\0';
  853.       *input_line_pointer = c;
  854.  
  855.       /* create the .note section */
  856.  
  857.       note_secp = subseg_new (".note", 0);
  858.       bfd_set_section_flags (stdoutput,
  859.                  note_secp,
  860.                  SEC_HAS_CONTENTS | SEC_READONLY);
  861.  
  862.       /* process the version string */
  863.  
  864.       len = strlen (name);
  865.  
  866.       i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
  867.       i_note.descsz = 0;    /* no description */
  868.       i_note.type = NT_VERSION;
  869.       p = frag_more (sizeof (e_note.namesz));
  870.       md_number_to_chars (p, (valueT) i_note.namesz, 4);
  871.       p = frag_more (sizeof (e_note.descsz));
  872.       md_number_to_chars (p, (valueT) i_note.descsz, 4);
  873.       p = frag_more (sizeof (e_note.type));
  874.       md_number_to_chars (p, (valueT) i_note.type, 4);
  875.  
  876.       for (i = 0; i < len; i++)
  877.     {
  878.       ch = *(name + i);
  879.       {
  880.         FRAG_APPEND_1_CHAR (ch);
  881.       }
  882.     }
  883.       frag_align (2, 0);
  884.  
  885.       subseg_set (seg, subseg);
  886.     }
  887.   else
  888.     {
  889.       as_bad ("Expected quoted string");
  890.     }
  891.   demand_empty_rest_of_line ();
  892. }
  893.  
  894. static void
  895. obj_elf_size (ignore)
  896.      int ignore;
  897. {
  898.   char *name = input_line_pointer;
  899.   char c = get_symbol_end ();
  900.   char *p;
  901.   expressionS exp;
  902.   symbolS *sym;
  903.  
  904.   p = input_line_pointer;
  905.   *p = c;
  906.   SKIP_WHITESPACE ();
  907.   if (*input_line_pointer != ',')
  908.     {
  909.       *p = 0;
  910.       as_bad ("expected comma after name `%s' in .size directive", name);
  911.       *p = c;
  912.       ignore_rest_of_line ();
  913.       return;
  914.     }
  915.   input_line_pointer++;
  916.   expression (&exp);
  917.   if (exp.X_op == O_absent)
  918.     {
  919.       as_bad ("missing expression in .size directive");
  920.       exp.X_op = O_constant;
  921.       exp.X_add_number = 0;
  922.     }
  923.   *p = 0;
  924.   sym = symbol_find_or_make (name);
  925.   *p = c;
  926.   if (exp.X_op == O_constant)
  927.     S_SET_SIZE (sym, exp.X_add_number);
  928.   else
  929.     {
  930.       sym->sy_obj = (expressionS *) xmalloc (sizeof (expressionS));
  931.       *sym->sy_obj = exp;
  932.     }
  933.   demand_empty_rest_of_line ();
  934. }
  935.  
  936. /* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
  937.    There are three syntaxes.  The first (used on Solaris) is
  938.        .type SYM,#function
  939.    The second (used on UnixWare) is
  940.        .type SYM,@function
  941.    The third (reportedly to be used on Irix 6.0) is
  942.        .type SYM STT_FUNC
  943.    */
  944.  
  945. static void
  946. obj_elf_type (ignore)
  947.      int ignore;
  948. {
  949.   char *name;
  950.   char c;
  951.   int type;
  952.   const char *typename;
  953.   symbolS *sym;
  954.  
  955.   name = input_line_pointer;
  956.   c = get_symbol_end ();
  957.   sym = symbol_find_or_make (name);
  958.   *input_line_pointer = c;
  959.  
  960.   SKIP_WHITESPACE ();
  961.   if (*input_line_pointer == ',')
  962.     ++input_line_pointer;
  963.  
  964.   SKIP_WHITESPACE ();
  965.   if (*input_line_pointer == '#' || *input_line_pointer == '@')
  966.     ++input_line_pointer;
  967.  
  968.   typename = input_line_pointer;
  969.   c = get_symbol_end ();
  970.  
  971.   type = 0;
  972.   if (strcmp (typename, "function") == 0
  973.       || strcmp (typename, "STT_FUNC") == 0)
  974.     type = BSF_FUNCTION;
  975.   else if (strcmp (typename, "object") == 0
  976.        || strcmp (typename, "STT_OBJECT") == 0)
  977.     type = BSF_OBJECT;
  978.   else
  979.     as_bad ("ignoring unrecognized symbol type \"%s\"", typename);
  980.  
  981.   *input_line_pointer = c;
  982.  
  983.   sym->bsym->flags |= type;
  984.  
  985.   demand_empty_rest_of_line ();
  986. }
  987.  
  988. static void
  989. obj_elf_ident (ignore)
  990.      int ignore;
  991. {
  992.   static segT comment_section;
  993.   segT old_section = now_seg;
  994.   int old_subsection = now_subseg;
  995.  
  996.   if (!comment_section)
  997.     {
  998.       char *p;
  999.       comment_section = subseg_new (".comment", 0);
  1000.       bfd_set_section_flags (stdoutput, comment_section,
  1001.                  SEC_READONLY | SEC_HAS_CONTENTS);
  1002.       p = frag_more (1);
  1003.       *p = 0;
  1004.     }
  1005.   else
  1006.     subseg_set (comment_section, 0);
  1007.   stringer (1);
  1008.   subseg_set (old_section, old_subsection);
  1009. }
  1010.  
  1011. #ifdef INIT_STAB_SECTION
  1012.  
  1013. /* The first entry in a .stabs section is special.  */
  1014.  
  1015. void
  1016. obj_elf_init_stab_section (seg)
  1017.      segT seg;
  1018. {
  1019.   char *file;
  1020.   char *p;
  1021.   char *stabstr_name;
  1022.   unsigned int stroff;
  1023.  
  1024.   /* Force the section to align to a longword boundary.  Without this,
  1025.      UnixWare ar crashes.  */
  1026.   bfd_set_section_alignment (stdoutput, seg, 2);
  1027.  
  1028.   /* Make space for this first symbol. */
  1029.   p = frag_more (12);
  1030.   /* Zero it out. */
  1031.   memset (p, 0, 12);
  1032.   as_where (&file, (unsigned int *) NULL);
  1033.   stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
  1034.   strcpy (stabstr_name, segment_name (seg));
  1035.   strcat (stabstr_name, "str");
  1036.   stroff = get_stab_string_offset (file, stabstr_name);
  1037.   know (stroff == 1);
  1038.   md_number_to_chars (p, stroff, 4);
  1039.   seg_info (seg)->stabu.p = p;
  1040. }
  1041.  
  1042. #endif
  1043.  
  1044. /* Fill in the counts in the first entry in a .stabs section.  */
  1045.  
  1046. static void
  1047. adjust_stab_sections (abfd, sec, xxx)
  1048.      bfd *abfd;
  1049.      asection *sec;
  1050.      PTR xxx;
  1051. {
  1052.   char *name;
  1053.   asection *strsec;
  1054.   char *p;
  1055.   int strsz, nsyms;
  1056.  
  1057.   if (strncmp (".stab", sec->name, 5))
  1058.     return;
  1059.   if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
  1060.     return;
  1061.  
  1062.   name = (char *) alloca (strlen (sec->name) + 4);
  1063.   strcpy (name, sec->name);
  1064.   strcat (name, "str");
  1065.   strsec = bfd_get_section_by_name (abfd, name);
  1066.   if (strsec)
  1067.     strsz = bfd_section_size (abfd, strsec);
  1068.   else
  1069.     strsz = 0;
  1070.   nsyms = bfd_section_size (abfd, sec) / 12 - 1;
  1071.  
  1072.   p = seg_info (sec)->stabu.p;
  1073.   assert (p != 0);
  1074.  
  1075.   bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
  1076.   bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
  1077. }
  1078.  
  1079. #ifdef NEED_ECOFF_DEBUG
  1080.  
  1081. /* This function is called by the ECOFF code.  It is supposed to
  1082.    record the external symbol information so that the backend can
  1083.    write it out correctly.  The ELF backend doesn't actually handle
  1084.    this at the moment, so we do it ourselves.  We save the information
  1085.    in the symbol.  */
  1086.  
  1087. void
  1088. elf_ecoff_set_ext (sym, ext)
  1089.      symbolS *sym;
  1090.      struct ecoff_extr *ext;
  1091. {
  1092.   sym->bsym->udata.p = (PTR) ext;
  1093. }
  1094.  
  1095. /* This function is called by bfd_ecoff_debug_externals.  It is
  1096.    supposed to *EXT to the external symbol information, and return
  1097.    whether the symbol should be used at all.  */
  1098.  
  1099. static boolean
  1100. elf_get_extr (sym, ext)
  1101.      asymbol *sym;
  1102.      EXTR *ext;
  1103. {
  1104.   if (sym->udata.p == NULL)
  1105.     return false;
  1106.   *ext = *(EXTR *) sym->udata.p;
  1107.   return true;
  1108. }
  1109.  
  1110. /* This function is called by bfd_ecoff_debug_externals.  It has
  1111.    nothing to do for ELF.  */
  1112.  
  1113. /*ARGSUSED*/
  1114. static void
  1115. elf_set_index (sym, indx)
  1116.      asymbol *sym;
  1117.      bfd_size_type indx;
  1118. {
  1119. }
  1120.  
  1121. #endif /* NEED_ECOFF_DEBUG */
  1122.  
  1123. void
  1124. elf_frob_symbol (symp, puntp)
  1125.      symbolS *symp;
  1126.      int *puntp;
  1127. {
  1128. #ifdef NEED_ECOFF_DEBUG
  1129.   if (ECOFF_DEBUGGING)
  1130.     ecoff_frob_symbol (symp);
  1131. #endif
  1132.  
  1133.   if (symp->sy_obj)
  1134.     {
  1135.       switch (symp->sy_obj->X_op)
  1136.     {
  1137.     case O_subtract:
  1138.       S_SET_SIZE (symp,
  1139.               (S_GET_VALUE (symp->sy_obj->X_add_symbol)
  1140.                + symp->sy_obj->X_add_number
  1141.                - S_GET_VALUE (symp->sy_obj->X_op_symbol)));
  1142.       break;
  1143.     case O_constant:
  1144.       S_SET_SIZE (symp,
  1145.               (S_GET_VALUE (symp->sy_obj->X_add_symbol)
  1146.                + symp->sy_obj->X_add_number));
  1147.       break;
  1148.     default:
  1149.       as_bad (".size expression too complicated to fix up");
  1150.       break;
  1151.     }
  1152.       free (symp->sy_obj);
  1153.       symp->sy_obj = 0;
  1154.     }
  1155.  
  1156.   /* Double check weak symbols.  */
  1157.   if (symp->bsym->flags & BSF_WEAK)
  1158.     {
  1159.       if (S_IS_COMMON (symp))
  1160.     as_bad ("Symbol `%s' can not be both weak and common",
  1161.         S_GET_NAME (symp));
  1162.     }
  1163.  
  1164. #ifdef TC_MIPS
  1165.   /* The Irix 5 assembler appears to set the type of any common symbol
  1166.      to STT_OBJECT.  We try to be compatible, since the Irix 5 linker
  1167.      apparently sometimes cares.  FIXME: What about Irix 6?  */
  1168.   if (S_IS_COMMON (symp))
  1169.     symp->bsym->flags |= BSF_OBJECT;
  1170. #endif
  1171.  
  1172. #ifdef TC_PPC
  1173.   /* Frob the PowerPC, so that the symbol always has object type
  1174.      if it is not some other type.  VxWorks needs this.  */
  1175.   if ((symp->bsym->flags & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
  1176.       && S_IS_DEFINED (symp))
  1177.     symp->bsym->flags |= BSF_OBJECT;
  1178. #endif
  1179. }
  1180.  
  1181. void 
  1182. elf_frob_file ()
  1183. {
  1184.   bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
  1185.  
  1186. #ifdef elf_tc_final_processing
  1187.   elf_tc_final_processing ();
  1188. #endif
  1189.  
  1190. #ifdef NEED_ECOFF_DEBUG
  1191.   if (ECOFF_DEBUGGING)
  1192.     /* Generate the ECOFF debugging information.  */
  1193.     {
  1194.       const struct ecoff_debug_swap *debug_swap;
  1195.       struct ecoff_debug_info debug;
  1196.       char *buf;
  1197.       asection *sec;
  1198.  
  1199.       debug_swap
  1200.     = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
  1201.       know (debug_swap != (const struct ecoff_debug_swap *) NULL);
  1202.       ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
  1203.  
  1204.       /* Set up the pointers in debug.  */
  1205. #define SET(ptr, offset, type) \
  1206.     debug.ptr = (type) (buf + debug.symbolic_header.offset)
  1207.  
  1208.     SET (line, cbLineOffset, unsigned char *);
  1209.       SET (external_dnr, cbDnOffset, PTR);
  1210.       SET (external_pdr, cbPdOffset, PTR);
  1211.       SET (external_sym, cbSymOffset, PTR);
  1212.       SET (external_opt, cbOptOffset, PTR);
  1213.       SET (external_aux, cbAuxOffset, union aux_ext *);
  1214.       SET (ss, cbSsOffset, char *);
  1215.       SET (external_fdr, cbFdOffset, PTR);
  1216.       SET (external_rfd, cbRfdOffset, PTR);
  1217.       /* ssext and external_ext are set up just below.  */
  1218.  
  1219. #undef SET    
  1220.  
  1221.       /* Set up the external symbols.  */
  1222.       debug.ssext = debug.ssext_end = NULL;
  1223.       debug.external_ext = debug.external_ext_end = NULL;
  1224.       if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
  1225.                        elf_get_extr, elf_set_index))
  1226.     as_fatal ("Failed to set up debugging information: %s",
  1227.           bfd_errmsg (bfd_get_error ()));
  1228.  
  1229.       sec = bfd_get_section_by_name (stdoutput, ".mdebug");
  1230.       assert (sec != NULL);
  1231.  
  1232.       know (stdoutput->output_has_begun == false);
  1233.  
  1234.       /* We set the size of the section, call bfd_set_section_contents
  1235.      to force the ELF backend to allocate a file position, and then
  1236.      write out the data.  FIXME: Is this really the best way to do
  1237.      this?  */
  1238.       sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
  1239.  
  1240.       if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
  1241.                       (file_ptr) 0, (bfd_size_type) 0))
  1242.     as_fatal ("Can't start writing .mdebug section: %s",
  1243.           bfd_errmsg (bfd_get_error ()));
  1244.  
  1245.       know (stdoutput->output_has_begun == true);
  1246.       know (sec->filepos != 0);
  1247.  
  1248.       if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
  1249.                    sec->filepos))
  1250.     as_fatal ("Could not write .mdebug section: %s",
  1251.           bfd_errmsg (bfd_get_error ()));
  1252.     }
  1253. #endif /* NEED_ECOFF_DEBUG */
  1254. }
  1255.  
  1256. const struct format_ops elf_format_ops =
  1257. {
  1258.   bfd_target_elf_flavour,
  1259.   0,
  1260.   1,
  1261.   elf_frob_symbol,
  1262.   elf_frob_file,
  1263.   elf_s_get_size, elf_s_set_size,
  1264.   elf_s_get_align, elf_s_set_align,
  1265.   elf_copy_symbol_attributes,
  1266. #ifdef NEED_ECOFF_DEBUG
  1267.   ecoff_generate_asm_lineno,
  1268.   ecoff_stab,
  1269. #else
  1270.   0,
  1271.   0,                /* process_stab */
  1272. #endif
  1273.   elf_sec_sym_ok_for_reloc,
  1274.   elf_pop_insert,
  1275. #ifdef NEED_ECOFF_DEBUG
  1276.   elf_ecoff_set_ext,
  1277. #else
  1278.   0,
  1279. #endif
  1280.   obj_read_begin_hook,
  1281.   obj_symbol_new_hook,
  1282. };
  1283.