/* libunwind - a platform-independent unwind library
Copyright (c) 2001-2005 Hewlett-Packard Development Company, L.P.
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
static inline int
read_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, void *arg)
{
- unw_accessors_t *a = unw_get_accessors (as);
+ unw_accessors_t *a = unw_get_accessors_int (as);
return (*a->access_mem) (as, addr, valp, 0, arg);
}
/* Helper macro for reading an ia64_table_entry from remote memory. */
-#define remote_read(addr, member) \
- (*a->access_mem) (as, (addr) + offsetof (struct ia64_table_entry, \
- member), &member, 0, arg)
+#define remote_read(addr, member) \
+ (*a->access_mem) (as, (addr) + offsetof (struct ia64_table_entry, \
+ member), &member, 0, arg)
/* Lookup an unwind-table entry in remote memory. Returns 1 if an
entry is found, 0 if no entry is found, negative if an error
occurred reading remote memory. */
static int
remote_lookup (unw_addr_space_t as,
- unw_word_t table, size_t table_size, unw_word_t rel_ip,
- struct ia64_table_entry *e, void *arg)
+ unw_word_t table, size_t table_size, unw_word_t rel_ip,
+ struct ia64_table_entry *e, void *arg)
{
unw_word_t e_addr = 0, start_offset, end_offset, info_offset;
- unw_accessors_t *a = unw_get_accessors (as);
+ unw_accessors_t *a = unw_get_accessors_int (as);
unsigned long lo, hi, mid;
int ret;
mid = (lo + hi) / 2;
e_addr = table + mid * sizeof (struct ia64_table_entry);
if ((ret = remote_read (e_addr, start_offset)) < 0)
- return ret;
+ return ret;
if (rel_ip < start_offset)
- hi = mid;
+ hi = mid;
else
- {
- if ((ret = remote_read (e_addr, end_offset)) < 0)
- return ret;
-
- if (rel_ip >= end_offset)
- lo = mid + 1;
- else
- break;
- }
+ {
+ if ((ret = remote_read (e_addr, end_offset)) < 0)
+ return ret;
+
+ if (rel_ip >= end_offset)
+ lo = mid + 1;
+ else
+ break;
+ }
}
if (rel_ip < start_offset || rel_ip >= end_offset)
return 0;
}
}
-PROTECTED unw_word_t
+unw_word_t
_Uia64_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg)
{
unw_word_t hdr_addr, info_addr, hdr, directives, pers, cookie, off;
table_size = di->u.ti.table_len * sizeof (di->u.ti.table_data[0]);
segbase = di->u.ti.segbase;
if (table_size < sizeof (struct ia64_table_entry))
- return 0;
+ return 0;
start_offset = e[0].start_offset;
end_offset = e[0].end_offset;
info_offset = e[0].info_offset;
case UNW_INFO_FORMAT_REMOTE_TABLE:
{
- unw_accessors_t *a = unw_get_accessors (as);
- unw_word_t e_addr = di->u.rti.table_data;
-
- table_size = di->u.rti.table_len * sizeof (unw_word_t);
- segbase = di->u.rti.segbase;
- if (table_size < sizeof (struct ia64_table_entry))
- return 0;
-
- if ( (ret = remote_read (e_addr, start_offset) < 0)
- || (ret = remote_read (e_addr, end_offset) < 0)
- || (ret = remote_read (e_addr, info_offset) < 0))
- return ret;
+ unw_accessors_t *a = unw_get_accessors_int (as);
+ unw_word_t e_addr = di->u.rti.table_data;
+
+ table_size = di->u.rti.table_len * sizeof (unw_word_t);
+ segbase = di->u.rti.segbase;
+ if (table_size < sizeof (struct ia64_table_entry))
+ return 0;
+
+ if ( (ret = remote_read (e_addr, start_offset) < 0)
+ || (ret = remote_read (e_addr, end_offset) < 0)
+ || (ret = remote_read (e_addr, info_offset) < 0))
+ return ret;
}
break;
}
mid = (lo + hi) / 2;
e = table + mid;
if (rel_ip < e->start_offset)
- hi = mid;
+ hi = mid;
else if (rel_ip >= e->end_offset)
- lo = mid + 1;
+ lo = mid + 1;
else
- break;
+ break;
}
if (rel_ip < e->start_offset || rel_ip >= e->end_offset)
return NULL;
return e;
}
-PROTECTED int
+int
unw_search_ia64_unwind_table (unw_addr_space_t as, unw_word_t ip,
- unw_dyn_info_t *di, unw_proc_info_t *pi,
- int need_unwind_info, void *arg)
+ unw_dyn_info_t *di, unw_proc_info_t *pi,
+ int need_unwind_info, void *arg)
{
unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp;
const struct ia64_table_entry *e = NULL;
#endif
assert ((di->format == UNW_INFO_FORMAT_TABLE
- || di->format == UNW_INFO_FORMAT_REMOTE_TABLE)
- && (ip >= di->start_ip && ip < di->end_ip));
+ || di->format == UNW_INFO_FORMAT_REMOTE_TABLE)
+ && (ip >= di->start_ip && ip < di->end_ip));
pi->flags = 0;
pi->unwind_info = 0;
{
segbase = di->u.ti.segbase;
e = lookup ((struct ia64_table_entry *) di->u.ti.table_data,
- di->u.ti.table_len * sizeof (unw_word_t),
- ip - segbase);
+ di->u.ti.table_len * sizeof (unw_word_t),
+ ip - segbase);
}
#ifndef UNW_LOCAL_ONLY
else
{
segbase = di->u.rti.segbase;
if ((ret = remote_lookup (as, di->u.rti.table_data,
- di->u.rti.table_len * sizeof (unw_word_t),
- ip - segbase, &ent, arg)) < 0)
- return ret;
+ di->u.rti.table_len * sizeof (unw_word_t),
+ ip - segbase, &ent, arg)) < 0)
+ return ret;
if (ret)
- e = &ent;
+ e = &ent;
}
#endif
if (!e)
{
/* IP is inside this table's range, but there is no explicit
- unwind info => use default conventions (i.e., this is NOT an
- error). */
+ unwind info => use default conventions (i.e., this is NOT an
+ error). */
memset (pi, 0, sizeof (*pi));
pi->start_ip = 0;
pi->end_ip = 0;
if (IA64_UNW_VER (hdr) != 1)
{
Debug (1, "Unknown header version %ld (hdr word=0x%lx @ 0x%lx)\n",
- IA64_UNW_VER (hdr), (unsigned long) hdr,
- (unsigned long) hdr_addr);
+ IA64_UNW_VER (hdr), (unsigned long) hdr,
+ (unsigned long) hdr_addr);
return -UNW_EBADVERSION;
}
pi->unwind_info_size = 8 * IA64_UNW_LENGTH (hdr);
if (is_local)
- pi->unwind_info = (void *) (uintptr_t) info_addr;
+ pi->unwind_info = (void *) (uintptr_t) info_addr;
else
- {
- /* Internalize unwind info. Note: since we're doing this
- only for non-local address spaces, there is no
- signal-safety issue and it is OK to use malloc()/free(). */
- pi->unwind_info = malloc (8 * IA64_UNW_LENGTH (hdr));
- if (!pi->unwind_info)
- return -UNW_ENOMEM;
-
- wp = (unw_word_t *) pi->unwind_info;
- for (addr = info_addr; addr < info_end_addr; addr += 8, ++wp)
- {
- if ((ret = read_mem (as, addr, wp, arg)) < 0)
- {
- free (pi->unwind_info);
- return ret;
- }
- }
- }
+ {
+ /* Internalize unwind info. Note: since we're doing this
+ only for non-local address spaces, there is no
+ signal-safety issue and it is OK to use malloc()/free(). */
+ pi->unwind_info = malloc (8 * IA64_UNW_LENGTH (hdr));
+ if (!pi->unwind_info)
+ return -UNW_ENOMEM;
+
+ wp = (unw_word_t *) pi->unwind_info;
+ for (addr = info_addr; addr < info_end_addr; addr += 8, ++wp)
+ {
+ if ((ret = read_mem (as, addr, wp, arg)) < 0)
+ {
+ free (pi->unwind_info);
+ return ret;
+ }
+ }
+ }
}
if (IA64_UNW_FLAG_EHANDLER (hdr) || IA64_UNW_FLAG_UHANDLER (hdr))
{
/* read the personality routine address (address is gp-relative): */
if ((ret = read_mem (as, info_end_addr, &handler_offset, arg)) < 0)
- return ret;
+ return ret;
Debug (4, "handler ptr @ offset=%lx, gp=%lx\n", handler_offset, di->gp);
if ((read_mem (as, handler_offset + di->gp, &pi->handler, arg)) < 0)
- return ret;
+ return ret;
}
pi->lsda = info_end_addr + 8;
pi->gp = di->gp;
# include <unistd.h>
# include <sys/syscall.h>
# ifndef __NR_getunwind
-# define __NR_getunwind 1215
+# define __NR_getunwind 1215
# endif
static unsigned long
if (!ktab)
{
Dprintf (__FILE__".%s: failed to allocate %zu bytes",
- __FUNCTION__, size);
+ __FUNCTION__, size);
return -UNW_ENOMEM;
}
getunwind (ktab, size);
di->u.ti.table_data = (unw_word_t *) ktab;
Debug (16, "found table `%s': [%lx-%lx) segbase=%lx len=%lu\n",
- (char *) di->u.ti.name_ptr, di->start_ip, di->end_ip,
- di->u.ti.segbase, di->u.ti.table_len);
+ (char *) di->u.ti.name_ptr, di->start_ip, di->end_ip,
+ di->u.ti.segbase, di->u.ti.table_len);
return 0;
}
# ifndef UNW_LOCAL_ONLY
/* This is exported for the benefit of libunwind-ptrace.a. */
-PROTECTED int
+int
_Uia64_get_kernel_table (unw_dyn_info_t *di)
{
int ret;
/* Make sure struct dl_phdr_info is at least as big as we need. */
if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
- + sizeof (info->dlpi_phnum))
+ + sizeof (info->dlpi_phnum))
return -1;
Debug (16, "checking `%s' (load_base=%lx)\n",
- info->dlpi_name, info->dlpi_addr);
+ info->dlpi_name, info->dlpi_addr);
phdr = info->dlpi_phdr;
load_base = info->dlpi_addr;
for (n = info->dlpi_phnum; --n >= 0; phdr++)
{
if (phdr->p_type == PT_LOAD)
- {
- Elf64_Addr vaddr = phdr->p_vaddr + load_base;
- if (di->u.ti.segbase >= vaddr
- && di->u.ti.segbase < vaddr + phdr->p_memsz)
- p_text = phdr;
- }
+ {
+ Elf64_Addr vaddr = phdr->p_vaddr + load_base;
+ if (di->u.ti.segbase >= vaddr
+ && di->u.ti.segbase < vaddr + phdr->p_memsz)
+ p_text = phdr;
+ }
else if (phdr->p_type == PT_IA_64_UNWIND)
- p_unwind = phdr;
+ p_unwind = phdr;
else if (phdr->p_type == PT_DYNAMIC)
- p_dynamic = phdr;
+ p_dynamic = phdr;
}
if (!p_text || !p_unwind)
return 0;
if (likely (p_unwind->p_vaddr >= p_text->p_vaddr
- && p_unwind->p_vaddr < p_text->p_vaddr + p_text->p_memsz))
+ && p_unwind->p_vaddr < p_text->p_vaddr + p_text->p_memsz))
/* normal case: unwind table is inside text segment */
segbase = p_text->p_vaddr + load_base;
else
{
/* Special case: unwind table is in some other segment; this
- happens for the Linux kernel's gate DSO, for example. */
+ happens for the Linux kernel's gate DSO, for example. */
phdr = info->dlpi_phdr;
for (n = info->dlpi_phnum; --n >= 0; phdr++)
- {
- if (phdr->p_type == PT_LOAD && p_unwind->p_vaddr >= phdr->p_vaddr
- && p_unwind->p_vaddr < phdr->p_vaddr + phdr->p_memsz)
- {
- segbase = phdr->p_vaddr + load_base;
- break;
- }
- }
+ {
+ if (phdr->p_type == PT_LOAD && p_unwind->p_vaddr >= phdr->p_vaddr
+ && p_unwind->p_vaddr < phdr->p_vaddr + phdr->p_memsz)
+ {
+ segbase = phdr->p_vaddr + load_base;
+ break;
+ }
+ }
}
if (p_dynamic)
{
/* For dynamicly linked executables and shared libraries,
- DT_PLTGOT is the gp value for that object. */
+ DT_PLTGOT is the gp value for that object. */
Elf64_Dyn *dyn = (Elf64_Dyn *)(p_dynamic->p_vaddr + load_base);
for (; dyn->d_tag != DT_NULL; ++dyn)
- if (dyn->d_tag == DT_PLTGOT)
- {
- /* On IA-64, _DYNAMIC is writable and GLIBC has relocated it. */
- di->gp = dyn->d_un.d_ptr;
- break;
- }
+ if (dyn->d_tag == DT_PLTGOT)
+ {
+ /* On IA-64, _DYNAMIC is writable and GLIBC has relocated it. */
+ di->gp = dyn->d_un.d_ptr;
+ break;
+ }
}
else
/* Otherwise this is a static executable with no _DYNAMIC.
di->u.ti.segbase = segbase;
Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, "
- "table_data=%p\n", (char *) di->u.ti.name_ptr, di->u.ti.segbase,
- di->u.ti.table_len, di->gp, di->u.ti.table_data);
+ "table_data=%p\n", (char *) di->u.ti.name_ptr, di->u.ti.segbase,
+ di->u.ti.table_len, di->gp, di->u.ti.table_data);
return 1;
}
as->shared_object_removals = info->dlpi_subs;
unw_flush_cache (as, 0, 0);
- return -1; /* indicate that there were removals */
+ return -1; /* indicate that there were removals */
# else
return 1;
# endif
HIDDEN int
tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip,
- unw_proc_info_t *pi, int need_unwind_info, void *arg)
+ unw_proc_info_t *pi, int need_unwind_info, void *arg)
{
# if defined(HAVE_DL_ITERATE_PHDR)
unw_dyn_info_t di, *dip = &di;
intrmask_t saved_mask;
int ret;
- di.u.ti.segbase = ip; /* this is cheap... */
+ di.u.ti.segbase = ip; /* this is cheap... */
SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask);
ret = dl_iterate_phdr (callback, &di);
if (ret <= 0)
{
if (!kernel_table.u.ti.table_data)
- {
- if ((ret = get_kernel_table (&kernel_table)) < 0)
- return ret;
- }
+ {
+ if ((ret = get_kernel_table (&kernel_table)) < 0)
+ return ret;
+ }
if (ip < kernel_table.start_ip || ip >= kernel_table.end_ip)
- return -UNW_ENOINFO;
+ return -UNW_ENOINFO;
dip = &kernel_table;
}
# elif defined(HAVE_DLMODINFO)
-# define UNWIND_TBL_32BIT 0x8000000000000000
+# define UNWIND_TBL_32BIT 0x8000000000000000
struct load_module_desc lmd;
unw_dyn_info_t di, *dip = &di;
struct unwind_header
di.start_ip = lmd.text_base;
di.end_ip = lmd.text_base + lmd.text_size;
di.gp = lmd.linkage_ptr;
- di.u.ti.name_ptr = 0; /* no obvious table-name available */
+ di.u.ti.name_ptr = 0; /* no obvious table-name available */
di.u.ti.segbase = lmd.text_base;
uhdr = (struct unwind_header *) lmd.unwind_base;
&& (uhdr->header_version & ~UNWIND_TBL_32BIT) != 2)
{
Debug (1, "encountered unknown unwind header version %ld\n",
- (long) (uhdr->header_version & ~UNWIND_TBL_32BIT));
+ (long) (uhdr->header_version & ~UNWIND_TBL_32BIT));
return -UNW_EBADVERSION;
}
if (uhdr->header_version & UNWIND_TBL_32BIT)
di.u.ti.table_data = (unw_word_t *) (di.u.ti.segbase + uhdr->start_offset);
di.u.ti.table_len = ((uhdr->end_offset - uhdr->start_offset)
- / sizeof (unw_word_t));
+ / sizeof (unw_word_t));
Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, "
- "table_data=%p\n", (char *) di.u.ti.name_ptr, di.u.ti.segbase,
- di.u.ti.table_len, di.gp, di.u.ti.table_data);
+ "table_data=%p\n", (char *) di.u.ti.name_ptr, di.u.ti.segbase,
+ di.u.ti.table_len, di.gp, di.u.ti.table_data);
# endif
/* now search the table: */