blob: 427ffc394baafdbf07c532e0bded6c3e29740173 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* 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)