LCOV - code coverage report
Current view: top level - libasm - asm_newscn.c (source / functions) Hit Total Coverage
Test: elfutils-0.173 Lines: 33 62 53.2 %
Date: 2018-06-29 23:49:12 Functions: 2 3 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Create new section in output file.
       2             :    Copyright (C) 2002-2011, 2016 Red Hat, Inc.
       3             :    This file is part of elfutils.
       4             :    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
       5             : 
       6             :    This file is free software; you can redistribute it and/or modify
       7             :    it under the terms of either
       8             : 
       9             :      * the GNU Lesser General Public License as published by the Free
      10             :        Software Foundation; either version 3 of the License, or (at
      11             :        your option) any later version
      12             : 
      13             :    or
      14             : 
      15             :      * the GNU General Public License as published by the Free
      16             :        Software Foundation; either version 2 of the License, or (at
      17             :        your option) any later version
      18             : 
      19             :    or both in parallel, as here.
      20             : 
      21             :    elfutils is distributed in the hope that it will be useful, but
      22             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      24             :    General Public License for more details.
      25             : 
      26             :    You should have received copies of the GNU General Public License and
      27             :    the GNU Lesser General Public License along with this program.  If
      28             :    not, see <http://www.gnu.org/licenses/>.  */
      29             : 
      30             : #ifdef HAVE_CONFIG_H
      31             : # include <config.h>
      32             : #endif
      33             : 
      34             : #include <assert.h>
      35             : #include <error.h>
      36             : #include <libintl.h>
      37             : #include <stdlib.h>
      38             : #include <string.h>
      39             : 
      40             : #include <libasmP.h>
      41             : #include <libelf.h>
      42             : #include <system.h>
      43             : 
      44             : 
      45             : /* Memory for the default pattern.  The type uses a flexible array
      46             :    which does work well with a static initializer.  So we play some
      47             :    dirty tricks here.  */
      48             : static const struct
      49             : {
      50             :   struct FillPattern pattern;
      51             :   char zero;
      52             : } xdefault_pattern =
      53             :   {
      54             :     .pattern =
      55             :     {
      56             :       .len = 1
      57             :     },
      58             :     .zero = '\0'
      59             :   };
      60             : const struct FillPattern *__libasm_default_pattern = &xdefault_pattern.pattern;
      61             : 
      62             : 
      63             : static AsmScn_t *
      64           0 : text_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags)
      65             : {
      66             :   /* Buffer where we construct the flag string.  */
      67             :   char flagstr[sizeof (GElf_Xword) * 8 + 5];
      68           0 :   char *wp = flagstr;
      69           0 :   const char *typestr = "";
      70             : 
      71             :   /* Only write out the flag string if this is the first time the
      72             :      section is selected.  Some assemblers cannot cope with the
      73             :      .section pseudo-op otherwise.  */
      74           0 :   wp = stpcpy (wp, ", \"");
      75             : 
      76           0 :   if (flags & SHF_WRITE)
      77           0 :     *wp++ = 'w';
      78           0 :   if (flags & SHF_ALLOC)
      79           0 :     *wp++ = 'a';
      80           0 :   if (flags & SHF_EXECINSTR)
      81           0 :     *wp++ = 'x';
      82           0 :   if (flags & SHF_MERGE)
      83           0 :     *wp++ = 'M';
      84           0 :   if (flags & SHF_STRINGS)
      85           0 :     *wp++ = 'S';
      86           0 :   if (flags & SHF_LINK_ORDER)
      87           0 :     *wp++ = 'L';
      88             : 
      89           0 :   *wp++ = '"';
      90             : 
      91           0 :   if (type == SHT_PROGBITS)
      92             :     typestr = ",@progbits";
      93           0 :   else if (type == SHT_NOBITS)
      94           0 :     typestr = ",@nobits";
      95             : 
      96             :   /* Terminate the string.  */
      97           0 :   *wp = '\0';
      98             : 
      99           0 :   fprintf (result->ctx->out.file, "\t.section \"%s\"%s%s\n",
     100           0 :            result->name, flagstr, typestr);
     101             : 
     102           0 :   return result;
     103             : }
     104             : 
     105             : 
     106             : static AsmScn_t *
     107      176005 : binary_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags,
     108             :                size_t scnname_len)
     109             : {
     110             :   GElf_Shdr shdr_mem;
     111             :   GElf_Shdr *shdr;
     112             :   Elf_Scn *scn;
     113             : 
     114             :   /* The initial subsection has the number zero.  */
     115      176005 :   result->subsection_id = 0;
     116             : 
     117             :   /* We start at offset zero.  */
     118      176005 :   result->offset = 0;
     119             :   /* And generic alignment.  */
     120      176005 :   result->max_align = 1;
     121             : 
     122             :   /* No output yet.  */
     123      176005 :   result->content = NULL;
     124             : 
     125             :   /* Put the default fill pattern in place.  */
     126      176005 :   result->pattern = (struct FillPattern *) __libasm_default_pattern;
     127             : 
     128             :   /* There are no subsections so far.  */
     129      176005 :   result->subnext = NULL;
     130             : 
     131             :   /* Add the name to the section header string table.  */
     132      176005 :   result->data.main.strent = dwelf_strtab_add_len (result->ctx->section_strtab,
     133      176005 :                                                    result->name, scnname_len);
     134      176005 :   assert (result->data.main.strent != NULL);
     135             : 
     136             :   /* Create the new ELF section.  */
     137      176005 :   result->data.main.scn = scn = elf_newscn (result->ctx->out.elf);
     138      176005 :   if (scn == NULL)
     139             :     {
     140           0 :       free (result);
     141           0 :       __libasm_seterrno (ASM_E_LIBELF);
     142           0 :       return NULL;
     143             :     }
     144             : 
     145             :   /* Not part of a section group (yet).  */
     146      176005 :   result->data.main.next_in_group = NULL;
     147             : 
     148             :   /* Remember the flags.  */
     149      176005 :   shdr = gelf_getshdr (scn, &shdr_mem);
     150             : 
     151      176005 :   shdr->sh_flags = flags;
     152      176005 :   result->type = shdr->sh_type = type;
     153             : 
     154      176005 :   (void) gelf_update_shdr (scn, shdr);
     155             : 
     156      176005 :   return result;
     157             : }
     158             : 
     159             : 
     160             : AsmScn_t *
     161      176005 : asm_newscn (AsmCtx_t *ctx, const char *scnname, GElf_Word type,
     162             :             GElf_Xword flags)
     163             : {
     164      176005 :   size_t scnname_len = strlen (scnname) + 1;
     165             :   AsmScn_t *result;
     166             : 
     167             :   /* If no context is given there might be an earlier error.  */
     168      176005 :   if (ctx == NULL)
     169             :     return NULL;
     170             : 
     171             :   /* Check whether only flags are set which areselectable by the user.  */
     172      176005 :   if (unlikely ((flags & ~(SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE
     173             :                            | SHF_STRINGS | SHF_LINK_ORDER)) != 0)
     174             :       /* We allow only two section types: data and data without file
     175             :          representation.  */
     176      176005 :       || (type != SHT_PROGBITS && unlikely (type != SHT_NOBITS)))
     177             :     {
     178           0 :       __libasm_seterrno (ASM_E_INVALID);
     179           0 :       return NULL;
     180             :     }
     181             : 
     182             :   rwlock_wrlock (ctx->lock);
     183             : 
     184             :   /* This is a new section.  */
     185      176005 :   result = (AsmScn_t *) malloc (sizeof (AsmScn_t) + scnname_len);
     186      176005 :   if (result != NULL)
     187             :     {
     188             :       /* Add the name.  */
     189      176005 :       memcpy (result->name, scnname, scnname_len);
     190             : 
     191             :       /* Add the reference to the context.  */
     192      176005 :       result->ctx = ctx;
     193             : 
     194             :       /* Perform operations according to output mode.  */
     195      352010 :       result = (unlikely (ctx->textp)
     196             :                 ? text_newscn (result, type, flags)
     197      176005 :                 : binary_newscn (result, type, flags, scnname_len));
     198             : 
     199             :       /* If everything went well finally add the new section to the hash
     200             :          table.  */
     201      176005 :       if (result != NULL)
     202             :         {
     203      176005 :           result->allnext = ctx->section_list;
     204      176005 :           ctx->section_list = result;
     205             :         }
     206             :     }
     207             : 
     208             :   rwlock_unlock (ctx->lock);
     209             : 
     210      176005 :   return result;
     211             : }
     212             : INTDEF(asm_newscn)

Generated by: LCOV version 1.13