blob: d69d7474040daef9d1c9adefef9cea56c449baf0 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Create descriptor from ELF handle for processing file.
2 Copyright (C) 2000, 2002 Red Hat, Inc.
3 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
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 <assert.h>
20#include <endian.h>
21#include <gelf.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include <libdwarfP.h>
26
27
28/* Section names. */
29static const char dwarf_scnnames[IDX_last][17] =
30{
31 [IDX_debug_info] = ".debug_info",
32 [IDX_debug_abbrev] = ".debug_abbrev",
33 [IDX_debug_aranges] = ".debug_aranges",
34 [IDX_debug_line] = ".debug_line",
35 [IDX_debug_frame] = ".debug_frame",
36 [IDX_eh_frame] = ".eh_frame",
37 [IDX_debug_loc] = ".debug_loc",
38 [IDX_debug_pubnames] = ".debug_pubnames",
39 [IDX_debug_str] = ".debug_str",
40 [IDX_debug_funcnames] = ".debug_funcnames",
41 [IDX_debug_typenames] = ".debug_typenames",
42 [IDX_debug_varnames] = ".debug_varnames",
43 [IDX_debug_weaknames] = ".debug_weaknames",
44 [IDX_debug_macinfo] = ".debug_macinfo"
45};
46#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
47
48
49int
50dwarf_elf_init (elf, access, errhand, errarg, dbg, error)
51 Elf *elf;
52 Dwarf_Unsigned access;
53 Dwarf_Handler errhand;
54 Dwarf_Ptr errarg;
55 Dwarf_Debug *dbg;
56 Dwarf_Error *error;
57{
58 int result = DW_DLV_ERROR;
59 Dwarf_Debug newdbg;
60 GElf_Ehdr ehdr_mem;
61 GElf_Ehdr *ehdr;
62 Elf_Scn *scn;
63
64 /* XXX For now nothing but read-only support is available. */
65 if (access != DW_DLC_READ)
66 abort ();
67
68 /* Get the ELF header of the file. We need various pieces of
69 information from it. */
70 ehdr = gelf_getehdr (elf, &ehdr_mem);
71 if (ehdr == NULL)
72 {
73 struct Dwarf_Debug_s tmpdbg;
74
75 tmpdbg.dbg_errhand = errhand;
76 tmpdbg.dbg_errarg = errarg;
77
78 if (elf_kind (elf) != ELF_K_ELF)
79 __libdwarf_error (&tmpdbg, error, DW_E_NOELF);
80 else
81 __libdwarf_error (&tmpdbg, error, DW_E_GETEHDR_ERROR);
82
83 return result;
84 }
85
86 /* Allocate and fill the result data structure. */
87 newdbg = (Dwarf_Debug) calloc (1, sizeof (struct Dwarf_Debug_s));
88 if (newdbg == NULL)
89 {
90 struct Dwarf_Debug_s tmpdbg;
91
92 tmpdbg.dbg_errhand = errhand;
93 tmpdbg.dbg_errarg = errarg;
94
95 __libdwarf_error (&tmpdbg, error, DW_E_NOMEM);
96 }
97 else
98 {
99 /* We have been able to allocate the memory for the debug handle. */
100 newdbg->dbg_errhand = errhand;
101 newdbg->dbg_errarg = errarg;
102 newdbg->elf = elf;
103 if ((BYTE_ORDER == LITTLE_ENDIAN
104 && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
105 || (BYTE_ORDER == BIG_ENDIAN
106 && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
107 newdbg->other_byte_order = 1;
108 newdbg->access = access;
109#ifdef DWARF_DEBUG
110 newdbg->memtag = DW_DLA_DEBUG;
111#endif
112
113 /* All done. */
114 *dbg = newdbg;
115 result = DW_DLV_OK;
116
117 /* Find out whether the file actually has the necessary DWARF
118 sections. */
119 scn = NULL;
120 while ((scn = elf_nextscn (elf, scn)) != NULL)
121 {
122 GElf_Shdr shdr_mem;
123 GElf_Shdr *shdr;
124 const char *scnname;
125 size_t cnt;
126 Elf_Data *data;
127
128 /* Get the section header data. */
129 shdr = gelf_getshdr (scn, &shdr_mem);
130 if (shdr == NULL)
131 /* This should never happen. If it does something is
132 wrong in the libelf library. */
133 abort ();
134
135 /* We recognize the DWARF section by their names. This is
136 not very safe and stable but the best we can do. */
137 scnname = elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name);
138 if (scnname == NULL)
139 {
140 /* The section name must be valid. Otherwise is the ELF file
141 invalid. */
142 __libdwarf_error (newdbg, error, DW_E_INVALID_ELF);
143 break;
144 }
145
146 /* Recognize the various sections. Most names start with
147 .debug_. */
148 for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
149 if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
150 break;
151
152 if (cnt < ndwarf_scnnames)
153 {
154 /* Found it. Remember where the data is. */
155 assert (cnt < IDX_last);
156 if (unlikely (newdbg->sections[cnt].addr != NULL))
157 {
158 /* A section appears twice. That's bad. */
159 __libdwarf_error (newdbg, error, DW_E_INVALID_DWARF);
160 break;
161 }
162
163 /* Get the section data. */
164 data = elf_getdata (scn, NULL);
165 if (data != NULL && data->d_size != 0)
166 {
167 /* Yep, there is actually data available. */
168 newdbg->sections[cnt].addr = data->d_buf;
169 newdbg->sections[cnt].size = data->d_size;
170 }
171 }
172 }
173
174 if (scn == NULL)
175 {
176 /* We looked at all the sections. Now determine whether all
177 the sections with debugging information we need are there.
178
179 XXX Which sections are absolutely necessary? Add tests
180 if necessary. For now we require only .debug_info. Hopefully
181 this is correct. */
182 if (newdbg->sections[IDX_debug_info].addr == NULL)
183 {
184 __libdwarf_error (newdbg, error, DW_E_NO_DWARF);
185 result = DW_DLV_NO_ENTRY;
186 }
187 else
188 result = DW_DLV_OK;
189 }
190
191 if (result != DW_DLV_OK)
192 /* Something went wrong. */
193 free (newdbg);
194 }
195
196 return result;
197}