1 /* libunwind - a platform-independent unwind library 2 Copyright (C) 2002-2004 Hewlett-Packard Co 3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4 5 This file is part of libunwind. 6 7 Permission is hereby granted, free of charge, to any person obtaining 8 a copy of this software and associated documentation files (the 9 "Software"), to deal in the Software without restriction, including 10 without limitation the rights to use, copy, modify, merge, publish, 11 distribute, sublicense, and/or sell copies of the Software, and to 12 permit persons to whom the Software is furnished to do so, subject to 13 the following conditions: 14 15 The above copyright notice and this permission notice shall be 16 included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25 26 #ifndef LIBUNWIND_H 27 #define LIBUNWIND_H 28 29 #if defined(__linux__) 30 # define LINUX 31 #endif 32 #if defined(__i386__) 33 # define PLAIN_X86 34 #endif 35 #if defined(__x86_64__) 36 # define UNW_X86_64 37 #endif 38 #if defined(__arm__) 39 # define UNW_ARM 40 #endif 41 42 #if defined(PLAIN_X86) 43 # define UNW_IP UNW_X86_EIP 44 #elif defined(UNW_X86_64) 45 # define UNW_IP UNW_X86_64_RIP 46 #elif defined(UNW_ARM) 47 # define UNW_IP UNW_ARM_RIP 48 #endif 49 50 #ifdef UNW_ARM 51 # define CONFIG_DEBUG_FRAME 52 #endif 53 54 #if defined(__cplusplus) || defined(c_plusplus) 55 extern "C" { 56 #endif 57 58 #include <inttypes.h> 59 #ifndef UNW_ARM 60 # ifdef __APPLE__ 61 # define _XOPEN_SOURCE 62 # endif 63 # define __USE_GNU 64 # include <ucontext.h> 65 # undef __USE_GNU 66 #endif 67 68 /* XXXXXXXXXXXXXXXXXXXX x86 Target XXXXXXXXXXXXXXXXXXXX */ 69 70 #ifdef PLAIN_X86 71 72 #define UNW_TARGET x86 73 #define UNW_TARGET_X86 1 74 75 /* This needs to be big enough to accommodate "struct cursor", while 76 leaving some slack for future expansion. Changing this value will 77 require recompiling all users of this library. Stack allocation is 78 relatively cheap and unwind-state copying is relatively rare, so we 79 want to err on making it rather too big than too small. */ 80 #define UNW_TDEP_CURSOR_LEN 127 81 82 typedef unsigned long unw_word_t; 83 typedef long unw_sword_t; 84 85 typedef long double unw_tdep_fpreg_t; 86 87 typedef enum 88 { 89 /* Note: general registers are expected to start with index 0. 90 This convention facilitates architecture-independent 91 implementation of the C++ exception handling ABI. See 92 _Unwind_SetGR() and _Unwind_GetGR() for details. 93 94 The described register usage convention is based on "System V 95 Application Binary Interface, Intel386 Architecture Processor 96 Supplement, Fourth Edition" at 97 98 http://www.linuxbase.org/spec/refspecs/elf/abi386-4.pdf 99 100 It would have been nice to use the same register numbering as 101 DWARF, but that doesn't work because the libunwind requires 102 that the exception argument registers be consecutive, which the 103 wouldn't be with the DWARF numbering. */ 104 UNW_X86_EAX, /* scratch (exception argument 1) */ 105 UNW_X86_EDX, /* scratch (exception argument 2) */ 106 UNW_X86_ECX, /* scratch */ 107 UNW_X86_EBX, /* preserved */ 108 UNW_X86_ESI, /* preserved */ 109 UNW_X86_EDI, /* preserved */ 110 UNW_X86_EBP, /* (optional) frame-register */ 111 UNW_X86_ESP, /* (optional) frame-register */ 112 UNW_X86_EIP, /* frame-register */ 113 UNW_X86_EFLAGS, /* scratch (except for "direction", which is fixed */ 114 UNW_X86_TRAPNO, /* scratch */ 115 116 /* MMX/stacked-fp registers */ 117 UNW_X86_ST0, /* fp return value */ 118 UNW_X86_ST1, /* scratch */ 119 UNW_X86_ST2, /* scratch */ 120 UNW_X86_ST3, /* scratch */ 121 UNW_X86_ST4, /* scratch */ 122 UNW_X86_ST5, /* scratch */ 123 UNW_X86_ST6, /* scratch */ 124 UNW_X86_ST7, /* scratch */ 125 126 UNW_X86_FCW, /* scratch */ 127 UNW_X86_FSW, /* scratch */ 128 UNW_X86_FTW, /* scratch */ 129 UNW_X86_FOP, /* scratch */ 130 UNW_X86_FCS, /* scratch */ 131 UNW_X86_FIP, /* scratch */ 132 UNW_X86_FEA, /* scratch */ 133 UNW_X86_FDS, /* scratch */ 134 135 /* SSE registers */ 136 UNW_X86_XMM0_lo, /* scratch */ 137 UNW_X86_XMM0_hi, /* scratch */ 138 UNW_X86_XMM1_lo, /* scratch */ 139 UNW_X86_XMM1_hi, /* scratch */ 140 UNW_X86_XMM2_lo, /* scratch */ 141 UNW_X86_XMM2_hi, /* scratch */ 142 UNW_X86_XMM3_lo, /* scratch */ 143 UNW_X86_XMM3_hi, /* scratch */ 144 UNW_X86_XMM4_lo, /* scratch */ 145 UNW_X86_XMM4_hi, /* scratch */ 146 UNW_X86_XMM5_lo, /* scratch */ 147 UNW_X86_XMM5_hi, /* scratch */ 148 UNW_X86_XMM6_lo, /* scratch */ 149 UNW_X86_XMM6_hi, /* scratch */ 150 UNW_X86_XMM7_lo, /* scratch */ 151 UNW_X86_XMM7_hi, /* scratch */ 152 153 UNW_X86_MXCSR, /* scratch */ 154 155 /* segment registers */ 156 UNW_X86_GS, /* special */ 157 UNW_X86_FS, /* special */ 158 UNW_X86_ES, /* special */ 159 UNW_X86_DS, /* special */ 160 UNW_X86_SS, /* special */ 161 UNW_X86_CS, /* special */ 162 UNW_X86_TSS, /* special */ 163 UNW_X86_LDT, /* special */ 164 165 /* frame info (read-only) */ 166 UNW_X86_CFA, 167 168 UNW_TDEP_LAST_REG = UNW_X86_LDT, 169 170 UNW_TDEP_IP = UNW_X86_EIP, 171 UNW_TDEP_SP = UNW_X86_CFA, 172 UNW_TDEP_EH = UNW_X86_EAX 173 } 174 x86_regnum_t; 175 176 /* On x86, we can directly use ucontext_t as the unwind context. */ 177 typedef ucontext_t unw_tdep_context_t; 178 #define unw_tdep_getcontext(uc) (getcontext (uc), 0) 179 180 #endif 181 182 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ 183 184 /* XXXXXXXXXXXXXXXXXXXX x86_64 Target XXXXXXXXXXXXXXXXXXXX */ 185 186 #ifdef UNW_X86_64 187 188 #define UNW_TARGET x86_64 189 #define UNW_TARGET_X86_64 1 190 191 #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ 192 193 /* This needs to be big enough to accommodate "struct cursor", while 194 leaving some slack for future expansion. Changing this value will 195 require recompiling all users of this library. Stack allocation is 196 relatively cheap and unwind-state copying is relatively rare, so we 197 want to err on making it rather too big than too small. */ 198 #define UNW_TDEP_CURSOR_LEN 127 199 200 typedef uint64_t unw_word_t; 201 typedef int64_t unw_sword_t; 202 203 typedef long double unw_tdep_fpreg_t; 204 205 typedef enum 206 { 207 UNW_X86_64_RAX, 208 UNW_X86_64_RDX, 209 UNW_X86_64_RCX, 210 UNW_X86_64_RBX, 211 UNW_X86_64_RSI, 212 UNW_X86_64_RDI, 213 UNW_X86_64_RBP, 214 UNW_X86_64_RSP, 215 UNW_X86_64_R8, 216 UNW_X86_64_R9, 217 UNW_X86_64_R10, 218 UNW_X86_64_R11, 219 UNW_X86_64_R12, 220 UNW_X86_64_R13, 221 UNW_X86_64_R14, 222 UNW_X86_64_R15, 223 UNW_X86_64_RIP, 224 225 /* XXX Add other regs here */ 226 227 /* frame info (read-only) */ 228 UNW_X86_64_CFA, 229 230 UNW_TDEP_LAST_REG = UNW_X86_64_RIP, 231 232 UNW_TDEP_IP = UNW_X86_64_RIP, 233 UNW_TDEP_SP = UNW_X86_64_RSP, 234 UNW_TDEP_BP = UNW_X86_64_RBP, 235 UNW_TDEP_EH = UNW_X86_64_RAX 236 } 237 x86_64_regnum_t; 238 239 /* On x86, we can directly use ucontext_t as the unwind context. */ 240 typedef ucontext_t unw_tdep_context_t; 241 #define unw_tdep_getcontext(uc) (getcontext (uc), 0) 242 243 #endif 244 245 /* XXXXXXXXXXXXXXXXXXXX ARM Target XXXXXXXXXXXXXXXXXXXX */ 246 247 #ifdef UNW_ARM 248 249 #define UNW_TARGET ARM 250 #define UNW_TARGET_ARM 1 251 252 #define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ 253 254 /* This needs to be big enough to accommodate "struct cursor", while 255 leaving some slack for future expansion. Changing this value will 256 require recompiling all users of this library. Stack allocation is 257 relatively cheap and unwind-state copying is relatively rare, so we 258 want to err on making it rather too big than too small. */ 259 #define UNW_TDEP_CURSOR_LEN 127 260 261 typedef uint32_t unw_word_t; 262 typedef int32_t unw_sword_t; 263 264 typedef double unw_tdep_fpreg_t; 265 266 typedef enum 267 { 268 UNW_ARM_R0, 269 UNW_ARM_R1, 270 UNW_ARM_R2, 271 UNW_ARM_R3, 272 UNW_ARM_R4, 273 UNW_ARM_R5, 274 UNW_ARM_R6, 275 UNW_ARM_R7, 276 UNW_ARM_R8, 277 UNW_ARM_R9, 278 UNW_ARM_R10, 279 UNW_ARM_R11, 280 UNW_ARM_R12, 281 UNW_ARM_R13, 282 UNW_ARM_RSP = UNW_ARM_R13, 283 UNW_ARM_R14, 284 UNW_ARM_R15, 285 UNW_ARM_RIP = UNW_ARM_R15, 286 287 UNW_TDEP_LAST_REG = UNW_ARM_R15, 288 289 UNW_TDEP_IP = UNW_ARM_RIP, 290 UNW_TDEP_SP = UNW_ARM_RSP, 291 UNW_TDEP_EH = UNW_ARM_R0 292 293 } 294 arm_regnum_t; 295 296 typedef struct { 297 unsigned long regs[16]; 298 } unw_tdep_context_t; 299 300 /* There is no getcontext() on ARM. Use a stub version which only saves GP 301 registers. FIXME: Not ideal, may not be sufficient for all libunwind 302 use cases. Stores pc+8, which is only approximately correct, really. */ 303 #ifndef __thumb__ 304 #define unw_tdep_getcontext(uc) (({ \ 305 unw_tdep_context_t *unw_ctx = (uc); \ 306 register unsigned long *unw_base asm ("r0") = (unsigned long *)unw_ctx; \ 307 __asm__ __volatile__ ( \ 308 "stmia %[base], {r0-r15}" \ 309 : : [base] "r" (unw_base) : "memory"); \ 310 }), 0) 311 #else /* __thumb__ */ 312 #define unw_tdep_getcontext(uc) (({ \ 313 unw_tdep_context_t *unw_ctx = (uc); \ 314 register unsigned long *unw_base asm ("r0") = (unsigned long *)unw_ctx; \ 315 __asm__ __volatile__ ( \ 316 ".align 2\nbx pc\nnop\n.code 32\n" \ 317 "stmia %[base], {r0-r15}\n" \ 318 "orr %[base], pc, #1\nbx %[base]" \ 319 : [base] "+r" (unw_base) : : "memory", "cc"); \ 320 }), 0) 321 #endif 322 323 #ifndef PT_GNU_EH_FRAME 324 # define PT_GNU_EH_FRAME -1 325 #endif 326 327 #endif 328 329 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ 330 331 #define UNW_TDEP_NUM_EH_REGS 2 /* eax and edx are exception args */ 332 333 typedef struct unw_tdep_save_loc 334 { 335 /* Additional target-dependent info on a save location. */ 336 } 337 unw_tdep_save_loc_t; 338 339 340 typedef struct unw_dyn_remote_table_info 341 { 342 unw_word_t name_ptr; /* addr. of table name (e.g., library name) */ 343 unw_word_t segbase; /* segment base */ 344 unw_word_t table_len; /* must be a multiple of sizeof(unw_word_t)! */ 345 unw_word_t table_data; 346 } 347 unw_dyn_remote_table_info_t; 348 349 typedef struct unw_dyn_info 350 { 351 /* doubly-linked list of dyn-info structures: */ 352 struct unw_dyn_info *next; 353 struct unw_dyn_info *prev; 354 unw_word_t start_ip; /* first IP covered by this entry */ 355 unw_word_t end_ip; /* first IP NOT covered by this entry */ 356 unw_word_t gp; /* global-pointer in effect for this entry */ 357 int32_t format; /* real type: unw_dyn_info_format_t */ 358 int32_t pad; 359 union 360 { 361 unw_dyn_remote_table_info_t rti; 362 } 363 u; 364 } 365 unw_dyn_info_t; 366 367 #define UNW_INFO_FORMAT_TABLE 1 368 #define UNW_INFO_FORMAT_REMOTE_TABLE 2 369 370 typedef struct 371 { 372 /* no x86-specific auxiliary proc-info */ 373 } 374 unw_tdep_proc_info_t; 375 376 #define UNW_VERSION_MAJOR 0 377 #define UNW_VERSION_MINOR 99 378 #define UNW_VERSION_EXTRA 0 379 380 #define UNW_VERSION_CODE(maj,min) (((maj) << 16) | (min)) 381 #define UNW_VERSION UNW_VERSION_CODE(UNW_VERSION_MAJOR, UNW_VERSION_MINOR) 382 383 #define UNW_PASTE2(x,y) x##y 384 #define UNW_PASTE(x,y) UNW_PASTE2(x,y) 385 #define UNW_OBJ(fn) UNW_PASTE(UNW_PREFIX, fn) 386 #define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn) 387 388 #define UW_NO_SYNC 389 390 #include <sys/types.h> 391 392 # define UNW_PREFIX UNW_PASTE(UNW_PASTE(_UL,UNW_TARGET),_) 393 394 /* Error codes. The unwind routines return the *negated* values of 395 these error codes on error and a non-negative value on success. */ 396 typedef enum 397 { 398 UNW_ESUCCESS = 0, /* no error */ 399 UNW_EUNSPEC, /* unspecified (general) error */ 400 UNW_ENOMEM, /* out of memory */ 401 UNW_EBADREG, /* bad register number */ 402 UNW_EREADONLYREG, /* attempt to write read-only register */ 403 UNW_ESTOPUNWIND, /* stop unwinding */ 404 UNW_EINVALIDIP, /* invalid IP */ 405 UNW_EBADFRAME, /* bad frame */ 406 UNW_EINVAL, /* unsupported operation or bad value */ 407 UNW_EBADVERSION, /* unwind info has unsupported version */ 408 UNW_ENOINFO /* no unwind info found */ 409 } 410 unw_error_t; 411 412 /* The following enum defines the indices for a couple of 413 (pseudo-)registers which have the same meaning across all 414 platforms. (RO) means read-only. (RW) means read-write. General 415 registers (aka "integer registers") are expected to start with 416 index 0. The number of such registers is architecture-dependent. 417 The remaining indices can be used as an architecture sees fit. The 418 last valid register index is given by UNW_REG_LAST. */ 419 typedef enum 420 { 421 UNW_REG_IP = UNW_TDEP_IP, /* (rw) instruction pointer (pc) */ 422 UNW_REG_SP = UNW_TDEP_SP, /* (ro) stack pointer */ 423 UNW_REG_EH = UNW_TDEP_EH, /* (rw) exception-handling reg base */ 424 UNW_REG_LAST = UNW_TDEP_LAST_REG 425 } 426 unw_frame_regnum_t; 427 428 /* Number of exception-handler argument registers: */ 429 #define UNW_NUM_EH_REGS UNW_TDEP_NUM_EH_REGS 430 431 typedef enum 432 { 433 UNW_CACHE_NONE, /* no caching */ 434 UNW_CACHE_GLOBAL, /* shared global cache */ 435 UNW_CACHE_PER_THREAD /* per-thread caching */ 436 } 437 unw_caching_policy_t; 438 439 typedef int unw_regnum_t; 440 441 /* The unwind cursor starts at the youngest (most deeply nested) frame 442 and is used to track the frame state as the unwinder steps from 443 frame to frame. It is safe to make (shallow) copies of variables 444 of this type. */ 445 typedef struct unw_cursor 446 { 447 unw_word_t opaque[UNW_TDEP_CURSOR_LEN]; 448 } 449 unw_cursor_t; 450 451 /* This type encapsulates the entire (preserved) machine-state. */ 452 typedef unw_tdep_context_t unw_context_t; 453 454 /* unw_getcontext() fills the unw_context_t pointed to by UC with the 455 machine state as it exists at the call-site. For implementation 456 reasons, this needs to be a target-dependent macro. It's easiest 457 to think of unw_getcontext() as being identical to getcontext(). */ 458 #define unw_getcontext(uc) unw_tdep_getcontext(uc) 459 460 /* Return 1 if register number R is a floating-point register, zero 461 otherwise. 462 This routine is signal-safe. */ 463 #define unw_is_fpreg(r) unw_tdep_is_fpreg(r) 464 465 typedef unw_tdep_fpreg_t unw_fpreg_t; 466 467 typedef struct unw_addr_space *unw_addr_space_t; 468 469 /* Each target may define its own set of flags, but bits 0-15 are 470 reserved for general libunwind-use. */ 471 #define UNW_PI_FLAG_FIRST_TDEP_BIT 16 472 473 typedef struct unw_proc_info 474 { 475 unw_word_t start_ip; /* first IP covered by this procedure */ 476 unw_word_t end_ip; /* first IP NOT covered by this procedure */ 477 unw_word_t lsda; /* address of lang.-spec. data area (if any) */ 478 unw_word_t handler; /* optional personality routine */ 479 unw_word_t gp; /* global-pointer value for this procedure */ 480 unw_word_t flags; /* misc. flags */ 481 482 int format; /* unwind-info format (arch-specific) */ 483 int unwind_info_size; /* size of the information (if applicable) */ 484 void *unwind_info; /* unwind-info (arch-specific) */ 485 unw_tdep_proc_info_t extra; /* target-dependent auxiliary proc-info */ 486 } 487 unw_proc_info_t; 488 489 /* These are backend callback routines that provide access to the 490 state of a "remote" process. This can be used, for example, to 491 unwind another process through the ptrace() interface. */ 492 typedef struct unw_accessors 493 { 494 /* REMOVED */ 495 } 496 unw_accessors_t; 497 498 typedef enum unw_save_loc_type 499 { 500 UNW_SLT_NONE, /* register is not saved ("not an l-value") */ 501 UNW_SLT_MEMORY, /* register has been saved in memory */ 502 UNW_SLT_REG /* register has been saved in (another) register */ 503 } 504 unw_save_loc_type_t; 505 506 typedef struct unw_save_loc 507 { 508 unw_save_loc_type_t type; 509 union 510 { 511 unw_word_t addr; /* valid if type==UNW_SLT_MEMORY */ 512 unw_regnum_t regnum; /* valid if type==UNW_SLT_REG */ 513 } 514 u; 515 unw_tdep_save_loc_t extra; /* target-dependent additional information */ 516 } 517 unw_save_loc_t; 518 519 /* These routines work both for local and remote unwinding. */ 520 521 #define unw_local_addr_space UNW_OBJ(local_addr_space) 522 #define unw_create_addr_space UNW_OBJ(create_addr_space) 523 #define unw_destroy_addr_space UNW_OBJ(destroy_addr_space) 524 #define unw_get_accessors UNW_ARCH_OBJ(get_accessors) 525 #define unw_init_local UNW_OBJ(init_local) 526 #define unw_destroy_local UNW_OBJ(destroy_local) 527 #define unw_init_remote UNW_OBJ(init_remote) 528 #define unw_step UNW_OBJ(step) 529 #define unw_resume UNW_OBJ(resume) 530 #define unw_get_proc_info UNW_OBJ(get_proc_info) 531 #define unw_get_proc_info_by_ip UNW_OBJ(get_proc_info_by_ip) 532 #define unw_get_reg UNW_OBJ(get_reg) 533 #define unw_set_reg UNW_OBJ(set_reg) 534 #define unw_get_fpreg UNW_OBJ(get_fpreg) 535 #define unw_set_fpreg UNW_OBJ(set_fpreg) 536 #define unw_get_save_loc UNW_OBJ(get_save_loc) 537 #define unw_is_signal_frame UNW_OBJ(is_signal_frame) 538 #define unw_get_proc_name UNW_OBJ(get_proc_name) 539 #define unw_set_caching_policy UNW_OBJ(set_caching_policy) 540 #define unw_regname UNW_ARCH_OBJ(regname) 541 #define unw_flush_cache UNW_ARCH_OBJ(flush_cache) 542 #define unw_strerror UNW_ARCH_OBJ(strerror) 543 544 extern unw_addr_space_t unw_create_addr_space (unw_accessors_t *, int); 545 extern void unw_destroy_addr_space (unw_addr_space_t); 546 extern unw_accessors_t *unw_get_accessors (unw_addr_space_t); 547 extern void unw_flush_cache (unw_addr_space_t, unw_word_t, unw_word_t); 548 extern int unw_set_caching_policy (unw_addr_space_t, unw_caching_policy_t); 549 extern const char *unw_regname (unw_regnum_t); 550 551 extern int unw_init_local (unw_cursor_t *, unw_context_t *); 552 extern void unw_destroy_local(unw_cursor_t *); 553 extern int unw_init_remote (unw_cursor_t *, unw_addr_space_t, void *); 554 extern int unw_step (unw_cursor_t *); 555 extern int unw_resume (unw_cursor_t *); 556 extern int unw_get_proc_info (unw_cursor_t *, unw_proc_info_t *); 557 extern int unw_get_proc_info_by_ip (unw_addr_space_t, unw_word_t, 558 unw_proc_info_t *, void *); 559 extern int unw_get_reg (unw_cursor_t *, int, unw_word_t *); 560 extern int unw_set_reg (unw_cursor_t *, int, unw_word_t); 561 extern int unw_get_fpreg (unw_cursor_t *, int, unw_fpreg_t *); 562 extern int unw_set_fpreg (unw_cursor_t *, int, unw_fpreg_t); 563 extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *); 564 extern int unw_is_signal_frame (unw_cursor_t *); 565 extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *); 566 extern unw_word_t unw_get_ip(unw_cursor_t *); 567 extern unw_word_t unw_get_frame_pointer(unw_cursor_t *); 568 extern const char *unw_strerror (int); 569 570 #ifdef UNW_X86_64 571 void unw_manual_step(unw_cursor_t *_c, 572 void *ip_addr, 573 void *bp_addr, 574 void *sp_addr, 575 void *bx_addr, 576 void *r12_addr, 577 void *r13_addr); 578 #endif 579 #ifdef UNW_ARM 580 void unw_manual_step(unw_cursor_t *_c, 581 void *ip_addr, 582 void *sp_addr, 583 void *r0_addr, void *r1_addr, void *r2_addr, void *r3_addr, 584 void *r4_addr, void *r5_addr, void *r6_addr, void *r7_addr, 585 void *fp_addr); 586 #endif 587 588 extern unw_addr_space_t unw_local_addr_space; 589 590 extern int unw_reset_bad_ptr_flag(unw_cursor_t *c); 591 extern void unw_set_safe_pointer_range(unw_cursor_t *c, unw_word_t s, unw_word_t e); 592 593 #define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) 594 extern int unw_tdep_is_fpreg (int); 595 596 #if defined(__cplusplus) || defined(c_plusplus) 597 } 598 #endif 599 600 #endif /* LIBUNWIND_H */ 601