From 22c1128cf793d7c1245488a5e85f7af4860b6bc2 Mon Sep 17 00:00:00 2001 From: "mostang.com!davidm" Date: Tue, 3 Dec 2002 08:19:58 +0000 Subject: [PATCH] (struct ia64_table_entry): New type (moved from unwind_i.h). (lookup): New function (moved from parser.c). (_Uia64_search_unwind_table): New function (based on code in parser.c). (kernel_table): New variable. (get_kernel_table): Relocate the kernel table's "info_offset" values as we count it. Adjust for new callback-interface. (callback): Adjust for new interface. (_Uia64_find_proc_info): Rename from _Uia64_glibc_acquire_unwind_info). }(Logical change 1.29) --- src/ia64/tables-glibc.c | 186 ---------------------------------------- 1 file changed, 186 deletions(-) delete mode 100644 src/ia64/tables-glibc.c diff --git a/src/ia64/tables-glibc.c b/src/ia64/tables-glibc.c deleted file mode 100644 index e8476855..00000000 --- a/src/ia64/tables-glibc.c +++ /dev/null @@ -1,186 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -This file is based on gcc/config/ia64/fde-glibc.c, which is copyright -by: - - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Contributed by Richard Henderson . */ - -#ifndef UNW_REMOTE_ONLY - -#include -#include -#include - -#include "unwind_i.h" - -#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) \ - || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && !defined(DT_CONFIG)) -# error You need GLIBC 2.2.4 or later on IA-64 Linux -#endif - -#ifdef HAVE_GETUNWIND - -extern unsigned long getunwind (void *buf, size_t len); - -#else /* HAVE_GETUNWIND */ - -/* XXX fix me */ - -#include -#include - -# ifndef __NR_getunwind -# define __NR_getunwind 1215 -# endif - -static unsigned long -getunwind (void *buf, size_t len) -{ - return syscall (SYS_getunwind, buf, len); -} - -#endif /* HAVE_GETUNWIND */ - -static int -get_kernel_table (void *ptr) -{ - struct ia64_unwind_table_entry *ktab, *etab; - unw_ia64_table_t *info = ptr; - size_t size; - - debug (100, "unwind: checking kernel unwind table"); - - size = getunwind (NULL, 0); - ktab = sos_alloc (size); - if (!ktab) - { - dprintf (__FILE__".%s: failed to allocate %Zu bytes", - __FUNCTION__, size); - return -UNW_ENOMEM; - } - getunwind (ktab, size); - - /* Determine length of kernel's unwind table. */ - for (etab = ktab; etab->start_offset; ++etab); - - if (info->segbase < ktab[0].start_offset - || info->segbase >= etab[-1].end_offset) - { - sos_free (ktab); - return -1; - } - - info->name = ""; - info->gp = 0; - info->segbase = 0; - info->start = ktab[0].start_offset; - info->end = etab[-1].end_offset; - info->length = etab - ktab; - info->array = ktab; - info->unwind_info_base = (const u_int8_t *) ktab; - - debug (100, "unwind: found table `%s': segbase=%lx, length=%lu, gp=%lx\n", - info->name, info->segbase, info->length, info->gp); - - return 0; -} - -static int -callback (struct dl_phdr_info *info, size_t size, void *ptr) -{ - unw_ia64_table_t *data = ptr; - const Elf64_Phdr *phdr, *p_unwind, *p_dynamic, *p_text; - long n; - Elf64_Addr load_base; - - /* 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)) - return -1; - - debug (100, "unwind: checking `%s'\n", info->dlpi_name); - - phdr = info->dlpi_phdr; - load_base = info->dlpi_addr; - p_text = NULL; - p_unwind = NULL; - p_dynamic = NULL; - - /* See if PC falls into one of the loaded segments. Find the unwind - segment at the same time. */ - for (n = info->dlpi_phnum; --n >= 0; phdr++) - { - if (phdr->p_type == PT_LOAD) - { - Elf64_Addr vaddr = phdr->p_vaddr + load_base; - if (data->segbase >= vaddr && data->segbase < vaddr + phdr->p_memsz) - p_text = phdr; - } - else if (phdr->p_type == PT_IA_64_UNWIND) - p_unwind = phdr; - else if (phdr->p_type == PT_DYNAMIC) - p_dynamic = phdr; - } - if (!p_text || !p_unwind) - return 0; - - if (p_dynamic) - { - /* For dynamicly linked executables and shared libraries, - 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. */ - data->gp = dyn->d_un.d_ptr; - break; - } - } - else - { - /* Otherwise this is a static executable with no _DYNAMIC. - The gp is constant program-wide. */ - register unsigned long gp __asm__("gp"); - data->gp = gp; - } - data->name = info->dlpi_name; - data->array - = (struct ia64_unwind_table_entry *) (p_unwind->p_vaddr + load_base); - data->length = p_unwind->p_memsz / sizeof (struct ia64_unwind_table_entry); - data->segbase = p_text->p_vaddr + load_base; - data->start = p_text->p_vaddr + load_base; - data->end = p_text->p_vaddr + load_base + p_text->p_memsz; - data->unwind_info_base = (const u_int8_t *) data->segbase; - - debug (100, "unwind: found table `%s': segbase=%lx, length=%lu, gp=%lx, " - "array=%p\n", data->name, data->segbase, data->length, data->gp, - data->array); - - return 1; -} - -int -_Uia64_glibc_acquire_unwind_info (unw_word_t ip, void *info, void *arg) -{ - ((unw_ia64_table_t *) info)->segbase = ip; /* this is cheap... */ - - if (dl_iterate_phdr (callback, info) > 0) - return 0; - - return get_kernel_table (info); -} - -int -_Uia64_glibc_release_unwind_info (void *info, void *arg) -{ - /* nothing to do */ - return 0; -} - -#endif /* !UNW_REMOTE_ONLY */