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 #ifdef HAVE_ELF_H 25 # include <elf.h> 26 #endif 27 #ifdef HAVE_SYS_ELF32_H 28 # include <sys/elf32.h> 29 #endif 30 #ifdef HAVE_SYS_EXEC_ELF_H 31 # include <sys/exec_elf.h> 32 #endif 33 #if !defined(DT_NUM) 34 # if defined(DT_COUNT) 35 # define DT_NUM DT_COUNT 36 # else 37 /* this seems to be a satisfactory value on Solaris, which doesn't support this AFAICT */ 38 # define DT_NUM 24 39 # endif 40 #endif 41 #ifdef HAVE_LINK_H 42 # include <link.h> 43 #endif 44 #ifdef HAVE_SYS_LINK_H 45 # include <sys/link.h> 46 #endif 47 #ifdef HAVE_MACH_O_LOADER_H 48 #include <mach-o/loader.h> 49 50 #ifdef _WIN64 51 typedef struct mach_header_64 macho_mach_header; 52 typedef struct section_64 macho_section; 53 #else 54 typedef struct mach_header macho_mach_header; 55 typedef struct section macho_section; 56 #endif 57 #endif 58 59 #define IMAGE_NO_MAP ((void*)-1) 60 61 #if defined(__ELF__) && !defined(DBGHELP_STATIC_LIB) 62 63 #ifdef _WIN64 64 #define Elf_Ehdr Elf64_Ehdr 65 #define Elf_Shdr Elf64_Shdr 66 #define Elf_Phdr Elf64_Phdr 67 #define Elf_Dyn Elf64_Dyn 68 #define Elf_Sym Elf64_Sym 69 #define Elf_auxv_t Elf64_auxv_t 70 #else 71 #define Elf_Ehdr Elf32_Ehdr 72 #define Elf_Shdr Elf32_Shdr 73 #define Elf_Phdr Elf32_Phdr 74 #define Elf_Dyn Elf32_Dyn 75 #define Elf_Sym Elf32_Sym 76 #define Elf_auxv_t Elf32_auxv_t 77 #endif 78 #else 79 #ifndef SHT_NULL 80 #define SHT_NULL 0 81 #endif 82 #endif 83 84 /* structure holding information while handling an ELF image 85 * allows one by one section mapping for memory savings 86 */ 87 struct image_file_map 88 { 89 enum module_type modtype; 90 unsigned addr_size; /* either 16 (not used), 32 or 64 */ 91 union 92 { 93 struct elf_file_map 94 { 95 size_t elf_size; 96 size_t elf_start; 97 int fd; 98 const char* shstrtab; 99 struct image_file_map* alternate; /* another ELF file (linked to this one) */ 100 char* target_copy; 101 #if defined(__ELF__) && !defined(DBGHELP_STATIC_LIB) 102 Elf_Ehdr elfhdr; 103 struct 104 { 105 Elf_Shdr shdr; 106 const char* mapped; 107 }* sect; 108 #endif 109 } elf; 110 struct macho_file_map 111 { 112 size_t segs_size; 113 size_t segs_start; 114 int fd; 115 struct image_file_map* dsym; /* the debug symbols file associated with this one */ 116 117 #ifdef HAVE_MACH_O_LOADER_H 118 macho_mach_header mach_header; 119 const struct load_command* load_commands; 120 const struct uuid_command* uuid; 121 122 /* The offset in the file which is this architecture. mach_header was 123 * read from arch_offset. */ 124 unsigned arch_offset; 125 126 int num_sections; 127 struct 128 { 129 const macho_section* section; 130 const char* mapped; 131 unsigned int ignored : 1; 132 }* sect; 133 #endif 134 } macho; 135 struct pe_file_map 136 { 137 HANDLE hMap; 138 IMAGE_NT_HEADERS ntheader; 139 unsigned full_count; 140 void* full_map; 141 struct 142 { 143 IMAGE_SECTION_HEADER shdr; 144 const char* mapped; 145 }* sect; 146 const char* strtable; 147 } pe; 148 } u; 149 }; 150 151 struct image_section_map 152 { 153 struct image_file_map* fmap; 154 long sidx; 155 }; 156 157 extern BOOL elf_find_section(struct image_file_map* fmap, const char* name, 158 unsigned sht, struct image_section_map* ism) DECLSPEC_HIDDEN; 159 extern const char* elf_map_section(struct image_section_map* ism) DECLSPEC_HIDDEN; 160 extern void elf_unmap_section(struct image_section_map* ism) DECLSPEC_HIDDEN; 161 extern DWORD_PTR elf_get_map_rva(const struct image_section_map* ism) DECLSPEC_HIDDEN; 162 extern unsigned elf_get_map_size(const struct image_section_map* ism) DECLSPEC_HIDDEN; 163 164 extern BOOL macho_find_section(struct image_file_map* ifm, const char* segname, 165 const char* sectname, struct image_section_map* ism) DECLSPEC_HIDDEN; 166 extern const char* macho_map_section(struct image_section_map* ism) DECLSPEC_HIDDEN; 167 extern void macho_unmap_section(struct image_section_map* ism) DECLSPEC_HIDDEN; 168 extern DWORD_PTR macho_get_map_rva(const struct image_section_map* ism) DECLSPEC_HIDDEN; 169 extern unsigned macho_get_map_size(const struct image_section_map* ism) DECLSPEC_HIDDEN; 170 171 extern BOOL pe_find_section(struct image_file_map* fmap, const char* name, 172 struct image_section_map* ism) DECLSPEC_HIDDEN; 173 extern const char* pe_map_section(struct image_section_map* psm) DECLSPEC_HIDDEN; 174 extern void pe_unmap_section(struct image_section_map* psm) DECLSPEC_HIDDEN; 175 extern DWORD_PTR pe_get_map_rva(const struct image_section_map* psm) DECLSPEC_HIDDEN; 176 extern unsigned pe_get_map_size(const struct image_section_map* psm) DECLSPEC_HIDDEN; 177 178 static inline BOOL image_find_section(struct image_file_map* fmap, const char* name, 179 struct image_section_map* ism) 180 { 181 switch (fmap->modtype) 182 { 183 #ifndef DBGHELP_STATIC_LIB 184 case DMT_ELF: return elf_find_section(fmap, name, SHT_NULL, ism); 185 case DMT_MACHO: return macho_find_section(fmap, NULL, name, ism); 186 #endif 187 case DMT_PE: return pe_find_section(fmap, name, ism); 188 default: assert(0); return FALSE; 189 } 190 } 191 192 static inline const char* image_map_section(struct image_section_map* ism) 193 { 194 if (!ism->fmap) return NULL; 195 switch (ism->fmap->modtype) 196 { 197 #ifndef DBGHELP_STATIC_LIB 198 case DMT_ELF: return elf_map_section(ism); 199 case DMT_MACHO: return macho_map_section(ism); 200 #endif 201 case DMT_PE: return pe_map_section(ism); 202 default: assert(0); return NULL; 203 } 204 } 205 206 static inline void image_unmap_section(struct image_section_map* ism) 207 { 208 if (!ism->fmap) return; 209 switch (ism->fmap->modtype) 210 { 211 #ifndef DBGHELP_STATIC_LIB 212 case DMT_ELF: elf_unmap_section(ism); break; 213 case DMT_MACHO: macho_unmap_section(ism); break; 214 #endif 215 case DMT_PE: pe_unmap_section(ism); break; 216 default: assert(0); return; 217 } 218 } 219 220 static inline DWORD_PTR image_get_map_rva(const struct image_section_map* ism) 221 { 222 if (!ism->fmap) return 0; 223 switch (ism->fmap->modtype) 224 { 225 #ifndef DBGHELP_STATIC_LIB 226 case DMT_ELF: return elf_get_map_rva(ism); 227 case DMT_MACHO: return macho_get_map_rva(ism); 228 #endif 229 case DMT_PE: return pe_get_map_rva(ism); 230 default: assert(0); return 0; 231 } 232 } 233 234 static inline unsigned image_get_map_size(const struct image_section_map* ism) 235 { 236 if (!ism->fmap) return 0; 237 switch (ism->fmap->modtype) 238 { 239 #ifndef DBGHELP_STATIC_LIB 240 case DMT_ELF: return elf_get_map_size(ism); 241 case DMT_MACHO: return macho_get_map_size(ism); 242 #endif 243 case DMT_PE: return pe_get_map_size(ism); 244 default: assert(0); return 0; 245 } 246 } 247