Home | History | Annotate | Download | only in bfd
      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 (at) 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