GDB (API)
/home/stan/gdb/src/gdb/ia64-hpux-nat.c
Go to the documentation of this file.
00001 /* Copyright (C) 2010-2013 Free Software Foundation, Inc.
00002 
00003    This file is part of GDB.
00004 
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 3 of the License, or
00008    (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00017 
00018 #include "defs.h"
00019 #include "ia64-tdep.h"
00020 #include "inferior.h"
00021 #include "inf-ttrace.h"
00022 #include "regcache.h"
00023 #include "solib-ia64-hpux.h"
00024 
00025 #include <ia64/sys/uregs.h>
00026 #include <sys/ttrace.h>
00027 
00028 /* The offsets used with ttrace to read the value of the raw registers.  */
00029 
00030 static int u_offsets[] =
00031 { /* Static General Registers.  */
00032   -1,     __r1,   __r2,   __r3,   __r4,   __r5,   __r6,   __r7,
00033   __r8,   __r9,   __r10,  __r11,  __r12,  __r13,  __r14,  __r15,
00034   __r16,  __r17,  __r18,  __r19,  __r20,  __r21,  __r22,  __r23,
00035   __r24,  __r25,  __r26,  __r27,  __r28,  __r29,  __r30,  __r31,
00036   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00037   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00038   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00039   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00040   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00041   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00042   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00043   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00044   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00045   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00046   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00047   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00048 
00049   /* Static Floating-Point Registers.  */
00050     -1,     -1,   __f2,   __f3,   __f4,   __f5,   __f6,   __f7,
00051   __f8,   __f9,   __f10,  __f11,  __f12,  __f13,  __f14,  __f15,
00052   __f16,  __f17,  __f18,  __f19,  __f20,  __f21,  __f22,  __f23,
00053   __f24,  __f25,  __f26,  __f27,  __f28,  __f29,  __f30,  __f31,
00054   __f32,  __f33,  __f34,  __f35,  __f36,  __f37,  __f38,  __f39,
00055   __f40,  __f41,  __f42,  __f43,  __f44,  __f45,  __f46,  __f47,
00056   __f48,  __f49,  __f50,  __f51,  __f52,  __f53,  __f54,  __f55,
00057   __f56,  __f57,  __f58,  __f59,  __f60,  __f61,  __f62,  __f63,
00058   __f64,  __f65,  __f66,  __f67,  __f68,  __f69,  __f70,  __f71,
00059   __f72,  __f73,  __f74,  __f75,  __f76,  __f77,  __f78,  __f79,
00060   __f80,  __f81,  __f82,  __f83,  __f84,  __f85,  __f86,  __f87,
00061   __f88,  __f89,  __f90,  __f91,  __f92,  __f93,  __f94,  __f95,
00062   __f96,  __f97,  __f98,  __f99,  __f100, __f101, __f102, __f103,
00063   __f104, __f105, __f106, __f107, __f108, __f109, __f110, __f111,
00064   __f112, __f113, __f114, __f115, __f116, __f117, __f118, __f119,
00065   __f120, __f121, __f122, __f123, __f124, __f125, __f126, __f127,
00066 
00067   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00068   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00069   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00070   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00071   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00072   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00073   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00074   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
00075 
00076   /* Branch Registers.  */
00077   __b0,   __b1,   __b2,   __b3,   __b4,   __b5,   __b6,   __b7,
00078 
00079   /* Virtual frame pointer and virtual return address pointer.  */
00080   -1, -1,
00081 
00082   /* Other registers.  */
00083   __pr, __ip, __cr_ipsr, __cfm,
00084 
00085   /* Kernel registers.  */
00086   -1,   -1,   -1,   -1,
00087   -1,   -1,   -1,   -1,
00088 
00089   -1, -1, -1, -1, -1, -1, -1, -1,
00090 
00091   /* Some application registers.  */
00092   __ar_rsc, __ar_bsp, __ar_bspstore, __ar_rnat,
00093 
00094   -1,
00095   -1,  /* Not available: FCR, IA32 floating control register.  */
00096   -1, -1,
00097 
00098   -1,         /* Not available: EFLAG.  */
00099   -1,         /* Not available: CSD.  */
00100   -1,         /* Not available: SSD.  */
00101   -1,         /* Not available: CFLG.  */
00102   -1,         /* Not available: FSR.  */
00103   -1,         /* Not available: FIR.  */
00104   -1,         /* Not available: FDR.  */
00105   -1,
00106   __ar_ccv, -1, -1, -1, __ar_unat, -1, -1, -1,
00107   __ar_fpsr, -1, -1, -1,
00108   -1,         /* Not available: ITC.  */
00109   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00110   -1, -1, -1, -1, -1, -1, -1, -1, -1,
00111   __ar_pfs, __ar_lc, __ar_ec,
00112   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00113   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00114   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00115   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00116   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00117   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00118   -1
00119   /* All following registers, starting with nat0, are handled as
00120      pseudo registers, and hence are handled separately.  */
00121 };
00122 
00123 /* Some register have a fixed value and can not be modified.
00124    Store their value in static constant buffers that can be used
00125    later to fill the register cache.  */
00126 static const char r0_value[8] = {0x00, 0x00, 0x00, 0x00,
00127                                  0x00, 0x00, 0x00, 0x00};
00128 static const char f0_value[16] = {0x00, 0x00, 0x00, 0x00,
00129                                   0x00, 0x00, 0x00, 0x00,
00130                                   0x00, 0x00, 0x00, 0x00,
00131                                   0x00, 0x00, 0x00, 0x00};
00132 static const char f1_value[16] = {0x00, 0x00, 0x00, 0x00,
00133                                   0x00, 0x00, 0xff, 0xff,
00134                                   0x80, 0x00, 0x00, 0x00,
00135                                   0x00, 0x00, 0x00, 0x00};
00136 
00137 /* The "to_wait" routine from the "inf-ttrace" layer.  */
00138 
00139 static ptid_t (*super_to_wait) (struct target_ops *, ptid_t,
00140                                 struct target_waitstatus *, int);
00141 
00142 /* The "to_wait" target_ops routine routine for ia64-hpux.  */
00143 
00144 static ptid_t
00145 ia64_hpux_wait (struct target_ops *ops, ptid_t ptid,
00146                 struct target_waitstatus *ourstatus, int options)
00147 {
00148   ptid_t new_ptid;
00149 
00150   new_ptid = super_to_wait (ops, ptid, ourstatus, options);
00151 
00152   /* If this is a DLD event (hard-coded breakpoint instruction
00153      that was activated by the solib-ia64-hpux module), we need to
00154      process it, and then resume the execution as if the event did
00155      not happen.  */
00156   if (ourstatus->kind == TARGET_WAITKIND_STOPPED
00157       && ourstatus->value.sig == GDB_SIGNAL_TRAP
00158       && ia64_hpux_at_dld_breakpoint_p (new_ptid))
00159     {
00160       ia64_hpux_handle_dld_breakpoint (new_ptid);
00161 
00162       target_resume (new_ptid, 0, GDB_SIGNAL_0);
00163       ourstatus->kind = TARGET_WAITKIND_IGNORE;
00164     }
00165 
00166   return new_ptid;
00167 }
00168 
00169 /* Fetch the RNAT register and supply it to the REGCACHE.  */
00170 
00171 static void
00172 ia64_hpux_fetch_rnat_register (struct regcache *regcache)
00173 {
00174   CORE_ADDR addr;
00175   gdb_byte buf[8];
00176   int status;
00177 
00178   /* The value of RNAT is stored at bsp|0x1f8, and must be read using
00179      TT_LWP_RDRSEBS.  */
00180 
00181   regcache_raw_read_unsigned (regcache, IA64_BSP_REGNUM, &addr);
00182   addr |= 0x1f8;
00183 
00184   status = ttrace (TT_LWP_RDRSEBS, ptid_get_pid (inferior_ptid),
00185                    ptid_get_lwp (inferior_ptid), addr, sizeof (buf),
00186                    (uintptr_t) buf);
00187   if (status < 0)
00188     error (_("failed to read RNAT register at %s"),
00189            paddress (get_regcache_arch(regcache), addr));
00190 
00191   regcache_raw_supply (regcache, IA64_RNAT_REGNUM, buf);
00192 }
00193 
00194 /* Read the value of the register saved at OFFSET in the save_state_t
00195    structure, and store its value in BUF.  LEN is the size of the register
00196    to be read.  */
00197 
00198 static int
00199 ia64_hpux_read_register_from_save_state_t (int offset, gdb_byte *buf, int len)
00200 {
00201   int status;
00202 
00203  status = ttrace (TT_LWP_RUREGS, ptid_get_pid (inferior_ptid),
00204                   ptid_get_lwp (inferior_ptid), offset, len, (uintptr_t) buf);
00205 
00206   return status;
00207 }
00208 
00209 /* Fetch register REGNUM from the inferior.  */
00210 
00211 static void
00212 ia64_hpux_fetch_register (struct regcache *regcache, int regnum)
00213 {
00214   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00215   int offset, len, status;
00216   gdb_byte *buf;
00217 
00218   if (regnum == IA64_GR0_REGNUM)
00219     {
00220       /* r0 is always 0.  */
00221       regcache_raw_supply (regcache, regnum, r0_value);
00222       return;
00223     }
00224 
00225   if (regnum == IA64_FR0_REGNUM)
00226     {
00227       /* f0 is always 0.0.  */
00228       regcache_raw_supply (regcache, regnum, f0_value);
00229       return;
00230     }
00231 
00232   if (regnum == IA64_FR1_REGNUM)
00233     {
00234       /* f1 is always 1.0.  */
00235       regcache_raw_supply (regcache, regnum, f1_value);
00236       return;
00237     }
00238 
00239   if (regnum == IA64_RNAT_REGNUM)
00240     {
00241       ia64_hpux_fetch_rnat_register (regcache);
00242       return;
00243     }
00244 
00245   /* Get the register location. If the register can not be fetched,
00246      then return now.  */
00247   offset = u_offsets[regnum];
00248   if (offset == -1)
00249     return;
00250 
00251   len = register_size (gdbarch, regnum);
00252   buf = alloca (len * sizeof (gdb_byte));
00253   status = ia64_hpux_read_register_from_save_state_t (offset, buf, len);
00254   if (status < 0)
00255     warning (_("Failed to read register value for %s."),
00256              gdbarch_register_name (gdbarch, regnum));
00257 
00258   regcache_raw_supply (regcache, regnum, buf);
00259 }
00260 
00261 /* The "to_fetch_registers" target_ops routine for ia64-hpux.  */
00262 
00263 static void
00264 ia64_hpux_fetch_registers (struct target_ops *ops,
00265                            struct regcache *regcache, int regnum)
00266 {
00267   if (regnum == -1)
00268     for (regnum = 0;
00269          regnum < gdbarch_num_regs (get_regcache_arch (regcache));
00270          regnum++)
00271       ia64_hpux_fetch_register (regcache, regnum);
00272   else
00273     ia64_hpux_fetch_register (regcache, regnum);
00274 }
00275 
00276 /* Save register REGNUM (stored in BUF) in the save_state_t structure.
00277    LEN is the size of the register in bytes.
00278 
00279    Return the value from the corresponding ttrace call (a negative value
00280    means that the operation failed).  */
00281 
00282 static int
00283 ia64_hpux_write_register_to_saved_state_t (int offset, gdb_byte *buf, int len)
00284 {
00285   return ttrace (TT_LWP_WUREGS, ptid_get_pid (inferior_ptid),
00286                  ptid_get_lwp (inferior_ptid), offset, len, (uintptr_t) buf);
00287 }
00288 
00289 /* Store register REGNUM into the inferior.  */
00290 
00291 static void
00292 ia64_hpux_store_register (const struct regcache *regcache, int regnum)
00293 {
00294   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00295   int offset = u_offsets[regnum];
00296   gdb_byte *buf;
00297   int len, status;
00298 
00299   /* If the register can not be stored, then return now.  */
00300   if (offset == -1)
00301     return;
00302 
00303   /* I don't know how to store that register for now.  So just ignore any
00304      request to store it, to avoid an internal error.  */
00305   if (regnum == IA64_PSR_REGNUM)
00306     return;
00307 
00308   len = register_size (gdbarch, regnum);
00309   buf = alloca (len * sizeof (gdb_byte));
00310   regcache_raw_collect (regcache, regnum, buf);
00311 
00312   status = ia64_hpux_write_register_to_saved_state_t (offset, buf, len);
00313 
00314   if (status < 0)
00315     error (_("failed to write register value for %s."),
00316            gdbarch_register_name (gdbarch, regnum));
00317 }
00318 
00319 /* The "to_store_registers" target_ops routine for ia64-hpux.  */
00320 
00321 static void
00322 ia64_hpux_store_registers (struct target_ops *ops,
00323                            struct regcache *regcache, int regnum)
00324 {
00325   if (regnum == -1)
00326     for (regnum = 0;
00327          regnum < gdbarch_num_regs (get_regcache_arch (regcache));
00328          regnum++)
00329       ia64_hpux_store_register (regcache, regnum);
00330   else
00331     ia64_hpux_store_register (regcache, regnum);
00332 }
00333 
00334 /* The "xfer_partial" routine from the "inf-ttrace" target layer.
00335    Ideally, we would like to use this routine for all transfer
00336    requests, but this platforms has a lot of special cases that
00337    need to be handled manually.  So we override this routine and
00338    delegate back if we detect that we are not in a special case.  */
00339 
00340 static LONGEST (*super_xfer_partial) (struct target_ops *, enum target_object,
00341                                       const char *, gdb_byte *,
00342                                       const gdb_byte *, ULONGEST, LONGEST);
00343 
00344 /* The "xfer_partial" routine for a memory region that is completely
00345    outside of the backing-store region.  */
00346 
00347 static LONGEST
00348 ia64_hpux_xfer_memory_no_bs (struct target_ops *ops, const char *annex,
00349                              gdb_byte *readbuf, const gdb_byte *writebuf,
00350                              CORE_ADDR addr, LONGEST len)
00351 {
00352   /* Memory writes need to be aligned on 16byte boundaries, at least
00353      when writing in the text section.  On the other hand, the size
00354      of the buffer does not need to be a multiple of 16bytes.
00355 
00356      No such restriction when performing memory reads.  */
00357 
00358   if (writebuf && addr & 0x0f)
00359     {
00360       const CORE_ADDR aligned_addr = addr & ~0x0f;
00361       const int aligned_len = len + (addr - aligned_addr);
00362       gdb_byte *aligned_buf = alloca (aligned_len * sizeof (gdb_byte));
00363       LONGEST status;
00364 
00365       /* Read the portion of memory between ALIGNED_ADDR and ADDR, so
00366          that we can write it back during our aligned memory write.  */
00367       status = super_xfer_partial (ops, TARGET_OBJECT_MEMORY, annex,
00368                                    aligned_buf /* read */,
00369                                    NULL /* write */,
00370                                    aligned_addr, addr - aligned_addr);
00371       if (status <= 0)
00372         return 0;
00373       memcpy (aligned_buf + (addr - aligned_addr), writebuf, len);
00374 
00375       return super_xfer_partial (ops, TARGET_OBJECT_MEMORY, annex,
00376                                  NULL /* read */, aligned_buf /* write */,
00377                                  aligned_addr, aligned_len);
00378     }
00379   else
00380     /* Memory read or properly aligned memory write.  */
00381     return super_xfer_partial (ops, TARGET_OBJECT_MEMORY, annex, readbuf,
00382                                writebuf, addr, len);
00383 }
00384 
00385 /* Read LEN bytes at ADDR from memory, and store it in BUF.  This memory
00386    region is assumed to be inside the backing store.
00387 
00388    Return zero if the operation failed.  */
00389 
00390 static int
00391 ia64_hpux_read_memory_bs (gdb_byte *buf, CORE_ADDR addr, int len)
00392 {
00393   gdb_byte tmp_buf[8];
00394   CORE_ADDR tmp_addr = addr & ~0x7;
00395 
00396   while (tmp_addr < addr + len)
00397     {
00398       int status;
00399       int skip_lo = 0;
00400       int skip_hi = 0;
00401 
00402       status = ttrace (TT_LWP_RDRSEBS, ptid_get_pid (inferior_ptid),
00403                        ptid_get_lwp (inferior_ptid), tmp_addr,
00404                        sizeof (tmp_buf), (uintptr_t) tmp_buf);
00405       if (status < 0)
00406         return 0;
00407 
00408       if (tmp_addr < addr)
00409         skip_lo = addr - tmp_addr;
00410 
00411       if (tmp_addr + sizeof (tmp_buf) > addr + len)
00412         skip_hi = (tmp_addr + sizeof (tmp_buf)) - (addr + len);
00413 
00414       memcpy (buf + (tmp_addr + skip_lo - addr),
00415               tmp_buf + skip_lo,
00416               sizeof (tmp_buf) - skip_lo - skip_hi);
00417 
00418       tmp_addr += sizeof (tmp_buf);
00419     }
00420 
00421   return 1;
00422 }
00423 
00424 /* Write LEN bytes from BUF in memory at ADDR.  This memory region is assumed
00425    to be inside the backing store.
00426 
00427    Return zero if the operation failed.  */
00428 
00429 static int
00430 ia64_hpux_write_memory_bs (const gdb_byte *buf, CORE_ADDR addr, int len)
00431 {
00432   gdb_byte tmp_buf[8];
00433   CORE_ADDR tmp_addr = addr & ~0x7;
00434 
00435   while (tmp_addr < addr + len)
00436     {
00437       int status;
00438       int lo = 0;
00439       int hi = 7;
00440 
00441       if (tmp_addr < addr || tmp_addr + sizeof (tmp_buf) > addr + len)
00442         /* Part of the 8byte region pointed by tmp_addr needs to be preserved.
00443            So read it in before we copy the data that needs to be changed.  */
00444         if (!ia64_hpux_read_memory_bs (tmp_buf, tmp_addr, sizeof (tmp_buf)))
00445           return 0;
00446 
00447       if (tmp_addr < addr)
00448         lo = addr - tmp_addr;
00449 
00450       if (tmp_addr + sizeof (tmp_buf) > addr + len)
00451         hi = addr - tmp_addr + len - 1;
00452 
00453       memcpy (tmp_buf + lo, buf + tmp_addr - addr  + lo, hi - lo + 1);
00454 
00455       status = ttrace (TT_LWP_WRRSEBS, ptid_get_pid (inferior_ptid),
00456                        ptid_get_lwp (inferior_ptid), tmp_addr,
00457                        sizeof (tmp_buf), (uintptr_t) tmp_buf);
00458       if (status < 0)
00459         return 0;
00460 
00461       tmp_addr += sizeof (tmp_buf);
00462     }
00463 
00464   return 1;
00465 }
00466 
00467 /* The "xfer_partial" routine for a memory region that is completely
00468    inside of the backing-store region.  */
00469 
00470 static LONGEST
00471 ia64_hpux_xfer_memory_bs (struct target_ops *ops, const char *annex,
00472                           gdb_byte *readbuf, const gdb_byte *writebuf,
00473                           CORE_ADDR addr, LONGEST len)
00474 {
00475   int success;
00476 
00477   if (readbuf)
00478     success = ia64_hpux_read_memory_bs (readbuf, addr, len);
00479   else
00480     success = ia64_hpux_write_memory_bs (writebuf, addr, len);
00481 
00482   if (success)
00483     return len;
00484   else
00485     return 0;
00486 }
00487 
00488 /* Get a register value as a unsigned value directly from the system,
00489    instead of going through the regcache.
00490 
00491    This function is meant to be used when inferior_ptid is not
00492    a thread/process known to GDB.  */
00493 
00494 static ULONGEST
00495 ia64_hpux_get_register_from_save_state_t (int regnum, int reg_size)
00496 {
00497   gdb_byte *buf = alloca (reg_size);
00498   int offset = u_offsets[regnum];
00499   int status;
00500 
00501   /* The register is assumed to be available for fetching.  */
00502   gdb_assert (offset != -1);
00503 
00504   status = ia64_hpux_read_register_from_save_state_t (offset, buf, reg_size);
00505   if (status < 0)
00506     {
00507       /* This really should not happen.  If it does, emit a warning
00508          and pretend the register value is zero.  Not exactly the best
00509          error recovery mechanism, but better than nothing.  We will
00510          try to do better if we can demonstrate that this can happen
00511          under normal circumstances.  */
00512       warning (_("Failed to read value of register number %d."), regnum);
00513       return 0;
00514     }
00515 
00516   return extract_unsigned_integer (buf, reg_size, BFD_ENDIAN_BIG);
00517 }
00518 
00519 /* The "xfer_partial" target_ops routine for ia64-hpux, in the case
00520    where the requested object is TARGET_OBJECT_MEMORY.  */
00521 
00522 static LONGEST
00523 ia64_hpux_xfer_memory (struct target_ops *ops, const char *annex,
00524                        gdb_byte *readbuf, const gdb_byte *writebuf,
00525                        CORE_ADDR addr, LONGEST len)
00526 {
00527   CORE_ADDR bsp, bspstore;
00528   CORE_ADDR start_addr, short_len;
00529   int status = 0;
00530 
00531   /* The back-store region cannot be read/written by the standard memory
00532      read/write operations.  So we handle the memory region piecemeal:
00533        (1) and (2) The regions before and after the backing-store region,
00534            which can be treated as normal memory;
00535        (3) The region inside the backing-store, which needs to be
00536            read/written specially.  */
00537 
00538   if (in_inferior_list (ptid_get_pid (inferior_ptid)))
00539     {
00540       struct regcache *regcache = get_current_regcache ();
00541 
00542       regcache_raw_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
00543       regcache_raw_read_unsigned (regcache, IA64_BSPSTORE_REGNUM, &bspstore);
00544     }
00545   else
00546     {
00547       /* This is probably a child of our inferior created by a fork.
00548          Because this process has not been added to our inferior list
00549          (we are probably in the process of handling that child
00550          process), we do not have a regcache to read the registers
00551          from.  So get those values directly from the kernel.  */
00552       bsp = ia64_hpux_get_register_from_save_state_t (IA64_BSP_REGNUM, 8);
00553       bspstore =
00554         ia64_hpux_get_register_from_save_state_t (IA64_BSPSTORE_REGNUM, 8);
00555     }
00556 
00557   /* 1. Memory region before BSPSTORE.  */
00558 
00559   if (addr < bspstore)
00560     {
00561       short_len = len;
00562       if (addr + len > bspstore)
00563         short_len = bspstore - addr;
00564 
00565       status = ia64_hpux_xfer_memory_no_bs (ops, annex, readbuf, writebuf,
00566                                             addr, short_len);
00567       if (status <= 0)
00568         return 0;
00569     }
00570 
00571   /* 2. Memory region after BSP.  */
00572 
00573   if (addr + len > bsp)
00574     {
00575       start_addr = addr;
00576       if (start_addr < bsp)
00577         start_addr = bsp;
00578       short_len = len + addr - start_addr;
00579 
00580       status = ia64_hpux_xfer_memory_no_bs
00581                 (ops, annex,
00582                  readbuf ? readbuf + (start_addr - addr) : NULL,
00583                  writebuf ? writebuf + (start_addr - addr) : NULL,
00584                  start_addr, short_len);
00585       if (status <= 0)
00586         return 0;
00587     }
00588 
00589   /* 3. Memory region between BSPSTORE and BSP.  */
00590 
00591   if (bspstore != bsp
00592       && ((addr < bspstore && addr + len > bspstore)
00593           || (addr + len <= bsp && addr + len > bsp)))
00594     {
00595       start_addr = addr;
00596       if (addr < bspstore)
00597         start_addr = bspstore;
00598       short_len = len + addr - start_addr;
00599 
00600       if (start_addr + short_len > bsp)
00601         short_len = bsp - start_addr;
00602 
00603       gdb_assert (short_len > 0);
00604 
00605       status = ia64_hpux_xfer_memory_bs
00606                  (ops, annex,
00607                   readbuf ? readbuf + (start_addr - addr) : NULL,
00608                   writebuf ? writebuf + (start_addr - addr) : NULL,
00609                   start_addr, short_len);
00610       if (status < 0)
00611         return 0;
00612     }
00613 
00614   return len;
00615 }
00616 
00617 /* Handle the transfer of TARGET_OBJECT_HPUX_UREGS objects on ia64-hpux.
00618    ANNEX is currently ignored.
00619 
00620    The current implementation does not support write transfers (because
00621    we do not currently do not need these transfers), and will raise
00622    a failed assertion if WRITEBUF is not NULL.  */
00623 
00624 static LONGEST
00625 ia64_hpux_xfer_uregs (struct target_ops *ops, const char *annex,
00626                       gdb_byte *readbuf, const gdb_byte *writebuf,
00627                       ULONGEST offset, LONGEST len)
00628 {
00629   int status;
00630 
00631   gdb_assert (writebuf == NULL);
00632 
00633   status = ia64_hpux_read_register_from_save_state_t (offset, readbuf, len);
00634   if (status < 0)
00635     return -1;
00636   return len;
00637 }
00638 
00639 /* Handle the transfer of TARGET_OBJECT_HPUX_SOLIB_GOT objects on ia64-hpux.
00640 
00641    The current implementation does not support write transfers (because
00642    we do not currently do not need these transfers), and will raise
00643    a failed assertion if WRITEBUF is not NULL.  */
00644 
00645 static LONGEST
00646 ia64_hpux_xfer_solib_got (struct target_ops *ops, const char *annex,
00647                           gdb_byte *readbuf, const gdb_byte *writebuf,
00648                           ULONGEST offset, LONGEST len)
00649 {
00650   CORE_ADDR fun_addr;
00651   /* The linkage pointer.  We use a uint64_t to make sure that the size
00652      of the object we are returning is always 64 bits long, as explained
00653      in the description of the TARGET_OBJECT_HPUX_SOLIB_GOT object.
00654      This is probably paranoia, but we do not use a CORE_ADDR because
00655      it could conceivably be larger than uint64_t.  */
00656   uint64_t got;
00657 
00658   gdb_assert (writebuf == NULL);
00659 
00660   if (offset > sizeof (got))
00661     return 0;
00662 
00663   fun_addr = string_to_core_addr (annex);
00664   got = ia64_hpux_get_solib_linkage_addr (fun_addr);
00665 
00666   if (len > sizeof (got) - offset)
00667     len = sizeof (got) - offset;
00668   memcpy (readbuf, &got + offset, len);
00669 
00670   return len;
00671 }
00672 
00673 /* The "to_xfer_partial" target_ops routine for ia64-hpux.  */
00674 
00675 static LONGEST
00676 ia64_hpux_xfer_partial (struct target_ops *ops, enum target_object object,
00677                         const char *annex, gdb_byte *readbuf,
00678                         const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
00679 {
00680   LONGEST val;
00681 
00682   if (object == TARGET_OBJECT_MEMORY)
00683     val = ia64_hpux_xfer_memory (ops, annex, readbuf, writebuf, offset, len);
00684   else if (object == TARGET_OBJECT_HPUX_UREGS)
00685     val = ia64_hpux_xfer_uregs (ops, annex, readbuf, writebuf, offset, len);
00686   else if (object == TARGET_OBJECT_HPUX_SOLIB_GOT)
00687     val = ia64_hpux_xfer_solib_got (ops, annex, readbuf, writebuf, offset,
00688                                     len);
00689   else
00690     val = super_xfer_partial (ops, object, annex, readbuf, writebuf, offset,
00691                               len);
00692 
00693   return val;
00694 }
00695 
00696 /* The "to_can_use_hw_breakpoint" target_ops routine for ia64-hpux.  */
00697 
00698 static int
00699 ia64_hpux_can_use_hw_breakpoint (int type, int cnt, int othertype)
00700 {
00701   /* No hardware watchpoint/breakpoint support yet.  */
00702   return 0;
00703 }
00704 
00705 /* The "to_mourn_inferior" routine from the "inf-ttrace" target_ops layer.  */
00706 
00707 static void (*super_mourn_inferior) (struct target_ops *);
00708 
00709 /* The "to_mourn_inferior" target_ops routine for ia64-hpux.  */
00710 
00711 static void
00712 ia64_hpux_mourn_inferior (struct target_ops *ops)
00713 {
00714   const int pid = ptid_get_pid (inferior_ptid);
00715   int status;
00716 
00717   super_mourn_inferior (ops);
00718 
00719   /* On this platform, the process still exists even after we received
00720      an exit event.  Detaching from the process isn't sufficient either,
00721      as it only turns the process into a zombie.  So the only solution
00722      we found is to kill it.  */
00723   ttrace (TT_PROC_EXIT, pid, 0, 0, 0, 0);
00724   wait (&status);
00725 }
00726 
00727 /* Prevent warning from -Wmissing-prototypes.  */
00728 void _initialize_ia64_hpux_nat (void);
00729 
00730 void
00731 _initialize_ia64_hpux_nat (void)
00732 {
00733   struct target_ops *t;
00734 
00735   t = inf_ttrace_target ();
00736   super_to_wait = t->to_wait;
00737   super_xfer_partial = t->to_xfer_partial;
00738   super_mourn_inferior = t->to_mourn_inferior;
00739 
00740   t->to_wait = ia64_hpux_wait;
00741   t->to_fetch_registers = ia64_hpux_fetch_registers;
00742   t->to_store_registers = ia64_hpux_store_registers;
00743   t->to_xfer_partial = ia64_hpux_xfer_partial;
00744   t->to_can_use_hw_breakpoint = ia64_hpux_can_use_hw_breakpoint;
00745   t->to_mourn_inferior = ia64_hpux_mourn_inferior;
00746   t->to_attach_no_wait = 1;
00747 
00748   add_target (t);
00749 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines