1 /*
2 * File elf_private.h - definitions for processing of ELF files
3 *
4 * Copyright (C) 1996, Eric Youngdale.
5 * 1999-2007 Eric Pouech
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #pragma once
23
24 #define IMAGE_NO_MAP ((void*)-1)
25
26 struct elf_header
27 {
28 UINT8 e_ident[16]; /* Magic number and other info */
29 UINT16 e_type; /* Object file type */
30 UINT16 e_machine; /* Architecture */
31 UINT32 e_version; /* Object file version */
32 UINT64 e_entry; /* Entry point virtual address */
33 UINT64 e_phoff; /* Program header table file offset */
34 UINT64 e_shoff; /* Section header table file offset */
35 UINT32 e_flags; /* Processor-specific flags */
36 UINT16 e_ehsize; /* ELF header size in bytes */
37 UINT16 e_phentsize; /* Program header table entry size */
38 UINT16 e_phnum; /* Program header table entry count */
39 UINT16 e_shentsize; /* Section header table entry size */
40 UINT16 e_shnum; /* Section header table entry count */
41 UINT16 e_shstrndx; /* Section header string table index */
42 };
43
44 struct elf_section_header
45 {
46 UINT32 sh_name; /* Section name (string tbl index) */
47 UINT32 sh_type; /* Section type */
48 UINT64 sh_flags; /* Section flags */
49 UINT64 sh_addr; /* Section virtual addr at execution */
50 UINT64 sh_offset; /* Section file offset */
51 UINT64 sh_size; /* Section size in bytes */
52 UINT32 sh_link; /* Link to another section */
53 UINT32 sh_info; /* Additional section information */
54 UINT64 sh_addralign; /* Section alignment */
55 UINT64 sh_entsize; /* Entry size if section holds table */
56 };
57
58 struct macho_load_command
59 {
60 UINT32 cmd; /* type of load command */
61 UINT32 cmdsize; /* total size of command in bytes */
62 };
63
64 struct macho_uuid_command
65 {
66 UINT32 cmd; /* LC_UUID */
67 UINT32 cmdsize;
68 UINT8 uuid[16];
69 };
70
71 struct macho_section
72 {
73 char sectname[16]; /* name of this section */
74 char segname[16]; /* segment this section goes in */
75 UINT64 addr; /* memory address of this section */
76 UINT64 size; /* size in bytes of this section */
77 UINT32 offset; /* file offset of this section */
78 UINT32 align; /* section alignment (power of 2) */
79 UINT32 reloff; /* file offset of relocation entries */
80 UINT32 nreloc; /* number of relocation entries */
81 UINT32 flags; /* flags (section type and attributes)*/
82 UINT32 reserved1; /* reserved (for offset or index) */
83 UINT32 reserved2; /* reserved (for count or sizeof) */
84 UINT32 reserved3; /* reserved */
85 };
86
87 struct macho_section32
88 {
89 char sectname[16]; /* name of this section */
90 char segname[16]; /* segment this section goes in */
91 UINT32 addr; /* memory address of this section */
92 UINT32 size; /* size in bytes of this section */
93 UINT32 offset; /* file offset of this section */
94 UINT32 align; /* section alignment (power of 2) */
95 UINT32 reloff; /* file offset of relocation entries */
96 UINT32 nreloc; /* number of relocation entries */
97 UINT32 flags; /* flags (section type and attributes)*/
98 UINT32 reserved1; /* reserved (for offset or index) */
99 UINT32 reserved2; /* reserved (for count or sizeof) */
100 };
101
102 /* structure holding information while handling an ELF image
103 * allows one by one section mapping for memory savings
104 */
105 struct image_file_map
106 {
107 enum module_type modtype;
108 const struct image_file_map_ops *ops;
109 unsigned addr_size; /* either 16 (not used), 32 or 64 */
110 struct image_file_map* alternate; /* another file linked to this one */
111 union
112 {
113 struct elf_file_map
114 {
115 size_t elf_size;
116 size_t elf_start;
117 HANDLE handle;
118 const char* shstrtab;
119 char* target_copy;
120 struct elf_header elfhdr;
121 struct
122 {
123 struct elf_section_header shdr;
124 const char* mapped;
125 }* sect;
126 } elf;
127 struct macho_file_map
128 {
129 size_t segs_size;
130 size_t segs_start;
131 HANDLE handle;
132 struct image_file_map* dsym; /* the debug symbols file associated with this one */
133 size_t header_size; /* size of real header in file */
134 size_t commands_size;
135 unsigned int commands_count;
136
137 const struct macho_load_command* load_commands;
138 const struct macho_uuid_command* uuid;
139
140 /* The offset in the file which is this architecture. mach_header was
141 * read from arch_offset. */
142 unsigned arch_offset;
143
144 int num_sections;
145 struct
146 {
147 struct macho_section section;
148 const char* mapped;
149 unsigned int ignored : 1;
150 }* sect;
151 } macho;
152 struct pe_file_map
153 {
154 HANDLE hMap;
155 IMAGE_NT_HEADERS ntheader;
156 BOOL builtin;
157 unsigned full_count;
158 void* full_map;
159 struct
160 {
161 IMAGE_SECTION_HEADER shdr;
162 const char* mapped;
163 }* sect;
164 const char* strtable;
165 } pe;
166 } u;
167 };
168
169 struct image_section_map
170 {
171 struct image_file_map* fmap;
172 LONG_PTR sidx;
173 };
174
175 struct stab_nlist
176 {
177 unsigned n_strx;
178 unsigned char n_type;
179 char n_other;
180 short n_desc;
181 unsigned n_value;
182 };
183
184 struct macho64_nlist
185 {
186 unsigned n_strx;
187 unsigned char n_type;
188 char n_other;
189 short n_desc;
190 UINT64 n_value;
191 };
192
193 BOOL image_check_alternate(struct image_file_map* fmap, const struct module* module) DECLSPEC_HIDDEN;
194
195 BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap) DECLSPEC_HIDDEN;
196 BOOL pe_map_file(HANDLE file, struct image_file_map* fmap, enum module_type mt) DECLSPEC_HIDDEN;
197
198 struct image_file_map_ops
199 {
200 const char* (*map_section)(struct image_section_map* ism);
201 void (*unmap_section)(struct image_section_map* ism);
202 BOOL (*find_section)(struct image_file_map* fmap, const char* name, struct image_section_map* ism);
203 DWORD_PTR (*get_map_rva)(const struct image_section_map* ism);
204 unsigned (*get_map_size)(const struct image_section_map* ism);
205 void (*unmap_file)(struct image_file_map *fmap);
206 };
207
image_find_section(struct image_file_map * fmap,const char * name,struct image_section_map * ism)208 static inline BOOL image_find_section(struct image_file_map* fmap, const char* name,
209 struct image_section_map* ism)
210 {
211 while (fmap)
212 {
213 if (fmap->ops->find_section(fmap, name, ism)) return TRUE;
214 fmap = fmap->alternate;
215 }
216 ism->fmap = NULL;
217 ism->sidx = -1;
218 return FALSE;
219 }
220
image_unmap_file(struct image_file_map * fmap)221 static inline void image_unmap_file(struct image_file_map* fmap)
222 {
223 while (fmap)
224 {
225 fmap->ops->unmap_file(fmap);
226 fmap = fmap->alternate;
227 }
228 }
229
image_map_section(struct image_section_map * ism)230 static inline const char* image_map_section(struct image_section_map* ism)
231 {
232 return ism->fmap ? ism->fmap->ops->map_section(ism) : NULL;
233 }
234
image_unmap_section(struct image_section_map * ism)235 static inline void image_unmap_section(struct image_section_map* ism)
236 {
237 if (ism->fmap) ism->fmap->ops->unmap_section(ism);
238 }
239
image_get_map_rva(const struct image_section_map * ism)240 static inline DWORD_PTR image_get_map_rva(const struct image_section_map* ism)
241 {
242 return ism->fmap ? ism->fmap->ops->get_map_rva(ism) : 0;
243 }
244
image_get_map_size(const struct image_section_map * ism)245 static inline unsigned image_get_map_size(const struct image_section_map* ism)
246 {
247 return ism->fmap ? ism->fmap->ops->get_map_size(ism) : 0;
248 }
249