blob: ccf6ba5ce0d3c65e3b20374fcaadaf516759c4dc [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Internal definitions for libdwfl.
2 Copyright (C) 2005 Red Hat, Inc.
3
4 This program is Open Source software; you can redistribute it and/or
5 modify it under the terms of the Open Software License version 1.0 as
6 published by the Open Source Initiative.
7
8 You should have received a copy of the Open Software License along
9 with this program; if not, you may obtain a copy of the Open Software
10 License version 1.0 from http://www.opensource.org/licenses/osl.php or
11 by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
12 3001 King Ranch Road, Ukiah, CA 95482. */
13
14#ifndef _LIBDWFLP_H
15#define _LIBDWFLP_H 1
16
17#ifndef PACKAGE
18# include <config.h>
19#endif
20#include <libdwfl.h>
21#include <libebl.h>
22#include <assert.h>
23#include <errno.h>
24#include <stdbool.h>
25#include <stdlib.h>
26#include <string.h>
27
28/* gettext helper macros. */
29#define _(Str) dgettext ("elfutils", Str)
30
31#define DWFL_ERRORS \
32 DWFL_ERROR (NOERROR, N_("no error")) \
33 DWFL_ERROR (UNKNOWN_ERROR, N_("unknown error")) \
34 DWFL_ERROR (NOMEM, N_("out of memory")) \
35 DWFL_ERROR (ERRNO, N_("See errno")) \
36 DWFL_ERROR (LIBELF, N_("See elf_errno")) \
37 DWFL_ERROR (LIBDW, N_("See dwarf_errno")) \
38 DWFL_ERROR (LIBEBL, N_("See ebl_errno (XXX missing)")) \
39 DWFL_ERROR (NOREL, N_("Callbacks missing for ET_REL file")) \
40 DWFL_ERROR (BADRELTYPE, N_("Unsupported relocation type")) \
41 DWFL_ERROR (BADRELOFF, N_("r_offset is bogus")) \
42 DWFL_ERROR (BADSTROFF, N_("offset out of range")) \
43 DWFL_ERROR (RELUNDEF, N_("relocation refers to undefined symbol")) \
44 DWFL_ERROR (CB, N_("Callback returned failure")) \
45 DWFL_ERROR (NO_DWARF, N_("No DWARF information found")) \
46 DWFL_ERROR (NO_SYMTAB, N_("No symbol table found")) \
47 DWFL_ERROR (NO_PHDR, N_("No ELF program headers")) \
48 DWFL_ERROR (OVERLAP, N_("address range overlaps an existing module")) \
49 DWFL_ERROR (ADDR_OUTOFRANGE, N_("address out of range")) \
50 DWFL_ERROR (NO_MATCH, N_("no matching address range")) \
51 DWFL_ERROR (TRUNCATED, N_("image truncated")) \
52 DWFL_ERROR (BADELF, N_("not a valid ELF file"))
53
54#define DWFL_ERROR(name, text) DWFL_E_##name,
55typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error;
56#undef DWFL_ERROR
57
58#define OTHER_ERROR(name) ((unsigned int) DWFL_E_##name << 16)
59#define DWFL_E(name, errno) (OTHER_ERROR (name) | (errno))
60
61extern int __libdwfl_canon_error (Dwfl_Error error) internal_function;
62extern void __libdwfl_seterrno (Dwfl_Error error) internal_function;
63
64struct Dwfl
65{
66 const Dwfl_Callbacks *callbacks;
67
68 Dwfl_Module *modulelist; /* List in order used by full traversals. */
69
70 Dwfl_Module **modules;
71 size_t nmodules;
72};
73
74struct dwfl_file
75{
76 char *name;
77 int fd;
78
79 Elf *elf;
80 GElf_Addr bias; /* Actual load address - p_vaddr. */
81};
82
83struct Dwfl_Module
84{
85 Dwfl *dwfl;
86 struct Dwfl_Module *next; /* Link on Dwfl.moduelist. */
87
88 void *userdata;
89
90 char *name; /* Iterator name for this module. */
91 GElf_Addr low_addr, high_addr;
92
93 struct dwfl_file main, debug;
94 Ebl *ebl;
95 bool isrel; /* True iff this is an ET_REL file. */
96 Dwfl_Error elferr; /* Previous failure to open main file. */
97
98 struct dwfl_file *symfile; /* Either main or debug. */
99 Elf_Data *symdata; /* Data in the ELF symbol table section. */
100 size_t syments; /* sh_size / sh_entsize of that section. */
101 const Elf_Data *symstrdata; /* Data for its string table. */
102 Elf_Data *symxndxdata; /* Data in the extended section index table. */
103 Dwfl_Error symerr; /* Previous failure to load symbols. */
104
105 Dwarf *dw; /* libdw handle for its debugging info. */
106 Dwfl_Error dwerr; /* Previous failure to load info. */
107
108 /* Known CU's in this module. */
109 struct dwfl_cu *first_cu, **cu;
110 unsigned int ncu;
111
112 void *lazy_cu_root; /* Table indexed by Dwarf_Off of CU. */
113 unsigned int lazycu; /* Possible users, deleted when none left. */
114
115 struct dwfl_arange *aranges; /* Mapping of addresses in module to CUs. */
116 unsigned int naranges;
117
118 bool gc; /* Mark/sweep flag. */
119};
120
121
122
123/* Information cached about each CU in Dwfl_Module.dw. */
124struct dwfl_cu
125{
126 /* This caches libdw information about the CU. It's also the
127 address passed back to users, so we take advantage of the
128 fact that it's placed first to cast back. */
129 Dwarf_Die die;
130
131 Dwfl_Module *mod; /* Pointer back to containing module. */
132
133 struct dwfl_cu *next; /* CU immediately following in the file. */
134
135 struct Dwfl_Lines *lines;
136};
137
138struct Dwfl_Lines
139{
140 struct dwfl_cu *cu;
141
142 /* This is what the opaque Dwfl_Line * pointers we pass to users are.
143 We need to recover pointers to our struct dwfl_cu and a record in
144 libdw's Dwarf_Line table. To minimize the memory used in addition
145 to libdw's Dwarf_Lines buffer, we just point to our own index in
146 this table, and have one pointer back to the CU. The indices here
147 match those in libdw's Dwarf_CU.lines->info table. */
148 struct Dwfl_Line
149 {
150 unsigned int idx; /* My index in the dwfl_cu.lines table. */
151 } idx[0];
152};
153
154static inline struct dwfl_cu *
155dwfl_linecu (const Dwfl_Line *line)
156{
157 const struct Dwfl_Lines *lines = ((const void *) line
158 - offsetof (struct Dwfl_Lines,
159 idx[line->idx]));
160 return lines->cu;
161}
162
163/* This describes a contiguous address range that lies in a single CU.
164 We condense runs of Dwarf_Arange entries for the same CU into this. */
165struct dwfl_arange
166{
167 struct dwfl_cu *cu;
168 size_t arange; /* Index in Dwarf_Aranges. */
169};
170
171
172
173
174extern void __libdwfl_module_free (Dwfl_Module *mod) internal_function;
175
176
177/* Process relocations in debugging sections in an ET_REL file.
178 MOD->debug.elf must be opened with ELF_C_READ_MMAP_PRIVATE or ELF_C_READ,
179 to make it possible to relocate the data in place (or ELF_C_RDWR or
180 ELF_C_RDWR_MMAP if you intend to modify the Elf file on disk). After
181 this, dwarf_begin_elf on MOD->debug.elf will read the relocated data. */
182extern Dwfl_Error __libdwfl_relocate (Dwfl_Module *) internal_function;
183
184/* Adjust *VALUE from section-relative to absolute.
185 MOD->dwfl->callbacks->section_address is called to determine the actual
186 address of a loaded section. */
187extern Dwfl_Error __libdwfl_relocate_value (Dwfl_Module *mod,
188 size_t m_shstrndx,
189 Elf32_Word shndx,
190 GElf_Addr *value)
191 internal_function;
192
193/* Iterate through all the CU's in the module. Start by passing a null
194 LASTCU, and then pass the last *CU returned. Success return with null
195 *CU no more CUs. */
196extern Dwfl_Error __libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu,
197 struct dwfl_cu **cu) internal_function;
198
199/* Find the CU by address. */
200extern Dwfl_Error __libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr,
201 struct dwfl_cu **cu) internal_function;
202
203/* Ensure that CU->lines (and CU->cu->lines) is set up. */
204extern Dwfl_Error __libdwfl_cu_getsrclines (struct dwfl_cu *cu)
205 internal_function;
206
207
208
209
210/* Avoid PLT entries. */
211INTDECL (dwfl_begin)
212INTDECL (dwfl_errmsg)
213INTDECL (dwfl_addrmodule)
214INTDECL (dwfl_addrdwarf)
215INTDECL (dwfl_addrdie)
216INTDECL (dwfl_module_addrdie)
217INTDECL (dwfl_module_getdwarf)
218INTDECL (dwfl_module_getelf)
219INTDECL (dwfl_module_getsrc)
220INTDECL (dwfl_report_elf)
221INTDECL (dwfl_report_begin)
222INTDECL (dwfl_report_module)
223INTDECL (dwfl_report_end)
224INTDECL (dwfl_standard_find_debuginfo)
225INTDECL (dwfl_linux_kernel_find_elf)
226INTDECL (dwfl_linux_kernel_module_section_address)
227INTDECL (dwfl_linux_proc_report)
228INTDECL (dwfl_linux_proc_find_elf)
229INTDECL (dwfl_linux_kernel_report_kernel)
230INTDECL (dwfl_linux_kernel_report_modules)
231
232/* Leading arguments standard to callbacks passed a Dwfl_Module. */
233#define MODCB_ARGS(mod) (mod), &(mod)->userdata, (mod)->name, (mod)->low_addr
234#define CBFAIL (errno ? DWFL_E (ERRNO, errno) : DWFL_E_CB);
235
236
237#endif /* libdwflP.h */