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