GDB (API)
|
00001 /* Target-dependent code for Cygwin running on i386's, for GDB. 00002 00003 Copyright (C) 2003-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "osabi.h" 00022 #include "gdb_string.h" 00023 #include "i386-tdep.h" 00024 #include "windows-tdep.h" 00025 #include "regset.h" 00026 #include "gdb_obstack.h" 00027 #include "xml-support.h" 00028 #include "gdbcore.h" 00029 #include "inferior.h" 00030 00031 /* Core file support. */ 00032 00033 /* This vector maps GDB's idea of a register's number into an address 00034 in the windows exception context vector. */ 00035 00036 static int i386_windows_gregset_reg_offset[] = 00037 { 00038 176, /* eax */ 00039 172, /* ecx */ 00040 168, /* edx */ 00041 164, /* ebx */ 00042 00043 196, /* esp */ 00044 180, /* ebp */ 00045 160, /* esi */ 00046 156, /* edi */ 00047 00048 184, /* eip */ 00049 192, /* eflags */ 00050 188, /* cs */ 00051 200, /* ss */ 00052 00053 152, /* ds */ 00054 148, /* es */ 00055 144, /* fs */ 00056 140, /* gs */ 00057 00058 56, /* FloatSave.RegisterArea[0 * 10] */ 00059 66, /* FloatSave.RegisterArea[1 * 10] */ 00060 76, /* FloatSave.RegisterArea[2 * 10] */ 00061 86, /* FloatSave.RegisterArea[3 * 10] */ 00062 96, /* FloatSave.RegisterArea[4 * 10] */ 00063 106, /* FloatSave.RegisterArea[5 * 10] */ 00064 116, /* FloatSave.RegisterArea[6 * 10] */ 00065 126, /* FloatSave.RegisterArea[7 * 10] */ 00066 00067 28, /* FloatSave.ControlWord */ 00068 32, /* FloatSave.StatusWord */ 00069 36, /* FloatSave.TagWord */ 00070 44, /* FloatSave.ErrorSelector */ 00071 40, /* FloatSave.ErrorOffset */ 00072 52, /* FloatSave.DataSelector */ 00073 48, /* FloatSave.DataOffset */ 00074 44, /* FloatSave.ErrorSelector */ 00075 00076 /* XMM0-7 */ 00077 364, /* ExtendedRegisters[10*16] */ 00078 380, /* ExtendedRegisters[11*16] */ 00079 396, /* ExtendedRegisters[12*16] */ 00080 412, /* ExtendedRegisters[13*16] */ 00081 428, /* ExtendedRegisters[14*16] */ 00082 444, /* ExtendedRegisters[15*16] */ 00083 460, /* ExtendedRegisters[16*16] */ 00084 476, /* ExtendedRegisters[17*16] */ 00085 00086 /* MXCSR */ 00087 228 /* ExtendedRegisters[24] */ 00088 }; 00089 00090 #define I386_WINDOWS_SIZEOF_GREGSET 716 00091 00092 /* Return the appropriate register set for the core section identified 00093 by SECT_NAME and SECT_SIZE. */ 00094 00095 static const struct regset * 00096 i386_windows_regset_from_core_section (struct gdbarch *gdbarch, 00097 const char *sect_name, size_t sect_size) 00098 { 00099 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00100 00101 if (strcmp (sect_name, ".reg") == 0 00102 && sect_size == I386_WINDOWS_SIZEOF_GREGSET) 00103 { 00104 if (tdep->gregset == NULL) 00105 tdep->gregset = regset_alloc (gdbarch, i386_supply_gregset, 00106 i386_collect_gregset); 00107 return tdep->gregset; 00108 } 00109 00110 return NULL; 00111 } 00112 00113 struct cpms_data 00114 { 00115 struct gdbarch *gdbarch; 00116 struct obstack *obstack; 00117 int module_count; 00118 }; 00119 00120 static void 00121 core_process_module_section (bfd *abfd, asection *sect, void *obj) 00122 { 00123 struct cpms_data *data = obj; 00124 enum bfd_endian byte_order = gdbarch_byte_order (data->gdbarch); 00125 00126 char *module_name; 00127 size_t module_name_size; 00128 CORE_ADDR base_addr; 00129 00130 gdb_byte *buf = NULL; 00131 00132 if (strncmp (sect->name, ".module", 7) != 0) 00133 return; 00134 00135 buf = xmalloc (bfd_get_section_size (sect) + 1); 00136 if (!buf) 00137 { 00138 printf_unfiltered ("memory allocation failed for %s\n", sect->name); 00139 goto out; 00140 } 00141 if (!bfd_get_section_contents (abfd, sect, 00142 buf, 0, bfd_get_section_size (sect))) 00143 goto out; 00144 00145 00146 00147 /* A DWORD (data_type) followed by struct windows_core_module_info. */ 00148 00149 base_addr = 00150 extract_unsigned_integer (buf + 4, 4, byte_order); 00151 00152 module_name_size = 00153 extract_unsigned_integer (buf + 8, 4, byte_order); 00154 00155 if (12 + module_name_size > bfd_get_section_size (sect)) 00156 goto out; 00157 module_name = (char *) buf + 12; 00158 00159 /* The first module is the .exe itself. */ 00160 if (data->module_count != 0) 00161 windows_xfer_shared_library (module_name, base_addr, 00162 data->gdbarch, data->obstack); 00163 data->module_count++; 00164 00165 out: 00166 if (buf) 00167 xfree (buf); 00168 return; 00169 } 00170 00171 static LONGEST 00172 windows_core_xfer_shared_libraries (struct gdbarch *gdbarch, 00173 gdb_byte *readbuf, 00174 ULONGEST offset, LONGEST len) 00175 { 00176 struct obstack obstack; 00177 const char *buf; 00178 LONGEST len_avail; 00179 struct cpms_data data = { gdbarch, &obstack, 0 }; 00180 00181 obstack_init (&obstack); 00182 obstack_grow_str (&obstack, "<library-list>\n"); 00183 bfd_map_over_sections (core_bfd, 00184 core_process_module_section, 00185 &data); 00186 obstack_grow_str0 (&obstack, "</library-list>\n"); 00187 00188 buf = obstack_finish (&obstack); 00189 len_avail = strlen (buf); 00190 if (offset >= len_avail) 00191 return 0; 00192 00193 if (len > len_avail - offset) 00194 len = len_avail - offset; 00195 memcpy (readbuf, buf + offset, len); 00196 00197 obstack_free (&obstack, NULL); 00198 return len; 00199 } 00200 00201 /* This is how we want PTIDs from core files to be printed. */ 00202 00203 static char * 00204 i386_windows_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid) 00205 { 00206 static char buf[80]; 00207 00208 if (ptid_get_lwp (ptid) != 0) 00209 { 00210 snprintf (buf, sizeof (buf), "Thread 0x%lx", ptid_get_lwp (ptid)); 00211 return buf; 00212 } 00213 00214 return normal_pid_to_str (ptid); 00215 } 00216 00217 static CORE_ADDR 00218 i386_cygwin_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) 00219 { 00220 return i386_pe_skip_trampoline_code (frame, pc, NULL); 00221 } 00222 00223 static const char * 00224 i386_cygwin_auto_wide_charset (void) 00225 { 00226 return "UTF-16"; 00227 } 00228 00229 static void 00230 i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 00231 { 00232 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00233 00234 windows_init_abi (info, gdbarch); 00235 00236 set_gdbarch_skip_trampoline_code (gdbarch, i386_cygwin_skip_trampoline_code); 00237 00238 set_gdbarch_skip_main_prologue (gdbarch, i386_skip_main_prologue); 00239 00240 tdep->struct_return = reg_struct_return; 00241 00242 tdep->gregset_reg_offset = i386_windows_gregset_reg_offset; 00243 tdep->gregset_num_regs = ARRAY_SIZE (i386_windows_gregset_reg_offset); 00244 tdep->sizeof_gregset = I386_WINDOWS_SIZEOF_GREGSET; 00245 00246 /* Core file support. */ 00247 set_gdbarch_regset_from_core_section 00248 (gdbarch, i386_windows_regset_from_core_section); 00249 set_gdbarch_core_xfer_shared_libraries 00250 (gdbarch, windows_core_xfer_shared_libraries); 00251 set_gdbarch_core_pid_to_str (gdbarch, i386_windows_core_pid_to_str); 00252 00253 set_gdbarch_auto_wide_charset (gdbarch, i386_cygwin_auto_wide_charset); 00254 } 00255 00256 static enum gdb_osabi 00257 i386_cygwin_osabi_sniffer (bfd *abfd) 00258 { 00259 char *target_name = bfd_get_target (abfd); 00260 00261 if (strcmp (target_name, "pei-i386") == 0) 00262 return GDB_OSABI_CYGWIN; 00263 00264 /* Cygwin uses elf core dumps. Do not claim all ELF executables, 00265 check whether there is a .reg section of proper size. */ 00266 if (strcmp (target_name, "elf32-i386") == 0) 00267 { 00268 asection *section = bfd_get_section_by_name (abfd, ".reg"); 00269 if (section 00270 && bfd_section_size (abfd, section) == I386_WINDOWS_SIZEOF_GREGSET) 00271 return GDB_OSABI_CYGWIN; 00272 } 00273 00274 return GDB_OSABI_UNKNOWN; 00275 } 00276 00277 /* Provide a prototype to silence -Wmissing-prototypes. */ 00278 void _initialize_i386_cygwin_tdep (void); 00279 00280 void 00281 _initialize_i386_cygwin_tdep (void) 00282 { 00283 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour, 00284 i386_cygwin_osabi_sniffer); 00285 00286 /* Cygwin uses elf core dumps. */ 00287 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour, 00288 i386_cygwin_osabi_sniffer); 00289 00290 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN, 00291 i386_cygwin_init_abi); 00292 }