dwarf_begin_elf.c revision b08d5a8fb42f4586d756068065186b5af7e48da
1/* Create descriptor from ELF descriptor for processing file.
2   Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
3   Written by Ulrich Drepper <drepper@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.  */
30static 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  [IDX_debug_ranges] = ".debug_ranges"
47};
48#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
49
50
51static void
52check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
53{
54  GElf_Shdr shdr_mem;
55  GElf_Shdr *shdr;
56
57  /* Get the section header data.  */
58  shdr = gelf_getshdr (scn, &shdr_mem);
59  if (shdr == NULL)
60    /* This should never happen.  If it does something is
61       wrong in the libelf library.  */
62    abort ();
63
64
65  /* Make sure the section is part of a section group only iff we
66     really need it.  If we are looking for the global (= non-section
67     group debug info) we have to ignore all the info in section
68     groups.  If we are looking into a section group we cannot look at
69     a section which isn't part of the section group.  */
70  if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
71    /* Ignore the section.  */
72    return;
73
74
75  /* We recognize the DWARF section by their names.  This is not very
76     safe and stable but the best we can do.  */
77  const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx,
78				    shdr->sh_name);
79  if (scnname == NULL)
80    {
81      /* The section name must be valid.  Otherwise is the ELF file
82	 invalid.  */
83      __libdw_seterrno (DWARF_E_INVALID_ELF);
84      free (result);
85      return;
86    }
87
88
89  /* Recognize the various sections.  Most names start with .debug_.  */
90  size_t cnt;
91  for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
92    if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
93      {
94	/* Found it.  Remember where the data is.  */
95	if (unlikely (result->sectiondata[cnt] != NULL))
96	  /* A section appears twice.  That's bad.  We ignore the section.  */
97	  break;
98
99	/* Get the section data.  */
100	Elf_Data *data = elf_getdata (scn, NULL);
101	if (data != NULL && data->d_size != 0)
102	  /* Yep, there is actually data available.  */
103	  result->sectiondata[cnt] = data;
104
105	break;
106      }
107}
108
109
110/* Check whether all the necessary DWARF information is available.  */
111static Dwarf *
112valid_p (Dwarf *result)
113{
114  /* We looked at all the sections.  Now determine whether all the
115     sections with debugging information we need are there.
116
117     XXX Which sections are absolutely necessary?  Add tests if
118     necessary.  For now we require only .debug_info.  Hopefully this
119     is correct.  */
120  if (unlikely (result->sectiondata[IDX_debug_info] == NULL))
121    {
122      __libdw_seterrno (DWARF_E_NO_DWARF);
123      result = NULL;
124    }
125
126  return result;
127}
128
129
130static Dwarf *
131global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr)
132{
133  Elf_Scn *scn = NULL;
134
135  while ((scn = elf_nextscn (elf, scn)) != NULL)
136    check_section (result, ehdr, scn, false);
137
138  return valid_p (result);
139}
140
141
142static Dwarf *
143scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, 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
178Dwarf *
179dwarf_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);
238      else
239	return scngrp_read (result, elf, ehdr, 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}
252INTDEF(dwarf_begin_elf)
253