mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-29 16:44:03 +00:00
Various improvements for ia64:
o s/TARGET_XFER_DIRTY/NATIVE_XFER_DIRTY/g to be conformant, o Handle TARGET_OBJECT_DIRTY for core files. Required on Linux, o Replace ia64_fbsd_supply_fpregs() and ia64_fbsd_supply_gregs() with supply_fpregset() and supply_gregset() resp. Needed to support libthread_db. o For target_read_partial(), pass the address of bspstore as the annex instead of bspstore itself. This fixes crossbuilds. The annex is a pointer, while bspstore is a ULONGEST. o In ia64_frame_prev_register(), handle dirty stacked registers.
This commit is contained in:
parent
1a276a3f91
commit
4fd6e2a0c9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132685
@ -17,7 +17,7 @@
|
||||
|
||||
#include "target.h"
|
||||
|
||||
#define TARGET_XFER_DIRTY ia64_fbsd_xfer_dirty
|
||||
#define NATIVE_XFER_DIRTY ia64_fbsd_xfer_dirty
|
||||
extern LONGEST ia64_fbsd_xfer_dirty(struct target_ops *, enum target_object,
|
||||
const char *, void *, const void *, ULONGEST, LONGEST);
|
||||
|
||||
|
@ -525,10 +525,10 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||
{
|
||||
case TARGET_OBJECT_MEMORY:
|
||||
if (readbuf)
|
||||
return (*ops->to_xfer_memory) (offset, readbuf, len, 0/*write*/,
|
||||
return (*ops->to_xfer_memory) (offset, readbuf, len, 0/*read*/,
|
||||
NULL, ops);
|
||||
if (writebuf)
|
||||
return (*ops->to_xfer_memory) (offset, readbuf, len, 1/*write*/,
|
||||
return (*ops->to_xfer_memory) (offset, writebuf, len, 1/*write*/,
|
||||
NULL, ops);
|
||||
return -1;
|
||||
|
||||
@ -564,6 +564,19 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||
}
|
||||
return -1;
|
||||
|
||||
case TARGET_OBJECT_DIRTY:
|
||||
{
|
||||
ULONGEST addr;
|
||||
addr = *(ULONGEST*)annex + offset;
|
||||
if (readbuf)
|
||||
return (*ops->to_xfer_memory) (addr, readbuf, len, 0/*read*/,
|
||||
NULL, ops);
|
||||
if (writebuf)
|
||||
return (*ops->to_xfer_memory) (addr, writebuf, len, 1/*write*/,
|
||||
NULL, ops);
|
||||
return -1;
|
||||
}
|
||||
|
||||
default:
|
||||
if (ops->beneath != NULL)
|
||||
return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
|
||||
|
@ -49,10 +49,6 @@ typedef struct fpreg fpregset_t;
|
||||
#define FPREG_SUPPLIES(r) ((r) >= IA64_FR0_REGNUM && (r) <= IA64_FR127_REGNUM)
|
||||
#define GREG_SUPPLIES(r) (!FPREG_SUPPLIES(r))
|
||||
|
||||
/* XXX need to go away. */
|
||||
void ia64_fbsd_supply_fpregs (void *, int);
|
||||
void ia64_fbsd_supply_gregs (void *, int);
|
||||
|
||||
void
|
||||
fetch_inferior_registers (int regno)
|
||||
{
|
||||
@ -66,9 +62,7 @@ fetch_inferior_registers (int regno)
|
||||
if (ptrace (PT_GETREGS, PIDGET(inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE)®s.r, 0) == -1)
|
||||
perror_with_name ("Couldn't get registers");
|
||||
ia64_fbsd_supply_gregs (®s.r, regno);
|
||||
if (regno != -1)
|
||||
return;
|
||||
supply_gregset (®s.r);
|
||||
}
|
||||
|
||||
if (regno == -1 || FPREG_SUPPLIES(regno))
|
||||
@ -76,9 +70,7 @@ fetch_inferior_registers (int regno)
|
||||
if (ptrace (PT_GETFPREGS, PIDGET(inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE)®s.fpr, 0) == -1)
|
||||
perror_with_name ("Couldn't get FP registers");
|
||||
ia64_fbsd_supply_fpregs (®s.fpr, regno);
|
||||
if (regno != -1)
|
||||
return;
|
||||
supply_fpregset (®s.fpr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,8 +107,18 @@ ia64_fbsd_regcache_collect (struct regcache *regcache, int regno,
|
||||
return;
|
||||
|
||||
ofs = reg_offset[regno];
|
||||
if (ofs >= 0)
|
||||
regcache_raw_collect (regcache, regno, (char*)regs + ofs);
|
||||
if (regno == IA64_BSP_REGNUM)
|
||||
{
|
||||
uint64_t bsp, bspstore;
|
||||
regcache_raw_collect (regcache, regno, &bsp);
|
||||
regcache_raw_collect (regcache, IA64_BSPSTORE_REGNUM, &bspstore);
|
||||
*(uint64_t *)((char *)regs + ofs) = bsp - bspstore;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ofs >= 0)
|
||||
regcache_raw_collect (regcache, regno, (char*)regs + ofs);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -178,17 +188,11 @@ fill_gregset (void *gregs, int regno)
|
||||
}
|
||||
|
||||
void
|
||||
ia64_fbsd_supply_fpregs (const void *fpregs, int regno)
|
||||
supply_fpregset (const void *fpregs)
|
||||
{
|
||||
if (regno == -1)
|
||||
{
|
||||
for (regno = 0; regno < NUM_REGS; regno++)
|
||||
{
|
||||
if (FPREG_SUPPLIES(regno))
|
||||
ia64_fbsd_regcache_supply (current_regcache, regno, fpregs);
|
||||
}
|
||||
}
|
||||
else
|
||||
int regno;
|
||||
|
||||
for (regno = 0; regno < NUM_REGS; regno++)
|
||||
{
|
||||
if (FPREG_SUPPLIES(regno))
|
||||
ia64_fbsd_regcache_supply (current_regcache, regno, fpregs);
|
||||
@ -196,17 +200,11 @@ ia64_fbsd_supply_fpregs (const void *fpregs, int regno)
|
||||
}
|
||||
|
||||
void
|
||||
ia64_fbsd_supply_gregs (const void *gregs, int regno)
|
||||
supply_gregset (const void *gregs)
|
||||
{
|
||||
if (regno == -1)
|
||||
{
|
||||
for (regno = 0; regno < NUM_REGS; regno++)
|
||||
{
|
||||
if (GREG_SUPPLIES(regno))
|
||||
ia64_fbsd_regcache_supply (current_regcache, regno, gregs);
|
||||
}
|
||||
}
|
||||
else
|
||||
int regno;
|
||||
|
||||
for (regno = 0; regno < NUM_REGS; regno++)
|
||||
{
|
||||
if (GREG_SUPPLIES(regno))
|
||||
ia64_fbsd_regcache_supply (current_regcache, regno, gregs);
|
||||
|
@ -667,7 +667,7 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
regnum), reg);
|
||||
} else
|
||||
target_read_partial (¤t_target, TARGET_OBJECT_DIRTY,
|
||||
(void*)bspstore, buf, reg_addr - bspstore,
|
||||
(void*)&bspstore, buf, reg_addr - bspstore,
|
||||
register_size (current_gdbarch, regnum));
|
||||
}
|
||||
else
|
||||
@ -718,7 +718,7 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
else {
|
||||
char natbuf[8];
|
||||
target_read_partial (¤t_target, TARGET_OBJECT_DIRTY,
|
||||
(void*)bspstore, natbuf,
|
||||
(void*)&bspstore, natbuf,
|
||||
nat_addr - bspstore,
|
||||
register_size (current_gdbarch, regnum));
|
||||
nat_collection = *((uint64_t*)natbuf);
|
||||
@ -795,7 +795,7 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
write_memory (reg_addr, (void *)buf, 8);
|
||||
else
|
||||
target_write_partial (¤t_target, TARGET_OBJECT_DIRTY,
|
||||
(void*)bspstore, buf, reg_addr - bspstore,
|
||||
(void*)&bspstore, buf, reg_addr - bspstore,
|
||||
register_size (current_gdbarch, regnum));
|
||||
}
|
||||
}
|
||||
@ -859,7 +859,7 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
else {
|
||||
char natbuf[8];
|
||||
target_read_partial (¤t_target, TARGET_OBJECT_DIRTY,
|
||||
(void*)bspstore, natbuf,
|
||||
(void*)&bspstore, natbuf,
|
||||
nat_addr - bspstore,
|
||||
register_size (current_gdbarch, regnum));
|
||||
nat_collection = *((uint64_t*)natbuf);
|
||||
@ -875,7 +875,7 @@ ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
write_memory (nat_addr, nat_buf, 8);
|
||||
else
|
||||
target_write_partial (¤t_target, TARGET_OBJECT_DIRTY,
|
||||
(void*)bspstore, nat_buf,
|
||||
(void*)&bspstore, nat_buf,
|
||||
nat_addr - bspstore,
|
||||
register_size (current_gdbarch, regnum));
|
||||
}
|
||||
@ -1828,6 +1828,8 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
|
||||
CORE_ADDR r_addr;
|
||||
CORE_ADDR prev_cfm, prev_bsp, prev_bof;
|
||||
CORE_ADDR addr = 0;
|
||||
ULONGEST bspstore;
|
||||
|
||||
if (regnum >= V32_REGNUM)
|
||||
regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
|
||||
ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
|
||||
@ -1839,10 +1841,24 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
|
||||
prev_bof = rse_address_add (prev_bsp, -(prev_cfm & 0x7f));
|
||||
|
||||
addr = rse_address_add (prev_bof, (regnum - IA64_GR32_REGNUM));
|
||||
/* XXX marcel */
|
||||
*lvalp = lval_memory;
|
||||
*addrp = addr;
|
||||
read_memory (addr, valuep, register_size (current_gdbarch, regnum));
|
||||
|
||||
/* Figure out if the register was already flushed or is dirty.
|
||||
If the register was flushed already we can return the address
|
||||
on the backingstore for it. */
|
||||
regcache_cooked_read_unsigned (current_regcache, IA64_BSPSTORE_REGNUM,
|
||||
&bspstore);
|
||||
if (addr < bspstore)
|
||||
{
|
||||
*lvalp = lval_memory;
|
||||
*addrp = addr;
|
||||
read_memory (addr, valuep, register_size (current_gdbarch, regnum));
|
||||
}
|
||||
else
|
||||
{
|
||||
target_read_partial (¤t_target, TARGET_OBJECT_DIRTY,
|
||||
(void*)&bspstore, valuep, addr - bspstore,
|
||||
register_size (current_gdbarch, regnum));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -593,10 +593,10 @@ child_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||
offset, len);
|
||||
|
||||
case TARGET_OBJECT_DIRTY:
|
||||
#ifndef TARGET_XFER_DIRTY
|
||||
#define TARGET_XFER_DIRTY(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1)
|
||||
#ifndef NATIVE_XFER_DIRTY
|
||||
#define NATIVE_XFER_DIRTY(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1)
|
||||
#endif
|
||||
return TARGET_XFER_DIRTY (ops, object, annex, readbuf, writebuf,
|
||||
return NATIVE_XFER_DIRTY (ops, object, annex, readbuf, writebuf,
|
||||
offset, len);
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user