1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-15 20:58:13 +01:00

(Logical change 1.162)

This commit is contained in:
hp.com!davidm 2004-01-30 00:01:24 +00:00
parent 107cf10470
commit ab847fe68e
14 changed files with 708 additions and 0 deletions

343
include/dwarf_i.h Normal file
View file

@ -0,0 +1,343 @@
#ifndef DWARF_I_H
#define DWARF_I_H
/* This file contains definitions that cannot be used in code outside
of libunwind. In particular, most inline functions are here
because otherwise they'd generate unresolved references when the
files are compiled with inlining disabled. */
#include "dwarf.h"
#include "tdep.h"
#define dwarf_to_unw_regnum_map UNW_OBJ (dwarf_to_unw_regnum_map)
extern uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH];
static inline unw_regnum_t
dwarf_to_unw_regnum (unw_word_t regnum)
{
if (regnum <= DWARF_REGNUM_MAP_LENGTH)
return dwarf_to_unw_regnum_map[regnum];
return 0;
}
#ifdef UNW_LOCAL_ONLY
/* In the local-only case, we can let the compiler directly access
memory and don't need to worry about differing byte-order. */
typedef union
{
int8_t s8;
int16_t s16;
int32_t s32;
int64_t s64;
uint8_t u8;
uint16_t u16;
uint32_t u32;
uint64_t u64;
unw_word_t w;
void *ptr;
}
dwarf_misaligned_value_t __attribute__ ((packed));
static inline int
dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int8_t *val, void *arg)
{
dwarf_misaligned_value_t *mvp = (void *) *addr;
*val = mvp->s8;
*addr += sizeof (mvp->s8);
return 0;
}
static inline int
dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int16_t *val, void *arg)
{
dwarf_misaligned_value_t *mvp = (void *) *addr;
*val = mvp->s16;
*addr += sizeof (mvp->s16);
return 0;
}
static inline int
dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int32_t *val, void *arg)
{
dwarf_misaligned_value_t *mvp = (void *) *addr;
*val = mvp->s32;
*addr += sizeof (mvp->s32);
return 0;
}
static inline int
dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int64_t *val, void *arg)
{
dwarf_misaligned_value_t *mvp = (void *) *addr;
*val = mvp->s64;
*addr += sizeof (mvp->s64);
return 0;
}
static inline int
dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint8_t *val, void *arg)
{
dwarf_misaligned_value_t *mvp = (void *) *addr;
*val = mvp->u8;
*addr += sizeof (mvp->u8);
return 0;
}
static inline int
dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint16_t *val, void *arg)
{
dwarf_misaligned_value_t *mvp = (void *) *addr;
*val = mvp->u16;
*addr += sizeof (mvp->u16);
return 0;
}
static inline int
dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint32_t *val, void *arg)
{
dwarf_misaligned_value_t *mvp = (void *) *addr;
*val = mvp->u32;
*addr += sizeof (mvp->u32);
return 0;
}
static inline int
dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint64_t *val, void *arg)
{
dwarf_misaligned_value_t *mvp = (void *) *addr;
*val = mvp->u64;
*addr += sizeof (mvp->u64);
return 0;
}
static inline int
dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
unw_word_t *val, void *arg)
{
dwarf_misaligned_value_t *mvp = (void *) *addr;
*val = mvp->w;
*addr += sizeof (mvp->w);
return 0;
}
#else /* !UNW_LOCAL_ONLY */
static inline int
dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint8_t *valp, void *arg)
{
unw_word_t val, aligned_addr = *addr & -sizeof (unw_word_t);
unw_word_t off = *addr - aligned_addr;
int ret;
*addr += 1;
ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
#if __BYTE_ORDER == __LITTLE_ENDIAN
val >>= 8*off;
#else
val >>= 8*(sizeof (unw_word_t) - 1 - off);
#endif
*valp = (uint8_t) val;
return ret;
}
static inline int
dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint16_t *val, void *arg)
{
uint8_t v0, v1;
int ret;
if ((ret = dwarf_readu8 (as, a, addr, &v0, arg)) < 0
|| (ret = dwarf_readu8 (as, a, addr, &v1, arg)) < 0)
return ret;
if (tdep_big_endian (as))
*val = (uint16_t) v0 << 8 | v1;
else
*val = (uint16_t) v1 << 8 | v0;
return 0;
}
static inline int
dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint32_t *val, void *arg)
{
uint16_t v0, v1;
int ret;
if ((ret = dwarf_readu16 (as, a, addr, &v0, arg)) < 0
|| (ret = dwarf_readu16 (as, a, addr, &v1, arg)) < 0)
return ret;
if (tdep_big_endian (as))
*val = (uint32_t) v0 << 16 | v1;
else
*val = (uint32_t) v1 << 16 | v0;
return 0;
}
static inline int
dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
uint64_t *val, void *arg)
{
uint32_t v0, v1;
int ret;
if ((ret = dwarf_readu32 (as, a, addr, &v0, arg)) < 0
|| (ret = dwarf_readu32 (as, a, addr, &v1, arg)) < 0)
return ret;
if (tdep_big_endian (as))
*val = (uint64_t) v0 << 32 | v1;
else
*val = (uint64_t) v1 << 32 | v0;
return 0;
}
static inline int
dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int8_t *val, void *arg)
{
uint8_t uval;
int ret;
if ((ret = dwarf_readu8 (as, a, addr, &uval, arg)) < 0)
return ret;
*val = (int8_t) uval;
return 0;
}
static inline int
dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int16_t *val, void *arg)
{
uint16_t uval;
int ret;
if ((ret = dwarf_readu16 (as, a, addr, &uval, arg)) < 0)
return ret;
*val = (int16_t) uval;
return 0;
}
static inline int
dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int32_t *val, void *arg)
{
uint32_t uval;
int ret;
if ((ret = dwarf_readu32 (as, a, addr, &uval, arg)) < 0)
return ret;
*val = (int32_t) uval;
return 0;
}
static inline int
dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
int64_t *val, void *arg)
{
uint64_t uval;
int ret;
if ((ret = dwarf_readu64 (as, a, addr, &uval, arg)) < 0)
return ret;
*val = (int64_t) uval;
return 0;
}
static inline int
dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
unw_word_t *val, void *arg)
{
switch (sizeof (unw_word_t))
{
case 4:
return dwarf_readu32 (as, a, addr, (uint32_t *) val, arg);
case 8:
return dwarf_readu64 (as, a, addr, (uint64_t *) val, arg);
default:
abort ();
}
}
#endif /* !UNW_LOCAL_ONLY */
/* Read an unsigned "little-endian base 128" value. See Chapter 7.6
of DWARF spec v3. */
static inline int
dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
unw_word_t *valp, void *arg)
{
unw_word_t val = 0, shift = 0;
unsigned char byte;
int ret;
do
{
if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
return ret;
val |= ((unw_word_t) byte & 0x7f) << shift;
shift += 7;
}
while (byte & 0x80);
*valp = val;
return 0;
}
/* Read a signed "little-endian base 128" value. See Chapter 7.6 of
DWARF spec v3. */
static inline int
dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
unw_word_t *valp, void *arg)
{
unw_word_t val = 0, shift = 0;
unsigned char byte;
int ret;
do
{
if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
return ret;
val |= ((unw_word_t) byte & 0x7f) << shift;
shift += 7;
}
while (byte & 0x80);
if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0)
/* sign-extend negative value */
val |= ((unw_word_t) -1) << shift;
*valp = val;
return 0;
}
#endif /* DWARF_I_H */

127
include/remote.h Normal file
View file

@ -0,0 +1,127 @@
#ifndef REMOTE_H
#define REMOTE_H
/* Helper functions for accessing (remote) memory. These functions
assume that all addresses are naturally aligned (e.g., 32-bit
quantity is stored at a 32-bit-aligned address. */
#ifdef UNW_LOCAL_ONLY
static inline int
fetch8 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int8_t *valp, void *arg)
{
*valp = *(int8_t *) *addr;
*addr += 1;
return 0;
}
static inline int
fetch16 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int16_t *valp, void *arg)
{
*valp = *(int16_t *) *addr;
*addr += 2;
return 0;
}
static inline int
fetch32 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int32_t *valp, void *arg)
{
*valp = *(int32_t *) *addr;
*addr += 4;
return 0;
}
static inline int
fetchw (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, unw_word_t *valp, void *arg)
{
*valp = *(unw_word_t *) *addr;
*addr += sizeof (unw_word_t);
return 0;
}
#else /* !UNW_LOCAL_ONLY */
#define WSIZE (sizeof (unw_word_t))
static inline int
fetch8 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int8_t *valp, void *arg)
{
unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
int ret;
*addr += 1;
ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
#if __BYTE_ORDER == __LITTLE_ENDIAN
val >>= 8*off;
#else
val >>= 8*(WSIZE - 1 - off);
#endif
*valp = val & 0xff;
return ret;
}
static inline int
fetch16 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int16_t *valp, void *arg)
{
unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
int ret;
assert ((off & 0x1) == 0);
*addr += 2;
ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
#if __BYTE_ORDER == __LITTLE_ENDIAN
val >>= 8*off;
#else
val >>= 8*(WSIZE - 2 - off);
#endif
*valp = val & 0xffff;
return ret;
}
static inline int
fetch32 (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, int32_t *valp, void *arg)
{
unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr;
int ret;
assert ((off & 0x3) == 0);
*addr += 4;
ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
#if __BYTE_ORDER == __LITTLE_ENDIAN
val >>= 8*off;
#else
val >>= 8*(WSIZE - 4 - off);
#endif
*valp = val & 0xffffffff;
return ret;
}
static inline int
fetchw (unw_addr_space_t as, unw_accessors_t *a,
unw_word_t *addr, unw_word_t *valp, void *arg)
{
int ret;
ret = (*a->access_mem) (as, *addr, valp, 0, arg);
*addr += WSIZE;
return ret;
}
#endif /* !UNW_LOCAL_ONLY */
#endif /* REMOTE_H */

34
src/mi/Gget_fpreg.c Normal file
View file

@ -0,0 +1,34 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
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 "tdep.h"
PROTECTED int
unw_get_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t *valp)
{
struct cursor *c = (struct cursor *) cursor;
return tdep_access_fpreg (c, regnum, valp, 0);
}

34
src/mi/Gset_fpreg.c Normal file
View file

@ -0,0 +1,34 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
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 "tdep.h"
PROTECTED int
unw_set_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t val)
{
struct cursor *c = (struct cursor *) cursor;
return tdep_access_fpreg (c, regnum, &val, 1);
}

View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gdestroy_addr_space.c"
#endif

5
src/mi/Ldyn-remote.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gdyn-remote.c"
#endif

5
src/mi/Lget_accessors.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gget_accessors.c"
#endif

5
src/mi/Lget_fpreg.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gget_fpreg.c"
#endif

5
src/mi/Lget_reg.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gget_reg.c"
#endif

View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gset_caching_policy.c"
#endif

5
src/mi/Lset_fpreg.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gset_fpreg.c"
#endif

5
src/mi/Lset_reg.c Normal file
View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gset_reg.c"
#endif

125
src/x86/Gget_save_loc-x86.c Normal file
View file

@ -0,0 +1,125 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
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 "unwind_i.h"
PROTECTED int
unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc)
{
struct cursor *c = (struct cursor *) cursor;
dwarf_loc_t loc;
loc = DWARF_NULL_LOC; /* default to "not saved" */
switch (reg)
{
case UNW_X86_EIP: loc = c->dwarf.loc[EIP]; break;
case UNW_X86_CFA: break;
case UNW_X86_EAX: loc = c->dwarf.loc[EAX]; break;
case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break;
case UNW_X86_EDX: loc = c->dwarf.loc[EDX]; break;
case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break;
case UNW_X86_ESP: loc = c->dwarf.loc[ESP]; break;
case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break;
case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break;
case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break;
case UNW_X86_EFLAGS: loc = c->dwarf.loc[EFLAGS]; break;
case UNW_X86_TRAPNO: loc = c->dwarf.loc[TRAPNO]; break;
case UNW_X86_ST0: loc = c->dwarf.loc[ST0]; break;
case UNW_X86_FCW:
case UNW_X86_FSW:
case UNW_X86_FTW:
case UNW_X86_FOP:
case UNW_X86_FCS:
case UNW_X86_FIP:
case UNW_X86_FEA:
case UNW_X86_FDS:
case UNW_X86_MXCSR:
case UNW_X86_GS:
case UNW_X86_FS:
case UNW_X86_ES:
case UNW_X86_DS:
case UNW_X86_SS:
case UNW_X86_CS:
case UNW_X86_TSS:
case UNW_X86_LDT:
loc = x86_scratch_loc (c, reg);
break;
/* stacked fp registers */
case UNW_X86_ST1:
case UNW_X86_ST2:
case UNW_X86_ST3:
case UNW_X86_ST4:
case UNW_X86_ST5:
case UNW_X86_ST6:
case UNW_X86_ST7:
/* SSE fp registers */
case UNW_X86_XMM0_lo:
case UNW_X86_XMM0_hi:
case UNW_X86_XMM1_lo:
case UNW_X86_XMM1_hi:
case UNW_X86_XMM2_lo:
case UNW_X86_XMM2_hi:
case UNW_X86_XMM3_lo:
case UNW_X86_XMM3_hi:
case UNW_X86_XMM4_lo:
case UNW_X86_XMM4_hi:
case UNW_X86_XMM5_lo:
case UNW_X86_XMM5_hi:
case UNW_X86_XMM6_lo:
case UNW_X86_XMM6_hi:
case UNW_X86_XMM7_lo:
case UNW_X86_XMM7_hi:
loc = x86_scratch_loc (c, reg);
break;
default:
break;
}
memset (sloc, 0, sizeof (sloc));
if (DWARF_IS_NULL_LOC (loc))
{
sloc->type = UNW_SLT_NONE;
return 0;
}
#if !defined(UNW_LOCAL_ONLY)
if (DWARF_IS_REG_LOC (loc))
{
sloc->type = UNW_SLT_REG;
sloc->u.regnum = DWARF_GET_LOC (loc);
}
else
#endif
{
sloc->type = UNW_SLT_MEMORY;
sloc->u.addr = DWARF_GET_LOC (loc);
}
return 0;
}

View file

@ -0,0 +1,5 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
#include "Gget_save_loc-x86.c"
#endif