Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Functions | Variables
obj-elf.h File Reference
#include "bfd/elf-bfd.h"
#include "targ-cpu.h"
#include "dwarf2dbg.h"

Go to the source code of this file.

Classes

struct  elf_obj_sy

Defines

#define OBJ_ELF   1
#define OUTPUT_FLAVOR   bfd_target_elf_flavour
#define BYTES_IN_WORD   4 /* for now */
#define OBJ_SYMFIELD_TYPE   struct elf_obj_sy
#define ELF_TARGET_SYMBOL_FIELDS   unsigned int local:1;
#define TARGET_SYMBOL_FIELDS   ELF_TARGET_SYMBOL_FIELDS
#define FALSE   0
#define TRUE   !FALSE
#define obj_begin()   elf_begin ()
#define elf_symbol(asymbol)   ((elf_symbol_type *) (&(asymbol)->the_bfd))
#define S_GET_SIZE(S)   (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_size)
#define S_SET_SIZE(S, V)   (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_size = (V))
#define S_GET_ALIGN(S)   (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_value)
#define S_SET_ALIGN(S, V)   (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_value = (V))
#define S_GET_OTHER(S)   (elf_s_get_other (S))
#define S_SET_OTHER(S, V)   (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_other = (V))
#define obj_frob_file   elf_frob_file
#define obj_frob_file_before_adjust   elf_frob_file_before_adjust
#define obj_frob_file_after_relocs   elf_frob_file_after_relocs
#define obj_frob_label   dwarf2_emit_label
#define obj_app_file   elf_file_symbol
#define obj_sec_sym_ok_for_reloc(SEC)   ((SEC)->owner != 0)
#define obj_read_begin_hook   elf_obj_read_begin_hook
#define obj_symbol_new_hook   elf_obj_symbol_new_hook
#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC)   (elf_copy_symbol_attributes (DEST, SRC))
#define SEPARATE_STAB_SECTIONS   1
#define INIT_STAB_SECTION(seg)   obj_elf_init_stab_section (seg)
#define obj_frob_symbol(symp, punt)   elf_frob_symbol (symp, &punt)
#define obj_pop_insert()   elf_pop_insert()
#define obj_ecoff_set_ext   elf_ecoff_set_ext

Functions

void elf_begin (void)
int elf_s_get_other (symbolS *)
void elf_frob_file (void)
void elf_frob_file_before_adjust (void)
void elf_frob_file_after_relocs (void)
void elf_file_symbol (const char *, int)
void obj_elf_section_change_hook (void)
void obj_elf_section (int)
void obj_elf_previous (int)
void obj_elf_version (int)
void obj_elf_common (int)
void obj_elf_data (int)
void obj_elf_text (int)
void obj_elf_change_section (const char *, int, int, int, const char *, int, int)
struct fixobj_elf_vtable_inherit (int)
struct fixobj_elf_vtable_entry (int)
void elf_obj_read_begin_hook (void)
void elf_obj_symbol_new_hook (symbolS *)
void elf_copy_symbol_attributes (symbolS *, symbolS *)
void obj_elf_init_stab_section (segT)
void elf_frob_symbol (symbolS *, int *)
void elf_pop_insert (void)
void elf_ecoff_set_ext (symbolS *, struct ecoff_extr *)
symbolS * elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)

Variables

asectiongdb_section
asectionelf_com_section_ptr

Class Documentation

struct elf_obj_sy

Definition at line 60 of file obj-elf.h.

Collaboration diagram for elf_obj_sy:
Class Members
int local
expressionS * size
char * versioned_name

Define Documentation

#define BYTES_IN_WORD   4 /* for now */

Definition at line 37 of file obj-elf.h.

#define elf_symbol (   asymbol)    ((elf_symbol_type *) (&(asymbol)->the_bfd))

Definition at line 102 of file obj-elf.h.

#define ELF_TARGET_SYMBOL_FIELDS   unsigned int local:1;

Definition at line 84 of file obj-elf.h.

#define FALSE   0

Definition at line 92 of file obj-elf.h.

Definition at line 207 of file obj-elf.h.

Definition at line 156 of file obj-elf.h.

#define obj_begin ( )    elf_begin ()

Definition at line 97 of file obj-elf.h.

Definition at line 191 of file obj-elf.h.

Definition at line 239 of file obj-elf.h.

#define OBJ_ELF   1

Definition at line 28 of file obj-elf.h.

Definition at line 134 of file obj-elf.h.

Definition at line 144 of file obj-elf.h.

Definition at line 139 of file obj-elf.h.

Definition at line 152 of file obj-elf.h.

#define obj_frob_symbol (   symp,
  punt 
)    elf_frob_symbol (symp, &punt)

Definition at line 230 of file obj-elf.h.

#define obj_pop_insert ( )    elf_pop_insert()

Definition at line 235 of file obj-elf.h.

Definition at line 181 of file obj-elf.h.

#define obj_sec_sym_ok_for_reloc (   SEC)    ((SEC)->owner != 0)

Definition at line 176 of file obj-elf.h.

Definition at line 186 of file obj-elf.h.

Definition at line 81 of file obj-elf.h.

Definition at line 34 of file obj-elf.h.

#define S_GET_ALIGN (   S)    (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_value)

Definition at line 114 of file obj-elf.h.

#define S_GET_OTHER (   S)    (elf_s_get_other (S))

Definition at line 124 of file obj-elf.h.

#define S_GET_SIZE (   S)    (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_size)

Definition at line 105 of file obj-elf.h.

#define S_SET_ALIGN (   S,
  V 
)    (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_value = (V))

Definition at line 118 of file obj-elf.h.

#define S_SET_OTHER (   S,
  V 
)    (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_other = (V))

Definition at line 127 of file obj-elf.h.

#define S_SET_SIZE (   S,
  V 
)    (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_size = (V))

Definition at line 109 of file obj-elf.h.

#define SEPARATE_STAB_SECTIONS   1

Definition at line 202 of file obj-elf.h.

Definition at line 88 of file obj-elf.h.

#define TRUE   !FALSE

Definition at line 93 of file obj-elf.h.


Function Documentation

void elf_begin ( void  )

Definition at line 189 of file obj-elf.c.

Here is the call graph for this function:

symbolS* elf_common_parse ( int ignore  ATTRIBUTE_UNUSED,
symbolS *  symbolP,
addressT  size 
)

Definition at line 286 of file obj-elf.c.

{
  addressT align = 0;
  int is_local = symbol_get_obj (symbolP)->local;

  if (*input_line_pointer == ',')
    {
      char *save = input_line_pointer;

      input_line_pointer++;
      SKIP_WHITESPACE ();

      if (*input_line_pointer == '"')
       {
         /* For sparc.  Accept .common symbol, length, "bss"  */
         input_line_pointer++;
         /* Some use the dot, some don't.  */
         if (*input_line_pointer == '.')
           input_line_pointer++;
         /* Some say data, some say bss.  */
         if (strncmp (input_line_pointer, "bss\"", 4) == 0)
           input_line_pointer += 4;
         else if (strncmp (input_line_pointer, "data\"", 5) == 0)
           input_line_pointer += 5;
         else
           {
             char *p = input_line_pointer;
             char c;

             while (*--p != '"')
              ;
             while (!is_end_of_line[(unsigned char) *input_line_pointer])
              if (*input_line_pointer++ == '"')
                break;
             c = *input_line_pointer;
             *input_line_pointer = '\0';
             as_bad (_("bad .common segment %s"), p);
             *input_line_pointer = c;
             ignore_rest_of_line ();
             return NULL;
           }
         /* ??? Don't ask me why these are always global.  */
         is_local = 0;
       }
      else
       {
         input_line_pointer = save;
         align = parse_align (is_local);
         if (align == (addressT) -1)
           return NULL;
       }
    }

  if (is_local)
    {
      bss_alloc (symbolP, size, align);
      S_CLEAR_EXTERNAL (symbolP);
    }
  else
    {
      S_SET_VALUE (symbolP, size);
      S_SET_ALIGN (symbolP, align);
      S_SET_EXTERNAL (symbolP);
      S_SET_SEGMENT (symbolP, elf_com_section_ptr);
    }

  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;

  return symbolP;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void elf_copy_symbol_attributes ( symbolS *  ,
symbolS *   
)

Definition at line 1393 of file obj-elf.c.

{
  struct elf_obj_sy *srcelf = symbol_get_obj (src);
  struct elf_obj_sy *destelf = symbol_get_obj (dest);
  if (srcelf->size)
    {
      if (destelf->size == NULL)
       destelf->size = xmalloc (sizeof (expressionS));
      *destelf->size = *srcelf->size;
    }
  else
    {
      if (destelf->size != NULL)
       free (destelf->size);
      destelf->size = NULL;
    }
  S_SET_SIZE (dest, S_GET_SIZE (src));
  /* Don't copy visibility.  */
  S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
                    | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
}

Here is the call graph for this function:

void elf_ecoff_set_ext ( symbolS *  ,
struct ecoff_extr  
)
void elf_file_symbol ( const char *  ,
int   
)

Definition at line 254 of file obj-elf.c.

{
  if (!appfile
      || symbol_rootP == NULL
      || symbol_rootP->bsym == NULL
      || (symbol_rootP->bsym->flags & BSF_FILE) == 0)
    {
      symbolS *sym;

      sym = symbol_new (s, absolute_section, 0, NULL);
      symbol_set_frag (sym, &zero_address_frag);
      symbol_get_bfdsym (sym)->flags |= BSF_FILE;

      if (symbol_rootP != sym)
       {
         symbol_remove (sym, &symbol_rootP, &symbol_lastP);
         symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
#ifdef DEBUG
         verify_symbol_chain (symbol_rootP, symbol_lastP);
#endif
       }
    }

#ifdef NEED_ECOFF_DEBUG
  ecoff_new_file (s, appfile);
#endif
}

Here is the call graph for this function:

void elf_frob_file ( void  )

Definition at line 1920 of file obj-elf.c.

{
  struct group_list list;
  unsigned int i;

  bfd_map_over_sections (stdoutput, adjust_stab_sections, NULL);

  /* Go find section groups.  */
  list.num_group = 0;
  list.head = NULL;
  list.elt_count = NULL;
  bfd_map_over_sections (stdoutput, build_group_lists, &list);

  /* Make the SHT_GROUP sections that describe each section group.  We
     can't set up the section contents here yet, because elf section
     indices have yet to be calculated.  elf.c:set_group_contents does
     the rest of the work.  */
  for (i = 0; i < list.num_group; i++)
    {
      const char *group_name = elf_group_name (list.head[i]);
      const char *sec_name;
      asection *s;
      flagword flags;
      struct symbol *sy;
      int has_sym;
      bfd_size_type size;

      flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
      for (s = list.head[i]; s != NULL; s = elf_next_in_group (s))
       if ((s->flags ^ flags) & SEC_LINK_ONCE)
         {
           flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
           if (s != list.head[i])
             {
              as_warn (_("assuming all members of group `%s' are COMDAT"),
                      group_name);
              break;
             }
         }

      sec_name = group_name;
      sy = symbol_find_exact (group_name);
      has_sym = 0;
      if (sy != NULL
         && (sy == symbol_lastP
             || (sy->sy_next != NULL
                && sy->sy_next->sy_previous == sy)))
       {
         has_sym = 1;
         sec_name = ".group";
       }
      s = subseg_force_new (sec_name, 0);
      if (s == NULL
         || !bfd_set_section_flags (stdoutput, s, flags)
         || !bfd_set_section_alignment (stdoutput, s, 2))
       {
         as_fatal (_("can't create group: %s"),
                  bfd_errmsg (bfd_get_error ()));
       }
      elf_section_type (s) = SHT_GROUP;

      /* Pass a pointer to the first section in this group.  */
      elf_next_in_group (s) = list.head[i];
      if (has_sym)
       elf_group_id (s) = sy->bsym;

      size = 4 * (list.elt_count[i] + 1);
      bfd_set_section_size (stdoutput, s, size);
      s->contents = (unsigned char *) frag_more (size);
      frag_now->fr_fix = frag_now_fix_octets ();
      frag_wane (frag_now);
    }

#ifdef elf_tc_final_processing
  elf_tc_final_processing ();
#endif
}

Here is the call graph for this function:

void elf_frob_file_after_relocs ( void  )

Definition at line 2048 of file obj-elf.c.

{
#ifdef NEED_ECOFF_DEBUG
  if (ECOFF_DEBUGGING)
    /* Generate the ECOFF debugging information.  */
    {
      const struct ecoff_debug_swap *debug_swap;
      struct ecoff_debug_info debug;
      char *buf;
      asection *sec;

      debug_swap
       = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
      know (debug_swap != NULL);
      ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);

      /* Set up the pointers in debug.  */
#define SET(ptr, offset, type) \
    debug.ptr = (type) (buf + debug.symbolic_header.offset)

      SET (line, cbLineOffset, unsigned char *);
      SET (external_dnr, cbDnOffset, void *);
      SET (external_pdr, cbPdOffset, void *);
      SET (external_sym, cbSymOffset, void *);
      SET (external_opt, cbOptOffset, void *);
      SET (external_aux, cbAuxOffset, union aux_ext *);
      SET (ss, cbSsOffset, char *);
      SET (external_fdr, cbFdOffset, void *);
      SET (external_rfd, cbRfdOffset, void *);
      /* ssext and external_ext are set up just below.  */

#undef SET

      /* Set up the external symbols.  */
      debug.ssext = debug.ssext_end = NULL;
      debug.external_ext = debug.external_ext_end = NULL;
      if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, TRUE,
                                   elf_get_extr, elf_set_index))
       as_fatal (_("failed to set up debugging information: %s"),
                bfd_errmsg (bfd_get_error ()));

      sec = bfd_get_section_by_name (stdoutput, ".mdebug");
      assert (sec != NULL);

      know (!stdoutput->output_has_begun);

      /* We set the size of the section, call bfd_set_section_contents
        to force the ELF backend to allocate a file position, and then
        write out the data.  FIXME: Is this really the best way to do
        this?  */
      bfd_set_section_size
       (stdoutput, sec, bfd_ecoff_debug_size (stdoutput, &debug, debug_swap));

      /* Pass BUF to bfd_set_section_contents because this will
        eventually become a call to fwrite, and ISO C prohibits
        passing a NULL pointer to a stdio function even if the
        pointer will not be used.  */
      if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
       as_fatal (_("can't start writing .mdebug section: %s"),
                bfd_errmsg (bfd_get_error ()));

      know (stdoutput->output_has_begun);
      know (sec->filepos != 0);

      if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
                               sec->filepos))
       as_fatal (_("could not write .mdebug section: %s"),
                bfd_errmsg (bfd_get_error ()));
    }
#endif /* NEED_ECOFF_DEBUG */
}

Here is the call graph for this function:

void elf_frob_file_before_adjust ( void  )

Definition at line 2001 of file obj-elf.c.

{
  if (symbol_rootP)
    {
      symbolS *symp;

      for (symp = symbol_rootP; symp; symp = symbol_next (symp))
       if (!S_IS_DEFINED (symp))
         {
           if (symbol_get_obj (symp)->versioned_name)
             {
              char *p;

              /* The @@@ syntax is a special case. If the symbol is
                 not defined, 2 `@'s will be removed from the
                 versioned_name.  */

              p = strchr (symbol_get_obj (symp)->versioned_name,
                         ELF_VER_CHR);
              know (p != NULL);
              if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
                {
                  size_t l = strlen (&p[3]) + 1;
                  memmove (&p[1], &p[3], l);
                }
              if (symbol_used_p (symp) == 0
                  && symbol_used_in_reloc_p (symp) == 0)
                symbol_remove (symp, &symbol_rootP, &symbol_lastP);
             }

           /* If there was .weak foo, but foo was neither defined nor
              used anywhere, remove it.  */

           else if (S_IS_WEAK (symp)
                   && symbol_used_p (symp) == 0
                   && symbol_used_in_reloc_p (symp) == 0)
             symbol_remove (symp, &symbol_rootP, &symbol_lastP);
         }
    }
}

Here is the call graph for this function:

void elf_frob_symbol ( symbolS *  ,
int  
)

Definition at line 1727 of file obj-elf.c.

{
  struct elf_obj_sy *sy_obj;

#ifdef NEED_ECOFF_DEBUG
  if (ECOFF_DEBUGGING)
    ecoff_frob_symbol (symp);
#endif

  sy_obj = symbol_get_obj (symp);

  if (sy_obj->size != NULL)
    {
      switch (sy_obj->size->X_op)
       {
       case O_subtract:
         S_SET_SIZE (symp,
                    (S_GET_VALUE (sy_obj->size->X_add_symbol)
                     + sy_obj->size->X_add_number
                     - S_GET_VALUE (sy_obj->size->X_op_symbol)));
         break;
       case O_constant:
         S_SET_SIZE (symp,
                    (S_GET_VALUE (sy_obj->size->X_add_symbol)
                     + sy_obj->size->X_add_number));
         break;
       default:
         as_bad (_(".size expression too complicated to fix up"));
         break;
       }
      free (sy_obj->size);
      sy_obj->size = NULL;
    }

  if (sy_obj->versioned_name != NULL)
    {
      char *p;

      p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
      know (p != NULL);

      /* This symbol was given a new name with the .symver directive.

        If this is an external reference, just rename the symbol to
        include the version string.  This will make the relocs be
        against the correct versioned symbol.

        If this is a definition, add an alias.  FIXME: Using an alias
        will permit the debugging information to refer to the right
        symbol.  However, it's not clear whether it is the best
        approach.  */

      if (! S_IS_DEFINED (symp))
       {
         /* Verify that the name isn't using the @@ syntax--this is
            reserved for definitions of the default version to link
            against.  */
         if (p[1] == ELF_VER_CHR)
           {
             as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
                    sy_obj->versioned_name);
             *puntp = TRUE;
           }
         S_SET_NAME (symp, sy_obj->versioned_name);
       }
      else
       {
         if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
           {
             size_t l;

             /* The @@@ syntax is a special case. It renames the
               symbol name to versioned_name with one `@' removed.  */
             l = strlen (&p[3]) + 1;
             memmove (&p[2], &p[3], l);
             S_SET_NAME (symp, sy_obj->versioned_name);
           }
         else
           {
             symbolS *symp2;

             /* FIXME: Creating a new symbol here is risky.  We're
               in the final loop over the symbol table.  We can
               get away with it only because the symbol goes to
               the end of the list, where the loop will still see
               it.  It would probably be better to do this in
               obj_frob_file_before_adjust.  */

             symp2 = symbol_find_or_make (sy_obj->versioned_name);

             /* Now we act as though we saw symp2 = sym.  */

             S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));

             /* Subtracting out the frag address here is a hack
               because we are in the middle of the final loop.  */
             S_SET_VALUE (symp2,
                        (S_GET_VALUE (symp)
                         - symbol_get_frag (symp)->fr_address));

             symbol_set_frag (symp2, symbol_get_frag (symp));

             /* This will copy over the size information.  */
             copy_symbol_attributes (symp2, symp);

             S_SET_OTHER (symp2, S_GET_OTHER (symp));

             if (S_IS_WEAK (symp))
              S_SET_WEAK (symp2);

             if (S_IS_EXTERNAL (symp))
              S_SET_EXTERNAL (symp2);
           }
       }
    }

  /* Double check weak symbols.  */
  if (S_IS_WEAK (symp))
    {
      if (S_IS_COMMON (symp))
       as_bad (_("symbol `%s' can not be both weak and common"),
              S_GET_NAME (symp));
    }

#ifdef TC_MIPS
  /* The Irix 5 and 6 assemblers set the type of any common symbol and
     any undefined non-function symbol to STT_OBJECT.  We try to be
     compatible, since newer Irix 5 and 6 linkers care.  However, we
     only set undefined symbols to be STT_OBJECT if we are on Irix,
     because that is the only time gcc will generate the necessary
     .global directives to mark functions.  */

  if (S_IS_COMMON (symp))
    symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;

  if (strstr (TARGET_OS, "irix") != NULL
      && ! S_IS_DEFINED (symp)
      && (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0)
    symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
#endif
}

Here is the call graph for this function:

void elf_obj_read_begin_hook ( void  )

Definition at line 1365 of file obj-elf.c.

{
#ifdef NEED_ECOFF_DEBUG
  if (ECOFF_DEBUGGING)
    ecoff_read_begin_hook ();
#endif
}
void elf_obj_symbol_new_hook ( symbolS *  )

Definition at line 1374 of file obj-elf.c.

{
  struct elf_obj_sy *sy_obj;

  sy_obj = symbol_get_obj (symbolP);
  sy_obj->size = NULL;
  sy_obj->versioned_name = NULL;

#ifdef NEED_ECOFF_DEBUG
  if (ECOFF_DEBUGGING)
    ecoff_symbol_new_hook (symbolP);
#endif
}
void elf_pop_insert ( void  )

Definition at line 204 of file obj-elf.c.

Here is the call graph for this function:

int elf_s_get_other ( symbolS *  )

Definition at line 236 of file obj-elf.c.

{
  return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
}

Here is the call graph for this function:

void obj_elf_change_section ( const char *  ,
int  ,
int  ,
int  ,
const char *  ,
int  ,
int   
)

Definition at line 524 of file obj-elf.c.

{
  asection *old_sec;
  segT sec;
  flagword flags;
  const struct elf_backend_data *bed;
  const struct bfd_elf_special_section *ssect;

#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  /* Switch to the section, creating it if necessary.  */
  if (push)
    {
      struct section_stack *elt;
      elt = xmalloc (sizeof (struct section_stack));
      elt->next = section_stack;
      elt->seg = now_seg;
      elt->prev_seg = previous_section;
      elt->subseg = now_subseg;
      elt->prev_subseg = previous_subsection;
      section_stack = elt;
    }
  previous_section = now_seg;
  previous_subsection = now_subseg;

  old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
                                   (void *) group_name);
  if (old_sec)
    {
      sec = old_sec;
      subseg_set (sec, 0);
    }
  else
    sec = subseg_force_new (name, 0);

  bed = get_elf_backend_data (stdoutput);
  ssect = (*bed->get_sec_type_attr) (stdoutput, sec);

  if (ssect != NULL)
    {
      bfd_boolean override = FALSE;

      if (type == SHT_NULL)
       type = ssect->type;
      else if (type != ssect->type)
       {
         if (old_sec == NULL
             /* FIXME: gcc, as of 2002-10-22, will emit

               .section .init_array,"aw",@progbits

               for __attribute__ ((section (".init_array"))).
               "@progbits" is incorrect.  Also for x86-64 large bss
               sections, gcc, as of 2005-07-06, will emit

               .section .lbss,"aw",@progbits

               "@progbits" is incorrect.  */
#ifdef TC_I386
             && (bed->s->arch_size != 64
                || !(ssect->attr & SHF_X86_64_LARGE))
#endif
             && ssect->type != SHT_INIT_ARRAY
             && ssect->type != SHT_FINI_ARRAY
             && ssect->type != SHT_PREINIT_ARRAY)
           {
             /* We allow to specify any type for a .note section.  */
             if (ssect->type != SHT_NOTE)
              as_warn (_("setting incorrect section type for %s"),
                      name);
           }
         else
           {
             as_warn (_("ignoring incorrect section type for %s"),
                     name);
             type = ssect->type;
           }
       }

      if (old_sec == NULL && (attr & ~ssect->attr) != 0)
       {
         /* As a GNU extension, we permit a .note section to be
            allocatable.  If the linker sees an allocatable .note
            section, it will create a PT_NOTE segment in the output
            file.  We also allow "x" for .note.GNU-stack.  */
         if (ssect->type == SHT_NOTE
             && (attr == SHF_ALLOC || attr == SHF_EXECINSTR))
           ;
         /* Allow different SHF_MERGE and SHF_STRINGS if we have
            something like .rodata.str.  */
         else if (ssect->suffix_length == -2
                 && name[ssect->prefix_length] == '.'
                 && (attr
                     & ~ssect->attr
                     & ~SHF_MERGE
                     & ~SHF_STRINGS) == 0)
           ;
         /* .interp, .strtab and .symtab can have SHF_ALLOC.  */
         else if (attr == SHF_ALLOC
                 && (strcmp (name, ".interp") == 0
                     || strcmp (name, ".strtab") == 0
                     || strcmp (name, ".symtab") == 0))
           override = TRUE;
         /* .note.GNU-stack can have SHF_EXECINSTR.  */
         else if (attr == SHF_EXECINSTR
                 && strcmp (name, ".note.GNU-stack") == 0)
           override = TRUE;
#ifdef TC_ALPHA
         /* A section on Alpha may have SHF_ALPHA_GPREL.  */
         else if ((attr & ~ssect->attr) == SHF_ALPHA_GPREL)
           override = TRUE;
#endif
         else
           {
             if (group_name == NULL)
              as_warn (_("setting incorrect section attributes for %s"),
                      name);
             override = TRUE;
           }
       }
      if (!override && old_sec == NULL)
       attr |= ssect->attr;
    }

  /* Convert ELF type and flags to BFD flags.  */
  flags = (SEC_RELOC
          | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
          | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
          | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
          | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
          | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
          | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
          | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
#ifdef md_elf_section_flags
  flags = md_elf_section_flags (flags, attr, type);
#endif

  if (linkonce)
    flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;

  if (old_sec == NULL)
    {
      symbolS *secsym;

      elf_section_type (sec) = type;
      elf_section_flags (sec) = attr;

      /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
      if (type == SHT_NOBITS)
       seg_info (sec)->bss = 1;

      bfd_set_section_flags (stdoutput, sec, flags);
      if (flags & SEC_MERGE)
       sec->entsize = entsize;
      elf_group_name (sec) = group_name;

      /* Add a symbol for this section to the symbol table.  */
      secsym = symbol_find (name);
      if (secsym != NULL)
       symbol_set_bfdsym (secsym, sec->symbol);
      else
       symbol_table_insert (section_symbol (sec));
    }
  else
    {
      if (type != SHT_NULL
         && (unsigned) type != elf_section_type (old_sec))
       as_warn (_("ignoring changed section type for %s"), name);

      if (attr != 0)
       {
         /* If section attributes are specified the second time we see a
            particular section, then check that they are the same as we
            saw the first time.  */
         if (((old_sec->flags ^ flags)
              & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
                | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
                | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
                | SEC_THREAD_LOCAL)))
           as_warn (_("ignoring changed section attributes for %s"), name);
         if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
           as_warn (_("ignoring changed section entity size for %s"), name);
       }
    }

#ifdef md_elf_section_change_hook
  md_elf_section_change_hook ();
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void obj_elf_common ( int  )

Definition at line 358 of file obj-elf.c.

{
  if (flag_mri && is_common)
    s_mri_common (0);
  else
    s_comm_internal (0, elf_common_parse);
}

Here is the call graph for this function:

void obj_elf_data ( int  )

Definition at line 1037 of file obj-elf.c.

{
#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  previous_section = now_seg;
  previous_subsection = now_subseg;
  s_data (i);

#ifdef md_elf_section_change_hook
  md_elf_section_change_hook ();
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Here is the caller graph for this function:

void obj_elf_previous ( int  )
void obj_elf_section ( int  )

Definition at line 879 of file obj-elf.c.

{
  char *name, *group_name, *beg;
  int type, attr, dummy;
  int entsize;
  int linkonce;

#ifndef TC_I370
  if (flag_mri)
    {
      char mri_type;

#ifdef md_flush_pending_output
      md_flush_pending_output ();
#endif

      previous_section = now_seg;
      previous_subsection = now_subseg;

      s_mri_sect (&mri_type);

#ifdef md_elf_section_change_hook
      md_elf_section_change_hook ();
#endif

      return;
    }
#endif /* ! defined (TC_I370) */

  name = obj_elf_section_name ();
  if (name == NULL)
    return;
  type = SHT_NULL;
  attr = 0;
  group_name = NULL;
  entsize = 0;
  linkonce = 0;

  if (*input_line_pointer == ',')
    {
      /* Skip the comma.  */
      ++input_line_pointer;
      SKIP_WHITESPACE ();

      if (*input_line_pointer == '"')
       {
         beg = demand_copy_C_string (&dummy);
         if (beg == NULL)
           {
             ignore_rest_of_line ();
             return;
           }
         attr |= obj_elf_parse_section_letters (beg, strlen (beg));

         SKIP_WHITESPACE ();
         if (*input_line_pointer == ',')
           {
             char c;
             char *save = input_line_pointer;

             ++input_line_pointer;
             SKIP_WHITESPACE ();
             c = *input_line_pointer;
             if (c == '"')
              {
                beg = demand_copy_C_string (&dummy);
                if (beg == NULL)
                  {
                    ignore_rest_of_line ();
                    return;
                  }
                type = obj_elf_section_type (beg, strlen (beg));
              }
             else if (c == '@' || c == '%')
              {
                beg = ++input_line_pointer;
                c = get_symbol_end ();
                *input_line_pointer = c;
                type = obj_elf_section_type (beg, input_line_pointer - beg);
              }
             else
              input_line_pointer = save;
           }

         SKIP_WHITESPACE ();
         if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',')
           {
             ++input_line_pointer;
             SKIP_WHITESPACE ();
             entsize = get_absolute_expression ();
             SKIP_WHITESPACE ();
             if (entsize < 0)
              {
                as_warn (_("invalid merge entity size"));
                attr &= ~SHF_MERGE;
                entsize = 0;
              }
           }
         else if ((attr & SHF_MERGE) != 0)
           {
             as_warn (_("entity size for SHF_MERGE not specified"));
             attr &= ~SHF_MERGE;
           }

         if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
           {
             ++input_line_pointer;
             group_name = obj_elf_section_name ();
             if (group_name == NULL)
              attr &= ~SHF_GROUP;
             else if (strncmp (input_line_pointer, ",comdat", 7) == 0)
              {
                input_line_pointer += 7;
                linkonce = 1;
              }
             else if (strncmp (name, ".gnu.linkonce", 13) == 0)
              linkonce = 1;
           }
         else if ((attr & SHF_GROUP) != 0)
           {
             as_warn (_("group name for SHF_GROUP not specified"));
             attr &= ~SHF_GROUP;
           }
       }
      else
       {
         do
           {
             char c;

             SKIP_WHITESPACE ();
             if (*input_line_pointer != '#')
              {
                as_bad (_("character following name is not '#'"));
                ignore_rest_of_line ();
                return;
              }
             beg = ++input_line_pointer;
             c = get_symbol_end ();
             *input_line_pointer = c;

             attr |= obj_elf_section_word (beg, input_line_pointer - beg);

             SKIP_WHITESPACE ();
           }
         while (*input_line_pointer++ == ',');
         --input_line_pointer;
       }
    }

  demand_empty_rest_of_line ();

  obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void obj_elf_section_change_hook ( void  )

Definition at line 1113 of file obj-elf.c.

Here is the caller graph for this function:

void obj_elf_text ( int  )

Definition at line 1055 of file obj-elf.c.

{
#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  previous_section = now_seg;
  previous_subsection = now_subseg;
  s_text (i);

#ifdef md_elf_section_change_hook
  md_elf_section_change_hook ();
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void obj_elf_version ( int  )

Variable Documentation

Definition at line 186 of file obj-elf.c.