X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Famd64-tdep.c;h=3e5d1bd8a7cdc62c87a0c77956500e162077b277;hb=4bd7dc42558fcf53bb0c783f852f03dcac38866f;hp=e69da0196ba0aae7c121f54408821515fb4290e1;hpb=43f3e411c415ac74130808a76473e05ff41a1d94;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index e69da0196b..3e5d1bd8a7 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for AMD64. - Copyright (C) 2001-2014 Free Software Foundation, Inc. + Copyright (C) 2001-2015 Free Software Foundation, Inc. Contributed by Jiri Smid, SuSE Labs. @@ -199,7 +199,13 @@ static int amd64_dwarf_regmap[] = AMD64_ST0_REGNUM + 2, AMD64_ST0_REGNUM + 3, AMD64_ST0_REGNUM + 4, AMD64_ST0_REGNUM + 5, AMD64_ST0_REGNUM + 6, AMD64_ST0_REGNUM + 7, - + + /* MMX Registers 0 - 7. + We have to handle those registers specifically, as their register + number within GDB depends on the target (or they may even not be + available at all). */ + -1, -1, -1, -1, -1, -1, -1, -1, + /* Control and Status Flags Register. */ AMD64_EFLAGS_REGNUM, @@ -502,7 +508,7 @@ amd64_merge_classes (enum amd64_reg_class class1, enum amd64_reg_class class2) return AMD64_SSE; } -static void amd64_classify (struct type *type, enum amd64_reg_class class[2]); +static void amd64_classify (struct type *type, enum amd64_reg_class theclass[2]); /* Return non-zero if TYPE is a non-POD structure or union type. */ @@ -521,19 +527,19 @@ amd64_non_pod_p (struct type *type) arrays) and union types, and store the result in CLASS. */ static void -amd64_classify_aggregate (struct type *type, enum amd64_reg_class class[2]) +amd64_classify_aggregate (struct type *type, enum amd64_reg_class theclass[2]) { /* 1. If the size of an object is larger than two eightbytes, or in C++, is a non-POD structure or union type, or contains unaligned fields, it has class memory. */ if (TYPE_LENGTH (type) > 16 || amd64_non_pod_p (type)) { - class[0] = class[1] = AMD64_MEMORY; + theclass[0] = theclass[1] = AMD64_MEMORY; return; } /* 2. Both eightbytes get initialized to class NO_CLASS. */ - class[0] = class[1] = AMD64_NO_CLASS; + theclass[0] = theclass[1] = AMD64_NO_CLASS; /* 3. Each field of an object is classified recursively so that always two fields are considered. The resulting class is @@ -545,9 +551,9 @@ amd64_classify_aggregate (struct type *type, enum amd64_reg_class class[2]) struct type *subtype = check_typedef (TYPE_TARGET_TYPE (type)); /* All fields in an array have the same type. */ - amd64_classify (subtype, class); - if (TYPE_LENGTH (type) > 8 && class[1] == AMD64_NO_CLASS) - class[1] = class[0]; + amd64_classify (subtype, theclass); + if (TYPE_LENGTH (type) > 8 && theclass[1] == AMD64_NO_CLASS) + theclass[1] = theclass[0]; } else { @@ -576,7 +582,7 @@ amd64_classify_aggregate (struct type *type, enum amd64_reg_class class[2]) gdb_assert (pos == 0 || pos == 1); amd64_classify (subtype, subclass); - class[pos] = amd64_merge_classes (class[pos], subclass[0]); + theclass[pos] = amd64_merge_classes (theclass[pos], subclass[0]); if (bitsize <= 64 && pos == 0 && endpos == 1) /* This is a bit of an odd case: We have a field that would normally fit in one of the two eightbytes, except that @@ -600,9 +606,9 @@ amd64_classify_aggregate (struct type *type, enum amd64_reg_class class[2]) use up all 16 bytes of the aggregate, and are already handled just fine (because each portion sits on its own 8-byte). */ - class[1] = amd64_merge_classes (class[1], subclass[0]); + theclass[1] = amd64_merge_classes (theclass[1], subclass[0]); if (pos == 0) - class[1] = amd64_merge_classes (class[1], subclass[1]); + theclass[1] = amd64_merge_classes (theclass[1], subclass[1]); } } @@ -610,26 +616,26 @@ amd64_classify_aggregate (struct type *type, enum amd64_reg_class class[2]) /* Rule (a): If one of the classes is MEMORY, the whole argument is passed in memory. */ - if (class[0] == AMD64_MEMORY || class[1] == AMD64_MEMORY) - class[0] = class[1] = AMD64_MEMORY; + if (theclass[0] == AMD64_MEMORY || theclass[1] == AMD64_MEMORY) + theclass[0] = theclass[1] = AMD64_MEMORY; /* Rule (b): If SSEUP is not preceded by SSE, it is converted to SSE. */ - if (class[0] == AMD64_SSEUP) - class[0] = AMD64_SSE; - if (class[1] == AMD64_SSEUP && class[0] != AMD64_SSE) - class[1] = AMD64_SSE; + if (theclass[0] == AMD64_SSEUP) + theclass[0] = AMD64_SSE; + if (theclass[1] == AMD64_SSEUP && theclass[0] != AMD64_SSE) + theclass[1] = AMD64_SSE; } /* Classify TYPE, and store the result in CLASS. */ static void -amd64_classify (struct type *type, enum amd64_reg_class class[2]) +amd64_classify (struct type *type, enum amd64_reg_class theclass[2]) { enum type_code code = TYPE_CODE (type); int len = TYPE_LENGTH (type); - class[0] = class[1] = AMD64_NO_CLASS; + theclass[0] = theclass[1] = AMD64_NO_CLASS; /* Arguments of types (signed and unsigned) _Bool, char, short, int, long, long long, and pointers are in the INTEGER class. Similarly, @@ -640,28 +646,28 @@ amd64_classify (struct type *type, enum amd64_reg_class class[2]) || code == TYPE_CODE_CHAR || code == TYPE_CODE_PTR || code == TYPE_CODE_REF) && (len == 1 || len == 2 || len == 4 || len == 8)) - class[0] = AMD64_INTEGER; + theclass[0] = AMD64_INTEGER; /* Arguments of types float, double, _Decimal32, _Decimal64 and __m64 are in class SSE. */ else if ((code == TYPE_CODE_FLT || code == TYPE_CODE_DECFLOAT) && (len == 4 || len == 8)) /* FIXME: __m64 . */ - class[0] = AMD64_SSE; + theclass[0] = AMD64_SSE; /* Arguments of types __float128, _Decimal128 and __m128 are split into two halves. The least significant ones belong to class SSE, the most significant one to class SSEUP. */ else if (code == TYPE_CODE_DECFLOAT && len == 16) /* FIXME: __float128, __m128. */ - class[0] = AMD64_SSE, class[1] = AMD64_SSEUP; + theclass[0] = AMD64_SSE, theclass[1] = AMD64_SSEUP; /* The 64-bit mantissa of arguments of type long double belongs to class X87, the 16-bit exponent plus 6 bytes of padding belongs to class X87UP. */ else if (code == TYPE_CODE_FLT && len == 16) /* Class X87 and X87UP. */ - class[0] = AMD64_X87, class[1] = AMD64_X87UP; + theclass[0] = AMD64_X87, theclass[1] = AMD64_X87UP; /* Arguments of complex T where T is one of the types float or double get treated as if they are implemented as: @@ -673,19 +679,19 @@ amd64_classify (struct type *type, enum amd64_reg_class class[2]) */ else if (code == TYPE_CODE_COMPLEX && len == 8) - class[0] = AMD64_SSE; + theclass[0] = AMD64_SSE; else if (code == TYPE_CODE_COMPLEX && len == 16) - class[0] = class[1] = AMD64_SSE; + theclass[0] = theclass[1] = AMD64_SSE; /* A variable of type complex long double is classified as type COMPLEX_X87. */ else if (code == TYPE_CODE_COMPLEX && len == 32) - class[0] = AMD64_COMPLEX_X87; + theclass[0] = AMD64_COMPLEX_X87; /* Aggregates. */ else if (code == TYPE_CODE_ARRAY || code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) - amd64_classify_aggregate (type, class); + amd64_classify_aggregate (type, theclass); } static enum return_value_convention @@ -693,7 +699,7 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { - enum amd64_reg_class class[2]; + enum amd64_reg_class theclass[2]; int len = TYPE_LENGTH (type); static int integer_regnum[] = { AMD64_RAX_REGNUM, AMD64_RDX_REGNUM }; static int sse_regnum[] = { AMD64_XMM0_REGNUM, AMD64_XMM1_REGNUM }; @@ -704,7 +710,7 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function, gdb_assert (!(readbuf && writebuf)); /* 1. Classify the return type with the classification algorithm. */ - amd64_classify (type, class); + amd64_classify (type, theclass); /* 2. If the type has class MEMORY, then the caller provides space for the return value and passes the address of this storage in @@ -713,7 +719,7 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function, On return %rax will contain the address that has been passed in by the caller in %rdi. */ - if (class[0] == AMD64_MEMORY) + if (theclass[0] == AMD64_MEMORY) { /* As indicated by the comment above, the ABI guarantees that we can always find the return value just after the function has @@ -732,7 +738,7 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function, /* 8. If the class is COMPLEX_X87, the real part of the value is returned in %st0 and the imaginary part in %st1. */ - if (class[0] == AMD64_COMPLEX_X87) + if (theclass[0] == AMD64_COMPLEX_X87) { if (readbuf) { @@ -754,7 +760,7 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function, return RETURN_VALUE_REGISTER_CONVENTION; } - gdb_assert (class[1] != AMD64_MEMORY); + gdb_assert (theclass[1] != AMD64_MEMORY); gdb_assert (len <= 16); for (i = 0; len > 0; i++, len -= 8) @@ -762,7 +768,7 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function, int regnum = -1; int offset = 0; - switch (class[i]) + switch (theclass[i]) { case AMD64_INTEGER: /* 3. If the class is INTEGER, the next available register @@ -795,7 +801,7 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function, case AMD64_X87UP: /* 7. If the class is X87UP, the value is returned together with the previous X87 value in %st0. */ - gdb_assert (i > 0 && class[0] == AMD64_X87); + gdb_assert (i > 0 && theclass[0] == AMD64_X87); regnum = AMD64_ST0_REGNUM; offset = 8; len = 2; @@ -859,21 +865,21 @@ amd64_push_arguments (struct regcache *regcache, int nargs, { struct type *type = value_type (args[i]); int len = TYPE_LENGTH (type); - enum amd64_reg_class class[2]; + enum amd64_reg_class theclass[2]; int needed_integer_regs = 0; int needed_sse_regs = 0; int j; /* Classify argument. */ - amd64_classify (type, class); + amd64_classify (type, theclass); /* Calculate the number of integer and SSE registers needed for this argument. */ for (j = 0; j < 2; j++) { - if (class[j] == AMD64_INTEGER) + if (theclass[j] == AMD64_INTEGER) needed_integer_regs++; - else if (class[j] == AMD64_SSE) + else if (theclass[j] == AMD64_SSE) needed_sse_regs++; } @@ -900,7 +906,7 @@ amd64_push_arguments (struct regcache *regcache, int nargs, int regnum = -1; int offset = 0; - switch (class[j]) + switch (theclass[j]) { case AMD64_INTEGER: regnum = integer_regnum[integer_reg++]; @@ -2372,8 +2378,7 @@ amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) if (post_prologue_pc && (cust != NULL && COMPUNIT_PRODUCER (cust) != NULL - && strncmp (COMPUNIT_PRODUCER (cust), "clang ", - sizeof ("clang ") - 1) == 0)) + && startswith (COMPUNIT_PRODUCER (cust), "clang "))) return max (start_pc, post_prologue_pc); } @@ -2461,7 +2466,6 @@ amd64_frame_cache_1 (struct frame_info *this_frame, static struct amd64_frame_cache * amd64_frame_cache (struct frame_info *this_frame, void **this_cache) { - volatile struct gdb_exception ex; struct amd64_frame_cache *cache; if (*this_cache) @@ -2470,12 +2474,16 @@ amd64_frame_cache (struct frame_info *this_frame, void **this_cache) cache = amd64_alloc_frame_cache (); *this_cache = cache; - TRY_CATCH (ex, RETURN_MASK_ERROR) + TRY { amd64_frame_cache_1 (this_frame, cache); } - if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR) - throw_exception (ex); + CATCH (ex, RETURN_MASK_ERROR) + { + if (ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + } + END_CATCH return cache; } @@ -2574,7 +2582,6 @@ amd64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - volatile struct gdb_exception ex; struct amd64_frame_cache *cache; CORE_ADDR addr; gdb_byte buf[8]; @@ -2585,7 +2592,7 @@ amd64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) cache = amd64_alloc_frame_cache (); - TRY_CATCH (ex, RETURN_MASK_ERROR) + TRY { get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); cache->base = extract_unsigned_integer (buf, 8, byte_order) - 8; @@ -2599,8 +2606,12 @@ amd64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) cache->base_p = 1; } - if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR) - throw_exception (ex); + CATCH (ex, RETURN_MASK_ERROR) + { + if (ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + } + END_CATCH *this_cache = cache; return cache; @@ -2747,7 +2758,6 @@ amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - volatile struct gdb_exception ex; struct amd64_frame_cache *cache; gdb_byte buf[8]; @@ -2757,7 +2767,7 @@ amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) cache = amd64_alloc_frame_cache (); *this_cache = cache; - TRY_CATCH (ex, RETURN_MASK_ERROR) + TRY { /* Cache base will be %esp plus cache->sp_offset (-8). */ get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); @@ -2775,8 +2785,12 @@ amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) cache->base_p = 1; } - if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR) - throw_exception (ex); + CATCH (ex, RETURN_MASK_ERROR) + { + if (ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + } + END_CATCH return cache; } @@ -2848,7 +2862,7 @@ amd64_supply_fpregset (const struct regset *regset, struct regcache *regcache, struct gdbarch *gdbarch = get_regcache_arch (regcache); const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - gdb_assert (len == tdep->sizeof_fpregset); + gdb_assert (len >= tdep->sizeof_fpregset); amd64_supply_fxsave (regcache, regnum, fpregs); } @@ -2865,7 +2879,7 @@ amd64_collect_fpregset (const struct regset *regset, struct gdbarch *gdbarch = get_regcache_arch (regcache); const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - gdb_assert (len == tdep->sizeof_fpregset); + gdb_assert (len >= tdep->sizeof_fpregset); amd64_collect_fxsave (regcache, regnum, fpregs); }