15796c8dcSSimon Schubert /* Read the export table symbols from a portable executable and 25796c8dcSSimon Schubert convert to internal format, for GDB. Used as a last resort if no 35796c8dcSSimon Schubert debugging symbols recognized. 45796c8dcSSimon Schubert 5*ef5ccd6cSJohn Marino Copyright (C) 2003-2013 Free Software Foundation, Inc. 65796c8dcSSimon Schubert 75796c8dcSSimon Schubert This file is part of GDB. 85796c8dcSSimon Schubert 95796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 105796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 115796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 125796c8dcSSimon Schubert (at your option) any later version. 135796c8dcSSimon Schubert 145796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 155796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 165796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 175796c8dcSSimon Schubert GNU General Public License for more details. 185796c8dcSSimon Schubert 195796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 205796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. 215796c8dcSSimon Schubert 225796c8dcSSimon Schubert Contributed by Raoul M. Gough (RaoulGough@yahoo.co.uk). */ 235796c8dcSSimon Schubert 24*ef5ccd6cSJohn Marino #include "defs.h" 25*ef5ccd6cSJohn Marino 265796c8dcSSimon Schubert #include "coff-pe-read.h" 275796c8dcSSimon Schubert 28a45ae5f8SJohn Marino #include "bfd.h" 295796c8dcSSimon Schubert #include "gdbtypes.h" 305796c8dcSSimon Schubert 31*ef5ccd6cSJohn Marino #include "command.h" 32*ef5ccd6cSJohn Marino #include "gdbcmd.h" 335796c8dcSSimon Schubert #include "symtab.h" 345796c8dcSSimon Schubert #include "symfile.h" 355796c8dcSSimon Schubert #include "objfiles.h" 36*ef5ccd6cSJohn Marino #include "common/common-utils.h" 37*ef5ccd6cSJohn Marino #include "coff/internal.h" 38*ef5ccd6cSJohn Marino 39*ef5ccd6cSJohn Marino #include <ctype.h> 405796c8dcSSimon Schubert 415796c8dcSSimon Schubert /* Internal section information */ 425796c8dcSSimon Schubert 43*ef5ccd6cSJohn Marino /* Coff PE read debugging flag: 44*ef5ccd6cSJohn Marino default value is 0, 45*ef5ccd6cSJohn Marino value 1 outputs problems encountered while parsing PE file, 46*ef5ccd6cSJohn Marino value above 1 also lists all generated minimal symbols. */ 47*ef5ccd6cSJohn Marino static unsigned int debug_coff_pe_read; 48*ef5ccd6cSJohn Marino 495796c8dcSSimon Schubert struct read_pe_section_data 505796c8dcSSimon Schubert { 515796c8dcSSimon Schubert CORE_ADDR vma_offset; /* Offset to loaded address of section. */ 525796c8dcSSimon Schubert unsigned long rva_start; /* Start offset within the pe. */ 535796c8dcSSimon Schubert unsigned long rva_end; /* End offset within the pe. */ 54c50c785cSJohn Marino enum minimal_symbol_type ms_type; /* Type to assign symbols in 55c50c785cSJohn Marino section. */ 56*ef5ccd6cSJohn Marino char *section_name; /* Recorded section name. */ 575796c8dcSSimon Schubert }; 585796c8dcSSimon Schubert 59*ef5ccd6cSJohn Marino #define IMAGE_SCN_CNT_CODE 0x20 60*ef5ccd6cSJohn Marino #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x40 61*ef5ccd6cSJohn Marino #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x80 625796c8dcSSimon Schubert #define PE_SECTION_INDEX_TEXT 0 635796c8dcSSimon Schubert #define PE_SECTION_INDEX_DATA 1 645796c8dcSSimon Schubert #define PE_SECTION_INDEX_BSS 2 655796c8dcSSimon Schubert #define PE_SECTION_TABLE_SIZE 3 665796c8dcSSimon Schubert #define PE_SECTION_INDEX_INVALID -1 675796c8dcSSimon Schubert 685796c8dcSSimon Schubert /* Get the index of the named section in our own array, which contains 695796c8dcSSimon Schubert text, data and bss in that order. Return PE_SECTION_INDEX_INVALID 705796c8dcSSimon Schubert if passed an unrecognised section name. */ 715796c8dcSSimon Schubert 725796c8dcSSimon Schubert static int 735796c8dcSSimon Schubert read_pe_section_index (const char *section_name) 745796c8dcSSimon Schubert { 755796c8dcSSimon Schubert if (strcmp (section_name, ".text") == 0) 765796c8dcSSimon Schubert { 775796c8dcSSimon Schubert return PE_SECTION_INDEX_TEXT; 785796c8dcSSimon Schubert } 795796c8dcSSimon Schubert 805796c8dcSSimon Schubert else if (strcmp (section_name, ".data") == 0) 815796c8dcSSimon Schubert { 825796c8dcSSimon Schubert return PE_SECTION_INDEX_DATA; 835796c8dcSSimon Schubert } 845796c8dcSSimon Schubert 855796c8dcSSimon Schubert else if (strcmp (section_name, ".bss") == 0) 865796c8dcSSimon Schubert { 875796c8dcSSimon Schubert return PE_SECTION_INDEX_BSS; 885796c8dcSSimon Schubert } 895796c8dcSSimon Schubert 905796c8dcSSimon Schubert else 915796c8dcSSimon Schubert { 925796c8dcSSimon Schubert return PE_SECTION_INDEX_INVALID; 935796c8dcSSimon Schubert } 945796c8dcSSimon Schubert } 955796c8dcSSimon Schubert 96*ef5ccd6cSJohn Marino /* Get the index of the named section in our own full arrayi. 97*ef5ccd6cSJohn Marino text, data and bss in that order. Return PE_SECTION_INDEX_INVALID 98*ef5ccd6cSJohn Marino if passed an unrecognised section name. */ 99*ef5ccd6cSJohn Marino 100*ef5ccd6cSJohn Marino static int 101*ef5ccd6cSJohn Marino get_pe_section_index (const char *section_name, 102*ef5ccd6cSJohn Marino struct read_pe_section_data *sections, 103*ef5ccd6cSJohn Marino int nb_sections) 104*ef5ccd6cSJohn Marino { 105*ef5ccd6cSJohn Marino int i; 106*ef5ccd6cSJohn Marino 107*ef5ccd6cSJohn Marino for (i = 0; i < nb_sections; i++) 108*ef5ccd6cSJohn Marino if (strcmp (sections[i].section_name, section_name) == 0) 109*ef5ccd6cSJohn Marino return i; 110*ef5ccd6cSJohn Marino return PE_SECTION_INDEX_INVALID; 111*ef5ccd6cSJohn Marino } 112*ef5ccd6cSJohn Marino 113*ef5ccd6cSJohn Marino /* Structure used by get_section_vmas function below 114*ef5ccd6cSJohn Marino to access section_data array and the size of the array 115*ef5ccd6cSJohn Marino stored in nb_sections field. */ 116*ef5ccd6cSJohn Marino struct pe_sections_info 117*ef5ccd6cSJohn Marino { 118*ef5ccd6cSJohn Marino int nb_sections; 119*ef5ccd6cSJohn Marino struct read_pe_section_data *sections; 120*ef5ccd6cSJohn Marino }; 121*ef5ccd6cSJohn Marino 1225796c8dcSSimon Schubert /* Record the virtual memory address of a section. */ 1235796c8dcSSimon Schubert 1245796c8dcSSimon Schubert static void 1255796c8dcSSimon Schubert get_section_vmas (bfd *abfd, asection *sectp, void *context) 1265796c8dcSSimon Schubert { 127*ef5ccd6cSJohn Marino struct pe_sections_info *data = context; 128*ef5ccd6cSJohn Marino struct read_pe_section_data *sections = data->sections; 129*ef5ccd6cSJohn Marino int sectix = get_pe_section_index (sectp->name, sections, 130*ef5ccd6cSJohn Marino data->nb_sections); 1315796c8dcSSimon Schubert 1325796c8dcSSimon Schubert if (sectix != PE_SECTION_INDEX_INVALID) 1335796c8dcSSimon Schubert { 1345796c8dcSSimon Schubert /* Data within the section start at rva_start in the pe and at 1355796c8dcSSimon Schubert bfd_get_section_vma() within memory. Store the offset. */ 1365796c8dcSSimon Schubert 1375796c8dcSSimon Schubert sections[sectix].vma_offset 1385796c8dcSSimon Schubert = bfd_get_section_vma (abfd, sectp) - sections[sectix].rva_start; 1395796c8dcSSimon Schubert } 1405796c8dcSSimon Schubert } 1415796c8dcSSimon Schubert 142*ef5ccd6cSJohn Marino /* Create a minimal symbol entry for an exported symbol. 143*ef5ccd6cSJohn Marino SYM_NAME contains the exported name or NULL if exported by ordinal, 144*ef5ccd6cSJohn Marino FUNC_RVA contains the Relative Virtual Address of the symbol, 145*ef5ccd6cSJohn Marino ORDINAL is the ordinal index value of the symbol, 146*ef5ccd6cSJohn Marino SECTION_DATA contains information about the section in which the 147*ef5ccd6cSJohn Marino symbol is declared, 148*ef5ccd6cSJohn Marino DLL_NAME is the internal name of the DLL file, 149*ef5ccd6cSJohn Marino OBJFILE is the objfile struct of DLL_NAME. */ 1505796c8dcSSimon Schubert 1515796c8dcSSimon Schubert static void 152*ef5ccd6cSJohn Marino add_pe_exported_sym (const char *sym_name, 1535796c8dcSSimon Schubert unsigned long func_rva, 154*ef5ccd6cSJohn Marino int ordinal, 1555796c8dcSSimon Schubert const struct read_pe_section_data *section_data, 1565796c8dcSSimon Schubert const char *dll_name, struct objfile *objfile) 1575796c8dcSSimon Schubert { 158*ef5ccd6cSJohn Marino char *qualified_name, *bare_name; 1595796c8dcSSimon Schubert /* Add the stored offset to get the loaded address of the symbol. */ 1605796c8dcSSimon Schubert CORE_ADDR vma = func_rva + section_data->vma_offset; 1615796c8dcSSimon Schubert int dll_name_len = strlen (dll_name); 1625796c8dcSSimon Schubert 1635796c8dcSSimon Schubert /* Generate a (hopefully unique) qualified name using the first part 1645796c8dcSSimon Schubert of the dll name, e.g. KERNEL32!AddAtomA. This matches the style 1655796c8dcSSimon Schubert used by windbg from the "Microsoft Debugging Tools for Windows". */ 1665796c8dcSSimon Schubert 167*ef5ccd6cSJohn Marino if (sym_name == NULL || *sym_name == '\0') 168*ef5ccd6cSJohn Marino bare_name = xstrprintf ("#%d", ordinal); 169*ef5ccd6cSJohn Marino else 170*ef5ccd6cSJohn Marino bare_name = xstrdup (sym_name); 1715796c8dcSSimon Schubert 172*ef5ccd6cSJohn Marino qualified_name = xstrprintf ("%s!%s", dll_name, bare_name); 1735796c8dcSSimon Schubert 174*ef5ccd6cSJohn Marino if ((section_data->ms_type == mst_unknown) && debug_coff_pe_read) 175*ef5ccd6cSJohn Marino fprintf_unfiltered (gdb_stdlog , _("Unknown section type for \"%s\"" 176*ef5ccd6cSJohn Marino " for entry \"%s\" in dll \"%s\"\n"), 177*ef5ccd6cSJohn Marino section_data->section_name, sym_name, dll_name); 1785796c8dcSSimon Schubert 179*ef5ccd6cSJohn Marino prim_record_minimal_symbol (qualified_name, vma, 180*ef5ccd6cSJohn Marino section_data->ms_type, objfile); 1815796c8dcSSimon Schubert 1825796c8dcSSimon Schubert /* Enter the plain name as well, which might not be unique. */ 183*ef5ccd6cSJohn Marino prim_record_minimal_symbol (bare_name, vma, section_data->ms_type, objfile); 184*ef5ccd6cSJohn Marino if (debug_coff_pe_read > 1) 185*ef5ccd6cSJohn Marino fprintf_unfiltered (gdb_stdlog, _("Adding exported symbol \"%s\"" 186*ef5ccd6cSJohn Marino " in dll \"%s\"\n"), sym_name, dll_name); 187*ef5ccd6cSJohn Marino xfree (qualified_name); 188*ef5ccd6cSJohn Marino xfree (bare_name); 1895796c8dcSSimon Schubert } 1905796c8dcSSimon Schubert 191*ef5ccd6cSJohn Marino /* Create a minimal symbol entry for an exported forward symbol. 192*ef5ccd6cSJohn Marino Return 1 if the forwarded function was found 0 otherwise. 193*ef5ccd6cSJohn Marino SYM_NAME contains the exported name or NULL if exported by ordinal, 194*ef5ccd6cSJohn Marino FORWARD_DLL_NAME is the name of the DLL in which the target symobl resides, 195*ef5ccd6cSJohn Marino FORWARD_FUNC_NAME is the name of the target symbol in that DLL, 196*ef5ccd6cSJohn Marino ORDINAL is the ordinal index value of the symbol, 197*ef5ccd6cSJohn Marino DLL_NAME is the internal name of the DLL file, 198*ef5ccd6cSJohn Marino OBJFILE is the objfile struct of DLL_NAME. */ 199*ef5ccd6cSJohn Marino 200*ef5ccd6cSJohn Marino static int 201*ef5ccd6cSJohn Marino add_pe_forwarded_sym (const char *sym_name, const char *forward_dll_name, 202*ef5ccd6cSJohn Marino const char *forward_func_name, int ordinal, 203*ef5ccd6cSJohn Marino const char *dll_name, struct objfile *objfile) 204*ef5ccd6cSJohn Marino { 205*ef5ccd6cSJohn Marino CORE_ADDR vma; 206*ef5ccd6cSJohn Marino struct objfile *forward_objfile; 207*ef5ccd6cSJohn Marino struct minimal_symbol *msymbol; 208*ef5ccd6cSJohn Marino short section; 209*ef5ccd6cSJohn Marino enum minimal_symbol_type msymtype; 210*ef5ccd6cSJohn Marino int dll_name_len = strlen (dll_name); 211*ef5ccd6cSJohn Marino char *qualified_name, *bare_name; 212*ef5ccd6cSJohn Marino int forward_dll_name_len = strlen (forward_dll_name); 213*ef5ccd6cSJohn Marino int forward_func_name_len = strlen (forward_func_name); 214*ef5ccd6cSJohn Marino int forward_len = forward_dll_name_len + forward_func_name_len + 2; 215*ef5ccd6cSJohn Marino char *forward_qualified_name = alloca (forward_len); 216*ef5ccd6cSJohn Marino 217*ef5ccd6cSJohn Marino xsnprintf (forward_qualified_name, forward_len, "%s!%s", forward_dll_name, 218*ef5ccd6cSJohn Marino forward_func_name); 219*ef5ccd6cSJohn Marino 220*ef5ccd6cSJohn Marino 221*ef5ccd6cSJohn Marino msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name, 222*ef5ccd6cSJohn Marino &forward_objfile); 223*ef5ccd6cSJohn Marino 224*ef5ccd6cSJohn Marino if (!msymbol) 225*ef5ccd6cSJohn Marino { 226*ef5ccd6cSJohn Marino int i; 227*ef5ccd6cSJohn Marino 228*ef5ccd6cSJohn Marino for (i = 0; i < forward_dll_name_len; i++) 229*ef5ccd6cSJohn Marino forward_qualified_name[i] = tolower (forward_qualified_name[i]); 230*ef5ccd6cSJohn Marino msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name, 231*ef5ccd6cSJohn Marino &forward_objfile); 232*ef5ccd6cSJohn Marino } 233*ef5ccd6cSJohn Marino 234*ef5ccd6cSJohn Marino if (!msymbol) 235*ef5ccd6cSJohn Marino { 236*ef5ccd6cSJohn Marino if (debug_coff_pe_read) 237*ef5ccd6cSJohn Marino fprintf_unfiltered (gdb_stdlog, _("Unable to find function \"%s\" in" 238*ef5ccd6cSJohn Marino " dll \"%s\", forward of \"%s\" in dll \"%s\"\n"), 239*ef5ccd6cSJohn Marino forward_func_name, forward_dll_name, sym_name, 240*ef5ccd6cSJohn Marino dll_name); 241*ef5ccd6cSJohn Marino return 0; 242*ef5ccd6cSJohn Marino } 243*ef5ccd6cSJohn Marino 244*ef5ccd6cSJohn Marino if (debug_coff_pe_read > 1) 245*ef5ccd6cSJohn Marino fprintf_unfiltered (gdb_stdlog, _("Adding forwarded exported symbol" 246*ef5ccd6cSJohn Marino " \"%s\" in dll \"%s\", pointing to \"%s\"\n"), 247*ef5ccd6cSJohn Marino sym_name, dll_name, forward_qualified_name); 248*ef5ccd6cSJohn Marino 249*ef5ccd6cSJohn Marino vma = SYMBOL_VALUE_ADDRESS (msymbol); 250*ef5ccd6cSJohn Marino section = SYMBOL_SECTION (msymbol); 251*ef5ccd6cSJohn Marino msymtype = MSYMBOL_TYPE (msymbol); 252*ef5ccd6cSJohn Marino 253*ef5ccd6cSJohn Marino /* Generate a (hopefully unique) qualified name using the first part 254*ef5ccd6cSJohn Marino of the dll name, e.g. KERNEL32!AddAtomA. This matches the style 255*ef5ccd6cSJohn Marino used by windbg from the "Microsoft Debugging Tools for Windows". */ 256*ef5ccd6cSJohn Marino 257*ef5ccd6cSJohn Marino if (sym_name == NULL || *sym_name == '\0') 258*ef5ccd6cSJohn Marino bare_name = xstrprintf ("#%d", ordinal); 259*ef5ccd6cSJohn Marino else 260*ef5ccd6cSJohn Marino bare_name = xstrdup (sym_name); 261*ef5ccd6cSJohn Marino 262*ef5ccd6cSJohn Marino qualified_name = xstrprintf ("%s!%s", dll_name, bare_name); 263*ef5ccd6cSJohn Marino 264*ef5ccd6cSJohn Marino prim_record_minimal_symbol (qualified_name, vma, msymtype, objfile); 265*ef5ccd6cSJohn Marino 266*ef5ccd6cSJohn Marino /* Enter the plain name as well, which might not be unique. */ 267*ef5ccd6cSJohn Marino prim_record_minimal_symbol (bare_name, vma, msymtype, objfile); 268*ef5ccd6cSJohn Marino xfree (qualified_name); 269*ef5ccd6cSJohn Marino xfree (bare_name); 270*ef5ccd6cSJohn Marino 271*ef5ccd6cSJohn Marino return 1; 272*ef5ccd6cSJohn Marino } 273*ef5ccd6cSJohn Marino 274*ef5ccd6cSJohn Marino /* Truncate a dll_name at the last dot character. */ 2755796c8dcSSimon Schubert 2765796c8dcSSimon Schubert static void 2775796c8dcSSimon Schubert read_pe_truncate_name (char *dll_name) 2785796c8dcSSimon Schubert { 279*ef5ccd6cSJohn Marino char *last_point = strrchr (dll_name, '.'); 2805796c8dcSSimon Schubert 281*ef5ccd6cSJohn Marino if (last_point != NULL) 282*ef5ccd6cSJohn Marino *last_point = '\0'; 2835796c8dcSSimon Schubert } 2845796c8dcSSimon Schubert 2855796c8dcSSimon Schubert /* Low-level support functions, direct from the ld module pe-dll.c. */ 2865796c8dcSSimon Schubert static unsigned int 2875796c8dcSSimon Schubert pe_get16 (bfd *abfd, int where) 2885796c8dcSSimon Schubert { 2895796c8dcSSimon Schubert unsigned char b[2]; 2905796c8dcSSimon Schubert 2915796c8dcSSimon Schubert bfd_seek (abfd, (file_ptr) where, SEEK_SET); 2925796c8dcSSimon Schubert bfd_bread (b, (bfd_size_type) 2, abfd); 2935796c8dcSSimon Schubert return b[0] + (b[1] << 8); 2945796c8dcSSimon Schubert } 2955796c8dcSSimon Schubert 2965796c8dcSSimon Schubert static unsigned int 2975796c8dcSSimon Schubert pe_get32 (bfd *abfd, int where) 2985796c8dcSSimon Schubert { 2995796c8dcSSimon Schubert unsigned char b[4]; 3005796c8dcSSimon Schubert 3015796c8dcSSimon Schubert bfd_seek (abfd, (file_ptr) where, SEEK_SET); 3025796c8dcSSimon Schubert bfd_bread (b, (bfd_size_type) 4, abfd); 3035796c8dcSSimon Schubert return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24); 3045796c8dcSSimon Schubert } 3055796c8dcSSimon Schubert 3065796c8dcSSimon Schubert static unsigned int 307*ef5ccd6cSJohn Marino pe_as16 (void *ptr) 308*ef5ccd6cSJohn Marino { 309*ef5ccd6cSJohn Marino unsigned char *b = ptr; 310*ef5ccd6cSJohn Marino 311*ef5ccd6cSJohn Marino return b[0] + (b[1] << 8); 312*ef5ccd6cSJohn Marino } 313*ef5ccd6cSJohn Marino 314*ef5ccd6cSJohn Marino static unsigned int 3155796c8dcSSimon Schubert pe_as32 (void *ptr) 3165796c8dcSSimon Schubert { 3175796c8dcSSimon Schubert unsigned char *b = ptr; 3185796c8dcSSimon Schubert 3195796c8dcSSimon Schubert return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24); 3205796c8dcSSimon Schubert } 3215796c8dcSSimon Schubert 3225796c8dcSSimon Schubert /* Read the (non-debug) export symbol table from a portable 3235796c8dcSSimon Schubert executable. Code originally lifted from the ld function 3245796c8dcSSimon Schubert pe_implied_import_dll in pe-dll.c. */ 3255796c8dcSSimon Schubert 3265796c8dcSSimon Schubert void 3275796c8dcSSimon Schubert read_pe_exported_syms (struct objfile *objfile) 3285796c8dcSSimon Schubert { 3295796c8dcSSimon Schubert bfd *dll = objfile->obfd; 330*ef5ccd6cSJohn Marino unsigned long nbnormal, nbforward; 3315796c8dcSSimon Schubert unsigned long pe_header_offset, opthdr_ofs, num_entries, i; 332*ef5ccd6cSJohn Marino unsigned long export_opthdrrva, export_opthdrsize; 3335796c8dcSSimon Schubert unsigned long export_rva, export_size, nsections, secptr, expptr; 3345796c8dcSSimon Schubert unsigned long exp_funcbase; 3355796c8dcSSimon Schubert unsigned char *expdata, *erva; 3365796c8dcSSimon Schubert unsigned long name_rvas, ordinals, nexp, ordbase; 337*ef5ccd6cSJohn Marino char *dll_name = (char *) dll->filename; 338*ef5ccd6cSJohn Marino int otherix = PE_SECTION_TABLE_SIZE; 339*ef5ccd6cSJohn Marino int exportix = -1; 3405796c8dcSSimon Schubert int is_pe64 = 0; 3415796c8dcSSimon Schubert int is_pe32 = 0; 3425796c8dcSSimon Schubert 3435796c8dcSSimon Schubert /* Array elements are for text, data and bss in that order 344*ef5ccd6cSJohn Marino Initialization with RVA_START > RVA_END guarantees that 3455796c8dcSSimon Schubert unused sections won't be matched. */ 346*ef5ccd6cSJohn Marino struct read_pe_section_data *section_data; 347*ef5ccd6cSJohn Marino struct pe_sections_info pe_sections_info; 3485796c8dcSSimon Schubert 349*ef5ccd6cSJohn Marino struct cleanup *back_to = make_cleanup (null_cleanup, 0); 3505796c8dcSSimon Schubert 3515796c8dcSSimon Schubert char const *target = bfd_get_target (objfile->obfd); 3525796c8dcSSimon Schubert 353*ef5ccd6cSJohn Marino section_data = xzalloc (PE_SECTION_TABLE_SIZE 354*ef5ccd6cSJohn Marino * sizeof (struct read_pe_section_data)); 355*ef5ccd6cSJohn Marino 356*ef5ccd6cSJohn Marino make_cleanup (free_current_contents, §ion_data); 357*ef5ccd6cSJohn Marino 358*ef5ccd6cSJohn Marino for (i=0; i < PE_SECTION_TABLE_SIZE; i++) 359*ef5ccd6cSJohn Marino { 360*ef5ccd6cSJohn Marino section_data[i].vma_offset = 0; 361*ef5ccd6cSJohn Marino section_data[i].rva_start = 1; 362*ef5ccd6cSJohn Marino section_data[i].rva_end = 0; 363*ef5ccd6cSJohn Marino }; 364*ef5ccd6cSJohn Marino section_data[PE_SECTION_INDEX_TEXT].ms_type = mst_text; 365*ef5ccd6cSJohn Marino section_data[PE_SECTION_INDEX_TEXT].section_name = ".text"; 366*ef5ccd6cSJohn Marino section_data[PE_SECTION_INDEX_DATA].ms_type = mst_data; 367*ef5ccd6cSJohn Marino section_data[PE_SECTION_INDEX_DATA].section_name = ".data"; 368*ef5ccd6cSJohn Marino section_data[PE_SECTION_INDEX_BSS].ms_type = mst_bss; 369*ef5ccd6cSJohn Marino section_data[PE_SECTION_INDEX_BSS].section_name = ".bss"; 370*ef5ccd6cSJohn Marino 3715796c8dcSSimon Schubert is_pe64 = (strcmp (target, "pe-x86-64") == 0 3725796c8dcSSimon Schubert || strcmp (target, "pei-x86-64") == 0); 3735796c8dcSSimon Schubert is_pe32 = (strcmp (target, "pe-i386") == 0 3745796c8dcSSimon Schubert || strcmp (target, "pei-i386") == 0 3755796c8dcSSimon Schubert || strcmp (target, "pe-arm-wince-little") == 0 3765796c8dcSSimon Schubert || strcmp (target, "pei-arm-wince-little") == 0); 3775796c8dcSSimon Schubert if (!is_pe32 && !is_pe64) 3785796c8dcSSimon Schubert { 3795796c8dcSSimon Schubert /* This is not a recognized PE format file. Abort now, because 3805796c8dcSSimon Schubert the code is untested on anything else. *FIXME* test on 3815796c8dcSSimon Schubert further architectures and loosen or remove this test. */ 382*ef5ccd6cSJohn Marino do_cleanups (back_to); 3835796c8dcSSimon Schubert return; 3845796c8dcSSimon Schubert } 3855796c8dcSSimon Schubert 3865796c8dcSSimon Schubert /* Get pe_header, optional header and numbers of export entries. */ 3875796c8dcSSimon Schubert pe_header_offset = pe_get32 (dll, 0x3c); 3885796c8dcSSimon Schubert opthdr_ofs = pe_header_offset + 4 + 20; 3895796c8dcSSimon Schubert if (is_pe64) 3905796c8dcSSimon Schubert num_entries = pe_get32 (dll, opthdr_ofs + 108); 3915796c8dcSSimon Schubert else 3925796c8dcSSimon Schubert num_entries = pe_get32 (dll, opthdr_ofs + 92); 3935796c8dcSSimon Schubert 3945796c8dcSSimon Schubert if (num_entries < 1) /* No exports. */ 3955796c8dcSSimon Schubert { 396*ef5ccd6cSJohn Marino do_cleanups (back_to); 3975796c8dcSSimon Schubert return; 3985796c8dcSSimon Schubert } 3995796c8dcSSimon Schubert if (is_pe64) 4005796c8dcSSimon Schubert { 401*ef5ccd6cSJohn Marino export_opthdrrva = pe_get32 (dll, opthdr_ofs + 112); 402*ef5ccd6cSJohn Marino export_opthdrsize = pe_get32 (dll, opthdr_ofs + 116); 4035796c8dcSSimon Schubert } 4045796c8dcSSimon Schubert else 4055796c8dcSSimon Schubert { 406*ef5ccd6cSJohn Marino export_opthdrrva = pe_get32 (dll, opthdr_ofs + 96); 407*ef5ccd6cSJohn Marino export_opthdrsize = pe_get32 (dll, opthdr_ofs + 100); 4085796c8dcSSimon Schubert } 4095796c8dcSSimon Schubert nsections = pe_get16 (dll, pe_header_offset + 4 + 2); 4105796c8dcSSimon Schubert secptr = (pe_header_offset + 4 + 20 + 4115796c8dcSSimon Schubert pe_get16 (dll, pe_header_offset + 4 + 16)); 4125796c8dcSSimon Schubert expptr = 0; 413*ef5ccd6cSJohn Marino export_size = 0; 4145796c8dcSSimon Schubert 4155796c8dcSSimon Schubert /* Get the rva and size of the export section. */ 4165796c8dcSSimon Schubert for (i = 0; i < nsections; i++) 4175796c8dcSSimon Schubert { 4185796c8dcSSimon Schubert char sname[8]; 4195796c8dcSSimon Schubert unsigned long secptr1 = secptr + 40 * i; 4205796c8dcSSimon Schubert unsigned long vaddr = pe_get32 (dll, secptr1 + 12); 4215796c8dcSSimon Schubert unsigned long vsize = pe_get32 (dll, secptr1 + 16); 4225796c8dcSSimon Schubert unsigned long fptr = pe_get32 (dll, secptr1 + 20); 4235796c8dcSSimon Schubert 4245796c8dcSSimon Schubert bfd_seek (dll, (file_ptr) secptr1, SEEK_SET); 425*ef5ccd6cSJohn Marino bfd_bread (sname, (bfd_size_type) sizeof (sname), dll); 4265796c8dcSSimon Schubert 427*ef5ccd6cSJohn Marino if ((strcmp (sname, ".edata") == 0) 428*ef5ccd6cSJohn Marino || (vaddr <= export_opthdrrva && export_opthdrrva < vaddr + vsize)) 4295796c8dcSSimon Schubert { 430*ef5ccd6cSJohn Marino if (strcmp (sname, ".edata") != 0) 431*ef5ccd6cSJohn Marino { 432*ef5ccd6cSJohn Marino if (debug_coff_pe_read) 433*ef5ccd6cSJohn Marino fprintf_unfiltered (gdb_stdlog, _("Export RVA for dll " 434*ef5ccd6cSJohn Marino "\"%s\" is in section \"%s\"\n"), 435*ef5ccd6cSJohn Marino dll_name, sname); 436*ef5ccd6cSJohn Marino } 437*ef5ccd6cSJohn Marino else if (export_opthdrrva != vaddr && debug_coff_pe_read) 438*ef5ccd6cSJohn Marino fprintf_unfiltered (gdb_stdlog, _("Wrong value of export RVA" 439*ef5ccd6cSJohn Marino " for dll \"%s\": 0x%lx instead of 0x%lx\n"), 440*ef5ccd6cSJohn Marino dll_name, export_opthdrrva, vaddr); 441*ef5ccd6cSJohn Marino expptr = fptr + (export_opthdrrva - vaddr); 442*ef5ccd6cSJohn Marino exportix = i; 4435796c8dcSSimon Schubert break; 4445796c8dcSSimon Schubert } 4455796c8dcSSimon Schubert } 4465796c8dcSSimon Schubert 447*ef5ccd6cSJohn Marino export_rva = export_opthdrrva; 448*ef5ccd6cSJohn Marino export_size = export_opthdrsize; 449*ef5ccd6cSJohn Marino 4505796c8dcSSimon Schubert if (export_size == 0) 4515796c8dcSSimon Schubert { 4525796c8dcSSimon Schubert /* Empty export table. */ 453*ef5ccd6cSJohn Marino do_cleanups (back_to); 4545796c8dcSSimon Schubert return; 4555796c8dcSSimon Schubert } 4565796c8dcSSimon Schubert 457c50c785cSJohn Marino /* Scan sections and store the base and size of the relevant 458c50c785cSJohn Marino sections. */ 4595796c8dcSSimon Schubert for (i = 0; i < nsections; i++) 4605796c8dcSSimon Schubert { 4615796c8dcSSimon Schubert unsigned long secptr1 = secptr + 40 * i; 4625796c8dcSSimon Schubert unsigned long vsize = pe_get32 (dll, secptr1 + 8); 4635796c8dcSSimon Schubert unsigned long vaddr = pe_get32 (dll, secptr1 + 12); 464*ef5ccd6cSJohn Marino unsigned long characteristics = pe_get32 (dll, secptr1 + 36); 465*ef5ccd6cSJohn Marino char sec_name[SCNNMLEN + 1]; 4665796c8dcSSimon Schubert int sectix; 4675796c8dcSSimon Schubert 4685796c8dcSSimon Schubert bfd_seek (dll, (file_ptr) secptr1 + 0, SEEK_SET); 469*ef5ccd6cSJohn Marino bfd_bread (sec_name, (bfd_size_type) SCNNMLEN, dll); 470*ef5ccd6cSJohn Marino sec_name[SCNNMLEN] = '\0'; 4715796c8dcSSimon Schubert 4725796c8dcSSimon Schubert sectix = read_pe_section_index (sec_name); 4735796c8dcSSimon Schubert 4745796c8dcSSimon Schubert if (sectix != PE_SECTION_INDEX_INVALID) 4755796c8dcSSimon Schubert { 4765796c8dcSSimon Schubert section_data[sectix].rva_start = vaddr; 4775796c8dcSSimon Schubert section_data[sectix].rva_end = vaddr + vsize; 4785796c8dcSSimon Schubert } 479*ef5ccd6cSJohn Marino else 480*ef5ccd6cSJohn Marino { 481*ef5ccd6cSJohn Marino char *name; 482*ef5ccd6cSJohn Marino 483*ef5ccd6cSJohn Marino section_data = xrealloc (section_data, (otherix + 1) 484*ef5ccd6cSJohn Marino * sizeof (struct read_pe_section_data)); 485*ef5ccd6cSJohn Marino name = xstrdup (sec_name); 486*ef5ccd6cSJohn Marino section_data[otherix].section_name = name; 487*ef5ccd6cSJohn Marino make_cleanup (xfree, name); 488*ef5ccd6cSJohn Marino section_data[otherix].rva_start = vaddr; 489*ef5ccd6cSJohn Marino section_data[otherix].rva_end = vaddr + vsize; 490*ef5ccd6cSJohn Marino section_data[otherix].vma_offset = 0; 491*ef5ccd6cSJohn Marino if (characteristics & IMAGE_SCN_CNT_CODE) 492*ef5ccd6cSJohn Marino section_data[otherix].ms_type = mst_text; 493*ef5ccd6cSJohn Marino else if (characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) 494*ef5ccd6cSJohn Marino section_data[otherix].ms_type = mst_data; 495*ef5ccd6cSJohn Marino else if (characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) 496*ef5ccd6cSJohn Marino section_data[otherix].ms_type = mst_bss; 497*ef5ccd6cSJohn Marino else 498*ef5ccd6cSJohn Marino section_data[otherix].ms_type = mst_unknown; 499*ef5ccd6cSJohn Marino otherix++; 500*ef5ccd6cSJohn Marino } 5015796c8dcSSimon Schubert } 5025796c8dcSSimon Schubert 5035796c8dcSSimon Schubert expdata = (unsigned char *) xmalloc (export_size); 504*ef5ccd6cSJohn Marino make_cleanup (xfree, expdata); 5055796c8dcSSimon Schubert 5065796c8dcSSimon Schubert bfd_seek (dll, (file_ptr) expptr, SEEK_SET); 5075796c8dcSSimon Schubert bfd_bread (expdata, (bfd_size_type) export_size, dll); 5085796c8dcSSimon Schubert erva = expdata - export_rva; 5095796c8dcSSimon Schubert 5105796c8dcSSimon Schubert nexp = pe_as32 (expdata + 24); 5115796c8dcSSimon Schubert name_rvas = pe_as32 (expdata + 32); 5125796c8dcSSimon Schubert ordinals = pe_as32 (expdata + 36); 5135796c8dcSSimon Schubert ordbase = pe_as32 (expdata + 16); 5145796c8dcSSimon Schubert exp_funcbase = pe_as32 (expdata + 28); 5155796c8dcSSimon Schubert 5165796c8dcSSimon Schubert /* Use internal dll name instead of full pathname. */ 5175796c8dcSSimon Schubert dll_name = pe_as32 (expdata + 12) + erva; 5185796c8dcSSimon Schubert 519*ef5ccd6cSJohn Marino pe_sections_info.nb_sections = otherix; 520*ef5ccd6cSJohn Marino pe_sections_info.sections = section_data; 521*ef5ccd6cSJohn Marino 522*ef5ccd6cSJohn Marino bfd_map_over_sections (dll, get_section_vmas, &pe_sections_info); 5235796c8dcSSimon Schubert 5245796c8dcSSimon Schubert /* Adjust the vma_offsets in case this PE got relocated. This 5255796c8dcSSimon Schubert assumes that *all* sections share the same relocation offset 5265796c8dcSSimon Schubert as the text section. */ 527*ef5ccd6cSJohn Marino for (i = 0; i < otherix; i++) 5285796c8dcSSimon Schubert { 5295796c8dcSSimon Schubert section_data[i].vma_offset 5305796c8dcSSimon Schubert += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); 5315796c8dcSSimon Schubert } 5325796c8dcSSimon Schubert 5335796c8dcSSimon Schubert /* Truncate name at first dot. Should maybe also convert to all 5345796c8dcSSimon Schubert lower case for convenience on Windows. */ 5355796c8dcSSimon Schubert read_pe_truncate_name (dll_name); 5365796c8dcSSimon Schubert 537*ef5ccd6cSJohn Marino if (debug_coff_pe_read) 538*ef5ccd6cSJohn Marino fprintf_unfiltered (gdb_stdlog, _("DLL \"%s\" has %ld export entries," 539*ef5ccd6cSJohn Marino " base=%ld\n"), dll_name, nexp, ordbase); 540*ef5ccd6cSJohn Marino nbforward = 0; 541*ef5ccd6cSJohn Marino nbnormal = 0; 5425796c8dcSSimon Schubert /* Iterate through the list of symbols. */ 5435796c8dcSSimon Schubert for (i = 0; i < nexp; i++) 5445796c8dcSSimon Schubert { 5455796c8dcSSimon Schubert /* Pointer to the names vector. */ 5465796c8dcSSimon Schubert unsigned long name_rva = pe_as32 (erva + name_rvas + i * 4); 547*ef5ccd6cSJohn Marino /* Retrieve ordinal value. */ 548*ef5ccd6cSJohn Marino 549*ef5ccd6cSJohn Marino unsigned long ordinal = pe_as16 (erva + ordinals + i * 2); 550*ef5ccd6cSJohn Marino 5515796c8dcSSimon Schubert 5525796c8dcSSimon Schubert /* Pointer to the function address vector. */ 553*ef5ccd6cSJohn Marino /* This is relatived to ordinal value. */ 554*ef5ccd6cSJohn Marino unsigned long func_rva = pe_as32 (erva + exp_funcbase + 555*ef5ccd6cSJohn Marino ordinal * 4); 5565796c8dcSSimon Schubert 5575796c8dcSSimon Schubert /* Find this symbol's section in our own array. */ 5585796c8dcSSimon Schubert int sectix = 0; 559*ef5ccd6cSJohn Marino int section_found = 0; 5605796c8dcSSimon Schubert 561*ef5ccd6cSJohn Marino /* First handle forward cases. */ 562*ef5ccd6cSJohn Marino if (func_rva >= export_rva && func_rva < export_rva + export_size) 563*ef5ccd6cSJohn Marino { 564*ef5ccd6cSJohn Marino char *forward_name = (char *) (erva + func_rva); 565*ef5ccd6cSJohn Marino char *funcname = (char *) (erva + name_rva); 566*ef5ccd6cSJohn Marino char *forward_dll_name = forward_name; 567*ef5ccd6cSJohn Marino char *forward_func_name = forward_name; 568*ef5ccd6cSJohn Marino char *sep = strrchr (forward_name, '.'); 569*ef5ccd6cSJohn Marino 570*ef5ccd6cSJohn Marino if (sep) 571*ef5ccd6cSJohn Marino { 572*ef5ccd6cSJohn Marino int len = (int) (sep - forward_name); 573*ef5ccd6cSJohn Marino 574*ef5ccd6cSJohn Marino forward_dll_name = alloca (len + 1); 575*ef5ccd6cSJohn Marino strncpy (forward_dll_name, forward_name, len); 576*ef5ccd6cSJohn Marino forward_dll_name[len] = '\0'; 577*ef5ccd6cSJohn Marino forward_func_name = ++sep; 578*ef5ccd6cSJohn Marino } 579*ef5ccd6cSJohn Marino if (add_pe_forwarded_sym (funcname, forward_dll_name, 580*ef5ccd6cSJohn Marino forward_func_name, ordinal, 581*ef5ccd6cSJohn Marino dll_name, objfile) != 0) 582*ef5ccd6cSJohn Marino ++nbforward; 583*ef5ccd6cSJohn Marino continue; 584*ef5ccd6cSJohn Marino } 585*ef5ccd6cSJohn Marino 586*ef5ccd6cSJohn Marino for (sectix = 0; sectix < otherix; ++sectix) 5875796c8dcSSimon Schubert { 5885796c8dcSSimon Schubert if ((func_rva >= section_data[sectix].rva_start) 5895796c8dcSSimon Schubert && (func_rva < section_data[sectix].rva_end)) 5905796c8dcSSimon Schubert { 591*ef5ccd6cSJohn Marino section_found = 1; 5925796c8dcSSimon Schubert add_pe_exported_sym (erva + name_rva, 593*ef5ccd6cSJohn Marino func_rva, ordinal, 5945796c8dcSSimon Schubert section_data + sectix, dll_name, objfile); 595*ef5ccd6cSJohn Marino ++nbnormal; 5965796c8dcSSimon Schubert break; 5975796c8dcSSimon Schubert } 5985796c8dcSSimon Schubert } 599*ef5ccd6cSJohn Marino if (!section_found) 600*ef5ccd6cSJohn Marino { 601*ef5ccd6cSJohn Marino char *funcname = (char *) (erva + name_rva); 602*ef5ccd6cSJohn Marino 603*ef5ccd6cSJohn Marino if (name_rva == 0) 604*ef5ccd6cSJohn Marino { 605*ef5ccd6cSJohn Marino add_pe_exported_sym (NULL, func_rva, ordinal, 606*ef5ccd6cSJohn Marino section_data, dll_name, objfile); 607*ef5ccd6cSJohn Marino ++nbnormal; 608*ef5ccd6cSJohn Marino } 609*ef5ccd6cSJohn Marino else if (debug_coff_pe_read) 610*ef5ccd6cSJohn Marino fprintf_unfiltered (gdb_stdlog, _("Export name \"%s\" ord. %lu," 611*ef5ccd6cSJohn Marino " RVA 0x%lx in dll \"%s\" not handled\n"), 612*ef5ccd6cSJohn Marino funcname, ordinal, func_rva, dll_name); 613*ef5ccd6cSJohn Marino } 6145796c8dcSSimon Schubert } 6155796c8dcSSimon Schubert 616*ef5ccd6cSJohn Marino if (debug_coff_pe_read) 617*ef5ccd6cSJohn Marino fprintf_unfiltered (gdb_stdlog, _("Finished reading \"%s\", exports %ld," 618*ef5ccd6cSJohn Marino " forwards %ld, total %ld/%ld.\n"), dll_name, nbnormal, 619*ef5ccd6cSJohn Marino nbforward, nbnormal + nbforward, nexp); 620*ef5ccd6cSJohn Marino /* Discard expdata and section_data. */ 6215796c8dcSSimon Schubert do_cleanups (back_to); 6225796c8dcSSimon Schubert } 623*ef5ccd6cSJohn Marino 624*ef5ccd6cSJohn Marino /* Extract from ABFD the offset of the .text section. 625*ef5ccd6cSJohn Marino This offset is mainly related to the offset within the file. 626*ef5ccd6cSJohn Marino The value was previously expected to be 0x1000 for all files, 627*ef5ccd6cSJohn Marino but some Windows OS core DLLs seem to use 0x10000 section alignement 628*ef5ccd6cSJohn Marino which modified the return value of that function. 629*ef5ccd6cSJohn Marino Still return default 0x1000 value if ABFD is NULL or 630*ef5ccd6cSJohn Marino if '.text' section is not found, but that should not happen... */ 631*ef5ccd6cSJohn Marino 632*ef5ccd6cSJohn Marino #define DEFAULT_COFF_PE_TEXT_SECTION_OFFSET 0x1000 633*ef5ccd6cSJohn Marino 634*ef5ccd6cSJohn Marino CORE_ADDR 635*ef5ccd6cSJohn Marino pe_text_section_offset (struct bfd *abfd) 636*ef5ccd6cSJohn Marino 637*ef5ccd6cSJohn Marino { 638*ef5ccd6cSJohn Marino unsigned long pe_header_offset, opthdr_ofs, num_entries, i; 639*ef5ccd6cSJohn Marino unsigned long export_rva, export_size, nsections, secptr, expptr; 640*ef5ccd6cSJohn Marino unsigned long exp_funcbase; 641*ef5ccd6cSJohn Marino unsigned char *expdata, *erva; 642*ef5ccd6cSJohn Marino unsigned long name_rvas, ordinals, nexp, ordbase; 643*ef5ccd6cSJohn Marino char *dll_name; 644*ef5ccd6cSJohn Marino int is_pe64 = 0; 645*ef5ccd6cSJohn Marino int is_pe32 = 0; 646*ef5ccd6cSJohn Marino char const *target; 647*ef5ccd6cSJohn Marino 648*ef5ccd6cSJohn Marino if (!abfd) 649*ef5ccd6cSJohn Marino return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET; 650*ef5ccd6cSJohn Marino 651*ef5ccd6cSJohn Marino target = bfd_get_target (abfd); 652*ef5ccd6cSJohn Marino 653*ef5ccd6cSJohn Marino is_pe64 = (strcmp (target, "pe-x86-64") == 0 654*ef5ccd6cSJohn Marino || strcmp (target, "pei-x86-64") == 0); 655*ef5ccd6cSJohn Marino is_pe32 = (strcmp (target, "pe-i386") == 0 656*ef5ccd6cSJohn Marino || strcmp (target, "pei-i386") == 0 657*ef5ccd6cSJohn Marino || strcmp (target, "pe-arm-wince-little") == 0 658*ef5ccd6cSJohn Marino || strcmp (target, "pei-arm-wince-little") == 0); 659*ef5ccd6cSJohn Marino 660*ef5ccd6cSJohn Marino if (!is_pe32 && !is_pe64) 661*ef5ccd6cSJohn Marino { 662*ef5ccd6cSJohn Marino /* This is not a recognized PE format file. Abort now, because 663*ef5ccd6cSJohn Marino the code is untested on anything else. *FIXME* test on 664*ef5ccd6cSJohn Marino further architectures and loosen or remove this test. */ 665*ef5ccd6cSJohn Marino return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET; 666*ef5ccd6cSJohn Marino } 667*ef5ccd6cSJohn Marino 668*ef5ccd6cSJohn Marino /* Get pe_header, optional header and numbers of sections. */ 669*ef5ccd6cSJohn Marino pe_header_offset = pe_get32 (abfd, 0x3c); 670*ef5ccd6cSJohn Marino opthdr_ofs = pe_header_offset + 4 + 20; 671*ef5ccd6cSJohn Marino nsections = pe_get16 (abfd, pe_header_offset + 4 + 2); 672*ef5ccd6cSJohn Marino secptr = (pe_header_offset + 4 + 20 + 673*ef5ccd6cSJohn Marino pe_get16 (abfd, pe_header_offset + 4 + 16)); 674*ef5ccd6cSJohn Marino 675*ef5ccd6cSJohn Marino /* Get the rva and size of the export section. */ 676*ef5ccd6cSJohn Marino for (i = 0; i < nsections; i++) 677*ef5ccd6cSJohn Marino { 678*ef5ccd6cSJohn Marino char sname[SCNNMLEN + 1]; 679*ef5ccd6cSJohn Marino unsigned long secptr1 = secptr + 40 * i; 680*ef5ccd6cSJohn Marino unsigned long vaddr = pe_get32 (abfd, secptr1 + 12); 681*ef5ccd6cSJohn Marino 682*ef5ccd6cSJohn Marino bfd_seek (abfd, (file_ptr) secptr1, SEEK_SET); 683*ef5ccd6cSJohn Marino bfd_bread (sname, (bfd_size_type) SCNNMLEN, abfd); 684*ef5ccd6cSJohn Marino sname[SCNNMLEN] = '\0'; 685*ef5ccd6cSJohn Marino if (strcmp (sname, ".text") == 0) 686*ef5ccd6cSJohn Marino return vaddr; 687*ef5ccd6cSJohn Marino } 688*ef5ccd6cSJohn Marino 689*ef5ccd6cSJohn Marino return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET; 690*ef5ccd6cSJohn Marino } 691*ef5ccd6cSJohn Marino 692*ef5ccd6cSJohn Marino /* Implements "show debug coff_pe_read" command. */ 693*ef5ccd6cSJohn Marino 694*ef5ccd6cSJohn Marino static void 695*ef5ccd6cSJohn Marino show_debug_coff_pe_read (struct ui_file *file, int from_tty, 696*ef5ccd6cSJohn Marino struct cmd_list_element *c, const char *value) 697*ef5ccd6cSJohn Marino { 698*ef5ccd6cSJohn Marino fprintf_filtered (file, _("Coff PE read debugging is %s.\n"), value); 699*ef5ccd6cSJohn Marino } 700*ef5ccd6cSJohn Marino 701*ef5ccd6cSJohn Marino /* Provide a prototype to silence -Wmissing-prototypes. */ 702*ef5ccd6cSJohn Marino 703*ef5ccd6cSJohn Marino void _initialize_coff_pe_read (void); 704*ef5ccd6cSJohn Marino 705*ef5ccd6cSJohn Marino /* Adds "Set/show debug coff_pe_read" commands. */ 706*ef5ccd6cSJohn Marino 707*ef5ccd6cSJohn Marino void 708*ef5ccd6cSJohn Marino _initialize_coff_pe_read (void) 709*ef5ccd6cSJohn Marino { 710*ef5ccd6cSJohn Marino add_setshow_zuinteger_cmd ("coff-pe-read", class_maintenance, 711*ef5ccd6cSJohn Marino &debug_coff_pe_read, 712*ef5ccd6cSJohn Marino _("Set coff PE read debugging."), 713*ef5ccd6cSJohn Marino _("Show coff PE read debugging."), 714*ef5ccd6cSJohn Marino _("When set, debugging messages for coff reading " 715*ef5ccd6cSJohn Marino "of exported symbols are displayed."), 716*ef5ccd6cSJohn Marino NULL, show_debug_coff_pe_read, 717*ef5ccd6cSJohn Marino &setdebuglist, &showdebuglist); 718*ef5ccd6cSJohn Marino } 719