Home | History | Annotate | Download | only in libdw
      1 /* Create descriptor from ELF descriptor for processing file.
      2    Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
      3    Written by Ulrich Drepper <drepper (at) redhat.com>, 2002.
      4 
      5    This program is Open Source software; you can redistribute it and/or
      6    modify it under the terms of the Open Software License version 1.0 as
      7    published by the Open Source Initiative.
      8 
      9    You should have received a copy of the Open Software License along
     10    with this program; if not, you may obtain a copy of the Open Software
     11    License version 1.0 from http://www.opensource.org/licenses/osl.php or
     12    by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
     13    3001 King Ranch Road, Ukiah, CA 95482.   */
     14 
     15 #ifdef HAVE_CONFIG_H
     16 # include <config.h>
     17 #endif
     18 
     19 #include <stdbool.h>
     20 #include <stddef.h>
     21 #include <stdlib.h>
     22 #include <string.h>
     23 #include <unistd.h>
     24 #include <sys/stat.h>
     25 
     26 #include "libdwP.h"
     27 
     28 
     29 /* Section names.  */
     30 static const char dwarf_scnnames[IDX_last][17] =
     31 {
     32   [IDX_debug_info] = ".debug_info",
     33   [IDX_debug_abbrev] = ".debug_abbrev",
     34   [IDX_debug_aranges] = ".debug_aranges",
     35   [IDX_debug_line] = ".debug_line",
     36   [IDX_debug_frame] = ".debug_frame",
     37   [IDX_eh_frame] = ".eh_frame",
     38   [IDX_debug_loc] = ".debug_loc",
     39   [IDX_debug_pubnames] = ".debug_pubnames",
     40   [IDX_debug_str] = ".debug_str",
     41   [IDX_debug_funcnames] = ".debug_funcnames",
     42   [IDX_debug_typenames] = ".debug_typenames",
     43   [IDX_debug_varnames] = ".debug_varnames",
     44   [IDX_debug_weaknames] = ".debug_weaknames",
     45   [IDX_debug_macinfo] = ".debug_macinfo"
     46 };
     47 #define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
     48 
     49 
     50 static void
     51 check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
     52 {
     53   GElf_Shdr shdr_mem;
     54   GElf_Shdr *shdr;
     55 
     56   /* Get the section header data.  */
     57   shdr = gelf_getshdr (scn, &shdr_mem);
     58   if (shdr == NULL)
     59     /* This should never happen.  If it does something is
     60        wrong in the libelf library.  */
     61     abort ();
     62 
     63 
     64   /* Make sure the section is part of a section group only iff we
     65      really need it.  If we are looking for the global (= non-section
     66      group debug info) we have to ignore all the info in section
     67      groups.  If we are looking into a section group we cannot look at
     68      a section which isn't part of the section group.  */
     69   if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
     70     /* Ignore the section.  */
     71     return;
     72 
     73 
     74   /* We recognize the DWARF section by their names.  This is not very
     75      safe and stable but the best we can do.  */
     76   const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx,
     77 				    shdr->sh_name);
     78   if (scnname == NULL)
     79     {
     80       /* The section name must be valid.  Otherwise is the ELF file
     81 	 invalid.  */
     82       __libdw_seterrno (DWARF_E_INVALID_ELF);
     83       free (result);
     84       return;
     85     }
     86 
     87 
     88   /* Recognize the various sections.  Most names start with .debug_.  */
     89   size_t cnt;
     90   for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
     91     if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
     92       {
     93 	/* Found it.  Remember where the data is.  */
     94 	if (unlikely (result->sectiondata[cnt] != NULL))
     95 	  /* A section appears twice.  That's bad.  We ignore the section.  */
     96 	  break;
     97 
     98 	/* Get the section data.  */
     99 	Elf_Data *data = elf_getdata (scn, NULL);
    100 	if (data != NULL && data->d_size != 0)
    101 	  /* Yep, there is actually data available.  */
    102 	  result->sectiondata[cnt] = data;
    103 
    104 	break;
    105       }
    106 }
    107 
    108 
    109 /* Check whether all the necessary DWARF information is available.  */
    110 static Dwarf *
    111 valid_p (Dwarf *result)
    112 {
    113   /* We looked at all the sections.  Now determine whether all the
    114      sections with debugging information we need are there.
    115 
    116      XXX Which sections are absolutely necessary?  Add tests if
    117      necessary.  For now we require only .debug_info.  Hopefully this
    118      is correct.  */
    119   if (unlikely (result->sectiondata[IDX_debug_info] == NULL))
    120     {
    121       __libdw_seterrno (DWARF_E_NO_DWARF);
    122       result = NULL;
    123     }
    124 
    125   return result;
    126 }
    127 
    128 
    129 static Dwarf *
    130 global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Dwarf_Cmd cmd)
    131 {
    132   Elf_Scn *scn = NULL;
    133 
    134   while ((scn = elf_nextscn (elf, scn)) != NULL)
    135     check_section (result, ehdr, scn, false);
    136 
    137   return valid_p (result);
    138 }
    139 
    140 
    141 static Dwarf *
    142 scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Dwarf_Cmd cmd,
    143 	     Elf_Scn *scngrp)
    144 {
    145   /* SCNGRP is the section descriptor for a section group which might
    146      contain debug sections.  */
    147   Elf_Data *data = elf_getdata (scngrp, NULL);
    148   if (data == NULL)
    149     {
    150       /* We cannot read the section content.  Fail!  */
    151       free (result);
    152       return NULL;
    153     }
    154 
    155   /* The content of the section is a number of 32-bit words which
    156      represent section indices.  The first word is a flag word.  */
    157   Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
    158   size_t cnt;
    159   for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
    160     {
    161       Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
    162       if (scn == NULL)
    163 	{
    164 	  /* A section group refers to a non-existing section.  Should
    165 	     never happen.  */
    166 	  __libdw_seterrno (DWARF_E_INVALID_ELF);
    167 	  free (result);
    168 	  return NULL;
    169 	}
    170 
    171       check_section (result, ehdr, scn, true);
    172     }
    173 
    174   return valid_p (result);
    175 }
    176 
    177 
    178 Dwarf *
    179 dwarf_begin_elf (elf, cmd, scngrp)
    180      Elf *elf;
    181      Dwarf_Cmd cmd;
    182      Elf_Scn *scngrp;
    183 {
    184   GElf_Ehdr *ehdr;
    185   GElf_Ehdr ehdr_mem;
    186 
    187   /* Get the ELF header of the file.  We need various pieces of
    188      information from it.  */
    189   ehdr = gelf_getehdr (elf, &ehdr_mem);
    190   if (ehdr == NULL)
    191     {
    192       if (elf_kind (elf) != ELF_K_ELF)
    193 	__libdw_seterrno (DWARF_E_NOELF);
    194       else
    195 	__libdw_seterrno (DWARF_E_GETEHDR_ERROR);
    196 
    197       return NULL;
    198     }
    199 
    200 
    201   /* Default memory allocation size.  */
    202   size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
    203 
    204   /* Allocate the data structure.  */
    205   Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf) + mem_default_size);
    206   if (result == NULL)
    207     {
    208       __libdw_seterrno (DWARF_E_NOMEM);
    209       return NULL;
    210     }
    211 
    212   /* Fill in some values.  */
    213   if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
    214       || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
    215     result->other_byte_order = true;
    216 
    217   result->elf = elf;
    218 
    219   /* Initialize the memory handling.  */
    220   result->mem_default_size = mem_default_size;
    221   result->oom_handler = __libdw_oom;
    222   result->mem_tail = (struct libdw_memblock *) (result + 1);
    223   result->mem_tail->size = (result->mem_default_size
    224 			    - offsetof (struct libdw_memblock, mem));
    225   result->mem_tail->remaining = result->mem_tail->size;
    226   result->mem_tail->prev = NULL;
    227 
    228 
    229   if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
    230     {
    231       /* If the caller provides a section group we get the DWARF
    232 	 sections only from this setion group.  Otherwise we search
    233 	 for the first section with the required name.  Further
    234 	 sections with the name are ignored.  The DWARF specification
    235 	 does not really say this is allowed.  */
    236       if (scngrp == NULL)
    237 	return global_read (result, elf, ehdr, cmd);
    238       else
    239 	return scngrp_read (result, elf, ehdr, cmd, scngrp);
    240     }
    241   else if (cmd == DWARF_C_WRITE)
    242     {
    243       __libdw_seterrno (DWARF_E_UNIMPL);
    244       free (result);
    245       return NULL;
    246     }
    247 
    248   __libdw_seterrno (DWARF_E_INVALID_CMD);
    249   free (result);
    250   return NULL;
    251 }
    252