diff --git a/include/libunwind_i.h b/include/libunwind_i.h index 73092347..17b3cf83 100644 --- a/include/libunwind_i.h +++ b/include/libunwind_i.h @@ -1,6 +1,7 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2001-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang This file is part of libunwind. @@ -285,4 +286,8 @@ struct elf_image #include "tdep/libunwind_i.h" +#ifndef tdep_get_func_addr +# define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0) +#endif + #endif /* libunwind_i_h */ diff --git a/include/tdep-ppc64/libunwind_i.h b/include/tdep-ppc64/libunwind_i.h index 9458addd..1c7646c9 100644 --- a/include/tdep-ppc64/libunwind_i.h +++ b/include/tdep-ppc64/libunwind_i.h @@ -255,7 +255,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) #define tdep_access_reg UNW_OBJ(access_reg) #define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_access_vreg UNW_OBJ(access_vreg) +#define tdep_get_func_addr UNW_OBJ(get_func_addr) #ifdef UNW_LOCAL_ONLY # define tdep_find_proc_info(c,ip,n) \ @@ -293,5 +293,7 @@ extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t * valp, int write); extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t * valp, int write); +extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, + unw_word_t *entry_point); #endif /* PPC64_LIBUNWIND_I_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 07eadf9f..c69f90e8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -209,7 +209,7 @@ libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \ $(dwarf_SOURCES_common) \ elf64.c elf64.h \ ppc64/init.h ppc64/unwind_i.h ppc64/ucontext_i.h \ - ppc64/is_fpreg.c ppc64/regname.c + ppc64/is_fpreg.c ppc64/regname.c ppc64/get_func_addr.c # The list of files that go into libunwind: libunwind_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ diff --git a/src/Makefile.in b/src/Makefile.in index e731cb2e..50047bc3 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -155,7 +155,7 @@ am__libunwind_ppc64_la_SOURCES_DIST = os-hpux.c os-linux.h os-linux.c \ mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c \ dwarf/global.c elf64.c elf64.h ppc64/init.h ppc64/unwind_i.h \ ppc64/ucontext_i.h ppc64/is_fpreg.c ppc64/regname.c \ - mi/Gdyn-extract.c mi/Gdyn-remote.c \ + ppc64/get_func_addr.c mi/Gdyn-extract.c mi/Gdyn-remote.c \ mi/Gfind_dynamic_proc_info.c mi/Gget_accessors.c \ mi/Gget_proc_info_by_ip.c mi/Gget_proc_name.c \ mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \ @@ -168,7 +168,7 @@ am__libunwind_ppc64_la_SOURCES_DIST = os-hpux.c os-linux.h os-linux.c \ ppc64/Gis_signal_frame.c ppc64/Gregs.c ppc64/Gresume.c \ ppc64/Gstep.c am__objects_12 = $(am__objects_4) $(am__objects_5) elf64.lo \ - ppc64/is_fpreg.lo ppc64/regname.lo + ppc64/is_fpreg.lo ppc64/regname.lo ppc64/get_func_addr.lo am__objects_13 = $(am__objects_12) $(am__objects_7) $(am__objects_8) \ dwarf/Gfind_proc_info-lsb.lo ppc64/Gcreate_addr_space.lo \ ppc64/Gget_proc_info.lo ppc64/Gget_save_loc.lo \ @@ -268,8 +268,9 @@ am__libunwind_la_SOURCES_DIST = os-hpux.c os-linux.h os-linux.c \ mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c \ dwarf/global.c elf64.c elf64.h ppc64/init.h ppc64/unwind_i.h \ ppc64/ucontext_i.h ppc64/is_fpreg.c ppc64/regname.c \ - mi/_ReadULEB.c mi/_ReadSLEB.c mi/backtrace.c mi/dyn-cancel.c \ - mi/dyn-info-list.c mi/dyn-register.c mi/Ldyn-extract.c \ + ppc64/get_func_addr.c mi/_ReadULEB.c mi/_ReadSLEB.c \ + mi/backtrace.c mi/dyn-cancel.c mi/dyn-info-list.c \ + mi/dyn-register.c mi/Ldyn-extract.c \ mi/Lfind_dynamic_proc_info.c mi/Lget_accessors.c \ mi/Lget_proc_info_by_ip.c mi/Lget_proc_name.c \ mi/Lput_dynamic_unwind_info.c mi/Ldestroy_addr_space.c \ @@ -777,7 +778,7 @@ libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \ $(dwarf_SOURCES_common) \ elf64.c elf64.h \ ppc64/init.h ppc64/unwind_i.h ppc64/ucontext_i.h \ - ppc64/is_fpreg.c ppc64/regname.c + ppc64/is_fpreg.c ppc64/regname.c ppc64/get_func_addr.c # The list of files that go into libunwind: @@ -1122,6 +1123,8 @@ ppc64/is_fpreg.lo: ppc64/$(am__dirstamp) \ ppc64/$(DEPDIR)/$(am__dirstamp) ppc64/regname.lo: ppc64/$(am__dirstamp) \ ppc64/$(DEPDIR)/$(am__dirstamp) +ppc64/get_func_addr.lo: ppc64/$(am__dirstamp) \ + ppc64/$(DEPDIR)/$(am__dirstamp) ppc64/Gcreate_addr_space.lo: ppc64/$(am__dirstamp) \ ppc64/$(DEPDIR)/$(am__dirstamp) ppc64/Gget_proc_info.lo: ppc64/$(am__dirstamp) \ @@ -1690,6 +1693,8 @@ mostlyclean-compile: -rm -f ppc64/Lresume.lo -rm -f ppc64/Lstep.$(OBJEXT) -rm -f ppc64/Lstep.lo + -rm -f ppc64/get_func_addr.$(OBJEXT) + -rm -f ppc64/get_func_addr.lo -rm -f ppc64/is_fpreg.$(OBJEXT) -rm -f ppc64/is_fpreg.lo -rm -f ppc64/longjmp.$(OBJEXT) @@ -1986,6 +1991,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Lregs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Lresume.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/Lstep.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/get_func_addr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/is_fpreg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ppc64/$(DEPDIR)/regname.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ptrace/$(DEPDIR)/_UPT_access_fpreg.Po@am__quote@ diff --git a/src/elfxx.c b/src/elfxx.c index 7b135067..05b99438 100644 --- a/src/elfxx.c +++ b/src/elfxx.c @@ -1,6 +1,7 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang This file is part of libunwind. @@ -39,7 +40,8 @@ elf_w (valid_object) (struct elf_image *ei) static int -elf_w (lookup_symbol) (unw_word_t ip, struct elf_image *ei, +elf_w (lookup_symbol) (unw_addr_space_t as, + unw_word_t ip, struct elf_image *ei, Elf_W (Addr) load_offset, char *buf, size_t buf_len, unw_word_t *offp) { @@ -98,7 +100,8 @@ elf_w (lookup_symbol) (unw_word_t ip, struct elf_image *ei, if (ELF_W (ST_TYPE) (sym->st_info) == STT_FUNC && sym->st_shndx != SHN_UNDEF) { - val = sym->st_value; + if (tdep_get_func_addr (as, sym->st_value, &val) < 0) + continue; if (sym->st_shndx != SHN_ABS) val += load_offset; Debug (16, "0x%016lx info=0x%02x %s\n", @@ -134,8 +137,8 @@ elf_w (lookup_symbol) (unw_word_t ip, struct elf_image *ei, sensitive to the performance of this routine, why bother... */ HIDDEN int -elf_w (get_proc_name) (pid_t pid, unw_word_t ip, char *buf, size_t buf_len, - unw_word_t *offp) +elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) { unsigned long segbase, mapoff; Elf_W (Addr) load_offset = 0; @@ -158,7 +161,7 @@ elf_w (get_proc_name) (pid_t pid, unw_word_t ip, char *buf, size_t buf_len, break; } - ret = elf_w (lookup_symbol) (ip, &ei, load_offset, buf, buf_len, offp); + ret = elf_w (lookup_symbol) (as, ip, &ei, load_offset, buf, buf_len, offp); munmap (ei.image, ei.size); ei.image = NULL; diff --git a/src/elfxx.h b/src/elfxx.h index a12375b9..7742806b 100644 --- a/src/elfxx.h +++ b/src/elfxx.h @@ -1,6 +1,7 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2003, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang This file is part of libunwind. @@ -68,6 +69,7 @@ elf_map_image (struct elf_image *ei, const char *path) } extern int elf_w (valid_object) (struct elf_image *ei); -extern int elf_w (get_proc_name) (pid_t pid, unw_word_t ip, +extern int elf_w (get_proc_name) (unw_addr_space_t as, + pid_t pid, unw_word_t ip, char *buf, size_t len, unw_word_t *offp); diff --git a/src/hppa/Ginit.c b/src/hppa/Ginit.c index 6826d4a3..5326b829 100644 --- a/src/hppa/Ginit.c +++ b/src/hppa/Ginit.c @@ -1,6 +1,7 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2002, 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang This file is part of libunwind. @@ -171,7 +172,7 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, char *buf, size_t buf_len, unw_word_t *offp, void *arg) { - return _Uelf32_get_proc_name (getpid (), ip, buf, buf_len, offp); + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } HIDDEN void diff --git a/src/ia64/Ginit.c b/src/ia64/Ginit.c index 24596b06..0ba95546 100644 --- a/src/ia64/Ginit.c +++ b/src/ia64/Ginit.c @@ -1,6 +1,7 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2001-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang This file is part of libunwind. @@ -352,7 +353,7 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, if (!_Uelf64_get_proc_name) return -UNW_EINVAL; #endif - return _Uelf64_get_proc_name (getpid (), ip, buf, buf_len, offp); + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } HIDDEN void diff --git a/src/ppc64/Ginit.c b/src/ppc64/Ginit.c index 572f9c62..97c9d78c 100644 --- a/src/ppc64/Ginit.c +++ b/src/ppc64/Ginit.c @@ -208,7 +208,7 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, char *buf, size_t buf_len, unw_word_t *offp, void *arg) { - return _Uelf64_get_proc_name (getpid (), ip, buf, buf_len, offp); + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } HIDDEN void diff --git a/src/ppc64/get_func_addr.c b/src/ppc64/get_func_addr.c new file mode 100644 index 00000000..5a8139fa --- /dev/null +++ b/src/ppc64/get_func_addr.c @@ -0,0 +1,43 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +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" + +int +tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, + unw_word_t *entry_point) +{ + unw_accessors_t *a; + int ret; + + a = unw_get_accessors (as); + /* entry-point is stored in the 1st word of the function descriptor: */ + ret = (a->access_mem) (as, addr + offset, entry_point, 0, NULL); + if (ret < 0) + return ret; + return 0; +} diff --git a/src/ptrace/_UPT_get_proc_name.c b/src/ptrace/_UPT_get_proc_name.c index ebb7b5f6..6ac85a0a 100644 --- a/src/ptrace/_UPT_get_proc_name.c +++ b/src/ptrace/_UPT_get_proc_name.c @@ -1,6 +1,7 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang This file is part of libunwind. @@ -32,9 +33,9 @@ _UPT_get_proc_name (unw_addr_space_t as, unw_word_t ip, struct UPT_info *ui = arg; #if ELF_CLASS == ELFCLASS64 - return _Uelf64_get_proc_name (ui->pid, ip, buf, buf_len, offp); + return _Uelf64_get_proc_name (as, ui->pid, ip, buf, buf_len, offp); #elif ELF_CLASS == ELFCLASS32 - return _Uelf32_get_proc_name (ui->pid, ip, buf, buf_len, offp); + return _Uelf32_get_proc_name (as, ui->pid, ip, buf, buf_len, offp); #else return -UNW_ENOINFO; #endif diff --git a/src/x86/Ginit.c b/src/x86/Ginit.c index 3b206a3e..abc9e613 100644 --- a/src/x86/Ginit.c +++ b/src/x86/Ginit.c @@ -1,6 +1,7 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang This file is part of libunwind. @@ -186,7 +187,7 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, char *buf, size_t buf_len, unw_word_t *offp, void *arg) { - return _Uelf32_get_proc_name (getpid (), ip, buf, buf_len, offp); + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } HIDDEN void diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c index 4689ef91..026e8d25 100644 --- a/src/x86_64/Ginit.c +++ b/src/x86_64/Ginit.c @@ -1,6 +1,7 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang Modified for x86_64 by Max Asbock @@ -233,7 +234,7 @@ get_static_proc_name (unw_addr_space_t as, unw_word_t ip, char *buf, size_t buf_len, unw_word_t *offp, void *arg) { - return _Uelf64_get_proc_name (getpid (), ip, buf, buf_len, offp); + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); } HIDDEN void