Add libunwind source code from AOSP (android-8.1.0_r7).
This commit is contained in:
Коммит
c99b3e5844
|
@ -0,0 +1,69 @@
|
|||
*.la
|
||||
*.a
|
||||
*.o
|
||||
*.lo
|
||||
*~
|
||||
|
||||
.libs/
|
||||
.deps/
|
||||
|
||||
.dirstamp
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
||||
INSTALL
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.log
|
||||
config.status
|
||||
config/
|
||||
configure
|
||||
libtool
|
||||
|
||||
doc/common.tex
|
||||
|
||||
src/[GL]cursor_i.h
|
||||
src/mk_[GL]cursor_i.s
|
||||
|
||||
include/config.h
|
||||
include/config.h.in
|
||||
include/libunwind-common.h
|
||||
include/stamp-h1
|
||||
|
||||
tests/[GL]test-bt
|
||||
tests/[GL]test-concurrent
|
||||
tests/[GL]test-dyn1
|
||||
tests/[GL]test-exc
|
||||
tests/[GL]test-init
|
||||
tests/[GL]test-resume-sig
|
||||
tests/[GL]test-resume-sig-rt
|
||||
tests/[GL]perf-simple
|
||||
tests/Ltest-nomalloc
|
||||
tests/Ltest-nocalloc
|
||||
tests/Lperf-simple
|
||||
tests/check-namespace.sh
|
||||
tests/crasher
|
||||
tests/forker
|
||||
tests/mapper
|
||||
tests/rs-race
|
||||
tests/test-async-sig
|
||||
tests/test-coredump-unwind
|
||||
tests/test-flush-cache
|
||||
tests/test-init-remote
|
||||
tests/test-mem
|
||||
tests/test-ptrace
|
||||
tests/test-setjmp
|
||||
tests/test-strerror
|
||||
tests/test-proc-info
|
||||
tests/test-ptrace-misc
|
||||
tests/test-varargs
|
||||
tests/test-static-link
|
||||
tests/[GL]test-trace
|
||||
tests/[GL]perf-trace
|
||||
tests/Ltest-cxx-exceptions
|
||||
tests/[GL]ia64-test-nat
|
||||
tests/[GL]ia64-test-rbs
|
||||
tests/[GL]ia64-test-readonly
|
||||
tests/[GL]ia64-test-stack
|
||||
tests/ia64-test-dyn1
|
||||
tests/ia64-test-sig
|
|
@ -0,0 +1 @@
|
|||
David Mosberger <dmosberger@gmail.org>
|
|
@ -0,0 +1,508 @@
|
|||
//
|
||||
// Copyright (C) 2014 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// Set to true to enable a debug build of the libraries.
|
||||
// To control what is logged, set the environment variable UNW_DEBUG_LEVEL=x,
|
||||
// where x controls the verbosity (from 1 to 20).
|
||||
//libunwind_debug = false
|
||||
|
||||
cc_defaults {
|
||||
name: "libunwind_defaults",
|
||||
host_supported: true,
|
||||
vendor_available: true,
|
||||
|
||||
cppflags: [
|
||||
"-Wno-old-style-cast",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-Werror",
|
||||
"-Wno-#pragma-messages",
|
||||
"-Wno-unused-parameter",
|
||||
|
||||
"-DHAVE_CONFIG_H",
|
||||
"-D_GNU_SOURCE",
|
||||
"-DNDEBUG",
|
||||
],
|
||||
|
||||
// libunwind expects to find include/libunwind_i.h before
|
||||
// include/tdep-<arch>/libunwind_i.h, but soong prepends arch-specific
|
||||
// include directories. To keep the include directories in the right
|
||||
// order, pass "include" as an architecture specific include for every
|
||||
// architecture.
|
||||
arch: {
|
||||
arm: {
|
||||
local_include_dirs: [
|
||||
"include",
|
||||
"include/tdep-arm",
|
||||
],
|
||||
},
|
||||
arm64: {
|
||||
local_include_dirs: [
|
||||
"include",
|
||||
"include/tdep-aarch64",
|
||||
],
|
||||
},
|
||||
mips: {
|
||||
local_include_dirs: [
|
||||
"include",
|
||||
"include/tdep-mips",
|
||||
],
|
||||
},
|
||||
mips64: {
|
||||
local_include_dirs: [
|
||||
"include",
|
||||
"include/tdep-mips",
|
||||
],
|
||||
},
|
||||
x86: {
|
||||
local_include_dirs: [
|
||||
"include",
|
||||
"include/tdep-x86",
|
||||
],
|
||||
},
|
||||
x86_64: {
|
||||
local_include_dirs: [
|
||||
"include",
|
||||
"include/tdep-x86_64",
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
target: {
|
||||
android: {
|
||||
// gcc 4.8 appears to be overeager declaring that a variable is uninitialized,
|
||||
// under certain circumstances. Turn off this warning only for target so that
|
||||
// coverage is still present for the host code. When the entire build system
|
||||
// is switched to 4.9, then this can be removed.
|
||||
cflags: ["-Wno-maybe-uninitialized"],
|
||||
},
|
||||
darwin: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
|
||||
clang_cflags: [
|
||||
// src/mi/backtrace.c is misdetected as a bogus header guard by clang 3.5
|
||||
// src/x86_64/Gstash_frame.c has unnecessary calls to labs.
|
||||
"-Wno-header-guard",
|
||||
"-Wno-absolute-value",
|
||||
// The latest clang (r230699) does not allow SP/PC to be declared in inline asm lists.
|
||||
"-Wno-inline-asm",
|
||||
],
|
||||
|
||||
debug: {
|
||||
cflags: [
|
||||
"-UNDEBUG",
|
||||
"-DDEBUG",
|
||||
"-U_FORTIFY_SOURCE",
|
||||
],
|
||||
},
|
||||
|
||||
local_include_dirs: [
|
||||
"src",
|
||||
],
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// libunwind shared and static library
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cc_library {
|
||||
name: "libunwind",
|
||||
defaults: ["libunwind_defaults"],
|
||||
vndk: {
|
||||
enabled: true,
|
||||
support_system_process: true,
|
||||
},
|
||||
sdk_version: "21",
|
||||
stl: "none",
|
||||
|
||||
srcs: [
|
||||
"src/mi/init.c",
|
||||
"src/mi/flush_cache.c",
|
||||
"src/mi/mempool.c",
|
||||
"src/mi/strerror.c",
|
||||
"src/mi/backtrace.c",
|
||||
"src/mi/dyn-cancel.c",
|
||||
"src/mi/dyn-info-list.c",
|
||||
"src/mi/dyn-register.c",
|
||||
"src/mi/map.c",
|
||||
"src/mi/Lmap.c",
|
||||
"src/mi/Ldyn-extract.c",
|
||||
"src/mi/Lfind_dynamic_proc_info.c",
|
||||
"src/mi/Lget_proc_info_by_ip.c",
|
||||
"src/mi/Lget_proc_name.c",
|
||||
"src/mi/Lput_dynamic_unwind_info.c",
|
||||
"src/mi/Ldestroy_addr_space.c",
|
||||
"src/mi/Lget_reg.c",
|
||||
"src/mi/Lset_reg.c",
|
||||
"src/mi/Lget_fpreg.c",
|
||||
"src/mi/Lset_fpreg.c",
|
||||
"src/mi/Lset_caching_policy.c",
|
||||
"src/mi/Gdyn-extract.c",
|
||||
"src/mi/Gdyn-remote.c",
|
||||
"src/mi/Gfind_dynamic_proc_info.c",
|
||||
"src/mi/Gget_accessors.c",
|
||||
"src/mi/Gget_proc_info_by_ip.c",
|
||||
"src/mi/Gget_proc_name.c",
|
||||
"src/mi/Gput_dynamic_unwind_info.c",
|
||||
"src/mi/Gdestroy_addr_space.c",
|
||||
"src/mi/Gget_reg.c",
|
||||
"src/mi/Gset_reg.c",
|
||||
"src/mi/Gget_fpreg.c",
|
||||
"src/mi/Gset_fpreg.c",
|
||||
"src/mi/Gset_caching_policy.c",
|
||||
"src/dwarf/Lexpr.c",
|
||||
"src/dwarf/Lfde.c",
|
||||
"src/dwarf/Lparser.c",
|
||||
"src/dwarf/Lpe.c",
|
||||
"src/dwarf/Lstep_dwarf.c",
|
||||
"src/dwarf/Lfind_proc_info-lsb.c",
|
||||
"src/dwarf/Lfind_unwind_table.c",
|
||||
"src/dwarf/Gexpr.c",
|
||||
"src/dwarf/Gfde.c",
|
||||
"src/dwarf/Gfind_proc_info-lsb.c",
|
||||
"src/dwarf/Gfind_unwind_table.c",
|
||||
"src/dwarf/Gparser.c",
|
||||
"src/dwarf/Gpe.c",
|
||||
"src/dwarf/Gstep_dwarf.c",
|
||||
"src/dwarf/global.c",
|
||||
"src/os-common.c",
|
||||
"src/os-linux.c",
|
||||
"src/Los-common.c",
|
||||
|
||||
// ptrace files for remote unwinding.
|
||||
"src/ptrace/_UPT_accessors.c",
|
||||
"src/ptrace/_UPT_access_fpreg.c",
|
||||
"src/ptrace/_UPT_access_mem.c",
|
||||
"src/ptrace/_UPT_access_reg.c",
|
||||
"src/ptrace/_UPT_create.c",
|
||||
"src/ptrace/_UPT_destroy.c",
|
||||
"src/ptrace/_UPT_find_proc_info.c",
|
||||
"src/ptrace/_UPT_get_dyn_info_list_addr.c",
|
||||
"src/ptrace/_UPT_put_unwind_info.c",
|
||||
"src/ptrace/_UPT_get_proc_name.c",
|
||||
"src/ptrace/_UPT_reg_offset.c",
|
||||
"src/ptrace/_UPT_resume.c",
|
||||
],
|
||||
|
||||
arch: {
|
||||
arm: {
|
||||
srcs: [
|
||||
"src/arm/is_fpreg.c",
|
||||
"src/arm/regname.c",
|
||||
"src/arm/Gcreate_addr_space.c",
|
||||
"src/arm/Gget_proc_info.c",
|
||||
"src/arm/Gget_save_loc.c",
|
||||
"src/arm/Gglobal.c",
|
||||
"src/arm/Ginit.c",
|
||||
"src/arm/Ginit_local.c",
|
||||
"src/arm/Ginit_remote.c",
|
||||
"src/arm/Gregs.c",
|
||||
"src/arm/Gresume.c",
|
||||
"src/arm/Gstep.c",
|
||||
"src/arm/Lcreate_addr_space.c",
|
||||
"src/arm/Lget_proc_info.c",
|
||||
"src/arm/Lget_save_loc.c",
|
||||
"src/arm/Lglobal.c",
|
||||
"src/arm/Linit.c",
|
||||
"src/arm/Linit_local.c",
|
||||
"src/arm/Linit_remote.c",
|
||||
"src/arm/Lregs.c",
|
||||
"src/arm/Lresume.c",
|
||||
"src/arm/Lstep.c",
|
||||
|
||||
"src/arm/getcontext.S",
|
||||
"src/arm/Gis_signal_frame.c",
|
||||
"src/arm/Gex_tables.c",
|
||||
"src/arm/Lis_signal_frame.c",
|
||||
"src/arm/Lex_tables.c",
|
||||
],
|
||||
},
|
||||
arm64: {
|
||||
srcs: [
|
||||
"src/aarch64/is_fpreg.c",
|
||||
"src/aarch64/regname.c",
|
||||
"src/aarch64/Gcreate_addr_space.c",
|
||||
"src/aarch64/Gget_proc_info.c",
|
||||
"src/aarch64/Gget_save_loc.c",
|
||||
"src/aarch64/Gglobal.c",
|
||||
"src/aarch64/Ginit.c",
|
||||
"src/aarch64/Ginit_local.c",
|
||||
"src/aarch64/Ginit_remote.c",
|
||||
"src/aarch64/Gregs.c",
|
||||
"src/aarch64/Gresume.c",
|
||||
"src/aarch64/Gstep.c",
|
||||
"src/aarch64/Lcreate_addr_space.c",
|
||||
"src/aarch64/Lget_proc_info.c",
|
||||
"src/aarch64/Lget_save_loc.c",
|
||||
"src/aarch64/Lglobal.c",
|
||||
"src/aarch64/Linit.c",
|
||||
"src/aarch64/Linit_local.c",
|
||||
"src/aarch64/Linit_remote.c",
|
||||
"src/aarch64/Lregs.c",
|
||||
"src/aarch64/Lresume.c",
|
||||
"src/aarch64/Lstep.c",
|
||||
|
||||
"src/aarch64/Gis_signal_frame.c",
|
||||
"src/aarch64/Lis_signal_frame.c",
|
||||
],
|
||||
},
|
||||
mips: {
|
||||
srcs: [
|
||||
"src/mips/is_fpreg.c",
|
||||
"src/mips/regname.c",
|
||||
"src/mips/Gcreate_addr_space.c",
|
||||
"src/mips/Gget_proc_info.c",
|
||||
"src/mips/Gget_save_loc.c",
|
||||
"src/mips/Gglobal.c",
|
||||
"src/mips/Ginit.c",
|
||||
"src/mips/Ginit_local.c",
|
||||
"src/mips/Ginit_remote.c",
|
||||
"src/mips/Gregs.c",
|
||||
"src/mips/Gresume.c",
|
||||
"src/mips/Gstep.c",
|
||||
"src/mips/Lcreate_addr_space.c",
|
||||
"src/mips/Lget_proc_info.c",
|
||||
"src/mips/Lget_save_loc.c",
|
||||
"src/mips/Lglobal.c",
|
||||
"src/mips/Linit.c",
|
||||
"src/mips/Linit_local.c",
|
||||
"src/mips/Linit_remote.c",
|
||||
"src/mips/Lregs.c",
|
||||
"src/mips/Lresume.c",
|
||||
"src/mips/Lstep.c",
|
||||
|
||||
"src/mips/getcontext-android.S",
|
||||
"src/mips/Gis_signal_frame.c",
|
||||
"src/mips/Lis_signal_frame.c",
|
||||
],
|
||||
},
|
||||
// mips and mips64 use the same sources but define _MIP_SIM differently
|
||||
// to change the behavior.
|
||||
// mips uses o32 abi (_MIPS_SIM == _ABIO32).
|
||||
// mips64 uses n64 abi (_MIPS_SIM == _ABI64).
|
||||
mips64: {
|
||||
srcs: [
|
||||
"src/mips/is_fpreg.c",
|
||||
"src/mips/regname.c",
|
||||
"src/mips/Gcreate_addr_space.c",
|
||||
"src/mips/Gget_proc_info.c",
|
||||
"src/mips/Gget_save_loc.c",
|
||||
"src/mips/Gglobal.c",
|
||||
"src/mips/Ginit.c",
|
||||
"src/mips/Ginit_local.c",
|
||||
"src/mips/Ginit_remote.c",
|
||||
"src/mips/Gregs.c",
|
||||
"src/mips/Gresume.c",
|
||||
"src/mips/Gstep.c",
|
||||
"src/mips/Lcreate_addr_space.c",
|
||||
"src/mips/Lget_proc_info.c",
|
||||
"src/mips/Lget_save_loc.c",
|
||||
"src/mips/Lglobal.c",
|
||||
"src/mips/Linit.c",
|
||||
"src/mips/Linit_local.c",
|
||||
"src/mips/Linit_remote.c",
|
||||
"src/mips/Lregs.c",
|
||||
"src/mips/Lresume.c",
|
||||
"src/mips/Lstep.c",
|
||||
|
||||
"src/mips/getcontext-android.S",
|
||||
"src/mips/Gis_signal_frame.c",
|
||||
"src/mips/Lis_signal_frame.c",
|
||||
],
|
||||
},
|
||||
x86: {
|
||||
srcs: [
|
||||
"src/x86/is_fpreg.c",
|
||||
"src/x86/regname.c",
|
||||
"src/x86/Gcreate_addr_space.c",
|
||||
"src/x86/Gget_proc_info.c",
|
||||
"src/x86/Gget_save_loc.c",
|
||||
"src/x86/Gglobal.c",
|
||||
"src/x86/Ginit.c",
|
||||
"src/x86/Ginit_local.c",
|
||||
"src/x86/Ginit_remote.c",
|
||||
"src/x86/Gregs.c",
|
||||
"src/x86/Gresume.c",
|
||||
"src/x86/Gstep.c",
|
||||
"src/x86/Lcreate_addr_space.c",
|
||||
"src/x86/Lget_proc_info.c",
|
||||
"src/x86/Lget_save_loc.c",
|
||||
"src/x86/Lglobal.c",
|
||||
"src/x86/Linit.c",
|
||||
"src/x86/Linit_local.c",
|
||||
"src/x86/Linit_remote.c",
|
||||
"src/x86/Lregs.c",
|
||||
"src/x86/Lresume.c",
|
||||
"src/x86/Lstep.c",
|
||||
|
||||
"src/x86/getcontext-linux.S",
|
||||
"src/x86/Gos-linux.c",
|
||||
"src/x86/Los-linux.c",
|
||||
],
|
||||
},
|
||||
x86_64: {
|
||||
srcs: [
|
||||
"src/x86_64/is_fpreg.c",
|
||||
"src/x86_64/regname.c",
|
||||
"src/x86_64/Gcreate_addr_space.c",
|
||||
"src/x86_64/Gget_proc_info.c",
|
||||
"src/x86_64/Gget_save_loc.c",
|
||||
"src/x86_64/Gglobal.c",
|
||||
"src/x86_64/Ginit.c",
|
||||
"src/x86_64/Ginit_local.c",
|
||||
"src/x86_64/Ginit_remote.c",
|
||||
"src/x86_64/Gregs.c",
|
||||
"src/x86_64/Gresume.c",
|
||||
"src/x86_64/Gstep.c",
|
||||
"src/x86_64/Lcreate_addr_space.c",
|
||||
"src/x86_64/Lget_proc_info.c",
|
||||
"src/x86_64/Lget_save_loc.c",
|
||||
"src/x86_64/Lglobal.c",
|
||||
"src/x86_64/Linit.c",
|
||||
"src/x86_64/Linit_local.c",
|
||||
"src/x86_64/Linit_remote.c",
|
||||
"src/x86_64/Lregs.c",
|
||||
"src/x86_64/Lresume.c",
|
||||
"src/x86_64/Lstep.c",
|
||||
|
||||
"src/x86_64/getcontext.S",
|
||||
"src/x86_64/Gstash_frame.c",
|
||||
"src/x86_64/Gtrace.c",
|
||||
"src/x86_64/Gos-linux.c",
|
||||
"src/x86_64/Lstash_frame.c",
|
||||
"src/x86_64/Ltrace.c",
|
||||
"src/x86_64/Los-linux.c",
|
||||
"src/x86_64/setcontext.S",
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
multilib: {
|
||||
lib32: {
|
||||
srcs: ["src/elf32.c"],
|
||||
},
|
||||
lib64: {
|
||||
srcs: ["src/elf64.c"],
|
||||
},
|
||||
},
|
||||
|
||||
target: {
|
||||
android: {
|
||||
shared_libs: ["libdl"],
|
||||
},
|
||||
linux: {
|
||||
ldflags: ["-nostdlib"],
|
||||
host_ldlibs: [
|
||||
"-lc",
|
||||
"-lpthread",
|
||||
],
|
||||
},
|
||||
linux_bionic: {
|
||||
enabled: true,
|
||||
shared_libs: ["libdl"],
|
||||
},
|
||||
},
|
||||
|
||||
export_include_dirs: ["include"],
|
||||
|
||||
shared_libs: ["liblzma"],
|
||||
|
||||
debug: {
|
||||
//shared_libs: ["liblog"],
|
||||
},
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// libunwindbacktrace static library
|
||||
//-----------------------------------------------------------------------
|
||||
cc_library_static {
|
||||
name: "libunwindbacktrace",
|
||||
defaults: ["libunwind_defaults"],
|
||||
sdk_version: "21",
|
||||
srcs: [
|
||||
"src/unwind/BacktraceWrapper.c",
|
||||
"src/unwind/DeleteException.c",
|
||||
"src/unwind/FindEnclosingFunction.c",
|
||||
"src/unwind/ForcedUnwind.c",
|
||||
"src/unwind/GetBSP.c",
|
||||
"src/unwind/GetCFA.c",
|
||||
"src/unwind/GetDataRelBase.c",
|
||||
"src/unwind/GetGR.c",
|
||||
"src/unwind/GetIP.c",
|
||||
"src/unwind/GetIPInfo.c",
|
||||
"src/unwind/GetLanguageSpecificData.c",
|
||||
"src/unwind/GetRegionStart.c",
|
||||
"src/unwind/GetTextRelBase.c",
|
||||
"src/unwind/RaiseException.c",
|
||||
"src/unwind/Resume.c",
|
||||
"src/unwind/Resume_or_Rethrow.c",
|
||||
"src/unwind/SetGR.c",
|
||||
"src/unwind/SetIP.c",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-Wno-old-style-declaration",
|
||||
"-fvisibility=hidden",
|
||||
],
|
||||
|
||||
whole_static_libs: ["libunwind"],
|
||||
|
||||
target: {
|
||||
linux_bionic: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// libunwind testing
|
||||
//-----------------------------------------------------------------------
|
||||
cc_test {
|
||||
name: "libunwind-unit-tests",
|
||||
srcs: ["android/tests/local_test.cpp"],
|
||||
defaults: ["libunwind_defaults"],
|
||||
|
||||
cflags: [
|
||||
"-fno-builtin",
|
||||
"-O0",
|
||||
"-g",
|
||||
],
|
||||
|
||||
local_include_dirs: ["include"],
|
||||
shared_libs: ["libunwind"],
|
||||
}
|
||||
|
||||
/*
|
||||
// Run the unit tests built for x86 or x86_64.
|
||||
// ANDROIDMK TRANSLATION ERROR: unsupported conditional
|
||||
// ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
|
||||
// ANDROIDMK TRANSLATION ERROR: unsupported conditional
|
||||
// ifneq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86))
|
||||
LINKER = ["linker64"]
|
||||
TEST_SUFFIX = ["64"]
|
||||
// ANDROIDMK TRANSLATION ERROR: else from unsupported contitional
|
||||
// else
|
||||
LINKER = ["linker"]
|
||||
TEST_SUFFIX = ["32"]
|
||||
// ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional
|
||||
// endif
|
||||
|
||||
// ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional
|
||||
// endif
|
||||
*/
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2002 Hewlett-Packard Co.
|
||||
|
||||
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.
|
|
@ -0,0 +1,55 @@
|
|||
***********************************************************
|
||||
|
||||
Discontinued. See git log instead at
|
||||
|
||||
http://www.kernel.org/git/gitweb.cgi?p=libs/libunwind/libunwind.git;a=log
|
||||
|
||||
***********************************************************
|
||||
|
||||
2002-11-08 David Mosberger-Tang <David.Mosberger@acm.org>
|
||||
|
||||
* src/ia64/unwind_i.h (ia64_getfp): Change from macro to inline
|
||||
function. Check "loc" argument for being NULL before dereferencing it.
|
||||
(ia64_putfp): Ditto.
|
||||
(ia64_get): Ditto.
|
||||
(ia64_put): Ditto.
|
||||
|
||||
2002-01-18 David Mosberger-Tang <David.Mosberger@acm.org>
|
||||
|
||||
* src/ia64/parser.c (__ia64_unw_create_state_record): Set
|
||||
IA64_FLAG_HAS_HANDLER if the unwind info descriptors indicate that
|
||||
there a handler.
|
||||
|
||||
* src/ia64/regs.c (__ia64_access_reg): Return zero for UNW_REG_HANDLER
|
||||
in frames that don't have a personality routine.
|
||||
|
||||
* src/ia64/unwind_i.h (IA64_FLAG_HAS_HANDLER): New flag.
|
||||
|
||||
* src/ia64/regs.c (__ia64_access_reg): When reading UNW_REG_HANDLER,
|
||||
account for the fact that the personality address is gp-relative.
|
||||
|
||||
* src/ia64/parser.c (__ia64_unw_create_state_record): Fix
|
||||
initialization of segbase and len.
|
||||
|
||||
2002-01-17 David Mosberger-Tang <David.Mosberger@acm.org>
|
||||
|
||||
* include/unwind-ia64.h: Include via "unwind.h" to ensure
|
||||
the file is picked up from same directory.
|
||||
|
||||
2002-01-16 David Mosberger-Tang <David.Mosberger@acm.org>
|
||||
|
||||
* include/unwind.h: Define UNW_ESTOPUNWIND. This error code may
|
||||
be returned by acquire_unwind_info() to force termination of
|
||||
unwinding. An application may want to do this when encountering a
|
||||
call frame for dynamically generated code, for example.
|
||||
|
||||
* unwind.h: Pass opaque argument pointer to acquire_unwind_info()
|
||||
and release_unwind_info() like we do for access_mem() etc.
|
||||
|
||||
2002-01-14 David Mosberger-Tang <David.Mosberger@acm.org>
|
||||
|
||||
* Version 0.0 released.
|
||||
|
||||
2002-01-11 David Mosberger-Tang <David.Mosberger@acm.org>
|
||||
|
||||
* ChangeLog created.
|
|
@ -0,0 +1,18 @@
|
|||
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.
|
|
@ -0,0 +1,86 @@
|
|||
include_HEADERS = include/libunwind-dynamic.h \
|
||||
include/libunwind-ptrace.h \
|
||||
include/libunwind-coredump.h
|
||||
|
||||
if ARCH_AARCH64
|
||||
include_HEADERS += include/libunwind-aarch64.h
|
||||
endif
|
||||
if ARCH_ARM
|
||||
include_HEADERS += include/libunwind-arm.h
|
||||
endif
|
||||
if ARCH_IA64
|
||||
include_HEADERS += include/libunwind-ia64.h
|
||||
endif
|
||||
if ARCH_HPPA
|
||||
include_HEADERS += include/libunwind-hppa.h
|
||||
endif
|
||||
if ARCH_MIPS
|
||||
include_HEADERS += include/libunwind-mips.h
|
||||
endif
|
||||
if ARCH_X86
|
||||
include_HEADERS += include/libunwind-x86.h
|
||||
endif
|
||||
if ARCH_X86_64
|
||||
include_HEADERS += include/libunwind-x86_64.h
|
||||
endif
|
||||
if ARCH_PPC32
|
||||
include_HEADERS += include/libunwind-ppc32.h
|
||||
endif
|
||||
if ARCH_PPC64
|
||||
include_HEADERS += include/libunwind-ppc64.h
|
||||
endif
|
||||
if ARCH_SH
|
||||
include_HEADERS += include/libunwind-sh.h
|
||||
endif
|
||||
|
||||
if !REMOTE_ONLY
|
||||
include_HEADERS += include/libunwind.h include/unwind.h
|
||||
endif
|
||||
|
||||
nodist_include_HEADERS = include/libunwind-common.h
|
||||
|
||||
SUBDIRS = src tests doc
|
||||
|
||||
noinst_HEADERS = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \
|
||||
include/compiler.h include/libunwind_i.h include/mempool.h \
|
||||
include/remote.h \
|
||||
include/tdep-aarch64/dwarf-config.h \
|
||||
include/tdep-aarch64/jmpbuf.h \
|
||||
include/tdep-aarch64/libunwind_i.h \
|
||||
include/tdep-arm/dwarf-config.h include/tdep-arm/ex_tables.h \
|
||||
include/tdep-arm/jmpbuf.h include/tdep-arm/libunwind_i.h \
|
||||
include/tdep-ia64/jmpbuf.h include/tdep-ia64/rse.h \
|
||||
include/tdep-ia64/libunwind_i.h include/tdep-ia64/script.h \
|
||||
include/tdep-hppa/libunwind_i.h \
|
||||
include/tdep-hppa/jmpbuf.h include/tdep-hppa/dwarf-config.h \
|
||||
include/tdep-mips/libunwind_i.h \
|
||||
include/tdep-mips/jmpbuf.h include/tdep-mips/dwarf-config.h \
|
||||
include/tdep-x86/libunwind_i.h \
|
||||
include/tdep-x86/jmpbuf.h include/tdep-x86/dwarf-config.h \
|
||||
include/tdep-x86_64/libunwind_i.h \
|
||||
include/tdep-x86_64/jmpbuf.h include/tdep-x86_64/dwarf-config.h \
|
||||
include/tdep-ppc32/dwarf-config.h \
|
||||
include/tdep-ppc32/jmpbuf.h include/tdep-ppc32/libunwind_i.h \
|
||||
include/tdep-ppc64/dwarf-config.h \
|
||||
include/tdep-ppc64/jmpbuf.h include/tdep-ppc64/libunwind_i.h \
|
||||
include/tdep-sh/dwarf-config.h \
|
||||
include/tdep-sh/jmpbuf.h include/tdep-sh/libunwind_i.h \
|
||||
include/tdep/libunwind_i.h \
|
||||
include/tdep/jmpbuf.h include/tdep/dwarf-config.h
|
||||
|
||||
EXTRA_DIST = include/libunwind-common.h.in
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in \
|
||||
INSTALL \
|
||||
aclocal.m4 \
|
||||
configure \
|
||||
config/compile \
|
||||
config/config.guess \
|
||||
config/config.sub \
|
||||
config/depcomp \
|
||||
config/install-sh \
|
||||
config/ltmain.sh \
|
||||
config/missing \
|
||||
include/config.h.in \
|
||||
include/config.h.in~
|
|
@ -0,0 +1,229 @@
|
|||
-*-Mode: outline-*-
|
||||
|
||||
* News for v1.1:
|
||||
|
||||
** coredump unwind support
|
||||
** New arch: SuperH
|
||||
** Improved support for PowerPC, ARM
|
||||
** Lots of cleanups, perf tweaks
|
||||
** pkg-config support
|
||||
|
||||
* News for v1.0:
|
||||
|
||||
** Fast unwind (rbp, rsp, rip only) on x86_64 with a fallback to
|
||||
slow code path (Lassi Tuura)
|
||||
** Improved local and remote unwinding on ARM (Ken Werner)
|
||||
** Testing, stability and many fixes on x86 (Paul Pluzhnikov)
|
||||
** FreeBSD port and clean separation of OS specific bits
|
||||
(Konstantin Belousov)
|
||||
** Thanks for all the bug reports, contributions and testing!
|
||||
|
||||
* News for v0.99:
|
||||
|
||||
** Greatly improved x86-64 support thanks to Arun Sharma.
|
||||
** Support for PPC64 added by Jose Flavio Aguilar Paulino.
|
||||
|
||||
* News for v0.98.6:
|
||||
|
||||
** Fix address-leak triggered by invalid byte-order. Fixed by Andreas Schwab.
|
||||
** On ia64, get_static_proc_name() no longer uses a weak reference to
|
||||
_Uelf64_get_proc_name(), since that was causing problems with archive
|
||||
libraries and no longer served any apparent purpose. Fixed by
|
||||
Curt Wohlgemuth.
|
||||
|
||||
* News for v0.98.5:
|
||||
|
||||
** Fix a typo in the man-page of unw_create_addr_space().
|
||||
** Fix an off-by-1 bug in the handling of the dynamic ALIAS directive
|
||||
for ia64. Reported by Todd L. Miller.
|
||||
** Fix a bug in libunwind-ptrace which could cause crash due to extraneous
|
||||
munmap() calls.
|
||||
|
||||
* News for v0.98.4:
|
||||
|
||||
** Fix a typo in _ReadSLEB.c which caused hangs when throwing exceptions
|
||||
from Intel ICC-compiled programs. Reported by Tommy Hoffner.
|
||||
|
||||
* News for v0.98.3:
|
||||
|
||||
** Make it possible to link against libunwind-ia64.a only (i.e., without
|
||||
requiring libunwind.a as well). This keeps apps which need only
|
||||
remote unwinding cleaner, since they logically have no dependency
|
||||
on libunwind.a.
|
||||
** Dont link against libatomic_ops for now. Due to a packaging bug on
|
||||
Debian, linking against this library causes libunwind.so to get
|
||||
a dependency on libatomic_ops.so, which is not at all what we want.
|
||||
Fortunately, we don't have to link against that library on x86 or
|
||||
ia64 since the library is strictly needed only for platforms with
|
||||
poor atomic operation support. Once the libatomic_ops package is fixed,
|
||||
we can re-enable linking against libatomic_ops.
|
||||
|
||||
* News for v0.98.2:
|
||||
|
||||
** Fixed bug which caused _UPT_get_dyn_info_list_addr() to sometimes fail
|
||||
needlessly. Found by Todd L. Miller.
|
||||
|
||||
** When using GCC to build libunwind on ia64, libunwind.so had an
|
||||
unresolved reference to __divdi3. This is undesirable since it
|
||||
creates an implicit dependency on libgcc. This problem has been
|
||||
fixed in the 0.98.2 release by explicitly linking against libgcc.a
|
||||
when building libunwind.
|
||||
|
||||
* News for v0.98.1:
|
||||
|
||||
** Fixed a bug which caused "make install" to install libunwind-common.h.in
|
||||
instead of libunwind-common.h.
|
||||
** Fixed a bug in the ia64 {sig,}longjmp() which showed on
|
||||
SuSE Linux 9 because it's using a newer compiler & the EPC-based system
|
||||
call stubs.
|
||||
** Fixed incorrect offsets in tests/ia64-test-nat-asm.S.
|
||||
Warning: you'll need a GNU assembler dated later than 21-Sep-2004 to
|
||||
get this file translated correctly. With an old assembler, "make check"
|
||||
will get lots of failures when running Gia64-test-nat or Lia64-test-nat!
|
||||
** Convert tests/bt into a full-blown test-case. It's designed to
|
||||
trigger a (rarely-encountered) bug in the GNU assembler on ia64.
|
||||
The assembler has been fixed and once the libraries (libc etc)
|
||||
have been rebuilt, this test will pass.
|
||||
** Added test-case tests/run-ptrace-misc which, on ia64, triggers a bug in
|
||||
current GCC (including v3.4.2) which causes bad unwind info.
|
||||
|
||||
* News for v0.98:
|
||||
|
||||
** Update libunwind to be compliant with the updated/expanded
|
||||
ia64 unwind specificiation by HJ Lu [1]. This is needed for
|
||||
GCC 3.4 compatibility.
|
||||
|
||||
[1] http://www.kernel.org/pub/linux/devel/gcc/unwind/
|
||||
|
||||
** Initial support for x86-64 has been added courtesy of Max Asbock.
|
||||
Along with this came a bunch of DWARF2 unwinder fixes.
|
||||
|
||||
** A new rountine unw_strerror() has been added courtesy of
|
||||
Thomas Hallgren.
|
||||
|
||||
** Including <libunwind.h> now defines 4 macros that can be used
|
||||
to determine the version number of libunwind. Specifically,
|
||||
UNW_VERSION_MAJOR, UNW_VERSION_MINOR, UNW_VERSION, and
|
||||
UNW_VERSION_CODE are defined by the header now.
|
||||
|
||||
** Bug fixes
|
||||
*** Fix a memory-leak in _UPT_get_dyn_info_list_addr() courtesy of Ed Connell.
|
||||
*** Fix a crash in libunwind-ptrace courtesy of Mark Young.
|
||||
*** Fix a bug in ia64-version of unw_init_remote() which prevented
|
||||
it from working correctly for the local address space. Reported by
|
||||
Troy Heber.
|
||||
*** Many other small and not so small fixes.
|
||||
|
||||
* News for v0.97:
|
||||
|
||||
** unw_get_proc_name() may now be called from signal-handler.
|
||||
|
||||
** The ptrace-helper routines are now declared in libunwind-ptrace.h.
|
||||
Applications which use ptrace-based unwinding should include
|
||||
<libunwind-ptrace.h> to get the _UPT_*() routines declared.
|
||||
|
||||
** libunwind has been split into a "local-only" and a "generic" versions.
|
||||
The former is optimized for local unwinding (within a process) and
|
||||
is called libunwind.so (shared version) or libunwind.a (archive
|
||||
version). The generic version is not limited to unwinding within a
|
||||
process and is called libunwind-generic.so (shared version)
|
||||
libunwind-generic.a (archive version). Similarly, the ptrace()
|
||||
support has been separated out into a convenience library called
|
||||
libunwind-ptrace.a. For the most part, backwards-compatibility
|
||||
is retained. However, when building an application which uses
|
||||
libunwind, it may be necessary to change the linker command-line
|
||||
as shown in the table below:
|
||||
|
||||
Application which does: Before v0.97: With v0.97:
|
||||
----------------------- ------------- -----------
|
||||
local unwinding only: -lunwind -lunwind
|
||||
remote unwinding: -lunwind -lunwind-generic
|
||||
cross unwinding: -lunwind-PLAT -lunwind-PLAT
|
||||
ptrace-based unwinding: -lunwind -lunwind-ptrace -lunwind-generic
|
||||
|
||||
The motivation for this splitting is to keep libunwind.so as minimal
|
||||
as possible. This library will eventually be loaded by most (if not
|
||||
all) executables and hence it is important to ensure that it can
|
||||
be loaded as quickly as possible.
|
||||
|
||||
** unw_getcontext() tuned on IA-64.
|
||||
|
||||
The unw_getcontext() routine used to be provided by (GNU) libc
|
||||
(getcontext()). This caused unnecessary overhead (e.g., an
|
||||
unnecessary system-call to sigprocmask()). The new
|
||||
unw_getcontext() only does the work really needed for libunwind and
|
||||
hence performs much better. However, this change implies that
|
||||
programs linked against libunwind v0.97 won't be
|
||||
backwards-compatible with earlier versions (there would be an
|
||||
unresolved symbol for _Uia64_getcontext()).
|
||||
|
||||
** Fix NaT-bit handling on IA-64.
|
||||
|
||||
New test-cases have been added to test the handling of the NaT bit
|
||||
(and floating-point NaT values) and all discovered/known bugs have
|
||||
been fixed.
|
||||
|
||||
** Initial DWARF-based unwinder for x86.
|
||||
|
||||
There is a beginning for a DWARF-based unwinder for x86. Work for
|
||||
x86-64-support based on this DWARF unwinder is currently underway
|
||||
at IBM and it is expected that this support will be merged into the
|
||||
official tree soon.
|
||||
|
||||
|
||||
* News for v0.96:
|
||||
|
||||
** _Unwind_*() routines defined by the C++ ABI are now included in
|
||||
libunwind.
|
||||
|
||||
|
||||
* News for v0.95:
|
||||
|
||||
** Bigger, better, faster, or so the theory goes.
|
||||
|
||||
|
||||
* News for v0.93:
|
||||
|
||||
** More bug-fixes & improved HP-UX support.
|
||||
|
||||
|
||||
* News for v0.92:
|
||||
|
||||
** Bug-fix release. IA-64 unwinder can now be built with Intel compiler (ECC).
|
||||
|
||||
|
||||
* News for v0.91:
|
||||
|
||||
** Lots of documentation updates
|
||||
** Some portability fixes.
|
||||
|
||||
|
||||
* News for v0.9:
|
||||
|
||||
** The libunwind API is mostly feature-complete at this point (hence the
|
||||
version jump from v0.2 to v0.9).
|
||||
|
||||
|
||||
* News for v0.2:
|
||||
|
||||
** Automated configuration/build with autoconf and automake.
|
||||
** Added support for building libunwind as a shared library.
|
||||
** Added support for remote unwinding.
|
||||
** Added support for cross-building.
|
||||
** Added two new routines to the API:
|
||||
- unw_is_fpreg()
|
||||
- unw_get_save_loc()
|
||||
** Added multi-architecture supports (lets a single application use
|
||||
the unwind libraries for multiple target architectures; this is useful,
|
||||
e.g., useful for building a debugger that can support multiple targets
|
||||
such as x86, ia64, etc.)
|
||||
|
||||
|
||||
* News for v0.1:
|
||||
|
||||
** Added support for exception handling.
|
||||
|
||||
|
||||
* News for v0.0:
|
||||
|
||||
** It's a brand new package.
|
|
@ -0,0 +1,18 @@
|
|||
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.
|
|
@ -0,0 +1,214 @@
|
|||
-*- mode: Outline -*-
|
||||
|
||||
This is version 1.0 of the unwind library. This library supports
|
||||
several architecture/operating-system combinations:
|
||||
|
||||
Linux/x86-64: Works well.
|
||||
Linux/x86: Works well.
|
||||
Linux/ARM: Works well.
|
||||
Linux/IA-64: Fully tested and supported.
|
||||
Linux/PARISC: Works well, but C library missing unwind-info.
|
||||
HP-UX/IA-64: Mostly works but known to have some serious limitations.
|
||||
Linux/AArch64: Newly added.
|
||||
Linux/PPC64: Newly added.
|
||||
Linux/SuperH: Newly added.
|
||||
FreeBSD/i386: Newly added.
|
||||
FreeBSD/x86-64: Newly added (FreeBSD architecture is known as amd64).
|
||||
|
||||
|
||||
* General Build Instructions
|
||||
|
||||
In general, this library can be built and installed with the following
|
||||
commands:
|
||||
|
||||
$ autoreconf -i # Needed only for building from git. Depends on libtool.
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install prefix=PREFIX
|
||||
|
||||
where PREFIX is the installation prefix. By default, a prefix of
|
||||
/usr/local is used, such that libunwind.a is installed in
|
||||
/usr/local/lib and unwind.h is installed in /usr/local/include. For
|
||||
testing, you may want to use a prefix of /usr/local instead.
|
||||
|
||||
|
||||
* Building with Intel compiler
|
||||
|
||||
** Version 8 and later
|
||||
|
||||
Starting with version 8, the preferred name for the IA-64 Intel
|
||||
compiler is "icc" (same name as on x86). Thus, the configure-line
|
||||
should look like this:
|
||||
|
||||
$ ./configure CC=icc CFLAGS="-g -O3 -ip" CXX=icc CCAS=gcc CCASFLAGS=-g \
|
||||
LDFLAGS="-L$PWD/src/.libs"
|
||||
|
||||
|
||||
* Building on HP-UX
|
||||
|
||||
For the time being, libunwind must be built with GCC on HP-UX.
|
||||
|
||||
libunwind should be configured and installed on HP-UX like this:
|
||||
|
||||
$ ./configure CFLAGS="-g -O2 -mlp64" CXXFLAGS="-g -O2 -mlp64"
|
||||
|
||||
Caveat: Unwinding of 32-bit (ILP32) binaries is not supported
|
||||
at the moment.
|
||||
|
||||
** Workaround for older versions of GCC
|
||||
|
||||
GCC v3.0 and GCC v3.2 ship with a bad version of sys/types.h. The
|
||||
workaround is to issue the following commands before running
|
||||
"configure":
|
||||
|
||||
$ mkdir $top_dir/include/sys
|
||||
$ cp /usr/include/sys/types.h $top_dir/include/sys
|
||||
|
||||
GCC v3.3.2 or later have been fixed and do not require this
|
||||
workaround.
|
||||
|
||||
* Building for PowerPC64 / Linux
|
||||
|
||||
For building for power64 you should use:
|
||||
|
||||
$ ./configure CFLAGS="-g -O2 -m64" CXXFLAGS="-g -O2 -m64"
|
||||
|
||||
If your power support altivec registers:
|
||||
$ ./configure CFLAGS="-g -O2 -m64 -maltivec" CXXFLAGS="-g -O2 -m64 -maltivec"
|
||||
|
||||
To check if your processor has support for vector registers (altivec):
|
||||
cat /proc/cpuinfo | grep altivec
|
||||
and should have something like this:
|
||||
cpu : PPC970, altivec supported
|
||||
|
||||
If libunwind seems to not work (backtracing failing), try to compile
|
||||
it with -O0, without optimizations. There are some compiler problems
|
||||
depending on the version of your gcc.
|
||||
|
||||
* Building on FreeBSD
|
||||
|
||||
General building instructions apply. To build and execute several tests,
|
||||
you need libexecinfo library available in ports as devel/libexecinfo.
|
||||
|
||||
Development of the port was done of FreeBSD 8.0-STABLE. The library
|
||||
was build with the system compiler that is modified version of gcc 4.2.1,
|
||||
as well as the gcc 4.4.3.
|
||||
|
||||
* Regression Testing
|
||||
|
||||
After building the library, you can run a set of regression tests with:
|
||||
|
||||
$ make check
|
||||
|
||||
** Expected results on IA-64 Linux
|
||||
|
||||
Unless you have a very recent C library and compiler installed, it is
|
||||
currently expected to have the following tests fail on IA-64 Linux:
|
||||
|
||||
Gtest-init (should pass starting with glibc-2.3.x/gcc-3.4)
|
||||
Ltest-init (should pass starting with glibc-2.3.x/gcc-3.4)
|
||||
test-ptrace (should pass starting with glibc-2.3.x/gcc-3.4)
|
||||
run-ia64-test-dyn1 (should pass starting with glibc-2.3.x)
|
||||
|
||||
This does not mean that libunwind cannot be used with older compilers
|
||||
or C libraries, it just means that for certain corner cases, unwinding
|
||||
will fail. Since they're corner cases, it is not likely for
|
||||
applications to trigger them.
|
||||
|
||||
Note: If you get lots of errors in Gia64-test-nat and Lia64-test-nat, it's
|
||||
almost certainly a sign of an old assembler. The GNU assembler used
|
||||
to encode previous-stack-pointer-relative offsets incorrectly.
|
||||
This bug was fixed on 21-Sep-2004 so any later assembler will be
|
||||
fine.
|
||||
|
||||
** Expected results on x86 Linux
|
||||
|
||||
The following tests are expected to fail on x86 Linux:
|
||||
|
||||
Gtest-resume-sig (fails to get SIGUSR2)
|
||||
Ltest-resume-sig (likewise)
|
||||
Gtest-dyn1 (no dynamic unwind info support yet)
|
||||
Ltest-dyn1 (no dynamic unwind info support yet)
|
||||
test-setjmp (longjmp() not implemented yet)
|
||||
run-check-namespace (no _Ux86_getcontext yet)
|
||||
test-ptrace
|
||||
|
||||
** Expected results on x86-64 Linux
|
||||
|
||||
The following tests are expected to fail on x86-64 Linux:
|
||||
|
||||
Gtest-dyn1 (no dynamic unwind info support yet)
|
||||
Ltest-dyn1 (no dynamic unwind info support yet)
|
||||
Gtest-init (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18743)
|
||||
Ltest-init (likewise)
|
||||
test-async-sig (crashes due to bad unwind-info?)
|
||||
test-setjmp (longjmp() not implemented yet)
|
||||
run-check-namespace (no _Ux86_64_getcontext yet)
|
||||
run-ptrace-mapper (??? investigate)
|
||||
run-ptrace-misc (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18748
|
||||
and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18749)
|
||||
|
||||
** Expected results on PARISC Linux
|
||||
|
||||
Caveat: GCC v3.4 or newer is needed on PA-RISC Linux. Earlier
|
||||
versions of the compiler failed to generate the exception-handling
|
||||
program header (GNU_EH_FRAME) needed for unwinding.
|
||||
|
||||
The following tests are expected to fail on x86-64 Linux:
|
||||
|
||||
Gtest-bt (backtrace truncated at kill() due to lack of unwind-info)
|
||||
Ltest-bt (likewise)
|
||||
Gtest-resume-sig (Gresume.c:my_rt_sigreturn() is wrong somehow)
|
||||
Ltest-resume-sig (likewise)
|
||||
Gtest-init (likewise)
|
||||
Ltest-init (likewise)
|
||||
Gtest-dyn1 (no dynamic unwind info support yet)
|
||||
Ltest-dyn1 (no dynamic unwind info support yet)
|
||||
test-setjmp (longjmp() not implemented yet)
|
||||
run-check-namespace (toolchain doesn't support HIDDEN yet)
|
||||
|
||||
** Expected results on HP-UX
|
||||
|
||||
"make check" is currently unsupported for HP-UX. You can try to run
|
||||
it, but most tests will fail (and some may fail to terminate). The
|
||||
only test programs that are known to work at this time are:
|
||||
|
||||
tests/bt
|
||||
tests/Gperf-simple
|
||||
tests/test-proc-info
|
||||
tests/test-static-link
|
||||
tests/Gtest-init
|
||||
tests/Ltest-init
|
||||
tests/Gtest-resume-sig
|
||||
tests/Ltest-resume-sig
|
||||
|
||||
** Expected results on PPC64 Linux
|
||||
|
||||
"make check" should run with no more than 10 out of 24 tests failed.
|
||||
|
||||
|
||||
* Performance Testing
|
||||
|
||||
This distribution includes a few simple performance tests which give
|
||||
some idea of the basic cost of various libunwind operations. After
|
||||
building the library, you can run these tests with the following
|
||||
commands:
|
||||
|
||||
$ cd tests
|
||||
$ make perf
|
||||
|
||||
* Contacting the Developers
|
||||
|
||||
Please direct all questions regarding this library to:
|
||||
|
||||
libunwind-devel@nongnu.org
|
||||
|
||||
You can do this by sending a mail to libunwind-request@nongnu.org with
|
||||
a body of:
|
||||
|
||||
subscribe libunwind-devel
|
||||
|
||||
or you can subscribe and manage your subscription via the
|
||||
web-interface at:
|
||||
|
||||
https://savannah.nongnu.org/mail/?group=libunwind
|
|
@ -0,0 +1,97 @@
|
|||
- Update the libunwind man page for the new/fixed cache-flushing behavior.
|
||||
Effectively, that unw_flush_cache() doesn't have to be called by
|
||||
applications except for extraordinary circumstances (e.g., if application
|
||||
implements its own runtime loader).
|
||||
- document split local-only/generic libraries and separate libunwind-ptrace.a
|
||||
convenience-library
|
||||
- document new "tdep" member in unw_proc_info_t structure
|
||||
- for DWARF 2, use a dummy CIE entry with an augmentation that
|
||||
provides the dyn-info-list-address
|
||||
|
||||
=== taken care of:
|
||||
|
||||
Testing:
|
||||
+ ensure that saving r4-r7 in a stacked register properly preserves
|
||||
the NaT bit, even in the face of register-rotation
|
||||
+ ensure that IA64_INSN_MOVE_STACKED works correctly in the face of
|
||||
register rotation
|
||||
+ on Linux, test access to f32-f127 in a signal handler (e.g., verify
|
||||
that fph partition gets initialized properly)
|
||||
+ According to Nicholas S. Wourms <nwourms@netscape.net>, adding this to the
|
||||
Makefile.am:
|
||||
AUTOMAKE_OPTIONS = 1.6 subdir-objects
|
||||
ensures that object-files are build in separate subdirectories and that
|
||||
in turn makes it possible for source files in different directories to
|
||||
have the same filename, thus avoiding the need for those ugly -x86, -ia64,
|
||||
etc., postfixes.
|
||||
+ Switch ia64 (and rest over) to using Debug() instead of debug()
|
||||
+ implement non-local versions of dwarf_readXX()
|
||||
+ consolidate mostly architecture-independent code such as
|
||||
unw_get_accessors() into shared files
|
||||
+ caching is pretty fundamentally broken, what should happen is this:
|
||||
o On unw_init_local()/unw_init_remote(), libunwind should validate
|
||||
that the cached information is still valid and, if not, flush the
|
||||
cache on its own. Rationale: once unw_init_local() has been
|
||||
called, it is clear that the unwind info for the calling thread
|
||||
cannot change (otherwise the program would be buggy anyhow) and
|
||||
hence it is sufficient to validate the cache at this point.
|
||||
Similarly, once unw_init_remote() has been called, the target
|
||||
address space must have been stopped, because the unwinding would
|
||||
otherwise be unreliable anyhow.
|
||||
o glibc currently lacks a feature for dl_iterate_phdr() to support
|
||||
safe caching; I proposed on 12/16/2003 that glibc maintain two
|
||||
atomic counters which get inremented whenever something is added
|
||||
to/removed from the dl_iterate_phdr-list. Once we have such counters,
|
||||
we can use them in libunwind to implement an efficient version of a
|
||||
cache-validation routine.
|
||||
Once this has been fixed, update the libunwind man page accordingly.
|
||||
Effectively, what this means is that unw_flush_cache() doesn't have
|
||||
to be called by applications except for extraordinary circumstances
|
||||
(e.g., if application implements its own runtime loader).
|
||||
+ man-page for unw_is_fpreg()
|
||||
+ man-page for _U_dyn_cancel()
|
||||
+ man-page for _U_dyn_register()
|
||||
+ global data is not protected by a lock; causes problems if two threads
|
||||
call ia64_init() at almost the same time
|
||||
+ cache the value of *cfm_loc; each rotate_FOO() call needs it!
|
||||
+ implement the remote-lookup of the dynamic registration list
|
||||
+ when doing sigreturn, must restore fp regs (and perhaps other regs) the same
|
||||
way as the (user-level) gate.S sigreturn path does!
|
||||
+ unw_resume() must at least restore gp (r1)! consider restoring all
|
||||
scratch regs (but what's the performance impact on exception handling?);
|
||||
alternative: restore scratch regs that may be used during procedure
|
||||
call/return (e.g., r8-r11, f8-f11)
|
||||
+ implement unw_resume() for the case where the current register frame is split
|
||||
across multiple backing stores
|
||||
+ document restricions on using unw_resume():
|
||||
+ implement remote cases of unw_resume()
|
||||
+ test both with UNW_LOCAL_ONLY and without where this makes sense
|
||||
+ allow region-length (insn_count) in unw_dyn_region_info_t to be negative
|
||||
to indicate counting from the end of the procedure (to make it possible
|
||||
for differently-sized procedures to share the same region list if they
|
||||
share the same prologue/epilogue).
|
||||
+ it appears that it is currently not possible to read register UNW_IA64_TP;
|
||||
fix that => no, attempts to access r13 will result in access_reg() callbacks,
|
||||
as desired; for local-case, access to r13 will fail though (since
|
||||
getcontext() doesn't, and shouldn't, capture r13)
|
||||
+ document the special nature of UNW_IA64_GP: read-only, but adjusted
|
||||
automatically if the IP is changed
|
||||
+ use pthread-mutexes where necessary, atomic ops where possible
|
||||
+ man-page for unw_init_local()
|
||||
+ man-page for unw_init_remote()
|
||||
+ man-page for unw_create_addr_space()
|
||||
+ man-page for unw_destroy_addr_space()
|
||||
+ man-page for unw_get_proc_info()
|
||||
+ man-page for unw_get_proc_name()
|
||||
+ man-page for unw_get_accessors()
|
||||
+ man-page for unw_regname()
|
||||
+ man-page for unw_flush_cache()
|
||||
+ man-page for unw_set_caching_policy()
|
||||
+ man-page for unw_getcontext()
|
||||
+ man-page for unw_is_signal_frame()
|
||||
+ man-page for unw_step()
|
||||
+ man-page for unw_get_reg()
|
||||
+ man-page for unw_set_reg()
|
||||
+ man-page for unw_get_fpreg()
|
||||
+ man-page for unw_set_fpreg()
|
||||
+ test with Intel compiler
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,57 @@
|
|||
AC_DEFUN([LIBUNWIND___THREAD],
|
||||
[dnl Check whether the compiler supports the __thread keyword.
|
||||
if test "x$enable___thread" != xno; then
|
||||
AC_CACHE_CHECK([for __thread], libc_cv_gcc___thread,
|
||||
[cat > conftest.c <<\EOF
|
||||
__thread int a = 42;
|
||||
EOF
|
||||
if AC_TRY_COMMAND([${CC-cc} $CFLAGS -c conftest.c >&AS_MESSAGE_LOG_FD]); then
|
||||
libc_cv_gcc___thread=yes
|
||||
else
|
||||
libc_cv_gcc___thread=no
|
||||
fi
|
||||
rm -f conftest*])
|
||||
if test "$libc_cv_gcc___thread" = yes; then
|
||||
AC_DEFINE(HAVE___THREAD, 1,
|
||||
[Define to 1 if __thread keyword is supported by the C compiler.])
|
||||
fi
|
||||
else
|
||||
libc_cv_gcc___thread=no
|
||||
fi])
|
||||
|
||||
AC_DEFUN([CHECK_ATOMIC_OPS],
|
||||
[dnl Check whether the system has the atomic_ops package installed.
|
||||
AC_CHECK_HEADERS(atomic_ops.h)
|
||||
#
|
||||
# Don't link against libatomic_ops for now. We don't want libunwind
|
||||
# to depend on libatomic_ops.so. Fortunately, none of the platforms
|
||||
# we care about so far need libatomic_ops.a (everything is done via
|
||||
# inline macros).
|
||||
#
|
||||
# AC_CHECK_LIB(atomic_ops, main)
|
||||
])
|
||||
|
||||
# ANDROID support update.
|
||||
AC_DEFUN([CHECK_ANDROID],
|
||||
[dnl Check whether the system has __ANDROID__ defined.
|
||||
if test "x$enable_conserve_stack" != xno; then
|
||||
AC_CACHE_CHECK([for __ANDROID__], ac_cv_android,
|
||||
[cat > conftest.c <<\EOF
|
||||
#if !defined(__ANDROID__)
|
||||
value = fail
|
||||
#endif
|
||||
EOF
|
||||
if AC_TRY_COMMAND([${CC-cc} $CFLAGS -c conftest.c >&AS_MESSAGE_LOG_FD]); then
|
||||
ac_cv_android=yes
|
||||
else
|
||||
ac_cv_android=no
|
||||
fi
|
||||
rm -f conftest*])
|
||||
if test "$ac_cv_android" = yes; then
|
||||
AC_DEFINE([CONSERVE_STACK], [],
|
||||
[Allocate large structures rather than place them on the stack.])
|
||||
fi
|
||||
else
|
||||
ac_cv_android=no
|
||||
fi])
|
||||
# End of ANDROID update.
|
|
@ -0,0 +1,26 @@
|
|||
This version of libunwind based on libunwind 1.1.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
To configure a libunwind install for arm:
|
||||
|
||||
source build/envsetup.sh
|
||||
lunch aosp_arm-eng
|
||||
make -jXX
|
||||
cd external/libuwnind
|
||||
android/conf_arm.sh
|
||||
|
||||
To configure a libunwind install for mips:
|
||||
|
||||
source build/envsetup.sh
|
||||
lunch aosp_mips-eng
|
||||
make -jXX
|
||||
cd external/libuwnind
|
||||
android/conf_mips.sh
|
||||
|
||||
To configure a libunwind install for x86:
|
||||
|
||||
source build/envsetup.sh
|
||||
lunch aosp_x86-eng
|
||||
make -jXX
|
||||
cd external/libuwnind
|
||||
android/conf_x86.sh
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ "$OUT" == "" ]]; then
|
||||
echo "In order for this script to function, please choose an arm target"
|
||||
echo "using source build/envsetup.sh and lunch XXX\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
arm_cc="${ANDROID_TOOLCHAIN}/arm-linux-androideabi-gcc"
|
||||
arm_cpp="${ANDROID_TOOLCHAIN}/arm-linux-androideabi-g++"
|
||||
|
||||
includes=(
|
||||
"-isystem ${ANDROID_BUILD_TOP}/system/core/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/hardware/libhardware/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/hardware/libhardware_legacy/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/hardware/ril/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/libnativehelper/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/native/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/native/opengl/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/av/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/base/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/external/skia/include"
|
||||
"-isystem ${OUT}/obj/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/arch-arm/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libstdc++/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/kernel/uapi"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/kernel/uapi/asm-arm"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libm/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libm/include/arm"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libthread_db/include"
|
||||
"-include ${ANDROID_BUILD_TOP}/build/core/combo/include/arch/linux-arm/AndroidConfig.h"
|
||||
"-I ${ANDROID_BUILD_TOP}/build/core/combo/include/arch/linux-arm/"
|
||||
)
|
||||
|
||||
ldflags=(
|
||||
"-nostdlib"
|
||||
"-Bdynamic"
|
||||
"-fPIE"
|
||||
"-pie"
|
||||
"-Wl,-dynamic-linker,/system/bin/linker"
|
||||
"-Wl,--gc-sections"
|
||||
"-Wl,-z,nocopyreloc"
|
||||
"-L${OUT}/obj/lib"
|
||||
"-Wl,-rpath-link=${OUT}/obj/lib"
|
||||
"-Wl,--whole-archive"
|
||||
"-Wl,--no-whole-archive"
|
||||
"-lc"
|
||||
"-lstdc++"
|
||||
"-lm"
|
||||
"-Wl,-z,noexecstack"
|
||||
"-Wl,-z,relro"
|
||||
"-Wl,-z,now"
|
||||
"-Wl,--warn-shared-textrel"
|
||||
"-Wl,--fatal-warnings"
|
||||
"-Wl,--icf=safe"
|
||||
"-Wl,--no-undefined"
|
||||
"-ldl"
|
||||
)
|
||||
|
||||
eval ./configure CC=\"${arm_cc} ${includes[@]}\" \
|
||||
CPP=\"${arm_cc} ${includes[@]} -E\" \
|
||||
CXX=\"${arm_cpp} ${includes[@]}\" \
|
||||
CXXCPP=\"${arm_cpp} ${includes[@]} -E\" \
|
||||
LDFLAGS=\"${ldflags[@]}\" \
|
||||
--host=arm
|
|
@ -0,0 +1,63 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ "$OUT" == "" ]]; then
|
||||
echo "In order for this script to function, please choose an arm target"
|
||||
echo "using source build/envsetup.sh and lunch XXX\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cc="${ANDROID_TOOLCHAIN}/mipsel-linux-android-gcc"
|
||||
cpp="${ANDROID_TOOLCHAIN}/mipsel-linux-android-g++"
|
||||
|
||||
includes=(
|
||||
"-isystem ${ANDROID_BUILD_TOP}/system/core/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/hardware/libhardware/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/hardware/libhardware_legacy/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/hardware/ril/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/libnativehelper/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/native/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/native/opengl/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/av/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/base/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/external/skia/include"
|
||||
"-isystem ${OUT}/obj/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/arch-mips/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libstdc++/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/kernel/uapi"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/kernel/uapi/asm-mips"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libm/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libm/include/mips"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libthread_db/include"
|
||||
)
|
||||
|
||||
ldflags=(
|
||||
"-nostdlib"
|
||||
"-Bdynamic"
|
||||
"-fPIE"
|
||||
"-pie"
|
||||
"-Wl,-dynamic-linker,/system/bin/linker"
|
||||
"-Wl,--gc-sections"
|
||||
"-Wl,-z,nocopyreloc"
|
||||
"-L${OUT}/obj/lib"
|
||||
"-Wl,-rpath-link=${OUT}/obj/lib"
|
||||
"-Wl,--whole-archive"
|
||||
"-Wl,--no-whole-archive"
|
||||
"-lc"
|
||||
"-lstdc++"
|
||||
"-lm"
|
||||
"-Wl,-z,noexecstack"
|
||||
"-Wl,-z,relro"
|
||||
"-Wl,-z,now"
|
||||
"-Wl,--warn-shared-textrel"
|
||||
"-EL"
|
||||
"-Wl,--no-undefined"
|
||||
"-ldl"
|
||||
)
|
||||
|
||||
eval ./configure CC=\"${cc} ${includes[@]}\" \
|
||||
CPP=\"${cc} ${includes[@]} -E\" \
|
||||
CXX=\"${cpp} ${includes[@]}\" \
|
||||
CXXCPP=\"${cpp} ${includes[@]} -E\" \
|
||||
LDFLAGS=\"${ldflags[@]}\" \
|
||||
--host=mips
|
|
@ -0,0 +1,63 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ "$OUT" == "" ]]; then
|
||||
echo "In order for this script to function, please choose an arm target"
|
||||
echo "using source build/envsetup.sh and lunch XXX\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cc="${ANDROID_TOOLCHAIN}/i686-linux-android-gcc"
|
||||
cpp="${ANDROID_TOOLCHAIN}/i686-linux-android-g++"
|
||||
|
||||
includes=(
|
||||
"-isystem ${ANDROID_BUILD_TOP}/system/core/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/hardware/libhardware/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/hardware/libhardware_legacy/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/hardware/ril/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/libnativehelper/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/native/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/native/opengl/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/av/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/frameworks/base/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/external/skia/include"
|
||||
"-isystem ${OUT}/obj/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/arch-x86/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libstdc++/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/kernel/uapi"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libc/kernel/uapi/asm-x86"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libm/include"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libm/include/i387"
|
||||
"-isystem ${ANDROID_BUILD_TOP}/bionic/libthread_db/include"
|
||||
)
|
||||
|
||||
ldflags=(
|
||||
"-m32"
|
||||
"-Wl,-z,noexecstack"
|
||||
"-Wl,-z,relro"
|
||||
"-Wl,-z,now"
|
||||
"-Wl,--warn-shared-textrel"
|
||||
"-Wl,--gc-sections"
|
||||
"-nostdlib"
|
||||
"-Bdynamic"
|
||||
"-Wl,-dynamic-linker,/system/bin/linker"
|
||||
"-Wl,-z,nocopyreloc"
|
||||
"-fPIE"
|
||||
"-pie"
|
||||
"-L${OUT}/obj/lib"
|
||||
"-Wl,-rpath-link=${OUT}/obj/lib"
|
||||
"-Wl,--whole-archive"
|
||||
"-Wl,--no-whole-archive"
|
||||
"-lc"
|
||||
"-lstdc++"
|
||||
"-lm"
|
||||
"-Wl,--no-undefined"
|
||||
"-ldl"
|
||||
)
|
||||
|
||||
eval ./configure CC=\"${cc} ${includes[@]}\" \
|
||||
CPP=\"${cc} ${includes[@]} -E\" \
|
||||
CXX=\"${cpp} ${includes[@]}\" \
|
||||
CXXCPP=\"${cpp} ${includes[@]} -E\" \
|
||||
LDFLAGS=\"${ldflags[@]}\" \
|
||||
--host=i386
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
|
||||
#define EXTRA_CONTEXT_BYTES 1024
|
||||
|
||||
TEST(libbacktrace, getcontext_size) {
|
||||
unw_context_t* context;
|
||||
context = reinterpret_cast<unw_context_t*>(malloc(sizeof(unw_context_t) + EXTRA_CONTEXT_BYTES));
|
||||
ASSERT_TRUE(context != NULL);
|
||||
uint8_t* extra = reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(context) + sizeof(unw_context_t));
|
||||
for (size_t i = 0; i < EXTRA_CONTEXT_BYTES; i++) {
|
||||
extra[i] = (i % 255) + 1;
|
||||
}
|
||||
ASSERT_TRUE(unw_getcontext(context) == 0);
|
||||
/* Check that nothing was written past the end of the structure. */
|
||||
for (size_t i = 0; i < EXTRA_CONTEXT_BYTES; i++) {
|
||||
ASSERT_EQ((i % 255) + 1, extra[i]);
|
||||
}
|
||||
|
||||
free(context);
|
||||
}
|
|
@ -0,0 +1,390 @@
|
|||
define(pkg_major, 1)
|
||||
define(pkg_minor, 1)
|
||||
define(pkg_extra, )
|
||||
define(pkg_maintainer, libunwind-devel@nongnu.org)
|
||||
define(mkvers, $1.$2$3)
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT([libunwind],[mkvers(pkg_major, pkg_minor, pkg_extra)],[pkg_maintainer])
|
||||
AC_CONFIG_SRCDIR(src/mi/backtrace.c)
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
AC_CANONICAL_TARGET
|
||||
AM_INIT_AUTOMAKE([1.6 subdir-objects])
|
||||
AM_MAINTAINER_MODE
|
||||
AC_CONFIG_HEADERS([include/config.h])
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_MAKE_SET
|
||||
LT_INIT
|
||||
AM_PROG_AS
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
dnl Checks for libraries.
|
||||
AC_CHECK_LIB(uca, __uc_get_grs)
|
||||
OLD_LIBS=${LIBS}
|
||||
AC_SEARCH_LIBS(dlopen, dl)
|
||||
LIBS=${OLD_LIBS}
|
||||
case "$ac_cv_search_dlopen" in
|
||||
-l*) DLLIB=$ac_cv_search_dlopen;;
|
||||
*) DLLIB="";;
|
||||
esac
|
||||
|
||||
CHECK_ATOMIC_OPS
|
||||
|
||||
# ANDROID support update.
|
||||
CHECK_ANDROID
|
||||
# End of ANDROID update.
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(asm/ptrace_offsets.h endian.h sys/endian.h execinfo.h \
|
||||
ia64intrin.h sys/uc_access.h unistd.h signal.h sys/types.h \
|
||||
sys/procfs.h sys/ptrace.h byteswap.h elf.h sys/elf.h link.h sys/link.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_TYPE_SIZE_T
|
||||
AC_CHECK_SIZEOF(off_t)
|
||||
|
||||
CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE"
|
||||
|
||||
AC_CHECK_MEMBERS([struct dl_phdr_info.dlpi_subs],,,[#include <link.h>])
|
||||
AC_CHECK_TYPES([struct elf_prstatus, struct prstatus], [], [],
|
||||
[$ac_includes_default
|
||||
#if HAVE_SYS_PROCFS_H
|
||||
# include <sys/procfs.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_CHECK_DECLS([PTRACE_POKEUSER, PTRACE_POKEDATA,
|
||||
PTRACE_TRACEME, PTRACE_CONT, PTRACE_SINGLESTEP,
|
||||
PTRACE_SYSCALL, PT_IO, PT_GETREGS,
|
||||
PT_GETFPREGS, PT_CONTINUE, PT_TRACE_ME,
|
||||
PT_STEP, PT_SYSCALL], [], [],
|
||||
[$ac_includes_default
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/ptrace.h>
|
||||
])
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS(dl_iterate_phdr dl_phdr_removals_counter dlmodinfo getunwind \
|
||||
ttrace mincore)
|
||||
|
||||
AC_MSG_CHECKING([if building with AltiVec])
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#ifndef __ALTIVEC__
|
||||
# error choke
|
||||
#endif
|
||||
]])], [use_altivec=yes],[use_altivec=no])
|
||||
AM_CONDITIONAL(USE_ALTIVEC, [test x$use_altivec = xyes])
|
||||
AC_MSG_RESULT([$use_altivec])
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#ifndef __powerpc64__
|
||||
# error choke
|
||||
#endif
|
||||
]])], [ppc_bits=64], [ppc_bits=32])
|
||||
|
||||
AC_DEFUN([SET_ARCH],[
|
||||
AS_CASE([$1],
|
||||
[arm*],[$2=arm],
|
||||
[i?86],[$2=x86],
|
||||
[hppa*],[$2=hppa],
|
||||
[mips*],[$2=mips],
|
||||
[powerpc*],[$2=ppc$ppc_bits],
|
||||
[sh*],[$2=sh],
|
||||
[amd64],[$2=x86_64],
|
||||
[$2=$1])
|
||||
]) dnl SET_ARCH
|
||||
|
||||
SET_ARCH([$build_cpu],[build_arch])
|
||||
SET_ARCH([$host_cpu],[host_arch])
|
||||
SET_ARCH([$target_cpu],[target_arch])
|
||||
|
||||
AC_ARG_ENABLE(coredump,
|
||||
AS_HELP_STRING([--enable-coredump],[building libunwind-coredump library]),,
|
||||
[AS_CASE([$host_arch], [aarch64*|arm*|mips*|sh*|x86*], [enable_coredump=yes], [enable_coredump=no])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([if we should build libunwind-coredump])
|
||||
AC_MSG_RESULT([$enable_coredump])
|
||||
|
||||
AC_ARG_ENABLE(ptrace,
|
||||
AS_HELP_STRING([--enable-ptrace],[building libunwind-ptrace library]),,
|
||||
[AC_CHECK_HEADER([sys/ptrace.h], [enable_ptrace=yes], [enable_ptrace=no])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([if we should build libunwind-ptrace])
|
||||
AC_MSG_RESULT([$enable_ptrace])
|
||||
|
||||
AC_ARG_ENABLE(setjmp,
|
||||
AS_HELP_STRING([--enable-setjmp],[building libunwind-setjmp library]),,
|
||||
[AS_IF([test x$target_arch == x$host_arch], [enable_setjmp=yes], [enable_setjmp=no])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([if we should build libunwind-setjmp])
|
||||
AC_MSG_RESULT([$enable_setjmp])
|
||||
|
||||
AC_MSG_CHECKING([for build architecture])
|
||||
AC_MSG_RESULT([$build_arch])
|
||||
AC_MSG_CHECKING([for host architecture])
|
||||
AC_MSG_RESULT([$host_arch])
|
||||
AC_MSG_CHECKING([for target architecture])
|
||||
AC_MSG_RESULT([$target_arch])
|
||||
AC_MSG_CHECKING([for target operating system])
|
||||
AC_MSG_RESULT([$target_os])
|
||||
|
||||
AM_CONDITIONAL(BUILD_COREDUMP, test x$enable_coredump = xyes)
|
||||
AM_CONDITIONAL(BUILD_PTRACE, test x$enable_ptrace = xyes)
|
||||
AM_CONDITIONAL(BUILD_SETJMP, test x$enable_setjmp = xyes)
|
||||
AM_CONDITIONAL(REMOTE_ONLY, test x$target_arch != x$host_arch)
|
||||
AM_CONDITIONAL(ARCH_AARCH64, test x$target_arch = xaarch64)
|
||||
AM_CONDITIONAL(ARCH_ARM, test x$target_arch = xarm)
|
||||
AM_CONDITIONAL(ARCH_IA64, test x$target_arch = xia64)
|
||||
AM_CONDITIONAL(ARCH_HPPA, test x$target_arch = xhppa)
|
||||
AM_CONDITIONAL(ARCH_MIPS, test x$target_arch = xmips)
|
||||
AM_CONDITIONAL(ARCH_X86, test x$target_arch = xx86)
|
||||
AM_CONDITIONAL(ARCH_X86_64, test x$target_arch = xx86_64)
|
||||
AM_CONDITIONAL(ARCH_PPC32, test x$target_arch = xppc32)
|
||||
AM_CONDITIONAL(ARCH_PPC64, test x$target_arch = xppc64)
|
||||
AM_CONDITIONAL(ARCH_SH, test x$target_arch = xsh)
|
||||
AM_CONDITIONAL(OS_LINUX, expr x$target_os : xlinux >/dev/null)
|
||||
AM_CONDITIONAL(OS_HPUX, expr x$target_os : xhpux >/dev/null)
|
||||
AM_CONDITIONAL(OS_FREEBSD, expr x$target_os : xfreebsd >/dev/null)
|
||||
AM_CONDITIONAL(OS_QNX, expr x$target_os : xnto-qnx >/dev/null)
|
||||
|
||||
AC_MSG_CHECKING([for ELF helper width])
|
||||
case "${target_arch}" in
|
||||
(arm|hppa|ppc32|x86|sh) use_elf32=yes; AC_MSG_RESULT([32]);;
|
||||
(aarch64|ia64|ppc64|x86_64) use_elf64=yes; AC_MSG_RESULT([64]);;
|
||||
(mips) use_elfxx=yes; AC_MSG_RESULT([xx]);;
|
||||
*) AC_MSG_ERROR([Unknown ELF target: ${target_arch}])
|
||||
esac
|
||||
AM_CONDITIONAL(USE_ELF32, [test x$use_elf32 = xyes])
|
||||
AM_CONDITIONAL(USE_ELF64, [test x$use_elf64 = xyes])
|
||||
AM_CONDITIONAL(USE_ELFXX, [test x$use_elfxx = xyes])
|
||||
|
||||
AC_MSG_CHECKING([whether to include DWARF support])
|
||||
if test x$target_arch != xia64; then
|
||||
use_dwarf=yes
|
||||
else
|
||||
use_dwarf=no
|
||||
fi
|
||||
AM_CONDITIONAL(USE_DWARF, [test x$use_dwarf = xyes])
|
||||
AC_MSG_RESULT([$use_dwarf])
|
||||
|
||||
if test x$target_arch = xppc64; then
|
||||
libdir='${exec_prefix}/lib64'
|
||||
AC_MSG_NOTICE([PowerPC64 detected, lib will be installed ${libdir}]);
|
||||
AC_SUBST([libdir])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether to restrict build to remote support])
|
||||
if test x$target_arch != x$host_arch; then
|
||||
CPPFLAGS="${CPPFLAGS} -DUNW_REMOTE_ONLY"
|
||||
remote_only=yes
|
||||
else
|
||||
remote_only=no
|
||||
fi
|
||||
AC_MSG_RESULT([$remote_only])
|
||||
|
||||
AC_MSG_CHECKING([whether to enable debug support])
|
||||
AC_ARG_ENABLE(debug,
|
||||
AS_HELP_STRING([--enable-debug],[turn on debug support (slows down execution)]))
|
||||
if test x$enable_debug = xyes; then
|
||||
CPPFLAGS="${CPPFLAGS} -DDEBUG"
|
||||
else
|
||||
CPPFLAGS="${CPPFLAGS} -DNDEBUG"
|
||||
fi
|
||||
AC_MSG_RESULT([$enable_debug])
|
||||
|
||||
AC_MSG_CHECKING([whether to enable C++ exception support])
|
||||
AC_ARG_ENABLE(cxx_exceptions,
|
||||
AS_HELP_STRING([--enable-cxx-exceptions],[use libunwind to handle C++ exceptions]),,
|
||||
[
|
||||
# C++ exception handling doesn't work too well on x86
|
||||
case $target_arch in
|
||||
x86*) enable_cxx_exceptions=no;;
|
||||
aarch64*) enable_cxx_exceptions=no;;
|
||||
arm*) enable_cxx_exceptions=no;;
|
||||
mips*) enable_cxx_exceptions=no;;
|
||||
*) enable_cxx_exceptions=yes;;
|
||||
esac
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([SUPPORT_CXX_EXCEPTIONS], [test x$enable_cxx_exceptions = xyes])
|
||||
AC_MSG_RESULT([$enable_cxx_exceptions])
|
||||
|
||||
AC_MSG_CHECKING([whether to load .debug_frame sections])
|
||||
AC_ARG_ENABLE(debug_frame,
|
||||
AS_HELP_STRING([--enable-debug-frame],[Load the ".debug_frame" section if available]),, [
|
||||
case "${target_arch}" in
|
||||
(arm) enable_debug_frame=yes;;
|
||||
(*) enable_debug_frame=no;;
|
||||
esac])
|
||||
if test x$enable_debug_frame = xyes; then
|
||||
AC_DEFINE([CONFIG_DEBUG_FRAME], [], [Enable Debug Frame])
|
||||
fi
|
||||
AC_MSG_RESULT([$enable_debug_frame])
|
||||
|
||||
AC_MSG_CHECKING([whether to block signals during mutex ops])
|
||||
AC_ARG_ENABLE(block_signals,
|
||||
AS_HELP_STRING([--enable-block-signals],[Block signals before performing mutex operations]),,
|
||||
[enable_block_signals=yes])
|
||||
if test x$enable_block_signals = xyes; then
|
||||
AC_DEFINE([CONFIG_BLOCK_SIGNALS], [], [Block signals before mutex operations])
|
||||
fi
|
||||
AC_MSG_RESULT([$enable_block_signals])
|
||||
|
||||
AC_MSG_CHECKING([whether to validate memory addresses before use])
|
||||
AC_ARG_ENABLE(conservative_checks,
|
||||
AS_HELP_STRING([--enable-conservative-checks],[Validate all memory addresses before use]),,
|
||||
[enable_conservative_checks=yes])
|
||||
if test x$enable_conservative_checks = xyes; then
|
||||
AC_DEFINE(CONSERVATIVE_CHECKS, 1,
|
||||
[Define to 1 if you want every memory access validated])
|
||||
fi
|
||||
AC_MSG_RESULT([$enable_conservative_checks])
|
||||
|
||||
AC_MSG_CHECKING([whether to enable msabi support])
|
||||
AC_ARG_ENABLE(msabi_support,
|
||||
AS_HELP_STRING([--enable-msabi-support],[Enables support for Microsoft ABI extensions]))
|
||||
if test x$enable_msabi_support = xyes; then
|
||||
AC_DEFINE([CONFIG_MSABI_SUPPORT], [], [Support for Microsoft ABI extensions])
|
||||
fi
|
||||
AC_MSG_RESULT([$enable_msabi_support])
|
||||
|
||||
LIBLZMA=
|
||||
AC_MSG_CHECKING([whether to support LZMA-compressed symbol tables])
|
||||
AC_ARG_ENABLE(minidebuginfo,
|
||||
AS_HELP_STRING([--enable-minidebuginfo], [Enables support for LZMA-compressed symbol tables]),, [enable_minidebuginfo=auto])
|
||||
AC_MSG_RESULT([$enable_minidebuginfo])
|
||||
if test x$enable_minidebuginfo != xno; then
|
||||
AC_CHECK_LIB([lzma], [lzma_mf_is_supported],
|
||||
[LIBLZMA=-llzma
|
||||
AC_DEFINE([HAVE_LZMA], [1], [Define if you have liblzma])
|
||||
enable_minidebuginfo=yes],
|
||||
[if test x$enable_minidebuginfo = xyes; then
|
||||
AC_MSG_FAILURE([liblzma not found])
|
||||
fi])
|
||||
fi
|
||||
AC_SUBST([LIBLZMA])
|
||||
AM_CONDITIONAL(HAVE_LZMA, test x$enable_minidebuginfo = xyes)
|
||||
|
||||
LIBUNWIND___THREAD
|
||||
|
||||
AC_MSG_CHECKING([for Intel compiler])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[#ifndef __INTEL_COMPILER
|
||||
#error choke me
|
||||
#endif]])],[intel_compiler=yes],[intel_compiler=no])
|
||||
|
||||
if test x$GCC = xyes -a x$intel_compiler != xyes; then
|
||||
CFLAGS="${CFLAGS} -fexceptions -Wall -Wsign-compare"
|
||||
fi
|
||||
AC_MSG_RESULT([$intel_compiler])
|
||||
|
||||
AC_MSG_CHECKING([for QCC compiler])
|
||||
AS_CASE([$CC], [qcc*|QCC*], [qcc_compiler=yes], [qcc_compiler=no])
|
||||
AC_MSG_RESULT([$qcc_compiler])
|
||||
|
||||
if test x$intel_compiler = xyes; then
|
||||
AC_MSG_CHECKING([if linker supports -static-libcxa])
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -static-libcxa"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[have_static_libcxa=yes],[have_static_libcxa=no])
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
if test "x$have_static_libcxa" = xyes; then
|
||||
LDFLAGS_STATIC_LIBCXA="-XCClinker -static-libcxa"
|
||||
fi
|
||||
AC_MSG_RESULT([$have_static_libcxa])
|
||||
fi
|
||||
|
||||
if test x$qcc_compiler = xyes; then
|
||||
LDFLAGS_NOSTARTFILES="-XCClinker -Wc,-nostartfiles"
|
||||
else
|
||||
LDFLAGS_NOSTARTFILES="-XCClinker -nostartfiles"
|
||||
fi
|
||||
|
||||
if test x$GCC = xyes -a x$intel_compiler != xyes -a x$qcc_compiler != xyes; then
|
||||
LIBCRTS="-lgcc"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for __builtin___clear_cache])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]], [[__builtin___clear_cache(0, 0)]])],
|
||||
[have__builtin___clear_cache=yes],
|
||||
[have__builtin___clear_cache=no])
|
||||
if test x$have__builtin___clear_cache = xyes; then
|
||||
AC_DEFINE([HAVE__BUILTIN___CLEAR_CACHE], [1],
|
||||
[Defined if __builtin___clear_cache() is available])
|
||||
fi
|
||||
AC_MSG_RESULT([$have__builtin___clear_cache])
|
||||
|
||||
AC_MSG_CHECKING([for __builtin_unreachable])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]], [[__builtin_unreachable()]])],
|
||||
[have__builtin_unreachable=yes],
|
||||
[have__builtin_unreachable=no])
|
||||
if test x$have__builtin_unreachable = xyes; then
|
||||
AC_DEFINE([HAVE__BUILTIN_UNREACHABLE], [1],
|
||||
[Defined if __builtin_unreachable() is available])
|
||||
fi
|
||||
AC_MSG_RESULT([$have__builtin_unreachable])
|
||||
|
||||
AC_MSG_CHECKING([for __sync atomics])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]], [[
|
||||
__sync_bool_compare_and_swap((int *)0, 0, 1);
|
||||
__sync_fetch_and_add((int *)0, 1);
|
||||
]])],
|
||||
[have_sync_atomics=yes],
|
||||
[have_sync_atomics=no])
|
||||
if test x$have_sync_atomics = xyes; then
|
||||
AC_DEFINE([HAVE_SYNC_ATOMICS], [1],
|
||||
[Defined if __sync atomics are available])
|
||||
fi
|
||||
AC_MSG_RESULT([$have_sync_atomics])
|
||||
|
||||
CCASFLAGS="${CCASFLAGS} ${CPPFLAGS}"
|
||||
|
||||
arch="$target_arch"
|
||||
ARCH=`echo $target_arch | tr [a-z] [A-Z]`
|
||||
|
||||
dnl create shell variables from the M4 macros:
|
||||
PKG_MAJOR=pkg_major
|
||||
PKG_MINOR=pkg_minor
|
||||
PKG_EXTRA=pkg_extra
|
||||
PKG_MAINTAINER=pkg_maintainer
|
||||
|
||||
old_LIBS="$LIBS"
|
||||
LIBS=""
|
||||
AC_SEARCH_LIBS(backtrace, execinfo)
|
||||
LIBS="$old_LIBS"
|
||||
|
||||
AC_SUBST(build_arch)
|
||||
AC_SUBST(target_os)
|
||||
AC_SUBST(arch)
|
||||
AC_SUBST(ARCH)
|
||||
AC_SUBST(LDFLAGS_STATIC_LIBCXA)
|
||||
AC_SUBST(LDFLAGS_NOSTARTFILES)
|
||||
AC_SUBST(LIBCRTS)
|
||||
AC_SUBST(PKG_MAJOR)
|
||||
AC_SUBST(PKG_MINOR)
|
||||
AC_SUBST(PKG_EXTRA)
|
||||
AC_SUBST(PKG_MAINTAINER)
|
||||
AC_SUBST(enable_cxx_exceptions)
|
||||
AC_SUBST(enable_debug_frame)
|
||||
AC_SUBST(DLLIB)
|
||||
|
||||
AC_CONFIG_FILES(Makefile src/Makefile tests/Makefile tests/check-namespace.sh
|
||||
doc/Makefile doc/common.tex include/libunwind-common.h
|
||||
include/libunwind.h include/tdep/libunwind_i.h)
|
||||
AC_CONFIG_FILES(src/unwind/libunwind.pc src/coredump/libunwind-coredump.pc
|
||||
src/ptrace/libunwind-ptrace.pc src/setjmp/libunwind-setjmp.pc
|
||||
src/libunwind-generic.pc)
|
||||
AC_OUTPUT
|
|
@ -0,0 +1,73 @@
|
|||
# man pages that go into section 3:
|
||||
man3_MANS = libunwind.man libunwind-dynamic.man libunwind-ia64.man \
|
||||
libunwind-ptrace.man libunwind-setjmp.man \
|
||||
unw_backtrace.man \
|
||||
unw_flush_cache.man \
|
||||
unw_get_accessors.man \
|
||||
unw_get_proc_info.man \
|
||||
unw_get_proc_info_by_ip.man \
|
||||
unw_get_proc_name.man \
|
||||
unw_get_fpreg.man \
|
||||
unw_get_reg.man \
|
||||
unw_getcontext.man \
|
||||
unw_init_local.man unw_init_remote.man \
|
||||
unw_is_fpreg.man \
|
||||
unw_is_signal_frame.man \
|
||||
unw_create_addr_space.man \
|
||||
unw_destroy_addr_space.man \
|
||||
unw_regname.man unw_resume.man \
|
||||
unw_set_caching_policy.man \
|
||||
unw_set_fpreg.man \
|
||||
unw_set_reg.man \
|
||||
unw_step.man \
|
||||
unw_strerror.man \
|
||||
_U_dyn_register.man \
|
||||
_U_dyn_cancel.man
|
||||
|
||||
EXTRA_DIST = NOTES libunwind.trans \
|
||||
libunwind.tex libunwind-dynamic.tex libunwind-ia64.tex \
|
||||
libunwind-ptrace.tex libunwind-setjmp.tex \
|
||||
unw_backtrace.tex \
|
||||
unw_flush_cache.tex \
|
||||
unw_get_accessors.tex \
|
||||
unw_get_proc_info.tex \
|
||||
unw_get_proc_info_by_ip.tex \
|
||||
unw_get_proc_name.tex \
|
||||
unw_get_fpreg.tex \
|
||||
unw_get_reg.tex \
|
||||
unw_getcontext.tex \
|
||||
unw_init_local.tex unw_init_remote.tex \
|
||||
unw_is_fpreg.tex \
|
||||
unw_is_signal_frame.tex \
|
||||
unw_create_addr_space.tex unw_destroy_addr_space.tex \
|
||||
unw_regname.tex unw_resume.tex unw_set_caching_policy.tex \
|
||||
unw_set_fpreg.tex \
|
||||
unw_set_reg.tex \
|
||||
unw_step.tex \
|
||||
unw_strerror.tex \
|
||||
_U_dyn_register.tex \
|
||||
_U_dyn_cancel.tex \
|
||||
$(man3_MANS)
|
||||
|
||||
L2M = latex2man
|
||||
L2P = pdflatex
|
||||
L2M_CMD = $(L2M) -t $(srcdir)/libunwind.trans
|
||||
L2H_CMD = $(L2M) -H -t $(srcdir)/libunwind.trans
|
||||
|
||||
.tex.man:
|
||||
$(L2M_CMD) $< $@
|
||||
-cp $@ $(srcdir)/$@
|
||||
|
||||
html:
|
||||
for n in $(man3_MANS); do \
|
||||
page=`basename $$n .man`; \
|
||||
$(L2H_CMD) $(srcdir)/$$page.tex "$$page(3).raw"; \
|
||||
done
|
||||
|
||||
pdf:
|
||||
for n in $(man3_MANS); do \
|
||||
page=`basename $$n .man`; \
|
||||
$(L2P) $(srcdir)/$$page.tex "$$page(3).pdf"; \
|
||||
done
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
|
@ -0,0 +1,127 @@
|
|||
The central data structure of the unwind API is the unwind cursor.
|
||||
This structure tracks the register contents. The unwind API defines a
|
||||
handful of well-known frame "registers":
|
||||
|
||||
- ip: the instruction pointer (pc)
|
||||
- rp: the return pointer (rp, aka "return address" or "return link")
|
||||
- sp: the stack pointer (memory stack pointer, in the case of ia64)
|
||||
- fp: the frame pointer
|
||||
- first_ip: the starting address of the current "procedure"
|
||||
- handler: a pointer to an architecture & language-specific
|
||||
"personality" routine
|
||||
- lsda: a pointer to an architecture & language-specific
|
||||
data-area
|
||||
|
||||
The API defines no well-known preserved registers. Each architecture
|
||||
can define additional registers as needed. Of course, a portable
|
||||
application may only rely on well-known registers. The names for
|
||||
preserved registers are defined in the architecture-specific header
|
||||
file <unwind-ARCH.h>. For example, to get the IA-64-specific register
|
||||
names, an application would do:
|
||||
|
||||
#include <unwind-ia64.h>
|
||||
|
||||
The API is designed to handle two primary cases: unwinding within the
|
||||
current (local) process and unwinding of another ("remote") process
|
||||
(e.g., through ptrace()). In the local case, the initial machine
|
||||
state is captured by an unwind context (currently the same as
|
||||
ucontext_t). In the remote case, the initial machine state is
|
||||
captured by an unwind accessor structure, which provides callback
|
||||
routines for reading/writing memory and registers and for obtaining
|
||||
unwind information.
|
||||
|
||||
Once a cursor has been initialized, you can step through the call
|
||||
chain with the unw_step() routine. The frame registers and the
|
||||
preserved state can then be accessed with unw_get_reg() or modified
|
||||
with unw_set_reg(). For floating-point registers, there are separate
|
||||
unw_get_fpreg() and unw_set_fpreg() routines (on some arches, e.g.,
|
||||
Alpha, these could be just aliases for unw_{g,s}et_reg()). The
|
||||
unw_resume() routine can be used to resume execution at an arbitrary
|
||||
point in the call-chain (as identified by an unwind cursor). This is
|
||||
intended for exception handling and, at least for now, the intention
|
||||
is to support this routine only for the local case. Kevin, if you
|
||||
feel gdb could benefit from such a routine, I'd be interested to hear
|
||||
about it.
|
||||
|
||||
Note that it is perfectly legal to make copies of the unwind cursor.
|
||||
This makes it possible, e.g., to obtain an unwind context, modify the
|
||||
state in an earlier call frame, and then resume execution at the point
|
||||
at which the unwind context was captured.
|
||||
|
||||
Here is a quick example of how to use the unwind API to do a simple
|
||||
stack trace:
|
||||
|
||||
unw_cursor_t cursor;
|
||||
unw_word_t ip, sp;
|
||||
unw_context_t uc;
|
||||
|
||||
unw_getcontext(&uc);
|
||||
unw_init_local(&cursor, &uc);
|
||||
do
|
||||
{
|
||||
unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
||||
unw_get_reg(&cursor, UNW_REG_SP, &sp);
|
||||
printf ("ip=%016lx sp=%016lx\n", ip, sp);
|
||||
}
|
||||
while (unw_step (&cursor) > 0);
|
||||
|
||||
Note that this particular example should work on pretty much any
|
||||
architecture, as it doesn't rely on any arch-specific registers.
|
||||
|
||||
* Multiarchitecture support
|
||||
|
||||
If libunwind is configured for a target other than the local (native)
|
||||
host, the library is installed as libunwind-$ARCH, where $ARCH is
|
||||
the target architecture name (e.g., ia32, ia64, or alpha). Similarly,
|
||||
the header file is installed as libunwind-$ARCH.
|
||||
|
||||
With this setup, an application should:
|
||||
|
||||
- include <libunwind.h>, and
|
||||
- link against -lunwind
|
||||
|
||||
if the application needs to use the unwinder of the host. An
|
||||
application wanting to use the unwinder for a different target (e.g.,
|
||||
a cross-debugger) should:
|
||||
|
||||
- include <libunwind-$ARCH.h>, and
|
||||
- link against -lunwind-$ARCH
|
||||
|
||||
The global symbols exported by -lunwind-$ARCH are unique such that the
|
||||
same application can be linked against the separate unwind libraries
|
||||
of multiple targets. However, a single compilation unit can include
|
||||
the header file for only one target. For example, foo.c might include
|
||||
<libunwind-ia64.h> and bar.c might include <libunwind.h> and the
|
||||
entire application would have to be linked against both -lunwind and
|
||||
-lunwind-ia64.
|
||||
|
||||
Note: the unwind header files of all targets have a common dependency
|
||||
on libunwind-common.h. To avoid version conflicts, it is necessary to
|
||||
ensure that the unwind libraries for all targets were derived from the
|
||||
same release of libunwind. That is, if the unwind library for one
|
||||
target is upgraded to a newer version, the libraries for all other
|
||||
targets also need to be upgraded.
|
||||
|
||||
Note 2: The assumption is that a cross-unwinder can handle all
|
||||
interesting flavors of a target. For example, the unwinder for the
|
||||
ia64 target is expected to be able to handle both Linux and HP-UX.
|
||||
|
||||
* IA-64 Specific Information
|
||||
|
||||
Apart from the normal frame-registers, the IA-64 implementation of
|
||||
libunwind provides the means to access the current value of the
|
||||
register backing store pointer (bsp). One quirk with this
|
||||
frame-register is that it corresponds to the address that would be in
|
||||
register ar.bsp after flushing the current register stack to the
|
||||
backing store (i.e., as if a "flushrs" instruction had been executed).
|
||||
Of course, given this value and the contents of the current frame
|
||||
marker (CFM), it's easy to calculate the original value of ar.bsp:
|
||||
|
||||
unw_word_t cfm, bsp, bsp_after_flushrs, sof;
|
||||
|
||||
unw_get_reg (&cursor, UNW_IA64_BSP, &bsp_after_flushrs);
|
||||
unw_get_reg (&cursor, UNW_IA64_CFM, &cfm);
|
||||
bsp = ia64_rse_skip_regs (bsp_after_flushrs, -(cfm & 0x7f));
|
||||
|
||||
** Dynamic Unwind Info
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "\\_U\\_DYN\\_CANCEL" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
_U_dyn_cancel
|
||||
\-\- cancel unwind\-info for dynamically generated code
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
void
|
||||
_U_dyn_cancel(unw_dyn_info_t *di);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The _U_dyn_cancel()
|
||||
routine cancels the registration of the
|
||||
unwind\-info for a dynamically generated procedure. Argument di
|
||||
is the pointer to the unw_dyn_info_t
|
||||
structure that
|
||||
describes the procedure\&'s unwind\-info.
|
||||
.PP
|
||||
The _U_dyn_cancel()
|
||||
routine is guaranteed to execute in
|
||||
constant time (in the absence of contention from concurrent calls to
|
||||
_U_dyn_register()
|
||||
or _U_dyn_cancel()).
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
_U_dyn_cancel()
|
||||
is thread\-safe but \fInot\fP
|
||||
safe to use
|
||||
from a signal handler.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind\-dynamic(3),
|
||||
_U_dyn_register(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,46 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{\_U\_dyn\_cancel}{David Mosberger-Tang}{Programming Library}{\_U\_dyn\_cancel}\_U\_dyn\_cancel -- cancel unwind-info for dynamically generated code
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{void} \Func{\_U\_dyn\_cancel}(\Type{unw\_dyn\_info\_t~*}\Var{di});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{\_U\_dyn\_cancel}() routine cancels the registration of the
|
||||
unwind-info for a dynamically generated procedure. Argument \Var{di}
|
||||
is the pointer to the \Type{unw\_dyn\_info\_t} structure that
|
||||
describes the procedure's unwind-info.
|
||||
|
||||
The \Func{\_U\_dyn\_cancel}() routine is guaranteed to execute in
|
||||
constant time (in the absence of contention from concurrent calls to
|
||||
\Func{\_U\_dyn\_register}() or \Func{\_U\_dyn\_cancel}()).
|
||||
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{\_U\_dyn\_cancel}() is thread-safe but \emph{not} safe to use
|
||||
from a signal handler.
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind-dynamic(3)}, \SeeAlso{\_U\_dyn\_register(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,68 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "\\_U\\_DYN\\_REGISTER" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
_U_dyn_register
|
||||
\-\- register unwind\-info for dynamically generated code
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
void
|
||||
_U_dyn_register(unw_dyn_info_t *di);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The _U_dyn_register()
|
||||
routine registers unwind\-info for a
|
||||
dynamically generated procedure. The procedure\&'s unwind\-info is
|
||||
described by a structure of type unw_dyn_info_t
|
||||
(see
|
||||
libunwind\-dynamic(3)).
|
||||
A pointer to this structure is
|
||||
passed in argument di\&.
|
||||
.PP
|
||||
The _U_dyn_register()
|
||||
routine is guaranteed to execute in
|
||||
constant time (in the absence of contention from concurrent calls to
|
||||
_U_dyn_register()
|
||||
or _U_dyn_cancel()).
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
_U_dyn_register()
|
||||
is thread\-safe but \fInot\fP
|
||||
safe to use
|
||||
from a signal handler.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind\-dynamic(3),
|
||||
_U_dyn_cancel(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,47 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{\_U\_dyn\_register}{David Mosberger-Tang}{Programming Library}{\_U\_dyn\_register}\_U\_dyn\_register -- register unwind-info for dynamically generated code
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{void} \Func{\_U\_dyn\_register}(\Type{unw\_dyn\_info\_t~*}\Var{di});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{\_U\_dyn\_register}() routine registers unwind-info for a
|
||||
dynamically generated procedure. The procedure's unwind-info is
|
||||
described by a structure of type \Type{unw\_dyn\_info\_t} (see
|
||||
\SeeAlso{libunwind-dynamic(3)}). A pointer to this structure is
|
||||
passed in argument \Var{di}.
|
||||
|
||||
The \Func{\_U\_dyn\_register}() routine is guaranteed to execute in
|
||||
constant time (in the absence of contention from concurrent calls to
|
||||
\Func{\_U\_dyn\_register}() or \Func{\_U\_dyn\_cancel}()).
|
||||
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{\_U\_dyn\_register}() is thread-safe but \emph{not} safe to use
|
||||
from a signal handler.
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind-dynamic(3)}, \SeeAlso{\_U\_dyn\_cancel(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,11 @@
|
|||
\setVersion{@VERSION@}
|
||||
|
||||
\sloppy
|
||||
|
||||
\newcommand{\Lt}{\symbol{"3C}}
|
||||
\newcommand{\Gt}{\symbol{"3E}}
|
||||
\newcommand{\Type}[1]{\File{#1}} % see libunwind.trans
|
||||
\newcommand{\Func}[1]{\Prog{#1}} % see libunwind.trans
|
||||
\newcommand{\Var}[1]{\Prog{#1}} % see libunwind.trans
|
||||
\newcommand{\Const}[1]{\File{#1}} % see libunwind.trans
|
||||
\newcommand{\SeeAlso}[2]{\File{#1}} % see libunwind.trans
|
|
@ -0,0 +1,538 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "LIBUNWIND\-DYNAMIC" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
libunwind\-dynamic
|
||||
\-\- libunwind\-support for runtime\-generated code
|
||||
.PP
|
||||
.SH INTRODUCTION
|
||||
|
||||
.PP
|
||||
For libunwind
|
||||
to do its job, it needs to be able to reconstruct
|
||||
the \fIframe state\fP
|
||||
of each frame in a call\-chain. The frame state
|
||||
describes the subset of the machine\-state that consists of the
|
||||
\fIframe registers\fP
|
||||
(typically the instruction\-pointer and the
|
||||
stack\-pointer) and all callee\-saved registers (preserved registers).
|
||||
The frame state describes each register either by providing its
|
||||
current value (for frame registers) or by providing the location at
|
||||
which the current value is stored (callee\-saved registers).
|
||||
.PP
|
||||
For statically generated code, the compiler normally takes care of
|
||||
emitting \fIunwind\-info\fP
|
||||
which provides the minimum amount of
|
||||
information needed to reconstruct the frame\-state for each instruction
|
||||
in a procedure. For dynamically generated code, the runtime code
|
||||
generator must use the dynamic unwind\-info interface provided by
|
||||
libunwind
|
||||
to supply the equivalent information. This manual
|
||||
page describes the format of this information in detail.
|
||||
.PP
|
||||
For the purpose of this discussion, a \fIprocedure\fP
|
||||
is defined to
|
||||
be an arbitrary piece of \fIcontiguous\fP
|
||||
code. Normally, each
|
||||
procedure directly corresponds to a function in the source\-language
|
||||
but this is not strictly required. For example, a runtime
|
||||
code\-generator could translate a given function into two separate
|
||||
(discontiguous) procedures: one for frequently\-executed (hot) code and
|
||||
one for rarely\-executed (cold) code. Similarly, simple
|
||||
source\-language functions (usually leaf functions) may get translated
|
||||
into code for which the default unwind\-conventions apply and for such
|
||||
code, it is not strictly necessary to register dynamic unwind\-info.
|
||||
.PP
|
||||
A procedure logically consists of a sequence of \fIregions\fP\&.
|
||||
Regions are nested in the sense that the frame state at the end of one
|
||||
region is, by default, assumed to be the frame state for the next
|
||||
region. Each region is thought of as being divided into a
|
||||
\fIprologue\fP,
|
||||
a \fIbody\fP,
|
||||
and an \fIepilogue\fP\&.
|
||||
Each of them
|
||||
can be empty. If non\-empty, the prologue sets up the frame state for
|
||||
the body. For example, the prologue may need to allocate some space
|
||||
on the stack and save certain callee\-saved registers. The body
|
||||
performs the actual work of the procedure but does not change the
|
||||
frame state in any way. If non\-empty, the epilogue restores the
|
||||
previous frame state and as such it undoes or cancels the effect of
|
||||
the prologue. In fact, a single epilogue may undo the effect of the
|
||||
prologues of several (nested) regions.
|
||||
.PP
|
||||
We should point out that even though the prologue, body, and epilogue
|
||||
are logically separate entities, optimizing code\-generators will
|
||||
generally interleave instructions from all three entities. For this
|
||||
reason, the dynamic unwind\-info interface of libunwind
|
||||
makes no
|
||||
distinction whatsoever between prologue and body. Similarly, the
|
||||
exact set of instructions that make up an epilogue is also irrelevant.
|
||||
The only point in the epilogue that needs to be described explicitly
|
||||
by the dynamic unwind\-info is the point at which the stack\-pointer
|
||||
gets restored. The reason this point needs to be described is that
|
||||
once the stack\-pointer is restored, all values saved in the
|
||||
deallocated portion of the stack frame become invalid and hence
|
||||
libunwind
|
||||
needs to know about it. The portion of the frame
|
||||
state not saved on the stack is assume to remain valid through the end
|
||||
of the region. For this reason, there is usually no need to describe
|
||||
instructions which restore the contents of callee\-saved registers.
|
||||
.PP
|
||||
Within a region, each instruction that affects the frame state in some
|
||||
fashion needs to be described with an operation descriptor. For this
|
||||
purpose, each instruction in the region is assigned a unique index.
|
||||
Exactly how this index is derived depends on the architecture. For
|
||||
example, on RISC and EPIC\-style architecture, instructions have a
|
||||
fixed size so it\&'s possible to simply number the instructions. In
|
||||
contrast, most CISC use variable\-length instruction encodings, so it
|
||||
is usually necessary to use a byte\-offset as the index. Given the
|
||||
instruction index, the operation descriptor specifies the effect of
|
||||
the instruction in an abstract manner. For example, it might express
|
||||
that the instruction stores calle\-saved register r1
|
||||
at offset 16
|
||||
in the stack frame.
|
||||
.PP
|
||||
.SH PROCEDURES
|
||||
|
||||
.PP
|
||||
A runtime code\-generator registers the dynamic unwind\-info of a
|
||||
procedure by setting up a structure of type unw_dyn_info_t
|
||||
and calling _U_dyn_register(),
|
||||
passing the address of the
|
||||
structure as the sole argument. The members of the
|
||||
unw_dyn_info_t
|
||||
structure are described below:
|
||||
.TP
|
||||
void *next
|
||||
Private to libunwind\&.
|
||||
Must not be used
|
||||
by the application.
|
||||
.TP
|
||||
void *prev
|
||||
Private to libunwind\&.
|
||||
Must not be used
|
||||
by the application.
|
||||
.TP
|
||||
unw_word_t start_ip
|
||||
The start\-address of the
|
||||
instructions of the procedure (remember: procedure are defined to be
|
||||
contiguous pieces of code, so a single code\-range is sufficient).
|
||||
.TP
|
||||
unw_word_t end_ip
|
||||
The end\-address of the
|
||||
instructions of the procedure (non\-inclusive, that is,
|
||||
end_ip\-start_ip
|
||||
is the size of the procedure in
|
||||
bytes).
|
||||
.TP
|
||||
unw_word_t gp
|
||||
The global\-pointer value in use
|
||||
for this procedure. The exact meaing of the global\-pointer is
|
||||
architecture\-specific and on some architecture, it is not used at
|
||||
all.
|
||||
.TP
|
||||
int32_t format
|
||||
The format of the unwind\-info.
|
||||
This member can be one of UNW_INFO_FORMAT_DYNAMIC,
|
||||
UNW_INFO_FORMAT_TABLE,
|
||||
or
|
||||
UNW_INFO_FORMAT_REMOTE_TABLE\&.
|
||||
.TP
|
||||
union u
|
||||
This union contains one sub\-member
|
||||
structure for every possible unwind\-info format:
|
||||
.RS
|
||||
.TP
|
||||
unw_dyn_proc_info_t pi
|
||||
This member is used
|
||||
for format UNW_INFO_FORMAT_DYNAMIC\&.
|
||||
.TP
|
||||
unw_dyn_table_info_t ti
|
||||
This member is used
|
||||
for format UNW_INFO_FORMAT_TABLE\&.
|
||||
.TP
|
||||
unw_dyn_remote_table_info_t rti
|
||||
This member
|
||||
is used for format UNW_INFO_FORMAT_REMOTE_TABLE\&.
|
||||
.RE
|
||||
.RS
|
||||
.PP
|
||||
The format of these sub\-members is described in detail below.
|
||||
.RE
|
||||
.PP
|
||||
.SS PROC\-INFO FORMAT
|
||||
.PP
|
||||
This is the preferred dynamic unwind\-info format and it is generally
|
||||
the one used by full\-blown runtime code\-generators. In this format,
|
||||
the details of a procedure are described by a structure of type
|
||||
unw_dyn_proc_info_t\&.
|
||||
This structure contains the following
|
||||
members:
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
unw_word_t name_ptr
|
||||
The address of a
|
||||
(human\-readable) name of the procedure or 0 if no such name is
|
||||
available. If non\-zero, The string stored at this address must be
|
||||
ASCII NUL terminated. For source languages that use name\-mangling
|
||||
(such as C++ or Java) the string stored at this address should be
|
||||
the \fIdemangled\fP
|
||||
version of the name.
|
||||
.PP
|
||||
.TP
|
||||
unw_word_t handler
|
||||
The address of the
|
||||
personality\-routine for this procedure. Personality\-routines are
|
||||
used in conjunction with exception handling. See the C++ ABI draft
|
||||
(http://www.codesourcery.com/cxx\-abi/) for an overview and a
|
||||
description of the personality routine. If the procedure has no
|
||||
personality routine, handler
|
||||
must be set to 0.
|
||||
.PP
|
||||
.TP
|
||||
uint32_t flags
|
||||
A bitmask of flags. At the
|
||||
moment, no flags have been defined and this member must be
|
||||
set to 0.
|
||||
.PP
|
||||
.TP
|
||||
unw_dyn_region_info_t *regions
|
||||
A NULL\-terminated
|
||||
linked list of region\-descriptors. See section ``Region
|
||||
descriptors\&'' below for more details.
|
||||
.PP
|
||||
.SS TABLE\-INFO FORMAT
|
||||
.PP
|
||||
This format is generally used when the dynamically generated code was
|
||||
derived from static code and the unwind\-info for the dynamic and the
|
||||
static versions is identical. For example, this format can be useful
|
||||
when loading statically\-generated code into an address\-space in a
|
||||
non\-standard fashion (i.e., through some means other than
|
||||
dlopen()).
|
||||
In this format, the details of a group of procedures
|
||||
is described by a structure of type unw_dyn_table_info\&.
|
||||
This structure contains the following members:
|
||||
.PP
|
||||
.TP
|
||||
unw_word_t name_ptr
|
||||
The address of a
|
||||
(human\-readable) name of the procedure or 0 if no such name is
|
||||
available. If non\-zero, The string stored at this address must be
|
||||
ASCII NUL terminated. For source languages that use name\-mangling
|
||||
(such as C++ or Java) the string stored at this address should be
|
||||
the \fIdemangled\fP
|
||||
version of the name.
|
||||
.PP
|
||||
.TP
|
||||
unw_word_t segbase
|
||||
The segment\-base value
|
||||
that needs to be added to the segment\-relative values stored in the
|
||||
unwind\-info. The exact meaning of this value is
|
||||
architecture\-specific.
|
||||
.PP
|
||||
.TP
|
||||
unw_word_t table_len
|
||||
The length of the
|
||||
unwind\-info (table_data)
|
||||
counted in units of words
|
||||
(unw_word_t).
|
||||
.PP
|
||||
.TP
|
||||
unw_word_t table_data
|
||||
A pointer to the actual
|
||||
data encoding the unwind\-info. The exact format is
|
||||
architecture\-specific (see architecture\-specific sections below).
|
||||
.PP
|
||||
.SS REMOTE TABLE\-INFO FORMAT
|
||||
.PP
|
||||
The remote table\-info format has the same basic purpose as the regular
|
||||
table\-info format. The only difference is that when libunwind
|
||||
uses the unwind\-info, it will keep the table data in the target
|
||||
address\-space (which may be remote). Consequently, the type of the
|
||||
table_data
|
||||
member is unw_word_t
|
||||
rather than a pointer.
|
||||
This implies that libunwind
|
||||
will have to access the table\-data
|
||||
via the address\-space\&'s access_mem()
|
||||
call\-back, rather than
|
||||
through a direct memory reference.
|
||||
.PP
|
||||
From the point of view of a runtime\-code generator, the remote
|
||||
table\-info format offers no advantage and it is expected that such
|
||||
generators will describe their procedures either with the proc\-info
|
||||
format or the normal table\-info format. The main reason that the
|
||||
remote table\-info format exists is to enable the
|
||||
address\-space\-specific find_proc_info()
|
||||
callback (see
|
||||
unw_create_addr_space(3))
|
||||
to return unwind tables whose
|
||||
data remains in remote memory. This can speed up unwinding (e.g., for
|
||||
a debugger) because it reduces the amount of data that needs to be
|
||||
loaded from remote memory.
|
||||
.PP
|
||||
.SH REGIONS DESCRIPTORS
|
||||
|
||||
.PP
|
||||
A region descriptor is a variable length structure that describes how
|
||||
each instruction in the region affects the frame state. Of course,
|
||||
most instructions in a region usualy do not change the frame state and
|
||||
for those, nothing needs to be recorded in the region descriptor. A
|
||||
region descriptor is a structure of type
|
||||
unw_dyn_region_info_t
|
||||
and has the following members:
|
||||
.TP
|
||||
unw_dyn_region_info_t *next
|
||||
A pointer to the
|
||||
next region. If this is the last region, next
|
||||
is NULL\&.
|
||||
.TP
|
||||
int32_t insn_count
|
||||
The length of the region in
|
||||
instructions. Each instruction is assumed to have a fixed size (see
|
||||
architecture\-specific sections for details). The value of
|
||||
insn_count
|
||||
may be negative in the last region of a procedure
|
||||
(i.e., it may be negative only if next
|
||||
is NULL).
|
||||
A
|
||||
negative value indicates that the region covers the last \fIN\fP
|
||||
instructions of the procedure, where \fIN\fP
|
||||
is the absolute value
|
||||
of insn_count\&.
|
||||
.TP
|
||||
uint32_t op_count
|
||||
The (allocated) length of
|
||||
the op_count
|
||||
array.
|
||||
.TP
|
||||
unw_dyn_op_t op
|
||||
An array of dynamic unwind
|
||||
directives. See Section ``Dynamic unwind directives\&'' for a
|
||||
description of the directives.
|
||||
.PP
|
||||
A region descriptor with an insn_count
|
||||
of zero is an
|
||||
\fIempty region\fP
|
||||
and such regions are perfectly legal. In fact,
|
||||
empty regions can be useful to establish a particular frame state
|
||||
before the start of another region.
|
||||
.PP
|
||||
A single region list can be shared across multiple procedures provided
|
||||
those procedures share a common prologue and epilogue (their bodies
|
||||
may differ, of course). Normally, such procedures consist of a canned
|
||||
prologue, the body, and a canned epilogue. This could be described by
|
||||
two regions: one covering the prologue and one covering the epilogue.
|
||||
Since the body length is variable, the latter region would need to
|
||||
specify a negative value in insn_count
|
||||
such that
|
||||
libunwind
|
||||
knows that the region covers the end of the procedure
|
||||
(up to the address specified by end_ip).
|
||||
.PP
|
||||
The region descriptor is a variable length structure to make it
|
||||
possible to allocate all the necessary memory with a single
|
||||
memory\-allocation request. To facilitate the allocation of a region
|
||||
descriptors libunwind
|
||||
provides a helper routine with the
|
||||
following synopsis:
|
||||
.PP
|
||||
size_t
|
||||
_U_dyn_region_size(int
|
||||
op_count);
|
||||
.PP
|
||||
This routine returns the number of bytes needed to hold a region
|
||||
descriptor with space for op_count
|
||||
unwind directives. Note
|
||||
that the length of the op
|
||||
array does not have to match exactly
|
||||
with the number of directives in a region. Instead, it is sufficient
|
||||
if the op
|
||||
array contains at least as many entries as there are
|
||||
directives, since the end of the directives can always be indicated
|
||||
with the UNW_DYN_STOP
|
||||
directive.
|
||||
.PP
|
||||
.SH DYNAMIC UNWIND DIRECTIVES
|
||||
|
||||
.PP
|
||||
A dynamic unwind directive describes how the frame state changes
|
||||
at a particular point within a region. The description is in
|
||||
the form of a structure of type unw_dyn_op_t\&.
|
||||
This
|
||||
structure has the following members:
|
||||
.TP
|
||||
int8_t tag
|
||||
The operation tag. Must be one
|
||||
of the unw_dyn_operation_t
|
||||
values described below.
|
||||
.TP
|
||||
int8_t qp
|
||||
The qualifying predicate that controls
|
||||
whether or not this directive is active. This is useful for
|
||||
predicated architecturs such as IA\-64 or ARM, where the contents of
|
||||
another (callee\-saved) register determines whether or not an
|
||||
instruction is executed (takes effect). If the directive is always
|
||||
active, this member should be set to the manifest constant
|
||||
_U_QP_TRUE
|
||||
(this constant is defined for all
|
||||
architectures, predicated or not).
|
||||
.TP
|
||||
int16_t reg
|
||||
The number of the register affected
|
||||
by the instruction.
|
||||
.TP
|
||||
int32_t when
|
||||
The region\-relative number of
|
||||
the instruction to which this directive applies. For example,
|
||||
a value of 0 means that the effect described by this directive
|
||||
has taken place once the first instruction in the region has
|
||||
executed.
|
||||
.TP
|
||||
unw_word_t val
|
||||
The value to be applied by the
|
||||
operation tag. The exact meaning of this value varies by tag. See
|
||||
Section ``Operation tags\&'' below.
|
||||
.PP
|
||||
It is perfectly legitimate to specify multiple dynamic unwind
|
||||
directives with the same when
|
||||
value, if a particular instruction
|
||||
has a complex effect on the frame state.
|
||||
.PP
|
||||
Empty regions by definition contain no actual instructions and as such
|
||||
the directives are not tied to a particular instruction. By
|
||||
convention, the when
|
||||
member should be set to 0, however.
|
||||
.PP
|
||||
There is no need for the dynamic unwind directives to appear
|
||||
in order of increasing when
|
||||
values. If the directives happen to
|
||||
be sorted in that order, it may result in slightly faster execution,
|
||||
but a runtime code\-generator should not go to extra lengths just to
|
||||
ensure that the directives are sorted.
|
||||
.PP
|
||||
IMPLEMENTATION NOTE: should libunwind
|
||||
implementations for
|
||||
certain architectures prefer the list of unwind directives to be
|
||||
sorted, it is recommended that such implementations first check
|
||||
whether the list happens to be sorted already and, if not, sort the
|
||||
directives explicitly before the first use. With this approach, the
|
||||
overhead of explicit sorting is only paid when there is a real benefit
|
||||
and if the runtime code\-generator happens to generated sorted lists
|
||||
naturally, the performance penalty is limited to a simple O(N) check.
|
||||
.PP
|
||||
.SS OPERATIONS TAGS
|
||||
.PP
|
||||
The possible operation tags are defined by enumeration type
|
||||
unw_dyn_operation_t
|
||||
which defines the following
|
||||
values:
|
||||
.PP
|
||||
.TP
|
||||
UNW_DYN_STOP
|
||||
Marks the end of the dynamic unwind
|
||||
directive list. All remaining entries in the op
|
||||
array of the
|
||||
region\-descriptor are ignored. This tag is guaranteed to have a
|
||||
value of 0.
|
||||
.PP
|
||||
.TP
|
||||
UNW_DYN_SAVE_REG
|
||||
Marks an instruction which saves
|
||||
register reg
|
||||
to register val\&.
|
||||
.PP
|
||||
.TP
|
||||
UNW_DYN_SPILL_FP_REL
|
||||
Marks an instruction which
|
||||
spills register reg
|
||||
to a frame\-pointer\-relative location. The
|
||||
frame\-pointer\-relative offset is given by the value stored in member
|
||||
val\&.
|
||||
See the architecture\-specific sections for a description
|
||||
of the stack frame layout.
|
||||
.PP
|
||||
.TP
|
||||
UNW_DYN_SPILL_SP_REL
|
||||
Marks an instruction which
|
||||
spills register reg
|
||||
to a stack\-pointer\-relative location. The
|
||||
stack\-pointer\-relative offset is given by the value stored in member
|
||||
val\&.
|
||||
See the architecture\-specific sections for a description
|
||||
of the stack frame layout.
|
||||
.PP
|
||||
.TP
|
||||
UNW_DYN_ADD
|
||||
Marks an instruction which adds
|
||||
the constant value val
|
||||
to register reg\&.
|
||||
To add subtract
|
||||
a constant value, store the two\&'s\-complement of the value in
|
||||
val\&.
|
||||
The set of registers that can be specified for this tag
|
||||
is described in the architecture\-specific sections below.
|
||||
.PP
|
||||
.TP
|
||||
UNW_DYN_POP_FRAMES
|
||||
.PP
|
||||
.TP
|
||||
UNW_DYN_LABEL_STATE
|
||||
.PP
|
||||
.TP
|
||||
UNW_DYN_COPY_STATE
|
||||
.PP
|
||||
.TP
|
||||
UNW_DYN_ALIAS
|
||||
.PP
|
||||
unw_dyn_op_t
|
||||
.PP
|
||||
_U_dyn_op_save_reg();
|
||||
_U_dyn_op_spill_fp_rel();
|
||||
_U_dyn_op_spill_sp_rel();
|
||||
_U_dyn_op_add();
|
||||
_U_dyn_op_pop_frames();
|
||||
_U_dyn_op_label_state();
|
||||
_U_dyn_op_copy_state();
|
||||
_U_dyn_op_alias();
|
||||
_U_dyn_op_stop();
|
||||
.PP
|
||||
.SH IA\-64 SPECIFICS
|
||||
|
||||
.PP
|
||||
\- meaning of segbase member in table\-info/table\-remote\-info format
|
||||
\- format of table_data in table\-info/table\-remote\-info format
|
||||
\- instruction size: each bundle is counted as 3 instructions, regardless
|
||||
of template (MLX)
|
||||
\- describe stack\-frame layout, especially with regards to sp\-relative
|
||||
and fp\-relative addressing
|
||||
\- UNW_DYN_ADD can only add to ``sp\&'' (always a negative value); use
|
||||
POP_FRAMES otherwise
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
_U_dyn_register(3),
|
||||
_U_dyn_cancel(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,401 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{libunwind-dynamic}{David Mosberger-Tang}{Programming Library}{Introduction to dynamic unwind-info}libunwind-dynamic -- libunwind-support for runtime-generated code
|
||||
\end{Name}
|
||||
|
||||
\section{Introduction}
|
||||
|
||||
For \Prog{libunwind} to do its job, it needs to be able to reconstruct
|
||||
the \emph{frame state} of each frame in a call-chain. The frame state
|
||||
describes the subset of the machine-state that consists of the
|
||||
\emph{frame registers} (typically the instruction-pointer and the
|
||||
stack-pointer) and all callee-saved registers (preserved registers).
|
||||
The frame state describes each register either by providing its
|
||||
current value (for frame registers) or by providing the location at
|
||||
which the current value is stored (callee-saved registers).
|
||||
|
||||
For statically generated code, the compiler normally takes care of
|
||||
emitting \emph{unwind-info} which provides the minimum amount of
|
||||
information needed to reconstruct the frame-state for each instruction
|
||||
in a procedure. For dynamically generated code, the runtime code
|
||||
generator must use the dynamic unwind-info interface provided by
|
||||
\Prog{libunwind} to supply the equivalent information. This manual
|
||||
page describes the format of this information in detail.
|
||||
|
||||
For the purpose of this discussion, a \emph{procedure} is defined to
|
||||
be an arbitrary piece of \emph{contiguous} code. Normally, each
|
||||
procedure directly corresponds to a function in the source-language
|
||||
but this is not strictly required. For example, a runtime
|
||||
code-generator could translate a given function into two separate
|
||||
(discontiguous) procedures: one for frequently-executed (hot) code and
|
||||
one for rarely-executed (cold) code. Similarly, simple
|
||||
source-language functions (usually leaf functions) may get translated
|
||||
into code for which the default unwind-conventions apply and for such
|
||||
code, it is not strictly necessary to register dynamic unwind-info.
|
||||
|
||||
A procedure logically consists of a sequence of \emph{regions}.
|
||||
Regions are nested in the sense that the frame state at the end of one
|
||||
region is, by default, assumed to be the frame state for the next
|
||||
region. Each region is thought of as being divided into a
|
||||
\emph{prologue}, a \emph{body}, and an \emph{epilogue}. Each of them
|
||||
can be empty. If non-empty, the prologue sets up the frame state for
|
||||
the body. For example, the prologue may need to allocate some space
|
||||
on the stack and save certain callee-saved registers. The body
|
||||
performs the actual work of the procedure but does not change the
|
||||
frame state in any way. If non-empty, the epilogue restores the
|
||||
previous frame state and as such it undoes or cancels the effect of
|
||||
the prologue. In fact, a single epilogue may undo the effect of the
|
||||
prologues of several (nested) regions.
|
||||
|
||||
We should point out that even though the prologue, body, and epilogue
|
||||
are logically separate entities, optimizing code-generators will
|
||||
generally interleave instructions from all three entities. For this
|
||||
reason, the dynamic unwind-info interface of \Prog{libunwind} makes no
|
||||
distinction whatsoever between prologue and body. Similarly, the
|
||||
exact set of instructions that make up an epilogue is also irrelevant.
|
||||
The only point in the epilogue that needs to be described explicitly
|
||||
by the dynamic unwind-info is the point at which the stack-pointer
|
||||
gets restored. The reason this point needs to be described is that
|
||||
once the stack-pointer is restored, all values saved in the
|
||||
deallocated portion of the stack frame become invalid and hence
|
||||
\Prog{libunwind} needs to know about it. The portion of the frame
|
||||
state not saved on the stack is assume to remain valid through the end
|
||||
of the region. For this reason, there is usually no need to describe
|
||||
instructions which restore the contents of callee-saved registers.
|
||||
|
||||
Within a region, each instruction that affects the frame state in some
|
||||
fashion needs to be described with an operation descriptor. For this
|
||||
purpose, each instruction in the region is assigned a unique index.
|
||||
Exactly how this index is derived depends on the architecture. For
|
||||
example, on RISC and EPIC-style architecture, instructions have a
|
||||
fixed size so it's possible to simply number the instructions. In
|
||||
contrast, most CISC use variable-length instruction encodings, so it
|
||||
is usually necessary to use a byte-offset as the index. Given the
|
||||
instruction index, the operation descriptor specifies the effect of
|
||||
the instruction in an abstract manner. For example, it might express
|
||||
that the instruction stores calle-saved register \Var{r1} at offset 16
|
||||
in the stack frame.
|
||||
|
||||
\section{Procedures}
|
||||
|
||||
A runtime code-generator registers the dynamic unwind-info of a
|
||||
procedure by setting up a structure of type \Type{unw\_dyn\_info\_t}
|
||||
and calling \Func{\_U\_dyn\_register}(), passing the address of the
|
||||
structure as the sole argument. The members of the
|
||||
\Type{unw\_dyn\_info\_t} structure are described below:
|
||||
\begin{itemize}
|
||||
\item[\Type{void~*}next] Private to \Prog{libunwind}. Must not be used
|
||||
by the application.
|
||||
\item[\Type{void~*}prev] Private to \Prog{libunwind}. Must not be used
|
||||
by the application.
|
||||
\item[\Type{unw\_word\_t} \Var{start\_ip}] The start-address of the
|
||||
instructions of the procedure (remember: procedure are defined to be
|
||||
contiguous pieces of code, so a single code-range is sufficient).
|
||||
\item[\Type{unw\_word\_t} \Var{end\_ip}] The end-address of the
|
||||
instructions of the procedure (non-inclusive, that is,
|
||||
\Var{end\_ip}-\Var{start\_ip} is the size of the procedure in
|
||||
bytes).
|
||||
\item[\Type{unw\_word\_t} \Var{gp}] The global-pointer value in use
|
||||
for this procedure. The exact meaing of the global-pointer is
|
||||
architecture-specific and on some architecture, it is not used at
|
||||
all.
|
||||
\item[\Type{int32\_t} \Var{format}] The format of the unwind-info.
|
||||
This member can be one of \Const{UNW\_INFO\_FORMAT\_DYNAMIC},
|
||||
\Const{UNW\_INFO\_FORMAT\_TABLE}, or
|
||||
\Const{UNW\_INFO\_FORMAT\_REMOTE\_TABLE}.
|
||||
\item[\Type{union} \Var{u}] This union contains one sub-member
|
||||
structure for every possible unwind-info format:
|
||||
\begin{description}
|
||||
\item[\Type{unw\_dyn\_proc\_info\_t} \Var{pi}] This member is used
|
||||
for format \Const{UNW\_INFO\_FORMAT\_DYNAMIC}.
|
||||
\item[\Type{unw\_dyn\_table\_info\_t} \Var{ti}] This member is used
|
||||
for format \Const{UNW\_INFO\_FORMAT\_TABLE}.
|
||||
\item[\Type{unw\_dyn\_remote\_table\_info\_t} \Var{rti}] This member
|
||||
is used for format \Const{UNW\_INFO\_FORMAT\_REMOTE\_TABLE}.
|
||||
\end{description}\
|
||||
The format of these sub-members is described in detail below.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Proc-info format}
|
||||
|
||||
This is the preferred dynamic unwind-info format and it is generally
|
||||
the one used by full-blown runtime code-generators. In this format,
|
||||
the details of a procedure are described by a structure of type
|
||||
\Type{unw\_dyn\_proc\_info\_t}. This structure contains the following
|
||||
members:
|
||||
\begin{description}
|
||||
|
||||
\item[\Type{unw\_word\_t} \Var{name\_ptr}] The address of a
|
||||
(human-readable) name of the procedure or 0 if no such name is
|
||||
available. If non-zero, The string stored at this address must be
|
||||
ASCII NUL terminated. For source languages that use name-mangling
|
||||
(such as C++ or Java) the string stored at this address should be
|
||||
the \emph{demangled} version of the name.
|
||||
|
||||
\item[\Type{unw\_word\_t} \Var{handler}] The address of the
|
||||
personality-routine for this procedure. Personality-routines are
|
||||
used in conjunction with exception handling. See the C++ ABI draft
|
||||
(http://www.codesourcery.com/cxx-abi/) for an overview and a
|
||||
description of the personality routine. If the procedure has no
|
||||
personality routine, \Var{handler} must be set to 0.
|
||||
|
||||
\item[\Type{uint32\_t} \Var{flags}] A bitmask of flags. At the
|
||||
moment, no flags have been defined and this member must be
|
||||
set to 0.
|
||||
|
||||
\item[\Type{unw\_dyn\_region\_info\_t~*}\Var{regions}] A NULL-terminated
|
||||
linked list of region-descriptors. See section ``Region
|
||||
descriptors'' below for more details.
|
||||
|
||||
\end{description}
|
||||
|
||||
\subsection{Table-info format}
|
||||
|
||||
This format is generally used when the dynamically generated code was
|
||||
derived from static code and the unwind-info for the dynamic and the
|
||||
static versions is identical. For example, this format can be useful
|
||||
when loading statically-generated code into an address-space in a
|
||||
non-standard fashion (i.e., through some means other than
|
||||
\Func{dlopen}()). In this format, the details of a group of procedures
|
||||
is described by a structure of type \Type{unw\_dyn\_table\_info}.
|
||||
This structure contains the following members:
|
||||
\begin{description}
|
||||
|
||||
\item[\Type{unw\_word\_t} \Var{name\_ptr}] The address of a
|
||||
(human-readable) name of the procedure or 0 if no such name is
|
||||
available. If non-zero, The string stored at this address must be
|
||||
ASCII NUL terminated. For source languages that use name-mangling
|
||||
(such as C++ or Java) the string stored at this address should be
|
||||
the \emph{demangled} version of the name.
|
||||
|
||||
\item[\Type{unw\_word\_t} \Var{segbase}] The segment-base value
|
||||
that needs to be added to the segment-relative values stored in the
|
||||
unwind-info. The exact meaning of this value is
|
||||
architecture-specific.
|
||||
|
||||
\item[\Type{unw\_word\_t} \Var{table\_len}] The length of the
|
||||
unwind-info (\Var{table\_data}) counted in units of words
|
||||
(\Type{unw\_word\_t}).
|
||||
|
||||
\item[\Type{unw\_word\_t} \Var{table\_data}] A pointer to the actual
|
||||
data encoding the unwind-info. The exact format is
|
||||
architecture-specific (see architecture-specific sections below).
|
||||
|
||||
\end{description}
|
||||
|
||||
\subsection{Remote table-info format}
|
||||
|
||||
The remote table-info format has the same basic purpose as the regular
|
||||
table-info format. The only difference is that when \Prog{libunwind}
|
||||
uses the unwind-info, it will keep the table data in the target
|
||||
address-space (which may be remote). Consequently, the type of the
|
||||
\Var{table\_data} member is \Type{unw\_word\_t} rather than a pointer.
|
||||
This implies that \Prog{libunwind} will have to access the table-data
|
||||
via the address-space's \Func{access\_mem}() call-back, rather than
|
||||
through a direct memory reference.
|
||||
|
||||
From the point of view of a runtime-code generator, the remote
|
||||
table-info format offers no advantage and it is expected that such
|
||||
generators will describe their procedures either with the proc-info
|
||||
format or the normal table-info format. The main reason that the
|
||||
remote table-info format exists is to enable the
|
||||
address-space-specific \Func{find\_proc\_info}() callback (see
|
||||
\SeeAlso{unw\_create\_addr\_space}(3)) to return unwind tables whose
|
||||
data remains in remote memory. This can speed up unwinding (e.g., for
|
||||
a debugger) because it reduces the amount of data that needs to be
|
||||
loaded from remote memory.
|
||||
|
||||
\section{Regions descriptors}
|
||||
|
||||
A region descriptor is a variable length structure that describes how
|
||||
each instruction in the region affects the frame state. Of course,
|
||||
most instructions in a region usualy do not change the frame state and
|
||||
for those, nothing needs to be recorded in the region descriptor. A
|
||||
region descriptor is a structure of type
|
||||
\Type{unw\_dyn\_region\_info\_t} and has the following members:
|
||||
\begin{description}
|
||||
\item[\Type{unw\_dyn\_region\_info\_t~*}\Var{next}] A pointer to the
|
||||
next region. If this is the last region, \Var{next} is \Const{NULL}.
|
||||
\item[\Type{int32\_t} \Var{insn\_count}] The length of the region in
|
||||
instructions. Each instruction is assumed to have a fixed size (see
|
||||
architecture-specific sections for details). The value of
|
||||
\Var{insn\_count} may be negative in the last region of a procedure
|
||||
(i.e., it may be negative only if \Var{next} is \Const{NULL}). A
|
||||
negative value indicates that the region covers the last \emph{N}
|
||||
instructions of the procedure, where \emph{N} is the absolute value
|
||||
of \Var{insn\_count}.
|
||||
\item[\Type{uint32\_t} \Var{op\_count}] The (allocated) length of
|
||||
the \Var{op\_count} array.
|
||||
\item[\Type{unw\_dyn\_op\_t} \Var{op}] An array of dynamic unwind
|
||||
directives. See Section ``Dynamic unwind directives'' for a
|
||||
description of the directives.
|
||||
\end{description}
|
||||
A region descriptor with an \Var{insn\_count} of zero is an
|
||||
\emph{empty region} and such regions are perfectly legal. In fact,
|
||||
empty regions can be useful to establish a particular frame state
|
||||
before the start of another region.
|
||||
|
||||
A single region list can be shared across multiple procedures provided
|
||||
those procedures share a common prologue and epilogue (their bodies
|
||||
may differ, of course). Normally, such procedures consist of a canned
|
||||
prologue, the body, and a canned epilogue. This could be described by
|
||||
two regions: one covering the prologue and one covering the epilogue.
|
||||
Since the body length is variable, the latter region would need to
|
||||
specify a negative value in \Var{insn\_count} such that
|
||||
\Prog{libunwind} knows that the region covers the end of the procedure
|
||||
(up to the address specified by \Var{end\_ip}).
|
||||
|
||||
The region descriptor is a variable length structure to make it
|
||||
possible to allocate all the necessary memory with a single
|
||||
memory-allocation request. To facilitate the allocation of a region
|
||||
descriptors \Prog{libunwind} provides a helper routine with the
|
||||
following synopsis:
|
||||
|
||||
\noindent
|
||||
\Type{size\_t} \Func{\_U\_dyn\_region\_size}(\Type{int} \Var{op\_count});
|
||||
|
||||
This routine returns the number of bytes needed to hold a region
|
||||
descriptor with space for \Var{op\_count} unwind directives. Note
|
||||
that the length of the \Var{op} array does not have to match exactly
|
||||
with the number of directives in a region. Instead, it is sufficient
|
||||
if the \Var{op} array contains at least as many entries as there are
|
||||
directives, since the end of the directives can always be indicated
|
||||
with the \Const{UNW\_DYN\_STOP} directive.
|
||||
|
||||
\section{Dynamic unwind directives}
|
||||
|
||||
A dynamic unwind directive describes how the frame state changes
|
||||
at a particular point within a region. The description is in
|
||||
the form of a structure of type \Type{unw\_dyn\_op\_t}. This
|
||||
structure has the following members:
|
||||
\begin{description}
|
||||
\item[\Type{int8\_t} \Var{tag}] The operation tag. Must be one
|
||||
of the \Type{unw\_dyn\_operation\_t} values described below.
|
||||
\item[\Type{int8\_t} \Var{qp}] The qualifying predicate that controls
|
||||
whether or not this directive is active. This is useful for
|
||||
predicated architecturs such as IA-64 or ARM, where the contents of
|
||||
another (callee-saved) register determines whether or not an
|
||||
instruction is executed (takes effect). If the directive is always
|
||||
active, this member should be set to the manifest constant
|
||||
\Const{\_U\_QP\_TRUE} (this constant is defined for all
|
||||
architectures, predicated or not).
|
||||
\item[\Type{int16\_t} \Var{reg}] The number of the register affected
|
||||
by the instruction.
|
||||
\item[\Type{int32\_t} \Var{when}] The region-relative number of
|
||||
the instruction to which this directive applies. For example,
|
||||
a value of 0 means that the effect described by this directive
|
||||
has taken place once the first instruction in the region has
|
||||
executed.
|
||||
\item[\Type{unw\_word\_t} \Var{val}] The value to be applied by the
|
||||
operation tag. The exact meaning of this value varies by tag. See
|
||||
Section ``Operation tags'' below.
|
||||
\end{description}
|
||||
It is perfectly legitimate to specify multiple dynamic unwind
|
||||
directives with the same \Var{when} value, if a particular instruction
|
||||
has a complex effect on the frame state.
|
||||
|
||||
Empty regions by definition contain no actual instructions and as such
|
||||
the directives are not tied to a particular instruction. By
|
||||
convention, the \Var{when} member should be set to 0, however.
|
||||
|
||||
There is no need for the dynamic unwind directives to appear
|
||||
in order of increasing \Var{when} values. If the directives happen to
|
||||
be sorted in that order, it may result in slightly faster execution,
|
||||
but a runtime code-generator should not go to extra lengths just to
|
||||
ensure that the directives are sorted.
|
||||
|
||||
IMPLEMENTATION NOTE: should \Prog{libunwind} implementations for
|
||||
certain architectures prefer the list of unwind directives to be
|
||||
sorted, it is recommended that such implementations first check
|
||||
whether the list happens to be sorted already and, if not, sort the
|
||||
directives explicitly before the first use. With this approach, the
|
||||
overhead of explicit sorting is only paid when there is a real benefit
|
||||
and if the runtime code-generator happens to generated sorted lists
|
||||
naturally, the performance penalty is limited to a simple O(N) check.
|
||||
|
||||
\subsection{Operations tags}
|
||||
|
||||
The possible operation tags are defined by enumeration type
|
||||
\Type{unw\_dyn\_operation\_t} which defines the following
|
||||
values:
|
||||
\begin{description}
|
||||
|
||||
\item[\Const{UNW\_DYN\_STOP}] Marks the end of the dynamic unwind
|
||||
directive list. All remaining entries in the \Var{op} array of the
|
||||
region-descriptor are ignored. This tag is guaranteed to have a
|
||||
value of 0.
|
||||
|
||||
\item[\Const{UNW\_DYN\_SAVE\_REG}] Marks an instruction which saves
|
||||
register \Var{reg} to register \Var{val}.
|
||||
|
||||
\item[\Const{UNW\_DYN\_SPILL\_FP\_REL}] Marks an instruction which
|
||||
spills register \Var{reg} to a frame-pointer-relative location. The
|
||||
frame-pointer-relative offset is given by the value stored in member
|
||||
\Var{val}. See the architecture-specific sections for a description
|
||||
of the stack frame layout.
|
||||
|
||||
\item[\Const{UNW\_DYN\_SPILL\_SP\_REL}] Marks an instruction which
|
||||
spills register \Var{reg} to a stack-pointer-relative location. The
|
||||
stack-pointer-relative offset is given by the value stored in member
|
||||
\Var{val}. See the architecture-specific sections for a description
|
||||
of the stack frame layout.
|
||||
|
||||
\item[\Const{UNW\_DYN\_ADD}] Marks an instruction which adds
|
||||
the constant value \Var{val} to register \Var{reg}. To add subtract
|
||||
a constant value, store the two's-complement of the value in
|
||||
\Var{val}. The set of registers that can be specified for this tag
|
||||
is described in the architecture-specific sections below.
|
||||
|
||||
\item[\Const{UNW\_DYN\_POP\_FRAMES}]
|
||||
|
||||
\item[\Const{UNW\_DYN\_LABEL\_STATE}]
|
||||
|
||||
\item[\Const{UNW\_DYN\_COPY\_STATE}]
|
||||
|
||||
\item[\Const{UNW\_DYN\_ALIAS}]
|
||||
|
||||
\end{description}
|
||||
|
||||
unw\_dyn\_op\_t
|
||||
|
||||
\_U\_dyn\_op\_save\_reg();
|
||||
\_U\_dyn\_op\_spill\_fp\_rel();
|
||||
\_U\_dyn\_op\_spill\_sp\_rel();
|
||||
\_U\_dyn\_op\_add();
|
||||
\_U\_dyn\_op\_pop\_frames();
|
||||
\_U\_dyn\_op\_label\_state();
|
||||
\_U\_dyn\_op\_copy\_state();
|
||||
\_U\_dyn\_op\_alias();
|
||||
\_U\_dyn\_op\_stop();
|
||||
|
||||
\section{IA-64 specifics}
|
||||
|
||||
- meaning of segbase member in table-info/table-remote-info format
|
||||
- format of table\_data in table-info/table-remote-info format
|
||||
- instruction size: each bundle is counted as 3 instructions, regardless
|
||||
of template (MLX)
|
||||
- describe stack-frame layout, especially with regards to sp-relative
|
||||
and fp-relative addressing
|
||||
- UNW\_DYN\_ADD can only add to ``sp'' (always a negative value); use
|
||||
POP\_FRAMES otherwise
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{\_U\_dyn\_register(3)},
|
||||
\SeeAlso{\_U\_dyn\_cancel(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,314 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "LIBUNWIND\-IA64" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
libunwind\-ia64
|
||||
\-\- IA\-64\-specific support in libunwind
|
||||
.PP
|
||||
.SH INTRODUCTION
|
||||
|
||||
.PP
|
||||
The IA\-64 version of libunwind
|
||||
uses a platform\-string of
|
||||
ia64
|
||||
and, at least in theory, should be able to support all
|
||||
operating systems adhering to the processor\-specific ABI defined for
|
||||
the Itanium Processor Family. This includes both little\-endian Linux
|
||||
and big\-endian HP\-UX. Furthermore, to make it possible for a single
|
||||
library to unwind both 32\- and 64\-bit targets, the type
|
||||
unw_word_t
|
||||
is always defined to be 64 bits wide (independent
|
||||
of the natural word\-size of the host). Having said that, the current
|
||||
implementation has been tested only with IA\-64 Linux.
|
||||
.PP
|
||||
When targeting IA\-64, the libunwind
|
||||
header file defines the
|
||||
macro UNW_TARGET_IA64
|
||||
as 1 and the macro UNW_TARGET
|
||||
as ``ia64\&'' (without the quotation marks). The former makes it
|
||||
possible for platform\-dependent unwind code to use
|
||||
conditional\-compilation to select an appropriate implementation. The
|
||||
latter is useful for stringification purposes and to construct
|
||||
target\-platform\-specific symbols.
|
||||
.PP
|
||||
One special feature of IA\-64 is the use of NaT bits to support
|
||||
speculative execution. Often, NaT bits are thought of as the ``65\-th
|
||||
bit\&'' of a general register. However, to make everything fit into
|
||||
64\-bit wide unw_word_t
|
||||
values, libunwind
|
||||
treats the
|
||||
NaT\-bits like separate boolean registers, whose 64\-bit value is either
|
||||
TRUE (non\-zero) or FALSE (zero).
|
||||
.PP
|
||||
.SH MACHINE\-STATE
|
||||
|
||||
.PP
|
||||
The machine\-state (set of registers) that is accessible through
|
||||
libunwind
|
||||
depends on the type of stack frame that a cursor
|
||||
points to. For normal frames, all ``preserved\&'' (callee\-saved)
|
||||
registers are accessible. For signal\-trampoline frames, all registers
|
||||
(including ``scratch\&'' (caller\-saved) registers) are accessible. Most
|
||||
applications do not have to worry a\-priori about which registers are
|
||||
accessible when. In case of doubt, it is always safe to \fItry\fP
|
||||
to
|
||||
access a register (via unw_get_reg()
|
||||
or
|
||||
unw_get_fpreg())
|
||||
and if the register isn\&'t accessible, the
|
||||
call will fail with a return\-value of \-UNW_EBADREG\&.
|
||||
.PP
|
||||
As a special exception to the above general rule, scratch registers
|
||||
r15\-r18
|
||||
are always accessible, even in normal
|
||||
frames. This makes it possible to pass arguments, e.g., to exception
|
||||
handlers.
|
||||
.PP
|
||||
For a detailed description of the IA\-64 register usage convention,
|
||||
please see the ``Itanium Software Conventions and Runtime Architecture
|
||||
Guide\&'', available at:
|
||||
.ce 100
|
||||
\fBhttp://www.intel.com/design/itanium/downloads/245358.htm\fP
|
||||
.ce 0
|
||||
|
||||
.PP
|
||||
.SH REGISTER NAMES
|
||||
|
||||
.PP
|
||||
The IA\-64\-version of libunwind
|
||||
defines three kinds of register
|
||||
name macros: frame\-register macros, normal register macros, and
|
||||
convenience macros. Below, we describe each kind in turn:
|
||||
.PP
|
||||
.SS FRAME\-REGISTER MACROS
|
||||
.PP
|
||||
Frame\-registers are special (pseudo) registers because they always
|
||||
have a valid value, even though sometimes they do not get saved
|
||||
explicitly (e.g., if a memory stack frame is 16 bytes in size, the
|
||||
previous stack\-pointer value can be calculated simply as
|
||||
sp+16,
|
||||
so there is no need to save the stack\-pointer
|
||||
explicitly). Moreover, the set of frame register values uniquely
|
||||
identifies a stack frame. The IA\-64 architecture defines two stacks
|
||||
(a memory and a register stack). Including the instruction\-pointer
|
||||
(IP), this means there are three frame registers:
|
||||
.TP
|
||||
UNW_IA64_IP:
|
||||
Contains the instruction pointer (IP, or
|
||||
``program counter\&'') of the current stack frame. Given this value,
|
||||
the remaining machine\-state corresponds to the register\-values that
|
||||
were present in the CPU when it was just about to execute the
|
||||
instruction pointed to by UNW_IA64_IP\&.
|
||||
Bits 0 and 1 of
|
||||
this frame\-register encode the slot number of the instruction.
|
||||
\fBNote:\fP
|
||||
Due to the way the call instruction works on IA\-64,
|
||||
the slot number is usually zero, but can be non\-zero, e.g., in the
|
||||
stack\-frame of a signal\-handler trampoline.
|
||||
.TP
|
||||
UNW_IA64_SP:
|
||||
Contains the (memory) stack\-pointer
|
||||
value (SP).
|
||||
.TP
|
||||
UNW_IA64_BSP:
|
||||
Contains the register backing\-store
|
||||
pointer (BSP). \fBNote:\fP
|
||||
the value in this register is equal
|
||||
to the contents of register ar.bsp
|
||||
at the time the
|
||||
instruction at UNW_IA64_IP
|
||||
was about to begin execution.
|
||||
.PP
|
||||
.SS NORMAL REGISTER MACROS
|
||||
.PP
|
||||
The following normal register name macros are available:
|
||||
.TP
|
||||
UNW_IA64_GR:
|
||||
The base\-index for general (integer)
|
||||
registers. Add an index in the range from 0..127 to get a
|
||||
particular general register. For example, to access r4,
|
||||
the index UNW_IA64_GR+4
|
||||
should be used.
|
||||
Registers r0
|
||||
and r1
|
||||
(gp)
|
||||
are read\-only,
|
||||
and any attempt to write them will result in an error
|
||||
(\-UNW_EREADONLYREG).
|
||||
Even though r1
|
||||
is
|
||||
read\-only, libunwind
|
||||
will automatically adjust its value if
|
||||
the instruction\-pointer (UNW_IA64_IP)
|
||||
is modified. For
|
||||
example, if UNW_IA64_IP
|
||||
is set to a value inside a
|
||||
function func(),
|
||||
then reading
|
||||
UNW_IA64_GR+1
|
||||
will return the global\-pointer
|
||||
value for this function.
|
||||
.TP
|
||||
UNW_IA64_NAT:
|
||||
The base\-index for the NaT bits of the
|
||||
general (integer) registers. A non\-zero value in these registers
|
||||
corresponds to a set NaT\-bit. Add an index in the range from 0..127
|
||||
to get a particular NaT\-bit register. For example, to access the
|
||||
NaT bit of r4,
|
||||
the index UNW_IA64_NAT+4
|
||||
should be used.
|
||||
.TP
|
||||
UNW_IA64_FR:
|
||||
The base\-index for floating\-point
|
||||
registers. Add an index in the range from 0..127 to get a
|
||||
particular floating\-point register. For example, to access
|
||||
f2,
|
||||
the index UNW_IA64_FR+2
|
||||
should be
|
||||
used. Registers f0
|
||||
and f1
|
||||
are read\-only, and any
|
||||
attempt to write to indices UNW_IA64_FR+0
|
||||
or
|
||||
UNW_IA64_FR+1
|
||||
will result in an error
|
||||
(\-UNW_EREADONLYREG).
|
||||
.TP
|
||||
UNW_IA64_AR:
|
||||
The base\-index for application
|
||||
registers. Add an index in the range from 0..127 to get a
|
||||
particular application register. For example, to access
|
||||
ar40,
|
||||
the index UNW_IA64_AR+40
|
||||
should be
|
||||
used. The IA\-64 architecture defines several application registers
|
||||
as ``reserved for future use\&''\&. Attempting to access such registers
|
||||
results in an error (\-UNW_EBADREG).
|
||||
.TP
|
||||
UNW_IA64_BR:
|
||||
The base\-index for branch registers.
|
||||
Add an index in the range from 0..7 to get a particular branch
|
||||
register. For example, to access b6,
|
||||
the index
|
||||
UNW_IA64_BR+6
|
||||
should be used.
|
||||
.TP
|
||||
UNW_IA64_PR:
|
||||
Contains the set of predicate registers.
|
||||
This 64\-bit wide register contains registers p0
|
||||
through
|
||||
p63
|
||||
in the ``broad\-side\&'' format. Just like with the
|
||||
``move predicates\&'' instruction, the registers are mapped as if
|
||||
CFM.rrb.pr
|
||||
were set to 0. Thus, in general the value of
|
||||
predicate register pN
|
||||
with N>=16 can be found
|
||||
in bit 16 + ((N\-16)+CFM.rrb.pr) % 48\&.
|
||||
.TP
|
||||
UNW_IA64_CFM:
|
||||
Contains the current\-frame\-mask
|
||||
register.
|
||||
.PP
|
||||
.SS CONVENIENCE MACROS
|
||||
.PP
|
||||
Convenience macros are simply aliases for certain frequently used
|
||||
registers:
|
||||
.TP
|
||||
UNW_IA64_GP:
|
||||
Alias for UNW_IA64_GR+1,
|
||||
the global\-pointer register.
|
||||
.TP
|
||||
UNW_IA64_TP:
|
||||
Alias for UNW_IA64_GR+13,
|
||||
the thread\-pointer register.
|
||||
.TP
|
||||
UNW_IA64_AR_RSC:
|
||||
Alias for UNW_IA64_GR+16,
|
||||
the register\-stack configuration register.
|
||||
.TP
|
||||
UNW_IA64_AR_BSP:
|
||||
Alias for
|
||||
UNW_IA64_GR+17\&.
|
||||
This register index accesses the
|
||||
value of register ar.bsp
|
||||
as of the time it was last saved
|
||||
explicitly. This is rarely what you want. Normally, you\&'ll want to
|
||||
use UNW_IA64_BSP
|
||||
instead.
|
||||
.TP
|
||||
UNW_IA64_AR_BSPSTORE:
|
||||
Alias for UNW_IA64_GR+18,
|
||||
the register\-backing store write pointer.
|
||||
.TP
|
||||
UNW_IA64_AR_RNAT:
|
||||
Alias for UNW_IA64_GR+19,
|
||||
the register\-backing store NaT\-collection register.
|
||||
.TP
|
||||
UNW_IA64_AR_CCV:
|
||||
Alias for UNW_IA64_GR+32,
|
||||
the compare\-and\-swap value register.
|
||||
.TP
|
||||
UNW_IA64_AR_CSD:
|
||||
Alias for UNW_IA64_GR+25,
|
||||
the compare\-and\-swap\-data register (used by 16\-byte atomic operations).
|
||||
.TP
|
||||
UNW_IA64_AR_UNAT:
|
||||
Alias for UNW_IA64_GR+36,
|
||||
the user NaT\-collection register.
|
||||
.TP
|
||||
UNW_IA64_AR_FPSR:
|
||||
Alias for UNW_IA64_GR+40,
|
||||
the floating\-point status (and control) register.
|
||||
.TP
|
||||
UNW_IA64_AR_PFS:
|
||||
Alias for UNW_IA64_GR+64,
|
||||
the previous frame\-state register.
|
||||
.TP
|
||||
UNW_IA64_AR_LC:
|
||||
Alias for UNW_IA64_GR+65
|
||||
the loop\-count register.
|
||||
.TP
|
||||
UNW_IA64_AR_EC:
|
||||
Alias for UNW_IA64_GR+66,
|
||||
the epilogue\-count register.
|
||||
.PP
|
||||
.SH THE UNWIND\-CONTEXT TYPE
|
||||
|
||||
.PP
|
||||
On IA\-64, unw_context_t
|
||||
is simply an alias for
|
||||
ucontext_t
|
||||
(as defined by the Single UNIX Spec). This implies
|
||||
that it is possible to initialize a value of this type not just with
|
||||
unw_getcontext(),
|
||||
but also with getcontext(),
|
||||
for
|
||||
example. However, since this is an IA\-64\-specific extension to
|
||||
libunwind,
|
||||
portable code should not rely on this equivalence.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,216 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{libunwind-ia64}{David Mosberger-Tang}{Programming Library}{IA-64-specific support in libunwind}libunwind-ia64 -- IA-64-specific support in libunwind
|
||||
\end{Name}
|
||||
|
||||
|
||||
\section{Introduction}
|
||||
|
||||
The IA-64 version of \Prog{libunwind} uses a platform-string of
|
||||
\texttt{ia64} and, at least in theory, should be able to support all
|
||||
operating systems adhering to the processor-specific ABI defined for
|
||||
the Itanium Processor Family. This includes both little-endian Linux
|
||||
and big-endian HP-UX. Furthermore, to make it possible for a single
|
||||
library to unwind both 32- and 64-bit targets, the type
|
||||
\Type{unw\_word\_t} is always defined to be 64 bits wide (independent
|
||||
of the natural word-size of the host). Having said that, the current
|
||||
implementation has been tested only with IA-64 Linux.
|
||||
|
||||
When targeting IA-64, the \Prog{libunwind} header file defines the
|
||||
macro \Const{UNW\_TARGET\_IA64} as 1 and the macro \Const{UNW\_TARGET}
|
||||
as ``ia64'' (without the quotation marks). The former makes it
|
||||
possible for platform-dependent unwind code to use
|
||||
conditional-compilation to select an appropriate implementation. The
|
||||
latter is useful for stringification purposes and to construct
|
||||
target-platform-specific symbols.
|
||||
|
||||
One special feature of IA-64 is the use of NaT bits to support
|
||||
speculative execution. Often, NaT bits are thought of as the ``65-th
|
||||
bit'' of a general register. However, to make everything fit into
|
||||
64-bit wide \Type{unw\_word\_t} values, \Prog{libunwind} treats the
|
||||
NaT-bits like separate boolean registers, whose 64-bit value is either
|
||||
TRUE (non-zero) or FALSE (zero).
|
||||
|
||||
|
||||
\section{Machine-State}
|
||||
|
||||
The machine-state (set of registers) that is accessible through
|
||||
\Prog{libunwind} depends on the type of stack frame that a cursor
|
||||
points to. For normal frames, all ``preserved'' (callee-saved)
|
||||
registers are accessible. For signal-trampoline frames, all registers
|
||||
(including ``scratch'' (caller-saved) registers) are accessible. Most
|
||||
applications do not have to worry a-priori about which registers are
|
||||
accessible when. In case of doubt, it is always safe to \emph{try} to
|
||||
access a register (via \Func{unw\_get\_reg}() or
|
||||
\Func{unw\_get\_fpreg}()) and if the register isn't accessible, the
|
||||
call will fail with a return-value of \texttt{-}\Const{UNW\_EBADREG}.
|
||||
|
||||
As a special exception to the above general rule, scratch registers
|
||||
\texttt{r15}-\texttt{r18} are always accessible, even in normal
|
||||
frames. This makes it possible to pass arguments, e.g., to exception
|
||||
handlers.
|
||||
|
||||
For a detailed description of the IA-64 register usage convention,
|
||||
please see the ``Itanium Software Conventions and Runtime Architecture
|
||||
Guide'', available at:
|
||||
\begin{center}
|
||||
\URL{http://www.intel.com/design/itanium/downloads/245358.htm}
|
||||
\end{center}
|
||||
|
||||
|
||||
\section{Register Names}
|
||||
|
||||
The IA-64-version of \Prog{libunwind} defines three kinds of register
|
||||
name macros: frame-register macros, normal register macros, and
|
||||
convenience macros. Below, we describe each kind in turn:
|
||||
|
||||
|
||||
\subsection{Frame-register Macros}
|
||||
|
||||
Frame-registers are special (pseudo) registers because they always
|
||||
have a valid value, even though sometimes they do not get saved
|
||||
explicitly (e.g., if a memory stack frame is 16 bytes in size, the
|
||||
previous stack-pointer value can be calculated simply as
|
||||
\texttt{sp+16}, so there is no need to save the stack-pointer
|
||||
explicitly). Moreover, the set of frame register values uniquely
|
||||
identifies a stack frame. The IA-64 architecture defines two stacks
|
||||
(a memory and a register stack). Including the instruction-pointer
|
||||
(IP), this means there are three frame registers:
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_IA64\_IP}:] Contains the instruction pointer (IP, or
|
||||
``program counter'') of the current stack frame. Given this value,
|
||||
the remaining machine-state corresponds to the register-values that
|
||||
were present in the CPU when it was just about to execute the
|
||||
instruction pointed to by \Const{UNW\_IA64\_IP}. Bits 0 and 1 of
|
||||
this frame-register encode the slot number of the instruction.
|
||||
\textbf{Note:} Due to the way the call instruction works on IA-64,
|
||||
the slot number is usually zero, but can be non-zero, e.g., in the
|
||||
stack-frame of a signal-handler trampoline.
|
||||
\item[\Const{UNW\_IA64\_SP}:] Contains the (memory) stack-pointer
|
||||
value (SP).
|
||||
\item[\Const{UNW\_IA64\_BSP}:] Contains the register backing-store
|
||||
pointer (BSP). \textbf{Note:} the value in this register is equal
|
||||
to the contents of register \texttt{ar.bsp} at the time the
|
||||
instruction at \Const{UNW\_IA64\_IP} was about to begin execution.
|
||||
\end{Description}
|
||||
|
||||
|
||||
\subsection{Normal Register Macros}
|
||||
|
||||
The following normal register name macros are available:
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_IA64\_GR}:] The base-index for general (integer)
|
||||
registers. Add an index in the range from 0..127 to get a
|
||||
particular general register. For example, to access \texttt{r4},
|
||||
the index \Const{UNW\_IA64\_GR}\texttt{+4} should be used.
|
||||
Registers \texttt{r0} and \texttt{r1} (\texttt{gp}) are read-only,
|
||||
and any attempt to write them will result in an error
|
||||
(\texttt{-}\Const{UNW\_EREADONLYREG}). Even though \texttt{r1} is
|
||||
read-only, \Prog{libunwind} will automatically adjust its value if
|
||||
the instruction-pointer (\Const{UNW\_IA64\_IP}) is modified. For
|
||||
example, if \Const{UNW\_IA64\_IP} is set to a value inside a
|
||||
function \Func{func}(), then reading
|
||||
\Const{UNW\_IA64\_GR}\texttt{+1} will return the global-pointer
|
||||
value for this function.
|
||||
\item[\Const{UNW\_IA64\_NAT}:] The base-index for the NaT bits of the
|
||||
general (integer) registers. A non-zero value in these registers
|
||||
corresponds to a set NaT-bit. Add an index in the range from 0..127
|
||||
to get a particular NaT-bit register. For example, to access the
|
||||
NaT bit of \texttt{r4}, the index \Const{UNW\_IA64\_NAT}\texttt{+4}
|
||||
should be used.
|
||||
\item[\Const{UNW\_IA64\_FR}:] The base-index for floating-point
|
||||
registers. Add an index in the range from 0..127 to get a
|
||||
particular floating-point register. For example, to access
|
||||
\texttt{f2}, the index \Const{UNW\_IA64\_FR}\texttt{+2} should be
|
||||
used. Registers \texttt{f0} and \texttt{f1} are read-only, and any
|
||||
attempt to write to indices \Const{UNW\_IA64\_FR}\texttt{+0} or
|
||||
\Const{UNW\_IA64\_FR}\texttt{+1} will result in an error
|
||||
(\texttt{-}\Const{UNW\_EREADONLYREG}).
|
||||
\item[\Const{UNW\_IA64\_AR}:] The base-index for application
|
||||
registers. Add an index in the range from 0..127 to get a
|
||||
particular application register. For example, to access
|
||||
\texttt{ar40}, the index \Const{UNW\_IA64\_AR}\texttt{+40} should be
|
||||
used. The IA-64 architecture defines several application registers
|
||||
as ``reserved for future use''. Attempting to access such registers
|
||||
results in an error (\texttt{-}\Const{UNW\_EBADREG}).
|
||||
\item[\Const{UNW\_IA64\_BR}:] The base-index for branch registers.
|
||||
Add an index in the range from 0..7 to get a particular branch
|
||||
register. For example, to access \texttt{b6}, the index
|
||||
\Const{UNW\_IA64\_BR}\texttt{+6} should be used.
|
||||
\item[\Const{UNW\_IA64\_PR}:] Contains the set of predicate registers.
|
||||
This 64-bit wide register contains registers \texttt{p0} through
|
||||
\texttt{p63} in the ``broad-side'' format. Just like with the
|
||||
``move predicates'' instruction, the registers are mapped as if
|
||||
\texttt{CFM.rrb.pr} were set to 0. Thus, in general the value of
|
||||
predicate register \texttt{p}$N$ with $N$>=16 can be found
|
||||
in bit \texttt{16 + (($N$-16)+CFM.rrb.pr) \% 48}.
|
||||
\item[\Const{UNW\_IA64\_CFM}:] Contains the current-frame-mask
|
||||
register.
|
||||
\end{Description}
|
||||
|
||||
|
||||
\subsection{Convenience Macros}
|
||||
|
||||
Convenience macros are simply aliases for certain frequently used
|
||||
registers:
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_IA64\_GP}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+1},
|
||||
the global-pointer register.
|
||||
\item[\Const{UNW\_IA64\_TP}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+13},
|
||||
the thread-pointer register.
|
||||
\item[\Const{UNW\_IA64\_AR\_RSC}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+16},
|
||||
the register-stack configuration register.
|
||||
\item[\Const{UNW\_IA64\_AR\_BSP}:] Alias for
|
||||
\Const{UNW\_IA64\_GR}\texttt{+17}. This register index accesses the
|
||||
value of register \texttt{ar.bsp} as of the time it was last saved
|
||||
explicitly. This is rarely what you want. Normally, you'll want to
|
||||
use \Const{UNW\_IA64\_BSP} instead.
|
||||
\item[\Const{UNW\_IA64\_AR\_BSPSTORE}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+18},
|
||||
the register-backing store write pointer.
|
||||
\item[\Const{UNW\_IA64\_AR\_RNAT}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+19},
|
||||
the register-backing store NaT-collection register.
|
||||
\item[\Const{UNW\_IA64\_AR\_CCV}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+32},
|
||||
the compare-and-swap value register.
|
||||
\item[\Const{UNW\_IA64\_AR\_CSD}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+25},
|
||||
the compare-and-swap-data register (used by 16-byte atomic operations).
|
||||
\item[\Const{UNW\_IA64\_AR\_UNAT}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+36},
|
||||
the user NaT-collection register.
|
||||
\item[\Const{UNW\_IA64\_AR\_FPSR}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+40},
|
||||
the floating-point status (and control) register.
|
||||
\item[\Const{UNW\_IA64\_AR\_PFS}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+64},
|
||||
the previous frame-state register.
|
||||
\item[\Const{UNW\_IA64\_AR\_LC}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+65}
|
||||
the loop-count register.
|
||||
\item[\Const{UNW\_IA64\_AR\_EC}:] Alias for \Const{UNW\_IA64\_GR}\texttt{+66},
|
||||
the epilogue-count register.
|
||||
\end{Description}
|
||||
|
||||
|
||||
\section{The Unwind-Context Type}
|
||||
|
||||
On IA-64, \Type{unw\_context\_t} is simply an alias for
|
||||
\Type{ucontext\_t} (as defined by the Single UNIX Spec). This implies
|
||||
that it is possible to initialize a value of this type not just with
|
||||
\Func{unw\_getcontext}(), but also with \Func{getcontext}(), for
|
||||
example. However, since this is an IA-64-specific extension to
|
||||
\Prog{libunwind}, portable code should not rely on this equivalence.
|
||||
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,220 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "LIBUNWIND\-PTRACE" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
libunwind\-ptrace
|
||||
\-\- ptrace() support in libunwind
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind\-ptrace.h>
|
||||
.br
|
||||
.PP
|
||||
unw_accessors_t
|
||||
_UPT_accessors;
|
||||
.br
|
||||
.PP
|
||||
void *_UPT_create(pid_t);
|
||||
.br
|
||||
void
|
||||
_UPT_destroy(void *);
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
_UPT_find_proc_info(unw_addr_space_t,
|
||||
unw_word_t,
|
||||
unw_proc_info_t *,
|
||||
int,
|
||||
void *);
|
||||
.br
|
||||
void
|
||||
_UPT_put_unwind_info(unw_addr_space_t,
|
||||
unw_proc_info_t *,
|
||||
void *);
|
||||
.br
|
||||
int
|
||||
_UPT_get_dyn_info_list_addr(unw_addr_space_t,
|
||||
unw_word_t *,
|
||||
void *);
|
||||
.br
|
||||
int
|
||||
_UPT_access_mem(unw_addr_space_t,
|
||||
unw_word_t,
|
||||
unw_word_t *,
|
||||
int,
|
||||
void *);
|
||||
.br
|
||||
int
|
||||
_UPT_access_reg(unw_addr_space_t,
|
||||
unw_regnum_t,
|
||||
unw_word_t *,
|
||||
int,
|
||||
void *);
|
||||
.br
|
||||
int
|
||||
_UPT_access_fpreg(unw_addr_space_t,
|
||||
unw_regnum_t,
|
||||
unw_fpreg_t *,
|
||||
int,
|
||||
void *);
|
||||
.br
|
||||
int
|
||||
_UPT_get_proc_name(unw_addr_space_t,
|
||||
unw_word_t,
|
||||
char *,
|
||||
size_t,
|
||||
unw_word_t *,
|
||||
void *);
|
||||
.br
|
||||
int
|
||||
_UPT_resume(unw_addr_space_t,
|
||||
unw_cursor_t *,
|
||||
void *);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The ptrace(2)
|
||||
system\-call makes it possible for a process to
|
||||
gain access to the machine\-state and virtual memory of \fIanother\fP
|
||||
process. With the right set of call\-back routines, it is therefore
|
||||
possible to hook up libunwind
|
||||
to another process via
|
||||
ptrace(2).
|
||||
While it\&'s not very difficult to do so directly,
|
||||
libunwind
|
||||
further facilitates this task by providing
|
||||
ready\-to\-use callbacks for this purpose. The routines and variables
|
||||
implementing this facility use a name\-prefix of _UPT,
|
||||
which is
|
||||
stands for ``unwind\-via\-ptrace\&''\&.
|
||||
.PP
|
||||
An application that wants to use the _UPT\-facility
|
||||
first needs
|
||||
to create a new libunwind
|
||||
address\-space that represents the
|
||||
target process. This is done by calling
|
||||
unw_create_addr_space().
|
||||
In many cases, the application
|
||||
will simply want to pass the address of _UPT_accessors
|
||||
as the
|
||||
first argument to this routine. Doing so will ensure that
|
||||
libunwind
|
||||
will be able to properly unwind the target process.
|
||||
However, in special circumstances, an application may prefer to use
|
||||
only portions of the _UPT\-facility.
|
||||
For this reason, the
|
||||
individual callback routines (_UPT_find_proc_info(),
|
||||
_UPT_put_unwind_info(),
|
||||
etc.) are also available for direct
|
||||
use. Of course, the addresses of these routines could also be picked
|
||||
up from _UPT_accessors,
|
||||
but doing so would prevent static
|
||||
initialization. Also, when using _UPT_accessors,
|
||||
\fIall\fP
|
||||
the callback routines will be linked into the application, even if
|
||||
they are never actually called.
|
||||
.PP
|
||||
Next, the application can turn on ptrace\-mode on the target process,
|
||||
either by forking a new process, invoking PTRACE_TRACEME,
|
||||
and
|
||||
then starting the target program (via execve(2)),
|
||||
or by
|
||||
directly attaching to an already running process (via
|
||||
PTRACE_ATTACH).
|
||||
Either way, once the process\-ID (pid) of the
|
||||
target process is known, a _UPT\-info\-structure
|
||||
can be created
|
||||
by calling _UPT_create(),
|
||||
passing the pid of the target process
|
||||
as the only argument. The returned void\-pointer then needs to be
|
||||
passed as the ``argument\&'' pointer (third argument) to
|
||||
unw_init_remote().
|
||||
.PP
|
||||
The _UPT_resume()
|
||||
routine can be used to resume execution of
|
||||
the target process. It simply invokes ptrace(2)
|
||||
with a command
|
||||
value of PTRACE_CONT\&.
|
||||
.PP
|
||||
When the application is done using libunwind
|
||||
on the target
|
||||
process, _UPT_destroy()
|
||||
needs to be called, passing it the
|
||||
void\-pointer that was returned by the corresponding call to
|
||||
_UPT_create().
|
||||
This ensures that all memory and other
|
||||
resources are freed up.
|
||||
.PP
|
||||
.SH AVAILABILITY
|
||||
|
||||
.PP
|
||||
Since ptrace(2)
|
||||
works within a single machine only, the
|
||||
_UPT\-facility
|
||||
by definition is not available in
|
||||
libunwind\-versions
|
||||
configured for cross\-unwinding.
|
||||
.PP
|
||||
.SH THREAD SAFETY
|
||||
|
||||
.PP
|
||||
The _UPT\-facility
|
||||
assumes that a single _UPT\-info
|
||||
structure is never shared between threads. Because of this, no
|
||||
explicit locking is used. As long as only one thread uses
|
||||
a _UPT\-info
|
||||
structure at any given time, this facility
|
||||
is thread\-safe.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
_UPT_create()
|
||||
may return a NULL
|
||||
pointer if it fails
|
||||
to create the _UPT\-info\-structure
|
||||
for any reason. For the
|
||||
current implementation, the only reason this call may fail is when the
|
||||
system is out of memory.
|
||||
.PP
|
||||
.SH FILES
|
||||
|
||||
.PP
|
||||
.TP
|
||||
libunwind\-ptrace.h
|
||||
Headerfile to include when using the
|
||||
interface defined by this library.
|
||||
.TP
|
||||
\fB\-l\fPunwind\-ptrace \fB\-l\fPunwind\-generic
|
||||
Linker\-switches to add when building a program that uses the
|
||||
functions defined by this library.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
execve(2),
|
||||
libunwind(3),
|
||||
ptrace(2)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,134 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{libunwind-ptrace}{David Mosberger-Tang}{Programming Library}{ptrace() support in libunwind}libunwind-ptrace -- ptrace() support in libunwind
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind-ptrace.h$>$}\\
|
||||
|
||||
\noindent
|
||||
\Type{unw\_accessors\_t} \Var{\_UPT\_accessors};\\
|
||||
|
||||
\Type{void~*}\Func{\_UPT\_create}(\Type{pid\_t});\\
|
||||
\noindent
|
||||
\Type{void} \Func{\_UPT\_destroy}(\Type{void~*});\\
|
||||
|
||||
\noindent
|
||||
\Type{int} \Func{\_UPT\_find\_proc\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_proc\_info\_t~*}, \Type{int}, \Type{void~*});\\
|
||||
\noindent
|
||||
\Type{void} \Func{\_UPT\_put\_unwind\_info}(\Type{unw\_addr\_space\_t}, \Type{unw\_proc\_info\_t~*}, \Type{void~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{\_UPT\_get\_dyn\_info\_list\_addr}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{\_UPT\_access\_mem}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{\_UPT\_access\_reg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_word\_t~*}, \Type{int}, \Type{void~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{\_UPT\_access\_fpreg}(\Type{unw\_addr\_space\_t}, \Type{unw\_regnum\_t}, \Type{unw\_fpreg\_t~*}, \Type{int}, \Type{void~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{\_UPT\_get\_proc\_name}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{char~*}, \Type{size\_t}, \Type{unw\_word\_t~*}, \Type{void~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{\_UPT\_resume}(\Type{unw\_addr\_space\_t}, \Type{unw\_cursor\_t~*}, \Type{void~*});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{ptrace}(2) system-call makes it possible for a process to
|
||||
gain access to the machine-state and virtual memory of \emph{another}
|
||||
process. With the right set of call-back routines, it is therefore
|
||||
possible to hook up \Prog{libunwind} to another process via
|
||||
\Func{ptrace}(2). While it's not very difficult to do so directly,
|
||||
\Prog{libunwind} further facilitates this task by providing
|
||||
ready-to-use callbacks for this purpose. The routines and variables
|
||||
implementing this facility use a name-prefix of \Func{\_UPT}, which is
|
||||
stands for ``unwind-via-ptrace''.
|
||||
|
||||
An application that wants to use the \Func{\_UPT}-facility first needs
|
||||
to create a new \Prog{libunwind} address-space that represents the
|
||||
target process. This is done by calling
|
||||
\Func{unw\_create\_addr\_space}(). In many cases, the application
|
||||
will simply want to pass the address of \Var{\_UPT\_accessors} as the
|
||||
first argument to this routine. Doing so will ensure that
|
||||
\Prog{libunwind} will be able to properly unwind the target process.
|
||||
However, in special circumstances, an application may prefer to use
|
||||
only portions of the \Prog{\_UPT}-facility. For this reason, the
|
||||
individual callback routines (\Func{\_UPT\_find\_proc\_info}(),
|
||||
\Func{\_UPT\_put\_unwind\_info}(), etc.) are also available for direct
|
||||
use. Of course, the addresses of these routines could also be picked
|
||||
up from \Var{\_UPT\_accessors}, but doing so would prevent static
|
||||
initialization. Also, when using \Var{\_UPT\_accessors}, \emph{all}
|
||||
the callback routines will be linked into the application, even if
|
||||
they are never actually called.
|
||||
|
||||
Next, the application can turn on ptrace-mode on the target process,
|
||||
either by forking a new process, invoking \Const{PTRACE\_TRACEME}, and
|
||||
then starting the target program (via \Func{execve}(2)), or by
|
||||
directly attaching to an already running process (via
|
||||
\Const{PTRACE\_ATTACH}). Either way, once the process-ID (pid) of the
|
||||
target process is known, a \Prog{\_UPT}-info-structure can be created
|
||||
by calling \Func{\_UPT\_create}(), passing the pid of the target process
|
||||
as the only argument. The returned void-pointer then needs to be
|
||||
passed as the ``argument'' pointer (third argument) to
|
||||
\Func{unw\_init\_remote}().
|
||||
|
||||
The \Func{\_UPT\_resume}() routine can be used to resume execution of
|
||||
the target process. It simply invokes \Func{ptrace}(2) with a command
|
||||
value of \Const{PTRACE\_CONT}.
|
||||
|
||||
When the application is done using \Prog{libunwind} on the target
|
||||
process, \Func{\_UPT\_destroy}() needs to be called, passing it the
|
||||
void-pointer that was returned by the corresponding call to
|
||||
\Func{\_UPT\_create}(). This ensures that all memory and other
|
||||
resources are freed up.
|
||||
|
||||
\section{Availability}
|
||||
|
||||
Since \Func{ptrace}(2) works within a single machine only, the
|
||||
\Prog{\_UPT}-facility by definition is not available in
|
||||
\Prog{libunwind}-versions configured for cross-unwinding.
|
||||
|
||||
\section{Thread Safety}
|
||||
|
||||
The \Prog{\_UPT}-facility assumes that a single \Prog{\_UPT}-info
|
||||
structure is never shared between threads. Because of this, no
|
||||
explicit locking is used. As long as only one thread uses
|
||||
a \Prog{\_UPT}-info structure at any given time, this facility
|
||||
is thread-safe.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
\Func{\_UPT\_create}() may return a \Const{NULL} pointer if it fails
|
||||
to create the \Prog{\_UPT}-info-structure for any reason. For the
|
||||
current implementation, the only reason this call may fail is when the
|
||||
system is out of memory.
|
||||
|
||||
\section{Files}
|
||||
|
||||
\begin{Description}
|
||||
\item[\File{libunwind-ptrace.h}] Headerfile to include when using the
|
||||
interface defined by this library.
|
||||
\item[\Opt{-l}\File{unwind-ptrace} \Opt{-l}\File{unwind-generic}]
|
||||
Linker-switches to add when building a program that uses the
|
||||
functions defined by this library.
|
||||
\end{Description}
|
||||
|
||||
\section{See Also}
|
||||
|
||||
execve(2),
|
||||
\SeeAlso{libunwind(3)},
|
||||
ptrace(2)
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,132 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "LIBUNWIND\-SETJMP" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
libunwind\-setjmp
|
||||
\-\- libunwind\-based non\-local gotos
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <setjmp.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
setjmp(jmp_buf env);
|
||||
.br
|
||||
void
|
||||
longjmp(jmp_buf env,
|
||||
int val);
|
||||
.br
|
||||
int
|
||||
_setjmp(jmp_buf env);
|
||||
.br
|
||||
void
|
||||
_longjmp(jmp_buf env,
|
||||
int val);
|
||||
.br
|
||||
int
|
||||
sigsetjmp(sigjmp_buf env,
|
||||
int savemask);
|
||||
.br
|
||||
void
|
||||
siglongjmp(sigjmp_buf env,
|
||||
int val);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unwind\-setjmp
|
||||
library offers a libunwind\-based
|
||||
implementation of non\-local gotos. This implementation is intended to
|
||||
be a drop\-in replacement for the normal, system\-provided routines of
|
||||
the same name. The main advantage of using the unwind\-setjmp
|
||||
library is that setting up a non\-local goto via one of the
|
||||
setjmp()
|
||||
routines is very fast. Typically, just 2 or 3 words
|
||||
need to be saved in the jump\-buffer (plus one call to
|
||||
sigprocmask(2),
|
||||
in the case of sigsetjmp).
|
||||
On the
|
||||
other hand, executing a non\-local goto by calling one of the
|
||||
longjmp()
|
||||
routines tends to be much slower than with the
|
||||
system\-provided routines. In fact, the time spent on a
|
||||
longjmp()
|
||||
will be proportional to the number of call frames
|
||||
that exist between the points where setjmp()
|
||||
and
|
||||
longjmp()
|
||||
were called. For this reason, the
|
||||
unwind\-setjmp
|
||||
library is beneficial primarily in applications
|
||||
that frequently call setjmp()
|
||||
but only rarely call
|
||||
longjmp().
|
||||
.PP
|
||||
.SH CAVEATS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
.B *
|
||||
The correct operation of this library depends on the presence of
|
||||
correct unwind information. On newer platforms, this is rarely an
|
||||
issue. On older platforms, care needs to be taken to
|
||||
ensure that each of the functions whose stack frames may have to be
|
||||
unwound during a longjmp()
|
||||
have correct unwind information
|
||||
(on those platforms, there is usually a compiler\-switch, such as
|
||||
\fB\-funwind\-tables\fP,
|
||||
to request the generation of unwind
|
||||
information).
|
||||
.TP
|
||||
.B *
|
||||
The contents of jmp_buf and sigjmp_buf as setup
|
||||
and used by these routines is completely different from the ones
|
||||
used by the system\-provided routines. Thus, a jump\-buffer created
|
||||
by the libunwind\-based setjmp()/_setjmp
|
||||
may only be
|
||||
used in a call to the libunwind\-based
|
||||
longjmp()/_longjmp().
|
||||
The analogous applies for
|
||||
sigjmp_buf
|
||||
with sigsetjmp()
|
||||
and siglongjmp().
|
||||
.PP
|
||||
.SH FILES
|
||||
|
||||
.PP
|
||||
.TP
|
||||
\fB\-l\fPunwind\-setjmp
|
||||
The library an application should
|
||||
be linked against to ensure it uses the libunwind\-based non\-local
|
||||
goto routines.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
setjmp(3), longjmp(3),
|
||||
_setjmp(3), _longjmp(3),
|
||||
sigsetjmp(3), siglongjmp(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,87 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{libunwind-setjmp}{David Mosberger-Tang}{Programming Library}{libunwind-based non-local gotos}libunwind-setjmp -- libunwind-based non-local gotos
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$setjmp.h$>$}\\
|
||||
|
||||
\noindent
|
||||
\Type{int} \Func{setjmp}(\Type{jmp\_buf}~\Var{env});\\
|
||||
\Type{void} \Func{longjmp}(\Type{jmp\_buf}~\Var{env}, \Type{int}~\Var{val});\\
|
||||
\Type{int} \Func{\_setjmp}(\Type{jmp\_buf}~\Var{env});\\
|
||||
\Type{void} \Func{\_longjmp}(\Type{jmp\_buf}~\Var{env}, \Type{int}~\Var{val});\\
|
||||
\Type{int} \Func{sigsetjmp}(\Type{sigjmp\_buf}~\Var{env}, \Type{int}~\Var{savemask});\\
|
||||
\Type{void} \Func{siglongjmp}(\Type{sigjmp\_buf}~\Var{env}, \Type{int}~\Var{val});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Prog{unwind-setjmp} library offers a \Prog{libunwind}-based
|
||||
implementation of non-local gotos. This implementation is intended to
|
||||
be a drop-in replacement for the normal, system-provided routines of
|
||||
the same name. The main advantage of using the \Prog{unwind-setjmp}
|
||||
library is that setting up a non-local goto via one of the
|
||||
\Func{setjmp}() routines is very fast. Typically, just 2 or 3 words
|
||||
need to be saved in the jump-buffer (plus one call to
|
||||
\Func{sigprocmask}(2), in the case of \Func{sigsetjmp}). On the
|
||||
other hand, executing a non-local goto by calling one of the
|
||||
\Func{longjmp}() routines tends to be much slower than with the
|
||||
system-provided routines. In fact, the time spent on a
|
||||
\Func{longjmp}() will be proportional to the number of call frames
|
||||
that exist between the points where \Func{setjmp}() and
|
||||
\Func{longjmp}() were called. For this reason, the
|
||||
\Prog{unwind-setjmp} library is beneficial primarily in applications
|
||||
that frequently call \Func{setjmp}() but only rarely call
|
||||
\Func{longjmp}().
|
||||
|
||||
\section{Caveats}
|
||||
|
||||
\begin{itemize}
|
||||
\item The correct operation of this library depends on the presence of
|
||||
correct unwind information. On newer platforms, this is rarely an
|
||||
issue. On older platforms, care needs to be taken to
|
||||
ensure that each of the functions whose stack frames may have to be
|
||||
unwound during a \Func{longjmp}() have correct unwind information
|
||||
(on those platforms, there is usually a compiler-switch, such as
|
||||
\Opt{-funwind-tables}, to request the generation of unwind
|
||||
information).
|
||||
\item The contents of \Type{jmp\_buf} and \Type{sigjmp\_buf} as setup
|
||||
and used by these routines is completely different from the ones
|
||||
used by the system-provided routines. Thus, a jump-buffer created
|
||||
by the libunwind-based \Func{setjmp}()/\Func{\_setjmp} may only be
|
||||
used in a call to the libunwind-based
|
||||
\Func{longjmp}()/\Func{\_longjmp}(). The analogous applies for
|
||||
\Type{sigjmp\_buf} with \Func{sigsetjmp}() and \Func{siglongjmp}().
|
||||
\end{itemize}
|
||||
|
||||
\section{Files}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Opt{-l}\File{unwind-setjmp}] The library an application should
|
||||
be linked against to ensure it uses the libunwind-based non-local
|
||||
goto routines.
|
||||
\end{Description}
|
||||
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
setjmp(3), longjmp(3),
|
||||
\_setjmp(3), \_longjmp(3),
|
||||
sigsetjmp(3), siglongjmp(3)
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,500 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:43 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "LIBUNWIND" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
libunwind
|
||||
\-\- a (mostly) platform\-independent unwind API
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_getcontext(unw_context_t *);
|
||||
.br
|
||||
int
|
||||
unw_init_local(unw_cursor_t *,
|
||||
unw_context_t *);
|
||||
.br
|
||||
int
|
||||
unw_init_remote(unw_cursor_t *,
|
||||
unw_addr_space_t,
|
||||
void *);
|
||||
.br
|
||||
int
|
||||
unw_step(unw_cursor_t *);
|
||||
.br
|
||||
int
|
||||
unw_get_reg(unw_cursor_t *,
|
||||
unw_regnum_t,
|
||||
unw_word_t *);
|
||||
.br
|
||||
int
|
||||
unw_get_fpreg(unw_cursor_t *,
|
||||
unw_regnum_t,
|
||||
unw_fpreg_t *);
|
||||
.br
|
||||
int
|
||||
unw_set_reg(unw_cursor_t *,
|
||||
unw_regnum_t,
|
||||
unw_word_t);
|
||||
.br
|
||||
int
|
||||
unw_set_fpreg(unw_cursor_t *,
|
||||
unw_regnum_t,
|
||||
unw_fpreg_t);
|
||||
.br
|
||||
int
|
||||
unw_resume(unw_cursor_t *);
|
||||
.br
|
||||
.PP
|
||||
unw_addr_space_t
|
||||
unw_local_addr_space;
|
||||
.br
|
||||
unw_addr_space_t
|
||||
unw_create_addr_space(unw_accessors_t,
|
||||
int);
|
||||
.br
|
||||
void
|
||||
unw_destroy_addr_space(unw_addr_space_t);
|
||||
.br
|
||||
unw_accessors_t
|
||||
unw_get_accessors(unw_addr_space_t);
|
||||
.br
|
||||
void
|
||||
unw_flush_cache(unw_addr_space_t,
|
||||
unw_word_t,
|
||||
unw_word_t);
|
||||
.br
|
||||
int
|
||||
unw_set_caching_policy(unw_addr_space_t,
|
||||
unw_caching_policy_t);
|
||||
.br
|
||||
.PP
|
||||
const char *unw_regname(unw_regnum_t);
|
||||
.br
|
||||
int
|
||||
unw_get_proc_info(unw_cursor_t *,
|
||||
unw_proc_info_t *);
|
||||
.br
|
||||
int
|
||||
unw_get_save_loc(unw_cursor_t *,
|
||||
int,
|
||||
unw_save_loc_t *);
|
||||
.br
|
||||
int
|
||||
unw_is_fpreg(unw_regnum_t);
|
||||
.br
|
||||
int
|
||||
unw_is_signal_frame(unw_cursor_t *);
|
||||
.br
|
||||
int
|
||||
unw_get_proc_name(unw_cursor_t *,
|
||||
char *,
|
||||
size_t,
|
||||
unw_word_t *);
|
||||
.br
|
||||
.PP
|
||||
void
|
||||
_U_dyn_register(unw_dyn_info_t *);
|
||||
.br
|
||||
void
|
||||
_U_dyn_cancel(unw_dyn_info_t *);
|
||||
.br
|
||||
.PP
|
||||
.SH LOCAL UNWINDING
|
||||
|
||||
.PP
|
||||
Libunwind
|
||||
is very easy to use when unwinding a stack from
|
||||
within a running program. This is called \fIlocal\fP
|
||||
unwinding. Say
|
||||
you want to unwind the stack while executing in some function
|
||||
F().
|
||||
In this function, you would call unw_getcontext()
|
||||
to get a snapshot of the CPU registers (machine\-state). Then you
|
||||
initialize an \fIunwind cursor\fP
|
||||
based on this snapshot. This is
|
||||
done with a call to unw_init_local().
|
||||
The cursor now points
|
||||
to the current frame, that is, the stack frame that corresponds to the
|
||||
current activation of function F().
|
||||
The unwind cursor can then
|
||||
be moved ``up\&'' (towards earlier stack frames) by calling
|
||||
unw_step().
|
||||
By repeatedly calling this routine, you can
|
||||
uncover the entire call\-chain that led to the activation of function
|
||||
F().
|
||||
A positive return value from unw_step()
|
||||
indicates
|
||||
that there are more frames in the chain, zero indicates that the end
|
||||
of the chain has been reached, and any negative value indicates that
|
||||
some sort of error has occurred.
|
||||
.PP
|
||||
While it is not possible to directly move the unwind cursor in the
|
||||
``down\&'' direction (towards newer stack frames), this effect can be
|
||||
achieved by making copies of an unwind cursor. For example, a program
|
||||
that sometimes has to move ``down\&'' by one stack frame could maintain
|
||||
two cursor variables: ``curr\&''
|
||||
and ``prev\&''\&.
|
||||
The former
|
||||
would be used as the current cursor and prev
|
||||
would be maintained
|
||||
as the ``previous frame\&'' cursor by copying the contents of curr
|
||||
to prev
|
||||
right before calling unw_step().
|
||||
With this
|
||||
approach, the program could move one step ``down\&'' simply by copying
|
||||
back prev
|
||||
to curr
|
||||
whenever that is necessary. In the most
|
||||
extreme case, a program could maintain a separate cursor for each call
|
||||
frame and that way it could move up and down the callframe\-chain at
|
||||
will.
|
||||
.PP
|
||||
Given an unwind cursor, it is possible to read and write the CPU
|
||||
registers that were preserved for the current stack frame (as
|
||||
identified by the cursor). Libunwind
|
||||
provides several routines
|
||||
for this purpose: unw_get_reg()
|
||||
reads an integer (general)
|
||||
register, unw_get_fpreg()
|
||||
reads a floating\-point register,
|
||||
unw_set_reg()
|
||||
writes an integer register, and
|
||||
unw_set_fpreg()
|
||||
writes a floating\-point register. Note that,
|
||||
by definition, only the \fIpreserved\fP
|
||||
machine state can be accessed
|
||||
during an unwind operation. Normally, this state consists of the
|
||||
\fIcallee\-saved\fP
|
||||
(``preserved\&'') registers. However, in some
|
||||
special circumstances (e.g., in a signal handler trampoline), even the
|
||||
\fIcaller\-saved\fP
|
||||
(``scratch\&'') registers are preserved in the stack
|
||||
frame and, in those cases, libunwind
|
||||
will grant access to them
|
||||
as well. The exact set of registers that can be accessed via the
|
||||
cursor depends, of course, on the platform. However, there are two
|
||||
registers that can be read on all platforms: the instruction pointer
|
||||
(IP), sometimes also known as the ``program counter\&'', and the stack
|
||||
pointer (SP). In libunwind,
|
||||
these registers are identified by
|
||||
the macros UNW_REG_IP
|
||||
and UNW_REG_SP,
|
||||
respectively.
|
||||
.PP
|
||||
Besides just moving the unwind cursor and reading/writing saved
|
||||
registers, libunwind
|
||||
also provides the ability to resume
|
||||
execution at an arbitrary stack frame. As you might guess, this is
|
||||
useful for implementing non\-local gotos and the exception handling
|
||||
needed by some high\-level languages such as Java. Resuming execution
|
||||
with a particular stack frame simply requires calling
|
||||
unw_resume()
|
||||
and passing the cursor identifying the target
|
||||
frame as the only argument.
|
||||
.PP
|
||||
Normally, libunwind
|
||||
supports both local and remote unwinding
|
||||
(the latter will be explained in the next section). However, if you
|
||||
tell libunwind that your program only needs local unwinding, then a
|
||||
special implementation can be selected which may run much faster than
|
||||
the generic implementation which supports both kinds of unwinding. To
|
||||
select this optimized version, simply define the macro
|
||||
UNW_LOCAL_ONLY
|
||||
before including the headerfile
|
||||
<libunwind.h>\&.
|
||||
It is perfectly OK for a single program to
|
||||
employ both local\-only and generic unwinding. That is, whether or not
|
||||
UNW_LOCAL_ONLY
|
||||
is defined is a choice that each source\-file
|
||||
(compilation\-unit) can make on its own. Independent of the setting(s)
|
||||
of UNW_LOCAL_ONLY,
|
||||
you\&'ll always link the same library into
|
||||
the program (normally \fB\-l\fPunwind).
|
||||
Furthermore, the
|
||||
portion of libunwind
|
||||
that manages unwind\-info for dynamically
|
||||
generated code is not affected by the setting of
|
||||
UNW_LOCAL_ONLY\&.
|
||||
.PP
|
||||
If we put all of the above together, here is how we could use
|
||||
libunwind
|
||||
to write a function ``show_backtrace()\&''
|
||||
which prints a classic stack trace:
|
||||
.PP
|
||||
.Vb
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
|
||||
void show_backtrace (void) {
|
||||
unw_cursor_t cursor; unw_context_t uc;
|
||||
unw_word_t ip, sp;
|
||||
|
||||
unw_getcontext(&uc);
|
||||
unw_init_local(&cursor, &uc);
|
||||
while (unw_step(&cursor) > 0) {
|
||||
unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
||||
unw_get_reg(&cursor, UNW_REG_SP, &sp);
|
||||
printf ("ip = %lx, sp = %lx\\n", (long) ip, (long) sp);
|
||||
}
|
||||
}
|
||||
.Ve
|
||||
.PP
|
||||
.SH REMOTE UNWINDING
|
||||
|
||||
.PP
|
||||
Libunwind
|
||||
can also be used to unwind a stack in a ``remote\&''
|
||||
process. Here, ``remote\&'' may mean another process on the same
|
||||
machine or even a process on a completely different machine from the
|
||||
one that is running libunwind\&.
|
||||
Remote unwinding is typically
|
||||
used by debuggers and instruction\-set simulators, for example.
|
||||
.PP
|
||||
Before you can unwind a remote process, you need to create a new
|
||||
address\-space object for that process. This is achieved with the
|
||||
unw_create_addr_space()
|
||||
routine. The routine takes two
|
||||
arguments: a pointer to a set of \fIaccessor\fP
|
||||
routines and an
|
||||
integer that specifies the byte\-order of the target process. The
|
||||
accessor routines provide libunwind
|
||||
with the means to
|
||||
communicate with the remote process. In particular, there are
|
||||
callbacks to read and write the process\&'s memory, its registers, and
|
||||
to access unwind information which may be needed by libunwind\&.
|
||||
.PP
|
||||
With the address space created, unwinding can be initiated by a call
|
||||
to unw_init_remote().
|
||||
This routine is very similar to
|
||||
unw_init_local(),
|
||||
except that it takes an address\-space
|
||||
object and an opaque pointer as arguments. The routine uses these
|
||||
arguments to fetch the initial machine state. Libunwind
|
||||
never
|
||||
uses the opaque pointer on its own, but instead just passes it on to
|
||||
the accessor (callback) routines. Typically, this pointer is used to
|
||||
select, e.g., the thread within a process that is to be unwound.
|
||||
.PP
|
||||
Once a cursor has been initialized with unw_init_remote(),
|
||||
unwinding works exactly like in the local case. That is, you can use
|
||||
unw_step()
|
||||
to move ``up\&'' in the call\-chain, read and write
|
||||
registers, or resume execution at a particular stack frame by calling
|
||||
unw_resume\&.
|
||||
.PP
|
||||
.SH CROSS\-PLATFORM AND MULTI\-PLATFORM UNWINDING
|
||||
|
||||
.PP
|
||||
Libunwind
|
||||
has been designed to enable unwinding across
|
||||
platforms (architectures). Indeed, a single program can use
|
||||
libunwind
|
||||
to unwind an arbitrary number of target platforms,
|
||||
all at the same time!
|
||||
.PP
|
||||
We call the machine that is running libunwind
|
||||
the \fIhost\fP
|
||||
and the machine that is running the process being unwound the
|
||||
\fItarget\fP\&.
|
||||
If the host and the target platform are the same, we
|
||||
call it \fInative\fP
|
||||
unwinding. If they differ, we call it
|
||||
\fIcross\-platform\fP
|
||||
unwinding.
|
||||
.PP
|
||||
The principle behind supporting native, cross\-platform, and
|
||||
multi\-platform unwinding is very simple: for native unwinding, a
|
||||
program includes <libunwind.h>
|
||||
and uses the linker switch
|
||||
\fB\-l\fPunwind\&.
|
||||
For cross\-platform unwinding, a program
|
||||
includes <libunwind\-PLAT\&.h>
|
||||
and uses the linker
|
||||
switch \fB\-l\fPunwind\-PLAT,
|
||||
where PLAT
|
||||
is the name
|
||||
of the target platform (e.g., ia64
|
||||
for IA\-64, hppa\-elf
|
||||
for ELF\-based HP PA\-RISC, or x86
|
||||
for 80386). Multi\-platform
|
||||
unwinding works exactly like cross\-platform unwinding, the only
|
||||
limitation is that a single source file (compilation unit) can include
|
||||
at most one libunwind
|
||||
header file. In other words, the
|
||||
platform\-specific support for each supported target needs to be
|
||||
isolated in separate source files\-\-\-a limitation that shouldn\&'t be an
|
||||
issue in practice.
|
||||
.PP
|
||||
Note that, by definition, local unwinding is possible only for the
|
||||
native case. Attempting to call, e.g., unw_local_init()
|
||||
when
|
||||
targeting a cross\-platform will result in a link\-time error
|
||||
(unresolved references).
|
||||
.PP
|
||||
.SH THREAD\- AND SIGNAL\-SAFETY
|
||||
|
||||
.PP
|
||||
All libunwind
|
||||
routines are thread\-safe. What this means is
|
||||
that multiple threads may use libunwind
|
||||
simulatenously.
|
||||
However, any given cursor may be accessed by only one thread at
|
||||
any given time.
|
||||
.PP
|
||||
To ensure thread\-safety, some libunwind
|
||||
routines may have to
|
||||
use locking. Such routines \fImust not\fP
|
||||
be called from signal
|
||||
handlers (directly or indirectly) and are therefore \fInot\fP
|
||||
signal\-safe. The manual page for each libunwind
|
||||
routine
|
||||
identifies whether or not it is signal\-safe, but as a general rule,
|
||||
any routine that may be needed for \fIlocal\fP
|
||||
unwinding is
|
||||
signal\-safe (e.g., unw_step()
|
||||
for local unwinding is
|
||||
signal\-safe). For remote\-unwinding, \fInone\fP
|
||||
of the
|
||||
libunwind
|
||||
routines are guaranteed to be signal\-safe.
|
||||
.PP
|
||||
.SH UNWINDING THROUGH DYNAMICALLY GENERATED CODE
|
||||
|
||||
.PP
|
||||
Libunwind
|
||||
provides the routines _U_dyn_register()
|
||||
and
|
||||
_U_dyn_cancel()
|
||||
to register/cancel the information required to
|
||||
unwind through code that has been generated at runtime (e.g., by a
|
||||
just\-in\-time (JIT) compiler). It is important to register the
|
||||
information for \fIall\fP
|
||||
dynamically generated code because
|
||||
otherwise, a debugger may not be able to function properly or
|
||||
high\-level language exception handling may not work as expected.
|
||||
.PP
|
||||
The interface for registering and canceling dynamic unwind info has
|
||||
been designed for maximum efficiency, so as to minimize the
|
||||
performance impact on JIT\-compilers. In particular, both routines are
|
||||
guaranteed to execute in ``constant time\&'' (O(1)) and the
|
||||
data\-structure encapsulating the dynamic unwind info has been designed
|
||||
to facilitate sharing, such that similar procedures can share much of
|
||||
the underlying information.
|
||||
.PP
|
||||
For more information on the libunwind
|
||||
support for dynamically
|
||||
generated code, see libunwind\-dynamic(3)\&.
|
||||
.PP
|
||||
.SH CACHING OF UNWIND INFO
|
||||
|
||||
.PP
|
||||
To speed up execution, libunwind
|
||||
may aggressively cache the
|
||||
information it needs to perform unwinding. If a process changes
|
||||
during its lifetime, this creates a risk of libunwind
|
||||
using
|
||||
stale data. For example, this would happen if libunwind
|
||||
were
|
||||
to cache information about a shared library which later on gets
|
||||
unloaded (e.g., via \fIdlclose\fP(3)).
|
||||
.PP
|
||||
To prevent the risk of using stale data, libunwind
|
||||
provides two
|
||||
facilities: first, it is possible to flush the cached information
|
||||
associated with a specific address range in the target process (or the
|
||||
entire address space, if desired). This functionality is provided by
|
||||
unw_flush_cache().
|
||||
The second facility is provided by
|
||||
unw_set_caching_policy(),
|
||||
which lets a program
|
||||
select the exact caching policy in use for a given address\-space
|
||||
object. In particular, by selecting the policy
|
||||
UNW_CACHE_NONE,
|
||||
it is possible to turn off caching
|
||||
completely, therefore eliminating the risk of stale data alltogether
|
||||
(at the cost of slower execution). By default, caching is enabled for
|
||||
local unwinding only.
|
||||
.PP
|
||||
.SH FILES
|
||||
|
||||
.PP
|
||||
.TP
|
||||
libunwind.h
|
||||
Headerfile to include for native (same
|
||||
platform) unwinding.
|
||||
.TP
|
||||
libunwind\-PLAT\&.h
|
||||
Headerfile to include when
|
||||
the unwind target runs on platform PLAT\&.
|
||||
For example, to unwind
|
||||
an IA\-64 program, the header file libunwind\-ia64.h
|
||||
should be
|
||||
included.
|
||||
.TP
|
||||
\fB\-l\fPunwind
|
||||
Linker\-switch to add when building a
|
||||
program that does native (same platform) unwinding.
|
||||
.TP
|
||||
\fB\-l\fPunwind\-PLAT
|
||||
Linker\-switch to add when
|
||||
building a program that unwinds a program on platform PLAT\&.
|
||||
For example, to (cross\-)unwind an IA\-64 program, the linker switch
|
||||
\-lunwind\-ia64
|
||||
should be added. Note: multiple such switches
|
||||
may need to be specified for programs that can unwind programs on
|
||||
multiple platforms.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind\-dynamic(3),
|
||||
libunwind\-ia64(3),
|
||||
libunwind\-ptrace(3),
|
||||
libunwind\-setjmp(3),
|
||||
unw_create_addr_space(3),
|
||||
unw_destroy_addr_space(3),
|
||||
unw_flush_cache(3),
|
||||
unw_get_accessors(3),
|
||||
unw_get_fpreg(3),
|
||||
unw_get_proc_info(3),
|
||||
unw_get_proc_name(3),
|
||||
unw_get_reg(3),
|
||||
unw_getcontext(3),
|
||||
unw_init_local(3),
|
||||
unw_init_remote(3),
|
||||
unw_is_fpreg(3),
|
||||
unw_is_signal_frame(3),
|
||||
unw_regname(3),
|
||||
unw_resume(3),
|
||||
unw_set_caching_policy(3),
|
||||
unw_set_fpreg(3),
|
||||
unw_set_reg(3),
|
||||
unw_step(3),
|
||||
unw_strerror(3),
|
||||
_U_dyn_register(3),
|
||||
_U_dyn_cancel(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,355 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{libunwind}{David Mosberger-Tang}{Programming Library}{Introduction to libunwind}libunwind -- a (mostly) platform-independent unwind API
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_getcontext}(\Type{unw\_context\_t~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_init\_local}(\Type{unw\_cursor\_t~*}, \Type{unw\_context\_t~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_init\_remote}(\Type{unw\_cursor\_t~*}, \Type{unw\_addr\_space\_t}, \Type{void~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_step}(\Type{unw\_cursor\_t~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_get\_reg}(\Type{unw\_cursor\_t~*}, \Type{unw\_regnum\_t}, \Type{unw\_word\_t~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_get\_fpreg}(\Type{unw\_cursor\_t~*}, \Type{unw\_regnum\_t}, \Type{unw\_fpreg\_t~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_set\_reg}(\Type{unw\_cursor\_t~*}, \Type{unw\_regnum\_t}, \Type{unw\_word\_t});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_set\_fpreg}(\Type{unw\_cursor\_t~*}, \Type{unw\_regnum\_t}, \Type{unw\_fpreg\_t});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_resume}(\Type{unw\_cursor\_t~*});\\
|
||||
|
||||
\noindent
|
||||
\Type{unw\_addr\_space\_t} \Var{unw\_local\_addr\_space};\\
|
||||
\noindent
|
||||
\Type{unw\_addr\_space\_t} \Func{unw\_create\_addr\_space}(\Type{unw\_accessors\_t}, \Type{int});\\
|
||||
\noindent
|
||||
\Type{void} \Func{unw\_destroy\_addr\_space}(\Type{unw\_addr\_space\_t});\\
|
||||
\noindent
|
||||
\Type{unw\_accessors\_t} \Func{unw\_get\_accessors}(\Type{unw\_addr\_space\_t});\\
|
||||
\noindent
|
||||
\Type{void} \Func{unw\_flush\_cache}(\Type{unw\_addr\_space\_t}, \Type{unw\_word\_t}, \Type{unw\_word\_t});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_set\_caching\_policy}(\Type{unw\_addr\_space\_t}, \Type{unw\_caching\_policy\_t});\\
|
||||
|
||||
\noindent
|
||||
\Type{const char *}\Func{unw\_regname}(\Type{unw\_regnum\_t});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_get\_proc\_info}(\Type{unw\_cursor\_t~*}, \Type{unw\_proc\_info\_t~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_get\_save\_loc}(\Type{unw\_cursor\_t~*}, \Type{int}, \Type{unw\_save\_loc\_t~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_is\_fpreg}(\Type{unw\_regnum\_t});\\
|
||||
\Type{int} \Func{unw\_is\_signal\_frame}(\Type{unw\_cursor\_t~*});\\
|
||||
\noindent
|
||||
\Type{int} \Func{unw\_get\_proc\_name}(\Type{unw\_cursor\_t~*}, \Type{char~*}, \Type{size\_t}, \Type{unw\_word\_t~*});\\
|
||||
|
||||
\noindent
|
||||
\Type{void} \Func{\_U\_dyn\_register}(\Type{unw\_dyn\_info\_t~*});\\
|
||||
\noindent
|
||||
\Type{void} \Func{\_U\_dyn\_cancel}(\Type{unw\_dyn\_info\_t~*});\\
|
||||
|
||||
\section{Local Unwinding}
|
||||
|
||||
\Prog{Libunwind} is very easy to use when unwinding a stack from
|
||||
within a running program. This is called \emph{local} unwinding. Say
|
||||
you want to unwind the stack while executing in some function
|
||||
\Func{F}(). In this function, you would call \Func{unw\_getcontext}()
|
||||
to get a snapshot of the CPU registers (machine-state). Then you
|
||||
initialize an \emph{unwind~cursor} based on this snapshot. This is
|
||||
done with a call to \Func{unw\_init\_local}(). The cursor now points
|
||||
to the current frame, that is, the stack frame that corresponds to the
|
||||
current activation of function \Func{F}(). The unwind cursor can then
|
||||
be moved ``up'' (towards earlier stack frames) by calling
|
||||
\Func{unw\_step}(). By repeatedly calling this routine, you can
|
||||
uncover the entire call-chain that led to the activation of function
|
||||
\Func{F}(). A positive return value from \Func{unw\_step}() indicates
|
||||
that there are more frames in the chain, zero indicates that the end
|
||||
of the chain has been reached, and any negative value indicates that
|
||||
some sort of error has occurred.
|
||||
|
||||
While it is not possible to directly move the unwind cursor in the
|
||||
``down'' direction (towards newer stack frames), this effect can be
|
||||
achieved by making copies of an unwind cursor. For example, a program
|
||||
that sometimes has to move ``down'' by one stack frame could maintain
|
||||
two cursor variables: ``\Var{curr}'' and ``\Var{prev}''. The former
|
||||
would be used as the current cursor and \Var{prev} would be maintained
|
||||
as the ``previous frame'' cursor by copying the contents of \Var{curr}
|
||||
to \Var{prev} right before calling \Func{unw\_step}(). With this
|
||||
approach, the program could move one step ``down'' simply by copying
|
||||
back \Var{prev} to \Var{curr} whenever that is necessary. In the most
|
||||
extreme case, a program could maintain a separate cursor for each call
|
||||
frame and that way it could move up and down the callframe-chain at
|
||||
will.
|
||||
|
||||
Given an unwind cursor, it is possible to read and write the CPU
|
||||
registers that were preserved for the current stack frame (as
|
||||
identified by the cursor). \Prog{Libunwind} provides several routines
|
||||
for this purpose: \Func{unw\_get\_reg}() reads an integer (general)
|
||||
register, \Func{unw\_get\_fpreg}() reads a floating-point register,
|
||||
\Func{unw\_set\_reg}() writes an integer register, and
|
||||
\Func{unw\_set\_fpreg}() writes a floating-point register. Note that,
|
||||
by definition, only the \emph{preserved} machine state can be accessed
|
||||
during an unwind operation. Normally, this state consists of the
|
||||
\emph{callee-saved} (``preserved'') registers. However, in some
|
||||
special circumstances (e.g., in a signal handler trampoline), even the
|
||||
\emph{caller-saved} (``scratch'') registers are preserved in the stack
|
||||
frame and, in those cases, \Prog{libunwind} will grant access to them
|
||||
as well. The exact set of registers that can be accessed via the
|
||||
cursor depends, of course, on the platform. However, there are two
|
||||
registers that can be read on all platforms: the instruction pointer
|
||||
(IP), sometimes also known as the ``program counter'', and the stack
|
||||
pointer (SP). In \Prog{libunwind}, these registers are identified by
|
||||
the macros \Const{UNW\_REG\_IP} and \Const{UNW\_REG\_SP},
|
||||
respectively.
|
||||
|
||||
Besides just moving the unwind cursor and reading/writing saved
|
||||
registers, \Prog{libunwind} also provides the ability to resume
|
||||
execution at an arbitrary stack frame. As you might guess, this is
|
||||
useful for implementing non-local gotos and the exception handling
|
||||
needed by some high-level languages such as Java. Resuming execution
|
||||
with a particular stack frame simply requires calling
|
||||
\Func{unw\_resume}() and passing the cursor identifying the target
|
||||
frame as the only argument.
|
||||
|
||||
Normally, \Prog{libunwind} supports both local and remote unwinding
|
||||
(the latter will be explained in the next section). However, if you
|
||||
tell libunwind that your program only needs local unwinding, then a
|
||||
special implementation can be selected which may run much faster than
|
||||
the generic implementation which supports both kinds of unwinding. To
|
||||
select this optimized version, simply define the macro
|
||||
\Const{UNW\_LOCAL\_ONLY} before including the headerfile
|
||||
\File{$<$libunwind.h$>$}. It is perfectly OK for a single program to
|
||||
employ both local-only and generic unwinding. That is, whether or not
|
||||
\Const{UNW\_LOCAL\_ONLY} is defined is a choice that each source-file
|
||||
(compilation-unit) can make on its own. Independent of the setting(s)
|
||||
of \Const{UNW\_LOCAL\_ONLY}, you'll always link the same library into
|
||||
the program (normally \Opt{-l}\File{unwind}). Furthermore, the
|
||||
portion of \Prog{libunwind} that manages unwind-info for dynamically
|
||||
generated code is not affected by the setting of
|
||||
\Const{UNW\_LOCAL\_ONLY}.
|
||||
|
||||
If we put all of the above together, here is how we could use
|
||||
\Prog{libunwind} to write a function ``\Func{show\_backtrace}()''
|
||||
which prints a classic stack trace:
|
||||
|
||||
\begin{verbatim}
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
|
||||
void show_backtrace (void) {
|
||||
unw_cursor_t cursor; unw_context_t uc;
|
||||
unw_word_t ip, sp;
|
||||
|
||||
unw_getcontext(&uc);
|
||||
unw_init_local(&cursor, &uc);
|
||||
while (unw_step(&cursor) > 0) {
|
||||
unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
||||
unw_get_reg(&cursor, UNW_REG_SP, &sp);
|
||||
printf ("ip = %lx, sp = %lx\n", (long) ip, (long) sp);
|
||||
}
|
||||
}
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\section{Remote Unwinding}
|
||||
|
||||
\Prog{Libunwind} can also be used to unwind a stack in a ``remote''
|
||||
process. Here, ``remote'' may mean another process on the same
|
||||
machine or even a process on a completely different machine from the
|
||||
one that is running \Prog{libunwind}. Remote unwinding is typically
|
||||
used by debuggers and instruction-set simulators, for example.
|
||||
|
||||
Before you can unwind a remote process, you need to create a new
|
||||
address-space object for that process. This is achieved with the
|
||||
\Func{unw\_create\_addr\_space}() routine. The routine takes two
|
||||
arguments: a pointer to a set of \emph{accessor} routines and an
|
||||
integer that specifies the byte-order of the target process. The
|
||||
accessor routines provide \Func{libunwind} with the means to
|
||||
communicate with the remote process. In particular, there are
|
||||
callbacks to read and write the process's memory, its registers, and
|
||||
to access unwind information which may be needed by \Func{libunwind}.
|
||||
|
||||
With the address space created, unwinding can be initiated by a call
|
||||
to \Func{unw\_init\_remote}(). This routine is very similar to
|
||||
\Func{unw\_init\_local}(), except that it takes an address-space
|
||||
object and an opaque pointer as arguments. The routine uses these
|
||||
arguments to fetch the initial machine state. \Prog{Libunwind} never
|
||||
uses the opaque pointer on its own, but instead just passes it on to
|
||||
the accessor (callback) routines. Typically, this pointer is used to
|
||||
select, e.g., the thread within a process that is to be unwound.
|
||||
|
||||
Once a cursor has been initialized with \Func{unw\_init\_remote}(),
|
||||
unwinding works exactly like in the local case. That is, you can use
|
||||
\Func{unw\_step}() to move ``up'' in the call-chain, read and write
|
||||
registers, or resume execution at a particular stack frame by calling
|
||||
\Func{unw\_resume}.
|
||||
|
||||
|
||||
\section{Cross-platform and Multi-platform Unwinding}
|
||||
|
||||
\Prog{Libunwind} has been designed to enable unwinding across
|
||||
platforms (architectures). Indeed, a single program can use
|
||||
\Prog{libunwind} to unwind an arbitrary number of target platforms,
|
||||
all at the same time!
|
||||
|
||||
We call the machine that is running \Prog{libunwind} the \emph{host}
|
||||
and the machine that is running the process being unwound the
|
||||
\emph{target}. If the host and the target platform are the same, we
|
||||
call it \emph{native} unwinding. If they differ, we call it
|
||||
\emph{cross-platform} unwinding.
|
||||
|
||||
The principle behind supporting native, cross-platform, and
|
||||
multi-platform unwinding is very simple: for native unwinding, a
|
||||
program includes \File{$<$libunwind.h$>$} and uses the linker switch
|
||||
\Opt{-l}\File{unwind}. For cross-platform unwinding, a program
|
||||
includes \File{$<$libunwind-}\Var{PLAT}\File{.h$>$} and uses the linker
|
||||
switch \Opt{-l}\File{unwind-}\Var{PLAT}, where \Var{PLAT} is the name
|
||||
of the target platform (e.g., \File{ia64} for IA-64, \File{hppa-elf}
|
||||
for ELF-based HP PA-RISC, or \File{x86} for 80386). Multi-platform
|
||||
unwinding works exactly like cross-platform unwinding, the only
|
||||
limitation is that a single source file (compilation unit) can include
|
||||
at most one \Prog{libunwind} header file. In other words, the
|
||||
platform-specific support for each supported target needs to be
|
||||
isolated in separate source files---a limitation that shouldn't be an
|
||||
issue in practice.
|
||||
|
||||
Note that, by definition, local unwinding is possible only for the
|
||||
native case. Attempting to call, e.g., \Func{unw\_local\_init}() when
|
||||
targeting a cross-platform will result in a link-time error
|
||||
(unresolved references).
|
||||
|
||||
|
||||
\section{Thread- and Signal-Safety}
|
||||
|
||||
|
||||
All \Prog{libunwind} routines are thread-safe. What this means is
|
||||
that multiple threads may use \Prog{libunwind} simulatenously.
|
||||
However, any given cursor may be accessed by only one thread at
|
||||
any given time.
|
||||
|
||||
To ensure thread-safety, some \Prog{libunwind} routines may have to
|
||||
use locking. Such routines \emph{must~not} be called from signal
|
||||
handlers (directly or indirectly) and are therefore \emph{not}
|
||||
signal-safe. The manual page for each \Prog{libunwind} routine
|
||||
identifies whether or not it is signal-safe, but as a general rule,
|
||||
any routine that may be needed for \emph{local} unwinding is
|
||||
signal-safe (e.g., \Func{unw\_step}() for local unwinding is
|
||||
signal-safe). For remote-unwinding, \emph{none} of the
|
||||
\Prog{libunwind} routines are guaranteed to be signal-safe.
|
||||
|
||||
|
||||
\section{Unwinding Through Dynamically Generated Code}
|
||||
|
||||
\Func{Libunwind} provides the routines \Func{\_U\_dyn\_register}() and
|
||||
\Func{\_U\_dyn\_cancel}() to register/cancel the information required to
|
||||
unwind through code that has been generated at runtime (e.g., by a
|
||||
just-in-time (JIT) compiler). It is important to register the
|
||||
information for \emph{all} dynamically generated code because
|
||||
otherwise, a debugger may not be able to function properly or
|
||||
high-level language exception handling may not work as expected.
|
||||
|
||||
The interface for registering and canceling dynamic unwind info has
|
||||
been designed for maximum efficiency, so as to minimize the
|
||||
performance impact on JIT-compilers. In particular, both routines are
|
||||
guaranteed to execute in ``constant time'' (O(1)) and the
|
||||
data-structure encapsulating the dynamic unwind info has been designed
|
||||
to facilitate sharing, such that similar procedures can share much of
|
||||
the underlying information.
|
||||
|
||||
For more information on the \Prog{libunwind} support for dynamically
|
||||
generated code, see \SeeAlso{libunwind-dynamic(3)}.
|
||||
|
||||
|
||||
\section{Caching of Unwind Info}
|
||||
|
||||
To speed up execution, \Prog{libunwind} may aggressively cache the
|
||||
information it needs to perform unwinding. If a process changes
|
||||
during its lifetime, this creates a risk of \Prog{libunwind} using
|
||||
stale data. For example, this would happen if \Prog{libunwind} were
|
||||
to cache information about a shared library which later on gets
|
||||
unloaded (e.g., via \Cmd{dlclose}{3}).
|
||||
|
||||
To prevent the risk of using stale data, \Prog{libunwind} provides two
|
||||
facilities: first, it is possible to flush the cached information
|
||||
associated with a specific address range in the target process (or the
|
||||
entire address space, if desired). This functionality is provided by
|
||||
\Func{unw\_flush\_cache}(). The second facility is provided by
|
||||
\Func{unw\_set\_caching\_policy}(), which lets a program
|
||||
select the exact caching policy in use for a given address-space
|
||||
object. In particular, by selecting the policy
|
||||
\Const{UNW\_CACHE\_NONE}, it is possible to turn off caching
|
||||
completely, therefore eliminating the risk of stale data alltogether
|
||||
(at the cost of slower execution). By default, caching is enabled for
|
||||
local unwinding only.
|
||||
|
||||
|
||||
\section{Files}
|
||||
|
||||
\begin{Description}
|
||||
\item[\File{libunwind.h}] Headerfile to include for native (same
|
||||
platform) unwinding.
|
||||
\item[\File{libunwind-}\Var{PLAT}\File{.h}] Headerfile to include when
|
||||
the unwind target runs on platform \Var{PLAT}. For example, to unwind
|
||||
an IA-64 program, the header file \File{libunwind-ia64.h} should be
|
||||
included.
|
||||
\item[\Opt{-l}\File{unwind}] Linker-switch to add when building a
|
||||
program that does native (same platform) unwinding.
|
||||
\item[\Opt{-l}\File{unwind-}\Var{PLAT}] Linker-switch to add when
|
||||
building a program that unwinds a program on platform \Var{PLAT}.
|
||||
For example, to (cross-)unwind an IA-64 program, the linker switch
|
||||
\File{-lunwind-ia64} should be added. Note: multiple such switches
|
||||
may need to be specified for programs that can unwind programs on
|
||||
multiple platforms.
|
||||
\end{Description}
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind-dynamic(3)},
|
||||
\SeeAlso{libunwind-ia64(3)},
|
||||
\SeeAlso{libunwind-ptrace(3)},
|
||||
\SeeAlso{libunwind-setjmp(3)},
|
||||
\SeeAlso{unw\_create\_addr\_space(3)},
|
||||
\SeeAlso{unw\_destroy\_addr\_space(3)},
|
||||
\SeeAlso{unw\_flush\_cache(3)},
|
||||
\SeeAlso{unw\_get\_accessors(3)},
|
||||
\SeeAlso{unw\_get\_fpreg(3)},
|
||||
\SeeAlso{unw\_get\_proc\_info(3)},
|
||||
\SeeAlso{unw\_get\_proc\_name(3)},
|
||||
\SeeAlso{unw\_get\_reg(3)},
|
||||
\SeeAlso{unw\_getcontext(3)},
|
||||
\SeeAlso{unw\_init\_local(3)},
|
||||
\SeeAlso{unw\_init\_remote(3)},
|
||||
\SeeAlso{unw\_is\_fpreg(3)},
|
||||
\SeeAlso{unw\_is\_signal\_frame(3)},
|
||||
\SeeAlso{unw\_regname(3)},
|
||||
\SeeAlso{unw\_resume(3)},
|
||||
\SeeAlso{unw\_set\_caching\_policy(3)},
|
||||
\SeeAlso{unw\_set\_fpreg(3)},
|
||||
\SeeAlso{unw\_set\_reg(3)},
|
||||
\SeeAlso{unw\_step(3)},
|
||||
\SeeAlso{unw\_strerror(3)},
|
||||
\SeeAlso{\_U\_dyn\_register(3)},
|
||||
\SeeAlso{\_U\_dyn\_cancel(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,34 @@
|
|||
$manMacro1a{'Type'} = $manMacro1a{File};
|
||||
$manMacro1b{'Type'} = $manMacro1b{File};
|
||||
$htmlMacro1a{'Type'} = $htmlMacro1a{File};
|
||||
$htmlMacro1b{'Type'} = $htmlMacro1b{File};
|
||||
$texiMacro1a{'Type'} = $texiMacro1a{File};
|
||||
$texiMacro1b{'Type'} = $texiMacro1b{File};
|
||||
$manMacro1a{'Func'} = $manMacro1a{Prog};
|
||||
$manMacro1b{'Func'} = $manMacro1b{Prog};
|
||||
$htmlMacro1a{'Func'} = $htmlMacro1a{Arg};
|
||||
$htmlMacro1b{'Func'} = $htmlMacro1b{Arg};
|
||||
$texiMacro1a{'Func'} = $texiMacro1a{Prog};
|
||||
$texiMacro1b{'Func'} = $texiMacro1b{Prog};
|
||||
$manMacro1a{'Var'} = $manMacro1a{Prog};
|
||||
$manMacro1b{'Var'} = $manMacro1b{Prog};
|
||||
$htmlMacro1a{'Var'} = $htmlMacro1a{Prog};
|
||||
$htmlMacro1b{'Var'} = $htmlMacro1b{Prog};
|
||||
$texiMacro1a{'Var'} = $texiMacro1a{Prog};
|
||||
$texiMacro1b{'Var'} = $texiMacro1b{Prog};
|
||||
$manMacro1a{'Const'} = $manMacro1a{File};
|
||||
$manMacro1b{'Const'} = $manMacro1b{File};
|
||||
$htmlMacro1a{'Const'} = $htmlMacro1a{File};
|
||||
$htmlMacro1b{'Const'} = $htmlMacro1b{File};
|
||||
$texiMacro1a{'Const'} = $texiMacro1a{File};
|
||||
$texiMacro1b{'Const'} = $texiMacro1b{File};
|
||||
|
||||
$manMacro1a{'SeeAlso'} = $manMacro1a{File};
|
||||
$manMacro1b{'SeeAlso'} = $manMacro1b{File};
|
||||
# special handling of SeeAlso in latex2man, so that argument gets doubled:
|
||||
$htmlMacro2a{'SeeAlso'} = "<a href=\"";
|
||||
$htmlMacro2b{'SeeAlso'} = ".html\">$htmlMacro1a{File}";
|
||||
$htmlMacro2c{'SeeAlso'} = "$htmlMacro1b{File}</a>";
|
||||
$texiMacro1a{'SeeAlso'} = $texiMacro1a{File};
|
||||
$texiMacro1b{'SeeAlso'} = $texiMacro1b{File};
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Fri Aug 31 13:39:04 EEST 2012
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_BACKTRACE" "3" "31 August 2012" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_backtrace
|
||||
\-\- return backtrace for the calling program
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_backtrace(void **buffer,
|
||||
int size);
|
||||
.br
|
||||
.PP
|
||||
#include <execinfo.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
backtrace(void **buffer,
|
||||
int size);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
unw_backtrace()
|
||||
is a convenient routine for obtaining the backtrace for
|
||||
the calling program. The routine fills up to size
|
||||
addresses in the array
|
||||
pointed by buffer\&.
|
||||
The routine is only available for local unwinding.
|
||||
.PP
|
||||
Note that many (but not all) systems provide practically identical function
|
||||
called backtrace().
|
||||
The prototype for this function is usually obtained
|
||||
by including the <execinfo.h>
|
||||
header file \-\- a prototype for
|
||||
backtrace()
|
||||
is not provided by libunwind\&.
|
||||
libunwind
|
||||
weakly
|
||||
aliases backtrace()
|
||||
to unw_backtrace(),
|
||||
so when a program
|
||||
calling backtrace()
|
||||
is linked against libunwind,
|
||||
it may end up
|
||||
calling unw_backtrace().
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
The routine returns the number of addresses stored in the array pointed by
|
||||
buffer\&.
|
||||
The return value may be zero to indicate that no addresses were
|
||||
stored.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_step(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,54 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_backtrace}{David Mosberger-Tang}{Programming Library}{unw\_backtrace}unw\_backtrace -- return backtrace for the calling program
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_backtrace}(\Type{void~**}\Var{buffer}, \Type{int}~\Var{size});\\
|
||||
|
||||
\File{\#include $<$execinfo.h$>$}\\
|
||||
|
||||
\Type{int} \Func{backtrace}(\Type{void~**}\Var{buffer}, \Type{int}~\Var{size});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
\Func{unw\_backtrace}() is a convenient routine for obtaining the backtrace for
|
||||
the calling program. The routine fills up to \Var{size} addresses in the array
|
||||
pointed by \Var{buffer}. The routine is only available for local unwinding.
|
||||
|
||||
Note that many (but not all) systems provide practically identical function
|
||||
called \Func{backtrace}(). The prototype for this function is usually obtained
|
||||
by including the \File{$<$execinfo.h$>$} header file -- a prototype for
|
||||
\Func{backtrace}() is not provided by \Prog{libunwind}. \Prog{libunwind} weakly
|
||||
aliases \Func{backtrace}() to \Func{unw\_backtrace}(), so when a program
|
||||
calling \Func{backtrace}() is linked against \Prog{libunwind}, it may end up
|
||||
calling \Func{unw\_backtrace}().
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
The routine returns the number of addresses stored in the array pointed by
|
||||
\Var{buffer}. The return value may be zero to indicate that no addresses were
|
||||
stored.
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_step(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,457 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_CREATE\\_ADDR\\_SPACE" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_create_addr_space
|
||||
\-\- create address space for remote unwinding
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
unw_addr_space_t
|
||||
unw_create_addr_space(unw_accessors_t *ap,
|
||||
int
|
||||
byteorder);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_create_addr_space()
|
||||
routine creates a new unwind
|
||||
address\-space and initializes it based on the call\-back routines
|
||||
passed via the ap
|
||||
pointer and the specified byteorder\&.
|
||||
The call\-back routines are described in detail below. The
|
||||
byteorder
|
||||
can be set to 0 to request the default byte\-order of
|
||||
the unwind target. To request a particular byte\-order,
|
||||
byteorder
|
||||
can be set to any constant defined by
|
||||
<endian.h>\&.
|
||||
In particular, __LITTLE_ENDIAN
|
||||
would
|
||||
request little\-endian byte\-order and __BIG_ENDIAN
|
||||
would
|
||||
request big\-endian byte\-order. Whether or not a particular byte\-order
|
||||
is supported depends on the target platform.
|
||||
.PP
|
||||
.SH CALL\-BACK ROUTINES
|
||||
|
||||
.PP
|
||||
Libunwind
|
||||
uses a set of call\-back routines to access the
|
||||
information it needs to unwind a chain of stack\-frames. These
|
||||
routines are specified via the ap
|
||||
argument, which points to a
|
||||
variable of type unw_accessors_t\&.
|
||||
The contents of this
|
||||
variable is copied into the newly\-created address space, so the
|
||||
variable must remain valid only for the duration of the call to
|
||||
unw_create_addr_space().
|
||||
.PP
|
||||
The first argument to every call\-back routine is an address\-space
|
||||
identifier (as)
|
||||
and the last argument is an arbitrary,
|
||||
application\-specified void\-pointer (arg).
|
||||
When invoking a
|
||||
call\-back routine, libunwind
|
||||
sets the as
|
||||
argument to the
|
||||
address\-space on whose behalf the invocation is made and the arg
|
||||
argument to the value that was specified when
|
||||
unw_init_remote(3)
|
||||
was called.
|
||||
.PP
|
||||
The synopsis and a detailed description of every call\-back routine
|
||||
follows below.
|
||||
.PP
|
||||
.SS CALL\-BACK ROUTINE SYNOPSIS
|
||||
.PP
|
||||
int
|
||||
find_proc_info(unw_addr_space_t
|
||||
as,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPunw_word_t
|
||||
ip,
|
||||
unw_proc_info_t *pip,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPint
|
||||
need_unwind_info,
|
||||
void *arg);
|
||||
.br
|
||||
void
|
||||
put_unwind_info(unw_addr_space_t
|
||||
as,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPunw_proc_info_t *pip,
|
||||
void *arg);
|
||||
.br
|
||||
int
|
||||
get_dyn_info_list_addr(unw_addr_space_t
|
||||
as,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPunw_word_t *dilap,
|
||||
void *arg);
|
||||
.br
|
||||
int
|
||||
access_mem(unw_addr_space_t
|
||||
as,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPunw_word_t
|
||||
addr,
|
||||
unw_word_t *valp,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPint
|
||||
write,
|
||||
void *arg);
|
||||
.br
|
||||
int
|
||||
access_reg(unw_addr_space_t
|
||||
as,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPunw_regnum_t
|
||||
regnum,
|
||||
unw_word_t *valp,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPint
|
||||
write,
|
||||
void *arg);
|
||||
.br
|
||||
int
|
||||
access_fpreg(unw_addr_space_t
|
||||
as,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPunw_regnum_t
|
||||
regnum,
|
||||
unw_fpreg_t *fpvalp,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPint
|
||||
write,
|
||||
void *arg);
|
||||
.br
|
||||
int
|
||||
resume(unw_addr_space_t
|
||||
as,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPunw_cursor_t *cp,
|
||||
void *arg);
|
||||
.br
|
||||
int
|
||||
get_proc_name(unw_addr_space_t
|
||||
as,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPunw_word_t
|
||||
addr,
|
||||
char *bufp,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPsize_t
|
||||
buf_len,
|
||||
unw_word_t *offp,
|
||||
.br
|
||||
\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fP\fB \fPvoid *arg);
|
||||
.br
|
||||
.PP
|
||||
.SS FIND_PROC_INFO
|
||||
.PP
|
||||
Libunwind
|
||||
invokes the find_proc_info()
|
||||
call\-back to
|
||||
locate the information need to unwind a particular procedure. The
|
||||
ip
|
||||
argument is an instruction\-address inside the procedure whose
|
||||
information is needed. The pip
|
||||
argument is a pointer to the
|
||||
variable used to return the desired information. The type of this
|
||||
variable is unw_proc_info_t\&.
|
||||
See
|
||||
unw_get_proc_info(3)
|
||||
for details. Argument
|
||||
need_unwind_info
|
||||
is zero if the call\-back does not need to
|
||||
provide values for the following members in the
|
||||
unw_proc_info_t
|
||||
structure: format,
|
||||
unwind_info_size,
|
||||
and unwind_info\&.
|
||||
If
|
||||
need_unwind_info
|
||||
is non\-zero, valid values need to be returned
|
||||
in these members. Furthermore, the contents of the memory addressed
|
||||
by the unwind_info
|
||||
member must remain valid until the info is
|
||||
released via the put_unwind_info
|
||||
call\-back (see below).
|
||||
.PP
|
||||
On successful completion, the find_proc_info()
|
||||
call\-back must
|
||||
return zero. Otherwise, the negative value of one of the
|
||||
unw_error_t
|
||||
error\-codes may be returned. In particular, this
|
||||
call\-back may return \-UNW_ESTOPUNWIND
|
||||
to signal the end of
|
||||
the frame\-chain.
|
||||
.PP
|
||||
.SS PUT_UNWIND_INFO
|
||||
.PP
|
||||
Libunwind
|
||||
invokes the put_unwind_info()
|
||||
call\-back to
|
||||
release the resources (such as memory) allocated by a previous call to
|
||||
find_proc_info()
|
||||
with the need_unwind_info
|
||||
argument
|
||||
set to a non\-zero value. The pip
|
||||
argument has the same value as
|
||||
the argument of the same name in the previous matching call to
|
||||
find_proc_info().
|
||||
Note that libunwind
|
||||
does \fInot\fP
|
||||
invoke put_unwind_info
|
||||
for calls to find_proc_info()
|
||||
with a zero need_unwind_info
|
||||
argument.
|
||||
.PP
|
||||
.SS GET_DYN_INFO_LIST_ADDR
|
||||
.PP
|
||||
Libunwind
|
||||
invokes the get_dyn_info_list_addr()
|
||||
call\-back to obtain the address of the head of the dynamic unwind\-info
|
||||
registration list. The variable stored at the returned address must
|
||||
have a type of unw_dyn_info_list_t
|
||||
(see
|
||||
_U_dyn_register(3)).
|
||||
The dliap
|
||||
argument is a pointer
|
||||
to a variable of type unw_word_t
|
||||
which is used to return the
|
||||
address of the dynamic unwind\-info registration list. If no dynamic
|
||||
unwind\-info registration list exist, the value pointed to by
|
||||
dliap
|
||||
must be cleared to zero. Libunwind
|
||||
will cache the
|
||||
value returned by get_dyn_info_list_addr()
|
||||
if caching is
|
||||
enabled for the given address\-space. The cache can be cleared with a
|
||||
call to unw_flush_cache().
|
||||
.PP
|
||||
On successful completion, the get_dyn_info_list_addr()
|
||||
call\-back must return zero. Otherwise, the negative value of one of
|
||||
the unw_error_t
|
||||
error\-codes may be returned.
|
||||
.PP
|
||||
.SS ACCESS_MEM
|
||||
.PP
|
||||
Libunwind
|
||||
invokes the access_mem()
|
||||
call\-back to read
|
||||
from or write to a word of memory in the target address\-space. The
|
||||
address of the word to be accessed is passed in argument addr\&.
|
||||
To read memory, libunwind
|
||||
sets argument write
|
||||
to zero and
|
||||
valp
|
||||
to point to the word that receives the read value. To
|
||||
write memory, libunwind
|
||||
sets argument write
|
||||
to a non\-zero
|
||||
value and valp
|
||||
to point to the word that contains the value to
|
||||
be written. The word that valp
|
||||
points to is always in the
|
||||
byte\-order of the host\-platform, regardless of the byte\-order of the
|
||||
target. In other words, it is the responsibility of the call\-back
|
||||
routine to convert between the target\&'s and the host\&'s byte\-order, if
|
||||
necessary.
|
||||
.PP
|
||||
On successful completion, the access_mem()
|
||||
call\-back must return zero. Otherwise, the negative value of one of
|
||||
the unw_error_t
|
||||
error\-codes may be returned.
|
||||
.PP
|
||||
.SS ACCESS_REG
|
||||
.PP
|
||||
Libunwind
|
||||
invokes the access_reg()
|
||||
call\-back to read
|
||||
from or write to a scalar (non\-floating\-point) CPU register. The
|
||||
index of the register to be accessed is passed in argument
|
||||
regnum\&.
|
||||
To read a register, libunwind
|
||||
sets argument
|
||||
write
|
||||
to zero and valp
|
||||
to point to the word that receives
|
||||
the read value. To write a register, libunwind
|
||||
sets argument
|
||||
write
|
||||
to a non\-zero value and valp
|
||||
to point to the word
|
||||
that contains the value to be written. The word that valp
|
||||
points to is always in the byte\-order of the host\-platform, regardless
|
||||
of the byte\-order of the target. In other words, it is the
|
||||
responsibility of the call\-back routine to convert between the
|
||||
target\&'s and the host\&'s byte\-order, if necessary.
|
||||
.PP
|
||||
On successful completion, the access_reg()
|
||||
call\-back must
|
||||
return zero. Otherwise, the negative value of one of the
|
||||
unw_error_t
|
||||
error\-codes may be returned.
|
||||
.PP
|
||||
.SS ACCESS_FPREG
|
||||
.PP
|
||||
Libunwind
|
||||
invokes the access_fpreg()
|
||||
call\-back to read
|
||||
from or write to a floating\-point CPU register. The index of the
|
||||
register to be accessed is passed in argument regnum\&.
|
||||
To read a
|
||||
register, libunwind
|
||||
sets argument write
|
||||
to zero and
|
||||
fpvalp
|
||||
to point to a variable of type unw_fpreg_t
|
||||
that
|
||||
receives the read value. To write a register, libunwind
|
||||
sets
|
||||
argument write
|
||||
to a non\-zero value and fpvalp
|
||||
to point to
|
||||
the variable of type unw_fpreg_t
|
||||
that contains the value to
|
||||
be written. The word that fpvalp
|
||||
points to is always in the
|
||||
byte\-order of the host\-platform, regardless of the byte\-order of the
|
||||
target. In other words, it is the responsibility of the call\-back
|
||||
routine to convert between the target\&'s and the host\&'s byte\-order, if
|
||||
necessary.
|
||||
.PP
|
||||
On successful completion, the access_fpreg()
|
||||
call\-back must
|
||||
return zero. Otherwise, the negative value of one of the
|
||||
unw_error_t
|
||||
error\-codes may be returned.
|
||||
.PP
|
||||
.SS RESUME
|
||||
.PP
|
||||
Libunwind
|
||||
invokes the resume()
|
||||
call\-back to resume
|
||||
execution in the target address space. Argument cp
|
||||
is the
|
||||
unwind\-cursor that identifies the stack\-frame in which execution
|
||||
should resume. By the time libunwind
|
||||
invokes the resume
|
||||
call\-back, it has already established the desired machine\- and
|
||||
memory\-state via calls to the access_reg(),
|
||||
access_fpreg,
|
||||
and access_mem()
|
||||
call\-backs. Thus, all
|
||||
the call\-back needs to do is perform whatever action is needed to
|
||||
actually resume execution.
|
||||
.PP
|
||||
The resume
|
||||
call\-back is invoked only in response to a call to
|
||||
unw_resume(3),
|
||||
so applications which never invoke
|
||||
unw_resume(3)
|
||||
need not define the resume
|
||||
callback.
|
||||
.PP
|
||||
On successful completion, the resume()
|
||||
call\-back must return
|
||||
zero. Otherwise, the negative value of one of the
|
||||
unw_error_t
|
||||
error\-codes may be returned. As a special case,
|
||||
when resuming execution in the local address space, the call\-back will
|
||||
not return on success.
|
||||
.PP
|
||||
.SS GET_PROC_NAME
|
||||
.PP
|
||||
Libunwind
|
||||
invokes the get_proc_name()
|
||||
call\-back to
|
||||
obtain the procedure\-name of a static (not dynamically generated)
|
||||
procedure. Argument addr
|
||||
is an instruction\-address within the
|
||||
procedure whose name is to be obtained. The bufp
|
||||
argument is a
|
||||
pointer to a character\-buffer used to return the procedure name. The
|
||||
size of this buffer is specified in argument buf_len\&.
|
||||
The
|
||||
returned name must be terminated by a NUL character. If the
|
||||
procedure\&'s name is longer than buf_len
|
||||
bytes, it must be
|
||||
truncated to buf_len\-1
|
||||
bytes, with the last byte in the
|
||||
buffer set to the NUL character and \-UNW_ENOMEM
|
||||
must be
|
||||
returned. Argument offp
|
||||
is a pointer to a word which is used to
|
||||
return the byte\-offset relative to the start of the procedure whose
|
||||
name is being returned. For example, if procedure foo()
|
||||
starts
|
||||
at address 0x40003000, then invoking get_proc_name()
|
||||
with
|
||||
addr
|
||||
set to 0x40003080 should return a value of 0x80 in the word
|
||||
pointed to by offp
|
||||
(assuming the procedure is at least 0x80
|
||||
bytes long).
|
||||
.PP
|
||||
On successful completion, the get_proc_name()
|
||||
call\-back must
|
||||
return zero. Otherwise, the negative value of one of the
|
||||
unw_error_t
|
||||
error\-codes may be returned.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_create_addr_space()
|
||||
returns a
|
||||
non\-NULL
|
||||
value that represents the newly created
|
||||
address\-space. Otherwise, NULL
|
||||
is returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_create_addr_space()
|
||||
is thread\-safe but \fInot\fP
|
||||
safe to use from a signal handler.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
_U_dyn_register(3),
|
||||
libunwind(3),
|
||||
unw_destroy_addr_space(3),
|
||||
unw_get_proc_info(3),
|
||||
unw_init_remote(3),
|
||||
unw_resume(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,265 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_create\_addr\_space}{David Mosberger-Tang}{Programming Library}{unw\_create\_addr\_space}unw\_create\_addr\_space -- create address space for remote unwinding
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{unw\_addr\_space\_t} \Func{unw\_create\_addr\_space}(\Type{unw\_accessors\_t~*}\Var{ap}, \Type{int} \Var{byteorder});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_create\_addr\_space}() routine creates a new unwind
|
||||
address-space and initializes it based on the call-back routines
|
||||
passed via the \Var{ap} pointer and the specified \Var{byteorder}.
|
||||
The call-back routines are described in detail below. The
|
||||
\Var{byteorder} can be set to 0 to request the default byte-order of
|
||||
the unwind target. To request a particular byte-order,
|
||||
\Var{byteorder} can be set to any constant defined by
|
||||
\File{$<$endian.h$>$}. In particular, \Const{\_\_LITTLE\_ENDIAN} would
|
||||
request little-endian byte-order and \Const{\_\_BIG\_ENDIAN} would
|
||||
request big-endian byte-order. Whether or not a particular byte-order
|
||||
is supported depends on the target platform.
|
||||
|
||||
\section{Call-back Routines}
|
||||
|
||||
\Prog{Libunwind} uses a set of call-back routines to access the
|
||||
information it needs to unwind a chain of stack-frames. These
|
||||
routines are specified via the \Var{ap} argument, which points to a
|
||||
variable of type \Type{unw\_accessors\_t}. The contents of this
|
||||
variable is copied into the newly-created address space, so the
|
||||
variable must remain valid only for the duration of the call to
|
||||
\Func{unw\_create\_addr\_space}().
|
||||
|
||||
The first argument to every call-back routine is an address-space
|
||||
identifier (\Var{as}) and the last argument is an arbitrary,
|
||||
application-specified void-pointer (\Var{arg}). When invoking a
|
||||
call-back routine, \Prog{libunwind} sets the \Var{as} argument to the
|
||||
address-space on whose behalf the invocation is made and the \Var{arg}
|
||||
argument to the value that was specified when
|
||||
\Func{unw\_init\_remote}(3) was called.
|
||||
|
||||
The synopsis and a detailed description of every call-back routine
|
||||
follows below.
|
||||
|
||||
\subsection{Call-back Routine Synopsis}
|
||||
|
||||
\Type{int} \Func{find\_proc\_info}(\Type{unw\_addr\_space\_t} \Var{as},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{unw\_word\_t} \Var{ip}, \Type{unw\_proc\_info\_t~*}\Var{pip},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{int} \Var{need\_unwind\_info}, \Type{void~*}arg);\\
|
||||
\Type{void} \Func{put\_unwind\_info}(\Type{unw\_addr\_space\_t} \Var{as},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{unw\_proc\_info\_t~*}pip, \Type{void~*}\Var{arg});\\
|
||||
\Type{int} \Func{get\_dyn\_info\_list\_addr}(\Type{unw\_addr\_space\_t} \Var{as},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{unw\_word\_t~*}\Var{dilap}, \Type{void~*}\Var{arg});\\
|
||||
\Type{int} \Func{access\_mem}(\Var{unw\_addr\_space\_t} \Var{as},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{unw\_word\_t} \Var{addr}, \Type{unw\_word\_t~*}\Var{valp},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{int} \Var{write}, \Type{void~*}\Var{arg});\\
|
||||
\Type{int} \Func{access\_reg}(\Var{unw\_addr\_space\_t} \Var{as},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{unw\_regnum\_t} \Var{regnum}, \Type{unw\_word\_t~*}\Var{valp},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{int} \Var{write}, \Type{void~*}\Var{arg});\\
|
||||
\Type{int} \Func{access\_fpreg}(\Var{unw\_addr\_space\_t} \Var{as},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{unw\_regnum\_t} \Var{regnum}, \Type{unw\_fpreg\_t~*}\Var{fpvalp},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{int} \Var{write}, \Type{void~*}\Var{arg});\\
|
||||
\Type{int} \Func{resume}(\Var{unw\_addr\_space\_t} \Var{as},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{unw\_cursor\_t~*}\Var{cp}, \Type{void~*}\Var{arg});\\
|
||||
\Type{int} \Func{get\_proc\_name}(\Type{unw\_addr\_space\_t} \Var{as},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{unw\_word\_t} \Var{addr}, \Type{char~*}\Var{bufp},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{size\_t} \Var{buf\_len}, \Type{unw\_word\_t~*}\Var{offp},\\
|
||||
\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\SP\Type{void~*}\Var{arg});\\
|
||||
|
||||
\subsection{find\_proc\_info}
|
||||
|
||||
\Prog{Libunwind} invokes the \Func{find\_proc\_info}() call-back to
|
||||
locate the information need to unwind a particular procedure. The
|
||||
\Var{ip} argument is an instruction-address inside the procedure whose
|
||||
information is needed. The \Var{pip} argument is a pointer to the
|
||||
variable used to return the desired information. The type of this
|
||||
variable is \Type{unw\_proc\_info\_t}. See
|
||||
\Func{unw\_get\_proc\_info(3)} for details. Argument
|
||||
\Var{need\_unwind\_info} is zero if the call-back does not need to
|
||||
provide values for the following members in the
|
||||
\Type{unw\_proc\_info\_t} structure: \Var{format},
|
||||
\Var{unwind\_info\_size}, and \Var{unwind\_info}. If
|
||||
\Var{need\_unwind\_info} is non-zero, valid values need to be returned
|
||||
in these members. Furthermore, the contents of the memory addressed
|
||||
by the \Var{unwind\_info} member must remain valid until the info is
|
||||
released via the \Func{put\_unwind\_info} call-back (see below).
|
||||
|
||||
On successful completion, the \Func{find\_proc\_info}() call-back must
|
||||
return zero. Otherwise, the negative value of one of the
|
||||
\Type{unw\_error\_t} error-codes may be returned. In particular, this
|
||||
call-back may return -\Const{UNW\_ESTOPUNWIND} to signal the end of
|
||||
the frame-chain.
|
||||
|
||||
\subsection{put\_unwind\_info}
|
||||
|
||||
\Prog{Libunwind} invokes the \Func{put\_unwind\_info}() call-back to
|
||||
release the resources (such as memory) allocated by a previous call to
|
||||
\Func{find\_proc\_info}() with the \Var{need\_unwind\_info} argument
|
||||
set to a non-zero value. The \Var{pip} argument has the same value as
|
||||
the argument of the same name in the previous matching call to
|
||||
\Func{find\_proc\_info}(). Note that \Prog{libunwind} does \emph{not}
|
||||
invoke \Func{put\_unwind\_info} for calls to \Func{find\_proc\_info}()
|
||||
with a zero \Var{need\_unwind\_info} argument.
|
||||
|
||||
|
||||
\subsection{get\_dyn\_info\_list\_addr}
|
||||
|
||||
\Prog{Libunwind} invokes the \Func{get\_dyn\_info\_list\_addr}()
|
||||
call-back to obtain the address of the head of the dynamic unwind-info
|
||||
registration list. The variable stored at the returned address must
|
||||
have a type of \Type{unw\_dyn\_info\_list\_t} (see
|
||||
\Func{\_U\_dyn\_register}(3)). The \Var{dliap} argument is a pointer
|
||||
to a variable of type \Type{unw\_word\_t} which is used to return the
|
||||
address of the dynamic unwind-info registration list. If no dynamic
|
||||
unwind-info registration list exist, the value pointed to by
|
||||
\Var{dliap} must be cleared to zero. \Prog{Libunwind} will cache the
|
||||
value returned by \Func{get\_dyn\_info\_list\_addr}() if caching is
|
||||
enabled for the given address-space. The cache can be cleared with a
|
||||
call to \Func{unw\_flush\_cache}().
|
||||
|
||||
On successful completion, the \Func{get\_dyn\_info\_list\_addr}()
|
||||
call-back must return zero. Otherwise, the negative value of one of
|
||||
the \Type{unw\_error\_t} error-codes may be returned.
|
||||
|
||||
\subsection{access\_mem}
|
||||
|
||||
\Prog{Libunwind} invokes the \Func{access\_mem}() call-back to read
|
||||
from or write to a word of memory in the target address-space. The
|
||||
address of the word to be accessed is passed in argument \Var{addr}.
|
||||
To read memory, \Prog{libunwind} sets argument \Var{write} to zero and
|
||||
\Var{valp} to point to the word that receives the read value. To
|
||||
write memory, \Prog{libunwind} sets argument \Var{write} to a non-zero
|
||||
value and \Var{valp} to point to the word that contains the value to
|
||||
be written. The word that \Var{valp} points to is always in the
|
||||
byte-order of the host-platform, regardless of the byte-order of the
|
||||
target. In other words, it is the responsibility of the call-back
|
||||
routine to convert between the target's and the host's byte-order, if
|
||||
necessary.
|
||||
|
||||
On successful completion, the \Func{access\_mem}()
|
||||
call-back must return zero. Otherwise, the negative value of one of
|
||||
the \Type{unw\_error\_t} error-codes may be returned.
|
||||
|
||||
\subsection{access\_reg}
|
||||
|
||||
\Prog{Libunwind} invokes the \Func{access\_reg}() call-back to read
|
||||
from or write to a scalar (non-floating-point) CPU register. The
|
||||
index of the register to be accessed is passed in argument
|
||||
\Var{regnum}. To read a register, \Prog{libunwind} sets argument
|
||||
\Var{write} to zero and \Var{valp} to point to the word that receives
|
||||
the read value. To write a register, \Prog{libunwind} sets argument
|
||||
\Var{write} to a non-zero value and \Var{valp} to point to the word
|
||||
that contains the value to be written. The word that \Var{valp}
|
||||
points to is always in the byte-order of the host-platform, regardless
|
||||
of the byte-order of the target. In other words, it is the
|
||||
responsibility of the call-back routine to convert between the
|
||||
target's and the host's byte-order, if necessary.
|
||||
|
||||
On successful completion, the \Func{access\_reg}() call-back must
|
||||
return zero. Otherwise, the negative value of one of the
|
||||
\Type{unw\_error\_t} error-codes may be returned.
|
||||
|
||||
\subsection{access\_fpreg}
|
||||
|
||||
\Prog{Libunwind} invokes the \Func{access\_fpreg}() call-back to read
|
||||
from or write to a floating-point CPU register. The index of the
|
||||
register to be accessed is passed in argument \Var{regnum}. To read a
|
||||
register, \Prog{libunwind} sets argument \Var{write} to zero and
|
||||
\Var{fpvalp} to point to a variable of type \Type{unw\_fpreg\_t} that
|
||||
receives the read value. To write a register, \Prog{libunwind} sets
|
||||
argument \Var{write} to a non-zero value and \Var{fpvalp} to point to
|
||||
the variable of type \Type{unw\_fpreg\_t} that contains the value to
|
||||
be written. The word that \Var{fpvalp} points to is always in the
|
||||
byte-order of the host-platform, regardless of the byte-order of the
|
||||
target. In other words, it is the responsibility of the call-back
|
||||
routine to convert between the target's and the host's byte-order, if
|
||||
necessary.
|
||||
|
||||
On successful completion, the \Func{access\_fpreg}() call-back must
|
||||
return zero. Otherwise, the negative value of one of the
|
||||
\Type{unw\_error\_t} error-codes may be returned.
|
||||
|
||||
\subsection{resume}
|
||||
|
||||
\Prog{Libunwind} invokes the \Func{resume}() call-back to resume
|
||||
execution in the target address space. Argument \Var{cp} is the
|
||||
unwind-cursor that identifies the stack-frame in which execution
|
||||
should resume. By the time \Prog{libunwind} invokes the \Func{resume}
|
||||
call-back, it has already established the desired machine- and
|
||||
memory-state via calls to the \Func{access\_reg}(),
|
||||
\Func{access\_fpreg}, and \Func{access\_mem}() call-backs. Thus, all
|
||||
the call-back needs to do is perform whatever action is needed to
|
||||
actually resume execution.
|
||||
|
||||
The \Func{resume} call-back is invoked only in response to a call to
|
||||
\Func{unw\_resume}(3), so applications which never invoke
|
||||
\Func{unw\_resume}(3) need not define the \Func{resume} callback.
|
||||
|
||||
On successful completion, the \Func{resume}() call-back must return
|
||||
zero. Otherwise, the negative value of one of the
|
||||
\Type{unw\_error\_t} error-codes may be returned. As a special case,
|
||||
when resuming execution in the local address space, the call-back will
|
||||
not return on success.
|
||||
|
||||
\subsection{get\_proc\_name}
|
||||
|
||||
\Prog{Libunwind} invokes the \Func{get\_proc\_name}() call-back to
|
||||
obtain the procedure-name of a static (not dynamically generated)
|
||||
procedure. Argument \Var{addr} is an instruction-address within the
|
||||
procedure whose name is to be obtained. The \Var{bufp} argument is a
|
||||
pointer to a character-buffer used to return the procedure name. The
|
||||
size of this buffer is specified in argument \Var{buf\_len}. The
|
||||
returned name must be terminated by a NUL character. If the
|
||||
procedure's name is longer than \Var{buf\_len} bytes, it must be
|
||||
truncated to \Var{buf\_len}\Prog{-1} bytes, with the last byte in the
|
||||
buffer set to the NUL character and -\Const{UNW\_ENOMEM} must be
|
||||
returned. Argument \Var{offp} is a pointer to a word which is used to
|
||||
return the byte-offset relative to the start of the procedure whose
|
||||
name is being returned. For example, if procedure \Func{foo}() starts
|
||||
at address 0x40003000, then invoking \Func{get\_proc\_name}() with
|
||||
\Var{addr} set to 0x40003080 should return a value of 0x80 in the word
|
||||
pointed to by \Var{offp} (assuming the procedure is at least 0x80
|
||||
bytes long).
|
||||
|
||||
On successful completion, the \Func{get\_proc\_name}() call-back must
|
||||
return zero. Otherwise, the negative value of one of the
|
||||
\Type{unw\_error\_t} error-codes may be returned.
|
||||
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_create\_addr\_space}() returns a
|
||||
non-\Const{NULL} value that represents the newly created
|
||||
address-space. Otherwise, \Const{NULL} is returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_create\_addr\_space}() is thread-safe but \emph{not}
|
||||
safe to use from a signal handler.
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{\_U\_dyn\_register(3)},
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_destroy\_addr\_space(3)},
|
||||
\SeeAlso{unw\_get\_proc\_info(3)},
|
||||
\SeeAlso{unw\_init\_remote(3)},
|
||||
\SeeAlso{unw\_resume(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,57 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_DESTROY\\_ADDR\\_SPACE" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_destroy_addr_space
|
||||
\-\- destroy unwind address space
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
void
|
||||
unw_destroy_addr_space(unw_addr_space_t
|
||||
as);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_destroy_addr_space()
|
||||
routine destroys the
|
||||
address space specified by argument as
|
||||
and thereby releases
|
||||
all associated resources (such as memory).
|
||||
.PP
|
||||
Applications must not destroy the local address space
|
||||
unw_local_addr_space\&.
|
||||
Attempting to do so results in
|
||||
undefined behavior (e.g., the application may crash).
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_create_addr_space(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,40 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_destroy\_addr\_space}{David Mosberger-Tang}{Programming Library}{unw\_destroy\_addr\_space}unw\_destroy\_addr\_space -- destroy unwind address space
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{void} \Func{unw\_destroy\_addr\_space}(\Type{unw\_addr\_space\_t} \Var{as});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_destroy\_addr\_space}() routine destroys the
|
||||
address space specified by argument \Var{as} and thereby releases
|
||||
all associated resources (such as memory).
|
||||
|
||||
Applications must not destroy the local address space
|
||||
\Var{unw\_local\_addr\_space}. Attempting to do so results in
|
||||
undefined behavior (e.g., the application may crash).
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_create\_addr\_space(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,92 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_FLUSH\\_CACHE" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_flush_cache
|
||||
\-\- flush cached info
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
void
|
||||
unw_flush_cache(unw_addr_space_t
|
||||
as,
|
||||
unw_word_t
|
||||
lo,
|
||||
unw_word_t
|
||||
hi);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_flush_cache()
|
||||
routine flushes all cached info as it
|
||||
relates to address\-range lo
|
||||
to hi
|
||||
(non\-inclusive) in the
|
||||
target address\-space as\&.
|
||||
In addition, all info cached for
|
||||
address\-space as
|
||||
that is not tied to a particular code\-range is
|
||||
also flushed. For example, the address of the dynamic registration
|
||||
list is not tied to a code\-range and its cached value (if any) is
|
||||
flushed by a call to this routine. The address range specified by
|
||||
lo
|
||||
and hi
|
||||
should be understood as a hint:
|
||||
unw_flush_cache()
|
||||
may flush more information than requested,
|
||||
but \fInever\fP
|
||||
less. In other words, unw_flush_cache()
|
||||
may
|
||||
overflush, but not underflush.
|
||||
.PP
|
||||
As a special case, if arguments lo
|
||||
and hi
|
||||
are both 0, all
|
||||
information cached on behalf of address space as
|
||||
is flushed.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
The unw_flush_cache()
|
||||
routine cannot fail and does not
|
||||
return a value.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
The unw_flush_cache()
|
||||
routine is thread\-safe as well as safe to
|
||||
use from a signal handler.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_set_caching_policy(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,57 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_flush\_cache}{David Mosberger-Tang}{Programming Library}{unw\_flush\_cache}unw\_flush\_cache -- flush cached info
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{void} \Func{unw\_flush\_cache}(\Type{unw\_addr\_space\_t} \Var{as}, \Type{unw\_word\_t} \Var{lo}, \Type{unw\_word\_t} \Var{hi});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_flush\_cache}() routine flushes all cached info as it
|
||||
relates to address-range \Var{lo} to \Var{hi} (non-inclusive) in the
|
||||
target address-space \Var{as}. In addition, all info cached for
|
||||
address-space \Var{as} that is not tied to a particular code-range is
|
||||
also flushed. For example, the address of the dynamic registration
|
||||
list is not tied to a code-range and its cached value (if any) is
|
||||
flushed by a call to this routine. The address range specified by
|
||||
\Var{lo} and \Var{hi} should be understood as a hint:
|
||||
\Func{unw\_flush\_cache}() may flush more information than requested,
|
||||
but \emph{never} less. In other words, \Func{unw\_flush\_cache}() may
|
||||
overflush, but not underflush.
|
||||
|
||||
As a special case, if arguments \Var{lo} and \Var{hi} are both 0, all
|
||||
information cached on behalf of address space \Var{as} is flushed.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
The \Func{unw\_flush\_cache}() routine cannot fail and does not
|
||||
return a value.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
The \Func{unw\_flush\_cache}() routine is thread-safe as well as safe to
|
||||
use from a signal handler.
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_set\_caching\_policy(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,79 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_GET\\_ACCESSORS" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_get_accessors
|
||||
\-\- get pointer to accessor call\-backs
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
unw_accessors_t *unw_get_accessors(unw_addr_space_t as);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_get_accessors()
|
||||
routine returns a pointer to a
|
||||
unw_accessors_t
|
||||
structure, which contains the call\-back
|
||||
routines that were specified when address space as
|
||||
was created
|
||||
(see unw_create_addr_space(3)).
|
||||
The returned pointer is
|
||||
guaranteed to remain valid until address space as
|
||||
is destroyed
|
||||
by a call to unw_destroy_addr_space(3).
|
||||
.PP
|
||||
Note that unw_get_accessors()
|
||||
can be used to retrieve the
|
||||
call\-back routines for the local address space
|
||||
unw_local_addr_space\&.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
The unw_get_accessors()
|
||||
routine cannot fail and always
|
||||
returns a valid (non\-NULL)
|
||||
pointer to an
|
||||
unw_accessors_t
|
||||
structure.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
The unw_get_accessors()
|
||||
routine is thread\-safe as well as
|
||||
safe to use from a signal handler.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_create_addr_space(3),
|
||||
unw_destroy_addr_space(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,55 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_get\_accessors}{David Mosberger-Tang}{Programming Library}{unw\_get\_accessors}unw\_get\_accessors -- get pointer to accessor call-backs
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{unw\_accessors\_t~*}\Func{unw\_get\_accessors}(\Type{unw\_addr\_space\_t~}\Var{as});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_get\_accessors}() routine returns a pointer to a
|
||||
\Type{unw\_accessors\_t} structure, which contains the call-back
|
||||
routines that were specified when address space \Var{as} was created
|
||||
(see \Func{unw\_create\_addr\_space}(3)). The returned pointer is
|
||||
guaranteed to remain valid until address space \Var{as} is destroyed
|
||||
by a call to \Func{unw\_destroy\_addr\_space}(3).
|
||||
|
||||
Note that \Func{unw\_get\_accessors}() can be used to retrieve the
|
||||
call-back routines for the local address space
|
||||
\Var{unw\_local\_addr\_space}.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
The \Func{unw\_get\_accessors}() routine cannot fail and always
|
||||
returns a valid (non-\Const{NULL}) pointer to an
|
||||
\Type{unw\_accessors\_t} structure.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
The \Func{unw\_get\_accessors}() routine is thread-safe as well as
|
||||
safe to use from a signal handler.
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_create\_addr\_space(3)},
|
||||
\SeeAlso{unw\_destroy\_addr\_space(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,111 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_GET\\_FPREG" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_get_fpreg
|
||||
\-\- get contents of floating\-point register
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_get_fpreg(unw_cursor_t *cp,
|
||||
unw_regnum_t
|
||||
reg,
|
||||
unw_fpreg_t *valp);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_get_fpreg()
|
||||
routine reads the value of floating\-point
|
||||
register reg
|
||||
in the stack frame identified by cursor cp
|
||||
and stores the value in the variable pointed to by valp\&.
|
||||
.PP
|
||||
The register numbering is target\-dependent and described in separate
|
||||
manual pages (e.g., libunwind\-ia64(3) for the IA\-64 target).
|
||||
Furthermore, the exact set of accessible registers may depend on the
|
||||
type of frame that cp
|
||||
is referring to. For ordinary stack
|
||||
frames, it is normally possible to access only the preserved
|
||||
(``callee\-saved\&'') registers and frame\-related registers (such as the
|
||||
stack\-pointer). However, for signal frames (see
|
||||
unw_is_signal_frame(3)),
|
||||
it is usually possible to access
|
||||
all registers.
|
||||
.PP
|
||||
Note that unw_get_fpreg()
|
||||
can only read the contents of
|
||||
floating\-point registers. See unw_get_fpreg(3)
|
||||
for a way to
|
||||
read registers which fit in a single word.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_get_fpreg()
|
||||
returns 0.
|
||||
Otherwise the negative value of one of the error\-codes below is
|
||||
returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_get_fpreg()
|
||||
is thread\-safe as well as safe to use
|
||||
from a signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_EBADREG
|
||||
An attempt was made to read a register
|
||||
that is either invalid or not accessible in the current frame.
|
||||
.PP
|
||||
In addition, unw_get_fpreg()
|
||||
may return any error returned by
|
||||
the access_mem(),
|
||||
access_reg(),
|
||||
and
|
||||
access_fpreg()
|
||||
call\-backs (see
|
||||
unw_create_addr_space(3)).
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
libunwind\-ia64(3),
|
||||
unw_get_reg(3),
|
||||
unw_is_fpreg(3),
|
||||
unw_is_signal_frame(3),
|
||||
unw_set_fpreg(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,77 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_get\_fpreg}{David Mosberger-Tang}{Programming Library}{unw\_get\_fpreg}unw\_get\_fpreg -- get contents of floating-point register
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_get\_fpreg}(\Type{unw\_cursor\_t~*}\Var{cp}, \Type{unw\_regnum\_t} \Var{reg}, \Type{unw\_fpreg\_t~*}\Var{valp});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_get\_fpreg}() routine reads the value of floating-point
|
||||
register \Var{reg} in the stack frame identified by cursor \Var{cp}
|
||||
and stores the value in the variable pointed to by \Var{valp}.
|
||||
|
||||
The register numbering is target-dependent and described in separate
|
||||
manual pages (e.g., libunwind-ia64(3) for the IA-64 target).
|
||||
Furthermore, the exact set of accessible registers may depend on the
|
||||
type of frame that \Var{cp} is referring to. For ordinary stack
|
||||
frames, it is normally possible to access only the preserved
|
||||
(``callee-saved'') registers and frame-related registers (such as the
|
||||
stack-pointer). However, for signal frames (see
|
||||
\Func{unw\_is\_signal\_frame}(3)), it is usually possible to access
|
||||
all registers.
|
||||
|
||||
Note that \Func{unw\_get\_fpreg}() can only read the contents of
|
||||
floating-point registers. See \Func{unw\_get\_fpreg}(3) for a way to
|
||||
read registers which fit in a single word.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_get\_fpreg}() returns 0.
|
||||
Otherwise the negative value of one of the error-codes below is
|
||||
returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_get\_fpreg}() is thread-safe as well as safe to use
|
||||
from a signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_EBADREG}] An attempt was made to read a register
|
||||
that is either invalid or not accessible in the current frame.
|
||||
\end{Description}
|
||||
In addition, \Func{unw\_get\_fpreg}() may return any error returned by
|
||||
the \Func{access\_mem}(), \Func{access\_reg}(), and
|
||||
\Func{access\_fpreg}() call-backs (see
|
||||
\Func{unw\_create\_addr\_space}(3)).
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{libunwind-ia64(3)},
|
||||
\SeeAlso{unw\_get\_reg(3)},
|
||||
\SeeAlso{unw\_is\_fpreg(3)},
|
||||
\SeeAlso{unw\_is\_signal\_frame(3)},
|
||||
\SeeAlso{unw\_set\_fpreg(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,203 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:44 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_GET\\_PROC\\_INFO" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_get_proc_info
|
||||
\-\- get info on current procedure
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_get_proc_info(unw_cursor_t *cp,
|
||||
unw_proc_info_t *pip);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_get_proc_info()
|
||||
routine returns auxiliary
|
||||
information about the procedure that created the stack frame
|
||||
identified by argument cp\&.
|
||||
The pip
|
||||
argument is a pointer
|
||||
to a structure of type unw_proc_info_t
|
||||
which is used to
|
||||
return the information. The unw_proc_info_t
|
||||
has the
|
||||
following members:
|
||||
.TP
|
||||
unw_word_t start_ip
|
||||
The address of the first
|
||||
instruction of the procedure. If this address cannot be determined
|
||||
(e.g., due to lack of unwind information), the start_ip
|
||||
member is cleared to 0.
|
||||
.br
|
||||
.TP
|
||||
unw_word_t end_ip
|
||||
The address of the first
|
||||
instruction \fIbeyond\fP
|
||||
the end of the procedure. If this address
|
||||
cannot be determined (e.g., due to lack of unwind information),
|
||||
the end_ip
|
||||
member is cleared to 0.
|
||||
.br
|
||||
.TP
|
||||
unw_word_t lsda
|
||||
The address of the
|
||||
language\-specific data\-area (LSDA). This area normally contains
|
||||
language\-specific information needed during exception handling. If
|
||||
the procedure has no such area, this member is cleared to 0.
|
||||
.br
|
||||
.TP
|
||||
unw_word_t handler
|
||||
The address of the exception
|
||||
handler routine. This is sometimes called the \fIpersonality\fP
|
||||
routine. If the procedure does not define
|
||||
a personality routine, the handler
|
||||
member is cleared to 0.
|
||||
.br
|
||||
.TP
|
||||
unw_word_t gp
|
||||
The global\-pointer of the
|
||||
procedure. On platforms that do not use a global pointer, this
|
||||
member may contain an undefined value. On all other platforms, it
|
||||
must be set either to the correct global\-pointer value of the
|
||||
procedure or to 0 if the proper global\-pointer cannot be
|
||||
obtained for some reason.
|
||||
.br
|
||||
.TP
|
||||
unw_word_t flags
|
||||
A set of flags. There are
|
||||
currently no target\-independent flags. For the IA\-64 target, the
|
||||
flag UNW_PI_FLAG_IA64_RBS_SWITCH
|
||||
is set if the
|
||||
procedure may switch the register\-backing store.
|
||||
.br
|
||||
.TP
|
||||
int format
|
||||
The format of the unwind\-info for this
|
||||
procedure. If the unwind\-info consists of dynamic procedure info,
|
||||
format
|
||||
is equal to UNW_INFO_FORMAT_DYNAMIC\&.
|
||||
If the
|
||||
unwind\-info consists of a (target\-specific) unwind table, it is
|
||||
equal to to UNW_INFO_FORMAT_TABLE\&.
|
||||
All other values are
|
||||
reserved for future use by libunwind\&.
|
||||
This member exists
|
||||
for use by the find_proc_info()
|
||||
call\-back (see
|
||||
unw_create_addr_space(3)).
|
||||
The
|
||||
unw_get_proc_info()
|
||||
routine
|
||||
may return an undefined value in this member.
|
||||
.br
|
||||
.TP
|
||||
int unwind_info_size
|
||||
The size of the unwind\-info
|
||||
in bytes. This member exists for use by the
|
||||
find_proc_info()
|
||||
call\-back (see
|
||||
unw_create_addr_space(3)).
|
||||
The
|
||||
unw_get_proc_info()
|
||||
routine
|
||||
may return an undefined value in this member.
|
||||
.br
|
||||
.TP
|
||||
void *unwind_info
|
||||
The pointer to the unwind\-info.
|
||||
If no unwind info is available, this member must be set to
|
||||
NULL\&.
|
||||
This member exists for use by the
|
||||
find_proc_info()
|
||||
call\-back (see
|
||||
unw_create_addr_space(3)).
|
||||
The
|
||||
unw_get_proc_info()
|
||||
routine
|
||||
may return an undefined value in this member.
|
||||
.br
|
||||
.PP
|
||||
Note that for the purposes of libunwind,
|
||||
the code of a
|
||||
procedure is assumed to occupy a single, contiguous range of
|
||||
addresses. For this reason, it is alwas possible to describe the
|
||||
extent of a procedure with the start_ip
|
||||
and end_ip
|
||||
members. If a single function/routine is split into multiple,
|
||||
discontiguous pieces, libunwind
|
||||
will treat each piece as a
|
||||
separate procedure.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_get_proc_info()
|
||||
returns 0.
|
||||
Otherwise the negative value of one of the error\-codes below is
|
||||
returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_get_proc_info()
|
||||
is thread\-safe. If cursor cp
|
||||
is
|
||||
in the local address\-space, this routine is also safe to use from a
|
||||
signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_ENOINFO
|
||||
Libunwind
|
||||
was unable to locate
|
||||
unwind\-info for the procedure.
|
||||
.TP
|
||||
UNW_EBADVERSION
|
||||
The unwind\-info for the procedure has
|
||||
version or format that is not understood by libunwind\&.
|
||||
.PP
|
||||
In addition, unw_get_proc_info()
|
||||
may return any error
|
||||
returned by the access_mem()
|
||||
call\-back (see
|
||||
unw_create_addr_space(3)).
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_create_addr_space(3),
|
||||
unw_get_proc_name(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,123 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_get\_proc\_info}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_info}unw\_get\_proc\_info -- get info on current procedure
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_get\_proc\_info}(\Type{unw\_cursor\_t~*}\Var{cp}, \Type{unw\_proc\_info\_t~*}\Var{pip});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_get\_proc\_info}() routine returns auxiliary
|
||||
information about the procedure that created the stack frame
|
||||
identified by argument \Var{cp}. The \Var{pip} argument is a pointer
|
||||
to a structure of type \Type{unw\_proc\_info\_t} which is used to
|
||||
return the information. The \Type{unw\_proc\_info\_t} has the
|
||||
following members:
|
||||
\begin{description}
|
||||
\item[\Type{unw\_word\_t} \Var{start\_ip}] The address of the first
|
||||
instruction of the procedure. If this address cannot be determined
|
||||
(e.g., due to lack of unwind information), the \Var{start\_ip}
|
||||
member is cleared to 0. \\
|
||||
\item[\Type{unw\_word\_t} \Var{end\_ip}] The address of the first
|
||||
instruction \emph{beyond} the end of the procedure. If this address
|
||||
cannot be determined (e.g., due to lack of unwind information),
|
||||
the \Var{end\_ip} member is cleared to 0. \\
|
||||
\item[\Type{unw\_word\_t} \Var{lsda}] The address of the
|
||||
language-specific data-area (LSDA). This area normally contains
|
||||
language-specific information needed during exception handling. If
|
||||
the procedure has no such area, this member is cleared to 0. \\
|
||||
\item[\Type{unw\_word\_t} \Var{handler}] The address of the exception
|
||||
handler routine. This is sometimes called the \emph{personality}
|
||||
routine. If the procedure does not define
|
||||
a personality routine, the \Var{handler} member is cleared to 0. \\
|
||||
\item[\Type{unw\_word\_t} \Var{gp}] The global-pointer of the
|
||||
procedure. On platforms that do not use a global pointer, this
|
||||
member may contain an undefined value. On all other platforms, it
|
||||
must be set either to the correct global-pointer value of the
|
||||
procedure or to 0 if the proper global-pointer cannot be
|
||||
obtained for some reason. \\
|
||||
\item[\Type{unw\_word\_t} \Var{flags}] A set of flags. There are
|
||||
currently no target-independent flags. For the IA-64 target, the
|
||||
flag \Const{UNW\_PI\_FLAG\_IA64\_RBS\_SWITCH} is set if the
|
||||
procedure may switch the register-backing store.\\
|
||||
\item[\Type{int} \Var{format}] The format of the unwind-info for this
|
||||
procedure. If the unwind-info consists of dynamic procedure info,
|
||||
\Var{format} is equal to \Const{UNW\_INFO\_FORMAT\_DYNAMIC}. If the
|
||||
unwind-info consists of a (target-specific) unwind table, it is
|
||||
equal to to \Const{UNW\_INFO\_FORMAT\_TABLE}. All other values are
|
||||
reserved for future use by \Prog{libunwind}. This member exists
|
||||
for use by the \Func{find\_proc\_info}() call-back (see
|
||||
\Func{unw\_create\_addr\_space}(3)). The
|
||||
\Func{unw\_get\_proc\_info}() routine
|
||||
may return an undefined value in this member. \\
|
||||
\item[\Type{int} \Var{unwind\_info\_size}] The size of the unwind-info
|
||||
in bytes. This member exists for use by the
|
||||
\Func{find\_proc\_info}() call-back (see
|
||||
\Func{unw\_create\_addr\_space}(3)). The
|
||||
\Func{unw\_get\_proc\_info}() routine
|
||||
may return an undefined value in this member.\\
|
||||
\item[\Type{void~*}\Var{unwind\_info}] The pointer to the unwind-info.
|
||||
If no unwind info is available, this member must be set to
|
||||
\Const{NULL}. This member exists for use by the
|
||||
\Func{find\_proc\_info}() call-back (see
|
||||
\Func{unw\_create\_addr\_space}(3)). The
|
||||
\Func{unw\_get\_proc\_info}() routine
|
||||
may return an undefined value in this member.\\
|
||||
\end{description}
|
||||
Note that for the purposes of \Prog{libunwind}, the code of a
|
||||
procedure is assumed to occupy a single, contiguous range of
|
||||
addresses. For this reason, it is alwas possible to describe the
|
||||
extent of a procedure with the \Var{start\_ip} and \Var{end\_ip}
|
||||
members. If a single function/routine is split into multiple,
|
||||
discontiguous pieces, \Prog{libunwind} will treat each piece as a
|
||||
separate procedure.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_get\_proc\_info}() returns 0.
|
||||
Otherwise the negative value of one of the error-codes below is
|
||||
returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_get\_proc\_info}() is thread-safe. If cursor \Var{cp} is
|
||||
in the local address-space, this routine is also safe to use from a
|
||||
signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_ENOINFO}] \Prog{Libunwind} was unable to locate
|
||||
unwind-info for the procedure.
|
||||
\item[\Const{UNW\_EBADVERSION}] The unwind-info for the procedure has
|
||||
version or format that is not understood by \Prog{libunwind}.
|
||||
\end{Description}
|
||||
In addition, \Func{unw\_get\_proc\_info}() may return any error
|
||||
returned by the \Func{access\_mem}() call-back (see
|
||||
\Func{unw\_create\_addr\_space}(3)).
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_create\_addr\_space(3)},
|
||||
\SeeAlso{unw\_get\_proc\_name(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,134 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_GET\\_PROC\\_INFO\\_BY\\_IP" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_get_proc_info_by_ip
|
||||
\-\- get procedure info by IP
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_get_proc_info_by_ip(unw_addr_space_t as,
|
||||
unw_word_t ip,
|
||||
unw_proc_info_t *pip,
|
||||
void *arg);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_get_proc_info_by_ip()
|
||||
routine returns the same
|
||||
kind of auxiliary information about a procedure as
|
||||
unw_get_proc_info(),
|
||||
except that the info is looked up by
|
||||
instruction\-pointer (IP) instead of a cursor. This is more flexible
|
||||
because it is possible to look up the info for an arbitrary procedure,
|
||||
even if it is not part of the current call\-chain. However, since it
|
||||
is more flexible, it also tends to run slower (and often much slower)
|
||||
than unw_get_proc_info().
|
||||
.PP
|
||||
The routine expects the followins arguments: as
|
||||
is the
|
||||
address\-space in which the instruction\-pointer should be looked up.
|
||||
For a look\-up in the local address\-space,
|
||||
unw_local_addr_space
|
||||
can be passed for this argument.
|
||||
Argument ip
|
||||
is the instruction\-pointer for which the procedure
|
||||
info should be looked up and pip
|
||||
is a pointer to a structure of
|
||||
type unw_proc_info_t
|
||||
which is used to return the info.
|
||||
Lastly, arg
|
||||
is the address\-space argument that should be used
|
||||
when accessing the address\-space. It has the same purpose as the
|
||||
argument of the same name for unw_init_remote().
|
||||
When
|
||||
accessing the local address\-space (first argument is
|
||||
unw_local_addr_space),
|
||||
NULL
|
||||
must be passed for this
|
||||
argument.
|
||||
.PP
|
||||
Note that for the purposes of libunwind,
|
||||
the code of a
|
||||
procedure is assumed to occupy a single, contiguous range of
|
||||
addresses. For this reason, it is alwas possible to describe the
|
||||
extent of a procedure with the start_ip
|
||||
and end_ip
|
||||
members. If a single function/routine is split into multiple,
|
||||
discontiguous pieces, libunwind
|
||||
will treat each piece as a
|
||||
separate procedure.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_get_proc_info_by_ip()
|
||||
returns 0. Otherwise the negative value of one of the error\-codes
|
||||
below is returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_get_proc_info()
|
||||
is thread\-safe. If the local
|
||||
address\-space is passed in argument as,
|
||||
this routine is also
|
||||
safe to use from a signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_ENOINFO
|
||||
Libunwind
|
||||
was unable to locate
|
||||
unwind\-info for the procedure.
|
||||
.TP
|
||||
UNW_EBADVERSION
|
||||
The unwind\-info for the procedure has
|
||||
version or format that is not understood by libunwind\&.
|
||||
.PP
|
||||
In addition, unw_get_proc_info()
|
||||
may return any error
|
||||
returned by the access_mem()
|
||||
call\-back (see
|
||||
unw_create_addr_space(3)).
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_create_addr_space(3),
|
||||
unw_get_proc_name(3),
|
||||
unw_get_proc_info(3),
|
||||
unw_init_remote(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,91 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_get\_proc\_info\_by\_ip}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_info\_by\_ip}unw\_get\_proc\_info\_by\_ip -- get procedure info by IP
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_get\_proc\_info\_by\_ip}(\Type{unw\_addr\_space\_t~}\Var{as}, \Type{unw\_word\_t~}\Var{ip}, \Type{unw\_proc\_info\_t~*}\Var{pip}, \Type{void~*}\Var{arg});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_get\_proc\_info\_by\_ip}() routine returns the same
|
||||
kind of auxiliary information about a procedure as
|
||||
\Func{unw\_get\_proc\_info}(), except that the info is looked up by
|
||||
instruction-pointer (IP) instead of a cursor. This is more flexible
|
||||
because it is possible to look up the info for an arbitrary procedure,
|
||||
even if it is not part of the current call-chain. However, since it
|
||||
is more flexible, it also tends to run slower (and often much slower)
|
||||
than \Func{unw\_get\_proc\_info}().
|
||||
|
||||
The routine expects the followins arguments: \Var{as} is the
|
||||
address-space in which the instruction-pointer should be looked up.
|
||||
For a look-up in the local address-space,
|
||||
\Var{unw\_local\_addr\_space} can be passed for this argument.
|
||||
Argument \Var{ip} is the instruction-pointer for which the procedure
|
||||
info should be looked up and \Var{pip} is a pointer to a structure of
|
||||
type \Type{unw\_proc\_info\_t} which is used to return the info.
|
||||
Lastly, \Var{arg} is the address-space argument that should be used
|
||||
when accessing the address-space. It has the same purpose as the
|
||||
argument of the same name for \Func{unw\_init\_remote}(). When
|
||||
accessing the local address-space (first argument is
|
||||
\Var{unw\_local\_addr\_space}), \Const{NULL} must be passed for this
|
||||
argument.
|
||||
|
||||
Note that for the purposes of \Prog{libunwind}, the code of a
|
||||
procedure is assumed to occupy a single, contiguous range of
|
||||
addresses. For this reason, it is alwas possible to describe the
|
||||
extent of a procedure with the \Var{start\_ip} and \Var{end\_ip}
|
||||
members. If a single function/routine is split into multiple,
|
||||
discontiguous pieces, \Prog{libunwind} will treat each piece as a
|
||||
separate procedure.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_get\_proc\_info\_by\_ip}()
|
||||
returns 0. Otherwise the negative value of one of the error-codes
|
||||
below is returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_get\_proc\_info}() is thread-safe. If the local
|
||||
address-space is passed in argument \Var{as}, this routine is also
|
||||
safe to use from a signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_ENOINFO}] \Prog{Libunwind} was unable to locate
|
||||
unwind-info for the procedure.
|
||||
\item[\Const{UNW\_EBADVERSION}] The unwind-info for the procedure has
|
||||
version or format that is not understood by \Prog{libunwind}.
|
||||
\end{Description}
|
||||
In addition, \Func{unw\_get\_proc\_info}() may return any error
|
||||
returned by the \Func{access\_mem}() call-back (see
|
||||
\Func{unw\_create\_addr\_space}(3)).
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_create\_addr\_space(3)},
|
||||
\SeeAlso{unw\_get\_proc\_name(3)},
|
||||
\SeeAlso{unw\_get\_proc\_info(3)},
|
||||
\SeeAlso{unw\_init\_remote(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,123 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_GET\\_PROC\\_NAME" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_get_proc_name
|
||||
\-\- get name of current procedure
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_get_proc_name(unw_cursor_t *cp,
|
||||
char *bufp,
|
||||
size_t
|
||||
len,
|
||||
unw_word_t *offp);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_get_proc_name()
|
||||
routine returns the name of the
|
||||
procedure that created the stack frame identified by argument
|
||||
cp\&.
|
||||
The bufp
|
||||
argument is a pointer to a character buffer
|
||||
that is at least len
|
||||
bytes long. This buffer is used to return
|
||||
the name of the procedure. The offp
|
||||
argument is a pointer to a
|
||||
word that is used to return the byte\-offset of the instruction\-pointer
|
||||
saved in the stack frame identified by cp,
|
||||
relative to the start
|
||||
of the procedure. For example, if procedure foo()
|
||||
starts at
|
||||
address 0x40003000, then invoking unw_get_proc_name()
|
||||
on a
|
||||
stack frame with an instruction\-pointer value of 0x40003080 would
|
||||
return a value of 0x80 in the word pointed to by offp
|
||||
(assuming
|
||||
the procedure is at least 0x80 bytes long).
|
||||
.PP
|
||||
Note that on some platforms there is no reliable way to distinguish
|
||||
between procedure names and ordinary labels. Furthermore, if symbol
|
||||
information has been stripped from a program, procedure names may be
|
||||
completely unavailable or may be limited to those exported via a
|
||||
dynamic symbol table. In such cases, unw_get_proc_name()
|
||||
may return the name of a label or a preceeding (nearby) procedure.
|
||||
However, the offset returned through offp
|
||||
is always relative to
|
||||
the returned name, which ensures that the value (address) of the
|
||||
returned name plus the returned offset will always be equal to the
|
||||
instruction\-pointer of the stack frame identified by cp\&.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_get_proc_name()
|
||||
returns 0.
|
||||
Otherwise the negative value of one of the error\-codes below is
|
||||
returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_get_proc_name()
|
||||
is thread\-safe. If cursor cp
|
||||
is
|
||||
in the local address\-space, this routine is also safe to use from a
|
||||
signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_ENOINFO
|
||||
Libunwind
|
||||
was unable to determine
|
||||
the name of the procedure.
|
||||
.TP
|
||||
UNW_ENOMEM
|
||||
The procedure name is too long to fit
|
||||
in the buffer provided. A truncated version of the name has been
|
||||
returned.
|
||||
.PP
|
||||
In addition, unw_get_proc_name()
|
||||
may return any error
|
||||
returned by the access_mem()
|
||||
call\-back (see
|
||||
unw_create_addr_space(3)).
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_get_proc_info(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,82 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_get\_proc\_name}{David Mosberger-Tang}{Programming Library}{unw\_get\_proc\_name}unw\_get\_proc\_name -- get name of current procedure
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_get\_proc\_name}(\Type{unw\_cursor\_t~*}\Var{cp}, \Type{char~*}\Var{bufp}, \Type{size\_t} \Var{len}, \Type{unw\_word\_t~*}\Var{offp});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_get\_proc\_name}() routine returns the name of the
|
||||
procedure that created the stack frame identified by argument
|
||||
\Var{cp}. The \Var{bufp} argument is a pointer to a character buffer
|
||||
that is at least \Var{len} bytes long. This buffer is used to return
|
||||
the name of the procedure. The \Var{offp} argument is a pointer to a
|
||||
word that is used to return the byte-offset of the instruction-pointer
|
||||
saved in the stack frame identified by \Var{cp}, relative to the start
|
||||
of the procedure. For example, if procedure \Func{foo}() starts at
|
||||
address 0x40003000, then invoking \Func{unw\_get\_proc\_name}() on a
|
||||
stack frame with an instruction-pointer value of 0x40003080 would
|
||||
return a value of 0x80 in the word pointed to by \Var{offp} (assuming
|
||||
the procedure is at least 0x80 bytes long).
|
||||
|
||||
Note that on some platforms there is no reliable way to distinguish
|
||||
between procedure names and ordinary labels. Furthermore, if symbol
|
||||
information has been stripped from a program, procedure names may be
|
||||
completely unavailable or may be limited to those exported via a
|
||||
dynamic symbol table. In such cases, \Func{unw\_get\_proc\_name}()
|
||||
may return the name of a label or a preceeding (nearby) procedure.
|
||||
However, the offset returned through \Var{offp} is always relative to
|
||||
the returned name, which ensures that the value (address) of the
|
||||
returned name plus the returned offset will always be equal to the
|
||||
instruction-pointer of the stack frame identified by \Var{cp}.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_get\_proc\_name}() returns 0.
|
||||
Otherwise the negative value of one of the error-codes below is
|
||||
returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_get\_proc\_name}() is thread-safe. If cursor \Var{cp} is
|
||||
in the local address-space, this routine is also safe to use from a
|
||||
signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_ENOINFO}] \Prog{Libunwind} was unable to determine
|
||||
the name of the procedure.
|
||||
\item[\Const{UNW\_ENOMEM}] The procedure name is too long to fit
|
||||
in the buffer provided. A truncated version of the name has been
|
||||
returned.
|
||||
\end{Description}
|
||||
In addition, \Func{unw\_get\_proc\_name}() may return any error
|
||||
returned by the \Func{access\_mem}() call-back (see
|
||||
\Func{unw\_create\_addr\_space}(3)).
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_get\_proc\_info(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,112 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_GET\\_REG" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_get_reg
|
||||
\-\- get register contents
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_get_reg(unw_cursor_t *cp,
|
||||
unw_regnum_t
|
||||
reg,
|
||||
unw_word_t *valp);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_get_reg()
|
||||
routine reads the value of register
|
||||
reg
|
||||
in the stack frame identified by cursor cp
|
||||
and stores
|
||||
the value in the word pointed to by valp\&.
|
||||
.PP
|
||||
The register numbering is target\-dependent and described in separate
|
||||
manual pages (e.g., libunwind\-ia64(3) for the IA\-64 target).
|
||||
Furthermore, the exact set of accessible registers may depend on the
|
||||
type of frame that cp
|
||||
is referring to. For ordinary stack
|
||||
frames, it is normally possible to access only the preserved
|
||||
(``callee\-saved\&'') registers and frame\-related registers (such as the
|
||||
stack\-pointer). However, for signal frames (see
|
||||
unw_is_signal_frame(3)),
|
||||
it is usually possible to access
|
||||
all registers.
|
||||
.PP
|
||||
Note that unw_get_reg()
|
||||
can only read the contents of
|
||||
registers whose values fit in a single word. See
|
||||
unw_get_fpreg(3)
|
||||
for a way to read registers which do not fit
|
||||
this constraint.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_get_reg()
|
||||
returns 0.
|
||||
Otherwise the negative value of one of the error\-codes below is
|
||||
returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_get_reg()
|
||||
is thread\-safe as well as safe to use
|
||||
from a signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_EBADREG
|
||||
An attempt was made to read a register
|
||||
that is either invalid or not accessible in the current frame.
|
||||
.PP
|
||||
In addition, unw_get_reg()
|
||||
may return any error returned by
|
||||
the access_mem(),
|
||||
access_reg(),
|
||||
and
|
||||
access_fpreg()
|
||||
call\-backs (see
|
||||
unw_create_addr_space(3)).
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
libunwind\-ia64(3),
|
||||
unw_get_fpreg(3),
|
||||
unw_is_signal_frame(3),
|
||||
unw_set_reg(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,77 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_get\_reg}{David Mosberger-Tang}{Programming Library}{unw\_get\_reg}unw\_get\_reg -- get register contents
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_get\_reg}(\Type{unw\_cursor\_t~*}\Var{cp}, \Type{unw\_regnum\_t} \Var{reg}, \Type{unw\_word\_t~*}\Var{valp});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_get\_reg}() routine reads the value of register
|
||||
\Var{reg} in the stack frame identified by cursor \Var{cp} and stores
|
||||
the value in the word pointed to by \Var{valp}.
|
||||
|
||||
The register numbering is target-dependent and described in separate
|
||||
manual pages (e.g., libunwind-ia64(3) for the IA-64 target).
|
||||
Furthermore, the exact set of accessible registers may depend on the
|
||||
type of frame that \Var{cp} is referring to. For ordinary stack
|
||||
frames, it is normally possible to access only the preserved
|
||||
(``callee-saved'') registers and frame-related registers (such as the
|
||||
stack-pointer). However, for signal frames (see
|
||||
\Func{unw\_is\_signal\_frame}(3)), it is usually possible to access
|
||||
all registers.
|
||||
|
||||
Note that \Func{unw\_get\_reg}() can only read the contents of
|
||||
registers whose values fit in a single word. See
|
||||
\Func{unw\_get\_fpreg}(3) for a way to read registers which do not fit
|
||||
this constraint.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_get\_reg}() returns 0.
|
||||
Otherwise the negative value of one of the error-codes below is
|
||||
returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_get\_reg}() is thread-safe as well as safe to use
|
||||
from a signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_EBADREG}] An attempt was made to read a register
|
||||
that is either invalid or not accessible in the current frame.
|
||||
\end{Description}
|
||||
In addition, \Func{unw\_get\_reg}() may return any error returned by
|
||||
the \Func{access\_mem}(), \Func{access\_reg}(), and
|
||||
\Func{access\_fpreg}() call-backs (see
|
||||
\Func{unw\_create\_addr\_space}(3)).
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{libunwind-ia64(3)},
|
||||
\SeeAlso{unw\_get\_fpreg(3)},
|
||||
\SeeAlso{unw\_is\_signal\_frame(3)},
|
||||
\SeeAlso{unw\_set\_reg(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,93 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_GETCONTEXT" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_getcontext
|
||||
\-\- get initial machine\-state
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_getcontext(unw_context_t *ucp);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_getcontext()
|
||||
routine initializes the context structure
|
||||
pointed to by ucp
|
||||
with the machine\-state of the call\-site. The
|
||||
exact set of registers stored by unw_getcontext()
|
||||
is
|
||||
platform\-specific, but, in general, at least all preserved
|
||||
(``callee\-saved\&'') and all frame\-related registers, such as the
|
||||
stack\-pointer, will be stored.
|
||||
.PP
|
||||
This routine is normally implemented as a macro and applications
|
||||
should not attempt to take its address.
|
||||
.PP
|
||||
.SH PLATFORM\-SPECIFIC NOTES
|
||||
|
||||
.PP
|
||||
On IA\-64, unw_context_t
|
||||
has a layout that is compatible with
|
||||
that of ucontext_t
|
||||
and such structures can be initialized with
|
||||
getcontext()
|
||||
instead of unw_getcontext().
|
||||
However, the
|
||||
reverse is \fInot\fP
|
||||
true and it is \fInot\fP
|
||||
safe to use structures
|
||||
initialized by unw_getcontext()
|
||||
in places where a structure
|
||||
initialized by getcontext()
|
||||
is expected. The reason for this
|
||||
asymmetry is that unw_getcontext()
|
||||
is optimized for maximum
|
||||
performance and does not, for example, save the signal mask.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_getcontext()
|
||||
returns 0.
|
||||
Otherwise, a value of \-1 is returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_getcontext()
|
||||
is thread\-safe as well as safe to use
|
||||
from a signal handler.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_init_local(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,63 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_getcontext}{David Mosberger-Tang}{Programming Library}{unw\_getcontext}unw\_getcontext -- get initial machine-state
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_getcontext}(\Type{unw\_context\_t~*}\Var{ucp});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_getcontext}() routine initializes the context structure
|
||||
pointed to by \Var{ucp} with the machine-state of the call-site. The
|
||||
exact set of registers stored by \Func{unw\_getcontext}() is
|
||||
platform-specific, but, in general, at least all preserved
|
||||
(``callee-saved'') and all frame-related registers, such as the
|
||||
stack-pointer, will be stored.
|
||||
|
||||
This routine is normally implemented as a macro and applications
|
||||
should not attempt to take its address.
|
||||
|
||||
\section{Platform-specific Notes}
|
||||
|
||||
On IA-64, \Type{unw\_context\_t} has a layout that is compatible with
|
||||
that of \Type{ucontext\_t} and such structures can be initialized with
|
||||
\Func{getcontext}() instead of \Func{unw\_getcontext}(). However, the
|
||||
reverse is \emph{not} true and it is \emph{not} safe to use structures
|
||||
initialized by \Func{unw\_getcontext()} in places where a structure
|
||||
initialized by \Func{getcontext()} is expected. The reason for this
|
||||
asymmetry is that \Func{unw\_getcontext()} is optimized for maximum
|
||||
performance and does not, for example, save the signal mask.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_getcontext}() returns 0.
|
||||
Otherwise, a value of -1 is returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_getcontext}() is thread-safe as well as safe to use
|
||||
from a signal handler.
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_init\_local(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,119 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_INIT\\_LOCAL" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_init_local
|
||||
\-\- initialize cursor for local unwinding
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_init_local(unw_cursor_t *c,
|
||||
unw_context_t *ctxt);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_init_local()
|
||||
routine initializes the unwind cursor
|
||||
pointed to by c
|
||||
with the machine\-state in the context structure
|
||||
pointed to by ctxt\&.
|
||||
As such, the machine\-state pointed to by
|
||||
ctxt
|
||||
identifies the initial stack frame at which unwinding
|
||||
starts. The machine\-state must remain valid for the duration for
|
||||
which the cursor c
|
||||
is in use.
|
||||
.PP
|
||||
The unw_init_local()
|
||||
routine can be used only for unwinding in
|
||||
the address space of the current process (i.e., for local unwinding).
|
||||
For all other cases, unw_init_remote()
|
||||
must be used instead.
|
||||
From a behavioral point of view, the call:
|
||||
.PP
|
||||
.Vb
|
||||
ret = unw_init_local(&cursor, &ucontext);
|
||||
.Ve
|
||||
is equivalent to:
|
||||
.PP
|
||||
.Vb
|
||||
ret = unw_init_remote(&cursor, unw_local_addr_space,
|
||||
&ucontext);
|
||||
.Ve
|
||||
However, unwind performance may be better when using
|
||||
unw_init_local().
|
||||
Also, unw_init_local()
|
||||
is
|
||||
available even when UNW_LOCAL_ONLY
|
||||
has been defined before
|
||||
including <libunwind.h>,
|
||||
whereas unw_init_remote()
|
||||
is not.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_init_local()
|
||||
returns 0.
|
||||
Otherwise the negative value of one of the error\-codes below is
|
||||
returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_init_local()
|
||||
is thread\-safe as well as safe to use from a
|
||||
signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EINVAL
|
||||
unw_init_local()
|
||||
was called in a
|
||||
version of libunwind
|
||||
which supports remote unwinding only
|
||||
(this normally happens when calling unw_init_local()
|
||||
for a
|
||||
cross\-platform version of libunwind).
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_EBADREG
|
||||
A register needed by unw_init_local()
|
||||
wasn\&'t accessible.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_init_remote(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,81 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_init\_local}{David Mosberger-Tang}{Programming Library}{unw\_init\_local}unw\_init\_local -- initialize cursor for local unwinding
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_init\_local}(\Type{unw\_cursor\_t~*}\Var{c}, \Type{unw\_context\_t~*}\Var{ctxt});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_init\_local}() routine initializes the unwind cursor
|
||||
pointed to by \Var{c} with the machine-state in the context structure
|
||||
pointed to by \Var{ctxt}. As such, the machine-state pointed to by
|
||||
\Var{ctxt} identifies the initial stack frame at which unwinding
|
||||
starts. The machine-state must remain valid for the duration for
|
||||
which the cursor \Var{c} is in use.
|
||||
|
||||
The \Func{unw\_init\_local}() routine can be used only for unwinding in
|
||||
the address space of the current process (i.e., for local unwinding).
|
||||
For all other cases, \Func{unw\_init\_remote}() must be used instead.
|
||||
From a behavioral point of view, the call:
|
||||
|
||||
\begin{verbatim}
|
||||
ret = unw_init_local(&cursor, &ucontext);
|
||||
\end{verbatim}
|
||||
is equivalent to:
|
||||
|
||||
\begin{verbatim}
|
||||
ret = unw_init_remote(&cursor, unw_local_addr_space,
|
||||
&ucontext);
|
||||
\end{verbatim}
|
||||
However, unwind performance may be better when using
|
||||
\Func{unw\_init\_local}(). Also, \Func{unw\_init\_local}() is
|
||||
available even when \Const{UNW\_LOCAL\_ONLY} has been defined before
|
||||
including \File{$<$libunwind.h$>$}, whereas \Func{unw\_init\_remote}()
|
||||
is not.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_init\_local}() returns 0.
|
||||
Otherwise the negative value of one of the error-codes below is
|
||||
returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_init\_local}() is thread-safe as well as safe to use from a
|
||||
signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EINVAL}] \Func{unw\_init\_local}() was called in a
|
||||
version of \Prog{libunwind} which supports remote unwinding only
|
||||
(this normally happens when calling \Func{unw\_init\_local}() for a
|
||||
cross-platform version of \Prog{libunwind}).
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_EBADREG}] A register needed by \Func{unw\_init\_local}()
|
||||
wasn't accessible.
|
||||
\end{Description}
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)}, \SeeAlso{unw\_init\_remote(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,123 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_INIT\\_REMOTE" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_init_remote
|
||||
\-\- initialize cursor for remote unwinding
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_init_remote(unw_cursor_t *c,
|
||||
unw_addr_space_t as,
|
||||
void *arg);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_init_remote()
|
||||
routine initializes the unwind cursor
|
||||
pointed to by c
|
||||
for unwinding in the address space identified by
|
||||
as\&.
|
||||
The as
|
||||
argument can either be set to
|
||||
unw_local_addr_space
|
||||
(local address space) or to an arbitrary
|
||||
address space created with unw_create_addr_space().
|
||||
.PP
|
||||
The arg
|
||||
void\-pointer tells the address space exactly what entity
|
||||
should be unwound. For example, if unw_local_addr_space
|
||||
is
|
||||
passed in as,
|
||||
then arg
|
||||
needs to be a pointer to a context
|
||||
structure containing the machine\-state of the initial stack frame.
|
||||
However, other address\-spaces may instead expect a process\-id, a
|
||||
thread\-id, or a pointer to an arbitrary structure which identifies the
|
||||
stack\-frame chain to be unwound. In other words, the interpretation
|
||||
of arg
|
||||
is entirely dependent on the address\-space in use;
|
||||
libunwind
|
||||
never interprets the argument in any way on its own.
|
||||
.PP
|
||||
Note that unw_init_remote()
|
||||
can be used to initiate unwinding
|
||||
in \fIany\fP
|
||||
process, including the local process in which the
|
||||
unwinder itself is running. However, for local unwinding, it is
|
||||
generally preferable to use unw_init_local()
|
||||
instead, because
|
||||
it is easier to use and because it may perform better.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_init_remote()
|
||||
returns 0.
|
||||
Otherwise the negative value of one of the error\-codes below is
|
||||
returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_init_remote()
|
||||
is thread\-safe. If the local address\-space
|
||||
is passed in argument as,
|
||||
this routine is also safe to use from
|
||||
a signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EINVAL
|
||||
unw_init_remote()
|
||||
was called in a
|
||||
version of libunwind
|
||||
which supports local unwinding only
|
||||
(this normally happens when defining UNW_LOCAL_ONLY
|
||||
before
|
||||
including <libunwind.h>
|
||||
and then calling
|
||||
unw_init_remote()).
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_EBADREG
|
||||
A register needed by unw_init_remote()
|
||||
wasn\&'t accessible.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_create_addr_space(3),
|
||||
unw_init_local(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,79 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_init\_remote}{David Mosberger-Tang}{Programming Library}{unw\_init\_remote}unw\_init\_remote -- initialize cursor for remote unwinding
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_init\_remote}(\Type{unw\_cursor\_t~*}\Var{c}, \Type{unw\_addr\_space\_t~}\Var{as}, \Type{void~*}\Var{arg});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_init\_remote}() routine initializes the unwind cursor
|
||||
pointed to by \Var{c} for unwinding in the address space identified by
|
||||
\Var{as}. The \Var{as} argument can either be set to
|
||||
\Var{unw\_local\_addr\_space} (local address space) or to an arbitrary
|
||||
address space created with \Func{unw\_create\_addr\_space}().
|
||||
|
||||
The \Var{arg} void-pointer tells the address space exactly what entity
|
||||
should be unwound. For example, if \Var{unw\_local\_addr\_space} is
|
||||
passed in \Var{as}, then \Var{arg} needs to be a pointer to a context
|
||||
structure containing the machine-state of the initial stack frame.
|
||||
However, other address-spaces may instead expect a process-id, a
|
||||
thread-id, or a pointer to an arbitrary structure which identifies the
|
||||
stack-frame chain to be unwound. In other words, the interpretation
|
||||
of \Var{arg} is entirely dependent on the address-space in use;
|
||||
\Prog{libunwind} never interprets the argument in any way on its own.
|
||||
|
||||
Note that \Func{unw\_init\_remote}() can be used to initiate unwinding
|
||||
in \emph{any} process, including the local process in which the
|
||||
unwinder itself is running. However, for local unwinding, it is
|
||||
generally preferable to use \Func{unw\_init\_local}() instead, because
|
||||
it is easier to use and because it may perform better.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_init\_remote}() returns 0.
|
||||
Otherwise the negative value of one of the error-codes below is
|
||||
returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_init\_remote}() is thread-safe. If the local address-space
|
||||
is passed in argument \Var{as}, this routine is also safe to use from
|
||||
a signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EINVAL}] \Func{unw\_init\_remote}() was called in a
|
||||
version of \Prog{libunwind} which supports local unwinding only
|
||||
(this normally happens when defining \Const{UNW\_LOCAL\_ONLY} before
|
||||
including \File{$<$libunwind.h$>$} and then calling
|
||||
\Func{unw\_init\_remote}()).
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_EBADREG}] A register needed by \Func{unw\_init\_remote}()
|
||||
wasn't accessible.
|
||||
\end{Description}
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)}, \SeeAlso{unw\_create\_addr\_space(3)},
|
||||
\SeeAlso{unw\_init\_local(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,73 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_IS\\_FPREG" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_is_fpreg
|
||||
\-\- check if a register is a floating\-point register
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_is_fpreg(unw_regnum_t
|
||||
reg);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_is_fpreg()
|
||||
routine checks whether register number
|
||||
reg
|
||||
is a floating\-point register.
|
||||
.PP
|
||||
This routine is normally implemented as a macro and applications
|
||||
should not attempt to take its address.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
The unw_is_fpreg()
|
||||
routine returns a non\-zero value if
|
||||
reg
|
||||
is a floating\-point register. Otherwise, it returns a value
|
||||
of 0.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_is_fpreg()
|
||||
is thread\-safe as well as safe to use
|
||||
from a signal handler.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_get_reg(3),
|
||||
unw_set_reg(3),
|
||||
unw_get_fpreg(3),
|
||||
unw_set_fpreg(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,52 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_is\_fpreg}{David Mosberger-Tang}{Programming Library}{unw\_is\_fpreg}unw\_is\_fpreg -- check if a register is a floating-point register
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_is\_fpreg}(\Type{unw\_regnum\_t} \Var{reg});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_is\_fpreg}() routine checks whether register number
|
||||
\Var{reg} is a floating-point register.
|
||||
|
||||
This routine is normally implemented as a macro and applications
|
||||
should not attempt to take its address.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
The \Func{unw\_is\_fpreg}() routine returns a non-zero value if
|
||||
\Var{reg} is a floating-point register. Otherwise, it returns a value
|
||||
of 0.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_is\_fpreg}() is thread-safe as well as safe to use
|
||||
from a signal handler.
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_get\_reg(3)},
|
||||
\SeeAlso{unw\_set\_reg(3)},
|
||||
\SeeAlso{unw\_get\_fpreg(3)},
|
||||
\SeeAlso{unw\_set\_fpreg(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,88 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_IS\\_SIGNAL\\_FRAME" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_is_signal_frame
|
||||
\-\- check if current frame is a signal frame
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_is_signal_frame(unw_cursor_t *cp);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_is_signal_frame()
|
||||
routine returns a positive value
|
||||
if the current frame identified by cp
|
||||
is a signal frame, and a
|
||||
value of 0 otherwise. For the purpose of this discussion, a signal
|
||||
frame is a frame that was created in response to a potentially
|
||||
asynchronous interruption. For UNIX and UNIX\-like platforms, such
|
||||
frames are normally created by the kernel when delivering a signal.
|
||||
In a kernel\-environment, a signal frame might, for example, correspond
|
||||
to a frame created in response to a device interrupt.
|
||||
.PP
|
||||
Signal frames are somewhat unusual because the asynchronous nature of
|
||||
the events that create them require storing the contents of registers
|
||||
that are normally treated as scratch (``caller\-saved\&'') registers.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_is_signal_frame()
|
||||
returns a
|
||||
positive value if the current frame is a signal frame, or 0 if it is
|
||||
not. Otherwise, a negative value of one of the error\-codes below is
|
||||
returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_is_signal_frame()
|
||||
is thread\-safe as well as safe to use
|
||||
from a signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_ENOINFO
|
||||
Libunwind
|
||||
is unable to determine
|
||||
whether or not the current frame is a signal frame.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_get_reg(3),
|
||||
unw_set_reg(3),
|
||||
unw_get_fpreg(3),
|
||||
unw_set_fpreg(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,67 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_is\_signal\_frame}{David Mosberger-Tang}{Programming Library}{unw\_is\_signal\_frame}unw\_is\_signal\_frame -- check if current frame is a signal frame
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_is\_signal\_frame}(\Type{unw\_cursor\_t~*}\Var{cp});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_is\_signal\_frame}() routine returns a positive value
|
||||
if the current frame identified by \Var{cp} is a signal frame, and a
|
||||
value of 0 otherwise. For the purpose of this discussion, a signal
|
||||
frame is a frame that was created in response to a potentially
|
||||
asynchronous interruption. For UNIX and UNIX-like platforms, such
|
||||
frames are normally created by the kernel when delivering a signal.
|
||||
In a kernel-environment, a signal frame might, for example, correspond
|
||||
to a frame created in response to a device interrupt.
|
||||
|
||||
Signal frames are somewhat unusual because the asynchronous nature of
|
||||
the events that create them require storing the contents of registers
|
||||
that are normally treated as scratch (``caller-saved'') registers.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_is\_signal\_frame}() returns a
|
||||
positive value if the current frame is a signal frame, or 0 if it is
|
||||
not. Otherwise, a negative value of one of the error-codes below is
|
||||
returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_is\_signal\_frame}() is thread-safe as well as safe to use
|
||||
from a signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_ENOINFO}] \Prog{Libunwind} is unable to determine
|
||||
whether or not the current frame is a signal frame.
|
||||
\end{Description}
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_get\_reg(3)},
|
||||
\SeeAlso{unw\_set\_reg(3)},
|
||||
\SeeAlso{unw\_get\_fpreg(3)},
|
||||
\SeeAlso{unw\_set\_fpreg(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,68 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_REGNAME" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_regname
|
||||
\-\- get register name
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
const char *unw_regname(unw_regnum_t
|
||||
regnum);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_regname()
|
||||
routine returns a printable name for
|
||||
register regnum\&.
|
||||
If regnum
|
||||
is an invalid or otherwise
|
||||
unrecognized register number, a string consisting of three question
|
||||
marks is returned. The returned string is statically allocated and
|
||||
therefore guaranteed to remain valid until the application terminates.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
The unw_regname()
|
||||
routine cannot fail and always returns a
|
||||
valid (non\-NULL)
|
||||
string.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
The unw_regname()
|
||||
routine is thread\-safe as well as safe to
|
||||
use from a signal handler.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,47 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_regname}{David Mosberger-Tang}{Programming Library}{unw\_regname}unw\_regname -- get register name
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{const char~*}\Func{unw\_regname}(\Type{unw\_regnum\_t} \Var{regnum});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_regname}() routine returns a printable name for
|
||||
register \Var{regnum}. If \Var{regnum} is an invalid or otherwise
|
||||
unrecognized register number, a string consisting of three question
|
||||
marks is returned. The returned string is statically allocated and
|
||||
therefore guaranteed to remain valid until the application terminates.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
The \Func{unw\_regname}() routine cannot fail and always returns a
|
||||
valid (non-\Const{NULL}) string.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
The \Func{unw\_regname}() routine is thread-safe as well as safe to
|
||||
use from a signal handler.
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,146 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_RESUME" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_resume
|
||||
\-\- resume execution in a particular stack frame
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_resume(unw_cursor_t *cp);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_resume()
|
||||
routine resumes execution at the stack frame
|
||||
identified by cp\&.
|
||||
The behavior of this routine differs
|
||||
slightly for local and remote unwinding.
|
||||
.PP
|
||||
For local unwinding, unw_resume()
|
||||
restores the machine state
|
||||
and then directly resumes execution in the target stack frame. Thus
|
||||
unw_resume()
|
||||
does not return in this case. Restoring the
|
||||
machine state normally involves restoring the ``preserved\&''
|
||||
(callee\-saved) registers. However, if execution in any of the stack
|
||||
frames younger (more deeply nested) than the one identified by
|
||||
cp
|
||||
was interrupted by a signal, then unw_resume()
|
||||
will
|
||||
restore all registers as well as the signal mask. Attempting to call
|
||||
unw_resume()
|
||||
on a cursor which identifies the stack frame of
|
||||
another thread results in undefined behavior (e.g., the program may
|
||||
crash).
|
||||
.PP
|
||||
For remote unwinding, unw_resume()
|
||||
installs the machine state
|
||||
identified by the cursor by calling the access_reg
|
||||
and
|
||||
access_fpreg
|
||||
accessor callbacks as needed. Once that is
|
||||
accomplished, the resume
|
||||
accessor callback is invoked. The
|
||||
unw_resume
|
||||
routine then returns normally (that is, unlikely
|
||||
for local unwinding, unw_resume
|
||||
will always return for remote
|
||||
unwinding).
|
||||
.PP
|
||||
Most platforms reserve some registers to pass arguments to exception
|
||||
handlers (e.g., IA\-64 uses r15\-r18
|
||||
for this
|
||||
purpose). These registers are normally treated like ``scratch\&''
|
||||
registers. However, if libunwind
|
||||
is used to set an exception
|
||||
argument register to a particular value (e.g., via
|
||||
unw_set_reg()),
|
||||
then unw_resume()
|
||||
will install this
|
||||
value as the contents of the register. In other words, the exception
|
||||
handling arguments are installed even in cases where normally only the
|
||||
``preserved\&'' registers are restored.
|
||||
.PP
|
||||
Note that unw_resume()
|
||||
does \fInot\fP
|
||||
invoke any unwind
|
||||
handlers (aka, ``personality routines\&''). If a program needs this, it
|
||||
will have to do so on its own by obtaining the unw_proc_info_t
|
||||
of each unwound frame and appropriately processing its unwind handler
|
||||
and language\-specific data area (lsda). These steps are generally
|
||||
dependent on the target\-platform and are regulated by the
|
||||
processor\-specific ABI (application\-binary interface).
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
For local unwinding, unw_resume()
|
||||
does not return on success.
|
||||
For remote unwinding, it returns 0 on success. On failure, the
|
||||
negative value of one of the errors below is returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_resume()
|
||||
is thread\-safe. If cursor cp
|
||||
is in the
|
||||
local address\-space, this routine is also safe to use from a signal
|
||||
handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_EBADREG
|
||||
A register needed by unw_resume()
|
||||
wasn\&'t
|
||||
accessible.
|
||||
.TP
|
||||
UNW_EINVALIDIP
|
||||
The instruction pointer identified by
|
||||
cp
|
||||
is not valid.
|
||||
.TP
|
||||
UNW_BADFRAME
|
||||
The stack frame identified by
|
||||
cp
|
||||
is not valid.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_set_reg(3),
|
||||
sigprocmask(2)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,99 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_resume}{David Mosberger-Tang}{Programming Library}{unw\_resume}unw\_resume -- resume execution in a particular stack frame
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_resume}(\Type{unw\_cursor\_t~*}\Var{cp});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_resume}() routine resumes execution at the stack frame
|
||||
identified by \Var{cp}. The behavior of this routine differs
|
||||
slightly for local and remote unwinding.
|
||||
|
||||
For local unwinding, \Func{unw\_resume}() restores the machine state
|
||||
and then directly resumes execution in the target stack frame. Thus
|
||||
\Func{unw\_resume}() does not return in this case. Restoring the
|
||||
machine state normally involves restoring the ``preserved''
|
||||
(callee-saved) registers. However, if execution in any of the stack
|
||||
frames younger (more deeply nested) than the one identified by
|
||||
\Var{cp} was interrupted by a signal, then \Func{unw\_resume}() will
|
||||
restore all registers as well as the signal mask. Attempting to call
|
||||
\Func{unw\_resume}() on a cursor which identifies the stack frame of
|
||||
another thread results in undefined behavior (e.g., the program may
|
||||
crash).
|
||||
|
||||
For remote unwinding, \Func{unw\_resume}() installs the machine state
|
||||
identified by the cursor by calling the \Func{access\_reg} and
|
||||
\Func{access\_fpreg} accessor callbacks as needed. Once that is
|
||||
accomplished, the \Func{resume} accessor callback is invoked. The
|
||||
\Func{unw\_resume} routine then returns normally (that is, unlikely
|
||||
for local unwinding, \Func{unw\_resume} will always return for remote
|
||||
unwinding).
|
||||
|
||||
Most platforms reserve some registers to pass arguments to exception
|
||||
handlers (e.g., IA-64 uses \texttt{r15}-\texttt{r18} for this
|
||||
purpose). These registers are normally treated like ``scratch''
|
||||
registers. However, if \Prog{libunwind} is used to set an exception
|
||||
argument register to a particular value (e.g., via
|
||||
\Func{unw\_set\_reg}()), then \Func{unw\_resume}() will install this
|
||||
value as the contents of the register. In other words, the exception
|
||||
handling arguments are installed even in cases where normally only the
|
||||
``preserved'' registers are restored.
|
||||
|
||||
Note that \Func{unw\_resume}() does \emph{not} invoke any unwind
|
||||
handlers (aka, ``personality routines''). If a program needs this, it
|
||||
will have to do so on its own by obtaining the \Type{unw\_proc\_info\_t}
|
||||
of each unwound frame and appropriately processing its unwind handler
|
||||
and language-specific data area (lsda). These steps are generally
|
||||
dependent on the target-platform and are regulated by the
|
||||
processor-specific ABI (application-binary interface).
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
For local unwinding, \Func{unw\_resume}() does not return on success.
|
||||
For remote unwinding, it returns 0 on success. On failure, the
|
||||
negative value of one of the errors below is returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_resume}() is thread-safe. If cursor \Var{cp} is in the
|
||||
local address-space, this routine is also safe to use from a signal
|
||||
handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_EBADREG}] A register needed by \Func{unw\_resume}() wasn't
|
||||
accessible.
|
||||
\item[\Const{UNW\_EINVALIDIP}] The instruction pointer identified by
|
||||
\Var{cp} is not valid.
|
||||
\item[\Const{UNW\_BADFRAME}] The stack frame identified by
|
||||
\Var{cp} is not valid.
|
||||
\end{Description}
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_set\_reg(3)},
|
||||
sigprocmask(2)
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,118 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_SET\\_CACHING\\_POLICY" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_set_caching_policy
|
||||
\-\- set unwind caching policy
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_set_caching_policy(unw_addr_space_t
|
||||
as,
|
||||
unw_caching_policy_t
|
||||
policy);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_set_caching_policy()
|
||||
routine sets the caching policy
|
||||
of address space as
|
||||
to the policy specified by argument
|
||||
policy\&.
|
||||
The policy
|
||||
argument can take one of three
|
||||
possible values:
|
||||
.TP
|
||||
UNW_CACHE_NONE
|
||||
Turns off caching completely. This
|
||||
also implicitly flushes the contents of all caches as if
|
||||
unw_flush_cache()
|
||||
had been called.
|
||||
.TP
|
||||
UNW_CACHE_GLOBAL
|
||||
Enables caching using a global cache
|
||||
that is shared by all threads. If global caching is unavailable or
|
||||
unsupported, libunwind
|
||||
may fall back on using a per\-thread
|
||||
cache, as if UNW_CACHE_PER_THREAD
|
||||
had been specified.
|
||||
.TP
|
||||
UNW_CACHE_PER_THREAD
|
||||
Enables caching using
|
||||
thread\-local caches. If a thread\-local caching are unavailable or
|
||||
unsupported, libunwind
|
||||
may fall back on using a global cache,
|
||||
as if UNW_CACHE_GLOBAL
|
||||
had been specified.
|
||||
.PP
|
||||
If caching is enabled, an application must be prepared to make
|
||||
appropriate calls to unw_flush_cache()
|
||||
whenever the target
|
||||
changes in a way that could affect the validity of cached information.
|
||||
For example, after unloading (removing) a shared library,
|
||||
unw_flush_cache()
|
||||
would have to be called (at least) for the
|
||||
address\-range that was covered by the shared library.
|
||||
.PP
|
||||
For address spaces created via unw_create_addr_space(3),
|
||||
caching is turned off by default. For the local address space
|
||||
unw_local_addr_space,
|
||||
caching is turned on by default.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_set_caching_policy()
|
||||
returns 0.
|
||||
Otherwise the negative value of one of the error\-codes below is
|
||||
returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_set_caching_policy()
|
||||
is thread\-safe but \fInot\fP
|
||||
safe
|
||||
to use from a signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_ENOMEM
|
||||
The desired caching policy could not be
|
||||
established because the application is out of memory.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_create_addr_space(3),
|
||||
unw_flush_cache(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,80 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_set\_caching\_policy}{David Mosberger-Tang}{Programming Library}{unw\_set\_caching\_policy}unw\_set\_caching\_policy -- set unwind caching policy
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_set\_caching\_policy}(\Type{unw\_addr\_space\_t} \Var{as}, \Type{unw\_caching\_policy\_t} \Var{policy});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_set\_caching\_policy}() routine sets the caching policy
|
||||
of address space \Var{as} to the policy specified by argument
|
||||
\Var{policy}. The \Var{policy} argument can take one of three
|
||||
possible values:
|
||||
\begin{description}
|
||||
\item[\Const{UNW\_CACHE\_NONE}] Turns off caching completely. This
|
||||
also implicitly flushes the contents of all caches as if
|
||||
\Func{unw\_flush\_cache}() had been called.
|
||||
\item[\Const{UNW\_CACHE\_GLOBAL}] Enables caching using a global cache
|
||||
that is shared by all threads. If global caching is unavailable or
|
||||
unsupported, \Prog{libunwind} may fall back on using a per-thread
|
||||
cache, as if \Const{UNW\_CACHE\_PER\_THREAD} had been specified.
|
||||
\item[\Const{UNW\_CACHE\_PER\_THREAD}] Enables caching using
|
||||
thread-local caches. If a thread-local caching are unavailable or
|
||||
unsupported, \Prog{libunwind} may fall back on using a global cache,
|
||||
as if \Const{UNW\_CACHE\_GLOBAL} had been specified.
|
||||
\end{description}
|
||||
|
||||
If caching is enabled, an application must be prepared to make
|
||||
appropriate calls to \Func{unw\_flush\_cache}() whenever the target
|
||||
changes in a way that could affect the validity of cached information.
|
||||
For example, after unloading (removing) a shared library,
|
||||
\Func{unw\_flush\_cache}() would have to be called (at least) for the
|
||||
address-range that was covered by the shared library.
|
||||
|
||||
For address spaces created via \Func{unw\_create\_addr\_space}(3),
|
||||
caching is turned off by default. For the local address space
|
||||
\Func{unw\_local\_addr\_space}, caching is turned on by default.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_set\_caching\_policy}() returns 0.
|
||||
Otherwise the negative value of one of the error-codes below is
|
||||
returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_set\_caching\_policy}() is thread-safe but \emph{not} safe
|
||||
to use from a signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_ENOMEM}] The desired caching policy could not be
|
||||
established because the application is out of memory.
|
||||
\end{Description}
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_create\_addr\_space(3)},
|
||||
\SeeAlso{unw\_flush\_cache(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,117 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_SET\\_FPREG" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_set_fpreg
|
||||
\-\- set contents of floating\-point register
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_set_fpreg(unw_cursor_t *cp,
|
||||
unw_regnum_t
|
||||
reg,
|
||||
unw_fpreg_t
|
||||
val);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_set_fpreg()
|
||||
routine sets the value of register
|
||||
reg
|
||||
in the stack frame identified by cursor cp
|
||||
to the
|
||||
value passed in val\&.
|
||||
.PP
|
||||
The register numbering is target\-dependent and described in separate
|
||||
manual pages (e.g., libunwind\-ia64(3) for the IA\-64 target).
|
||||
Furthermore, the exact set of accessible registers may depend on the
|
||||
type of frame that cp
|
||||
is referring to. For ordinary stack
|
||||
frames, it is normally possible to access only the preserved
|
||||
(``callee\-saved\&'') registers and frame\-related registers (such as the
|
||||
stack\-pointer). However, for signal frames (see
|
||||
unw_is_signal_frame(3)),
|
||||
it is usually possible to access
|
||||
all registers.
|
||||
.PP
|
||||
Note that unw_set_fpreg()
|
||||
can only write the contents of
|
||||
floating\-point registers. See unw_set_reg(3)
|
||||
for a way to
|
||||
write registers which fit in a single word.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_set_fpreg()
|
||||
returns 0.
|
||||
Otherwise the negative value of one of the error\-codes below is
|
||||
returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_set_fpreg()
|
||||
is thread\-safe as well as safe to use
|
||||
from a signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_EBADREG
|
||||
An attempt was made to write a register
|
||||
that is either invalid or not accessible in the current frame.
|
||||
.TP
|
||||
UNW_EREADONLY
|
||||
An attempt was made to write to a
|
||||
read\-only register.
|
||||
.PP
|
||||
In addition, unw_set_fpreg()
|
||||
may return any error returned by
|
||||
the access_mem(),
|
||||
access_reg(),
|
||||
and
|
||||
access_fpreg()
|
||||
call\-backs (see
|
||||
unw_create_addr_space(3)).
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
libunwind\-ia64(3),
|
||||
unw_get_fpreg(3),
|
||||
unw_is_fpreg(3),
|
||||
unw_is_signal_frame(3),
|
||||
unw_set_reg(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,79 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_set\_fpreg}{David Mosberger-Tang}{Programming Library}{unw\_set\_fpreg}unw\_set\_fpreg -- set contents of floating-point register
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_set\_fpreg}(\Type{unw\_cursor\_t~*}\Var{cp}, \Type{unw\_regnum\_t} \Var{reg}, \Type{unw\_fpreg\_t} \Var{val});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_set\_fpreg}() routine sets the value of register
|
||||
\Var{reg} in the stack frame identified by cursor \Var{cp} to the
|
||||
value passed in \Var{val}.
|
||||
|
||||
The register numbering is target-dependent and described in separate
|
||||
manual pages (e.g., libunwind-ia64(3) for the IA-64 target).
|
||||
Furthermore, the exact set of accessible registers may depend on the
|
||||
type of frame that \Var{cp} is referring to. For ordinary stack
|
||||
frames, it is normally possible to access only the preserved
|
||||
(``callee-saved'') registers and frame-related registers (such as the
|
||||
stack-pointer). However, for signal frames (see
|
||||
\Func{unw\_is\_signal\_frame}(3)), it is usually possible to access
|
||||
all registers.
|
||||
|
||||
Note that \Func{unw\_set\_fpreg}() can only write the contents of
|
||||
floating-point registers. See \Func{unw\_set\_reg}(3) for a way to
|
||||
write registers which fit in a single word.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_set\_fpreg}() returns 0.
|
||||
Otherwise the negative value of one of the error-codes below is
|
||||
returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_set\_fpreg}() is thread-safe as well as safe to use
|
||||
from a signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_EBADREG}] An attempt was made to write a register
|
||||
that is either invalid or not accessible in the current frame.
|
||||
\item[\Const{UNW\_EREADONLY}] An attempt was made to write to a
|
||||
read-only register.
|
||||
\end{Description}
|
||||
In addition, \Func{unw\_set\_fpreg}() may return any error returned by
|
||||
the \Func{access\_mem}(), \Func{access\_reg}(), and
|
||||
\Func{access\_fpreg}() call-backs (see
|
||||
\Func{unw\_create\_addr\_space}(3)).
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{libunwind-ia64(3)},
|
||||
\SeeAlso{unw\_get\_fpreg(3)},
|
||||
\SeeAlso{unw\_is\_fpreg(3)},
|
||||
\SeeAlso{unw\_is\_signal\_frame(3)},
|
||||
\SeeAlso{unw\_set\_reg(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,117 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_SET\\_REG" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_set_reg
|
||||
\-\- set register contents
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_set_reg(unw_cursor_t *cp,
|
||||
unw_regnum_t
|
||||
reg,
|
||||
unw_word_t
|
||||
val);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_set_reg()
|
||||
routine sets the value of register
|
||||
reg
|
||||
in the stack frame identified by cursor cp
|
||||
to the
|
||||
value passed in val\&.
|
||||
.PP
|
||||
The register numbering is target\-dependent and described in separate
|
||||
manual pages (e.g., libunwind\-ia64(3) for the IA\-64 target).
|
||||
Furthermore, the exact set of accessible registers may depend on the
|
||||
type of frame that cp
|
||||
is referring to. For ordinary stack
|
||||
frames, it is normally possible to access only the preserved
|
||||
(``callee\-saved\&'') registers and frame\-related registers (such as the
|
||||
stack\-pointer). However, for signal frames (see
|
||||
unw_is_signal_frame(3)),
|
||||
it is usually possible to access
|
||||
all registers.
|
||||
.PP
|
||||
Note that unw_set_reg()
|
||||
can only write the contents of
|
||||
registers whose values fit in a single word. See
|
||||
unw_set_fpreg(3)
|
||||
for a way to write registers which do not
|
||||
fit this constraint.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_set_reg()
|
||||
returns 0.
|
||||
Otherwise the negative value of one of the error\-codes below is
|
||||
returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_set_reg()
|
||||
is thread\-safe as well as safe to use
|
||||
from a signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_EBADREG
|
||||
An attempt was made to write a register
|
||||
that is either invalid or not accessible in the current frame.
|
||||
.TP
|
||||
UNW_EREADONLY
|
||||
An attempt was made to write to a
|
||||
read\-only register.
|
||||
.PP
|
||||
In addition, unw_set_reg()
|
||||
may return any error returned by
|
||||
the access_mem(),
|
||||
access_reg(),
|
||||
and
|
||||
access_fpreg()
|
||||
call\-backs (see
|
||||
unw_create_addr_space(3)).
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
libunwind\-ia64(3),
|
||||
unw_get_reg(3),
|
||||
unw_is_signal_frame(3),
|
||||
unw_set_fpreg(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,79 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_set\_reg}{David Mosberger-Tang}{Programming Library}{unw\_set\_reg}unw\_set\_reg -- set register contents
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_set\_reg}(\Type{unw\_cursor\_t~*}\Var{cp}, \Type{unw\_regnum\_t} \Var{reg}, \Type{unw\_word\_t} \Var{val});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_set\_reg}() routine sets the value of register
|
||||
\Var{reg} in the stack frame identified by cursor \Var{cp} to the
|
||||
value passed in \Var{val}.
|
||||
|
||||
The register numbering is target-dependent and described in separate
|
||||
manual pages (e.g., libunwind-ia64(3) for the IA-64 target).
|
||||
Furthermore, the exact set of accessible registers may depend on the
|
||||
type of frame that \Var{cp} is referring to. For ordinary stack
|
||||
frames, it is normally possible to access only the preserved
|
||||
(``callee-saved'') registers and frame-related registers (such as the
|
||||
stack-pointer). However, for signal frames (see
|
||||
\Func{unw\_is\_signal\_frame}(3)), it is usually possible to access
|
||||
all registers.
|
||||
|
||||
Note that \Func{unw\_set\_reg}() can only write the contents of
|
||||
registers whose values fit in a single word. See
|
||||
\Func{unw\_set\_fpreg}(3) for a way to write registers which do not
|
||||
fit this constraint.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_set\_reg}() returns 0.
|
||||
Otherwise the negative value of one of the error-codes below is
|
||||
returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_set\_reg}() is thread-safe as well as safe to use
|
||||
from a signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_EBADREG}] An attempt was made to write a register
|
||||
that is either invalid or not accessible in the current frame.
|
||||
\item[\Const{UNW\_EREADONLY}] An attempt was made to write to a
|
||||
read-only register.
|
||||
\end{Description}
|
||||
In addition, \Func{unw\_set\_reg}() may return any error returned by
|
||||
the \Func{access\_mem}(), \Func{access\_reg}(), and
|
||||
\Func{access\_fpreg}() call-backs (see
|
||||
\Func{unw\_create\_addr\_space}(3)).
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{libunwind-ia64(3)},
|
||||
\SeeAlso{unw\_get\_reg(3)},
|
||||
\SeeAlso{unw\_is\_signal\_frame(3)},
|
||||
\SeeAlso{unw\_set\_fpreg(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,106 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Thu Aug 16 09:44:45 MDT 2007
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_STEP" "3" "16 August 2007" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_step
|
||||
\-\- advance to next stack frame
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
int
|
||||
unw_step(unw_cursor_t *cp);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_step()
|
||||
routine advances the unwind cursor cp
|
||||
to
|
||||
the next older, less deeply nested stack frame.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
On successful completion, unw_step()
|
||||
returns a positive value
|
||||
if the updated cursor refers to a valid stack frame, or 0 if the
|
||||
previous stack frame was the last frame in the chain. On error, the
|
||||
negative value of one of the error\-codes below is returned.
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_step()
|
||||
is thread\-safe. If cursor cp
|
||||
is in the local
|
||||
address\-space, this routine is also safe to use from a signal handler.
|
||||
.PP
|
||||
.SH ERRORS
|
||||
|
||||
.PP
|
||||
.TP
|
||||
UNW_EUNSPEC
|
||||
An unspecified error occurred.
|
||||
.TP
|
||||
UNW_ENOINFO
|
||||
Libunwind
|
||||
was unable to locate the
|
||||
unwind\-info needed to complete the operation.
|
||||
.TP
|
||||
UNW_EBADVERSION
|
||||
The unwind\-info needed to complete the
|
||||
operation has a version or a format that is not understood by
|
||||
libunwind\&.
|
||||
.TP
|
||||
UNW_EINVALIDIP
|
||||
The instruction\-pointer
|
||||
(``program\-counter\&'') of the next stack frame is invalid (e.g., not
|
||||
properly aligned).
|
||||
.TP
|
||||
UNW_EBADFRAME
|
||||
The next stack frame is invalid.
|
||||
.TP
|
||||
UNW_ESTOPUNWIND
|
||||
Returned if a call to
|
||||
find_proc_info()
|
||||
returned \-UNW_ESTOPUNWIND\&.
|
||||
.PP
|
||||
In addition, unw_step()
|
||||
may return any error returned by the
|
||||
find_proc_info(),
|
||||
get_dyn_info_list_addr(),
|
||||
access_mem(),
|
||||
access_reg(),
|
||||
or access_fpreg()
|
||||
call\-backs (see unw_create_addr_space(3)).
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
|
||||
.PP
|
||||
libunwind(3),
|
||||
unw_create_addr_space(3)
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
David Mosberger\-Tang
|
||||
.br
|
||||
Email: \fBdmosberger@gmail.com\fP
|
||||
.br
|
||||
WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&.
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,68 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_step}{David Mosberger-Tang}{Programming Library}{unw\_step}unw\_step -- advance to next stack frame
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{int} \Func{unw\_step}(\Type{unw\_cursor\_t~*}\Var{cp});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_step}() routine advances the unwind cursor \Var{cp} to
|
||||
the next older, less deeply nested stack frame.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
On successful completion, \Func{unw\_step}() returns a positive value
|
||||
if the updated cursor refers to a valid stack frame, or 0 if the
|
||||
previous stack frame was the last frame in the chain. On error, the
|
||||
negative value of one of the error-codes below is returned.
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_step}() is thread-safe. If cursor \Var{cp} is in the local
|
||||
address-space, this routine is also safe to use from a signal handler.
|
||||
|
||||
\section{Errors}
|
||||
|
||||
\begin{Description}
|
||||
\item[\Const{UNW\_EUNSPEC}] An unspecified error occurred.
|
||||
\item[\Const{UNW\_ENOINFO}] \Prog{Libunwind} was unable to locate the
|
||||
unwind-info needed to complete the operation.
|
||||
\item[\Const{UNW\_EBADVERSION}] The unwind-info needed to complete the
|
||||
operation has a version or a format that is not understood by
|
||||
\Prog{libunwind}.
|
||||
\item[\Const{UNW\_EINVALIDIP}] The instruction-pointer
|
||||
(``program-counter'') of the next stack frame is invalid (e.g., not
|
||||
properly aligned).
|
||||
\item[\Const{UNW\_EBADFRAME}] The next stack frame is invalid.
|
||||
\item[\Const{UNW\_ESTOPUNWIND}] Returned if a call to
|
||||
\Func{find\_proc\_info}() returned -\Const{UNW\_ESTOPUNWIND}.
|
||||
\end{Description}
|
||||
In addition, \Func{unw\_step}() may return any error returned by the
|
||||
\Func{find\_proc\_info}(), \Func{get\_dyn\_info\_list\_addr}(),
|
||||
\Func{access\_mem}(), \Func{access\_reg}(), or \Func{access\_fpreg}()
|
||||
call-backs (see \Func{unw\_create\_addr\_space}(3)).
|
||||
|
||||
\section{See Also}
|
||||
|
||||
\SeeAlso{libunwind(3)},
|
||||
\SeeAlso{unw\_create\_addr\_space(3)}
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
David Mosberger-Tang\\
|
||||
Email: \Email{dmosberger@gmail.com}\\
|
||||
WWW: \URL{http://www.nongnu.org/libunwind/}.
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,63 @@
|
|||
'\" t
|
||||
.\" Manual page created with latex2man on Wed Aug 18 16:51:29 CEST 2004
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
||||
.de Vb
|
||||
.ft CW
|
||||
.nf
|
||||
..
|
||||
.de Ve
|
||||
.ft R
|
||||
|
||||
.fi
|
||||
..
|
||||
.TH "UNW\\_STRERROR" "3" "18 August 2004" "Programming Library " "Programming Library "
|
||||
.SH NAME
|
||||
unw_strerror
|
||||
\-\- get text corresponding to error code
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
|
||||
.PP
|
||||
#include <libunwind.h>
|
||||
.br
|
||||
.PP
|
||||
const char *
|
||||
unw_strerror(int
|
||||
err_code);
|
||||
.br
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
|
||||
.PP
|
||||
The unw_strerror()
|
||||
routine maps the (negative) err_code
|
||||
to a corresponding text message and returns it.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
|
||||
.PP
|
||||
The message that corresponds to err_code
|
||||
or, if the
|
||||
err_code
|
||||
has no corresponding message, the text "invalid error
|
||||
code".
|
||||
.PP
|
||||
.SH THREAD AND SIGNAL SAFETY
|
||||
|
||||
.PP
|
||||
unw_strerror()
|
||||
is thread\-safe as well as safe to use
|
||||
from a signal handler.
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
|
||||
.PP
|
||||
Thomas Hallgren
|
||||
.br
|
||||
BEA Systems
|
||||
.br
|
||||
Stockholm, Sweden
|
||||
.br
|
||||
Email: \fBthallgre@bea.com\fP
|
||||
.br
|
||||
.\" NOTE: This file is generated, DO NOT EDIT.
|
|
@ -0,0 +1,42 @@
|
|||
\documentclass{article}
|
||||
\usepackage[fancyhdr,pdf]{latex2man}
|
||||
|
||||
\input{common.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{Name}{3}{unw\_strerror}{Thomas Hallgren}{Programming Library}{unw\_strerror}unw\_strerror -- get text corresponding to error code
|
||||
\end{Name}
|
||||
|
||||
\section{Synopsis}
|
||||
|
||||
\File{\#include $<$libunwind.h$>$}\\
|
||||
|
||||
\Type{const char *} \Func{unw\_strerror}(\Type{int} \Var{err\_code});\\
|
||||
|
||||
\section{Description}
|
||||
|
||||
The \Func{unw\_strerror}() routine maps the (negative) \Var{err\_code}
|
||||
to a corresponding text message and returns it.
|
||||
|
||||
\section{Return Value}
|
||||
|
||||
The message that corresponds to \Var{err\_code} or, if the
|
||||
\Var{err\_code} has no corresponding message, the text "invalid error
|
||||
code".
|
||||
|
||||
\section{Thread and Signal Safety}
|
||||
|
||||
\Func{unw\_strerror}() is thread-safe as well as safe to use
|
||||
from a signal handler.
|
||||
|
||||
\section{Author}
|
||||
|
||||
\noindent
|
||||
Thomas Hallgren\\
|
||||
BEA Systems\\
|
||||
Stockholm, Sweden\\
|
||||
Email: \Email{thallgre@bea.com}\\
|
||||
\LatexManEnd
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,74 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2001-2005 Hewlett-Packard Co
|
||||
Copyright (C) 2007 David Mosberger-Tang
|
||||
Contributed by David Mosberger-Tang <dmosberger@gmail.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. */
|
||||
|
||||
/* Compiler specific useful bits that are used in libunwind, and also in the
|
||||
* tests. */
|
||||
|
||||
#ifndef COMPILER_H
|
||||
#define COMPILER_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define ALIGNED(x) __attribute__((aligned(x)))
|
||||
# define CONST_ATTR __attribute__((__const__))
|
||||
# define UNUSED __attribute__((unused))
|
||||
# define NOINLINE __attribute__((noinline))
|
||||
# define NORETURN __attribute__((noreturn))
|
||||
# define ALIAS(name) __attribute__((alias (#name)))
|
||||
# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
|
||||
# define ALWAYS_INLINE inline __attribute__((always_inline))
|
||||
# define HIDDEN __attribute__((visibility ("hidden")))
|
||||
# define PROTECTED __attribute__((visibility ("protected")))
|
||||
# else
|
||||
# define ALWAYS_INLINE
|
||||
# define HIDDEN
|
||||
# define PROTECTED
|
||||
# endif
|
||||
# define WEAK __attribute__((weak))
|
||||
# if (__GNUC__ >= 3)
|
||||
# define likely(x) __builtin_expect ((x), 1)
|
||||
# define unlikely(x) __builtin_expect ((x), 0)
|
||||
# else
|
||||
# define likely(x) (x)
|
||||
# define unlikely(x) (x)
|
||||
# endif
|
||||
#else
|
||||
# define ALIGNED(x)
|
||||
# define ALWAYS_INLINE
|
||||
# define CONST_ATTR
|
||||
# define UNUSED
|
||||
# define NOINLINE
|
||||
# define NORETURN
|
||||
# define ALIAS(name)
|
||||
# define HIDDEN
|
||||
# define PROTECTED
|
||||
# define WEAK
|
||||
# define likely(x) (x)
|
||||
# define unlikely(x) (x)
|
||||
#endif
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
|
||||
|
||||
#endif /* COMPILER_H */
|
|
@ -0,0 +1,128 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
|
||||
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. */
|
||||
|
||||
#ifndef dwarf_eh_h
|
||||
#define dwarf_eh_h
|
||||
|
||||
#include "dwarf.h"
|
||||
|
||||
/* This header file defines the format of a DWARF exception-header
|
||||
section (.eh_frame_hdr, pointed to by program-header
|
||||
PT_GNU_EH_FRAME). The exception-header is self-describing in the
|
||||
sense that the format of the addresses contained in it is expressed
|
||||
as a one-byte type-descriptor called a "pointer-encoding" (PE).
|
||||
|
||||
The exception header encodes the address of the .eh_frame section
|
||||
and optionally contains a binary search table for the
|
||||
Frame Descriptor Entries (FDEs) in the .eh_frame. The contents of
|
||||
.eh_frame has the format described by the DWARF v3 standard
|
||||
(http://www.eagercon.com/dwarf/dwarf3std.htm), except that code
|
||||
addresses may be encoded in different ways. Also, .eh_frame has
|
||||
augmentations that allow encoding a language-specific data-area
|
||||
(LSDA) pointer and a pointer to a personality-routine.
|
||||
|
||||
Details:
|
||||
|
||||
The Common Information Entry (CIE) associated with an FDE may
|
||||
contain an augmentation string. Each character in this string has
|
||||
a specific meaning and either one or two associated operands. The
|
||||
operands are stored in an augmentation body which appears right
|
||||
after the "return_address_register" member and before the
|
||||
"initial_instructions" member. The operands appear in the order
|
||||
in which the characters appear in the string. For example, if the
|
||||
augmentation string is "zL", the operand for 'z' would be first in
|
||||
the augmentation body and the operand for 'L' would be second.
|
||||
The following characters are supported for the CIE augmentation
|
||||
string:
|
||||
|
||||
'z': The operand for this character is a uleb128 value that gives the
|
||||
length of the CIE augmentation body, not counting the length
|
||||
of the uleb128 operand itself. If present, this code must
|
||||
appear as the first character in the augmentation body.
|
||||
|
||||
'L': Indicates that the FDE's augmentation body contains an LSDA
|
||||
pointer. The operand for this character is a single byte
|
||||
that specifies the pointer-encoding (PE) that is used for
|
||||
the LSDA pointer.
|
||||
|
||||
'R': Indicates that the code-pointers (FDE members
|
||||
"initial_location" and "address_range" and the operand for
|
||||
DW_CFA_set_loc) in the FDE have a non-default encoding. The
|
||||
operand for this character is a single byte that specifies
|
||||
the pointer-encoding (PE) that is used for the
|
||||
code-pointers. Note: the "address_range" member is always
|
||||
encoded as an absolute value. Apart from that, the specified
|
||||
FDE pointer-encoding applies.
|
||||
|
||||
'P': Indicates the presence of a personality routine (handler).
|
||||
The first operand for this character specifies the
|
||||
pointer-encoding (PE) that is used for the second operand,
|
||||
which specifies the address of the personality routine.
|
||||
|
||||
If the augmentation string contains any other characters, the
|
||||
remainder of the augmentation string should be ignored.
|
||||
Furthermore, if the size of the augmentation body is unknown
|
||||
(i.e., 'z' is not the first character of the augmentation string),
|
||||
then the entire CIE as well all associated FDEs must be ignored.
|
||||
|
||||
A Frame Descriptor Entries (FDE) may contain an augmentation body
|
||||
which, if present, appears right after the "address_range" member
|
||||
and before the "instructions" member. The contents of this body
|
||||
is implicitly defined by the augmentation string of the associated
|
||||
CIE. The meaning of the characters in the CIE's augmentation
|
||||
string as far as FDEs are concerned is as follows:
|
||||
|
||||
'z': The first operand in the FDE's augmentation body specifies
|
||||
the total length of the augmentation body as a uleb128 (not
|
||||
counting the length of the uleb128 operand itself).
|
||||
|
||||
'L': The operand for this character is an LSDA pointer, encoded
|
||||
in the format specified by the corresponding operand in the
|
||||
CIE's augmentation body.
|
||||
|
||||
*/
|
||||
|
||||
#define DW_EH_VERSION 1 /* The version we're implementing */
|
||||
|
||||
struct dwarf_eh_frame_hdr
|
||||
{
|
||||
unsigned char version;
|
||||
unsigned char eh_frame_ptr_enc;
|
||||
unsigned char fde_count_enc;
|
||||
unsigned char table_enc;
|
||||
/* The rest of the header is variable-length and consists of the
|
||||
following members:
|
||||
|
||||
encoded_t eh_frame_ptr;
|
||||
encoded_t fde_count;
|
||||
struct
|
||||
{
|
||||
encoded_t start_ip; // first address covered by this FDE
|
||||
encoded_t fde_addr; // address of the FDE
|
||||
}
|
||||
binary_search_table[fde_count]; */
|
||||
};
|
||||
|
||||
#endif /* dwarf_eh_h */
|
|
@ -0,0 +1,443 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
|
||||
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. */
|
||||
|
||||
#ifndef dwarf_h
|
||||
#define dwarf_h
|
||||
|
||||
#include <libunwind.h>
|
||||
|
||||
struct dwarf_cursor; /* forward-declaration */
|
||||
struct elf_dyn_info;
|
||||
/* ANDROID support update. */
|
||||
struct elf_image;
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "dwarf-config.h"
|
||||
/* End of ANDROID update. */
|
||||
|
||||
#ifndef UNW_REMOTE_ONLY
|
||||
#if defined(HAVE_LINK_H)
|
||||
#include <link.h>
|
||||
#elif defined(HAVE_SYS_LINK_H)
|
||||
#include <sys/link.h>
|
||||
#else
|
||||
#error Could not find <link.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/* DWARF expression opcodes. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DW_OP_addr = 0x03,
|
||||
DW_OP_deref = 0x06,
|
||||
DW_OP_const1u = 0x08,
|
||||
DW_OP_const1s = 0x09,
|
||||
DW_OP_const2u = 0x0a,
|
||||
DW_OP_const2s = 0x0b,
|
||||
DW_OP_const4u = 0x0c,
|
||||
DW_OP_const4s = 0x0d,
|
||||
DW_OP_const8u = 0x0e,
|
||||
DW_OP_const8s = 0x0f,
|
||||
DW_OP_constu = 0x10,
|
||||
DW_OP_consts = 0x11,
|
||||
DW_OP_dup = 0x12,
|
||||
DW_OP_drop = 0x13,
|
||||
DW_OP_over = 0x14,
|
||||
DW_OP_pick = 0x15,
|
||||
DW_OP_swap = 0x16,
|
||||
DW_OP_rot = 0x17,
|
||||
DW_OP_xderef = 0x18,
|
||||
DW_OP_abs = 0x19,
|
||||
DW_OP_and = 0x1a,
|
||||
DW_OP_div = 0x1b,
|
||||
DW_OP_minus = 0x1c,
|
||||
DW_OP_mod = 0x1d,
|
||||
DW_OP_mul = 0x1e,
|
||||
DW_OP_neg = 0x1f,
|
||||
DW_OP_not = 0x20,
|
||||
DW_OP_or = 0x21,
|
||||
DW_OP_plus = 0x22,
|
||||
DW_OP_plus_uconst = 0x23,
|
||||
DW_OP_shl = 0x24,
|
||||
DW_OP_shr = 0x25,
|
||||
DW_OP_shra = 0x26,
|
||||
DW_OP_xor = 0x27,
|
||||
DW_OP_skip = 0x2f,
|
||||
DW_OP_bra = 0x28,
|
||||
DW_OP_eq = 0x29,
|
||||
DW_OP_ge = 0x2a,
|
||||
DW_OP_gt = 0x2b,
|
||||
DW_OP_le = 0x2c,
|
||||
DW_OP_lt = 0x2d,
|
||||
DW_OP_ne = 0x2e,
|
||||
DW_OP_lit0 = 0x30,
|
||||
DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_lit4, DW_OP_lit5,
|
||||
DW_OP_lit6, DW_OP_lit7, DW_OP_lit8, DW_OP_lit9, DW_OP_lit10,
|
||||
DW_OP_lit11, DW_OP_lit12, DW_OP_lit13, DW_OP_lit14, DW_OP_lit15,
|
||||
DW_OP_lit16, DW_OP_lit17, DW_OP_lit18, DW_OP_lit19, DW_OP_lit20,
|
||||
DW_OP_lit21, DW_OP_lit22, DW_OP_lit23, DW_OP_lit24, DW_OP_lit25,
|
||||
DW_OP_lit26, DW_OP_lit27, DW_OP_lit28, DW_OP_lit29, DW_OP_lit30,
|
||||
DW_OP_lit31,
|
||||
DW_OP_reg0 = 0x50,
|
||||
DW_OP_reg1, DW_OP_reg2, DW_OP_reg3, DW_OP_reg4, DW_OP_reg5,
|
||||
DW_OP_reg6, DW_OP_reg7, DW_OP_reg8, DW_OP_reg9, DW_OP_reg10,
|
||||
DW_OP_reg11, DW_OP_reg12, DW_OP_reg13, DW_OP_reg14, DW_OP_reg15,
|
||||
DW_OP_reg16, DW_OP_reg17, DW_OP_reg18, DW_OP_reg19, DW_OP_reg20,
|
||||
DW_OP_reg21, DW_OP_reg22, DW_OP_reg23, DW_OP_reg24, DW_OP_reg25,
|
||||
DW_OP_reg26, DW_OP_reg27, DW_OP_reg28, DW_OP_reg29, DW_OP_reg30,
|
||||
DW_OP_reg31,
|
||||
DW_OP_breg0 = 0x70,
|
||||
DW_OP_breg1, DW_OP_breg2, DW_OP_breg3, DW_OP_breg4, DW_OP_breg5,
|
||||
DW_OP_breg6, DW_OP_breg7, DW_OP_breg8, DW_OP_breg9, DW_OP_breg10,
|
||||
DW_OP_breg11, DW_OP_breg12, DW_OP_breg13, DW_OP_breg14, DW_OP_breg15,
|
||||
DW_OP_breg16, DW_OP_breg17, DW_OP_breg18, DW_OP_breg19, DW_OP_breg20,
|
||||
DW_OP_breg21, DW_OP_breg22, DW_OP_breg23, DW_OP_breg24, DW_OP_breg25,
|
||||
DW_OP_breg26, DW_OP_breg27, DW_OP_breg28, DW_OP_breg29, DW_OP_breg30,
|
||||
DW_OP_breg31,
|
||||
DW_OP_regx = 0x90,
|
||||
DW_OP_fbreg = 0x91,
|
||||
DW_OP_bregx = 0x92,
|
||||
DW_OP_piece = 0x93,
|
||||
DW_OP_deref_size = 0x94,
|
||||
DW_OP_xderef_size = 0x95,
|
||||
DW_OP_nop = 0x96,
|
||||
DW_OP_push_object_address = 0x97,
|
||||
DW_OP_call2 = 0x98,
|
||||
DW_OP_call4 = 0x99,
|
||||
DW_OP_call_ref = 0x9a,
|
||||
DW_OP_lo_user = 0xe0,
|
||||
DW_OP_hi_user = 0xff
|
||||
}
|
||||
dwarf_expr_op_t;
|
||||
|
||||
#define DWARF_CIE_VERSION 3 /* GCC emits version 1??? */
|
||||
|
||||
#define DWARF_CFA_OPCODE_MASK 0xc0
|
||||
#define DWARF_CFA_OPERAND_MASK 0x3f
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DW_CFA_advance_loc = 0x40,
|
||||
DW_CFA_offset = 0x80,
|
||||
DW_CFA_restore = 0xc0,
|
||||
DW_CFA_nop = 0x00,
|
||||
DW_CFA_set_loc = 0x01,
|
||||
DW_CFA_advance_loc1 = 0x02,
|
||||
DW_CFA_advance_loc2 = 0x03,
|
||||
DW_CFA_advance_loc4 = 0x04,
|
||||
DW_CFA_offset_extended = 0x05,
|
||||
DW_CFA_restore_extended = 0x06,
|
||||
DW_CFA_undefined = 0x07,
|
||||
DW_CFA_same_value = 0x08,
|
||||
DW_CFA_register = 0x09,
|
||||
DW_CFA_remember_state = 0x0a,
|
||||
DW_CFA_restore_state = 0x0b,
|
||||
DW_CFA_def_cfa = 0x0c,
|
||||
DW_CFA_def_cfa_register = 0x0d,
|
||||
DW_CFA_def_cfa_offset = 0x0e,
|
||||
DW_CFA_def_cfa_expression = 0x0f,
|
||||
DW_CFA_expression = 0x10,
|
||||
DW_CFA_offset_extended_sf = 0x11,
|
||||
DW_CFA_def_cfa_sf = 0x12,
|
||||
DW_CFA_def_cfa_offset_sf = 0x13,
|
||||
DW_CFA_lo_user = 0x1c,
|
||||
DW_CFA_MIPS_advance_loc8 = 0x1d,
|
||||
DW_CFA_GNU_window_save = 0x2d,
|
||||
DW_CFA_GNU_args_size = 0x2e,
|
||||
DW_CFA_GNU_negative_offset_extended = 0x2f,
|
||||
DW_CFA_hi_user = 0x3c
|
||||
}
|
||||
dwarf_cfa_t;
|
||||
|
||||
/* DWARF Pointer-Encoding (PEs).
|
||||
|
||||
Pointer-Encodings were invented for the GCC exception-handling
|
||||
support for C++, but they represent a rather generic way of
|
||||
describing the format in which an address/pointer is stored and
|
||||
hence we include the definitions here, in the main dwarf.h file.
|
||||
The Pointer-Encoding format is partially documented in Linux Base
|
||||
Spec v1.3 (http://www.linuxbase.org/spec/). The rest is reverse
|
||||
engineered from GCC.
|
||||
|
||||
*/
|
||||
#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
|
||||
#define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
|
||||
/* Flag bit. If set, the resulting pointer is the address of the word
|
||||
that contains the final address. */
|
||||
#define DW_EH_PE_indirect 0x80
|
||||
|
||||
/* Pointer-encoding formats: */
|
||||
#define DW_EH_PE_omit 0xff
|
||||
#define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */
|
||||
#define DW_EH_PE_uleb128 0x01 /* unsigned LE base-128 value */
|
||||
#define DW_EH_PE_udata2 0x02 /* unsigned 16-bit value */
|
||||
#define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */
|
||||
#define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */
|
||||
#define DW_EH_PE_sleb128 0x09 /* signed LE base-128 value */
|
||||
#define DW_EH_PE_sdata2 0x0a /* signed 16-bit value */
|
||||
#define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */
|
||||
#define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */
|
||||
|
||||
/* Pointer-encoding application: */
|
||||
#define DW_EH_PE_absptr 0x00 /* absolute value */
|
||||
#define DW_EH_PE_pcrel 0x10 /* rel. to addr. of encoded value */
|
||||
#define DW_EH_PE_textrel 0x20 /* text-relative (GCC-specific???) */
|
||||
#define DW_EH_PE_datarel 0x30 /* data-relative */
|
||||
/* The following are not documented by LSB v1.3, yet they are used by
|
||||
GCC, presumably they aren't documented by LSB since they aren't
|
||||
used on Linux: */
|
||||
#define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */
|
||||
#define DW_EH_PE_aligned 0x50 /* aligned pointer */
|
||||
|
||||
extern struct mempool dwarf_reg_state_pool;
|
||||
extern struct mempool dwarf_cie_info_pool;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DWARF_WHERE_UNDEF, /* register isn't saved at all */
|
||||
DWARF_WHERE_SAME, /* register has same value as in prev. frame */
|
||||
DWARF_WHERE_CFAREL, /* register saved at CFA-relative address */
|
||||
DWARF_WHERE_REG, /* register saved in another register */
|
||||
DWARF_WHERE_EXPR, /* register saved */
|
||||
}
|
||||
dwarf_where_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
dwarf_where_t where; /* how is the register saved? */
|
||||
unw_word_t val; /* where it's saved */
|
||||
}
|
||||
dwarf_save_loc_t;
|
||||
|
||||
/* For uniformity, we'd like to treat the CFA save-location like any
|
||||
other register save-location, but this doesn't quite work, because
|
||||
the CFA can be expressed as a (REGISTER,OFFSET) pair. To handle
|
||||
this, we use two dwarf_save_loc structures to describe the CFA.
|
||||
The first one (CFA_REG_COLUMN), tells us where the CFA is saved.
|
||||
In the case of DWARF_WHERE_EXPR, the CFA is defined by a DWARF
|
||||
location expression whose address is given by member "val". In the
|
||||
case of DWARF_WHERE_REG, member "val" gives the number of the
|
||||
base-register and the "val" member of DWARF_CFA_OFF_COLUMN gives
|
||||
the offset value. */
|
||||
#define DWARF_CFA_REG_COLUMN DWARF_NUM_PRESERVED_REGS
|
||||
#define DWARF_CFA_OFF_COLUMN (DWARF_NUM_PRESERVED_REGS + 1)
|
||||
|
||||
typedef struct dwarf_reg_state
|
||||
{
|
||||
struct dwarf_reg_state *next; /* for rs_stack */
|
||||
dwarf_save_loc_t reg[DWARF_NUM_PRESERVED_REGS + 2];
|
||||
unw_word_t ip; /* ip this rs is for */
|
||||
unw_word_t ret_addr_column; /* indicates which column in the rule table represents return address */
|
||||
unsigned short lru_chain; /* used for least-recently-used chain */
|
||||
unsigned short coll_chain; /* used for hash collisions */
|
||||
unsigned short hint; /* hint for next rs to try (or -1) */
|
||||
unsigned short valid : 1; /* optional machine-dependent signal info */
|
||||
unsigned short signal_frame : 1; /* optional machine-dependent signal info */
|
||||
}
|
||||
dwarf_reg_state_t;
|
||||
|
||||
typedef struct dwarf_cie_info
|
||||
{
|
||||
unw_word_t cie_instr_start; /* start addr. of CIE "initial_instructions" */
|
||||
unw_word_t cie_instr_end; /* end addr. of CIE "initial_instructions" */
|
||||
unw_word_t fde_instr_start; /* start addr. of FDE "instructions" */
|
||||
unw_word_t fde_instr_end; /* end addr. of FDE "instructions" */
|
||||
unw_word_t code_align; /* code-alignment factor */
|
||||
unw_word_t data_align; /* data-alignment factor */
|
||||
unw_word_t ret_addr_column; /* column of return-address register */
|
||||
unw_word_t handler; /* address of personality-routine */
|
||||
uint16_t abi;
|
||||
uint16_t tag;
|
||||
uint8_t fde_encoding;
|
||||
uint8_t lsda_encoding;
|
||||
unsigned int sized_augmentation : 1;
|
||||
unsigned int have_abi_marker : 1;
|
||||
unsigned int signal_frame : 1;
|
||||
}
|
||||
dwarf_cie_info_t;
|
||||
|
||||
typedef struct dwarf_state_record
|
||||
{
|
||||
unsigned char fde_encoding;
|
||||
unw_word_t args_size;
|
||||
|
||||
dwarf_reg_state_t rs_initial; /* reg-state after CIE instructions */
|
||||
dwarf_reg_state_t rs_current; /* current reg-state */
|
||||
}
|
||||
dwarf_state_record_t;
|
||||
|
||||
typedef struct dwarf_cursor
|
||||
{
|
||||
void *as_arg; /* argument to address-space callbacks */
|
||||
unw_addr_space_t as; /* reference to per-address-space info */
|
||||
|
||||
unw_word_t cfa; /* canonical frame address; aka frame-/stack-pointer */
|
||||
unw_word_t ip; /* instruction pointer */
|
||||
unw_word_t args_size; /* size of arguments */
|
||||
unw_word_t ret_addr_column; /* column for return-address */
|
||||
unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS];
|
||||
unsigned int eh_valid_mask;
|
||||
/* ANDROID support update. */
|
||||
unsigned int frame;
|
||||
/* End of ANDROID update. */
|
||||
|
||||
dwarf_loc_t loc[DWARF_NUM_PRESERVED_REGS];
|
||||
|
||||
unsigned int stash_frames :1; /* stash frames for fast lookup */
|
||||
unsigned int use_prev_instr :1; /* use previous (= call) or current (= signal) instruction? */
|
||||
unsigned int pi_valid :1; /* is proc_info valid? */
|
||||
unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */
|
||||
unw_proc_info_t pi; /* info about current procedure */
|
||||
|
||||
short hint; /* faster lookup of the rs cache */
|
||||
short prev_rs;
|
||||
}
|
||||
dwarf_cursor_t;
|
||||
|
||||
#define DWARF_LOG_UNW_CACHE_SIZE 7
|
||||
#define DWARF_UNW_CACHE_SIZE (1 << DWARF_LOG_UNW_CACHE_SIZE)
|
||||
|
||||
#define DWARF_LOG_UNW_HASH_SIZE (DWARF_LOG_UNW_CACHE_SIZE + 1)
|
||||
#define DWARF_UNW_HASH_SIZE (1 << DWARF_LOG_UNW_HASH_SIZE)
|
||||
|
||||
typedef unsigned char unw_hash_index_t;
|
||||
|
||||
struct dwarf_rs_cache
|
||||
{
|
||||
pthread_mutex_t lock;
|
||||
unsigned short lru_head; /* index of lead-recently used rs */
|
||||
unsigned short lru_tail; /* index of most-recently used rs */
|
||||
|
||||
/* hash table that maps instruction pointer to rs index: */
|
||||
unsigned short hash[DWARF_UNW_HASH_SIZE];
|
||||
|
||||
uint32_t generation; /* generation number */
|
||||
|
||||
/* rs cache: */
|
||||
dwarf_reg_state_t buckets[DWARF_UNW_CACHE_SIZE];
|
||||
};
|
||||
|
||||
/* A list of descriptors for loaded .debug_frame sections. */
|
||||
|
||||
struct unw_debug_frame_list
|
||||
{
|
||||
/* The start (inclusive) and end (exclusive) of the described region. */
|
||||
unw_word_t start;
|
||||
unw_word_t end;
|
||||
/* The debug frame itself. */
|
||||
char *debug_frame;
|
||||
size_t debug_frame_size;
|
||||
/* Relocation amount since debug_frame was compressed. */
|
||||
unw_word_t segbase_bias;
|
||||
/* Index (for binary search). */
|
||||
struct table_entry *index;
|
||||
size_t index_size;
|
||||
/* Pointer to next descriptor. */
|
||||
struct unw_debug_frame_list *next;
|
||||
};
|
||||
|
||||
struct dwarf_callback_data
|
||||
{
|
||||
/* in: */
|
||||
unw_word_t ip; /* instruction-pointer we're looking for */
|
||||
unw_proc_info_t *pi; /* proc-info pointer */
|
||||
int need_unwind_info;
|
||||
/* out: */
|
||||
int single_fde; /* did we find a single FDE? (vs. a table) */
|
||||
unw_dyn_info_t di; /* table info (if single_fde is false) */
|
||||
unw_dyn_info_t di_debug; /* additional table info for .debug_frame */
|
||||
};
|
||||
|
||||
/* Convenience macros: */
|
||||
#define dwarf_init UNW_ARCH_OBJ (dwarf_init)
|
||||
#define dwarf_callback UNW_OBJ (dwarf_callback)
|
||||
#define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info)
|
||||
#define dwarf_find_debug_frame UNW_OBJ (dwarf_find_debug_frame)
|
||||
#define dwarf_search_unwind_table UNW_OBJ (dwarf_search_unwind_table)
|
||||
#define dwarf_find_unwind_table UNW_OBJ (dwarf_find_unwind_table)
|
||||
#define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
|
||||
#define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
|
||||
#define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr)
|
||||
#define dwarf_extract_proc_info_from_fde \
|
||||
UNW_OBJ (dwarf_extract_proc_info_from_fde)
|
||||
#define dwarf_find_save_locs UNW_OBJ (dwarf_find_save_locs)
|
||||
#define dwarf_create_state_record UNW_OBJ (dwarf_create_state_record)
|
||||
#define dwarf_make_proc_info UNW_OBJ (dwarf_make_proc_info)
|
||||
#define dwarf_read_encoded_pointer UNW_OBJ (dwarf_read_encoded_pointer)
|
||||
#define dwarf_step UNW_OBJ (dwarf_step)
|
||||
|
||||
extern int dwarf_init (void);
|
||||
#ifndef UNW_REMOTE_ONLY
|
||||
extern int dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr);
|
||||
extern int dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
|
||||
unw_proc_info_t *pi,
|
||||
int need_unwind_info, void *arg);
|
||||
#endif /* !UNW_REMOTE_ONLY */
|
||||
extern int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug,
|
||||
unw_word_t ip, unw_word_t segbase,
|
||||
const char* obj_name, unw_word_t start,
|
||||
unw_word_t end);
|
||||
extern int dwarf_search_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);
|
||||
/* ANDROID support update. */
|
||||
extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, struct elf_image *ei,
|
||||
unw_addr_space_t as, char *path,
|
||||
unw_word_t segbase, unw_word_t mapoff,
|
||||
unw_word_t ip);
|
||||
/* End of ANDROID update. */
|
||||
extern void dwarf_put_unwind_info (unw_addr_space_t as,
|
||||
unw_proc_info_t *pi, void *arg);
|
||||
extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr,
|
||||
unw_word_t len, unw_word_t *valp,
|
||||
int *is_register);
|
||||
extern int dwarf_extract_proc_info_from_fde (unw_addr_space_t as,
|
||||
unw_accessors_t *a,
|
||||
unw_word_t *fde_addr,
|
||||
unw_proc_info_t *pi,
|
||||
int need_unwind_info,
|
||||
unw_word_t base,
|
||||
void *arg);
|
||||
extern int dwarf_find_save_locs (struct dwarf_cursor *c);
|
||||
extern int dwarf_create_state_record (struct dwarf_cursor *c,
|
||||
dwarf_state_record_t *sr);
|
||||
extern int dwarf_make_proc_info (struct dwarf_cursor *c);
|
||||
extern int dwarf_read_encoded_pointer (unw_addr_space_t as,
|
||||
unw_accessors_t *a,
|
||||
unw_word_t *addr,
|
||||
unsigned char encoding,
|
||||
const unw_proc_info_t *pi,
|
||||
unw_word_t *valp, void *arg);
|
||||
extern int dwarf_step (struct dwarf_cursor *c);
|
||||
|
||||
#endif /* dwarf_h */
|
|
@ -0,0 +1,490 @@
|
|||
#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 "libunwind_i.h"
|
||||
|
||||
/* Unless we are told otherwise, assume that a "machine address" is
|
||||
the size of an unw_word_t. */
|
||||
#ifndef dwarf_addr_size
|
||||
# define dwarf_addr_size(as) (sizeof (unw_word_t))
|
||||
#endif
|
||||
|
||||
#ifndef dwarf_to_unw_regnum
|
||||
# define dwarf_to_unw_regnum_map UNW_OBJ (dwarf_to_unw_regnum_map)
|
||||
extern const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH];
|
||||
/* REG is evaluated multiple times; it better be side-effects free! */
|
||||
# define dwarf_to_unw_regnum(reg) \
|
||||
(((reg) <= DWARF_REGNUM_MAP_LENGTH) ? dwarf_to_unw_regnum_map[reg] : 0)
|
||||
#endif
|
||||
|
||||
#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 __attribute__ ((packed))
|
||||
{
|
||||
int8_t s8;
|
||||
int16_t s16;
|
||||
int32_t s32;
|
||||
int64_t s64;
|
||||
uint8_t u8;
|
||||
uint16_t u16;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
void *ptr;
|
||||
}
|
||||
dwarf_misaligned_value_t;
|
||||
|
||||
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 *) (uintptr_t) *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 *) (uintptr_t) *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 *) (uintptr_t) *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 *) (uintptr_t) *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 *) (uintptr_t) *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 *) (uintptr_t) *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 *) (uintptr_t) *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 *) (uintptr_t) *addr;
|
||||
|
||||
*val = mvp->u64;
|
||||
*addr += sizeof (mvp->u64);
|
||||
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;
|
||||
}
|
||||
|
||||
#endif /* !UNW_LOCAL_ONLY */
|
||||
|
||||
static inline int
|
||||
dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
|
||||
unw_word_t *val, void *arg)
|
||||
{
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
int ret;
|
||||
|
||||
switch (dwarf_addr_size (as))
|
||||
{
|
||||
case 4:
|
||||
ret = dwarf_readu32 (as, a, addr, &u32, arg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*val = u32;
|
||||
return ret;
|
||||
|
||||
case 8:
|
||||
ret = dwarf_readu64 (as, a, addr, &u64, arg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*val = u64;
|
||||
return ret;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE int
|
||||
dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a,
|
||||
unw_word_t *addr, unsigned char encoding,
|
||||
const unw_proc_info_t *pi,
|
||||
unw_word_t *valp, void *arg)
|
||||
{
|
||||
unw_word_t val, initial_addr = *addr;
|
||||
uint16_t uval16;
|
||||
uint32_t uval32;
|
||||
uint64_t uval64;
|
||||
int16_t sval16;
|
||||
int32_t sval32;
|
||||
int64_t sval64;
|
||||
int ret;
|
||||
|
||||
/* DW_EH_PE_omit and DW_EH_PE_aligned don't follow the normal
|
||||
format/application encoding. Handle them first. */
|
||||
if (encoding == DW_EH_PE_omit)
|
||||
{
|
||||
*valp = 0;
|
||||
return 0;
|
||||
}
|
||||
else if (encoding == DW_EH_PE_aligned)
|
||||
{
|
||||
int size = dwarf_addr_size (as);
|
||||
*addr = (initial_addr + size - 1) & -size;
|
||||
return dwarf_readw (as, a, addr, valp, arg);
|
||||
}
|
||||
|
||||
switch (encoding & DW_EH_PE_FORMAT_MASK)
|
||||
{
|
||||
case DW_EH_PE_ptr:
|
||||
if ((ret = dwarf_readw (as, a, addr, &val, arg)) < 0)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_uleb128:
|
||||
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_udata2:
|
||||
if ((ret = dwarf_readu16 (as, a, addr, &uval16, arg)) < 0)
|
||||
return ret;
|
||||
val = uval16;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_udata4:
|
||||
if ((ret = dwarf_readu32 (as, a, addr, &uval32, arg)) < 0)
|
||||
return ret;
|
||||
val = uval32;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_udata8:
|
||||
if ((ret = dwarf_readu64 (as, a, addr, &uval64, arg)) < 0)
|
||||
return ret;
|
||||
val = uval64;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_sleb128:
|
||||
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_sdata2:
|
||||
if ((ret = dwarf_reads16 (as, a, addr, &sval16, arg)) < 0)
|
||||
return ret;
|
||||
val = sval16;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_sdata4:
|
||||
if ((ret = dwarf_reads32 (as, a, addr, &sval32, arg)) < 0)
|
||||
return ret;
|
||||
val = sval32;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_sdata8:
|
||||
if ((ret = dwarf_reads64 (as, a, addr, &sval64, arg)) < 0)
|
||||
return ret;
|
||||
val = sval64;
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug (1, "unexpected encoding format 0x%x\n",
|
||||
encoding & DW_EH_PE_FORMAT_MASK);
|
||||
return -UNW_EINVAL;
|
||||
}
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
/* 0 is a special value and always absolute. */
|
||||
*valp = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (encoding & DW_EH_PE_APPL_MASK)
|
||||
{
|
||||
case DW_EH_PE_absptr:
|
||||
break;
|
||||
|
||||
case DW_EH_PE_pcrel:
|
||||
val += initial_addr;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_datarel:
|
||||
/* XXX For now, assume that data-relative addresses are relative
|
||||
to the global pointer. */
|
||||
val += pi->gp;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_funcrel:
|
||||
val += pi->start_ip;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_textrel:
|
||||
/* XXX For now we don't support text-rel values. If there is a
|
||||
platform which needs this, we probably would have to add a
|
||||
"segbase" member to unw_proc_info_t. */
|
||||
default:
|
||||
Debug (1, "unexpected application type 0x%x\n",
|
||||
encoding & DW_EH_PE_APPL_MASK);
|
||||
return -UNW_EINVAL;
|
||||
}
|
||||
|
||||
/* Trim off any extra bits. Assume that sign extension isn't
|
||||
required; the only place it is needed is MIPS kernel space
|
||||
addresses. */
|
||||
if (sizeof (val) > dwarf_addr_size (as))
|
||||
{
|
||||
assert (dwarf_addr_size (as) == 4);
|
||||
val = (uint32_t) val;
|
||||
}
|
||||
|
||||
if (encoding & DW_EH_PE_indirect)
|
||||
{
|
||||
unw_word_t indirect_addr = val;
|
||||
|
||||
if ((ret = dwarf_readw (as, a, &indirect_addr, &val, arg)) < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
*valp = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* DWARF_I_H */
|
|
@ -0,0 +1,221 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2001-2004 Hewlett-Packard Co
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
Copyright (C) 2013 Linaro Limited
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef LIBUNWIND_H
|
||||
#define LIBUNWIND_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define UNW_TARGET aarch64
|
||||
#define UNW_TARGET_AARCH64 1
|
||||
|
||||
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
|
||||
|
||||
/* This needs to be big enough to accommodate "struct cursor", while
|
||||
leaving some slack for future expansion. Changing this value will
|
||||
require recompiling all users of this library. Stack allocation is
|
||||
relatively cheap and unwind-state copying is relatively rare, so we
|
||||
want to err on making it rather too big than too small. */
|
||||
|
||||
#define UNW_TDEP_CURSOR_LEN 4096
|
||||
|
||||
typedef uint64_t unw_word_t;
|
||||
typedef int64_t unw_sword_t;
|
||||
|
||||
typedef long double unw_tdep_fpreg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* no aarch64-specific auxiliary proc-info */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_proc_info_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* 64-bit general registers. */
|
||||
UNW_AARCH64_X0,
|
||||
UNW_AARCH64_X1,
|
||||
UNW_AARCH64_X2,
|
||||
UNW_AARCH64_X3,
|
||||
UNW_AARCH64_X4,
|
||||
UNW_AARCH64_X5,
|
||||
UNW_AARCH64_X6,
|
||||
UNW_AARCH64_X7,
|
||||
UNW_AARCH64_X8,
|
||||
|
||||
/* Temporary registers. */
|
||||
UNW_AARCH64_X9,
|
||||
UNW_AARCH64_X10,
|
||||
UNW_AARCH64_X11,
|
||||
UNW_AARCH64_X12,
|
||||
UNW_AARCH64_X13,
|
||||
UNW_AARCH64_X14,
|
||||
UNW_AARCH64_X15,
|
||||
|
||||
/* Intra-procedure-call temporary registers. */
|
||||
UNW_AARCH64_X16,
|
||||
UNW_AARCH64_X17,
|
||||
|
||||
/* Callee-saved registers. */
|
||||
UNW_AARCH64_X18,
|
||||
UNW_AARCH64_X19,
|
||||
UNW_AARCH64_X20,
|
||||
UNW_AARCH64_X21,
|
||||
UNW_AARCH64_X22,
|
||||
UNW_AARCH64_X23,
|
||||
UNW_AARCH64_X24,
|
||||
UNW_AARCH64_X25,
|
||||
UNW_AARCH64_X26,
|
||||
UNW_AARCH64_X27,
|
||||
UNW_AARCH64_X28,
|
||||
|
||||
/* 64-bit frame pointer. */
|
||||
UNW_AARCH64_X29,
|
||||
|
||||
/* 64-bit link register. */
|
||||
UNW_AARCH64_X30,
|
||||
|
||||
/* 64-bit stack pointer. */
|
||||
UNW_AARCH64_SP = 31,
|
||||
UNW_AARCH64_PC,
|
||||
UNW_AARCH64_PSTATE,
|
||||
|
||||
/* 128-bit FP/Advanced SIMD registers. */
|
||||
UNW_AARCH64_V0 = 64,
|
||||
UNW_AARCH64_V1,
|
||||
UNW_AARCH64_V2,
|
||||
UNW_AARCH64_V3,
|
||||
UNW_AARCH64_V4,
|
||||
UNW_AARCH64_V5,
|
||||
UNW_AARCH64_V6,
|
||||
UNW_AARCH64_V7,
|
||||
UNW_AARCH64_V8,
|
||||
UNW_AARCH64_V9,
|
||||
UNW_AARCH64_V10,
|
||||
UNW_AARCH64_V11,
|
||||
UNW_AARCH64_V12,
|
||||
UNW_AARCH64_V13,
|
||||
UNW_AARCH64_V14,
|
||||
UNW_AARCH64_V15,
|
||||
UNW_AARCH64_V16,
|
||||
UNW_AARCH64_V17,
|
||||
UNW_AARCH64_V18,
|
||||
UNW_AARCH64_V19,
|
||||
UNW_AARCH64_V20,
|
||||
UNW_AARCH64_V21,
|
||||
UNW_AARCH64_V22,
|
||||
UNW_AARCH64_V23,
|
||||
UNW_AARCH64_V24,
|
||||
UNW_AARCH64_V25,
|
||||
UNW_AARCH64_V26,
|
||||
UNW_AARCH64_V27,
|
||||
UNW_AARCH64_V28,
|
||||
UNW_AARCH64_V29,
|
||||
UNW_AARCH64_V30,
|
||||
UNW_AARCH64_V31,
|
||||
|
||||
UNW_AARCH64_FPSR,
|
||||
UNW_AARCH64_FPCR,
|
||||
|
||||
/* For AArch64, the CFA is the value of SP (x31) at the call site of the
|
||||
previous frame. */
|
||||
UNW_AARCH64_CFA = UNW_AARCH64_SP,
|
||||
|
||||
UNW_TDEP_LAST_REG = UNW_AARCH64_FPCR,
|
||||
|
||||
UNW_TDEP_IP = UNW_AARCH64_X30,
|
||||
UNW_TDEP_SP = UNW_AARCH64_SP,
|
||||
UNW_TDEP_EH = UNW_AARCH64_X0,
|
||||
|
||||
}
|
||||
aarch64_regnum_t;
|
||||
|
||||
/* Use R0 through R3 to pass exception handling information. */
|
||||
#define UNW_TDEP_NUM_EH_REGS 4
|
||||
|
||||
typedef struct unw_tdep_save_loc
|
||||
{
|
||||
/* Additional target-dependent info on a save location. */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_save_loc_t;
|
||||
|
||||
|
||||
/* On AArch64, we can directly use ucontext_t as the unwind context. */
|
||||
typedef ucontext_t unw_tdep_context_t;
|
||||
|
||||
#include "libunwind-common.h"
|
||||
#include "libunwind-dynamic.h"
|
||||
|
||||
/* ANDROID support update. */
|
||||
/* There is no getcontext in Android. */
|
||||
#define unw_tdep_getcontext(uc) (({ \
|
||||
unw_tdep_context_t *unw_ctx = (uc); \
|
||||
register uint64_t *unw_base asm ("x0") = (uint64_t*) unw_ctx->uc_mcontext.regs; \
|
||||
__asm__ __volatile__ ( \
|
||||
"1:\n" \
|
||||
"stp x0, x1, [%[base], #0]\n" \
|
||||
"stp x2, x3, [%[base], #16]\n" \
|
||||
"stp x4, x5, [%[base], #32]\n" \
|
||||
"stp x6, x7, [%[base], #48]\n" \
|
||||
"stp x8, x9, [%[base], #64]\n" \
|
||||
"stp x10, x11, [%[base], #80]\n" \
|
||||
"stp x12, x13, [%[base], #96]\n" \
|
||||
"stp x14, x15, [%[base], #112]\n" \
|
||||
"stp x16, x17, [%[base], #128]\n" \
|
||||
"stp x18, x19, [%[base], #144]\n" \
|
||||
"stp x20, x21, [%[base], #160]\n" \
|
||||
"stp x22, x23, [%[base], #176]\n" \
|
||||
"stp x24, x25, [%[base], #192]\n" \
|
||||
"stp x26, x27, [%[base], #208]\n" \
|
||||
"stp x28, x29, [%[base], #224]\n" \
|
||||
"str x30, [%[base], #240]\n" \
|
||||
"mov x1, sp\n" \
|
||||
"adr x2, 1b\n" \
|
||||
"stp x1, x2, [%[base], #248]\n" \
|
||||
: [base] "+r" (unw_base) : : "x1", "x2", "memory"); \
|
||||
}), 0)
|
||||
/* End of ANDROID update. */
|
||||
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
|
||||
|
||||
extern int unw_tdep_is_fpreg (int);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIBUNWIND_H */
|
|
@ -0,0 +1,308 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef LIBUNWIND_H
|
||||
#define LIBUNWIND_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define UNW_TARGET arm
|
||||
#define UNW_TARGET_ARM 1
|
||||
|
||||
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
|
||||
|
||||
/* This needs to be big enough to accommodate "struct cursor", while
|
||||
leaving some slack for future expansion. Changing this value will
|
||||
require recompiling all users of this library. Stack allocation is
|
||||
relatively cheap and unwind-state copying is relatively rare, so we
|
||||
want to err on making it rather too big than too small. */
|
||||
|
||||
/* FIXME for ARM. Too big? What do other things use for similar tasks? */
|
||||
#define UNW_TDEP_CURSOR_LEN 4096
|
||||
|
||||
typedef uint32_t unw_word_t;
|
||||
typedef int32_t unw_sword_t;
|
||||
|
||||
typedef long double unw_tdep_fpreg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNW_ARM_R0,
|
||||
UNW_ARM_R1,
|
||||
UNW_ARM_R2,
|
||||
UNW_ARM_R3,
|
||||
UNW_ARM_R4,
|
||||
UNW_ARM_R5,
|
||||
UNW_ARM_R6,
|
||||
UNW_ARM_R7,
|
||||
UNW_ARM_R8,
|
||||
UNW_ARM_R9,
|
||||
UNW_ARM_R10,
|
||||
UNW_ARM_R11,
|
||||
UNW_ARM_R12,
|
||||
UNW_ARM_R13,
|
||||
UNW_ARM_R14,
|
||||
UNW_ARM_R15,
|
||||
|
||||
/* VFPv2 s0-s31 (obsolescent numberings). */
|
||||
UNW_ARM_S0 = 64,
|
||||
UNW_ARM_S1,
|
||||
UNW_ARM_S2,
|
||||
UNW_ARM_S3,
|
||||
UNW_ARM_S4,
|
||||
UNW_ARM_S5,
|
||||
UNW_ARM_S6,
|
||||
UNW_ARM_S7,
|
||||
UNW_ARM_S8,
|
||||
UNW_ARM_S9,
|
||||
UNW_ARM_S10,
|
||||
UNW_ARM_S11,
|
||||
UNW_ARM_S12,
|
||||
UNW_ARM_S13,
|
||||
UNW_ARM_S14,
|
||||
UNW_ARM_S15,
|
||||
UNW_ARM_S16,
|
||||
UNW_ARM_S17,
|
||||
UNW_ARM_S18,
|
||||
UNW_ARM_S19,
|
||||
UNW_ARM_S20,
|
||||
UNW_ARM_S21,
|
||||
UNW_ARM_S22,
|
||||
UNW_ARM_S23,
|
||||
UNW_ARM_S24,
|
||||
UNW_ARM_S25,
|
||||
UNW_ARM_S26,
|
||||
UNW_ARM_S27,
|
||||
UNW_ARM_S28,
|
||||
UNW_ARM_S29,
|
||||
UNW_ARM_S30,
|
||||
UNW_ARM_S31,
|
||||
|
||||
/* FPA register numberings. */
|
||||
UNW_ARM_F0 = 96,
|
||||
UNW_ARM_F1,
|
||||
UNW_ARM_F2,
|
||||
UNW_ARM_F3,
|
||||
UNW_ARM_F4,
|
||||
UNW_ARM_F5,
|
||||
UNW_ARM_F6,
|
||||
UNW_ARM_F7,
|
||||
|
||||
/* iWMMXt GR register numberings. */
|
||||
UNW_ARM_wCGR0 = 104,
|
||||
UNW_ARM_wCGR1,
|
||||
UNW_ARM_wCGR2,
|
||||
UNW_ARM_wCGR3,
|
||||
UNW_ARM_wCGR4,
|
||||
UNW_ARM_wCGR5,
|
||||
UNW_ARM_wCGR6,
|
||||
UNW_ARM_wCGR7,
|
||||
|
||||
/* iWMMXt register numberings. */
|
||||
UNW_ARM_wR0 = 112,
|
||||
UNW_ARM_wR1,
|
||||
UNW_ARM_wR2,
|
||||
UNW_ARM_wR3,
|
||||
UNW_ARM_wR4,
|
||||
UNW_ARM_wR5,
|
||||
UNW_ARM_wR6,
|
||||
UNW_ARM_wR7,
|
||||
UNW_ARM_wR8,
|
||||
UNW_ARM_wR9,
|
||||
UNW_ARM_wR10,
|
||||
UNW_ARM_wR11,
|
||||
UNW_ARM_wR12,
|
||||
UNW_ARM_wR13,
|
||||
UNW_ARM_wR14,
|
||||
UNW_ARM_wR15,
|
||||
|
||||
/* Two-byte encodings from here on. */
|
||||
|
||||
/* SPSR. */
|
||||
UNW_ARM_SPSR = 128,
|
||||
UNW_ARM_SPSR_FIQ,
|
||||
UNW_ARM_SPSR_IRQ,
|
||||
UNW_ARM_SPSR_ABT,
|
||||
UNW_ARM_SPSR_UND,
|
||||
UNW_ARM_SPSR_SVC,
|
||||
|
||||
/* User mode registers. */
|
||||
UNW_ARM_R8_USR = 144,
|
||||
UNW_ARM_R9_USR,
|
||||
UNW_ARM_R10_USR,
|
||||
UNW_ARM_R11_USR,
|
||||
UNW_ARM_R12_USR,
|
||||
UNW_ARM_R13_USR,
|
||||
UNW_ARM_R14_USR,
|
||||
|
||||
/* FIQ registers. */
|
||||
UNW_ARM_R8_FIQ = 151,
|
||||
UNW_ARM_R9_FIQ,
|
||||
UNW_ARM_R10_FIQ,
|
||||
UNW_ARM_R11_FIQ,
|
||||
UNW_ARM_R12_FIQ,
|
||||
UNW_ARM_R13_FIQ,
|
||||
UNW_ARM_R14_FIQ,
|
||||
|
||||
/* IRQ registers. */
|
||||
UNW_ARM_R13_IRQ = 158,
|
||||
UNW_ARM_R14_IRQ,
|
||||
|
||||
/* ABT registers. */
|
||||
UNW_ARM_R13_ABT = 160,
|
||||
UNW_ARM_R14_ABT,
|
||||
|
||||
/* UND registers. */
|
||||
UNW_ARM_R13_UND = 162,
|
||||
UNW_ARM_R14_UND,
|
||||
|
||||
/* SVC registers. */
|
||||
UNW_ARM_R13_SVC = 164,
|
||||
UNW_ARM_R14_SVC,
|
||||
|
||||
/* iWMMXt control registers. */
|
||||
UNW_ARM_wC0 = 192,
|
||||
UNW_ARM_wC1,
|
||||
UNW_ARM_wC2,
|
||||
UNW_ARM_wC3,
|
||||
UNW_ARM_wC4,
|
||||
UNW_ARM_wC5,
|
||||
UNW_ARM_wC6,
|
||||
UNW_ARM_wC7,
|
||||
|
||||
/* VFPv3/Neon 64-bit registers. */
|
||||
UNW_ARM_D0 = 256,
|
||||
UNW_ARM_D1,
|
||||
UNW_ARM_D2,
|
||||
UNW_ARM_D3,
|
||||
UNW_ARM_D4,
|
||||
UNW_ARM_D5,
|
||||
UNW_ARM_D6,
|
||||
UNW_ARM_D7,
|
||||
UNW_ARM_D8,
|
||||
UNW_ARM_D9,
|
||||
UNW_ARM_D10,
|
||||
UNW_ARM_D11,
|
||||
UNW_ARM_D12,
|
||||
UNW_ARM_D13,
|
||||
UNW_ARM_D14,
|
||||
UNW_ARM_D15,
|
||||
UNW_ARM_D16,
|
||||
UNW_ARM_D17,
|
||||
UNW_ARM_D18,
|
||||
UNW_ARM_D19,
|
||||
UNW_ARM_D20,
|
||||
UNW_ARM_D21,
|
||||
UNW_ARM_D22,
|
||||
UNW_ARM_D23,
|
||||
UNW_ARM_D24,
|
||||
UNW_ARM_D25,
|
||||
UNW_ARM_D26,
|
||||
UNW_ARM_D27,
|
||||
UNW_ARM_D28,
|
||||
UNW_ARM_D29,
|
||||
UNW_ARM_D30,
|
||||
UNW_ARM_D31,
|
||||
|
||||
/* For ARM, the CFA is the value of SP (r13) at the call site in the
|
||||
previous frame. */
|
||||
UNW_ARM_CFA,
|
||||
|
||||
UNW_TDEP_LAST_REG = UNW_ARM_D31,
|
||||
|
||||
UNW_TDEP_IP = UNW_ARM_R14, /* A little white lie. */
|
||||
UNW_TDEP_SP = UNW_ARM_R13,
|
||||
UNW_TDEP_EH = UNW_ARM_R0 /* FIXME. */
|
||||
}
|
||||
arm_regnum_t;
|
||||
|
||||
#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for ARM. */
|
||||
|
||||
typedef struct unw_tdep_save_loc
|
||||
{
|
||||
/* Additional target-dependent info on a save location. */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_save_loc_t;
|
||||
|
||||
/* On ARM, we define our own unw_tdep_context instead of using ucontext_t.
|
||||
This allows us to support systems that don't support getcontext and
|
||||
therefore do not define ucontext_t. */
|
||||
typedef struct unw_tdep_context
|
||||
{
|
||||
unsigned long regs[16];
|
||||
}
|
||||
unw_tdep_context_t;
|
||||
|
||||
/* There is no getcontext() on ARM. Use a stub version which only saves GP
|
||||
registers. FIXME: Not ideal, may not be sufficient for all libunwind
|
||||
use cases. Stores pc+8, which is only approximately correct, really. */
|
||||
#ifndef __thumb__
|
||||
#define unw_tdep_getcontext(uc) (({ \
|
||||
unw_tdep_context_t *unw_ctx = (uc); \
|
||||
register unsigned long *unw_base asm ("r0") = unw_ctx->regs; \
|
||||
__asm__ __volatile__ ( \
|
||||
"stmia %[base], {r0-r15}" \
|
||||
: : [base] "r" (unw_base) : "memory"); \
|
||||
}), 0)
|
||||
#else /* __thumb__ */
|
||||
#define unw_tdep_getcontext(uc) (({ \
|
||||
unw_tdep_context_t *unw_ctx = (uc); \
|
||||
register unsigned long *unw_base asm ("r0") = unw_ctx->regs; \
|
||||
__asm__ __volatile__ ( \
|
||||
".align 2\nbx pc\nnop\n.code 32\n" \
|
||||
"stmia %[base], {r0-r15}\n" \
|
||||
"orr %[base], pc, #1\nbx %[base]" \
|
||||
: [base] "+r" (unw_base) : : "memory", "cc"); \
|
||||
}), 0)
|
||||
#endif
|
||||
|
||||
#include "libunwind-dynamic.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* no arm-specific auxiliary proc-info */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_proc_info_t;
|
||||
|
||||
#include "libunwind-common.h"
|
||||
|
||||
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
|
||||
extern int unw_tdep_is_fpreg (int);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIBUNWIND_H */
|
|
@ -0,0 +1,257 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2001-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. */
|
||||
|
||||
#define UNW_VERSION_MAJOR @PKG_MAJOR@
|
||||
#define UNW_VERSION_MINOR @PKG_MINOR@
|
||||
#define UNW_VERSION_EXTRA @PKG_EXTRA@
|
||||
|
||||
#define UNW_VERSION_CODE(maj,min) (((maj) << 16) | (min))
|
||||
#define UNW_VERSION UNW_VERSION_CODE(UNW_VERSION_MAJOR, UNW_VERSION_MINOR)
|
||||
|
||||
#define UNW_PASTE2(x,y) x##y
|
||||
#define UNW_PASTE(x,y) UNW_PASTE2(x,y)
|
||||
#define UNW_OBJ(fn) UNW_PASTE(UNW_PREFIX, fn)
|
||||
#define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
|
||||
|
||||
#ifdef UNW_LOCAL_ONLY
|
||||
# define UNW_PREFIX UNW_PASTE(UNW_PASTE(_UL,UNW_TARGET),_)
|
||||
#else /* !UNW_LOCAL_ONLY */
|
||||
# define UNW_PREFIX UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_)
|
||||
#endif /* !UNW_LOCAL_ONLY */
|
||||
|
||||
/* Error codes. The unwind routines return the *negated* values of
|
||||
these error codes on error and a non-negative value on success. */
|
||||
typedef enum
|
||||
{
|
||||
UNW_ESUCCESS = 0, /* no error */
|
||||
UNW_EUNSPEC, /* unspecified (general) error */
|
||||
UNW_ENOMEM, /* out of memory */
|
||||
UNW_EBADREG, /* bad register number */
|
||||
UNW_EREADONLYREG, /* attempt to write read-only register */
|
||||
UNW_ESTOPUNWIND, /* stop unwinding */
|
||||
UNW_EINVALIDIP, /* invalid IP */
|
||||
UNW_EBADFRAME, /* bad frame */
|
||||
UNW_EINVAL, /* unsupported operation or bad value */
|
||||
UNW_EBADVERSION, /* unwind info has unsupported version */
|
||||
UNW_ENOINFO /* no unwind info found */
|
||||
}
|
||||
unw_error_t;
|
||||
|
||||
/* The following enum defines the indices for a couple of
|
||||
(pseudo-)registers which have the same meaning across all
|
||||
platforms. (RO) means read-only. (RW) means read-write. General
|
||||
registers (aka "integer registers") are expected to start with
|
||||
index 0. The number of such registers is architecture-dependent.
|
||||
The remaining indices can be used as an architecture sees fit. The
|
||||
last valid register index is given by UNW_REG_LAST. */
|
||||
typedef enum
|
||||
{
|
||||
UNW_REG_IP = UNW_TDEP_IP, /* (rw) instruction pointer (pc) */
|
||||
UNW_REG_SP = UNW_TDEP_SP, /* (ro) stack pointer */
|
||||
UNW_REG_EH = UNW_TDEP_EH, /* (rw) exception-handling reg base */
|
||||
UNW_REG_LAST = UNW_TDEP_LAST_REG
|
||||
}
|
||||
unw_frame_regnum_t;
|
||||
|
||||
/* Number of exception-handler argument registers: */
|
||||
#define UNW_NUM_EH_REGS UNW_TDEP_NUM_EH_REGS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNW_CACHE_NONE, /* no caching */
|
||||
UNW_CACHE_GLOBAL, /* shared global cache */
|
||||
UNW_CACHE_PER_THREAD /* per-thread caching */
|
||||
}
|
||||
unw_caching_policy_t;
|
||||
|
||||
typedef int unw_regnum_t;
|
||||
|
||||
/* The unwind cursor starts at the youngest (most deeply nested) frame
|
||||
and is used to track the frame state as the unwinder steps from
|
||||
frame to frame. It is safe to make (shallow) copies of variables
|
||||
of this type. */
|
||||
typedef struct unw_cursor
|
||||
{
|
||||
unw_word_t opaque[UNW_TDEP_CURSOR_LEN];
|
||||
}
|
||||
unw_cursor_t;
|
||||
|
||||
/* This type encapsulates the entire (preserved) machine-state. */
|
||||
typedef unw_tdep_context_t unw_context_t;
|
||||
|
||||
/* unw_getcontext() fills the unw_context_t pointed to by UC with the
|
||||
machine state as it exists at the call-site. For implementation
|
||||
reasons, this needs to be a target-dependent macro. It's easiest
|
||||
to think of unw_getcontext() as being identical to getcontext(). */
|
||||
#define unw_getcontext(uc) unw_tdep_getcontext(uc)
|
||||
|
||||
/* Return 1 if register number R is a floating-point register, zero
|
||||
otherwise.
|
||||
This routine is signal-safe. */
|
||||
#define unw_is_fpreg(r) unw_tdep_is_fpreg(r)
|
||||
|
||||
typedef unw_tdep_fpreg_t unw_fpreg_t;
|
||||
|
||||
typedef struct unw_addr_space *unw_addr_space_t;
|
||||
|
||||
/* Each target may define it's own set of flags, but bits 0-15 are
|
||||
reserved for general libunwind-use. */
|
||||
#define UNW_PI_FLAG_FIRST_TDEP_BIT 16
|
||||
/* The information comes from a .debug_frame section. */
|
||||
#define UNW_PI_FLAG_DEBUG_FRAME 32
|
||||
|
||||
typedef struct unw_proc_info
|
||||
{
|
||||
unw_word_t start_ip; /* first IP covered by this procedure */
|
||||
unw_word_t end_ip; /* first IP NOT covered by this procedure */
|
||||
unw_word_t lsda; /* address of lang.-spec. data area (if any) */
|
||||
unw_word_t handler; /* optional personality routine */
|
||||
unw_word_t gp; /* global-pointer value for this procedure */
|
||||
unw_word_t flags; /* misc. flags */
|
||||
|
||||
int format; /* unwind-info format (arch-specific) */
|
||||
int unwind_info_size; /* size of the information (if applicable) */
|
||||
void *unwind_info; /* unwind-info (arch-specific) */
|
||||
unw_tdep_proc_info_t extra; /* target-dependent auxiliary proc-info */
|
||||
}
|
||||
unw_proc_info_t;
|
||||
|
||||
/* These are backend callback routines that provide access to the
|
||||
state of a "remote" process. This can be used, for example, to
|
||||
unwind another process through the ptrace() interface. */
|
||||
typedef struct unw_accessors
|
||||
{
|
||||
/* Look up the unwind info associated with instruction-pointer IP.
|
||||
On success, the routine fills in the PROC_INFO structure. */
|
||||
int (*find_proc_info) (unw_addr_space_t, unw_word_t, unw_proc_info_t *,
|
||||
int, void *);
|
||||
|
||||
/* Release any resources (e.g., memory) that were allocated for
|
||||
the unwind info returned in by a previous call to
|
||||
find_proc_info() with NEED_UNWIND_INFO set to 1. */
|
||||
void (*put_unwind_info) (unw_addr_space_t, unw_proc_info_t *, void *);
|
||||
|
||||
/* Return the list-head of the dynamically registered unwind
|
||||
info. */
|
||||
int (*get_dyn_info_list_addr) (unw_addr_space_t, unw_word_t *, void *);
|
||||
|
||||
/* Access aligned word at address ADDR. The value is returned
|
||||
according to the endianness of the host (e.g., if the host is
|
||||
little-endian and the target is big-endian, access_mem() needs
|
||||
to byte-swap the value before returning it). */
|
||||
int (*access_mem) (unw_addr_space_t, unw_word_t, unw_word_t *, int,
|
||||
void *);
|
||||
|
||||
/* Access register number REG at address ADDR. */
|
||||
int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, int,
|
||||
void *);
|
||||
|
||||
/* Access register number REG at address ADDR. */
|
||||
int (*access_fpreg) (unw_addr_space_t, unw_regnum_t,
|
||||
unw_fpreg_t *, int, void *);
|
||||
|
||||
int (*resume) (unw_addr_space_t, unw_cursor_t *, void *);
|
||||
|
||||
/* Optional call back to obtain the name of a (static) procedure.
|
||||
Dynamically generated procedures are handled automatically by
|
||||
libunwind. This callback is optional and may be set to
|
||||
NULL. */
|
||||
int (*get_proc_name) (unw_addr_space_t, unw_word_t, char *, size_t,
|
||||
unw_word_t *, void *);
|
||||
}
|
||||
unw_accessors_t;
|
||||
|
||||
typedef enum unw_save_loc_type
|
||||
{
|
||||
UNW_SLT_NONE, /* register is not saved ("not an l-value") */
|
||||
UNW_SLT_MEMORY, /* register has been saved in memory */
|
||||
UNW_SLT_REG /* register has been saved in (another) register */
|
||||
}
|
||||
unw_save_loc_type_t;
|
||||
|
||||
typedef struct unw_save_loc
|
||||
{
|
||||
unw_save_loc_type_t type;
|
||||
union
|
||||
{
|
||||
unw_word_t addr; /* valid if type==UNW_SLT_MEMORY */
|
||||
unw_regnum_t regnum; /* valid if type==UNW_SLT_REG */
|
||||
}
|
||||
u;
|
||||
unw_tdep_save_loc_t extra; /* target-dependent additional information */
|
||||
}
|
||||
unw_save_loc_t;
|
||||
|
||||
/* These routines work both for local and remote unwinding. */
|
||||
|
||||
#define unw_local_addr_space UNW_OBJ(local_addr_space)
|
||||
#define unw_create_addr_space UNW_OBJ(create_addr_space)
|
||||
#define unw_destroy_addr_space UNW_OBJ(destroy_addr_space)
|
||||
#define unw_get_accessors UNW_ARCH_OBJ(get_accessors)
|
||||
#define unw_init_local UNW_OBJ(init_local)
|
||||
#define unw_init_remote UNW_OBJ(init_remote)
|
||||
#define unw_step UNW_OBJ(step)
|
||||
#define unw_resume UNW_OBJ(resume)
|
||||
#define unw_get_proc_info UNW_OBJ(get_proc_info)
|
||||
#define unw_get_proc_info_by_ip UNW_OBJ(get_proc_info_by_ip)
|
||||
#define unw_get_reg UNW_OBJ(get_reg)
|
||||
#define unw_set_reg UNW_OBJ(set_reg)
|
||||
#define unw_get_fpreg UNW_OBJ(get_fpreg)
|
||||
#define unw_set_fpreg UNW_OBJ(set_fpreg)
|
||||
#define unw_get_save_loc UNW_OBJ(get_save_loc)
|
||||
#define unw_is_signal_frame UNW_OBJ(is_signal_frame)
|
||||
#define unw_handle_signal_frame UNW_OBJ(handle_signal_frame)
|
||||
#define unw_get_proc_name UNW_OBJ(get_proc_name)
|
||||
#define unw_set_caching_policy UNW_OBJ(set_caching_policy)
|
||||
#define unw_regname UNW_ARCH_OBJ(regname)
|
||||
#define unw_flush_cache UNW_ARCH_OBJ(flush_cache)
|
||||
#define unw_strerror UNW_ARCH_OBJ(strerror)
|
||||
|
||||
extern unw_addr_space_t unw_create_addr_space (unw_accessors_t *, int);
|
||||
extern void unw_destroy_addr_space (unw_addr_space_t);
|
||||
extern unw_accessors_t *unw_get_accessors (unw_addr_space_t);
|
||||
extern void unw_flush_cache (unw_addr_space_t, unw_word_t, unw_word_t);
|
||||
extern int unw_set_caching_policy (unw_addr_space_t, unw_caching_policy_t);
|
||||
extern const char *unw_regname (unw_regnum_t);
|
||||
|
||||
extern int unw_init_local (unw_cursor_t *, unw_context_t *);
|
||||
extern int unw_init_remote (unw_cursor_t *, unw_addr_space_t, void *);
|
||||
extern int unw_step (unw_cursor_t *);
|
||||
extern int unw_resume (unw_cursor_t *);
|
||||
extern int unw_get_proc_info (unw_cursor_t *, unw_proc_info_t *);
|
||||
extern int unw_get_proc_info_by_ip (unw_addr_space_t, unw_word_t,
|
||||
unw_proc_info_t *, void *);
|
||||
extern int unw_get_reg (unw_cursor_t *, int, unw_word_t *);
|
||||
extern int unw_set_reg (unw_cursor_t *, int, unw_word_t);
|
||||
extern int unw_get_fpreg (unw_cursor_t *, int, unw_fpreg_t *);
|
||||
extern int unw_set_fpreg (unw_cursor_t *, int, unw_fpreg_t);
|
||||
extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *);
|
||||
extern int unw_is_signal_frame (unw_cursor_t *);
|
||||
extern int unw_handle_signal_frame (unw_cursor_t *);
|
||||
extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *);
|
||||
extern const char *unw_strerror (int);
|
||||
extern int unw_backtrace (void **, int);
|
||||
|
||||
extern unw_addr_space_t unw_local_addr_space;
|
|
@ -0,0 +1,73 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef libunwind_coredump_h
|
||||
#define libunwind_coredump_h
|
||||
|
||||
#include <libunwind.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Helper routines which make it easy to use libunwind on a coredump.
|
||||
They're available only if UNW_REMOTE_ONLY is _not_ defined and they
|
||||
aren't really part of the libunwind API. They are implemented in a
|
||||
archive library called libunwind-coredump.a. */
|
||||
|
||||
struct UCD_info;
|
||||
|
||||
extern struct UCD_info *_UCD_create(const char *filename);
|
||||
extern void _UCD_destroy(struct UCD_info *);
|
||||
|
||||
extern int _UCD_get_num_threads(struct UCD_info *);
|
||||
extern void _UCD_select_thread(struct UCD_info *, int);
|
||||
extern pid_t _UCD_get_pid(struct UCD_info *);
|
||||
extern int _UCD_get_cursig(struct UCD_info *);
|
||||
extern int _UCD_add_backing_file_at_segment(struct UCD_info *, int phdr_no, const char *filename);
|
||||
extern int _UCD_add_backing_file_at_vaddr(struct UCD_info *,
|
||||
unsigned long vaddr,
|
||||
const char *filename);
|
||||
|
||||
extern int _UCD_find_proc_info (unw_addr_space_t, unw_word_t,
|
||||
unw_proc_info_t *, int, void *);
|
||||
extern void _UCD_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *);
|
||||
extern int _UCD_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *,
|
||||
void *);
|
||||
extern int _UCD_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int,
|
||||
void *);
|
||||
extern int _UCD_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *,
|
||||
int, void *);
|
||||
extern int _UCD_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *,
|
||||
int, void *);
|
||||
extern int _UCD_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t,
|
||||
unw_word_t *, void *);
|
||||
extern int _UCD_resume (unw_addr_space_t, unw_cursor_t *, void *);
|
||||
extern unw_accessors_t _UCD_accessors;
|
||||
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* libunwind_coredump_h */
|
|
@ -0,0 +1,210 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2002-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. */
|
||||
|
||||
/* This file defines the runtime-support routines for dynamically
|
||||
generated code. Even though it is implemented as part of libunwind,
|
||||
it is logically separate from the interface to perform the actual
|
||||
unwinding. In particular, this interface is always used in the
|
||||
context of the unwind target, whereas the rest of the unwind API is
|
||||
used in context of the process that is doing the unwind (which may be
|
||||
a debugger running on another machine, for example).
|
||||
|
||||
Note that the data-structures declared here server a dual purpose:
|
||||
when a program registers a dynamically generated procedure, it uses
|
||||
these structures directly. On the other hand, with remote-unwinding,
|
||||
the data-structures are read from the remote process's memory and
|
||||
translated into internalized versions. To facilitate remote-access,
|
||||
the following rules should be followed in declaring these structures:
|
||||
|
||||
(1) Declare a member as a pointer only if the the information the
|
||||
member points to needs to be internalized as well (e.g., a
|
||||
string representing a procedure name should be declared as
|
||||
"const char *", but the instruction pointer should be declared
|
||||
as unw_word_t).
|
||||
|
||||
(2) Provide sufficient padding to ensure that no implicit padding
|
||||
will be needed on any of the supported target architectures. For
|
||||
the time being, padding data structures with the assumption that
|
||||
sizeof (unw_word_t) == 8 should be sufficient. (Note: it's not
|
||||
impossible to internalize structures with internal padding, but
|
||||
it does make the process a bit harder).
|
||||
|
||||
(3) Don't declare members that contain bitfields or floating-point
|
||||
values.
|
||||
|
||||
(4) Don't declare members with enumeration types. Declare them as
|
||||
int32_t instead. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNW_DYN_STOP = 0, /* end-of-unwind-info marker */
|
||||
UNW_DYN_SAVE_REG, /* save register to another register */
|
||||
UNW_DYN_SPILL_FP_REL, /* frame-pointer-relative register spill */
|
||||
UNW_DYN_SPILL_SP_REL, /* stack-pointer-relative register spill */
|
||||
UNW_DYN_ADD, /* add constant value to a register */
|
||||
UNW_DYN_POP_FRAMES, /* drop one or more stack frames */
|
||||
UNW_DYN_LABEL_STATE, /* name the current state */
|
||||
UNW_DYN_COPY_STATE, /* set the region's entry-state */
|
||||
UNW_DYN_ALIAS /* get unwind info from an alias */
|
||||
}
|
||||
unw_dyn_operation_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNW_INFO_FORMAT_DYNAMIC, /* unw_dyn_proc_info_t */
|
||||
UNW_INFO_FORMAT_TABLE, /* unw_dyn_table_t */
|
||||
UNW_INFO_FORMAT_REMOTE_TABLE, /* unw_dyn_remote_table_t */
|
||||
UNW_INFO_FORMAT_ARM_EXIDX /* ARM specific unwind info */
|
||||
}
|
||||
unw_dyn_info_format_t;
|
||||
|
||||
typedef struct unw_dyn_op
|
||||
{
|
||||
int8_t tag; /* what operation? */
|
||||
int8_t qp; /* qualifying predicate register */
|
||||
int16_t reg; /* what register */
|
||||
int32_t when; /* when does it take effect? */
|
||||
unw_word_t val; /* auxiliary value */
|
||||
}
|
||||
unw_dyn_op_t;
|
||||
|
||||
typedef struct unw_dyn_region_info
|
||||
{
|
||||
struct unw_dyn_region_info *next; /* linked list of regions */
|
||||
int32_t insn_count; /* region length (# of instructions) */
|
||||
uint32_t op_count; /* length of op-array */
|
||||
unw_dyn_op_t op[1]; /* variable-length op-array */
|
||||
}
|
||||
unw_dyn_region_info_t;
|
||||
|
||||
typedef struct unw_dyn_proc_info
|
||||
{
|
||||
unw_word_t name_ptr; /* address of human-readable procedure name */
|
||||
unw_word_t handler; /* address of personality routine */
|
||||
uint32_t flags;
|
||||
int32_t pad0;
|
||||
unw_dyn_region_info_t *regions;
|
||||
}
|
||||
unw_dyn_proc_info_t;
|
||||
|
||||
typedef struct unw_dyn_table_info
|
||||
{
|
||||
unw_word_t name_ptr; /* addr. of table name (e.g., library name) */
|
||||
unw_word_t segbase; /* segment base */
|
||||
unw_word_t table_len; /* must be a multiple of sizeof(unw_word_t)! */
|
||||
unw_word_t *table_data;
|
||||
}
|
||||
unw_dyn_table_info_t;
|
||||
|
||||
typedef struct unw_dyn_remote_table_info
|
||||
{
|
||||
unw_word_t name_ptr; /* addr. of table name (e.g., library name) */
|
||||
unw_word_t segbase; /* segment base */
|
||||
unw_word_t table_len; /* must be a multiple of sizeof(unw_word_t)! */
|
||||
unw_word_t table_data;
|
||||
}
|
||||
unw_dyn_remote_table_info_t;
|
||||
|
||||
typedef struct unw_dyn_info
|
||||
{
|
||||
/* doubly-linked list of dyn-info structures: */
|
||||
struct unw_dyn_info *next;
|
||||
struct unw_dyn_info *prev;
|
||||
unw_word_t start_ip; /* first IP covered by this entry */
|
||||
unw_word_t end_ip; /* first IP NOT covered by this entry */
|
||||
unw_word_t gp; /* global-pointer in effect for this entry */
|
||||
int32_t format; /* real type: unw_dyn_info_format_t */
|
||||
int32_t pad;
|
||||
union
|
||||
{
|
||||
unw_dyn_proc_info_t pi;
|
||||
unw_dyn_table_info_t ti;
|
||||
unw_dyn_remote_table_info_t rti;
|
||||
}
|
||||
u;
|
||||
}
|
||||
unw_dyn_info_t;
|
||||
|
||||
typedef struct unw_dyn_info_list
|
||||
{
|
||||
uint32_t version;
|
||||
uint32_t generation;
|
||||
unw_dyn_info_t *first;
|
||||
}
|
||||
unw_dyn_info_list_t;
|
||||
|
||||
/* Return the size (in bytes) of an unw_dyn_region_info_t structure that can
|
||||
hold OP_COUNT ops. */
|
||||
#define _U_dyn_region_info_size(op_count) \
|
||||
((char *) (((unw_dyn_region_info_t *) NULL)->op + (op_count)) \
|
||||
- (char *) NULL)
|
||||
|
||||
/* Register the unwind info for a single procedure.
|
||||
This routine is NOT signal-safe. */
|
||||
extern void _U_dyn_register (unw_dyn_info_t *);
|
||||
|
||||
/* Cancel the unwind info for a single procedure.
|
||||
This routine is NOT signal-safe. */
|
||||
extern void _U_dyn_cancel (unw_dyn_info_t *);
|
||||
|
||||
|
||||
/* Convenience routines. */
|
||||
|
||||
#define _U_dyn_op(_tag, _qp, _when, _reg, _val) \
|
||||
((unw_dyn_op_t) { (_tag), (_qp), (_reg), (_when), (_val) })
|
||||
|
||||
#define _U_dyn_op_save_reg(op, qp, when, reg, dst) \
|
||||
(*(op) = _U_dyn_op (UNW_DYN_SAVE_REG, (qp), (when), (reg), (dst)))
|
||||
|
||||
#define _U_dyn_op_spill_fp_rel(op, qp, when, reg, offset) \
|
||||
(*(op) = _U_dyn_op (UNW_DYN_SPILL_FP_REL, (qp), (when), (reg), \
|
||||
(offset)))
|
||||
|
||||
#define _U_dyn_op_spill_sp_rel(op, qp, when, reg, offset) \
|
||||
(*(op) = _U_dyn_op (UNW_DYN_SPILL_SP_REL, (qp), (when), (reg), \
|
||||
(offset)))
|
||||
|
||||
#define _U_dyn_op_add(op, qp, when, reg, value) \
|
||||
(*(op) = _U_dyn_op (UNW_DYN_ADD, (qp), (when), (reg), (value)))
|
||||
|
||||
#define _U_dyn_op_pop_frames(op, qp, when, num_frames) \
|
||||
(*(op) = _U_dyn_op (UNW_DYN_POP_FRAMES, (qp), (when), 0, (num_frames)))
|
||||
|
||||
#define _U_dyn_op_label_state(op, label) \
|
||||
(*(op) = _U_dyn_op (UNW_DYN_LABEL_STATE, _U_QP_TRUE, -1, 0, (label)))
|
||||
|
||||
#define _U_dyn_op_copy_state(op, label) \
|
||||
(*(op) = _U_dyn_op (UNW_DYN_COPY_STATE, _U_QP_TRUE, -1, 0, (label)))
|
||||
|
||||
#define _U_dyn_op_alias(op, qp, when, addr) \
|
||||
(*(op) = _U_dyn_op (UNW_DYN_ALIAS, (qp), (when), 0, (addr)))
|
||||
|
||||
#define _U_dyn_op_stop(op) \
|
||||
(*(op) = _U_dyn_op (UNW_DYN_STOP, _U_QP_TRUE, -1, 0, 0))
|
||||
|
||||
/* The target-dependent qualifying predicate which is always TRUE. On
|
||||
IA-64, that's p0 (0), on non-predicated architectures, the value is
|
||||
ignored. */
|
||||
#define _U_QP_TRUE _U_TDEP_QP_TRUE
|
|
@ -0,0 +1,131 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2003-2004 Hewlett-Packard Co
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef LIBUNWIND_H
|
||||
#define LIBUNWIND_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define UNW_TARGET hppa
|
||||
#define UNW_TARGET_HPPA 1
|
||||
|
||||
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
|
||||
|
||||
/* This needs to be big enough to accommodate "struct cursor", while
|
||||
leaving some slack for future expansion. Changing this value will
|
||||
require recompiling all users of this library. Stack allocation is
|
||||
relatively cheap and unwind-state copying is relatively rare, so we
|
||||
want to err on making it rather too big than too small. */
|
||||
#define UNW_TDEP_CURSOR_LEN 511
|
||||
|
||||
typedef uint32_t unw_word_t;
|
||||
typedef int32_t unw_sword_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct { unw_word_t bits[2]; } raw;
|
||||
double val;
|
||||
}
|
||||
unw_tdep_fpreg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* Note: general registers are expected to start with index 0.
|
||||
This convention facilitates architecture-independent
|
||||
implementation of the C++ exception handling ABI. See
|
||||
_Unwind_SetGR() and _Unwind_GetGR() for details. */
|
||||
UNW_HPPA_GR = 0,
|
||||
UNW_HPPA_RP = 2, /* return pointer */
|
||||
UNW_HPPA_FP = 3, /* frame pointer */
|
||||
UNW_HPPA_SP = UNW_HPPA_GR + 30,
|
||||
|
||||
UNW_HPPA_FR = UNW_HPPA_GR + 32,
|
||||
|
||||
UNW_HPPA_IP = UNW_HPPA_FR + 32, /* instruction pointer */
|
||||
|
||||
/* other "preserved" registers (fpsr etc.)... */
|
||||
|
||||
/* PA-RISC has 4 exception-argument registers but they're not
|
||||
contiguous. To deal with this, we define 4 pseudo
|
||||
exception-handling registers which we then alias to the actual
|
||||
physical register. */
|
||||
|
||||
UNW_HPPA_EH0 = UNW_HPPA_IP + 1, /* alias for UNW_HPPA_GR + 20 */
|
||||
UNW_HPPA_EH1 = UNW_HPPA_EH0 + 1, /* alias for UNW_HPPA_GR + 21 */
|
||||
UNW_HPPA_EH2 = UNW_HPPA_EH1 + 1, /* alias for UNW_HPPA_GR + 22 */
|
||||
UNW_HPPA_EH3 = UNW_HPPA_EH2 + 1, /* alias for UNW_HPPA_GR + 31 */
|
||||
|
||||
/* frame info (read-only) */
|
||||
UNW_HPPA_CFA,
|
||||
|
||||
UNW_TDEP_LAST_REG = UNW_HPPA_IP,
|
||||
|
||||
UNW_TDEP_IP = UNW_HPPA_IP,
|
||||
UNW_TDEP_SP = UNW_HPPA_SP,
|
||||
UNW_TDEP_EH = UNW_HPPA_EH0
|
||||
}
|
||||
hppa_regnum_t;
|
||||
|
||||
#define UNW_TDEP_NUM_EH_REGS 4
|
||||
|
||||
typedef struct unw_tdep_save_loc
|
||||
{
|
||||
/* Additional target-dependent info on a save location. */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_save_loc_t;
|
||||
|
||||
/* On PA-RISC, we can directly use ucontext_t as the unwind context. */
|
||||
typedef ucontext_t unw_tdep_context_t;
|
||||
|
||||
#define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_HPPA_FR) < 32)
|
||||
|
||||
#include "libunwind-dynamic.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* no PA-RISC-specific auxiliary proc-info */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_proc_info_t;
|
||||
|
||||
#include "libunwind-common.h"
|
||||
|
||||
#define unw_tdep_getcontext UNW_ARCH_OBJ (getcontext)
|
||||
extern int unw_tdep_getcontext (unw_tdep_context_t *);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIBUNWIND_H */
|
|
@ -0,0 +1,197 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2001-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. */
|
||||
|
||||
#ifndef LIBUNWIND_H
|
||||
#define LIBUNWIND_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef ia64
|
||||
/* This works around a bug in Intel's ECC v7.0 which defines "ia64"
|
||||
as "1". */
|
||||
# undef ia64
|
||||
#endif
|
||||
|
||||
#ifdef __hpux
|
||||
/* On HP-UX, there is no hope of supporting UNW_LOCAL_ONLY, because
|
||||
it's impossible to obtain the address of the members in the
|
||||
sigcontext structure. */
|
||||
# undef UNW_LOCAL_ONLY
|
||||
# define UNW_GENERIC_ONLY
|
||||
#endif
|
||||
|
||||
#define UNW_TARGET ia64
|
||||
#define UNW_TARGET_IA64 1
|
||||
|
||||
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
|
||||
|
||||
/* This needs to be big enough to accommodate "struct cursor", while
|
||||
leaving some slack for future expansion. Changing this value will
|
||||
require recompiling all users of this library. Stack allocation is
|
||||
relatively cheap and unwind-state copying is relatively rare, so we
|
||||
want to err on making it rather too big than too small. */
|
||||
#define UNW_TDEP_CURSOR_LEN 511
|
||||
|
||||
/* If this bit is it indicates that the procedure saved all of ar.bsp,
|
||||
ar.bspstore, and ar.rnat. If, additionally, ar.bsp != saved ar.bsp,
|
||||
then this procedure has performed a register-backing-store switch. */
|
||||
#define UNW_PI_FLAG_IA64_RBS_SWITCH_BIT (UNW_PI_FLAG_FIRST_TDEP_BIT + 0)
|
||||
|
||||
#define UNW_PI_FLAG_IA64_RBS_SWITCH (1 << UNW_PI_FLAG_IA64_RBS_SWITCH_BIT)
|
||||
|
||||
typedef uint64_t unw_word_t;
|
||||
typedef int64_t unw_sword_t;
|
||||
|
||||
/* On IA-64, we want to access the contents of floating-point
|
||||
registers as a pair of "words", but to ensure 16-byte alignment, we
|
||||
make it a union that contains a "long double". This will do the
|
||||
Right Thing on all known IA-64 platforms, including HP-UX. */
|
||||
typedef union
|
||||
{
|
||||
struct { unw_word_t bits[2]; } raw;
|
||||
long double dummy; /* dummy to force 16-byte alignment */
|
||||
}
|
||||
unw_tdep_fpreg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* no ia64-specific auxiliary proc-info */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_proc_info_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* Note: general registers are excepted to start with index 0.
|
||||
This convention facilitates architecture-independent
|
||||
implementation of the C++ exception handling ABI. See
|
||||
_Unwind_SetGR() and _Unwind_GetGR() for details. */
|
||||
UNW_IA64_GR = 0, /* general registers (r0..r127) */
|
||||
UNW_IA64_GP = UNW_IA64_GR + 1,
|
||||
UNW_IA64_TP = UNW_IA64_GR + 13,
|
||||
|
||||
UNW_IA64_NAT = UNW_IA64_GR + 128, /* NaT registers (nat0..nat127) */
|
||||
|
||||
UNW_IA64_FR = UNW_IA64_NAT + 128, /* fp registers (f0..f127) */
|
||||
|
||||
UNW_IA64_AR = UNW_IA64_FR + 128, /* application registers (ar0..r127) */
|
||||
UNW_IA64_AR_RSC = UNW_IA64_AR + 16,
|
||||
UNW_IA64_AR_BSP = UNW_IA64_AR + 17,
|
||||
UNW_IA64_AR_BSPSTORE = UNW_IA64_AR + 18,
|
||||
UNW_IA64_AR_RNAT = UNW_IA64_AR + 19,
|
||||
UNW_IA64_AR_CSD = UNW_IA64_AR + 25,
|
||||
UNW_IA64_AR_26 = UNW_IA64_AR + 26,
|
||||
UNW_IA64_AR_SSD = UNW_IA64_AR_26,
|
||||
UNW_IA64_AR_CCV = UNW_IA64_AR + 32,
|
||||
UNW_IA64_AR_UNAT = UNW_IA64_AR + 36,
|
||||
UNW_IA64_AR_FPSR = UNW_IA64_AR + 40,
|
||||
UNW_IA64_AR_PFS = UNW_IA64_AR + 64,
|
||||
UNW_IA64_AR_LC = UNW_IA64_AR + 65,
|
||||
UNW_IA64_AR_EC = UNW_IA64_AR + 66,
|
||||
|
||||
UNW_IA64_BR = UNW_IA64_AR + 128, /* branch registers (b0..p7) */
|
||||
UNW_IA64_RP = UNW_IA64_BR + 0, /* return pointer (rp) */
|
||||
UNW_IA64_PR = UNW_IA64_BR + 8, /* predicate registers (p0..p63) */
|
||||
UNW_IA64_CFM,
|
||||
|
||||
/* frame info: */
|
||||
UNW_IA64_BSP,
|
||||
UNW_IA64_IP,
|
||||
UNW_IA64_SP,
|
||||
|
||||
UNW_TDEP_LAST_REG = UNW_IA64_SP,
|
||||
|
||||
UNW_TDEP_IP = UNW_IA64_IP,
|
||||
UNW_TDEP_SP = UNW_IA64_SP,
|
||||
UNW_TDEP_EH = UNW_IA64_GR + 15
|
||||
}
|
||||
ia64_regnum_t;
|
||||
|
||||
#define UNW_TDEP_NUM_EH_REGS 4 /* r15-r18 are exception args */
|
||||
|
||||
typedef struct unw_tdep_save_loc
|
||||
{
|
||||
/* Additional target-dependent info on a save location. On IA-64,
|
||||
we use this to provide the bit number in which a NaT bit gets
|
||||
saved. */
|
||||
uint8_t nat_bitnr;
|
||||
|
||||
/* Padding reserved for future use. */
|
||||
uint8_t reserved[7];
|
||||
}
|
||||
unw_tdep_save_loc_t;
|
||||
|
||||
/* On IA-64, we can directly use ucontext_t as the unwind context. */
|
||||
typedef ucontext_t unw_tdep_context_t;
|
||||
|
||||
#define unw_tdep_is_fpreg(r) ((unsigned) ((r) - UNW_IA64_FR) < 128)
|
||||
|
||||
#include "libunwind-dynamic.h"
|
||||
#include "libunwind-common.h"
|
||||
|
||||
#ifdef __hpux
|
||||
/* In theory, we could use _Uia64_getcontext() on HP-UX as well, but
|
||||
the benefit of doing so would be marginal given that it can't
|
||||
support UNW_LOCAL_ONLY. */
|
||||
# define unw_tdep_getcontext getcontext
|
||||
#else
|
||||
# define unw_tdep_getcontext UNW_ARCH_OBJ (getcontext)
|
||||
extern int unw_tdep_getcontext (unw_tdep_context_t *);
|
||||
#endif
|
||||
|
||||
/* This is a helper routine to search an ia64 unwind table. If the
|
||||
address-space argument AS points to something other than the local
|
||||
address-space, the memory for the unwind-info will be allocated
|
||||
with malloc(), and should be free()d during the put_unwind_info()
|
||||
callback. This routine is signal-safe for the local-address-space
|
||||
case ONLY. */
|
||||
#define unw_search_ia64_unwind_table UNW_OBJ(search_unwind_table)
|
||||
extern int unw_search_ia64_unwind_table (unw_addr_space_t, unw_word_t,
|
||||
unw_dyn_info_t *, unw_proc_info_t *,
|
||||
int, void *);
|
||||
|
||||
/* This is a helper routine which the get_dyn_info_list_addr()
|
||||
callback can use to locate the special dynamic-info list entry in
|
||||
an IA-64 unwind table. If the entry exists in the table, the
|
||||
list-address is returned. In all other cases, 0 is returned. */
|
||||
extern unw_word_t _Uia64_find_dyn_list (unw_addr_space_t, unw_dyn_info_t *,
|
||||
void *);
|
||||
|
||||
/* This is a helper routine to obtain the kernel-unwind info. It is
|
||||
signal-safe. */
|
||||
extern int _Uia64_get_kernel_table (unw_dyn_info_t *);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIBUNWIND_H */
|
|
@ -0,0 +1,163 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef LIBUNWIND_H
|
||||
#define LIBUNWIND_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#ifdef mips
|
||||
# undef mips
|
||||
#endif
|
||||
|
||||
#define UNW_TARGET mips
|
||||
#define UNW_TARGET_MIPS 1
|
||||
|
||||
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
|
||||
|
||||
/* This needs to be big enough to accommodate "struct cursor", while
|
||||
leaving some slack for future expansion. Changing this value will
|
||||
require recompiling all users of this library. Stack allocation is
|
||||
relatively cheap and unwind-state copying is relatively rare, so we
|
||||
want to err on making it rather too big than too small. */
|
||||
|
||||
/* FIXME for MIPS. Too big? What do other things use for similar tasks? */
|
||||
#define UNW_TDEP_CURSOR_LEN 4096
|
||||
|
||||
/* The size of a "word" varies on MIPS. This type is used for memory
|
||||
addresses and register values. To allow a single library to support
|
||||
multiple ABIs, and to support N32 at all, we must use a 64-bit type
|
||||
even when addresses are only 32 bits. */
|
||||
typedef uint64_t unw_word_t;
|
||||
typedef int32_t unw_sword_t;
|
||||
|
||||
/* FIXME: MIPS ABIs. */
|
||||
typedef long double unw_tdep_fpreg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNW_MIPS_R0,
|
||||
UNW_MIPS_R1,
|
||||
UNW_MIPS_R2,
|
||||
UNW_MIPS_R3,
|
||||
UNW_MIPS_R4,
|
||||
UNW_MIPS_R5,
|
||||
UNW_MIPS_R6,
|
||||
UNW_MIPS_R7,
|
||||
UNW_MIPS_R8,
|
||||
UNW_MIPS_R9,
|
||||
UNW_MIPS_R10,
|
||||
UNW_MIPS_R11,
|
||||
UNW_MIPS_R12,
|
||||
UNW_MIPS_R13,
|
||||
UNW_MIPS_R14,
|
||||
UNW_MIPS_R15,
|
||||
UNW_MIPS_R16,
|
||||
UNW_MIPS_R17,
|
||||
UNW_MIPS_R18,
|
||||
UNW_MIPS_R19,
|
||||
UNW_MIPS_R20,
|
||||
UNW_MIPS_R21,
|
||||
UNW_MIPS_R22,
|
||||
UNW_MIPS_R23,
|
||||
UNW_MIPS_R24,
|
||||
UNW_MIPS_R25,
|
||||
UNW_MIPS_R26,
|
||||
UNW_MIPS_R27,
|
||||
UNW_MIPS_R28,
|
||||
UNW_MIPS_R29,
|
||||
UNW_MIPS_R30,
|
||||
UNW_MIPS_R31,
|
||||
|
||||
UNW_MIPS_PC = 34,
|
||||
|
||||
/* FIXME: Other registers! */
|
||||
|
||||
/* For MIPS, the CFA is the value of SP (r29) at the call site in the
|
||||
previous frame. */
|
||||
UNW_MIPS_CFA,
|
||||
|
||||
UNW_TDEP_LAST_REG = UNW_MIPS_R31,
|
||||
|
||||
UNW_TDEP_IP = UNW_MIPS_R31,
|
||||
UNW_TDEP_SP = UNW_MIPS_R29,
|
||||
UNW_TDEP_EH = UNW_MIPS_R0 /* FIXME. */
|
||||
}
|
||||
mips_regnum_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNW_MIPS_ABI_O32,
|
||||
UNW_MIPS_ABI_N32,
|
||||
UNW_MIPS_ABI_N64
|
||||
}
|
||||
mips_abi_t;
|
||||
|
||||
#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for MIPS. */
|
||||
|
||||
typedef struct unw_tdep_save_loc
|
||||
{
|
||||
/* Additional target-dependent info on a save location. */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_save_loc_t;
|
||||
|
||||
/* On x86, we can directly use ucontext_t as the unwind context. FIXME for
|
||||
MIPS. */
|
||||
typedef ucontext_t unw_tdep_context_t;
|
||||
|
||||
#include "libunwind-dynamic.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* no mips-specific auxiliary proc-info */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_proc_info_t;
|
||||
|
||||
#include "libunwind-common.h"
|
||||
|
||||
/* There is no getcontext() on MIPS. Use a stub version which only saves GP
|
||||
registers. FIXME: Not ideal, may not be sufficient for all libunwind
|
||||
use cases. */
|
||||
#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext)
|
||||
extern int unw_tdep_getcontext (ucontext_t *uc);
|
||||
|
||||
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
|
||||
extern int unw_tdep_is_fpreg (int);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIBUNWIND_H */
|
|
@ -0,0 +1,213 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2006-2007 IBM
|
||||
Contributed by
|
||||
Corey Ashford <cjashfor@us.ibm.com>
|
||||
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
|
||||
|
||||
Copied from libunwind-x86_64.h, modified slightly for building
|
||||
frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
|
||||
Will be replaced when libunwind is ready on ppc64 platform.
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef LIBUNWIND_H
|
||||
#define LIBUNWIND_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define UNW_TARGET ppc32
|
||||
#define UNW_TARGET_PPC32 1
|
||||
|
||||
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
|
||||
|
||||
/*
|
||||
* This needs to be big enough to accommodate "struct cursor", while
|
||||
* leaving some slack for future expansion. Changing this value will
|
||||
* require recompiling all users of this library. Stack allocation is
|
||||
* relatively cheap and unwind-state copying is relatively rare, so we want
|
||||
* to err on making it rather too big than too small.
|
||||
*
|
||||
* To simplify this whole process, we are at least initially taking the
|
||||
* tack that UNW_PPC32_* map straight across to the .eh_frame column register
|
||||
* numbers. These register numbers come from gcc's source in
|
||||
* gcc/config/rs6000/rs6000.h
|
||||
*
|
||||
* UNW_TDEP_CURSOR_LEN is in terms of unw_word_t size. Since we have 115
|
||||
* elements in the loc array, each sized 2 * unw_word_t, plus the rest of
|
||||
* the cursor struct, this puts us at about 2 * 115 + 40 = 270. Let's
|
||||
* round that up to 280.
|
||||
*/
|
||||
|
||||
#define UNW_TDEP_CURSOR_LEN 280
|
||||
|
||||
#if __WORDSIZE==32
|
||||
typedef uint32_t unw_word_t;
|
||||
typedef int32_t unw_sword_t;
|
||||
#else
|
||||
typedef uint64_t unw_word_t;
|
||||
typedef int64_t unw_sword_t;
|
||||
#endif
|
||||
|
||||
typedef long double unw_tdep_fpreg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNW_PPC32_R0,
|
||||
UNW_PPC32_R1, /* called STACK_POINTER in gcc */
|
||||
UNW_PPC32_R2,
|
||||
UNW_PPC32_R3,
|
||||
UNW_PPC32_R4,
|
||||
UNW_PPC32_R5,
|
||||
UNW_PPC32_R6,
|
||||
UNW_PPC32_R7,
|
||||
UNW_PPC32_R8,
|
||||
UNW_PPC32_R9,
|
||||
UNW_PPC32_R10,
|
||||
UNW_PPC32_R11, /* called STATIC_CHAIN in gcc */
|
||||
UNW_PPC32_R12,
|
||||
UNW_PPC32_R13,
|
||||
UNW_PPC32_R14,
|
||||
UNW_PPC32_R15,
|
||||
UNW_PPC32_R16,
|
||||
UNW_PPC32_R17,
|
||||
UNW_PPC32_R18,
|
||||
UNW_PPC32_R19,
|
||||
UNW_PPC32_R20,
|
||||
UNW_PPC32_R21,
|
||||
UNW_PPC32_R22,
|
||||
UNW_PPC32_R23,
|
||||
UNW_PPC32_R24,
|
||||
UNW_PPC32_R25,
|
||||
UNW_PPC32_R26,
|
||||
UNW_PPC32_R27,
|
||||
UNW_PPC32_R28,
|
||||
UNW_PPC32_R29,
|
||||
UNW_PPC32_R30,
|
||||
UNW_PPC32_R31, /* called HARD_FRAME_POINTER in gcc */
|
||||
|
||||
/* Count Register */
|
||||
UNW_PPC32_CTR = 32,
|
||||
/* Fixed-Point Status and Control Register */
|
||||
UNW_PPC32_XER = 33,
|
||||
/* Condition Register */
|
||||
UNW_PPC32_CCR = 34,
|
||||
/* Machine State Register */
|
||||
//UNW_PPC32_MSR = 35,
|
||||
/* MQ or SPR0, not part of generic Power, part of MPC601 */
|
||||
//UNW_PPC32_MQ = 36,
|
||||
/* Link Register */
|
||||
UNW_PPC32_LR = 36,
|
||||
/* Floating Pointer Status and Control Register */
|
||||
UNW_PPC32_FPSCR = 37,
|
||||
|
||||
UNW_PPC32_F0 = 48,
|
||||
UNW_PPC32_F1,
|
||||
UNW_PPC32_F2,
|
||||
UNW_PPC32_F3,
|
||||
UNW_PPC32_F4,
|
||||
UNW_PPC32_F5,
|
||||
UNW_PPC32_F6,
|
||||
UNW_PPC32_F7,
|
||||
UNW_PPC32_F8,
|
||||
UNW_PPC32_F9,
|
||||
UNW_PPC32_F10,
|
||||
UNW_PPC32_F11,
|
||||
UNW_PPC32_F12,
|
||||
UNW_PPC32_F13,
|
||||
UNW_PPC32_F14,
|
||||
UNW_PPC32_F15,
|
||||
UNW_PPC32_F16,
|
||||
UNW_PPC32_F17,
|
||||
UNW_PPC32_F18,
|
||||
UNW_PPC32_F19,
|
||||
UNW_PPC32_F20,
|
||||
UNW_PPC32_F21,
|
||||
UNW_PPC32_F22,
|
||||
UNW_PPC32_F23,
|
||||
UNW_PPC32_F24,
|
||||
UNW_PPC32_F25,
|
||||
UNW_PPC32_F26,
|
||||
UNW_PPC32_F27,
|
||||
UNW_PPC32_F28,
|
||||
UNW_PPC32_F29,
|
||||
UNW_PPC32_F30,
|
||||
UNW_PPC32_F31,
|
||||
|
||||
UNW_TDEP_LAST_REG = UNW_PPC32_F31,
|
||||
|
||||
UNW_TDEP_IP = UNW_PPC32_LR,
|
||||
UNW_TDEP_SP = UNW_PPC32_R1,
|
||||
UNW_TDEP_EH = UNW_PPC32_R12
|
||||
}
|
||||
ppc32_regnum_t;
|
||||
|
||||
/*
|
||||
* According to David Edelsohn, GNU gcc uses R3, R4, R5, and maybe R6 for
|
||||
* passing parameters to exception handlers.
|
||||
*/
|
||||
|
||||
#define UNW_TDEP_NUM_EH_REGS 4
|
||||
|
||||
typedef struct unw_tdep_save_loc
|
||||
{
|
||||
/* Additional target-dependent info on a save location. */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_save_loc_t;
|
||||
|
||||
/* On ppc, we can directly use ucontext_t as the unwind context. */
|
||||
typedef ucontext_t unw_tdep_context_t;
|
||||
|
||||
/* XXX this is not ideal: an application should not be prevented from
|
||||
using the "getcontext" name just because it's using libunwind. We
|
||||
can't just use __getcontext() either, because that isn't exported
|
||||
by glibc... */
|
||||
#define unw_tdep_getcontext(uc) (getcontext (uc), 0)
|
||||
|
||||
#include "libunwind-dynamic.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* no ppc32-specific auxiliary proc-info */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_proc_info_t;
|
||||
|
||||
#include "libunwind-common.h"
|
||||
|
||||
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
|
||||
extern int unw_tdep_is_fpreg (int);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIBUNWIND_H */
|
|
@ -0,0 +1,270 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2006-2007 IBM
|
||||
Contributed by
|
||||
Corey Ashford <cjashfor@us.ibm.com>
|
||||
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
|
||||
|
||||
Copied from libunwind-x86_64.h, modified slightly for building
|
||||
frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
|
||||
Will be replaced when libunwind is ready on ppc64 platform.
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef LIBUNWIND_H
|
||||
#define LIBUNWIND_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define UNW_TARGET ppc64
|
||||
#define UNW_TARGET_PPC64 1
|
||||
|
||||
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
|
||||
|
||||
/*
|
||||
* This needs to be big enough to accommodate "struct cursor", while
|
||||
* leaving some slack for future expansion. Changing this value will
|
||||
* require recompiling all users of this library. Stack allocation is
|
||||
* relatively cheap and unwind-state copying is relatively rare, so we want
|
||||
* to err on making it rather too big than too small.
|
||||
*
|
||||
* To simplify this whole process, we are at least initially taking the
|
||||
* tack that UNW_PPC64_* map straight across to the .eh_frame column register
|
||||
* numbers. These register numbers come from gcc's source in
|
||||
* gcc/config/rs6000/rs6000.h
|
||||
*
|
||||
* UNW_TDEP_CURSOR_LEN is in terms of unw_word_t size. Since we have 115
|
||||
* elements in the loc array, each sized 2 * unw_word_t, plus the rest of
|
||||
* the cursor struct, this puts us at about 2 * 115 + 40 = 270. Let's
|
||||
* round that up to 280.
|
||||
*/
|
||||
|
||||
#define UNW_TDEP_CURSOR_LEN 280
|
||||
|
||||
#if __WORDSIZE==32
|
||||
typedef uint32_t unw_word_t;
|
||||
typedef int32_t unw_sword_t;
|
||||
#else
|
||||
typedef uint64_t unw_word_t;
|
||||
typedef int64_t unw_sword_t;
|
||||
#endif
|
||||
|
||||
typedef long double unw_tdep_fpreg_t;
|
||||
|
||||
/*
|
||||
* Vector register (in PowerPC64 used for AltiVec registers)
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t halves[2];
|
||||
} unw_tdep_vreg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNW_PPC64_R0,
|
||||
UNW_PPC64_R1, /* called STACK_POINTER in gcc */
|
||||
UNW_PPC64_R2,
|
||||
UNW_PPC64_R3,
|
||||
UNW_PPC64_R4,
|
||||
UNW_PPC64_R5,
|
||||
UNW_PPC64_R6,
|
||||
UNW_PPC64_R7,
|
||||
UNW_PPC64_R8,
|
||||
UNW_PPC64_R9,
|
||||
UNW_PPC64_R10,
|
||||
UNW_PPC64_R11, /* called STATIC_CHAIN in gcc */
|
||||
UNW_PPC64_R12,
|
||||
UNW_PPC64_R13,
|
||||
UNW_PPC64_R14,
|
||||
UNW_PPC64_R15,
|
||||
UNW_PPC64_R16,
|
||||
UNW_PPC64_R17,
|
||||
UNW_PPC64_R18,
|
||||
UNW_PPC64_R19,
|
||||
UNW_PPC64_R20,
|
||||
UNW_PPC64_R21,
|
||||
UNW_PPC64_R22,
|
||||
UNW_PPC64_R23,
|
||||
UNW_PPC64_R24,
|
||||
UNW_PPC64_R25,
|
||||
UNW_PPC64_R26,
|
||||
UNW_PPC64_R27,
|
||||
UNW_PPC64_R28,
|
||||
UNW_PPC64_R29,
|
||||
UNW_PPC64_R30,
|
||||
UNW_PPC64_R31, /* called HARD_FRAME_POINTER in gcc */
|
||||
|
||||
UNW_PPC64_F0 = 32,
|
||||
UNW_PPC64_F1,
|
||||
UNW_PPC64_F2,
|
||||
UNW_PPC64_F3,
|
||||
UNW_PPC64_F4,
|
||||
UNW_PPC64_F5,
|
||||
UNW_PPC64_F6,
|
||||
UNW_PPC64_F7,
|
||||
UNW_PPC64_F8,
|
||||
UNW_PPC64_F9,
|
||||
UNW_PPC64_F10,
|
||||
UNW_PPC64_F11,
|
||||
UNW_PPC64_F12,
|
||||
UNW_PPC64_F13,
|
||||
UNW_PPC64_F14,
|
||||
UNW_PPC64_F15,
|
||||
UNW_PPC64_F16,
|
||||
UNW_PPC64_F17,
|
||||
UNW_PPC64_F18,
|
||||
UNW_PPC64_F19,
|
||||
UNW_PPC64_F20,
|
||||
UNW_PPC64_F21,
|
||||
UNW_PPC64_F22,
|
||||
UNW_PPC64_F23,
|
||||
UNW_PPC64_F24,
|
||||
UNW_PPC64_F25,
|
||||
UNW_PPC64_F26,
|
||||
UNW_PPC64_F27,
|
||||
UNW_PPC64_F28,
|
||||
UNW_PPC64_F29,
|
||||
UNW_PPC64_F30,
|
||||
UNW_PPC64_F31,
|
||||
/* Note that there doesn't appear to be an .eh_frame register column
|
||||
for the FPSCR register. I don't know why this is. Since .eh_frame
|
||||
info is what this implementation uses for unwinding, we have no way
|
||||
to unwind this register, and so we will not expose an FPSCR register
|
||||
number in the libunwind API.
|
||||
*/
|
||||
|
||||
UNW_PPC64_LR = 65,
|
||||
UNW_PPC64_CTR = 66,
|
||||
UNW_PPC64_ARG_POINTER = 67,
|
||||
|
||||
UNW_PPC64_CR0 = 68,
|
||||
UNW_PPC64_CR1,
|
||||
UNW_PPC64_CR2,
|
||||
UNW_PPC64_CR3,
|
||||
UNW_PPC64_CR4,
|
||||
/* CR5 .. CR7 are currently unused */
|
||||
UNW_PPC64_CR5,
|
||||
UNW_PPC64_CR6,
|
||||
UNW_PPC64_CR7,
|
||||
|
||||
UNW_PPC64_XER = 76,
|
||||
|
||||
UNW_PPC64_V0 = 77,
|
||||
UNW_PPC64_V1,
|
||||
UNW_PPC64_V2,
|
||||
UNW_PPC64_V3,
|
||||
UNW_PPC64_V4,
|
||||
UNW_PPC64_V5,
|
||||
UNW_PPC64_V6,
|
||||
UNW_PPC64_V7,
|
||||
UNW_PPC64_V8,
|
||||
UNW_PPC64_V9,
|
||||
UNW_PPC64_V10,
|
||||
UNW_PPC64_V11,
|
||||
UNW_PPC64_V12,
|
||||
UNW_PPC64_V13,
|
||||
UNW_PPC64_V14,
|
||||
UNW_PPC64_V15,
|
||||
UNW_PPC64_V16,
|
||||
UNW_PPC64_V17,
|
||||
UNW_PPC64_V18,
|
||||
UNW_PPC64_V19,
|
||||
UNW_PPC64_V20,
|
||||
UNW_PPC64_V21,
|
||||
UNW_PPC64_V22,
|
||||
UNW_PPC64_V23,
|
||||
UNW_PPC64_V24,
|
||||
UNW_PPC64_V25,
|
||||
UNW_PPC64_V26,
|
||||
UNW_PPC64_V27,
|
||||
UNW_PPC64_V28,
|
||||
UNW_PPC64_V29,
|
||||
UNW_PPC64_V30,
|
||||
UNW_PPC64_V31,
|
||||
|
||||
UNW_PPC64_VRSAVE = 109,
|
||||
UNW_PPC64_VSCR = 110,
|
||||
UNW_PPC64_SPE_ACC = 111,
|
||||
UNW_PPC64_SPEFSCR = 112,
|
||||
|
||||
/* frame info (read-only) */
|
||||
UNW_PPC64_FRAME_POINTER,
|
||||
UNW_PPC64_NIP,
|
||||
|
||||
|
||||
UNW_TDEP_LAST_REG = UNW_PPC64_NIP,
|
||||
|
||||
UNW_TDEP_IP = UNW_PPC64_NIP,
|
||||
UNW_TDEP_SP = UNW_PPC64_R1,
|
||||
UNW_TDEP_EH = UNW_PPC64_R12
|
||||
}
|
||||
ppc64_regnum_t;
|
||||
|
||||
/*
|
||||
* According to David Edelsohn, GNU gcc uses R3, R4, R5, and maybe R6 for
|
||||
* passing parameters to exception handlers.
|
||||
*/
|
||||
|
||||
#define UNW_TDEP_NUM_EH_REGS 4
|
||||
|
||||
typedef struct unw_tdep_save_loc
|
||||
{
|
||||
/* Additional target-dependent info on a save location. */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_save_loc_t;
|
||||
|
||||
/* On ppc64, we can directly use ucontext_t as the unwind context. */
|
||||
typedef ucontext_t unw_tdep_context_t;
|
||||
|
||||
/* XXX this is not ideal: an application should not be prevented from
|
||||
using the "getcontext" name just because it's using libunwind. We
|
||||
can't just use __getcontext() either, because that isn't exported
|
||||
by glibc... */
|
||||
#define unw_tdep_getcontext(uc) (getcontext (uc), 0)
|
||||
|
||||
#include "libunwind-dynamic.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* no ppc64-specific auxiliary proc-info */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_proc_info_t;
|
||||
|
||||
#include "libunwind-common.h"
|
||||
|
||||
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
|
||||
extern int unw_tdep_is_fpreg (int);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIBUNWIND_H */
|
|
@ -0,0 +1,63 @@
|
|||
/* 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. */
|
||||
|
||||
#ifndef libunwind_ptrace_h
|
||||
#define libunwind_ptrace_h
|
||||
|
||||
#include <libunwind.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Helper routines which make it easy to use libunwind via ptrace().
|
||||
They're available only if UNW_REMOTE_ONLY is _not_ defined and they
|
||||
aren't really part of the libunwind API. They are implemented in a
|
||||
archive library called libunwind-ptrace.a. */
|
||||
|
||||
extern void *_UPT_create (pid_t);
|
||||
extern void _UPT_destroy (void *);
|
||||
extern int _UPT_find_proc_info (unw_addr_space_t, unw_word_t,
|
||||
unw_proc_info_t *, int, void *);
|
||||
extern void _UPT_put_unwind_info (unw_addr_space_t, unw_proc_info_t *, void *);
|
||||
extern int _UPT_get_dyn_info_list_addr (unw_addr_space_t, unw_word_t *,
|
||||
void *);
|
||||
extern int _UPT_access_mem (unw_addr_space_t, unw_word_t, unw_word_t *, int,
|
||||
void *);
|
||||
extern int _UPT_access_reg (unw_addr_space_t, unw_regnum_t, unw_word_t *,
|
||||
int, void *);
|
||||
extern int _UPT_access_fpreg (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *,
|
||||
int, void *);
|
||||
extern int _UPT_get_proc_name (unw_addr_space_t, unw_word_t, char *, size_t,
|
||||
unw_word_t *, void *);
|
||||
extern int _UPT_resume (unw_addr_space_t, unw_cursor_t *, void *);
|
||||
extern unw_accessors_t _UPT_accessors;
|
||||
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* libunwind_ptrace_h */
|
|
@ -0,0 +1,120 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2008 CodeSourcery
|
||||
Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.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. */
|
||||
|
||||
#ifndef LIBUNWIND_H
|
||||
#define LIBUNWIND_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define UNW_TARGET sh
|
||||
#define UNW_TARGET_SH 1
|
||||
|
||||
#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */
|
||||
|
||||
/* This needs to be big enough to accommodate "struct cursor", while
|
||||
leaving some slack for future expansion. Changing this value will
|
||||
require recompiling all users of this library. Stack allocation is
|
||||
relatively cheap and unwind-state copying is relatively rare, so we
|
||||
want to err on making it rather too big than too small. */
|
||||
|
||||
#define UNW_TDEP_CURSOR_LEN 4096
|
||||
|
||||
typedef uint32_t unw_word_t;
|
||||
typedef int32_t unw_sword_t;
|
||||
|
||||
typedef long double unw_tdep_fpreg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNW_SH_R0,
|
||||
UNW_SH_R1,
|
||||
UNW_SH_R2,
|
||||
UNW_SH_R3,
|
||||
UNW_SH_R4,
|
||||
UNW_SH_R5,
|
||||
UNW_SH_R6,
|
||||
UNW_SH_R7,
|
||||
UNW_SH_R8,
|
||||
UNW_SH_R9,
|
||||
UNW_SH_R10,
|
||||
UNW_SH_R11,
|
||||
UNW_SH_R12,
|
||||
UNW_SH_R13,
|
||||
UNW_SH_R14,
|
||||
UNW_SH_R15,
|
||||
|
||||
UNW_SH_PC,
|
||||
UNW_SH_PR,
|
||||
|
||||
UNW_TDEP_LAST_REG = UNW_SH_PR,
|
||||
|
||||
UNW_TDEP_IP = UNW_SH_PR,
|
||||
UNW_TDEP_SP = UNW_SH_R15,
|
||||
UNW_TDEP_EH = UNW_SH_R0
|
||||
}
|
||||
sh_regnum_t;
|
||||
|
||||
#define UNW_TDEP_NUM_EH_REGS 2
|
||||
|
||||
typedef ucontext_t unw_tdep_context_t;
|
||||
|
||||
#define unw_tdep_getcontext(uc) (getcontext (uc), 0)
|
||||
|
||||
typedef struct unw_tdep_save_loc
|
||||
{
|
||||
/* Additional target-dependent info on a save location. */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_save_loc_t;
|
||||
|
||||
#include "libunwind-dynamic.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* no sh-specific auxiliary proc-info */
|
||||
/* ANDROID support update. */
|
||||
char __reserved;
|
||||
/* End of ANDROID update. */
|
||||
}
|
||||
unw_tdep_proc_info_t;
|
||||
|
||||
#include "libunwind-common.h"
|
||||
|
||||
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
|
||||
extern int unw_tdep_is_fpreg (int);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIBUNWIND_H */
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче