xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_elfread.h (revision 28ab0ca48b3e331cbbb231b1c8325f9f24f9af95)
1 /* Copyright (c) 2013-2019, David Anderson
2 All rights reserved.
3 
4 Redistribution and use in source and binary forms, with
5 or without modification, are permitted provided that the
6 following conditions are met:
7 
8     Redistributions of source code must retain the above
9     copyright notice, this list of conditions and the following
10     disclaimer.
11 
12     Redistributions in binary form must reproduce the above
13     copyright notice, this list of conditions and the following
14     disclaimer in the documentation and/or other materials
15     provided with the distribution.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
18 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 */
32 #ifndef READELFOBJ_H
33 #define READELFOBJ_H
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif /* __cplusplus */
38 
39 
40 /*  Use this for .rel. too. */
41 struct generic_rela {
42     Dwarf_Unsigned gr_offset;
43     Dwarf_Unsigned gr_info;
44     Dwarf_Unsigned gr_sym; /* From info */
45     Dwarf_Unsigned gr_type; /* From info */
46     Dwarf_Signed   gr_addend;
47     unsigned char  gr_type2; /*MIPS64*/
48     unsigned char  gr_type3; /*MIPS64*/
49     /*  The following TRUE if .rela. and FALSE if .rel.
50         if FALSE, gr_addend will be zero. */
51     int            gr_is_rela;
52 };
53 
54 /*  The following are generic to simplify handling
55     Elf32 and Elf64.  Some fields added where
56     the two sizes have different extraction code. */
57 struct generic_ehdr {
58     unsigned char ge_ident[EI_NIDENT];
59     Dwarf_Unsigned ge_type;
60     Dwarf_Unsigned ge_machine;
61     Dwarf_Unsigned ge_version;
62     Dwarf_Unsigned ge_entry;
63     Dwarf_Unsigned ge_phoff;
64     Dwarf_Unsigned ge_shoff;
65     Dwarf_Unsigned ge_flags;
66     Dwarf_Unsigned ge_ehsize;
67     Dwarf_Unsigned ge_phentsize;
68     Dwarf_Unsigned ge_phnum;
69     Dwarf_Unsigned ge_shentsize;
70     Dwarf_Unsigned ge_shnum;
71     Dwarf_Unsigned ge_shstrndx;
72 };
73 struct generic_phdr {
74     Dwarf_Unsigned gp_type;
75     Dwarf_Unsigned gp_flags;
76     Dwarf_Unsigned gp_offset;
77     Dwarf_Unsigned gp_vaddr;
78     Dwarf_Unsigned gp_paddr;
79     Dwarf_Unsigned gp_filesz;
80     Dwarf_Unsigned gp_memsz;
81     Dwarf_Unsigned gp_align;
82 };
83 struct generic_shdr {
84     Dwarf_Unsigned gh_secnum;
85     Dwarf_Unsigned gh_name;
86     const char * gh_namestring;
87     Dwarf_Unsigned gh_type;
88     Dwarf_Unsigned gh_flags;
89     Dwarf_Unsigned gh_addr;
90     Dwarf_Unsigned gh_offset;
91     Dwarf_Unsigned gh_size;
92     Dwarf_Unsigned gh_link;
93     /*  Section index (in an SHT_REL or SHT_RELA section)
94         of the target section from gh_link. Otherwise 0. */
95     Dwarf_Unsigned gh_reloc_target_secnum;
96     Dwarf_Unsigned gh_info;
97     Dwarf_Unsigned gh_addralign;
98     Dwarf_Unsigned gh_entsize;
99 
100     /*  Zero unless content read in. Malloc space
101         of size gh_size,  in bytes. For dwarf
102         and strings mainly. free() this if not null*/
103     char *       gh_content;
104 
105     /*  If a .rel or .rela section this will point
106         to generic relocation records if such
107         have been loaded.
108         free() this if not null. */
109     Dwarf_Unsigned          gh_relcount;
110     struct generic_rela * gh_rels;
111 
112     /*  For SHT_GROUP based  grouping, which
113         group is this section in. 0 unknown,
114         1 DW_GROUP_NUMBER_BASE base DWARF,
115         2 DW_GROUPNUMBER_DWO  dwo sections, 3+
116         are in an SHT_GROUP. GNU uses this.
117         set with group number (3+) from SHT_GROUP
118         and the flags should have SHF_GROUP set
119         if in SHT_GROUP. Must only be in one group? */
120     Dwarf_Unsigned gh_section_group_number;
121 
122     /*  Content of an SHT_GROUP section as an array
123         of integers. [0] is the version, which
124         can only be one(1) . */
125     Dwarf_Unsigned * gh_sht_group_array;
126     /*  Number of elements in the gh_sht_group_array. */
127     Dwarf_Unsigned   gh_sht_group_array_count;
128 
129     /*   TRUE if .debug_info .eh_frame etc. */
130     char  gh_is_dwarf;
131 };
132 
133 struct generic_dynentry {
134     Dwarf_Unsigned  gd_tag;
135     /*  gd_val stands in for d_ptr and d_val union,
136         the union adds nothing in practice since
137         we expect ptrsize <= ulongest. */
138     Dwarf_Unsigned  gd_val;
139     Dwarf_Unsigned  gd_dyn_file_offset;
140 };
141 
142 struct generic_symentry {
143     Dwarf_Unsigned gs_name;
144     Dwarf_Unsigned gs_value;
145     Dwarf_Unsigned gs_size;
146     Dwarf_Unsigned gs_info;
147     Dwarf_Unsigned gs_other;
148     Dwarf_Unsigned gs_shndx;
149     /* derived */
150     Dwarf_Unsigned gs_bind;
151     Dwarf_Unsigned gs_type;
152 };
153 
154 struct location {
155     const char *g_name;
156     Dwarf_Unsigned g_offset;
157     Dwarf_Unsigned g_count;
158     Dwarf_Unsigned g_entrysize;
159     Dwarf_Unsigned g_totalsize;
160 };
161 
162 typedef struct elf_filedata_s {
163     /*  f_ident[0] == 'E' means it is elf and
164         elf_filedata_s is the struct involved.
165         Other means error/corruption of some kind.
166         f_ident[1] is a version number.
167         Only version 1 is defined. */
168     char           f_ident[8];
169     char *         f_path; /* non-null if known. Must be freed */
170     int            f_fd;
171     int            f_machine; /* EM_* */
172     int            f_destruct_close_fd;
173     int            f_is_64bit;
174     unsigned       f_endian;
175     Dwarf_Unsigned f_filesize;
176     /* Elf size, not DWARF. 32 or 64 */
177     Dwarf_Small    f_offsetsize;
178     Dwarf_Small    f_pointersize;
179     int            f_ftype;
180 
181     Dwarf_Unsigned f_max_secdata_offset;
182     Dwarf_Unsigned f_max_progdata_offset;
183 
184     void (*f_copy_word) (void *, const void *, unsigned long);
185 
186     struct location      f_loc_ehdr;
187     struct generic_ehdr* f_ehdr;
188 
189     struct location      f_loc_shdr;
190     struct generic_shdr* f_shdr;
191 
192     struct location      f_loc_phdr;
193     struct generic_phdr* f_phdr;
194 
195     char *f_elf_shstrings_data; /* section name strings */
196     /* length of currentsection.  Might be zero..*/
197     Dwarf_Unsigned  f_elf_shstrings_length;
198     /* size of malloc-d space */
199     Dwarf_Unsigned  f_elf_shstrings_max;
200 
201     /* This is the .dynamic section */
202     struct location      f_loc_dynamic;
203     struct generic_dynentry * f_dynamic;
204     Dwarf_Unsigned f_dynamic_sect_index;
205 
206     /* .dynsym, .dynstr */
207     struct location      f_loc_dynsym;
208     struct generic_symentry* f_dynsym;
209     char  *f_dynsym_sect_strings;
210     Dwarf_Unsigned f_dynsym_sect_strings_max;
211     Dwarf_Unsigned f_dynsym_sect_strings_sect_index;
212     Dwarf_Unsigned f_dynsym_sect_index;
213 
214     /* .symtab .strtab */
215     struct location      f_loc_symtab;
216     struct generic_symentry* f_symtab;
217     char * f_symtab_sect_strings;
218     Dwarf_Unsigned f_symtab_sect_strings_max;
219     Dwarf_Unsigned f_symtab_sect_strings_sect_index;
220     Dwarf_Unsigned f_symtab_sect_index;
221 
222     /* Starts at 3. 0,1,2 used specially. */
223     Dwarf_Unsigned f_sg_next_group_number;
224     /*  Both the following will be zero unless there
225         are explicit Elf groups. */
226     Dwarf_Unsigned f_sht_group_type_section_count;
227     Dwarf_Unsigned f_shf_group_flag_section_count;
228     Dwarf_Unsigned f_dwo_group_section_count;
229 } dwarf_elf_object_access_internals_t;
230 
231 int dwarf_construct_elf_access(int fd,
232     const char *path,
233     dwarf_elf_object_access_internals_t **ep,int *errcode);
234 int dwarf_destruct_elf_access(dwarf_elf_object_access_internals_t *ep,int *errcode);
235 int _dwarf_load_elf_header(dwarf_elf_object_access_internals_t *ep,int *errcode);
236 int _dwarf_load_elf_sectheaders(dwarf_elf_object_access_internals_t* ep,int *errcode);
237 
238 int _dwarf_load_elf_symtab_symbols(dwarf_elf_object_access_internals_t *ep,int *errcode);
239 int _dwarf_load_elf_symstr( dwarf_elf_object_access_internals_t *ep, int *errcode);
240 
241 /*  These two enums used for type safety in passing
242     values. */
243 enum RelocRela {
244     RelocIsRela = 1,
245     RelocIsRel = 2
246 };
247 enum RelocOffsetSize {
248     RelocOffset32 = 4,
249     RelocOffset64 = 8
250 };
251 
252 int _dwarf_load_elf_relx(dwarf_elf_object_access_internals_t *ep,
253     Dwarf_Unsigned secnum,enum RelocRela,int *errcode);
254 
255 #ifndef EI_NIDENT
256 #define EI_NIDENT 16
257 #endif /* EI_NIDENT */
258 
259 #ifdef __cplusplus
260 }
261 #endif /* __cplusplus */
262 
263 #endif /* READELFOBJ_H */
264