1 /* Create descriptor from ELF descriptor for processing file.
2 Copyright (C) 2002, 2003, 2004 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. */
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
check_section(Dwarf * result,GElf_Ehdr * ehdr,Elf_Scn * scn,bool inscngrp)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 *
valid_p(Dwarf * result)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 *
global_read(Dwarf * result,Elf * elf,GElf_Ehdr * ehdr,Dwarf_Cmd cmd)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 *
scngrp_read(Dwarf * result,Elf * elf,GElf_Ehdr * ehdr,Dwarf_Cmd cmd,Elf_Scn * scngrp)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 *
dwarf_begin_elf(elf,cmd,scngrp)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