GDBserver
/home/stan/gdb/src/gdb/gdbserver/linux-aarch64-low.c
Go to the documentation of this file.
00001 /* GNU/Linux/AArch64 specific low level interface, for the remote server for
00002    GDB.
00003 
00004    Copyright (C) 2009-2013 Free Software Foundation, Inc.
00005    Contributed by ARM Ltd.
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 #include "server.h"
00023 #include "linux-low.h"
00024 #include "elf/common.h"
00025 
00026 #include <signal.h>
00027 #include <sys/user.h>
00028 #include <sys/ptrace.h>
00029 #include <sys/uio.h>
00030 
00031 #include "gdb_proc_service.h"
00032 
00033 /* Defined in auto-generated files.  */
00034 void init_registers_aarch64 (void);
00035 extern const struct target_desc *tdesc_aarch64;
00036 
00037 #ifdef HAVE_SYS_REG_H
00038 #include <sys/reg.h>
00039 #endif
00040 
00041 #define AARCH64_X_REGS_NUM 31
00042 #define AARCH64_V_REGS_NUM 32
00043 #define AARCH64_X0_REGNO    0
00044 #define AARCH64_SP_REGNO   31
00045 #define AARCH64_PC_REGNO   32
00046 #define AARCH64_CPSR_REGNO 33
00047 #define AARCH64_V0_REGNO   34
00048 
00049 #define AARCH64_NUM_REGS (AARCH64_V0_REGNO + AARCH64_V_REGS_NUM)
00050 
00051 static int
00052 aarch64_regmap [] =
00053 {
00054   /* These offsets correspond to GET/SETREGSET */
00055   /* x0...  */
00056    0*8,  1*8,  2*8,  3*8,  4*8,  5*8,  6*8,  7*8,
00057    8*8,  9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8,
00058   16*8, 17*8, 18*8, 19*8, 20*8, 21*8, 22*8, 23*8,
00059   24*8, 25*8, 26*8, 27*8, 28*8,
00060   29*8,
00061   30*8,                         /* x30 lr */
00062   31*8,                         /* x31 sp */
00063   32*8,                         /*     pc */
00064   33*8,                         /*     cpsr    4 bytes!*/
00065 
00066   /* FP register offsets correspond to GET/SETFPREGSET */
00067    0*16,  1*16,  2*16,  3*16,  4*16,  5*16,  6*16,  7*16,
00068    8*16,  9*16, 10*16, 11*16, 12*16, 13*16, 14*16, 15*16,
00069   16*16, 17*16, 18*16, 19*16, 20*16, 21*16, 22*16, 23*16,
00070   24*16, 25*16, 26*16, 27*16, 28*16, 29*16, 30*16, 31*16
00071 };
00072 
00073 /* Here starts the macro definitions, data structures, and code for
00074    the hardware breakpoint and hardware watchpoint support.  The
00075    following is the abbreviations that are used frequently in the code
00076    and comment:
00077 
00078    hw - hardware
00079    bp - breakpoint
00080    wp - watchpoint  */
00081 
00082 /* Maximum number of hardware breakpoint and watchpoint registers.
00083    Neither of these values may exceed the width of dr_changed_t
00084    measured in bits.  */
00085 
00086 #define AARCH64_HBP_MAX_NUM 16
00087 #define AARCH64_HWP_MAX_NUM 16
00088 
00089 /* Alignment requirement in bytes of hardware breakpoint and
00090    watchpoint address.  This is the requirement for the addresses that
00091    can be written to the hardware breakpoint/watchpoint value
00092    registers.  The kernel currently does not do any alignment on
00093    addresses when receiving a writing request (via ptrace call) to
00094    these debug registers, and it will reject any address that is
00095    unaligned.
00096    Some limited support has been provided in this gdbserver port for
00097    unaligned watchpoints, so that from a gdb user point of view, an
00098    unaligned watchpoint can still be set.  This is achieved by
00099    minimally enlarging the watched area to meet the alignment
00100    requirement, and if necessary, splitting the watchpoint over
00101    several hardware watchpoint registers.  */
00102 
00103 #define AARCH64_HBP_ALIGNMENT 4
00104 #define AARCH64_HWP_ALIGNMENT 8
00105 
00106 /* The maximum length of a memory region that can be watched by one
00107    hardware watchpoint register.  */
00108 
00109 #define AARCH64_HWP_MAX_LEN_PER_REG 8
00110 
00111 /* Each bit of a variable of this type is used to indicate whether a
00112    hardware breakpoint or watchpoint setting has been changed since
00113    the last updating.  Bit N corresponds to the Nth hardware
00114    breakpoint or watchpoint setting which is managed in
00115    aarch64_debug_reg_state.  Where N is valid between 0 and the total
00116    number of the hardware breakpoint or watchpoint debug registers
00117    minus 1.  When the bit N is 1, it indicates the corresponding
00118    breakpoint or watchpoint setting is changed, and thus the
00119    corresponding hardware debug register needs to be updated via the
00120    ptrace interface.
00121 
00122    In the per-thread arch-specific data area, we define two such
00123    variables for per-thread hardware breakpoint and watchpoint
00124    settings respectively.
00125 
00126    This type is part of the mechanism which helps reduce the number of
00127    ptrace calls to the kernel, i.e. avoid asking the kernel to write
00128    to the debug registers with unchanged values.  */
00129 
00130 typedef unsigned long long dr_changed_t;
00131 
00132 /* Set each of the lower M bits of X to 1; assert X is wide enough.  */
00133 
00134 #define DR_MARK_ALL_CHANGED(x, m)                                       \
00135   do                                                                    \
00136     {                                                                   \
00137       gdb_assert (sizeof ((x)) * 8 >= (m));                             \
00138       (x) = (((dr_changed_t)1 << (m)) - 1);                             \
00139     } while (0)
00140 
00141 #define DR_MARK_N_CHANGED(x, n)                                         \
00142   do                                                                    \
00143     {                                                                   \
00144       (x) |= ((dr_changed_t)1 << (n));                                  \
00145     } while (0)
00146 
00147 #define DR_CLEAR_CHANGED(x)                                             \
00148   do                                                                    \
00149     {                                                                   \
00150       (x) = 0;                                                          \
00151     } while (0)
00152 
00153 #define DR_HAS_CHANGED(x) ((x) != 0)
00154 #define DR_N_HAS_CHANGED(x, n) ((x) & ((dr_changed_t)1 << (n)))
00155 
00156 /* Structure for managing the hardware breakpoint/watchpoint resources.
00157    DR_ADDR_* stores the address, DR_CTRL_* stores the control register
00158    content, and DR_REF_COUNT_* counts the numbers of references to the
00159    corresponding bp/wp, by which way the limited hardware resources
00160    are not wasted on duplicated bp/wp settings (though so far gdb has
00161    done a good job by not sending duplicated bp/wp requests).  */
00162 
00163 struct aarch64_debug_reg_state
00164 {
00165   /* hardware breakpoint */
00166   CORE_ADDR dr_addr_bp[AARCH64_HBP_MAX_NUM];
00167   unsigned int dr_ctrl_bp[AARCH64_HBP_MAX_NUM];
00168   unsigned int dr_ref_count_bp[AARCH64_HBP_MAX_NUM];
00169 
00170   /* hardware watchpoint */
00171   CORE_ADDR dr_addr_wp[AARCH64_HWP_MAX_NUM];
00172   unsigned int dr_ctrl_wp[AARCH64_HWP_MAX_NUM];
00173   unsigned int dr_ref_count_wp[AARCH64_HWP_MAX_NUM];
00174 };
00175 
00176 /* Per-process arch-specific data we want to keep.  */
00177 
00178 struct arch_process_info
00179 {
00180   /* Hardware breakpoint/watchpoint data.
00181      The reason for them to be per-process rather than per-thread is
00182      due to the lack of information in the gdbserver environment;
00183      gdbserver is not told that whether a requested hardware
00184      breakpoint/watchpoint is thread specific or not, so it has to set
00185      each hw bp/wp for every thread in the current process.  The
00186      higher level bp/wp management in gdb will resume a thread if a hw
00187      bp/wp trap is not expected for it.  Since the hw bp/wp setting is
00188      same for each thread, it is reasonable for the data to live here.
00189      */
00190   struct aarch64_debug_reg_state debug_reg_state;
00191 };
00192 
00193 /* Per-thread arch-specific data we want to keep.  */
00194 
00195 struct arch_lwp_info
00196 {
00197   /* When bit N is 1, it indicates the Nth hardware breakpoint or
00198      watchpoint register pair needs to be updated when the thread is
00199      resumed; see aarch64_linux_prepare_to_resume.  */
00200   dr_changed_t dr_changed_bp;
00201   dr_changed_t dr_changed_wp;
00202 };
00203 
00204 /* Number of hardware breakpoints/watchpoints the target supports.
00205    They are initialized with values obtained via the ptrace calls
00206    with NT_ARM_HW_BREAK and NT_ARM_HW_WATCH respectively.  */
00207 
00208 static int aarch64_num_bp_regs;
00209 static int aarch64_num_wp_regs;
00210 
00211 /* Hardware breakpoint/watchpoint types.
00212    The values map to their encodings in the bit 4 and bit 3 of the
00213    hardware breakpoint/watchpoint control registers.  */
00214 
00215 enum target_point_type
00216 {
00217   hw_execute = 0,               /* Execute HW breakpoint */
00218   hw_read = 1,                  /* Read    HW watchpoint */
00219   hw_write = 2,                 /* Common  HW watchpoint */
00220   hw_access = 3,                /* Access  HW watchpoint */
00221   point_type_unsupported
00222 };
00223 
00224 #define Z_PACKET_SW_BP '0'
00225 #define Z_PACKET_HW_BP '1'
00226 #define Z_PACKET_WRITE_WP '2'
00227 #define Z_PACKET_READ_WP '3'
00228 #define Z_PACKET_ACCESS_WP '4'
00229 
00230 /* Map the protocol breakpoint/watchpoint type TYPE to
00231    enum target_point_type.  */
00232 
00233 static enum target_point_type
00234 Z_packet_to_point_type (char type)
00235 {
00236   switch (type)
00237     {
00238     case Z_PACKET_SW_BP:
00239       /* Leave the handling of the sw breakpoint with the gdb client.  */
00240       return point_type_unsupported;
00241     case Z_PACKET_HW_BP:
00242       return hw_execute;
00243     case Z_PACKET_WRITE_WP:
00244       return hw_write;
00245     case Z_PACKET_READ_WP:
00246       return hw_read;
00247     case Z_PACKET_ACCESS_WP:
00248       return hw_access;
00249     default:
00250       return point_type_unsupported;
00251     }
00252 }
00253 
00254 static int
00255 aarch64_cannot_store_register (int regno)
00256 {
00257   return regno >= AARCH64_NUM_REGS;
00258 }
00259 
00260 static int
00261 aarch64_cannot_fetch_register (int regno)
00262 {
00263   return regno >= AARCH64_NUM_REGS;
00264 }
00265 
00266 static void
00267 aarch64_fill_gregset (struct regcache *regcache, void *buf)
00268 {
00269   struct user_pt_regs *regset = buf;
00270   int i;
00271 
00272   for (i = 0; i < AARCH64_X_REGS_NUM; i++)
00273     collect_register (regcache, AARCH64_X0_REGNO + i, &regset->regs[i]);
00274   collect_register (regcache, AARCH64_SP_REGNO, &regset->sp);
00275   collect_register (regcache, AARCH64_PC_REGNO, &regset->pc);
00276   collect_register (regcache, AARCH64_CPSR_REGNO, &regset->pstate);
00277 }
00278 
00279 static void
00280 aarch64_store_gregset (struct regcache *regcache, const void *buf)
00281 {
00282   const struct user_pt_regs *regset = buf;
00283   int i;
00284 
00285   for (i = 0; i < AARCH64_X_REGS_NUM; i++)
00286     supply_register (regcache, AARCH64_X0_REGNO + i, &regset->regs[i]);
00287   supply_register (regcache, AARCH64_SP_REGNO, &regset->sp);
00288   supply_register (regcache, AARCH64_PC_REGNO, &regset->pc);
00289   supply_register (regcache, AARCH64_CPSR_REGNO, &regset->pstate);
00290 }
00291 
00292 static void
00293 aarch64_fill_fpregset (struct regcache *regcache, void *buf)
00294 {
00295   struct user_fpsimd_state *regset = buf;
00296   int i;
00297 
00298   for (i = 0; i < AARCH64_V_REGS_NUM; i++)
00299     collect_register (regcache, AARCH64_V0_REGNO + i, &regset->vregs[i]);
00300 }
00301 
00302 static void
00303 aarch64_store_fpregset (struct regcache *regcache, const void *buf)
00304 {
00305   const struct user_fpsimd_state *regset = buf;
00306   int i;
00307 
00308   for (i = 0; i < AARCH64_V_REGS_NUM; i++)
00309     supply_register (regcache, AARCH64_V0_REGNO + i, &regset->vregs[i]);
00310 }
00311 
00312 /* Debugging of hardware breakpoint/watchpoint support.  */
00313 extern int debug_hw_points;
00314 
00315 /* Enable miscellaneous debugging output.  The name is historical - it
00316    was originally used to debug LinuxThreads support.  */
00317 extern int debug_threads;
00318 
00319 static CORE_ADDR
00320 aarch64_get_pc (struct regcache *regcache)
00321 {
00322   unsigned long pc;
00323 
00324   collect_register_by_name (regcache, "pc", &pc);
00325   if (debug_threads)
00326     fprintf (stderr, "stop pc is %08lx\n", pc);
00327   return pc;
00328 }
00329 
00330 static void
00331 aarch64_set_pc (struct regcache *regcache, CORE_ADDR pc)
00332 {
00333   unsigned long newpc = pc;
00334   supply_register_by_name (regcache, "pc", &newpc);
00335 }
00336 
00337 /* Correct in either endianness.  */
00338 
00339 #define aarch64_breakpoint_len 4
00340 
00341 static const unsigned long aarch64_breakpoint = 0x00800011;
00342 
00343 static int
00344 aarch64_breakpoint_at (CORE_ADDR where)
00345 {
00346   unsigned long insn;
00347 
00348   (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
00349   if (insn == aarch64_breakpoint)
00350     return 1;
00351 
00352   return 0;
00353 }
00354 
00355 /* Print the values of the cached breakpoint/watchpoint registers.
00356    This is enabled via the "set debug-hw-points" monitor command.  */
00357 
00358 static void
00359 aarch64_show_debug_reg_state (struct aarch64_debug_reg_state *state,
00360                               const char *func, CORE_ADDR addr,
00361                               int len, enum target_point_type type)
00362 {
00363   int i;
00364 
00365   fprintf (stderr, "%s", func);
00366   if (addr || len)
00367     fprintf (stderr, " (addr=0x%08lx, len=%d, type=%s)",
00368              (unsigned long) addr, len,
00369              type == hw_write ? "hw-write-watchpoint"
00370              : (type == hw_read ? "hw-read-watchpoint"
00371                 : (type == hw_access ? "hw-access-watchpoint"
00372                    : (type == hw_execute ? "hw-breakpoint"
00373                       : "??unknown??"))));
00374   fprintf (stderr, ":\n");
00375 
00376   fprintf (stderr, "\tBREAKPOINTs:\n");
00377   for (i = 0; i < aarch64_num_bp_regs; i++)
00378     fprintf (stderr, "\tBP%d: addr=0x%s, ctrl=0x%08x, ref.count=%d\n",
00379              i, paddress (state->dr_addr_bp[i]),
00380              state->dr_ctrl_bp[i], state->dr_ref_count_bp[i]);
00381 
00382   fprintf (stderr, "\tWATCHPOINTs:\n");
00383   for (i = 0; i < aarch64_num_wp_regs; i++)
00384     fprintf (stderr, "\tWP%d: addr=0x%s, ctrl=0x%08x, ref.count=%d\n",
00385              i, paddress (state->dr_addr_wp[i]),
00386              state->dr_ctrl_wp[i], state->dr_ref_count_wp[i]);
00387 }
00388 
00389 static void
00390 aarch64_init_debug_reg_state (struct aarch64_debug_reg_state *state)
00391 {
00392   int i;
00393 
00394   for (i = 0; i < AARCH64_HBP_MAX_NUM; ++i)
00395     {
00396       state->dr_addr_bp[i] = 0;
00397       state->dr_ctrl_bp[i] = 0;
00398       state->dr_ref_count_bp[i] = 0;
00399     }
00400 
00401   for (i = 0; i < AARCH64_HWP_MAX_NUM; ++i)
00402     {
00403       state->dr_addr_wp[i] = 0;
00404       state->dr_ctrl_wp[i] = 0;
00405       state->dr_ref_count_wp[i] = 0;
00406     }
00407 }
00408 
00409 /* ptrace expects control registers to be formatted as follows:
00410 
00411    31                             13          5      3      1     0
00412    +--------------------------------+----------+------+------+----+
00413    |         RESERVED (SBZ)         |  LENGTH  | TYPE | PRIV | EN |
00414    +--------------------------------+----------+------+------+----+
00415 
00416    The TYPE field is ignored for breakpoints.  */
00417 
00418 #define DR_CONTROL_ENABLED(ctrl)        (((ctrl) & 0x1) == 1)
00419 #define DR_CONTROL_LENGTH(ctrl)         (((ctrl) >> 5) & 0xff)
00420 
00421 /* Utility function that returns the length in bytes of a watchpoint
00422    according to the content of a hardware debug control register CTRL.
00423    Note that the kernel currently only supports the following Byte
00424    Address Select (BAS) values: 0x1, 0x3, 0xf and 0xff, which means
00425    that for a hardware watchpoint, its valid length can only be 1
00426    byte, 2 bytes, 4 bytes or 8 bytes.  */
00427 
00428 static inline unsigned int
00429 aarch64_watchpoint_length (unsigned int ctrl)
00430 {
00431   switch (DR_CONTROL_LENGTH (ctrl))
00432     {
00433     case 0x01:
00434       return 1;
00435     case 0x03:
00436       return 2;
00437     case 0x0f:
00438       return 4;
00439     case 0xff:
00440       return 8;
00441     default:
00442       return 0;
00443     }
00444 }
00445 
00446 /* Given the hardware breakpoint or watchpoint type TYPE and its
00447    length LEN, return the expected encoding for a hardware
00448    breakpoint/watchpoint control register.  */
00449 
00450 static unsigned int
00451 aarch64_point_encode_ctrl_reg (enum target_point_type type, int len)
00452 {
00453   unsigned int ctrl;
00454 
00455   /* type */
00456   ctrl = type << 3;
00457   /* length bitmask */
00458   ctrl |= ((1 << len) - 1) << 5;
00459   /* enabled at el0 */
00460   ctrl |= (2 << 1) | 1;
00461 
00462   return ctrl;
00463 }
00464 
00465 /* Addresses to be written to the hardware breakpoint and watchpoint
00466    value registers need to be aligned; the alignment is 4-byte and
00467    8-type respectively.  Linux kernel rejects any non-aligned address
00468    it receives from the related ptrace call.  Furthermore, the kernel
00469    currently only supports the following Byte Address Select (BAS)
00470    values: 0x1, 0x3, 0xf and 0xff, which means that for a hardware
00471    watchpoint to be accepted by the kernel (via ptrace call), its
00472    valid length can only be 1 byte, 2 bytes, 4 bytes or 8 bytes.
00473    Despite these limitations, the unaligned watchpoint is supported in
00474    this gdbserver port.
00475 
00476    Return 0 for any non-compliant ADDR and/or LEN; return 1 otherwise.  */
00477 
00478 static int
00479 aarch64_point_is_aligned (int is_watchpoint, CORE_ADDR addr, int len)
00480 {
00481   unsigned int alignment = is_watchpoint ? AARCH64_HWP_ALIGNMENT
00482     : AARCH64_HBP_ALIGNMENT;
00483 
00484   if (addr & (alignment - 1))
00485     return 0;
00486 
00487   if (len != 8 && len != 4 && len != 2 && len != 1)
00488     return 0;
00489 
00490   return 1;
00491 }
00492 
00493 /* Given the (potentially unaligned) watchpoint address in ADDR and
00494    length in LEN, return the aligned address and aligned length in
00495    *ALIGNED_ADDR_P and *ALIGNED_LEN_P, respectively.  The returned
00496    aligned address and length will be valid to be written to the
00497    hardware watchpoint value and control registers.  See the comment
00498    above aarch64_point_is_aligned for the information about the
00499    alignment requirement.  The given watchpoint may get truncated if
00500    more than one hardware register is needed to cover the watched
00501    region.  *NEXT_ADDR_P and *NEXT_LEN_P, if non-NULL, will return the
00502    address and length of the remaining part of the watchpoint (which
00503    can be processed by calling this routine again to generate another
00504    aligned address and length pair.
00505 
00506    Essentially, unaligned watchpoint is achieved by minimally
00507    enlarging the watched area to meet the alignment requirement, and
00508    if necessary, splitting the watchpoint over several hardware
00509    watchpoint registers.  The trade-off is that there will be
00510    false-positive hits for the read-type or the access-type hardware
00511    watchpoints; for the write type, which is more commonly used, there
00512    will be no such issues, as the higher-level breakpoint management
00513    in gdb always examines the exact watched region for any content
00514    change, and transparently resumes a thread from a watchpoint trap
00515    if there is no change to the watched region.
00516 
00517    Another limitation is that because the watched region is enlarged,
00518    the watchpoint fault address returned by
00519    aarch64_stopped_data_address may be outside of the original watched
00520    region, especially when the triggering instruction is accessing a
00521    larger region.  When the fault address is not within any known
00522    range, watchpoints_triggered in gdb will get confused, as the
00523    higher-level watchpoint management is only aware of original
00524    watched regions, and will think that some unknown watchpoint has
00525    been triggered.  In such a case, gdb may stop without displaying
00526    any detailed information.
00527 
00528    Once the kernel provides the full support for Byte Address Select
00529    (BAS) in the hardware watchpoint control register, these
00530    limitations can be largely relaxed with some further work.  */
00531 
00532 static void
00533 aarch64_align_watchpoint (CORE_ADDR addr, int len, CORE_ADDR *aligned_addr_p,
00534                           int *aligned_len_p, CORE_ADDR *next_addr_p,
00535                           int *next_len_p)
00536 {
00537   int aligned_len;
00538   unsigned int offset;
00539   CORE_ADDR aligned_addr;
00540   const unsigned int alignment = AARCH64_HWP_ALIGNMENT;
00541   const unsigned int max_wp_len = AARCH64_HWP_MAX_LEN_PER_REG;
00542 
00543   /* As assumed by the algorithm.  */
00544   gdb_assert (alignment == max_wp_len);
00545 
00546   if (len <= 0)
00547     return;
00548 
00549   /* Address to be put into the hardware watchpoint value register
00550      must be aligned.  */
00551   offset = addr & (alignment - 1);
00552   aligned_addr = addr - offset;
00553 
00554   gdb_assert (offset >= 0 && offset < alignment);
00555   gdb_assert (aligned_addr >= 0 && aligned_addr <= addr);
00556   gdb_assert ((offset + len) > 0);
00557 
00558   if (offset + len >= max_wp_len)
00559     {
00560       /* Need more than one watchpoint registers; truncate it at the
00561          alignment boundary.  */
00562       aligned_len = max_wp_len;
00563       len -= (max_wp_len - offset);
00564       addr += (max_wp_len - offset);
00565       gdb_assert ((addr & (alignment - 1)) == 0);
00566     }
00567   else
00568     {
00569       /* Find the smallest valid length that is large enough to
00570          accommodate this watchpoint.  */
00571       static const unsigned char
00572         aligned_len_array[AARCH64_HWP_MAX_LEN_PER_REG] =
00573         { 1, 2, 4, 4, 8, 8, 8, 8 };
00574 
00575       aligned_len = aligned_len_array[offset + len - 1];
00576       addr += len;
00577       len = 0;
00578     }
00579 
00580   if (aligned_addr_p != NULL)
00581     *aligned_addr_p = aligned_addr;
00582   if (aligned_len_p != NULL)
00583     *aligned_len_p = aligned_len;
00584   if (next_addr_p != NULL)
00585     *next_addr_p = addr;
00586   if (next_len_p != NULL)
00587     *next_len_p = len;
00588 }
00589 
00590 /* Call ptrace to set the thread TID's hardware breakpoint/watchpoint
00591    registers with data from *STATE.  */
00592 
00593 static void
00594 aarch64_linux_set_debug_regs (const struct aarch64_debug_reg_state *state,
00595                               int tid, int watchpoint)
00596 {
00597   int i, count;
00598   struct iovec iov;
00599   struct user_hwdebug_state regs;
00600   const CORE_ADDR *addr;
00601   const unsigned int *ctrl;
00602 
00603   memset (&regs, 0, sizeof (regs));
00604   iov.iov_base = &regs;
00605   iov.iov_len = sizeof (regs);
00606   count = watchpoint ? aarch64_num_wp_regs : aarch64_num_bp_regs;
00607   addr = watchpoint ? state->dr_addr_wp : state->dr_addr_bp;
00608   ctrl = watchpoint ? state->dr_ctrl_wp : state->dr_ctrl_bp;
00609 
00610   for (i = 0; i < count; i++)
00611     {
00612       regs.dbg_regs[i].addr = addr[i];
00613       regs.dbg_regs[i].ctrl = ctrl[i];
00614     }
00615 
00616   if (ptrace (PTRACE_SETREGSET, tid,
00617               watchpoint ? NT_ARM_HW_WATCH : NT_ARM_HW_BREAK,
00618               (void *) &iov))
00619     error (_("Unexpected error setting hardware debug registers"));
00620 }
00621 
00622 struct aarch64_dr_update_callback_param
00623 {
00624   int pid;
00625   int is_watchpoint;
00626   unsigned int idx;
00627 };
00628 
00629 /* Callback function which records the information about the change of
00630    one hardware breakpoint/watchpoint setting for the thread ENTRY.
00631    The information is passed in via PTR.
00632    N.B.  The actual updating of hardware debug registers is not
00633    carried out until the moment the thread is resumed.  */
00634 
00635 static int
00636 debug_reg_change_callback (struct inferior_list_entry *entry, void *ptr)
00637 {
00638   struct lwp_info *lwp = (struct lwp_info *) entry;
00639   struct aarch64_dr_update_callback_param *param_p
00640     = (struct aarch64_dr_update_callback_param *) ptr;
00641   int pid = param_p->pid;
00642   int idx = param_p->idx;
00643   int is_watchpoint = param_p->is_watchpoint;
00644   struct arch_lwp_info *info = lwp->arch_private;
00645   dr_changed_t *dr_changed_ptr;
00646   dr_changed_t dr_changed;
00647 
00648   if (debug_hw_points)
00649     {
00650       fprintf (stderr, "debug_reg_change_callback: \n\tOn entry:\n");
00651       fprintf (stderr, "\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
00652                "dr_changed_wp=0x%llx\n",
00653                pid, lwpid_of (lwp), info->dr_changed_bp,
00654                info->dr_changed_wp);
00655     }
00656 
00657   dr_changed_ptr = is_watchpoint ? &info->dr_changed_wp
00658     : &info->dr_changed_bp;
00659   dr_changed = *dr_changed_ptr;
00660 
00661   /* Only update the threads of this process.  */
00662   if (pid_of (lwp) == pid)
00663     {
00664       gdb_assert (idx >= 0
00665                   && (idx <= (is_watchpoint ? aarch64_num_wp_regs
00666                               : aarch64_num_bp_regs)));
00667 
00668       /* The following assertion is not right, as there can be changes
00669          that have not been made to the hardware debug registers
00670          before new changes overwrite the old ones.  This can happen,
00671          for instance, when the breakpoint/watchpoint hit one of the
00672          threads and the user enters continue; then what happens is:
00673          1) all breakpoints/watchpoints are removed for all threads;
00674          2) a single step is carried out for the thread that was hit;
00675          3) all of the points are inserted again for all threads;
00676          4) all threads are resumed.
00677          The 2nd step will only affect the one thread in which the
00678          bp/wp was hit, which means only that one thread is resumed;
00679          remember that the actual updating only happen in
00680          aarch64_linux_prepare_to_resume, so other threads remain
00681          stopped during the removal and insertion of bp/wp.  Therefore
00682          for those threads, the change of insertion of the bp/wp
00683          overwrites that of the earlier removals.  (The situation may
00684          be different when bp/wp is steppable, or in the non-stop
00685          mode.)  */
00686       /* gdb_assert (DR_N_HAS_CHANGED (dr_changed, idx) == 0);  */
00687 
00688       /* The actual update is done later just before resuming the lwp,
00689          we just mark that one register pair needs updating.  */
00690       DR_MARK_N_CHANGED (dr_changed, idx);
00691       *dr_changed_ptr = dr_changed;
00692 
00693       /* If the lwp isn't stopped, force it to momentarily pause, so
00694          we can update its debug registers.  */
00695       if (!lwp->stopped)
00696         linux_stop_lwp (lwp);
00697     }
00698 
00699   if (debug_hw_points)
00700     {
00701       fprintf (stderr, "\tOn exit:\n\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
00702                "dr_changed_wp=0x%llx\n",
00703                pid, lwpid_of (lwp), info->dr_changed_bp, info->dr_changed_wp);
00704     }
00705 
00706   return 0;
00707 }
00708 
00709 /* Notify each thread that their IDXth breakpoint/watchpoint register
00710    pair needs to be updated.  The message will be recorded in each
00711    thread's arch-specific data area, the actual updating will be done
00712    when the thread is resumed.  */
00713 
00714 void
00715 aarch64_notify_debug_reg_change (const struct aarch64_debug_reg_state *state,
00716                                  int is_watchpoint, unsigned int idx)
00717 {
00718   struct aarch64_dr_update_callback_param param;
00719 
00720   /* Only update the threads of this process.  */
00721   param.pid = pid_of (get_thread_lwp (current_inferior));
00722 
00723   param.is_watchpoint = is_watchpoint;
00724   param.idx = idx;
00725 
00726   find_inferior (&all_lwps, debug_reg_change_callback, (void *) &param);
00727 }
00728 
00729 
00730 /* Return the pointer to the debug register state structure in the
00731    current process' arch-specific data area.  */
00732 
00733 static struct aarch64_debug_reg_state *
00734 aarch64_get_debug_reg_state ()
00735 {
00736   struct process_info *proc;
00737 
00738   proc = current_process ();
00739   return &proc->private->arch_private->debug_reg_state;
00740 }
00741 
00742 /* Record the insertion of one breakpoint/watchpoint, as represented
00743    by ADDR and CTRL, in the process' arch-specific data area *STATE.  */
00744 
00745 static int
00746 aarch64_dr_state_insert_one_point (struct aarch64_debug_reg_state *state,
00747                                    enum target_point_type type,
00748                                    CORE_ADDR addr, int len)
00749 {
00750   int i, idx, num_regs, is_watchpoint;
00751   unsigned int ctrl, *dr_ctrl_p, *dr_ref_count;
00752   CORE_ADDR *dr_addr_p;
00753 
00754   /* Set up state pointers.  */
00755   is_watchpoint = (type != hw_execute);
00756   gdb_assert (aarch64_point_is_aligned (is_watchpoint, addr, len));
00757   if (is_watchpoint)
00758     {
00759       num_regs = aarch64_num_wp_regs;
00760       dr_addr_p = state->dr_addr_wp;
00761       dr_ctrl_p = state->dr_ctrl_wp;
00762       dr_ref_count = state->dr_ref_count_wp;
00763     }
00764   else
00765     {
00766       num_regs = aarch64_num_bp_regs;
00767       dr_addr_p = state->dr_addr_bp;
00768       dr_ctrl_p = state->dr_ctrl_bp;
00769       dr_ref_count = state->dr_ref_count_bp;
00770     }
00771 
00772   ctrl = aarch64_point_encode_ctrl_reg (type, len);
00773 
00774   /* Find an existing or free register in our cache.  */
00775   idx = -1;
00776   for (i = 0; i < num_regs; ++i)
00777     {
00778       if ((dr_ctrl_p[i] & 1) == 0)
00779         {
00780           gdb_assert (dr_ref_count[i] == 0);
00781           idx = i;
00782           /* no break; continue hunting for an exising one.  */
00783         }
00784       else if (dr_addr_p[i] == addr && dr_ctrl_p[i] == ctrl)
00785         {
00786           gdb_assert (dr_ref_count[i] != 0);
00787           idx = i;
00788           break;
00789         }
00790     }
00791 
00792   /* No space.  */
00793   if (idx == -1)
00794     return -1;
00795 
00796   /* Update our cache.  */
00797   if ((dr_ctrl_p[idx] & 1) == 0)
00798     {
00799       /* new entry */
00800       dr_addr_p[idx] = addr;
00801       dr_ctrl_p[idx] = ctrl;
00802       dr_ref_count[idx] = 1;
00803       /* Notify the change.  */
00804       aarch64_notify_debug_reg_change (state, is_watchpoint, idx);
00805     }
00806   else
00807     {
00808       /* existing entry */
00809       dr_ref_count[idx]++;
00810     }
00811 
00812   return 0;
00813 }
00814 
00815 /* Record the removal of one breakpoint/watchpoint, as represented by
00816    ADDR and CTRL, in the process' arch-specific data area *STATE.  */
00817 
00818 static int
00819 aarch64_dr_state_remove_one_point (struct aarch64_debug_reg_state *state,
00820                                    enum target_point_type type,
00821                                    CORE_ADDR addr, int len)
00822 {
00823   int i, num_regs, is_watchpoint;
00824   unsigned int ctrl, *dr_ctrl_p, *dr_ref_count;
00825   CORE_ADDR *dr_addr_p;
00826 
00827   /* Set up state pointers.  */
00828   is_watchpoint = (type != hw_execute);
00829   gdb_assert (aarch64_point_is_aligned (is_watchpoint, addr, len));
00830   if (is_watchpoint)
00831     {
00832       num_regs = aarch64_num_wp_regs;
00833       dr_addr_p = state->dr_addr_wp;
00834       dr_ctrl_p = state->dr_ctrl_wp;
00835       dr_ref_count = state->dr_ref_count_wp;
00836     }
00837   else
00838     {
00839       num_regs = aarch64_num_bp_regs;
00840       dr_addr_p = state->dr_addr_bp;
00841       dr_ctrl_p = state->dr_ctrl_bp;
00842       dr_ref_count = state->dr_ref_count_bp;
00843     }
00844 
00845   ctrl = aarch64_point_encode_ctrl_reg (type, len);
00846 
00847   /* Find the entry that matches the ADDR and CTRL.  */
00848   for (i = 0; i < num_regs; ++i)
00849     if (dr_addr_p[i] == addr && dr_ctrl_p[i] == ctrl)
00850       {
00851         gdb_assert (dr_ref_count[i] != 0);
00852         break;
00853       }
00854 
00855   /* Not found.  */
00856   if (i == num_regs)
00857     return -1;
00858 
00859   /* Clear our cache.  */
00860   if (--dr_ref_count[i] == 0)
00861     {
00862       /* Clear the enable bit.  */
00863       ctrl &= ~1;
00864       dr_addr_p[i] = 0;
00865       dr_ctrl_p[i] = ctrl;
00866       /* Notify the change.  */
00867       aarch64_notify_debug_reg_change (state, is_watchpoint, i);
00868     }
00869 
00870   return 0;
00871 }
00872 
00873 static int
00874 aarch64_handle_breakpoint (enum target_point_type type, CORE_ADDR addr,
00875                            int len, int is_insert)
00876 {
00877   struct aarch64_debug_reg_state *state;
00878 
00879   /* The hardware breakpoint on AArch64 should always be 4-byte
00880      aligned.  */
00881   if (!aarch64_point_is_aligned (0 /* is_watchpoint */ , addr, len))
00882     return -1;
00883 
00884   state = aarch64_get_debug_reg_state ();
00885 
00886   if (is_insert)
00887     return aarch64_dr_state_insert_one_point (state, type, addr, len);
00888   else
00889     return aarch64_dr_state_remove_one_point (state, type, addr, len);
00890 }
00891 
00892 /* This is essentially the same as aarch64_handle_breakpoint, apart
00893    from that it is an aligned watchpoint to be handled.  */
00894 
00895 static int
00896 aarch64_handle_aligned_watchpoint (enum target_point_type type,
00897                                    CORE_ADDR addr, int len, int is_insert)
00898 {
00899   struct aarch64_debug_reg_state *state;
00900 
00901   state = aarch64_get_debug_reg_state ();
00902 
00903   if (is_insert)
00904     return aarch64_dr_state_insert_one_point (state, type, addr, len);
00905   else
00906     return aarch64_dr_state_remove_one_point (state, type, addr, len);
00907 }
00908 
00909 /* Insert/remove unaligned watchpoint by calling
00910    aarch64_align_watchpoint repeatedly until the whole watched region,
00911    as represented by ADDR and LEN, has been properly aligned and ready
00912    to be written to one or more hardware watchpoint registers.
00913    IS_INSERT indicates whether this is an insertion or a deletion.
00914    Return 0 if succeed.  */
00915 
00916 static int
00917 aarch64_handle_unaligned_watchpoint (enum target_point_type type,
00918                                      CORE_ADDR addr, int len, int is_insert)
00919 {
00920   struct aarch64_debug_reg_state *state
00921     = aarch64_get_debug_reg_state ();
00922 
00923   while (len > 0)
00924     {
00925       CORE_ADDR aligned_addr;
00926       int aligned_len, ret;
00927 
00928       aarch64_align_watchpoint (addr, len, &aligned_addr, &aligned_len,
00929                                 &addr, &len);
00930 
00931       if (is_insert)
00932         ret = aarch64_dr_state_insert_one_point (state, type, aligned_addr,
00933                                                  aligned_len);
00934       else
00935         ret = aarch64_dr_state_remove_one_point (state, type, aligned_addr,
00936                                                  aligned_len);
00937 
00938       if (debug_hw_points)
00939         fprintf (stderr,
00940  "handle_unaligned_watchpoint: is_insert: %d\n"
00941  "                             aligned_addr: 0x%s, aligned_len: %d\n"
00942  "                                next_addr: 0x%s,    next_len: %d\n",
00943                  is_insert, paddress (aligned_addr), aligned_len,
00944                  paddress (addr), len);
00945 
00946       if (ret != 0)
00947         return ret;
00948     }
00949 
00950   return 0;
00951 }
00952 
00953 static int
00954 aarch64_handle_watchpoint (enum target_point_type type, CORE_ADDR addr,
00955                            int len, int is_insert)
00956 {
00957   if (aarch64_point_is_aligned (1 /* is_watchpoint */ , addr, len))
00958     return aarch64_handle_aligned_watchpoint (type, addr, len, is_insert);
00959   else
00960     return aarch64_handle_unaligned_watchpoint (type, addr, len, is_insert);
00961 }
00962 
00963 /* Insert a hardware breakpoint/watchpoint.
00964    It actually only records the info of the to-be-inserted bp/wp;
00965    the actual insertion will happen when threads are resumed.
00966 
00967    Return 0 if succeed;
00968    Return 1 if TYPE is unsupported type;
00969    Return -1 if an error occurs.  */
00970 
00971 static int
00972 aarch64_insert_point (char type, CORE_ADDR addr, int len)
00973 {
00974   int ret;
00975   enum target_point_type targ_type;
00976 
00977   if (debug_hw_points)
00978     fprintf (stderr, "insert_point on entry (addr=0x%08lx, len=%d)\n",
00979              (unsigned long) addr, len);
00980 
00981   /* Determine the type from the packet.  */
00982   targ_type = Z_packet_to_point_type (type);
00983   if (targ_type == point_type_unsupported)
00984     return 1;
00985 
00986   if (targ_type != hw_execute)
00987     ret =
00988       aarch64_handle_watchpoint (targ_type, addr, len, 1 /* is_insert */);
00989   else
00990     ret =
00991       aarch64_handle_breakpoint (targ_type, addr, len, 1 /* is_insert */);
00992 
00993   if (debug_hw_points > 1)
00994     aarch64_show_debug_reg_state (aarch64_get_debug_reg_state (),
00995                                   "insert_point", addr, len, targ_type);
00996 
00997   return ret;
00998 }
00999 
01000 /* Remove a hardware breakpoint/watchpoint.
01001    It actually only records the info of the to-be-removed bp/wp,
01002    the actual removal will be done when threads are resumed.
01003 
01004    Return 0 if succeed;
01005    Return 1 if TYPE is an unsupported type;
01006    Return -1 if an error occurs.  */
01007 
01008 static int
01009 aarch64_remove_point (char type, CORE_ADDR addr, int len)
01010 {
01011   int ret;
01012   enum target_point_type targ_type;
01013 
01014   if (debug_hw_points)
01015     fprintf (stderr, "remove_point on entry (addr=0x%08lx, len=%d)\n",
01016              (unsigned long) addr, len);
01017 
01018   /* Determine the type from the packet.  */
01019   targ_type = Z_packet_to_point_type (type);
01020   if (targ_type == point_type_unsupported)
01021     return 1;
01022 
01023   /* Set up state pointers.  */
01024   if (targ_type != hw_execute)
01025     ret =
01026       aarch64_handle_watchpoint (targ_type, addr, len, 0 /* is_insert */);
01027   else
01028     ret =
01029       aarch64_handle_breakpoint (targ_type, addr, len, 0 /* is_insert */);
01030 
01031   if (debug_hw_points > 1)
01032     aarch64_show_debug_reg_state (aarch64_get_debug_reg_state (),
01033                                   "remove_point", addr, len, targ_type);
01034 
01035   return ret;
01036 }
01037 
01038 /* Returns the address associated with the watchpoint that hit, if
01039    any; returns 0 otherwise.  */
01040 
01041 static CORE_ADDR
01042 aarch64_stopped_data_address (void)
01043 {
01044   siginfo_t siginfo;
01045   int pid, i;
01046   struct aarch64_debug_reg_state *state;
01047 
01048   pid = lwpid_of (get_thread_lwp (current_inferior));
01049 
01050   /* Get the siginfo.  */
01051   if (ptrace (PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0)
01052     return (CORE_ADDR) 0;
01053 
01054   /* Need to be a hardware breakpoint/watchpoint trap.  */
01055   if (siginfo.si_signo != SIGTRAP
01056       || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
01057     return (CORE_ADDR) 0;
01058 
01059   /* Check if the address matches any watched address.  */
01060   state = aarch64_get_debug_reg_state ();
01061   for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
01062     {
01063       const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
01064       const CORE_ADDR addr_trap = (CORE_ADDR) siginfo.si_addr;
01065       const CORE_ADDR addr_watch = state->dr_addr_wp[i];
01066       if (state->dr_ref_count_wp[i]
01067           && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])
01068           && addr_trap >= addr_watch
01069           && addr_trap < addr_watch + len)
01070         return addr_trap;
01071     }
01072 
01073   return (CORE_ADDR) 0;
01074 }
01075 
01076 /* Returns 1 if target was stopped due to a watchpoint hit, 0
01077    otherwise.  */
01078 
01079 static int
01080 aarch64_stopped_by_watchpoint (void)
01081 {
01082   if (aarch64_stopped_data_address () != 0)
01083     return 1;
01084   else
01085     return 0;
01086 }
01087 
01088 /* Fetch the thread-local storage pointer for libthread_db.  */
01089 
01090 ps_err_e
01091 ps_get_thread_area (const struct ps_prochandle *ph,
01092                     lwpid_t lwpid, int idx, void **base)
01093 {
01094   struct iovec iovec;
01095   uint64_t reg;
01096 
01097   iovec.iov_base = &reg;
01098   iovec.iov_len = sizeof (reg);
01099 
01100   if (ptrace (PTRACE_GETREGSET, lwpid, NT_ARM_TLS, &iovec) != 0)
01101     return PS_ERR;
01102 
01103   /* IDX is the bias from the thread pointer to the beginning of the
01104      thread descriptor.  It has to be subtracted due to implementation
01105      quirks in libthread_db.  */
01106   *base = (void *) (reg - idx);
01107 
01108   return PS_OK;
01109 }
01110 
01111 /* Called when a new process is created.  */
01112 
01113 static struct arch_process_info *
01114 aarch64_linux_new_process (void)
01115 {
01116   struct arch_process_info *info = xcalloc (1, sizeof (*info));
01117 
01118   aarch64_init_debug_reg_state (&info->debug_reg_state);
01119 
01120   return info;
01121 }
01122 
01123 /* Called when a new thread is detected.  */
01124 
01125 static struct arch_lwp_info *
01126 aarch64_linux_new_thread (void)
01127 {
01128   struct arch_lwp_info *info = xcalloc (1, sizeof (*info));
01129 
01130   /* Mark that all the hardware breakpoint/watchpoint register pairs
01131      for this thread need to be initialized (with data from
01132      aarch_process_info.debug_reg_state).  */
01133   DR_MARK_ALL_CHANGED (info->dr_changed_bp, aarch64_num_bp_regs);
01134   DR_MARK_ALL_CHANGED (info->dr_changed_wp, aarch64_num_wp_regs);
01135 
01136   return info;
01137 }
01138 
01139 /* Called when resuming a thread.
01140    If the debug regs have changed, update the thread's copies.  */
01141 
01142 static void
01143 aarch64_linux_prepare_to_resume (struct lwp_info *lwp)
01144 {
01145   ptid_t ptid = ptid_of (lwp);
01146   struct arch_lwp_info *info = lwp->arch_private;
01147 
01148   if (DR_HAS_CHANGED (info->dr_changed_bp)
01149       || DR_HAS_CHANGED (info->dr_changed_wp))
01150     {
01151       int tid = ptid_get_lwp (ptid);
01152       struct process_info *proc = find_process_pid (ptid_get_pid (ptid));
01153       struct aarch64_debug_reg_state *state
01154         = &proc->private->arch_private->debug_reg_state;
01155 
01156       if (debug_hw_points)
01157         fprintf (stderr, "prepare_to_resume thread %ld\n", lwpid_of (lwp));
01158 
01159       /* Watchpoints.  */
01160       if (DR_HAS_CHANGED (info->dr_changed_wp))
01161         {
01162           aarch64_linux_set_debug_regs (state, tid, 1);
01163           DR_CLEAR_CHANGED (info->dr_changed_wp);
01164         }
01165 
01166       /* Breakpoints.  */
01167       if (DR_HAS_CHANGED (info->dr_changed_bp))
01168         {
01169           aarch64_linux_set_debug_regs (state, tid, 0);
01170           DR_CLEAR_CHANGED (info->dr_changed_bp);
01171         }
01172     }
01173 }
01174 
01175 /* ptrace hardware breakpoint resource info is formatted as follows:
01176 
01177    31             24             16               8              0
01178    +---------------+--------------+---------------+---------------+
01179    |   RESERVED    |   RESERVED   |   DEBUG_ARCH  |  NUM_SLOTS    |
01180    +---------------+--------------+---------------+---------------+  */
01181 
01182 #define AARCH64_DEBUG_NUM_SLOTS(x) ((x) & 0xff)
01183 #define AARCH64_DEBUG_ARCH(x) (((x) >> 8) & 0xff)
01184 #define AARCH64_DEBUG_ARCH_V8 0x6
01185 
01186 static void
01187 aarch64_arch_setup (void)
01188 {
01189   int pid;
01190   struct iovec iov;
01191   struct user_hwdebug_state dreg_state;
01192 
01193   current_process ()->tdesc = tdesc_aarch64;
01194 
01195   pid = lwpid_of (get_thread_lwp (current_inferior));
01196   iov.iov_base = &dreg_state;
01197   iov.iov_len = sizeof (dreg_state);
01198 
01199   /* Get hardware watchpoint register info.  */
01200   if (ptrace (PTRACE_GETREGSET, pid, NT_ARM_HW_WATCH, &iov) == 0
01201       && AARCH64_DEBUG_ARCH (dreg_state.dbg_info) == AARCH64_DEBUG_ARCH_V8)
01202     {
01203       aarch64_num_wp_regs = AARCH64_DEBUG_NUM_SLOTS (dreg_state.dbg_info);
01204       if (aarch64_num_wp_regs > AARCH64_HWP_MAX_NUM)
01205         {
01206           warning ("Unexpected number of hardware watchpoint registers reported"
01207                    " by ptrace, got %d, expected %d.",
01208                    aarch64_num_wp_regs, AARCH64_HWP_MAX_NUM);
01209           aarch64_num_wp_regs = AARCH64_HWP_MAX_NUM;
01210         }
01211     }
01212   else
01213     {
01214       warning ("Unable to determine the number of hardware watchpoints"
01215                " available.");
01216       aarch64_num_wp_regs = 0;
01217     }
01218 
01219   /* Get hardware breakpoint register info.  */
01220   if (ptrace (PTRACE_GETREGSET, pid, NT_ARM_HW_BREAK, &iov) == 0
01221       && AARCH64_DEBUG_ARCH (dreg_state.dbg_info) == AARCH64_DEBUG_ARCH_V8)
01222     {
01223       aarch64_num_bp_regs = AARCH64_DEBUG_NUM_SLOTS (dreg_state.dbg_info);
01224       if (aarch64_num_bp_regs > AARCH64_HBP_MAX_NUM)
01225         {
01226           warning ("Unexpected number of hardware breakpoint registers reported"
01227                    " by ptrace, got %d, expected %d.",
01228                    aarch64_num_bp_regs, AARCH64_HBP_MAX_NUM);
01229           aarch64_num_bp_regs = AARCH64_HBP_MAX_NUM;
01230         }
01231     }
01232   else
01233     {
01234       warning ("Unable to determine the number of hardware breakpoints"
01235                " available.");
01236       aarch64_num_bp_regs = 0;
01237     }
01238 }
01239 
01240 static struct regset_info aarch64_regsets[] =
01241 {
01242   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
01243     sizeof (struct user_pt_regs), GENERAL_REGS,
01244     aarch64_fill_gregset, aarch64_store_gregset },
01245   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET,
01246     sizeof (struct user_fpsimd_state), FP_REGS,
01247     aarch64_fill_fpregset, aarch64_store_fpregset
01248   },
01249   { 0, 0, 0, -1, -1, NULL, NULL }
01250 };
01251 
01252 static struct regsets_info aarch64_regsets_info =
01253   {
01254     aarch64_regsets, /* regsets */
01255     0, /* num_regsets */
01256     NULL, /* disabled_regsets */
01257   };
01258 
01259 static struct usrregs_info aarch64_usrregs_info =
01260   {
01261     AARCH64_NUM_REGS,
01262     aarch64_regmap,
01263   };
01264 
01265 static struct regs_info regs_info =
01266   {
01267     NULL, /* regset_bitmap */
01268     &aarch64_usrregs_info,
01269     &aarch64_regsets_info,
01270   };
01271 
01272 static const struct regs_info *
01273 aarch64_regs_info (void)
01274 {
01275   return &regs_info;
01276 }
01277 
01278 struct linux_target_ops the_low_target =
01279 {
01280   aarch64_arch_setup,
01281   aarch64_regs_info,
01282   aarch64_cannot_fetch_register,
01283   aarch64_cannot_store_register,
01284   NULL,
01285   aarch64_get_pc,
01286   aarch64_set_pc,
01287   (const unsigned char *) &aarch64_breakpoint,
01288   aarch64_breakpoint_len,
01289   NULL,
01290   0,
01291   aarch64_breakpoint_at,
01292   aarch64_insert_point,
01293   aarch64_remove_point,
01294   aarch64_stopped_by_watchpoint,
01295   aarch64_stopped_data_address,
01296   NULL,
01297   NULL,
01298   NULL,
01299   aarch64_linux_new_process,
01300   aarch64_linux_new_thread,
01301   aarch64_linux_prepare_to_resume,
01302 };
01303 
01304 void
01305 initialize_low_arch (void)
01306 {
01307   init_registers_aarch64 ();
01308 
01309   initialize_regsets_info (&aarch64_regsets_info);
01310 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines