1 /* Support for the generic parts of PE/PEI; common header information. 2 Copyright (C) 1995-2014 Free Software Foundation, Inc. 3 Written by Cygnus Solutions. 4 5 This file is part of BFD, the Binary File Descriptor library. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program 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 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 23 /* Most of this hacked by Steve Chamberlain, 24 sac@cygnus.com 25 26 PE/PEI rearrangement (and code added): Donn Terry 27 Softway Systems, Inc. */ 28 29 /* Hey look, some documentation [and in a place you expect to find it]! 30 31 The main reference for the pei format is "Microsoft Portable Executable 32 and Common Object File Format Specification 4.1". Get it if you need to 33 do some serious hacking on this code. 34 35 Another reference: 36 "Peering Inside the PE: A Tour of the Win32 Portable Executable 37 File Format", MSJ 1994, Volume 9. 38 39 The *sole* difference between the pe format and the pei format is that the 40 latter has an MSDOS 2.0 .exe header on the front that prints the message 41 "This app must be run under Windows." (or some such). 42 (FIXME: Whether that statement is *really* true or not is unknown. 43 Are there more subtle differences between pe and pei formats? 44 For now assume there aren't. If you find one, then for God sakes 45 document it here!) 46 47 The Microsoft docs use the word "image" instead of "executable" because 48 the former can also refer to a DLL (shared library). Confusion can arise 49 because the `i' in `pei' also refers to "image". The `pe' format can 50 also create images (i.e. executables), it's just that to run on a win32 51 system you need to use the pei format. 52 53 FIXME: Please add more docs here so the next poor fool that has to hack 54 on this code has a chance of getting something accomplished without 55 wasting too much time. */ 56 57 #ifndef GET_FCN_LNNOPTR 58 #define GET_FCN_LNNOPTR(abfd, ext) \ 59 H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) 60 #endif 61 62 #ifndef GET_FCN_ENDNDX 63 #define GET_FCN_ENDNDX(abfd, ext) \ 64 H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx) 65 #endif 66 67 #ifndef PUT_FCN_LNNOPTR 68 #define PUT_FCN_LNNOPTR(abfd, in, ext) \ 69 H_PUT_32(abfd, in, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) 70 #endif 71 #ifndef PUT_FCN_ENDNDX 72 #define PUT_FCN_ENDNDX(abfd, in, ext) \ 73 H_PUT_32(abfd, in, ext->x_sym.x_fcnary.x_fcn.x_endndx) 74 #endif 75 #ifndef GET_LNSZ_LNNO 76 #define GET_LNSZ_LNNO(abfd, ext) \ 77 H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno) 78 #endif 79 #ifndef GET_LNSZ_SIZE 80 #define GET_LNSZ_SIZE(abfd, ext) \ 81 H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size) 82 #endif 83 #ifndef PUT_LNSZ_LNNO 84 #define PUT_LNSZ_LNNO(abfd, in, ext) \ 85 H_PUT_16(abfd, in, ext->x_sym.x_misc.x_lnsz.x_lnno) 86 #endif 87 #ifndef PUT_LNSZ_SIZE 88 #define PUT_LNSZ_SIZE(abfd, in, ext) \ 89 H_PUT_16(abfd, in, ext->x_sym.x_misc.x_lnsz.x_size) 90 #endif 91 #ifndef GET_SCN_SCNLEN 92 #define GET_SCN_SCNLEN(abfd, ext) \ 93 H_GET_32 (abfd, ext->x_scn.x_scnlen) 94 #endif 95 #ifndef GET_SCN_NRELOC 96 #define GET_SCN_NRELOC(abfd, ext) \ 97 H_GET_16 (abfd, ext->x_scn.x_nreloc) 98 #endif 99 #ifndef GET_SCN_NLINNO 100 #define GET_SCN_NLINNO(abfd, ext) \ 101 H_GET_16 (abfd, ext->x_scn.x_nlinno) 102 #endif 103 #ifndef PUT_SCN_SCNLEN 104 #define PUT_SCN_SCNLEN(abfd, in, ext) \ 105 H_PUT_32(abfd, in, ext->x_scn.x_scnlen) 106 #endif 107 #ifndef PUT_SCN_NRELOC 108 #define PUT_SCN_NRELOC(abfd, in, ext) \ 109 H_PUT_16(abfd, in, ext->x_scn.x_nreloc) 110 #endif 111 #ifndef PUT_SCN_NLINNO 112 #define PUT_SCN_NLINNO(abfd, in, ext) \ 113 H_PUT_16(abfd,in, ext->x_scn.x_nlinno) 114 #endif 115 #ifndef GET_LINENO_LNNO 116 #define GET_LINENO_LNNO(abfd, ext) \ 117 H_GET_16 (abfd, ext->l_lnno); 118 #endif 119 #ifndef PUT_LINENO_LNNO 120 #define PUT_LINENO_LNNO(abfd, val, ext) \ 121 H_PUT_16(abfd,val, ext->l_lnno); 122 #endif 123 124 /* The f_symptr field in the filehdr is sometimes 64 bits. */ 125 #ifndef GET_FILEHDR_SYMPTR 126 #define GET_FILEHDR_SYMPTR H_GET_32 127 #endif 128 #ifndef PUT_FILEHDR_SYMPTR 129 #define PUT_FILEHDR_SYMPTR H_PUT_32 130 #endif 131 132 /* Some fields in the aouthdr are sometimes 64 bits. */ 133 #ifndef GET_AOUTHDR_TSIZE 134 #define GET_AOUTHDR_TSIZE H_GET_32 135 #endif 136 #ifndef PUT_AOUTHDR_TSIZE 137 #define PUT_AOUTHDR_TSIZE H_PUT_32 138 #endif 139 #ifndef GET_AOUTHDR_DSIZE 140 #define GET_AOUTHDR_DSIZE H_GET_32 141 #endif 142 #ifndef PUT_AOUTHDR_DSIZE 143 #define PUT_AOUTHDR_DSIZE H_PUT_32 144 #endif 145 #ifndef GET_AOUTHDR_BSIZE 146 #define GET_AOUTHDR_BSIZE H_GET_32 147 #endif 148 #ifndef PUT_AOUTHDR_BSIZE 149 #define PUT_AOUTHDR_BSIZE H_PUT_32 150 #endif 151 #ifndef GET_AOUTHDR_ENTRY 152 #define GET_AOUTHDR_ENTRY H_GET_32 153 #endif 154 #ifndef PUT_AOUTHDR_ENTRY 155 #define PUT_AOUTHDR_ENTRY H_PUT_32 156 #endif 157 #ifndef GET_AOUTHDR_TEXT_START 158 #define GET_AOUTHDR_TEXT_START H_GET_32 159 #endif 160 #ifndef PUT_AOUTHDR_TEXT_START 161 #define PUT_AOUTHDR_TEXT_START H_PUT_32 162 #endif 163 #ifndef GET_AOUTHDR_DATA_START 164 #define GET_AOUTHDR_DATA_START H_GET_32 165 #endif 166 #ifndef PUT_AOUTHDR_DATA_START 167 #define PUT_AOUTHDR_DATA_START H_PUT_32 168 #endif 169 170 /* Some fields in the scnhdr are sometimes 64 bits. */ 171 #ifndef GET_SCNHDR_PADDR 172 #define GET_SCNHDR_PADDR H_GET_32 173 #endif 174 #ifndef PUT_SCNHDR_PADDR 175 #define PUT_SCNHDR_PADDR H_PUT_32 176 #endif 177 #ifndef GET_SCNHDR_VADDR 178 #define GET_SCNHDR_VADDR H_GET_32 179 #endif 180 #ifndef PUT_SCNHDR_VADDR 181 #define PUT_SCNHDR_VADDR H_PUT_32 182 #endif 183 #ifndef GET_SCNHDR_SIZE 184 #define GET_SCNHDR_SIZE H_GET_32 185 #endif 186 #ifndef PUT_SCNHDR_SIZE 187 #define PUT_SCNHDR_SIZE H_PUT_32 188 #endif 189 #ifndef GET_SCNHDR_SCNPTR 190 #define GET_SCNHDR_SCNPTR H_GET_32 191 #endif 192 #ifndef PUT_SCNHDR_SCNPTR 193 #define PUT_SCNHDR_SCNPTR H_PUT_32 194 #endif 195 #ifndef GET_SCNHDR_RELPTR 196 #define GET_SCNHDR_RELPTR H_GET_32 197 #endif 198 #ifndef PUT_SCNHDR_RELPTR 199 #define PUT_SCNHDR_RELPTR H_PUT_32 200 #endif 201 #ifndef GET_SCNHDR_LNNOPTR 202 #define GET_SCNHDR_LNNOPTR H_GET_32 203 #endif 204 #ifndef PUT_SCNHDR_LNNOPTR 205 #define PUT_SCNHDR_LNNOPTR H_PUT_32 206 #endif 207 208 #ifdef COFF_WITH_pex64 209 210 #define GET_OPTHDR_IMAGE_BASE H_GET_64 211 #define PUT_OPTHDR_IMAGE_BASE H_PUT_64 212 #define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64 213 #define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64 214 #define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64 215 #define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64 216 #define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64 217 #define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64 218 #define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64 219 #define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64 220 #define GET_PDATA_ENTRY bfd_get_32 221 222 #define _bfd_XX_bfd_copy_private_bfd_data_common _bfd_pex64_bfd_copy_private_bfd_data_common 223 #define _bfd_XX_bfd_copy_private_section_data _bfd_pex64_bfd_copy_private_section_data 224 #define _bfd_XX_get_symbol_info _bfd_pex64_get_symbol_info 225 #define _bfd_XX_only_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out 226 #define _bfd_XX_print_private_bfd_data_common _bfd_pex64_print_private_bfd_data_common 227 #define _bfd_XXi_final_link_postscript _bfd_pex64i_final_link_postscript 228 #define _bfd_XXi_only_swap_filehdr_out _bfd_pex64i_only_swap_filehdr_out 229 #define _bfd_XXi_swap_aouthdr_in _bfd_pex64i_swap_aouthdr_in 230 #define _bfd_XXi_swap_aouthdr_out _bfd_pex64i_swap_aouthdr_out 231 #define _bfd_XXi_swap_aux_in _bfd_pex64i_swap_aux_in 232 #define _bfd_XXi_swap_aux_out _bfd_pex64i_swap_aux_out 233 #define _bfd_XXi_swap_lineno_in _bfd_pex64i_swap_lineno_in 234 #define _bfd_XXi_swap_lineno_out _bfd_pex64i_swap_lineno_out 235 #define _bfd_XXi_swap_scnhdr_out _bfd_pex64i_swap_scnhdr_out 236 #define _bfd_XXi_swap_sym_in _bfd_pex64i_swap_sym_in 237 #define _bfd_XXi_swap_sym_out _bfd_pex64i_swap_sym_out 238 #define _bfd_XXi_swap_debugdir_in _bfd_pex64i_swap_debugdir_in 239 #define _bfd_XXi_swap_debugdir_out _bfd_pex64i_swap_debugdir_out 240 #define _bfd_XXi_write_codeview_record _bfd_pex64i_write_codeview_record 241 242 #elif defined COFF_WITH_pep 243 244 #define GET_OPTHDR_IMAGE_BASE H_GET_64 245 #define PUT_OPTHDR_IMAGE_BASE H_PUT_64 246 #define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64 247 #define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64 248 #define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64 249 #define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64 250 #define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64 251 #define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64 252 #define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64 253 #define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64 254 #define GET_PDATA_ENTRY bfd_get_64 255 256 #define _bfd_XX_bfd_copy_private_bfd_data_common _bfd_pep_bfd_copy_private_bfd_data_common 257 #define _bfd_XX_bfd_copy_private_section_data _bfd_pep_bfd_copy_private_section_data 258 #define _bfd_XX_get_symbol_info _bfd_pep_get_symbol_info 259 #define _bfd_XX_only_swap_filehdr_out _bfd_pep_only_swap_filehdr_out 260 #define _bfd_XX_print_private_bfd_data_common _bfd_pep_print_private_bfd_data_common 261 #define _bfd_XXi_final_link_postscript _bfd_pepi_final_link_postscript 262 #define _bfd_XXi_only_swap_filehdr_out _bfd_pepi_only_swap_filehdr_out 263 #define _bfd_XXi_swap_aouthdr_in _bfd_pepi_swap_aouthdr_in 264 #define _bfd_XXi_swap_aouthdr_out _bfd_pepi_swap_aouthdr_out 265 #define _bfd_XXi_swap_aux_in _bfd_pepi_swap_aux_in 266 #define _bfd_XXi_swap_aux_out _bfd_pepi_swap_aux_out 267 #define _bfd_XXi_swap_lineno_in _bfd_pepi_swap_lineno_in 268 #define _bfd_XXi_swap_lineno_out _bfd_pepi_swap_lineno_out 269 #define _bfd_XXi_swap_scnhdr_out _bfd_pepi_swap_scnhdr_out 270 #define _bfd_XXi_swap_sym_in _bfd_pepi_swap_sym_in 271 #define _bfd_XXi_swap_sym_out _bfd_pepi_swap_sym_out 272 #define _bfd_XXi_swap_debugdir_in _bfd_pepi_swap_debugdir_in 273 #define _bfd_XXi_swap_debugdir_out _bfd_pepi_swap_debugdir_out 274 #define _bfd_XXi_write_codeview_record _bfd_pepi_write_codeview_record 275 276 #else /* !COFF_WITH_pep */ 277 278 #define GET_OPTHDR_IMAGE_BASE H_GET_32 279 #define PUT_OPTHDR_IMAGE_BASE H_PUT_32 280 #define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_32 281 #define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_32 282 #define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_32 283 #define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_32 284 #define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_32 285 #define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_32 286 #define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_32 287 #define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_32 288 #define GET_PDATA_ENTRY bfd_get_32 289 290 #define _bfd_XX_bfd_copy_private_bfd_data_common _bfd_pe_bfd_copy_private_bfd_data_common 291 #define _bfd_XX_bfd_copy_private_section_data _bfd_pe_bfd_copy_private_section_data 292 #define _bfd_XX_get_symbol_info _bfd_pe_get_symbol_info 293 #define _bfd_XX_only_swap_filehdr_out _bfd_pe_only_swap_filehdr_out 294 #define _bfd_XX_print_private_bfd_data_common _bfd_pe_print_private_bfd_data_common 295 #define _bfd_XXi_final_link_postscript _bfd_pei_final_link_postscript 296 #define _bfd_XXi_only_swap_filehdr_out _bfd_pei_only_swap_filehdr_out 297 #define _bfd_XXi_swap_aouthdr_in _bfd_pei_swap_aouthdr_in 298 #define _bfd_XXi_swap_aouthdr_out _bfd_pei_swap_aouthdr_out 299 #define _bfd_XXi_swap_aux_in _bfd_pei_swap_aux_in 300 #define _bfd_XXi_swap_aux_out _bfd_pei_swap_aux_out 301 #define _bfd_XXi_swap_lineno_in _bfd_pei_swap_lineno_in 302 #define _bfd_XXi_swap_lineno_out _bfd_pei_swap_lineno_out 303 #define _bfd_XXi_swap_scnhdr_out _bfd_pei_swap_scnhdr_out 304 #define _bfd_XXi_swap_sym_in _bfd_pei_swap_sym_in 305 #define _bfd_XXi_swap_sym_out _bfd_pei_swap_sym_out 306 #define _bfd_XXi_swap_debugdir_in _bfd_pei_swap_debugdir_in 307 #define _bfd_XXi_swap_debugdir_out _bfd_pei_swap_debugdir_out 308 #define _bfd_XXi_write_codeview_record _bfd_pei_write_codeview_record 309 310 #endif /* !COFF_WITH_pep */ 311 312 /* These functions are architecture dependent, and are in peicode.h: 313 coff_swap_reloc_in 314 int coff_swap_reloc_out 315 coff_swap_filehdr_in 316 coff_swap_scnhdr_in 317 pe_mkobject 318 pe_mkobject_hook */ 319 320 /* The functions described below are common across all PE/PEI 321 implementations architecture types, and actually appear in 322 peigen.c. */ 323 324 #define coff_swap_sym_in _bfd_XXi_swap_sym_in 325 #define coff_swap_sym_out _bfd_XXi_swap_sym_out 326 #define coff_swap_aux_in _bfd_XXi_swap_aux_in 327 #define coff_swap_aux_out _bfd_XXi_swap_aux_out 328 #define coff_swap_lineno_in _bfd_XXi_swap_lineno_in 329 #define coff_swap_lineno_out _bfd_XXi_swap_lineno_out 330 #define coff_swap_aouthdr_in _bfd_XXi_swap_aouthdr_in 331 #define coff_swap_aouthdr_out _bfd_XXi_swap_aouthdr_out 332 #define coff_swap_scnhdr_out _bfd_XXi_swap_scnhdr_out 333 334 #ifndef coff_final_link_postscript 335 #define coff_final_link_postscript _bfd_XXi_final_link_postscript 336 #endif 337 338 void _bfd_XXi_swap_sym_in (bfd *, void *, void *); 339 unsigned _bfd_XXi_swap_sym_out (bfd *, void *, void *); 340 void _bfd_XXi_swap_aux_in (bfd *, void *, int, int, int, int, void *); 341 unsigned _bfd_XXi_swap_aux_out (bfd *, void *, int, int, int, int, void *); 342 void _bfd_XXi_swap_lineno_in (bfd *, void *, void *); 343 unsigned _bfd_XXi_swap_lineno_out (bfd *, void *, void *); 344 void _bfd_XXi_swap_aouthdr_in (bfd *, void *, void *); 345 unsigned _bfd_XXi_swap_aouthdr_out (bfd *, void *, void *); 346 unsigned _bfd_XXi_swap_scnhdr_out (bfd *, void *, void *); 347 bfd_boolean _bfd_XX_print_private_bfd_data_common (bfd *, void *); 348 bfd_boolean _bfd_XX_bfd_copy_private_bfd_data_common (bfd *, bfd *); 349 void _bfd_XX_get_symbol_info (bfd *, asymbol *, symbol_info *); 350 bfd_boolean _bfd_XXi_final_link_postscript (bfd *, struct coff_final_link_info *); 351 void _bfd_XXi_swap_debugdir_in (bfd *, void *, void *); 352 unsigned _bfd_XXi_swap_debugdir_out (bfd *, void *, void *); 353 unsigned _bfd_XXi_write_codeview_record (bfd *, file_ptr, CODEVIEW_INFO *); 354 355 /* The following are needed only for ONE of pe or pei, but don't 356 otherwise vary; peicode.h fixes up ifdefs but we provide the 357 prototype. */ 358 359 unsigned _bfd_XX_only_swap_filehdr_out (bfd *, void *, void *); 360 unsigned _bfd_XXi_only_swap_filehdr_out (bfd *, void *, void *); 361 bfd_boolean _bfd_XX_bfd_copy_private_section_data (bfd *, asection *, bfd *, asection *); 362 363 bfd_boolean _bfd_pe_print_ce_compressed_pdata (bfd *, void *); 364 bfd_boolean _bfd_pe64_print_ce_compressed_pdata (bfd *, void *); 365 bfd_boolean _bfd_pex64_print_ce_compressed_pdata (bfd *, void *); 366 bfd_boolean _bfd_pep_print_ce_compressed_pdata (bfd *, void *); 367 368