LCOV - code coverage report
Current view: top level - libdw - dwarf_begin_elf.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 68 122 55.7 %
Date: 2017-01-05 09:15:16 Functions: 4 5 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Create descriptor from ELF descriptor for processing file.
       2             :    Copyright (C) 2002-2011, 2014, 2015 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 <stdbool.h>
      36             : #include <stddef.h>
      37             : #include <stdlib.h>
      38             : #include <stdio.h>
      39             : #include <string.h>
      40             : #include <unistd.h>
      41             : #include <sys/types.h>
      42             : #include <sys/stat.h>
      43             : #include <fcntl.h>
      44             : 
      45             : #include "libdwP.h"
      46             : 
      47             : 
      48             : /* Section names.  */
      49             : static const char dwarf_scnnames[IDX_last][18] =
      50             : {
      51             :   [IDX_debug_info] = ".debug_info",
      52             :   [IDX_debug_types] = ".debug_types",
      53             :   [IDX_debug_abbrev] = ".debug_abbrev",
      54             :   [IDX_debug_aranges] = ".debug_aranges",
      55             :   [IDX_debug_line] = ".debug_line",
      56             :   [IDX_debug_frame] = ".debug_frame",
      57             :   [IDX_debug_loc] = ".debug_loc",
      58             :   [IDX_debug_pubnames] = ".debug_pubnames",
      59             :   [IDX_debug_str] = ".debug_str",
      60             :   [IDX_debug_macinfo] = ".debug_macinfo",
      61             :   [IDX_debug_macro] = ".debug_macro",
      62             :   [IDX_debug_ranges] = ".debug_ranges",
      63             :   [IDX_gnu_debugaltlink] = ".gnu_debugaltlink"
      64             : };
      65             : #define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
      66             : 
      67             : static Dwarf *
      68      206859 : check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
      69             : {
      70             :   GElf_Shdr shdr_mem;
      71             :   GElf_Shdr *shdr;
      72             : 
      73             :   /* Get the section header data.  */
      74      206859 :   shdr = gelf_getshdr (scn, &shdr_mem);
      75      206859 :   if (shdr == NULL)
      76             :     /* We may read /proc/PID/mem with only program headers mapped and section
      77             :        headers out of the mapped pages.  */
      78             :     goto err;
      79             : 
      80             :   /* Ignore any SHT_NOBITS sections.  Debugging sections should not
      81             :      have been stripped, but in case of a corrupt file we won't try
      82             :      to look at the missing data.  */
      83      206859 :   if (unlikely (shdr->sh_type == SHT_NOBITS))
      84             :     return result;
      85             : 
      86             :   /* Make sure the section is part of a section group only iff we
      87             :      really need it.  If we are looking for the global (= non-section
      88             :      group debug info) we have to ignore all the info in section
      89             :      groups.  If we are looking into a section group we cannot look at
      90             :      a section which isn't part of the section group.  */
      91      195250 :   if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
      92             :     /* Ignore the section.  */
      93             :     return result;
      94             : 
      95             : 
      96             :   /* We recognize the DWARF section by their names.  This is not very
      97             :      safe and stable but the best we can do.  */
      98      195250 :   const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx,
      99      195250 :                                     shdr->sh_name);
     100      195250 :   if (scnname == NULL)
     101             :     {
     102             :       /* The section name must be valid.  Otherwise is the ELF file
     103             :          invalid.  */
     104             :     err:
     105           1 :       Dwarf_Sig8_Hash_free (&result->sig8_hash);
     106           1 :       __libdw_seterrno (DWARF_E_INVALID_ELF);
     107           1 :       free (result);
     108           1 :       return NULL;
     109             :     }
     110             : 
     111             :   /* Recognize the various sections.  Most names start with .debug_.  */
     112             :   size_t cnt;
     113             :   bool gnu_compressed = false;
     114     2237259 :   for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
     115     2274117 :     if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
     116             :       break;
     117     2237321 :     else if (scnname[0] == '.' && scnname[1] == 'z'
     118         378 :              && strcmp (&scnname[2], &dwarf_scnnames[cnt][1]) == 0)
     119             :       {
     120             :         gnu_compressed = true;
     121             :         break;
     122             :       }
     123             : 
     124      195249 :   if (cnt >= ndwarf_scnnames)
     125             :     /* Not a debug section; ignore it. */
     126             :     return result;
     127             : 
     128       36858 :   if (unlikely (result->sectiondata[cnt] != NULL))
     129             :     /* A section appears twice.  That's bad.  We ignore the section.  */
     130             :     return result;
     131             : 
     132             :   /* We cannot know whether or not a GNU compressed section has already
     133             :      been uncompressed or not, so ignore any errors.  */
     134       36858 :   if (gnu_compressed)
     135          62 :     elf_compress_gnu (scn, 0, 0);
     136             : 
     137       36858 :   if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
     138             :     {
     139           8 :       if (elf_compress (scn, 0, 0) < 0)
     140             :         {
     141             :           /* If we failed to decompress the section and it's the
     142             :              debug_info section, then fail with specific error rather
     143             :              than the generic NO_DWARF. Without debug_info we can't do
     144             :              anything (see also valid_p()). */
     145           0 :           if (cnt == IDX_debug_info)
     146             :             {
     147           0 :               Dwarf_Sig8_Hash_free (&result->sig8_hash);
     148           0 :               __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
     149           0 :               free (result);
     150           0 :               return NULL;
     151             :             }
     152             :           return result;
     153             :         }
     154             :     }
     155             : 
     156             :   /* Get the section data.  */
     157       36858 :   Elf_Data *data = elf_getdata (scn, NULL);
     158       36858 :   if (data == NULL)
     159             :     goto err;
     160             : 
     161       36858 :   if (data->d_buf == NULL || data->d_size == 0)
     162             :     /* No data actually available, ignore it. */
     163             :     return result;
     164             : 
     165             :   /* We can now read the section data into results. */
     166       36855 :   result->sectiondata[cnt] = data;
     167             : 
     168       36855 :   return result;
     169             : }
     170             : 
     171             : 
     172             : /* Check whether all the necessary DWARF information is available.  */
     173             : static Dwarf *
     174        5383 : valid_p (Dwarf *result)
     175             : {
     176             :   /* We looked at all the sections.  Now determine whether all the
     177             :      sections with debugging information we need are there.
     178             : 
     179             :      XXX Which sections are absolutely necessary?  Add tests if
     180             :      necessary.  For now we require only .debug_info.  Hopefully this
     181             :      is correct.  */
     182        5383 :   if (likely (result != NULL)
     183        5382 :       && unlikely (result->sectiondata[IDX_debug_info] == NULL))
     184             :     {
     185          93 :       Dwarf_Sig8_Hash_free (&result->sig8_hash);
     186          93 :       __libdw_seterrno (DWARF_E_NO_DWARF);
     187          93 :       free (result);
     188          93 :       result = NULL;
     189             :     }
     190             : 
     191        5383 :   if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL)
     192             :     {
     193        5133 :       result->fake_loc_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
     194        5133 :       if (unlikely (result->fake_loc_cu == NULL))
     195             :         {
     196           0 :           Dwarf_Sig8_Hash_free (&result->sig8_hash);
     197           0 :           __libdw_seterrno (DWARF_E_NOMEM);
     198           0 :           free (result);
     199           0 :           result = NULL;
     200             :         }
     201             :       else
     202             :         {
     203        5133 :           result->fake_loc_cu->dbg = result;
     204             :           result->fake_loc_cu->startp
     205        5133 :             = result->sectiondata[IDX_debug_loc]->d_buf;
     206             :           result->fake_loc_cu->endp
     207        5133 :             = (result->sectiondata[IDX_debug_loc]->d_buf
     208        5133 :                + result->sectiondata[IDX_debug_loc]->d_size);
     209             :         }
     210             :     }
     211             : 
     212        5383 :   return result;
     213             : }
     214             : 
     215             : 
     216             : static Dwarf *
     217        5383 : global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr)
     218             : {
     219        5383 :   Elf_Scn *scn = NULL;
     220             : 
     221      217625 :   while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
     222      206859 :     result = check_section (result, ehdr, scn, false);
     223             : 
     224        5383 :   return valid_p (result);
     225             : }
     226             : 
     227             : 
     228             : static Dwarf *
     229           0 : scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
     230             : {
     231             :   GElf_Shdr shdr_mem;
     232           0 :   GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
     233           0 :   if (shdr == NULL)
     234             :     {
     235           0 :       Dwarf_Sig8_Hash_free (&result->sig8_hash);
     236           0 :       __libdw_seterrno (DWARF_E_INVALID_ELF);
     237           0 :       free (result);
     238           0 :       return NULL;
     239             :     }
     240             : 
     241           0 :   if ((shdr->sh_flags & SHF_COMPRESSED) != 0
     242           0 :       && elf_compress (scngrp, 0, 0) < 0)
     243             :     {
     244           0 :       Dwarf_Sig8_Hash_free (&result->sig8_hash);
     245           0 :       __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
     246           0 :       free (result);
     247           0 :       return NULL;
     248             :     }
     249             : 
     250             :   /* SCNGRP is the section descriptor for a section group which might
     251             :      contain debug sections.  */
     252           0 :   Elf_Data *data = elf_getdata (scngrp, NULL);
     253           0 :   if (data == NULL)
     254             :     {
     255             :       /* We cannot read the section content.  Fail!  */
     256           0 :       Dwarf_Sig8_Hash_free (&result->sig8_hash);
     257           0 :       free (result);
     258           0 :       return NULL;
     259             :     }
     260             : 
     261             :   /* The content of the section is a number of 32-bit words which
     262             :      represent section indices.  The first word is a flag word.  */
     263           0 :   Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
     264             :   size_t cnt;
     265           0 :   for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
     266             :     {
     267           0 :       Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
     268           0 :       if (scn == NULL)
     269             :         {
     270             :           /* A section group refers to a non-existing section.  Should
     271             :              never happen.  */
     272           0 :           Dwarf_Sig8_Hash_free (&result->sig8_hash);
     273           0 :           __libdw_seterrno (DWARF_E_INVALID_ELF);
     274           0 :           free (result);
     275           0 :           return NULL;
     276             :         }
     277             : 
     278           0 :       result = check_section (result, ehdr, scn, true);
     279           0 :       if (result == NULL)
     280             :         break;
     281             :     }
     282             : 
     283           0 :   return valid_p (result);
     284             : }
     285             : 
     286             : 
     287             : Dwarf *
     288        5383 : dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
     289             : {
     290             :   GElf_Ehdr *ehdr;
     291             :   GElf_Ehdr ehdr_mem;
     292             : 
     293             :   /* Get the ELF header of the file.  We need various pieces of
     294             :      information from it.  */
     295        5383 :   ehdr = gelf_getehdr (elf, &ehdr_mem);
     296        5383 :   if (ehdr == NULL)
     297             :     {
     298           0 :       if (elf_kind (elf) != ELF_K_ELF)
     299           0 :         __libdw_seterrno (DWARF_E_NOELF);
     300             :       else
     301           0 :         __libdw_seterrno (DWARF_E_GETEHDR_ERROR);
     302             : 
     303             :       return NULL;
     304             :     }
     305             : 
     306             : 
     307             :   /* Default memory allocation size.  */
     308        5383 :   size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
     309        5383 :   assert (sizeof (struct Dwarf) < mem_default_size);
     310             : 
     311             :   /* Allocate the data structure.  */
     312        5383 :   Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf) + mem_default_size);
     313        5383 :   if (unlikely (result == NULL)
     314        5383 :       || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
     315             :     {
     316           0 :       free (result);
     317           0 :       __libdw_seterrno (DWARF_E_NOMEM);
     318           0 :       return NULL;
     319             :     }
     320             : 
     321             :   /* Fill in some values.  */
     322        5383 :   if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
     323             :       || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
     324          49 :     result->other_byte_order = true;
     325             : 
     326        5383 :   result->elf = elf;
     327             : 
     328             :   /* Initialize the memory handling.  */
     329        5383 :   result->mem_default_size = mem_default_size;
     330        5383 :   result->oom_handler = __libdw_oom;
     331        5383 :   result->mem_tail = (struct libdw_memblock *) (result + 1);
     332        5383 :   result->mem_tail->size = (result->mem_default_size
     333        5383 :                             - offsetof (struct libdw_memblock, mem));
     334        5383 :   result->mem_tail->remaining = result->mem_tail->size;
     335        5383 :   result->mem_tail->prev = NULL;
     336             : 
     337        5383 :   if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
     338             :     {
     339             :       /* If the caller provides a section group we get the DWARF
     340             :          sections only from this setion group.  Otherwise we search
     341             :          for the first section with the required name.  Further
     342             :          sections with the name are ignored.  The DWARF specification
     343             :          does not really say this is allowed.  */
     344        5383 :       if (scngrp == NULL)
     345        5383 :         return global_read (result, elf, ehdr);
     346             :       else
     347           0 :         return scngrp_read (result, elf, ehdr, scngrp);
     348             :     }
     349           0 :   else if (cmd == DWARF_C_WRITE)
     350             :     {
     351           0 :       Dwarf_Sig8_Hash_free (&result->sig8_hash);
     352           0 :       __libdw_seterrno (DWARF_E_UNIMPL);
     353           0 :       free (result);
     354           0 :       return NULL;
     355             :     }
     356             : 
     357           0 :   Dwarf_Sig8_Hash_free (&result->sig8_hash);
     358           0 :   __libdw_seterrno (DWARF_E_INVALID_CMD);
     359           0 :   free (result);
     360           0 :   return NULL;
     361             : }
     362             : INTDEF(dwarf_begin_elf)

Generated by: LCOV version 1.12