X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Famd64-windows-tdep.c;h=487dfd45fc79250db041b1d92bb87b571e9a414c;hb=4445e8f59ac69e64e64c5f95882aa8172e4788f7;hp=4570622a17b1b303a1a6e951d6ea8ce4cf8d68ed;hpb=325fac504a327de9c46a4e5cf9c88ece9d9d7701;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c index 4570622a17..487dfd45fc 100644 --- a/gdb/amd64-windows-tdep.c +++ b/gdb/amd64-windows-tdep.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2009-2016 Free Software Foundation, Inc. +/* Copyright (C) 2009-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -18,6 +18,7 @@ #include "defs.h" #include "osabi.h" #include "amd64-tdep.h" +#include "gdbsupport/x86-xstate.h" #include "gdbtypes.h" #include "gdbcore.h" #include "regcache.h" @@ -47,7 +48,7 @@ static int amd64_windows_dummy_call_integer_regs[] = static int amd64_windows_passed_by_integer_register (struct type *type) { - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_INT: case TYPE_CODE_ENUM: @@ -56,6 +57,7 @@ amd64_windows_passed_by_integer_register (struct type *type) case TYPE_CODE_CHAR: case TYPE_CODE_PTR: case TYPE_CODE_REF: + case TYPE_CODE_RVALUE_REF: case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: return (TYPE_LENGTH (type) == 1 @@ -74,8 +76,8 @@ amd64_windows_passed_by_integer_register (struct type *type) static int amd64_windows_passed_by_xmm_register (struct type *type) { - return ((TYPE_CODE (type) == TYPE_CODE_FLT - || TYPE_CODE (type) == TYPE_CODE_DECFLOAT) + return ((type->code () == TYPE_CODE_FLT + || type->code () == TYPE_CODE_DECFLOAT) && (TYPE_LENGTH (type) == 4 || TYPE_LENGTH (type) == 8)); } @@ -142,8 +144,8 @@ amd64_windows_store_arg_in_reg (struct regcache *regcache, gdb_assert (TYPE_LENGTH (type) <= 8); memset (buf, 0, sizeof buf); - memcpy (buf, valbuf, std::min (TYPE_LENGTH (type), (unsigned int) 8)); - regcache_cooked_write (regcache, regno, buf); + memcpy (buf, valbuf, std::min (TYPE_LENGTH (type), (ULONGEST) 8)); + regcache->cooked_write (regno, buf); } /* Push the arguments for an inferior function call, and return @@ -155,7 +157,7 @@ amd64_windows_store_arg_in_reg (struct regcache *regcache, static CORE_ADDR amd64_windows_push_arguments (struct regcache *regcache, int nargs, struct value **args, CORE_ADDR sp, - int struct_return) + function_call_return_method return_method) { int reg_idx = 0; int i; @@ -178,7 +180,7 @@ amd64_windows_push_arguments (struct regcache *regcache, int nargs, } /* Reserve a register for the "hidden" argument. */ - if (struct_return) + if (return_method == return_method_struct) reg_idx++; for (i = 0; i < nargs; i++) @@ -242,25 +244,25 @@ static CORE_ADDR amd64_windows_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, - int nargs, struct value **args, - CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) + int nargs, struct value **args, CORE_ADDR sp, + function_call_return_method return_method, CORE_ADDR struct_addr) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte buf[8]; /* Pass arguments. */ sp = amd64_windows_push_arguments (regcache, nargs, args, sp, - struct_return); + return_method); /* Pass "hidden" argument". */ - if (struct_return) + if (return_method == return_method_struct) { /* The "hidden" argument is passed throught the first argument register. */ const int arg_regnum = amd64_windows_dummy_call_integer_regs[0]; store_unsigned_integer (buf, 8, byte_order, struct_addr); - regcache_cooked_write (regcache, arg_regnum, buf); + regcache->cooked_write (arg_regnum, buf); } /* Reserve some memory on the stack for the integer-parameter @@ -274,10 +276,10 @@ amd64_windows_push_dummy_call /* Update the stack pointer... */ store_unsigned_integer (buf, 8, byte_order, sp); - regcache_cooked_write (regcache, AMD64_RSP_REGNUM, buf); + regcache->cooked_write (AMD64_RSP_REGNUM, buf); /* ...and fake a frame pointer. */ - regcache_cooked_write (regcache, AMD64_RBP_REGNUM, buf); + regcache->cooked_write (AMD64_RBP_REGNUM, buf); return sp + 16; } @@ -294,7 +296,7 @@ amd64_windows_return_value (struct gdbarch *gdbarch, struct value *function, /* See if our value is returned through a register. If it is, then store the associated register number in REGNUM. */ - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_FLT: case TYPE_CODE_DECFLOAT: @@ -327,9 +329,9 @@ amd64_windows_return_value (struct gdbarch *gdbarch, struct value *function, { /* Extract the return value from the register where it was stored. */ if (readbuf) - regcache_raw_read_part (regcache, regnum, 0, len, readbuf); + regcache->raw_read_part (regnum, 0, len, readbuf); if (writebuf) - regcache_raw_write_part (regcache, regnum, 0, len, writebuf); + regcache->raw_write_part (regnum, 0, len, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; } } @@ -356,8 +358,8 @@ amd64_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order); s = lookup_minimal_symbol_by_pc (call_dest); if (s.minsym != NULL - && MSYMBOL_LINKAGE_NAME (s.minsym) != NULL - && strcmp (MSYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0) + && s.minsym->linkage_name () != NULL + && strcmp (s.minsym->linkage_name (), "__main") == 0) pc += 5; } } @@ -417,7 +419,7 @@ static const enum amd64_regnum amd64_windows_w2gdb_regnum[] = AMD64_R15_REGNUM }; -/* Return TRUE iff PC is the the range of the function corresponding to +/* Return TRUE iff PC is the range of the function corresponding to CACHE. */ static int @@ -951,8 +953,7 @@ amd64_windows_find_unwind_info (struct gdbarch *gdbarch, CORE_ADDR pc, pe = pe_data (sec->objfile->obfd); dir = &pe->pe_opthdr.DataDirectory[PE_EXCEPTION_TABLE]; - base = pe->pe_opthdr.ImageBase - + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + base = pe->pe_opthdr.ImageBase + objfile->text_section_offset (); *image_base = base; /* Find the entry. @@ -1185,7 +1186,7 @@ amd64_windows_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) = (indirect_addr ? lookup_minimal_symbol_by_pc (indirect_addr).minsym : NULL); - const char *symname = indsym ? MSYMBOL_LINKAGE_NAME (indsym) : NULL; + const char *symname = indsym ? indsym->linkage_name () : NULL; if (symname) { @@ -1207,12 +1208,14 @@ amd64_windows_auto_wide_charset (void) return "UTF-16"; } +/* Common parts for gdbarch initialization for Windows and Cygwin on AMD64. */ + static void -amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +amd64_windows_init_abi_common (gdbarch_info info, struct gdbarch *gdbarch) { /* The dwarf2 unwinder (appended very early by i386_gdbarch_init) is preferred over the SEH one. The reasons are: - - binaries without SEH but with dwarf2 debug info are correcly handled + - binaries without SEH but with dwarf2 debug info are correctly handled (although they aren't ABI compliant, gcc before 4.7 didn't emit SEH info). - dwarf3 DW_OP_call_frame_cfa is correctly handled (it can only be @@ -1223,12 +1226,8 @@ amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) */ frame_unwind_append_unwinder (gdbarch, &amd64_windows_frame_unwind); - amd64_init_abi (info, gdbarch); - - windows_init_abi (info, gdbarch); - - /* On Windows, "long"s are only 32bit. */ - set_gdbarch_long_bit (gdbarch, 32); + amd64_init_abi (info, gdbarch, + amd64_target_description (X86_XSTATE_SSE_MASK, false)); /* Function calls. */ set_gdbarch_push_dummy_call (gdbarch, amd64_windows_push_dummy_call); @@ -1242,12 +1241,50 @@ amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_auto_wide_charset (gdbarch, amd64_windows_auto_wide_charset); } -/* -Wmissing-prototypes */ -extern initialize_file_ftype _initialize_amd64_windows_tdep; +/* gdbarch initialization for Windows on AMD64. */ + +static void +amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + amd64_windows_init_abi_common (info, gdbarch); + windows_init_abi (info, gdbarch); + + /* On Windows, "long"s are only 32bit. */ + set_gdbarch_long_bit (gdbarch, 32); +} + +/* gdbarch initialization for Cygwin on AMD64. */ + +static void +amd64_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + amd64_windows_init_abi_common (info, gdbarch); + cygwin_init_abi (info, gdbarch); +} + +static gdb_osabi +amd64_windows_osabi_sniffer (bfd *abfd) +{ + const char *target_name = bfd_get_target (abfd); + if (!streq (target_name, "pei-x86-64")) + return GDB_OSABI_UNKNOWN; + + if (is_linked_with_cygwin_dll (abfd)) + return GDB_OSABI_CYGWIN; + + return GDB_OSABI_WINDOWS; +} + +void _initialize_amd64_windows_tdep (); void -_initialize_amd64_windows_tdep (void) +_initialize_amd64_windows_tdep () { - gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_CYGWIN, + gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_WINDOWS, amd64_windows_init_abi); + gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_CYGWIN, + amd64_cygwin_init_abi); + + gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour, + amd64_windows_osabi_sniffer); }