1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-06-30 21:21:45 +02:00

[HAVE_SYS_UC_ACCESS_H]: Add include of <sys/uc_access.h>.

(access_reg) [HAVE_SYS_UC_ACCESS_H]: New function.
(access_fpreg) [HAVE_SYS_UC_ACCESS_H]: New function.

(Logical change 1.75)
This commit is contained in:
mostang.com!davidm 2003-04-03 07:59:15 +00:00
parent 6ab15cdec4
commit bc41c6ad9f

View file

@ -23,12 +23,15 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <endian.h>
#include <stdlib.h>
#include "rse.h"
#include "unwind_i.h"
#ifdef HAVE_SYS_UC_ACCESS_H
# include <sys/uc_access.h>
#endif
#ifdef UNW_REMOTE_ONLY
/* unw_local_addr_space is a NULL pointer in this case. */
@ -40,6 +43,10 @@ static struct unw_addr_space local_addr_space;
unw_addr_space_t unw_local_addr_space = &local_addr_space;
#ifdef HAVE_SYS_UC_ACCESS_H
#else /* !HAVE_SYS_UC_ACCESS_H */
static inline void *
uc_addr (ucontext_t *uc, int reg)
{
@ -94,6 +101,7 @@ tdep_uc_addr (ucontext_t *uc, int reg)
}
# endif /* UNW_LOCAL_ONLY */
#endif /* !HAVE_SYS_UC_ACCESS_H */
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
@ -126,6 +134,129 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
return 0;
}
#ifdef HAVE_SYS_UC_ACCESS_H
static int
access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write,
void *arg)
{
ucontext_t *uc = arg;
unsigned int nat, mask;
uint64_t value;
int ret;
switch (reg)
{
case UNW_IA64_GR ... UNW_IA64_GR + 31:
if ((ret = __uc_get_grs (uc, (reg - UNW_IA64_GR), 1, &value, &nat)))
break;
if (write)
ret = __uc_set_grs (uc, (reg - UNW_IA64_GR), 1, val, nat);
else
*val = value;
break;
case UNW_IA64_NAT ... UNW_IA64_NAT + 31:
if ((ret = __uc_get_grs (uc, (reg - UNW_IA64_GR), 1, &value, &nat)))
break;
mask = 1 << (reg - UNW_IA64_GR);
if (write)
{
if (*val)
nat |= mask;
else
nat &= ~mask;
ret = __uc_set_grs (uc, (reg - UNW_IA64_GR), 1, &value, nat);
}
else
*val = (nat & mask) != 0;
break;
case UNW_IA64_AR ... UNW_IA64_AR + 127:
if (write)
ret = __uc_set_ar (uc, (reg - UNW_IA64_AR), *val);
else
ret = __uc_get_ar (uc, (reg - UNW_IA64_AR), val);
break;
case UNW_IA64_BR ... UNW_IA64_BR + 7:
if (write)
ret = __uc_set_brs (uc, (reg - UNW_IA64_BR), 1, val);
else
ret = __uc_get_brs (uc, (reg - UNW_IA64_BR), 1, val);
break;
case UNW_IA64_PR:
if (write)
ret = __uc_set_prs (uc, *val);
else
ret = __uc_get_prs (uc, val);
break;
case UNW_IA64_IP:
if (write)
ret = __uc_set_ip (uc, *val);
else
ret = __uc_get_ip (uc, val);
break;
case UNW_IA64_CFM:
if (write)
ret = __uc_set_cfm (uc, *val);
else
ret = __uc_get_cfm (uc, val);
break;
case UNW_IA64_FR ... UNW_IA64_FR + 127:
default:
ret = EINVAL;
break;
}
if (ret != 0)
return -UNW_EBADREG;
return 0;
}
static int
access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
int write, void *arg)
{
ucontext_t *uc = arg;
fp_regval_t fp_regval;
int ret;
switch (reg)
{
case UNW_IA64_FR ... UNW_IA64_FR + 127:
if (write)
{
memcpy (&fp_regval, val, sizeof (fp_regval));
ret = __uc_set_frs (uc, (reg - UNW_IA64_FR), 1, &fp_regval);
}
else
{
ret = __uc_get_frs (uc, (reg - UNW_IA64_FR), 1, &fp_regval);
memcpy (val, &fp_regval, sizeof (*val));
}
break;
default:
ret = EINVAL;
break;
}
if (ret != 0)
return -UNW_EBADREG;
return 0;
}
#else /* !HAVE_SYS_UC_ACCESS_H */
static int
access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write,
void *arg)
@ -211,6 +342,8 @@ access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
return -UNW_EBADREG;
}
#endif /* !HAVE_SYS_UC_ACCESS_H */
static int
get_static_proc_name (unw_addr_space_t as, unw_word_t ip,
char *buf, size_t buf_len, unw_word_t *offp,