mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-03-11 19:00:07 +01:00
(compile_reg): Take extra ia64_reg_info-pointer argument.
(build_script): Adjust for extra argument to compile_reg(). Fix the primary-NaT compilation such that it always updates IA64_REGPRI_UNAT_MEM. (run_script): For IA64_INSN_SETNET_MEMSTK, set the location based on IA64_REG_PRI_UNAT_MEM and don't forget to turn on the MEMSTK_NAT bit. (Logical change 1.178)
This commit is contained in:
parent
c4d1b80bfe
commit
d83276cb80
1 changed files with 36 additions and 20 deletions
|
@ -294,9 +294,9 @@ emit_nat_info (struct ia64_state_record *sr, int i, struct ia64_script *script)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
compile_reg (struct ia64_state_record *sr, int i, struct ia64_script *script)
|
compile_reg (struct ia64_state_record *sr, int i, struct ia64_reg_info *r,
|
||||||
|
struct ia64_script *script)
|
||||||
{
|
{
|
||||||
struct ia64_reg_info *r = sr->curr.reg + i;
|
|
||||||
enum ia64_script_insn_opcode opc;
|
enum ia64_script_insn_opcode opc;
|
||||||
unsigned long val, rval;
|
unsigned long val, rval;
|
||||||
struct ia64_script_insn insn;
|
struct ia64_script_insn insn;
|
||||||
|
@ -439,6 +439,7 @@ static inline int
|
||||||
build_script (struct cursor *c, struct ia64_script *script)
|
build_script (struct cursor *c, struct ia64_script *script)
|
||||||
{
|
{
|
||||||
int num_regs, i, ret, regorder[IA64_NUM_PREGS - 3];
|
int num_regs, i, ret, regorder[IA64_NUM_PREGS - 3];
|
||||||
|
struct ia64_reg_info *pri_unat;
|
||||||
struct ia64_state_record sr;
|
struct ia64_state_record sr;
|
||||||
struct ia64_script_insn insn;
|
struct ia64_script_insn insn;
|
||||||
|
|
||||||
|
@ -461,26 +462,36 @@ build_script (struct cursor *c, struct ia64_script *script)
|
||||||
script_emit (script, insn);
|
script_emit (script, insn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
compile_reg (&sr, IA64_REG_PSP, script);
|
compile_reg (&sr, IA64_REG_PSP, sr.curr.reg + IA64_REG_PSP, script);
|
||||||
|
|
||||||
/* Second, compile the update for the primary UNaT: */
|
/* Second, compile the update for the primary UNaT, if any: */
|
||||||
|
|
||||||
if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_GR].when)
|
if (sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_GR].when
|
||||||
i = IA64_REG_PRI_UNAT_MEM;
|
|| sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when)
|
||||||
else if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when)
|
{
|
||||||
i = IA64_REG_PRI_UNAT_GR;
|
if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_GR].when)
|
||||||
else if (sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when >
|
/* (primary) NaT bits were saved to memory only */
|
||||||
sr.curr.reg[IA64_REG_PRI_UNAT_GR].when)
|
pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM;
|
||||||
i = IA64_REG_PRI_UNAT_MEM;
|
else if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when)
|
||||||
else
|
/* (primary) NaT bits were saved to a register only */
|
||||||
i = IA64_REG_PRI_UNAT_GR;
|
pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM;
|
||||||
compile_reg (&sr, i, script);
|
else if (sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when >
|
||||||
|
sr.curr.reg[IA64_REG_PRI_UNAT_GR].when)
|
||||||
|
/* (primary) NaT bits were last saved to memory */
|
||||||
|
pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM;
|
||||||
|
else
|
||||||
|
/* (primary) NaT bits were last saved to a register */
|
||||||
|
pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_GR;
|
||||||
|
|
||||||
|
/* Note: we always store the final primary-UNaT location in UNAT_MEM. */
|
||||||
|
compile_reg (&sr, IA64_REG_PRI_UNAT_MEM, pri_unat, script);
|
||||||
|
}
|
||||||
|
|
||||||
/* Third, compile the other register in decreasing order of WHEN values. */
|
/* Third, compile the other register in decreasing order of WHEN values. */
|
||||||
|
|
||||||
num_regs = sort_regs (&sr, regorder);
|
num_regs = sort_regs (&sr, regorder);
|
||||||
for (i = 0; i < num_regs; ++i)
|
for (i = 0; i < num_regs; ++i)
|
||||||
compile_reg (&sr, regorder[i], script);
|
compile_reg (&sr, regorder[i], sr.curr.reg + regorder[i], script);
|
||||||
|
|
||||||
script->abi_marker = sr.abi_marker;
|
script->abi_marker = sr.abi_marker;
|
||||||
script_finalize (script, c, &sr);
|
script_finalize (script, c, &sr);
|
||||||
|
@ -497,9 +508,9 @@ static inline int
|
||||||
run_script (struct ia64_script *script, struct cursor *c)
|
run_script (struct ia64_script *script, struct cursor *c)
|
||||||
{
|
{
|
||||||
struct ia64_script_insn *ip, *limit, next_insn;
|
struct ia64_script_insn *ip, *limit, next_insn;
|
||||||
unw_word_t val, unat_addr;
|
|
||||||
unsigned long opc, dst;
|
unsigned long opc, dst;
|
||||||
ia64_loc_t loc;
|
ia64_loc_t loc;
|
||||||
|
unw_word_t val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
c->pi = script->pi;
|
c->pi = script->pi;
|
||||||
|
@ -550,10 +561,15 @@ run_script (struct ia64_script *script, struct cursor *c)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_INSN_SETNAT_MEMSTK:
|
case IA64_INSN_SETNAT_MEMSTK:
|
||||||
if ((ret = ia64_get (c, c->loc[IA64_REG_PRI_UNAT_MEM],
|
loc = c->loc[IA64_REG_PRI_UNAT_MEM];
|
||||||
&unat_addr)) < 0)
|
/* This is a fast and clean, if somewhat verbose way of
|
||||||
return ret;
|
turning on bit 1 in the first word. */
|
||||||
loc = IA64_LOC_ADDR (unat_addr, IA64_LOC_TYPE_MEMSTK_NAT);
|
if (IA64_IS_REG_LOC (loc))
|
||||||
|
loc = IA64_LOC_REG (IA64_GET_REG (loc),
|
||||||
|
IA64_LOC_TYPE_MEMSTK_NAT);
|
||||||
|
else
|
||||||
|
loc = IA64_LOC_ADDR (IA64_GET_ADDR (loc),
|
||||||
|
IA64_LOC_TYPE_MEMSTK_NAT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_INSN_INC_PSP:
|
case IA64_INSN_INC_PSP:
|
||||||
|
|
Loading…
Add table
Reference in a new issue