LCOV - code coverage report
Current view: top level - libasm - asm_newscn.c (source / functions) Hit Total Coverage
Test: elfutils-0.174 Lines: 32 61 52.5 %
Date: 2018-09-14 13:30:33 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 <libintl.h>
      36             : #include <stdlib.h>
      37             : #include <string.h>
      38             : 
      39             : #include <libasmP.h>
      40             : #include <libelf.h>
      41             : #include <system.h>
      42             : 
      43             : 
      44             : /* Memory for the default pattern.  The type uses a flexible array
      45             :    which does work well with a static initializer.  So we play some
      46             :    dirty tricks here.  */
      47             : static const struct
      48             : {
      49             :   struct FillPattern pattern;
      50             :   char zero;
      51             : } xdefault_pattern =
      52             :   {
      53             :     .pattern =
      54             :     {
      55             :       .len = 1
      56             :     },
      57             :     .zero = '\0'
      58             :   };
      59             : const struct FillPattern *__libasm_default_pattern = &xdefault_pattern.pattern;
      60             : 
      61             : 
      62             : static AsmScn_t *
      63           0 : text_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags)
      64             : {
      65             :   /* Buffer where we construct the flag string.  */
      66             :   char flagstr[sizeof (GElf_Xword) * 8 + 5];
      67           0 :   char *wp = flagstr;
      68           0 :   const char *typestr = "";
      69             : 
      70             :   /* Only write out the flag string if this is the first time the
      71             :      section is selected.  Some assemblers cannot cope with the
      72             :      .section pseudo-op otherwise.  */
      73           0 :   wp = stpcpy (wp, ", \"");
      74             : 
      75           0 :   if (flags & SHF_WRITE)
      76           0 :     *wp++ = 'w';
      77           0 :   if (flags & SHF_ALLOC)
      78           0 :     *wp++ = 'a';
      79           0 :   if (flags & SHF_EXECINSTR)
      80           0 :     *wp++ = 'x';
      81           0 :   if (flags & SHF_MERGE)
      82           0 :     *wp++ = 'M';
      83           0 :   if (flags & SHF_STRINGS)
      84           0 :     *wp++ = 'S';
      85           0 :   if (flags & SHF_LINK_ORDER)
      86           0 :     *wp++ = 'L';
      87             : 
      88           0 :   *wp++ = '"';
      89             : 
      90           0 :   if (type == SHT_PROGBITS)
      91             :     typestr = ",@progbits";
      92           0 :   else if (type == SHT_NOBITS)
      93           0 :     typestr = ",@nobits";
      94             : 
      95             :   /* Terminate the string.  */
      96           0 :   *wp = '\0';
      97             : 
      98           0 :   fprintf (result->ctx->out.file, "\t.section \"%s\"%s%s\n",
      99           0 :            result->name, flagstr, typestr);
     100             : 
     101           0 :   return result;
     102             : }
     103             : 
     104             : 
     105             : static AsmScn_t *
     106      176005 : binary_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags,
     107             :                size_t scnname_len)
     108             : {
     109             :   GElf_Shdr shdr_mem;
     110             :   GElf_Shdr *shdr;
     111             :   Elf_Scn *scn;
     112             : 
     113             :   /* The initial subsection has the number zero.  */
     114      176005 :   result->subsection_id = 0;
     115             : 
     116             :   /* We start at offset zero.  */
     117      176005 :   result->offset = 0;
     118             :   /* And generic alignment.  */
     119      176005 :   result->max_align = 1;
     120             : 
     121             :   /* No output yet.  */
     122      176005 :   result->content = NULL;
     123             : 
     124             :   /* Put the default fill pattern in place.  */
     125      176005 :   result->pattern = (struct FillPattern *) __libasm_default_pattern;
     126             : 
     127             :   /* There are no subsections so far.  */
     128      176005 :   result->subnext = NULL;
     129             : 
     130             :   /* Add the name to the section header string table.  */
     131      176005 :   result->data.main.strent = dwelf_strtab_add_len (result->ctx->section_strtab,
     132      176005 :                                                    result->name, scnname_len);
     133      176005 :   assert (result->data.main.strent != NULL);
     134             : 
     135             :   /* Create the new ELF section.  */
     136      176005 :   result->data.main.scn = scn = elf_newscn (result->ctx->out.elf);
     137      176005 :   if (scn == NULL)
     138             :     {
     139           0 :       free (result);
     140           0 :       __libasm_seterrno (ASM_E_LIBELF);
     141           0 :       return NULL;
     142             :     }
     143             : 
     144             :   /* Not part of a section group (yet).  */
     145      176005 :   result->data.main.next_in_group = NULL;
     146             : 
     147             :   /* Remember the flags.  */
     148      176005 :   shdr = gelf_getshdr (scn, &shdr_mem);
     149             : 
     150      176005 :   shdr->sh_flags = flags;
     151      176005 :   result->type = shdr->sh_type = type;
     152             : 
     153      176005 :   (void) gelf_update_shdr (scn, shdr);
     154             : 
     155      176005 :   return result;
     156             : }
     157             : 
     158             : 
     159             : AsmScn_t *
     160      176005 : asm_newscn (AsmCtx_t *ctx, const char *scnname, GElf_Word type,
     161             :             GElf_Xword flags)
     162             : {
     163      176005 :   size_t scnname_len = strlen (scnname) + 1;
     164             :   AsmScn_t *result;
     165             : 
     166             :   /* If no context is given there might be an earlier error.  */
     167      176005 :   if (ctx == NULL)
     168             :     return NULL;
     169             : 
     170             :   /* Check whether only flags are set which areselectable by the user.  */
     171      176005 :   if (unlikely ((flags & ~(SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE
     172             :                            | SHF_STRINGS | SHF_LINK_ORDER)) != 0)
     173             :       /* We allow only two section types: data and data without file
     174             :          representation.  */
     175      176005 :       || (type != SHT_PROGBITS && unlikely (type != SHT_NOBITS)))
     176             :     {
     177           0 :       __libasm_seterrno (ASM_E_INVALID);
     178           0 :       return NULL;
     179             :     }
     180             : 
     181             :   rwlock_wrlock (ctx->lock);
     182             : 
     183             :   /* This is a new section.  */
     184      176005 :   result = (AsmScn_t *) malloc (sizeof (AsmScn_t) + scnname_len);
     185      176005 :   if (result != NULL)
     186             :     {
     187             :       /* Add the name.  */
     188      352010 :       memcpy (result->name, scnname, scnname_len);
     189             : 
     190             :       /* Add the reference to the context.  */
     191      176005 :       result->ctx = ctx;
     192             : 
     193             :       /* Perform operations according to output mode.  */
     194      352010 :       result = (unlikely (ctx->textp)
     195             :                 ? text_newscn (result, type, flags)
     196      176005 :                 : binary_newscn (result, type, flags, scnname_len));
     197             : 
     198             :       /* If everything went well finally add the new section to the hash
     199             :          table.  */
     200      176005 :       if (result != NULL)
     201             :         {
     202      176005 :           result->allnext = ctx->section_list;
     203      176005 :           ctx->section_list = result;
     204             :         }
     205             :     }
     206             : 
     207             :   rwlock_unlock (ctx->lock);
     208             : 
     209             :   return result;
     210             : }
     211             : INTDEF(asm_newscn)

Generated by: LCOV version 1.13