From 64db0b20bd181c36489dc76a86a88ea5df0cc31b Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 7 May 2020 17:02:59 -0400 Subject: [PATCH 01/12] Delete files added by 1.3-rc1 --- src/coreclr/src/pal/src/libunwind/.gitignore | 79 - src/coreclr/src/pal/src/libunwind/.travis.yml | 18 - src/coreclr/src/pal/src/libunwind/AUTHORS | 1 - src/coreclr/src/pal/src/libunwind/COPYING | 20 - src/coreclr/src/pal/src/libunwind/ChangeLog | 55 - src/coreclr/src/pal/src/libunwind/LICENSE | 18 - src/coreclr/src/pal/src/libunwind/Makefile.am | 106 - src/coreclr/src/pal/src/libunwind/NEWS | 247 - src/coreclr/src/pal/src/libunwind/README | 207 - src/coreclr/src/pal/src/libunwind/TODO | 97 - .../src/pal/src/libunwind/acinclude.m4 | 32 - src/coreclr/src/pal/src/libunwind/autogen.sh | 9 - .../src/pal/src/libunwind/aux_/config.guess | 1321 ----- .../src/pal/src/libunwind/aux_/config.sub | 1443 ----- .../src/pal/src/libunwind/aux_/ltmain.sh | 5107 ----------------- .../src/pal/src/libunwind/configure.ac | 445 -- .../src/pal/src/libunwind/doc/Makefile.am | 80 - src/coreclr/src/pal/src/libunwind/doc/NOTES | 127 - .../pal/src/libunwind/doc/_U_dyn_cancel.man | 66 - .../pal/src/libunwind/doc/_U_dyn_cancel.tex | 46 - .../pal/src/libunwind/doc/_U_dyn_register.man | 68 - .../pal/src/libunwind/doc/_U_dyn_register.tex | 47 - .../src/pal/src/libunwind/doc/common.tex.in | 11 - .../src/libunwind/doc/libunwind-dynamic.man | 538 -- .../src/libunwind/doc/libunwind-dynamic.tex | 401 -- .../pal/src/libunwind/doc/libunwind-ia64.man | 314 - .../pal/src/libunwind/doc/libunwind-ia64.tex | 216 - .../src/libunwind/doc/libunwind-ptrace.man | 220 - .../src/libunwind/doc/libunwind-ptrace.tex | 134 - .../src/libunwind/doc/libunwind-setjmp.man | 132 - .../src/libunwind/doc/libunwind-setjmp.tex | 87 - .../src/pal/src/libunwind/doc/libunwind.man | 508 -- .../src/pal/src/libunwind/doc/libunwind.tex | 359 -- .../src/pal/src/libunwind/doc/libunwind.trans | 34 - .../src/libunwind/doc/unw_apply_reg_state.man | 90 - .../src/libunwind/doc/unw_apply_reg_state.tex | 63 - .../pal/src/libunwind/doc/unw_backtrace.man | 86 - .../pal/src/libunwind/doc/unw_backtrace.tex | 54 - .../libunwind/doc/unw_create_addr_space.man | 457 -- .../libunwind/doc/unw_create_addr_space.tex | 265 - .../libunwind/doc/unw_destroy_addr_space.man | 57 - .../libunwind/doc/unw_destroy_addr_space.tex | 40 - .../pal/src/libunwind/doc/unw_flush_cache.man | 93 - .../pal/src/libunwind/doc/unw_flush_cache.tex | 58 - .../src/libunwind/doc/unw_get_accessors.man | 79 - .../src/libunwind/doc/unw_get_accessors.tex | 55 - .../pal/src/libunwind/doc/unw_get_fpreg.man | 111 - .../pal/src/libunwind/doc/unw_get_fpreg.tex | 77 - .../src/libunwind/doc/unw_get_proc_info.man | 203 - .../src/libunwind/doc/unw_get_proc_info.tex | 123 - .../libunwind/doc/unw_get_proc_info_by_ip.man | 134 - .../libunwind/doc/unw_get_proc_info_by_ip.tex | 91 - .../src/libunwind/doc/unw_get_proc_name.man | 123 - .../src/libunwind/doc/unw_get_proc_name.tex | 82 - .../src/pal/src/libunwind/doc/unw_get_reg.man | 112 - .../src/pal/src/libunwind/doc/unw_get_reg.tex | 77 - .../pal/src/libunwind/doc/unw_getcontext.man | 93 - .../pal/src/libunwind/doc/unw_getcontext.tex | 63 - .../pal/src/libunwind/doc/unw_init_local.man | 124 - .../pal/src/libunwind/doc/unw_init_local.tex | 80 - .../pal/src/libunwind/doc/unw_init_local2.man | 1 - .../pal/src/libunwind/doc/unw_init_remote.man | 123 - .../pal/src/libunwind/doc/unw_init_remote.tex | 79 - .../pal/src/libunwind/doc/unw_is_fpreg.man | 73 - .../pal/src/libunwind/doc/unw_is_fpreg.tex | 52 - .../src/libunwind/doc/unw_is_signal_frame.man | 88 - .../src/libunwind/doc/unw_is_signal_frame.tex | 67 - .../libunwind/doc/unw_reg_states_iterate.man | 137 - .../libunwind/doc/unw_reg_states_iterate.tex | 83 - .../src/pal/src/libunwind/doc/unw_regname.man | 68 - .../src/pal/src/libunwind/doc/unw_regname.tex | 47 - .../src/pal/src/libunwind/doc/unw_resume.man | 146 - .../src/pal/src/libunwind/doc/unw_resume.tex | 99 - .../src/libunwind/doc/unw_set_cache_size.man | 88 - .../src/libunwind/doc/unw_set_cache_size.tex | 59 - .../libunwind/doc/unw_set_caching_policy.man | 119 - .../libunwind/doc/unw_set_caching_policy.tex | 81 - .../pal/src/libunwind/doc/unw_set_fpreg.man | 117 - .../pal/src/libunwind/doc/unw_set_fpreg.tex | 79 - .../src/pal/src/libunwind/doc/unw_set_reg.man | 117 - .../src/pal/src/libunwind/doc/unw_set_reg.tex | 79 - .../src/pal/src/libunwind/doc/unw_step.man | 106 - .../src/pal/src/libunwind/doc/unw_step.tex | 68 - .../pal/src/libunwind/doc/unw_strerror.man | 63 - .../pal/src/libunwind/doc/unw_strerror.tex | 42 - .../src/pal/src/libunwind/include/compiler.h | 72 - .../src/pal/src/libunwind/include/dwarf-eh.h | 128 - .../src/pal/src/libunwind/include/dwarf.h | 450 -- .../src/pal/src/libunwind/include/dwarf_i.h | 490 -- .../src/libunwind/include/libunwind-aarch64.h | 210 - .../pal/src/libunwind/include/libunwind-arm.h | 303 - .../libunwind/include/libunwind-common.h.in | 281 - .../libunwind/include/libunwind-coredump.h | 73 - .../src/libunwind/include/libunwind-dynamic.h | 214 - .../src/libunwind/include/libunwind-hppa.h | 125 - .../src/libunwind/include/libunwind-ia64.h | 194 - .../src/libunwind/include/libunwind-mips.h | 160 - .../src/libunwind/include/libunwind-ppc32.h | 207 - .../src/libunwind/include/libunwind-ppc64.h | 271 - .../src/libunwind/include/libunwind-ptrace.h | 63 - .../pal/src/libunwind/include/libunwind-sh.h | 114 - .../src/libunwind/include/libunwind-tilegx.h | 161 - .../pal/src/libunwind/include/libunwind-x86.h | 187 - .../src/libunwind/include/libunwind-x86_64.h | 141 - .../pal/src/libunwind/include/libunwind.h.in | 36 - .../pal/src/libunwind/include/libunwind_i.h | 366 -- .../src/pal/src/libunwind/include/mempool.h | 89 - .../src/pal/src/libunwind/include/remote.h | 129 - .../include/tdep-aarch64/dwarf-config.h | 52 - .../libunwind/include/tdep-aarch64/jmpbuf.h | 33 - .../include/tdep-aarch64/libunwind_i.h | 320 -- .../libunwind/include/tdep-arm/dwarf-config.h | 51 - .../libunwind/include/tdep-arm/ex_tables.h | 55 - .../src/libunwind/include/tdep-arm/jmpbuf.h | 32 - .../libunwind/include/tdep-arm/libunwind_i.h | 326 -- .../include/tdep-hppa/dwarf-config.h | 54 - .../src/libunwind/include/tdep-hppa/jmpbuf.h | 33 - .../libunwind/include/tdep-hppa/libunwind_i.h | 279 - .../src/libunwind/include/tdep-ia64/jmpbuf.h | 32 - .../libunwind/include/tdep-ia64/libunwind_i.h | 281 - .../pal/src/libunwind/include/tdep-ia64/rse.h | 67 - .../src/libunwind/include/tdep-ia64/script.h | 85 - .../include/tdep-mips/dwarf-config.h | 54 - .../src/libunwind/include/tdep-mips/jmpbuf.h | 32 - .../libunwind/include/tdep-mips/libunwind_i.h | 331 -- .../include/tdep-ppc32/dwarf-config.h | 56 - .../src/libunwind/include/tdep-ppc32/jmpbuf.h | 37 - .../include/tdep-ppc32/libunwind_i.h | 314 - .../include/tdep-ppc64/dwarf-config.h | 56 - .../src/libunwind/include/tdep-ppc64/jmpbuf.h | 37 - .../include/tdep-ppc64/libunwind_i.h | 369 -- .../libunwind/include/tdep-sh/dwarf-config.h | 49 - .../src/libunwind/include/tdep-sh/jmpbuf.h | 48 - .../libunwind/include/tdep-sh/libunwind_i.h | 280 - .../include/tdep-tilegx/dwarf-config.h | 50 - .../libunwind/include/tdep-tilegx/jmpbuf.h | 33 - .../include/tdep-tilegx/libunwind_i.h | 263 - .../libunwind/include/tdep-x86/dwarf-config.h | 52 - .../src/libunwind/include/tdep-x86/jmpbuf.h | 42 - .../libunwind/include/tdep-x86/libunwind_i.h | 293 - .../include/tdep-x86_64/dwarf-config.h | 57 - .../libunwind/include/tdep-x86_64/jmpbuf.h | 43 - .../include/tdep-x86_64/libunwind_i.h | 264 - .../src/libunwind/include/tdep/dwarf-config.h | 28 - .../pal/src/libunwind/include/tdep/jmpbuf.h | 30 - .../libunwind/include/tdep/libunwind_i.h.in | 37 - .../src/pal/src/libunwind/include/unwind.h | 154 - .../pal/src/libunwind/include/x86/jmpbuf.h | 31 - .../pal/src/libunwind/scripts/kernel-diff.sh | 10 - .../src/libunwind/scripts/kernel-files.txt | 19 - .../pal/src/libunwind/scripts/make-L-files | 30 - .../src/pal/src/libunwind/src/Makefile.am | 750 --- .../libunwind/src/aarch64/Gapply_reg_state.c | 37 - .../src/aarch64/Gcreate_addr_space.c | 60 - .../libunwind/src/aarch64/Gget_proc_info.c | 39 - .../src/libunwind/src/aarch64/Gget_save_loc.c | 100 - .../pal/src/libunwind/src/aarch64/Gglobal.c | 57 - .../src/pal/src/libunwind/src/aarch64/Ginit.c | 190 - .../src/libunwind/src/aarch64/Ginit_local.c | 78 - .../src/libunwind/src/aarch64/Ginit_remote.c | 45 - .../libunwind/src/aarch64/Gis_signal_frame.c | 64 - .../src/aarch64/Greg_states_iterate.c | 37 - .../src/pal/src/libunwind/src/aarch64/Gregs.c | 118 - .../pal/src/libunwind/src/aarch64/Gresume.c | 198 - .../src/libunwind/src/aarch64/Gstash_frame.c | 89 - .../src/pal/src/libunwind/src/aarch64/Gstep.c | 189 - .../pal/src/libunwind/src/aarch64/Gtrace.c | 548 -- .../libunwind/src/aarch64/Lapply_reg_state.c | 5 - .../src/aarch64/Lcreate_addr_space.c | 5 - .../libunwind/src/aarch64/Lget_proc_info.c | 5 - .../src/libunwind/src/aarch64/Lget_save_loc.c | 5 - .../pal/src/libunwind/src/aarch64/Lglobal.c | 5 - .../src/pal/src/libunwind/src/aarch64/Linit.c | 5 - .../src/libunwind/src/aarch64/Linit_local.c | 5 - .../src/libunwind/src/aarch64/Linit_remote.c | 5 - .../libunwind/src/aarch64/Lis_signal_frame.c | 5 - .../src/aarch64/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/aarch64/Lregs.c | 5 - .../pal/src/libunwind/src/aarch64/Lresume.c | 5 - .../src/libunwind/src/aarch64/Lstash_frame.c | 5 - .../src/pal/src/libunwind/src/aarch64/Lstep.c | 5 - .../pal/src/libunwind/src/aarch64/Ltrace.c | 5 - .../src/libunwind/src/aarch64/gen-offsets.c | 68 - .../src/libunwind/src/aarch64/getcontext.S | 52 - .../src/pal/src/libunwind/src/aarch64/init.h | 126 - .../pal/src/libunwind/src/aarch64/is_fpreg.c | 32 - .../pal/src/libunwind/src/aarch64/offsets.h | 49 - .../pal/src/libunwind/src/aarch64/regname.c | 106 - .../src/libunwind/src/aarch64/siglongjmp.S | 12 - .../pal/src/libunwind/src/aarch64/unwind_i.h | 64 - .../src/libunwind/src/arm/Gapply_reg_state.c | 37 - .../libunwind/src/arm/Gcreate_addr_space.c | 60 - .../pal/src/libunwind/src/arm/Gex_tables.c | 548 -- .../src/libunwind/src/arm/Gget_proc_info.c | 41 - .../pal/src/libunwind/src/arm/Gget_save_loc.c | 81 - .../src/pal/src/libunwind/src/arm/Gglobal.c | 65 - .../src/pal/src/libunwind/src/arm/Ginit.c | 235 - .../pal/src/libunwind/src/arm/Ginit_local.c | 78 - .../pal/src/libunwind/src/arm/Ginit_remote.c | 45 - .../pal/src/libunwind/src/arm/Gos-freebsd.c | 129 - .../src/pal/src/libunwind/src/arm/Gos-linux.c | 182 - .../src/pal/src/libunwind/src/arm/Gos-other.c | 48 - .../libunwind/src/arm/Greg_states_iterate.c | 37 - .../src/pal/src/libunwind/src/arm/Gregs.c | 83 - .../src/pal/src/libunwind/src/arm/Gresume.c | 154 - .../pal/src/libunwind/src/arm/Gstash_frame.c | 90 - .../src/pal/src/libunwind/src/arm/Gstep.c | 192 - .../src/pal/src/libunwind/src/arm/Gtrace.c | 557 -- .../src/libunwind/src/arm/Lapply_reg_state.c | 5 - .../libunwind/src/arm/Lcreate_addr_space.c | 5 - .../pal/src/libunwind/src/arm/Lex_tables.c | 5 - .../src/libunwind/src/arm/Lget_proc_info.c | 5 - .../pal/src/libunwind/src/arm/Lget_save_loc.c | 5 - .../src/pal/src/libunwind/src/arm/Lglobal.c | 5 - .../src/pal/src/libunwind/src/arm/Linit.c | 5 - .../pal/src/libunwind/src/arm/Linit_local.c | 5 - .../pal/src/libunwind/src/arm/Linit_remote.c | 5 - .../src/libunwind/src/arm/Lis_signal_frame.c | 5 - .../pal/src/libunwind/src/arm/Los-freebsd.c | 5 - .../src/pal/src/libunwind/src/arm/Los-linux.c | 5 - .../src/pal/src/libunwind/src/arm/Los-other.c | 5 - .../libunwind/src/arm/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/arm/Lregs.c | 5 - .../src/pal/src/libunwind/src/arm/Lresume.c | 5 - .../pal/src/libunwind/src/arm/Lstash_frame.c | 5 - .../src/pal/src/libunwind/src/arm/Lstep.c | 5 - .../src/pal/src/libunwind/src/arm/Ltrace.c | 6 - .../pal/src/libunwind/src/arm/gen-offsets.c | 54 - .../pal/src/libunwind/src/arm/getcontext.S | 63 - .../src/pal/src/libunwind/src/arm/init.h | 77 - .../src/pal/src/libunwind/src/arm/is_fpreg.c | 39 - .../src/pal/src/libunwind/src/arm/offsets.h | 42 - .../src/pal/src/libunwind/src/arm/regname.c | 90 - .../pal/src/libunwind/src/arm/siglongjmp.S | 12 - .../src/pal/src/libunwind/src/arm/unwind_i.h | 62 - .../src/pal/src/libunwind/src/coredump/README | 8 - .../libunwind/src/coredump/_UCD_access_mem.c | 98 - .../src/coredump/_UCD_access_reg_freebsd.c | 137 - .../src/coredump/_UCD_access_reg_linux.c | 146 - .../libunwind/src/coredump/_UCD_accessors.c | 36 - .../src/libunwind/src/coredump/_UCD_create.c | 417 -- .../src/libunwind/src/coredump/_UCD_destroy.c | 52 - .../src/coredump/_UCD_elf_map_image.c | 98 - .../src/coredump/_UCD_find_proc_info.c | 163 - .../src/coredump/_UCD_get_proc_name.c | 70 - .../libunwind/src/coredump/_UCD_internal.h | 105 - .../pal/src/libunwind/src/coredump/_UCD_lib.h | 57 - .../src/coredump/_UPT_access_fpreg.c | 34 - .../pal/src/libunwind/src/coredump/_UPT_elf.c | 5 - .../coredump/_UPT_get_dyn_info_list_addr.c | 108 - .../src/coredump/_UPT_put_unwind_info.c | 36 - .../src/libunwind/src/coredump/_UPT_resume.c | 35 - .../src/coredump/libunwind-coredump.pc.in | 11 - .../src/pal/src/libunwind/src/dwarf/Gexpr.c | 696 --- .../src/pal/src/libunwind/src/dwarf/Gfde.c | 359 -- .../libunwind/src/dwarf/Gfind_proc_info-lsb.c | 935 --- .../libunwind/src/dwarf/Gfind_unwind_table.c | 230 - .../src/pal/src/libunwind/src/dwarf/Gparser.c | 1059 ---- .../src/pal/src/libunwind/src/dwarf/Gpe.c | 39 - .../src/pal/src/libunwind/src/dwarf/Lexpr.c | 5 - .../src/pal/src/libunwind/src/dwarf/Lfde.c | 5 - .../libunwind/src/dwarf/Lfind_proc_info-lsb.c | 5 - .../libunwind/src/dwarf/Lfind_unwind_table.c | 5 - .../src/pal/src/libunwind/src/dwarf/Lparser.c | 5 - .../src/pal/src/libunwind/src/dwarf/Lpe.c | 5 - .../src/pal/src/libunwind/src/dwarf/global.c | 37 - src/coreclr/src/pal/src/libunwind/src/elf32.c | 4 - src/coreclr/src/pal/src/libunwind/src/elf32.h | 9 - src/coreclr/src/pal/src/libunwind/src/elf64.c | 4 - src/coreclr/src/pal/src/libunwind/src/elf64.h | 9 - src/coreclr/src/pal/src/libunwind/src/elfxx.c | 481 -- src/coreclr/src/pal/src/libunwind/src/elfxx.h | 101 - .../src/libunwind/src/hppa/Gapply_reg_state.c | 37 - .../libunwind/src/hppa/Gcreate_addr_space.c | 54 - .../src/libunwind/src/hppa/Gget_proc_info.c | 46 - .../src/libunwind/src/hppa/Gget_save_loc.c | 59 - .../src/pal/src/libunwind/src/hppa/Gglobal.c | 55 - .../src/pal/src/libunwind/src/hppa/Ginit.c | 194 - .../pal/src/libunwind/src/hppa/Ginit_local.c | 77 - .../pal/src/libunwind/src/hppa/Ginit_remote.c | 46 - .../src/libunwind/src/hppa/Gis_signal_frame.c | 74 - .../libunwind/src/hppa/Greg_states_iterate.c | 37 - .../src/pal/src/libunwind/src/hppa/Gregs.c | 87 - .../src/pal/src/libunwind/src/hppa/Gresume.c | 145 - .../src/pal/src/libunwind/src/hppa/Gstep.c | 95 - .../src/libunwind/src/hppa/Lapply_reg_state.c | 5 - .../libunwind/src/hppa/Lcreate_addr_space.c | 5 - .../src/libunwind/src/hppa/Lget_proc_info.c | 5 - .../src/libunwind/src/hppa/Lget_save_loc.c | 5 - .../src/pal/src/libunwind/src/hppa/Lglobal.c | 5 - .../src/pal/src/libunwind/src/hppa/Linit.c | 5 - .../pal/src/libunwind/src/hppa/Linit_local.c | 5 - .../pal/src/libunwind/src/hppa/Linit_remote.c | 5 - .../src/libunwind/src/hppa/Lis_signal_frame.c | 5 - .../libunwind/src/hppa/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/hppa/Lregs.c | 5 - .../src/pal/src/libunwind/src/hppa/Lresume.c | 5 - .../src/pal/src/libunwind/src/hppa/Lstep.c | 5 - .../src/libunwind/src/hppa/get_accessors.c | 38 - .../pal/src/libunwind/src/hppa/getcontext.S | 74 - .../src/pal/src/libunwind/src/hppa/init.h | 47 - .../src/pal/src/libunwind/src/hppa/offsets.h | 17 - .../src/pal/src/libunwind/src/hppa/regname.c | 50 - .../pal/src/libunwind/src/hppa/setcontext.S | 77 - .../pal/src/libunwind/src/hppa/siglongjmp.S | 16 - .../src/pal/src/libunwind/src/hppa/tables.c | 43 - .../src/pal/src/libunwind/src/hppa/unwind_i.h | 47 - .../src/libunwind/src/ia64/Gapply_reg_state.c | 39 - .../libunwind/src/ia64/Gcreate_addr_space.c | 63 - .../libunwind/src/ia64/Gfind_unwind_table.c | 143 - .../src/libunwind/src/ia64/Gget_proc_info.c | 38 - .../src/libunwind/src/ia64/Gget_save_loc.c | 168 - .../src/pal/src/libunwind/src/ia64/Gglobal.c | 122 - .../src/pal/src/libunwind/src/ia64/Ginit.c | 505 -- .../pal/src/libunwind/src/ia64/Ginit_local.c | 110 - .../pal/src/libunwind/src/ia64/Ginit_remote.c | 61 - .../src/libunwind/src/ia64/Ginstall_cursor.S | 348 -- .../src/libunwind/src/ia64/Gis_signal_frame.c | 54 - .../src/pal/src/libunwind/src/ia64/Gparser.c | 1131 ---- .../src/pal/src/libunwind/src/ia64/Grbs.c | 319 - .../libunwind/src/ia64/Greg_states_iterate.c | 39 - .../src/pal/src/libunwind/src/ia64/Gregs.c | 612 -- .../src/pal/src/libunwind/src/ia64/Gresume.c | 274 - .../src/pal/src/libunwind/src/ia64/Gscript.c | 765 --- .../src/pal/src/libunwind/src/ia64/Gstep.c | 359 -- .../src/pal/src/libunwind/src/ia64/Gtables.c | 731 --- .../src/libunwind/src/ia64/Lapply_reg_state.c | 5 - .../libunwind/src/ia64/Lcreate_addr_space.c | 5 - .../libunwind/src/ia64/Lfind_unwind_table.c | 5 - .../src/libunwind/src/ia64/Lget_proc_info.c | 5 - .../src/libunwind/src/ia64/Lget_save_loc.c | 5 - .../src/pal/src/libunwind/src/ia64/Lglobal.c | 5 - .../src/pal/src/libunwind/src/ia64/Linit.c | 5 - .../pal/src/libunwind/src/ia64/Linit_local.c | 5 - .../pal/src/libunwind/src/ia64/Linit_remote.c | 5 - .../src/libunwind/src/ia64/Linstall_cursor.S | 6 - .../src/libunwind/src/ia64/Lis_signal_frame.c | 5 - .../src/pal/src/libunwind/src/ia64/Lparser.c | 5 - .../src/pal/src/libunwind/src/ia64/Lrbs.c | 5 - .../libunwind/src/ia64/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/ia64/Lregs.c | 5 - .../src/pal/src/libunwind/src/ia64/Lresume.c | 5 - .../src/pal/src/libunwind/src/ia64/Lscript.c | 5 - .../src/pal/src/libunwind/src/ia64/Lstep.c | 5 - .../src/pal/src/libunwind/src/ia64/Ltables.c | 5 - .../src/pal/src/libunwind/src/ia64/NOTES | 65 - .../src/libunwind/src/ia64/dyn_info_list.S | 26 - .../pal/src/libunwind/src/ia64/getcontext.S | 177 - .../src/pal/src/libunwind/src/ia64/init.h | 132 - .../src/pal/src/libunwind/src/ia64/longjmp.S | 42 - .../pal/src/libunwind/src/ia64/mk_cursor_i | 7 - .../src/pal/src/libunwind/src/ia64/offsets.h | 137 - .../src/pal/src/libunwind/src/ia64/regname.c | 189 - .../src/pal/src/libunwind/src/ia64/regs.h | 73 - .../src/pal/src/libunwind/src/ia64/setjmp.S | 51 - .../pal/src/libunwind/src/ia64/siglongjmp.S | 69 - .../pal/src/libunwind/src/ia64/sigsetjmp.S | 69 - .../pal/src/libunwind/src/ia64/ucontext_i.h | 68 - .../src/libunwind/src/ia64/unwind_decoder.h | 477 -- .../src/pal/src/libunwind/src/ia64/unwind_i.h | 633 -- .../src/libunwind/src/libunwind-generic.pc.in | 11 - .../libunwind/src/mi/Gdestroy_addr_space.c | 37 - .../pal/src/libunwind/src/mi/Gdyn-extract.c | 64 - .../pal/src/libunwind/src/mi/Gdyn-remote.c | 326 -- .../src/mi/Gfind_dynamic_proc_info.c | 91 - .../pal/src/libunwind/src/mi/Gget_accessors.c | 37 - .../src/pal/src/libunwind/src/mi/Gget_fpreg.c | 34 - .../libunwind/src/mi/Gget_proc_info_by_ip.c | 39 - .../pal/src/libunwind/src/mi/Gget_proc_name.c | 118 - .../src/pal/src/libunwind/src/mi/Gget_reg.c | 41 - .../src/mi/Gput_dynamic_unwind_info.c | 55 - .../src/libunwind/src/mi/Gset_cache_size.c | 72 - .../libunwind/src/mi/Gset_caching_policy.c | 46 - .../src/pal/src/libunwind/src/mi/Gset_fpreg.c | 34 - .../src/pal/src/libunwind/src/mi/Gset_reg.c | 34 - .../libunwind/src/mi/Ldestroy_addr_space.c | 5 - .../pal/src/libunwind/src/mi/Ldyn-extract.c | 5 - .../pal/src/libunwind/src/mi/Ldyn-remote.c | 5 - .../src/mi/Lfind_dynamic_proc_info.c | 5 - .../pal/src/libunwind/src/mi/Lget_accessors.c | 5 - .../src/pal/src/libunwind/src/mi/Lget_fpreg.c | 5 - .../libunwind/src/mi/Lget_proc_info_by_ip.c | 5 - .../pal/src/libunwind/src/mi/Lget_proc_name.c | 5 - .../src/pal/src/libunwind/src/mi/Lget_reg.c | 5 - .../src/mi/Lput_dynamic_unwind_info.c | 5 - .../src/libunwind/src/mi/Lset_cache_size.c | 5 - .../libunwind/src/mi/Lset_caching_policy.c | 5 - .../src/pal/src/libunwind/src/mi/Lset_fpreg.c | 5 - .../src/pal/src/libunwind/src/mi/Lset_reg.c | 5 - .../src/pal/src/libunwind/src/mi/_ReadSLEB.c | 25 - .../src/pal/src/libunwind/src/mi/_ReadULEB.c | 20 - .../src/pal/src/libunwind/src/mi/backtrace.c | 81 - .../src/pal/src/libunwind/src/mi/dyn-cancel.c | 46 - .../pal/src/libunwind/src/mi/dyn-info-list.c | 34 - .../pal/src/libunwind/src/mi/dyn-register.c | 44 - .../pal/src/libunwind/src/mi/flush_cache.c | 59 - .../src/pal/src/libunwind/src/mi/init.c | 60 - .../src/pal/src/libunwind/src/mi/mempool.c | 184 - .../src/pal/src/libunwind/src/mi/strerror.c | 51 - .../src/libunwind/src/mips/Gapply_reg_state.c | 37 - .../libunwind/src/mips/Gcreate_addr_space.c | 66 - .../src/libunwind/src/mips/Gget_proc_info.c | 41 - .../src/libunwind/src/mips/Gget_save_loc.c | 100 - .../src/pal/src/libunwind/src/mips/Gglobal.c | 55 - .../src/pal/src/libunwind/src/mips/Ginit.c | 210 - .../pal/src/libunwind/src/mips/Ginit_local.c | 76 - .../pal/src/libunwind/src/mips/Ginit_remote.c | 45 - .../src/libunwind/src/mips/Gis_signal_frame.c | 78 - .../libunwind/src/mips/Greg_states_iterate.c | 37 - .../src/pal/src/libunwind/src/mips/Gregs.c | 105 - .../src/pal/src/libunwind/src/mips/Gresume.c | 45 - .../src/pal/src/libunwind/src/mips/Gstep.c | 132 - .../src/libunwind/src/mips/Lapply_reg_state.c | 5 - .../libunwind/src/mips/Lcreate_addr_space.c | 5 - .../src/libunwind/src/mips/Lget_proc_info.c | 5 - .../src/libunwind/src/mips/Lget_save_loc.c | 5 - .../src/pal/src/libunwind/src/mips/Lglobal.c | 5 - .../src/pal/src/libunwind/src/mips/Linit.c | 5 - .../pal/src/libunwind/src/mips/Linit_local.c | 5 - .../pal/src/libunwind/src/mips/Linit_remote.c | 5 - .../src/libunwind/src/mips/Lis_signal_frame.c | 5 - .../libunwind/src/mips/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/mips/Lregs.c | 5 - .../src/pal/src/libunwind/src/mips/Lresume.c | 5 - .../src/pal/src/libunwind/src/mips/Lstep.c | 5 - .../src/pal/src/libunwind/src/mips/elfxx.c | 27 - .../pal/src/libunwind/src/mips/gen-offsets.c | 30 - .../pal/src/libunwind/src/mips/getcontext.S | 93 - .../src/pal/src/libunwind/src/mips/init.h | 59 - .../src/pal/src/libunwind/src/mips/is_fpreg.c | 35 - .../src/pal/src/libunwind/src/mips/offsets.h | 86 - .../src/pal/src/libunwind/src/mips/regname.c | 48 - .../pal/src/libunwind/src/mips/siglongjmp.S | 8 - .../src/pal/src/libunwind/src/mips/unwind_i.h | 43 - .../src/pal/src/libunwind/src/os-freebsd.c | 166 - .../src/pal/src/libunwind/src/os-hpux.c | 78 - .../src/pal/src/libunwind/src/os-linux.c | 73 - .../src/pal/src/libunwind/src/os-linux.h | 297 - .../src/pal/src/libunwind/src/os-qnx.c | 117 - .../src/libunwind/src/ppc/Gapply_reg_state.c | 37 - .../src/libunwind/src/ppc/Gget_proc_info.c | 41 - .../pal/src/libunwind/src/ppc/Gget_save_loc.c | 34 - .../pal/src/libunwind/src/ppc/Ginit_local.c | 88 - .../pal/src/libunwind/src/ppc/Ginit_remote.c | 60 - .../src/libunwind/src/ppc/Gis_signal_frame.c | 78 - .../libunwind/src/ppc/Greg_states_iterate.c | 37 - .../src/libunwind/src/ppc/Lapply_reg_state.c | 5 - .../src/libunwind/src/ppc/Lget_proc_info.c | 5 - .../pal/src/libunwind/src/ppc/Lget_save_loc.c | 5 - .../pal/src/libunwind/src/ppc/Linit_local.c | 5 - .../pal/src/libunwind/src/ppc/Linit_remote.c | 5 - .../src/libunwind/src/ppc/Lis_signal_frame.c | 5 - .../libunwind/src/ppc/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/ppc/longjmp.S | 36 - .../pal/src/libunwind/src/ppc/siglongjmp.S | 31 - .../libunwind/src/ppc32/Gapply_reg_state.c | 37 - .../libunwind/src/ppc32/Gcreate_addr_space.c | 56 - .../src/pal/src/libunwind/src/ppc32/Gglobal.c | 135 - .../src/pal/src/libunwind/src/ppc32/Ginit.c | 216 - .../libunwind/src/ppc32/Greg_states_iterate.c | 37 - .../src/pal/src/libunwind/src/ppc32/Gregs.c | 90 - .../src/pal/src/libunwind/src/ppc32/Gresume.c | 77 - .../src/pal/src/libunwind/src/ppc32/Gstep.c | 309 - .../libunwind/src/ppc32/Lapply_reg_state.c | 5 - .../libunwind/src/ppc32/Lcreate_addr_space.c | 5 - .../src/pal/src/libunwind/src/ppc32/Lglobal.c | 5 - .../src/pal/src/libunwind/src/ppc32/Linit.c | 5 - .../libunwind/src/ppc32/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/ppc32/Lregs.c | 5 - .../src/pal/src/libunwind/src/ppc32/Lresume.c | 5 - .../src/pal/src/libunwind/src/ppc32/Lstep.c | 5 - .../pal/src/libunwind/src/ppc32/Make-arch.in | 11 - .../src/libunwind/src/ppc32/get_func_addr.c | 36 - .../src/pal/src/libunwind/src/ppc32/init.h | 72 - .../pal/src/libunwind/src/ppc32/is_fpreg.c | 34 - .../src/pal/src/libunwind/src/ppc32/regname.c | 112 - .../pal/src/libunwind/src/ppc32/setcontext.S | 9 - .../pal/src/libunwind/src/ppc32/ucontext_i.h | 128 - .../pal/src/libunwind/src/ppc32/unwind_i.h | 46 - .../libunwind/src/ppc64/Gapply_reg_state.c | 37 - .../libunwind/src/ppc64/Gcreate_addr_space.c | 71 - .../src/pal/src/libunwind/src/ppc64/Gglobal.c | 182 - .../src/pal/src/libunwind/src/ppc64/Ginit.c | 229 - .../libunwind/src/ppc64/Greg_states_iterate.c | 37 - .../src/pal/src/libunwind/src/ppc64/Gregs.c | 141 - .../src/pal/src/libunwind/src/ppc64/Gresume.c | 111 - .../src/pal/src/libunwind/src/ppc64/Gstep.c | 466 -- .../libunwind/src/ppc64/Lapply_reg_state.c | 5 - .../libunwind/src/ppc64/Lcreate_addr_space.c | 5 - .../src/pal/src/libunwind/src/ppc64/Lglobal.c | 5 - .../src/pal/src/libunwind/src/ppc64/Linit.c | 5 - .../libunwind/src/ppc64/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/ppc64/Lregs.c | 5 - .../src/pal/src/libunwind/src/ppc64/Lresume.c | 5 - .../src/pal/src/libunwind/src/ppc64/Lstep.c | 5 - .../src/libunwind/src/ppc64/get_func_addr.c | 51 - .../src/pal/src/libunwind/src/ppc64/init.h | 82 - .../pal/src/libunwind/src/ppc64/is_fpreg.c | 34 - .../src/pal/src/libunwind/src/ppc64/regname.c | 164 - .../pal/src/libunwind/src/ppc64/setcontext.S | 9 - .../pal/src/libunwind/src/ppc64/ucontext_i.h | 173 - .../pal/src/libunwind/src/ppc64/unwind_i.h | 52 - .../libunwind/src/ptrace/_UPT_access_fpreg.c | 121 - .../libunwind/src/ptrace/_UPT_access_mem.c | 123 - .../libunwind/src/ptrace/_UPT_access_reg.c | 352 -- .../src/libunwind/src/ptrace/_UPT_accessors.c | 38 - .../src/libunwind/src/ptrace/_UPT_create.c | 46 - .../src/libunwind/src/ptrace/_UPT_destroy.c | 34 - .../pal/src/libunwind/src/ptrace/_UPT_elf.c | 5 - .../src/ptrace/_UPT_find_proc_info.c | 145 - .../src/ptrace/_UPT_get_dyn_info_list_addr.c | 105 - .../libunwind/src/ptrace/_UPT_get_proc_name.c | 42 - .../src/libunwind/src/ptrace/_UPT_internal.h | 59 - .../src/ptrace/_UPT_put_unwind_info.c | 35 - .../libunwind/src/ptrace/_UPT_reg_offset.c | 638 -- .../src/libunwind/src/ptrace/_UPT_resume.c | 40 - .../src/ptrace/libunwind-ptrace.pc.in | 11 - .../src/setjmp/libunwind-setjmp.pc.in | 11 - .../pal/src/libunwind/src/setjmp/longjmp.c | 115 - .../src/pal/src/libunwind/src/setjmp/setjmp.c | 49 - .../pal/src/libunwind/src/setjmp/setjmp_i.h | 118 - .../pal/src/libunwind/src/setjmp/siglongjmp.c | 127 - .../pal/src/libunwind/src/setjmp/sigsetjmp.c | 50 - .../src/libunwind/src/sh/Gapply_reg_state.c | 37 - .../src/libunwind/src/sh/Gcreate_addr_space.c | 59 - .../pal/src/libunwind/src/sh/Gget_proc_info.c | 39 - .../pal/src/libunwind/src/sh/Gget_save_loc.c | 83 - .../src/pal/src/libunwind/src/sh/Gglobal.c | 56 - .../src/pal/src/libunwind/src/sh/Ginit.c | 186 - .../pal/src/libunwind/src/sh/Ginit_local.c | 78 - .../pal/src/libunwind/src/sh/Ginit_remote.c | 45 - .../src/libunwind/src/sh/Gis_signal_frame.c | 119 - .../libunwind/src/sh/Greg_states_iterate.c | 37 - .../src/pal/src/libunwind/src/sh/Gregs.c | 81 - .../src/pal/src/libunwind/src/sh/Gresume.c | 165 - .../src/pal/src/libunwind/src/sh/Gstep.c | 117 - .../src/libunwind/src/sh/Lapply_reg_state.c | 5 - .../src/libunwind/src/sh/Lcreate_addr_space.c | 5 - .../pal/src/libunwind/src/sh/Lget_proc_info.c | 5 - .../pal/src/libunwind/src/sh/Lget_save_loc.c | 5 - .../src/pal/src/libunwind/src/sh/Lglobal.c | 5 - .../src/pal/src/libunwind/src/sh/Linit.c | 5 - .../pal/src/libunwind/src/sh/Linit_local.c | 5 - .../pal/src/libunwind/src/sh/Linit_remote.c | 5 - .../src/libunwind/src/sh/Lis_signal_frame.c | 5 - .../libunwind/src/sh/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/sh/Lregs.c | 5 - .../src/pal/src/libunwind/src/sh/Lresume.c | 5 - .../src/pal/src/libunwind/src/sh/Lstep.c | 5 - .../pal/src/libunwind/src/sh/gen-offsets.c | 51 - .../src/pal/src/libunwind/src/sh/init.h | 73 - .../src/pal/src/libunwind/src/sh/is_fpreg.c | 32 - .../src/pal/src/libunwind/src/sh/offsets.h | 32 - .../src/pal/src/libunwind/src/sh/regname.c | 56 - .../src/pal/src/libunwind/src/sh/siglongjmp.S | 8 - .../src/pal/src/libunwind/src/sh/unwind_i.h | 40 - .../libunwind/src/tilegx/Gapply_reg_state.c | 37 - .../libunwind/src/tilegx/Gcreate_addr_space.c | 65 - .../src/libunwind/src/tilegx/Gget_proc_info.c | 48 - .../src/libunwind/src/tilegx/Gget_save_loc.c | 62 - .../pal/src/libunwind/src/tilegx/Gglobal.c | 64 - .../src/pal/src/libunwind/src/tilegx/Ginit.c | 167 - .../src/libunwind/src/tilegx/Ginit_local.c | 80 - .../src/libunwind/src/tilegx/Ginit_remote.c | 47 - .../libunwind/src/tilegx/Gis_signal_frame.c | 115 - .../src/tilegx/Greg_states_iterate.c | 37 - .../src/pal/src/libunwind/src/tilegx/Gregs.c | 76 - .../pal/src/libunwind/src/tilegx/Gresume.c | 94 - .../src/pal/src/libunwind/src/tilegx/Gstep.c | 53 - .../libunwind/src/tilegx/Lapply_reg_state.c | 5 - .../libunwind/src/tilegx/Lcreate_addr_space.c | 5 - .../src/libunwind/src/tilegx/Lget_proc_info.c | 5 - .../src/libunwind/src/tilegx/Lget_save_loc.c | 5 - .../pal/src/libunwind/src/tilegx/Lglobal.c | 5 - .../src/pal/src/libunwind/src/tilegx/Linit.c | 5 - .../src/libunwind/src/tilegx/Linit_local.c | 5 - .../src/libunwind/src/tilegx/Linit_remote.c | 5 - .../libunwind/src/tilegx/Lis_signal_frame.c | 5 - .../src/tilegx/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/tilegx/Lregs.c | 5 - .../pal/src/libunwind/src/tilegx/Lresume.c | 5 - .../src/pal/src/libunwind/src/tilegx/Lstep.c | 5 - .../src/pal/src/libunwind/src/tilegx/elfxx.c | 27 - .../src/libunwind/src/tilegx/gen-offsets.c | 30 - .../pal/src/libunwind/src/tilegx/getcontext.S | 36 - .../src/pal/src/libunwind/src/tilegx/init.h | 63 - .../pal/src/libunwind/src/tilegx/is_fpreg.c | 33 - .../pal/src/libunwind/src/tilegx/offsets.h | 12 - .../pal/src/libunwind/src/tilegx/regname.c | 55 - .../pal/src/libunwind/src/tilegx/siglongjmp.S | 7 - .../pal/src/libunwind/src/tilegx/unwind_i.h | 46 - .../pal/src/libunwind/src/unwind/Backtrace.c | 56 - .../libunwind/src/unwind/DeleteException.c | 38 - .../src/unwind/FindEnclosingFunction.c | 42 - .../src/libunwind/src/unwind/ForcedUnwind.c | 52 - .../src/pal/src/libunwind/src/unwind/GetBSP.c | 42 - .../src/pal/src/libunwind/src/unwind/GetCFA.c | 38 - .../src/libunwind/src/unwind/GetDataRelBase.c | 39 - .../src/pal/src/libunwind/src/unwind/GetGR.c | 43 - .../src/pal/src/libunwind/src/unwind/GetIP.c | 38 - .../pal/src/libunwind/src/unwind/GetIPInfo.c | 42 - .../src/unwind/GetLanguageSpecificData.c | 40 - .../src/libunwind/src/unwind/GetRegionStart.c | 39 - .../src/libunwind/src/unwind/GetTextRelBase.c | 35 - .../src/libunwind/src/unwind/RaiseException.c | 103 - .../src/pal/src/libunwind/src/unwind/Resume.c | 42 - .../libunwind/src/unwind/Resume_or_Rethrow.c | 47 - .../src/pal/src/libunwind/src/unwind/SetGR.c | 47 - .../src/pal/src/libunwind/src/unwind/SetIP.c | 35 - .../src/libunwind/src/unwind/libunwind.pc.in | 11 - .../libunwind/src/unwind/unwind-internal.h | 140 - .../src/libunwind/src/x86/Gapply_reg_state.c | 37 - .../libunwind/src/x86/Gcreate_addr_space.c | 58 - .../src/libunwind/src/x86/Gget_proc_info.c | 45 - .../pal/src/libunwind/src/x86/Gget_save_loc.c | 133 - .../src/pal/src/libunwind/src/x86/Gglobal.c | 67 - .../src/pal/src/libunwind/src/x86/Ginit.c | 243 - .../pal/src/libunwind/src/x86/Ginit_local.c | 79 - .../pal/src/libunwind/src/x86/Ginit_remote.c | 56 - .../pal/src/libunwind/src/x86/Gos-freebsd.c | 374 -- .../src/pal/src/libunwind/src/x86/Gos-linux.c | 331 -- .../libunwind/src/x86/Greg_states_iterate.c | 37 - .../src/pal/src/libunwind/src/x86/Gregs.c | 178 - .../src/pal/src/libunwind/src/x86/Gresume.c | 91 - .../src/pal/src/libunwind/src/x86/Gstep.c | 115 - .../src/libunwind/src/x86/Lapply_reg_state.c | 5 - .../libunwind/src/x86/Lcreate_addr_space.c | 5 - .../src/libunwind/src/x86/Lget_proc_info.c | 5 - .../pal/src/libunwind/src/x86/Lget_save_loc.c | 5 - .../src/pal/src/libunwind/src/x86/Lglobal.c | 5 - .../src/pal/src/libunwind/src/x86/Linit.c | 5 - .../pal/src/libunwind/src/x86/Linit_local.c | 5 - .../pal/src/libunwind/src/x86/Linit_remote.c | 5 - .../pal/src/libunwind/src/x86/Los-freebsd.c | 5 - .../src/pal/src/libunwind/src/x86/Los-linux.c | 5 - .../libunwind/src/x86/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/x86/Lregs.c | 5 - .../src/pal/src/libunwind/src/x86/Lresume.c | 5 - .../src/pal/src/libunwind/src/x86/Lstep.c | 5 - .../libunwind/src/x86/getcontext-freebsd.S | 112 - .../src/libunwind/src/x86/getcontext-linux.S | 74 - .../src/pal/src/libunwind/src/x86/init.h | 69 - .../src/pal/src/libunwind/src/x86/is_fpreg.c | 34 - .../src/pal/src/libunwind/src/x86/longjmp.S | 39 - .../src/pal/src/libunwind/src/x86/offsets.h | 140 - .../src/pal/src/libunwind/src/x86/regname.c | 27 - .../pal/src/libunwind/src/x86/siglongjmp.S | 92 - .../src/pal/src/libunwind/src/x86/unwind_i.h | 68 - .../libunwind/src/x86_64/Gapply_reg_state.c | 37 - .../libunwind/src/x86_64/Gcreate_addr_space.c | 61 - .../src/libunwind/src/x86_64/Gget_proc_info.c | 48 - .../src/libunwind/src/x86_64/Gget_save_loc.c | 73 - .../pal/src/libunwind/src/x86_64/Gglobal.c | 102 - .../src/pal/src/libunwind/src/x86_64/Ginit.c | 342 -- .../src/libunwind/src/x86_64/Ginit_local.c | 81 - .../src/libunwind/src/x86_64/Ginit_remote.c | 57 - .../src/libunwind/src/x86_64/Gos-freebsd.c | 218 - .../pal/src/libunwind/src/x86_64/Gos-linux.c | 156 - .../src/x86_64/Greg_states_iterate.c | 37 - .../src/pal/src/libunwind/src/x86_64/Gregs.c | 138 - .../pal/src/libunwind/src/x86_64/Gresume.c | 123 - .../src/libunwind/src/x86_64/Gstash_frame.c | 119 - .../src/pal/src/libunwind/src/x86_64/Gstep.c | 227 - .../src/pal/src/libunwind/src/x86_64/Gtrace.c | 551 -- .../libunwind/src/x86_64/Lapply_reg_state.c | 5 - .../libunwind/src/x86_64/Lcreate_addr_space.c | 5 - .../src/libunwind/src/x86_64/Lget_proc_info.c | 5 - .../src/libunwind/src/x86_64/Lget_save_loc.c | 5 - .../pal/src/libunwind/src/x86_64/Lglobal.c | 6 - .../src/pal/src/libunwind/src/x86_64/Linit.c | 5 - .../src/libunwind/src/x86_64/Linit_local.c | 5 - .../src/libunwind/src/x86_64/Linit_remote.c | 5 - .../src/libunwind/src/x86_64/Los-freebsd.c | 5 - .../pal/src/libunwind/src/x86_64/Los-linux.c | 5 - .../src/x86_64/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/x86_64/Lregs.c | 5 - .../pal/src/libunwind/src/x86_64/Lresume.c | 5 - .../src/libunwind/src/x86_64/Lstash_frame.c | 5 - .../src/pal/src/libunwind/src/x86_64/Lstep.c | 5 - .../src/pal/src/libunwind/src/x86_64/Ltrace.c | 5 - .../pal/src/libunwind/src/x86_64/getcontext.S | 134 - .../src/pal/src/libunwind/src/x86_64/init.h | 89 - .../pal/src/libunwind/src/x86_64/is_fpreg.c | 38 - .../pal/src/libunwind/src/x86_64/longjmp.S | 34 - .../pal/src/libunwind/src/x86_64/offsets.h | 3 - .../pal/src/libunwind/src/x86_64/regname.c | 56 - .../pal/src/libunwind/src/x86_64/setcontext.S | 83 - .../pal/src/libunwind/src/x86_64/siglongjmp.S | 32 - .../pal/src/libunwind/src/x86_64/ucontext_i.h | 82 - .../pal/src/libunwind/src/x86_64/unwind_i.h | 93 - .../pal/src/libunwind/tests/Gia64-test-nat.c | 626 -- .../pal/src/libunwind/tests/Gia64-test-rbs.c | 193 - .../src/libunwind/tests/Gia64-test-readonly.c | 89 - .../src/libunwind/tests/Gia64-test-stack.c | 176 - .../pal/src/libunwind/tests/Gperf-simple.c | 264 - .../src/pal/src/libunwind/tests/Gperf-trace.c | 250 - .../src/pal/src/libunwind/tests/Gtest-bt.c | 263 - .../src/libunwind/tests/Gtest-concurrent.c | 136 - .../src/pal/src/libunwind/tests/Gtest-dyn1.c | 223 - .../src/pal/src/libunwind/tests/Gtest-exc.c | 162 - .../pal/src/libunwind/tests/Gtest-init.cxx | 107 - .../pal/src/libunwind/tests/Gtest-nomalloc.c | 110 - .../src/libunwind/tests/Gtest-resume-sig-rt.c | 31 - .../src/libunwind/tests/Gtest-resume-sig.c | 200 - .../src/pal/src/libunwind/tests/Gtest-trace.c | 282 - .../pal/src/libunwind/tests/Lia64-test-nat.c | 5 - .../pal/src/libunwind/tests/Lia64-test-rbs.c | 5 - .../src/libunwind/tests/Lia64-test-readonly.c | 5 - .../src/libunwind/tests/Lia64-test-stack.c | 5 - .../pal/src/libunwind/tests/Lperf-simple.c | 5 - .../src/pal/src/libunwind/tests/Lperf-trace.c | 5 - .../src/pal/src/libunwind/tests/Lrs-race.c | 1514 ----- .../src/pal/src/libunwind/tests/Ltest-bt.c | 5 - .../src/libunwind/tests/Ltest-concurrent.c | 5 - .../libunwind/tests/Ltest-cxx-exceptions.cxx | 80 - .../src/pal/src/libunwind/tests/Ltest-dyn1.c | 5 - .../src/pal/src/libunwind/tests/Ltest-exc.c | 5 - .../tests/Ltest-init-local-signal-lib.c | 6 - .../libunwind/tests/Ltest-init-local-signal.c | 60 - .../pal/src/libunwind/tests/Ltest-init.cxx | 5 - .../src/libunwind/tests/Ltest-mem-validate.c | 143 - .../pal/src/libunwind/tests/Ltest-nocalloc.c | 137 - .../pal/src/libunwind/tests/Ltest-nomalloc.c | 5 - .../src/libunwind/tests/Ltest-resume-sig-rt.c | 5 - .../src/libunwind/tests/Ltest-resume-sig.c | 5 - .../src/pal/src/libunwind/tests/Ltest-trace.c | 5 - .../pal/src/libunwind/tests/Ltest-varargs.c | 84 - .../src/pal/src/libunwind/tests/Makefile.am | 234 - .../src/libunwind/tests/check-namespace.sh.in | 367 -- .../src/pal/src/libunwind/tests/crasher.c | 124 - .../src/pal/src/libunwind/tests/flush-cache.S | 104 - .../src/pal/src/libunwind/tests/flush-cache.h | 38 - .../src/pal/src/libunwind/tests/forker.c | 76 - .../pal/src/libunwind/tests/ia64-dyn-asm.S | 102 - .../pal/src/libunwind/tests/ia64-test-dyn1.c | 223 - .../src/libunwind/tests/ia64-test-nat-asm.S | 508 -- .../src/libunwind/tests/ia64-test-rbs-asm.S | 275 - .../pal/src/libunwind/tests/ia64-test-rbs.h | 3 - .../libunwind/tests/ia64-test-readonly-asm.S | 55 - .../src/libunwind/tests/ia64-test-setjmp.c | 155 - .../pal/src/libunwind/tests/ia64-test-sig.c | 102 - .../src/libunwind/tests/ia64-test-stack-asm.S | 183 - .../pal/src/libunwind/tests/ia64-test-stack.h | 3 - .../src/pal/src/libunwind/tests/ident.c | 5 - .../src/pal/src/libunwind/tests/mapper.c | 78 - .../src/pal/src/libunwind/tests/perf-startup | 19 - .../tests/ppc64-test-altivec-utils.c | 32 - .../src/libunwind/tests/ppc64-test-altivec.c | 177 - .../src/libunwind/tests/run-check-namespace | 3 - .../src/libunwind/tests/run-coredump-unwind | 53 - .../libunwind/tests/run-coredump-unwind-mdi | 8 - .../src/libunwind/tests/run-ia64-test-dyn1 | 2 - .../pal/src/libunwind/tests/run-ptrace-mapper | 2 - .../pal/src/libunwind/tests/run-ptrace-misc | 2 - .../pal/src/libunwind/tests/test-async-sig.c | 193 - .../libunwind/tests/test-coredump-unwind.c | 395 -- .../src/libunwind/tests/test-flush-cache.c | 143 - .../src/libunwind/tests/test-init-remote.c | 103 - .../src/pal/src/libunwind/tests/test-mem.c | 103 - .../pal/src/libunwind/tests/test-proc-info.c | 171 - .../src/libunwind/tests/test-ptrace-misc.c | 120 - .../src/pal/src/libunwind/tests/test-ptrace.c | 370 -- .../pal/src/libunwind/tests/test-reg-state.c | 133 - .../src/pal/src/libunwind/tests/test-setjmp.c | 285 - .../libunwind/tests/test-static-link-gen.c | 74 - .../libunwind/tests/test-static-link-loc.c | 102 - .../pal/src/libunwind/tests/test-strerror.c | 18 - 767 files changed, 78283 deletions(-) delete mode 100644 src/coreclr/src/pal/src/libunwind/.gitignore delete mode 100644 src/coreclr/src/pal/src/libunwind/.travis.yml delete mode 100644 src/coreclr/src/pal/src/libunwind/AUTHORS delete mode 100644 src/coreclr/src/pal/src/libunwind/COPYING delete mode 100644 src/coreclr/src/pal/src/libunwind/ChangeLog delete mode 100644 src/coreclr/src/pal/src/libunwind/LICENSE delete mode 100644 src/coreclr/src/pal/src/libunwind/Makefile.am delete mode 100644 src/coreclr/src/pal/src/libunwind/NEWS delete mode 100644 src/coreclr/src/pal/src/libunwind/README delete mode 100644 src/coreclr/src/pal/src/libunwind/TODO delete mode 100644 src/coreclr/src/pal/src/libunwind/acinclude.m4 delete mode 100755 src/coreclr/src/pal/src/libunwind/autogen.sh delete mode 100644 src/coreclr/src/pal/src/libunwind/aux_/config.guess delete mode 100644 src/coreclr/src/pal/src/libunwind/aux_/config.sub delete mode 100644 src/coreclr/src/pal/src/libunwind/aux_/ltmain.sh delete mode 100644 src/coreclr/src/pal/src/libunwind/configure.ac delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/Makefile.am delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/NOTES delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/common.tex.in delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind.trans delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_init_local.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_init_local.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_init_local2.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_regname.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_regname.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_resume.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_resume.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_step.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_step.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_strerror.man delete mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_strerror.tex delete mode 100644 src/coreclr/src/pal/src/libunwind/include/compiler.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/dwarf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/dwarf_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-arm.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-coredump.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-dynamic.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-hppa.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-ia64.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-ppc32.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-ppc64.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-ptrace.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-sh.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-tilegx.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-x86.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-x86_64.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind.h.in delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/mempool.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/remote.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-arm/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-arm/ex_tables.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-arm/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-hppa/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-hppa/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-hppa/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ia64/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ia64/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ia64/rse.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ia64/script.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-mips/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-sh/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-sh/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-sh/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in delete mode 100644 src/coreclr/src/pal/src/libunwind/include/unwind.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/x86/jmpbuf.h delete mode 100755 src/coreclr/src/pal/src/libunwind/scripts/kernel-diff.sh delete mode 100644 src/coreclr/src/pal/src/libunwind/scripts/kernel-files.txt delete mode 100755 src/coreclr/src/pal/src/libunwind/scripts/make-L-files delete mode 100644 src/coreclr/src/pal/src/libunwind/src/Makefile.am delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gstash_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gtrace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lstash_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Ltrace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/gen-offsets.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/getcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/is_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/offsets.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/siglongjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gos-freebsd.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gos-linux.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gos-other.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gstash_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gtrace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lex_tables.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Los-freebsd.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Los-linux.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Los-other.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lstash_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Ltrace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/gen-offsets.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/getcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/is_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/offsets.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/siglongjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/README delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_mem.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_accessors.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_destroy.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_elf_map_image.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_find_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_internal.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_lib.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_access_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_elf.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_put_unwind_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_resume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/libunwind-coredump.pc.in delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gfde.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gpe.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lexpr.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lfde.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_proc_info-lsb.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_unwind_table.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lparser.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lpe.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/global.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/elf32.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/elf32.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/elf64.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/elf64.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/elfxx.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/elfxx.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/get_accessors.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/getcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/offsets.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/setcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/siglongjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/tables.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gfind_unwind_table.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Ginstall_cursor.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gparser.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Grbs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gscript.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gtables.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lfind_unwind_table.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Linstall_cursor.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lparser.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lrbs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lscript.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Ltables.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/NOTES delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/dyn_info_list.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/getcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/longjmp.S delete mode 100755 src/coreclr/src/pal/src/libunwind/src/ia64/mk_cursor_i delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/offsets.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/regs.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/setjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/siglongjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/sigsetjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/ucontext_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/unwind_decoder.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/libunwind-generic.pc.in delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gdestroy_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-extract.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gget_accessors.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gget_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_info_by_ip.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gget_reg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gput_dynamic_unwind_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gset_cache_size.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gset_caching_policy.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gset_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gset_reg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Ldestroy_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-extract.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lfind_dynamic_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lget_accessors.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lget_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_info_by_ip.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_name.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lget_reg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lput_dynamic_unwind_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lset_cache_size.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lset_caching_policy.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lset_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lset_reg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/_ReadSLEB.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/_ReadULEB.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/dyn-cancel.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/dyn-info-list.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/dyn-register.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/init.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/mempool.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/strerror.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/elfxx.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/gen-offsets.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/getcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/is_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/offsets.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/siglongjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/os-freebsd.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/os-hpux.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/os-linux.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/os-linux.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/os-qnx.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Gis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Lis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/longjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/siglongjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Make-arch.in delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/get_func_addr.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/is_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/setcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/ucontext_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/get_func_addr.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/is_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/setcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/ucontext_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_mem.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_reg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_accessors.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_create.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_destroy.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_elf.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_find_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_proc_name.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_internal.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_put_unwind_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_resume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/libunwind-ptrace.pc.in delete mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/libunwind-setjmp.pc.in delete mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/longjmp.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/sigsetjmp.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/gen-offsets.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/is_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/offsets.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/siglongjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/elfxx.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/gen-offsets.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/getcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/is_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/offsets.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/siglongjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/Backtrace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/DeleteException.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/FindEnclosingFunction.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/ForcedUnwind.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetBSP.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetCFA.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetDataRelBase.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetGR.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetIP.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetIPInfo.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetLanguageSpecificData.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetRegionStart.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetTextRelBase.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/RaiseException.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/Resume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/Resume_or_Rethrow.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/SetGR.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/SetIP.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in delete mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/unwind-internal.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gos-freebsd.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gos-linux.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Los-freebsd.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Los-linux.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/getcontext-freebsd.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/getcontext-linux.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/is_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/longjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/offsets.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/siglongjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-freebsd.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-linux.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Los-freebsd.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Los-linux.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lstash_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Ltrace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/is_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/longjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/offsets.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/siglongjmp.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gia64-test-nat.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gia64-test-rbs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gia64-test-readonly.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gia64-test-stack.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gperf-simple.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gperf-trace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-concurrent.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-dyn1.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-exc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-init.cxx delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-nomalloc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig-rt.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lia64-test-nat.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lia64-test-rbs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lia64-test-readonly.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lia64-test-stack.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lperf-simple.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lperf-trace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lrs-race.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-bt.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-concurrent.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-cxx-exceptions.cxx delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-dyn1.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-exc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal-lib.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-init.cxx delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-nocalloc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-nomalloc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig-rt.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-trace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-varargs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Makefile.am delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/crasher.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/flush-cache.S delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/flush-cache.h delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/forker.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-dyn-asm.S delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-dyn1.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-nat-asm.S delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs-asm.S delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs.h delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-readonly-asm.S delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-setjmp.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-sig.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack-asm.S delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack.h delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ident.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/mapper.c delete mode 100755 src/coreclr/src/pal/src/libunwind/tests/perf-startup delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec-utils.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec.c delete mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-check-namespace delete mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind delete mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind-mdi delete mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-ia64-test-dyn1 delete mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-ptrace-mapper delete mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-ptrace-misc delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-async-sig.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-flush-cache.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-init-remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-mem.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-proc-info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-ptrace-misc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-ptrace.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-reg-state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-setjmp.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-static-link-gen.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-static-link-loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-strerror.c diff --git a/src/coreclr/src/pal/src/libunwind/.gitignore b/src/coreclr/src/pal/src/libunwind/.gitignore deleted file mode 100644 index 7b7905f0d59815..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/.gitignore +++ /dev/null @@ -1,79 +0,0 @@ -*.la -*.a -*.o -*.lo -*~ -*.pc - -.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 -include/libunwind.h -include/tdep/libunwind_i.h - -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/Lrs-race -tests/Ltest-varargs -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-reg-state -tests/test-varargs -tests/test-static-link -tests/[GL]test-trace -tests/[GL]perf-trace -tests/Ltest-cxx-exceptions -tests/Ltest-init-local-signal -tests/Ltest-mem-validate -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 -tests/*.log -tests/*.trs diff --git a/src/coreclr/src/pal/src/libunwind/.travis.yml b/src/coreclr/src/pal/src/libunwind/.travis.yml deleted file mode 100644 index 4a74b4a1bcb3ed..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -sudo: required -language: c -compiler: gcc -env: -- TARGET=x86_64-linux-gnu -- TARGET=x86-linux-gnu -- TARGET=arm-linux-gnueabihf -- TARGET=aarch64-linux-gnu -- TARGET=mipsel-unknown-linux-gnu -# Currently experiencing build failures here -#- TARGET=powerpc64-linux-gnu -script: -- ./autogen.sh -- ./configure --target=$TARGET --host=$HOST -- make -j32 -- sudo bash -c 'echo core.%p.%p > /proc/sys/kernel/core_pattern' -- ulimit -c unlimited -- if [ $TARGET == 'x86_64-linux-gnu' ]; then make check -j32; fi diff --git a/src/coreclr/src/pal/src/libunwind/AUTHORS b/src/coreclr/src/pal/src/libunwind/AUTHORS deleted file mode 100644 index 719eee5c85a2f7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -David Mosberger diff --git a/src/coreclr/src/pal/src/libunwind/COPYING b/src/coreclr/src/pal/src/libunwind/COPYING deleted file mode 100644 index 41e7d8a6fdb536..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/COPYING +++ /dev/null @@ -1,20 +0,0 @@ -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. diff --git a/src/coreclr/src/pal/src/libunwind/ChangeLog b/src/coreclr/src/pal/src/libunwind/ChangeLog deleted file mode 100644 index dfa24b957cb223..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/ChangeLog +++ /dev/null @@ -1,55 +0,0 @@ -*********************************************************** - - 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 - - * 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 - - * 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 - - * include/unwind-ia64.h: Include via "unwind.h" to ensure - the file is picked up from same directory. - -2002-01-16 David Mosberger-Tang - - * 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 - - * Version 0.0 released. - -2002-01-11 David Mosberger-Tang - - * ChangeLog created. diff --git a/src/coreclr/src/pal/src/libunwind/LICENSE b/src/coreclr/src/pal/src/libunwind/LICENSE deleted file mode 100644 index c9b44cb8aaebb1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -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. diff --git a/src/coreclr/src/pal/src/libunwind/Makefile.am b/src/coreclr/src/pal/src/libunwind/Makefile.am deleted file mode 100644 index 711d9100c75512..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/Makefile.am +++ /dev/null @@ -1,106 +0,0 @@ -include_HEADERS = include/libunwind-dynamic.h - -if BUILD_PTRACE -include_HEADERS += include/libunwind-ptrace.h -endif BUILD_PTRACE - -if BUILD_COREDUMP -include_HEADERS += include/libunwind-coredump.h -endif BUILD_COREDUMP - -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_TILEGX -include_HEADERS += include/libunwind-tilegx.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 - -if CONFIG_TESTS -SUBDIRS += tests -endif - -if CONFIG_DOCS -SUBDIRS += doc -endif - -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-tilegx/libunwind_i.h \ - include/tdep-tilegx/jmpbuf.h include/tdep-tilegx/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~ - diff --git a/src/coreclr/src/pal/src/libunwind/NEWS b/src/coreclr/src/pal/src/libunwind/NEWS deleted file mode 100644 index ae6cbcfb0b57d5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/NEWS +++ /dev/null @@ -1,247 +0,0 @@ --*-Mode: outline-*- - -* News for v1.3: - -** Iteration of unwind register states support - Doug Moore -** Freebsd/Armv6 support - Konstantin Belousov -** Many, many dwarf bugfixes -** Mips remote unwind support -** aarch64 ptrace support - -* News for v1.2: - -** aarch64 port -** dwarf parsing improvements -** Fast stacktraces for aarch64 & arm -** tilegx port -** powerpc64 port - -* 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 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 - 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. diff --git a/src/coreclr/src/pal/src/libunwind/README b/src/coreclr/src/pal/src/libunwind/README deleted file mode 100644 index 694f600b06dc91..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/README +++ /dev/null @@ -1,207 +0,0 @@ --*- mode: Outline -*- - -[![Build Status](https://travis-ci.org/libunwind/libunwind.svg?branch=master)](https://travis-ci.org/libunwind/libunwind) - -This is version 1.3 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: Works well. - Linux/PARISC: Works well, but C library missing unwind-info. - HP-UX/IA-64: Mostly works but known to have some serious limitations. - MIPS: Newly added. - Linux/AArch64: Works well. - Linux/PPC64: Newly added. - Linux/SuperH: Newly added. - FreeBSD/i386: Works well. - FreeBSD/x86-64: Newly added (FreeBSD architecture is known as amd64). - Linux/Tilegx: Newly added (64-bit mode only). - -* General Build Instructions - -In general, this library can be built and installed with the following -commands: - - $ ./autogen.sh # 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: - - test-ptrace - -** Expected results on x86-64 Linux - -The following tests are expected to fail on x86-64 Linux: - - 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 - -Or interact at the gihub page: - - https://github.com/libunwind/libunwind diff --git a/src/coreclr/src/pal/src/libunwind/TODO b/src/coreclr/src/pal/src/libunwind/TODO deleted file mode 100644 index 8b2e0262b00103..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/TODO +++ /dev/null @@ -1,97 +0,0 @@ -- 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 , 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 diff --git a/src/coreclr/src/pal/src/libunwind/acinclude.m4 b/src/coreclr/src/pal/src/libunwind/acinclude.m4 deleted file mode 100644 index 497f7c2f215253..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/acinclude.m4 +++ /dev/null @@ -1,32 +0,0 @@ -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) -]) diff --git a/src/coreclr/src/pal/src/libunwind/autogen.sh b/src/coreclr/src/pal/src/libunwind/autogen.sh deleted file mode 100755 index aad9de6615c22c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/autogen.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -test -n "$srcdir" || srcdir=`dirname "${BASH_SOURCE[0]}"` -test -n "$srcdir" || srcdir=. -( - cd "$srcdir" && - autoreconf --force -v --install -) || exit -test -n "$NOCONFIGURE" || "$srcdir/configure" "$@" diff --git a/src/coreclr/src/pal/src/libunwind/aux_/config.guess b/src/coreclr/src/pal/src/libunwind/aux_/config.guess deleted file mode 100644 index ed2e03b7f2b96b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/aux_/config.guess +++ /dev/null @@ -1,1321 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. - -timestamp='2002-03-20' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - - -dummy=dummy-$$ -trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int dummy(){}" > $dummy.c ; - for c in cc gcc c89 c99 ; do - ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; - if test $? = 0 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - rm -f $dummy.c $dummy.o $dummy.rel ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - macppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvmeppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mipseb-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sun3:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - cat <$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - eval $set_cc_for_build - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - 2-1307) - UNAME_MACHINE="alphaev68" - ;; - esac - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit 0 ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit 0 ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit 0;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit 0 ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit 0 ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit 0;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit 0 ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit 0 ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit 0 ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit 0 ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy \ - && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit 0 ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit 0 ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit 0 ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit 0 ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit 0 ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit 0 ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit 0 ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit 0 ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit 0 ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit 0 ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit 0 ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo rs6000-ibm-aix3.2.5 - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit 0 ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit 0 ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit 0 ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit 0 ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit 0 ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit 0 ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` - if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi - rm -f $dummy.c $dummy - fi ;; - esac - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo unknown-hitachi-hiuxwe2 - exit 0 ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit 0 ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit 0 ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit 0 ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit 0 ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit 0 ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit 0 ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit 0 ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit 0 ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit 0 ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit 0 ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit 0 ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3D:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - x86:Interix*:3*) - echo i386-pc-interix3 - exit 0 ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i386-pc-interix - exit 0 ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit 0 ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - rm -f $dummy.c - test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 - ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit 0 ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit 0 ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit 0 ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - rm -f $dummy.c - test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit 0 ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit 0 ;; - i*86:*:5:[78]*) - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit 0 ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` - (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit 0 ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit 0 ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit 0 ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit 0 ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit 0 ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit 0 ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit 0 ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit 0 ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit 0 ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit 0 ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit 0 ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit 0 ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit 0 ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} - exit 0 ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit 0 ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit 0 ;; - NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit 0 ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit 0 ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit 0 ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit 0 ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit 0 ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit 0 ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit 0 ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit 0 ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit 0 ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 -rm -f $dummy.c $dummy - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit 0 ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - c34*) - echo c34-convex-bsd - exit 0 ;; - c38*) - echo c38-convex-bsd - exit 0 ;; - c4*) - echo c4-convex-bsd - exit 0 ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/src/coreclr/src/pal/src/libunwind/aux_/config.sub b/src/coreclr/src/pal/src/libunwind/aux_/config.sub deleted file mode 100644 index f3657978c7401e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/aux_/config.sub +++ /dev/null @@ -1,1443 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. - -timestamp='2002-03-07' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit 0;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | c4x | clipper \ - | d10v | d30v | dsp16xx \ - | fr30 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | m32r | m68000 | m68k | m88k | mcore \ - | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el | mips64vr4300 \ - | mips64vr4300el | mips64vr5000 | mips64vr5000el \ - | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ - | mipsisa32 | mipsisa64 \ - | mn10200 | mn10300 \ - | ns16k | ns32k \ - | openrisc | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ - | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armv*-* \ - | avr-* \ - | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c54x-* \ - | clipper-* | cydra-* \ - | d10v-* | d30v-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | m32r-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | mcore-* \ - | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ - | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ - | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ - | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ - | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - crds | unos) - basic_machine=m68k-crds - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - or32 | or32-*) - basic_machine=or32-unknown - os=-coff - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon) - basic_machine=i686-pc - ;; - pentiumii | pentium2) - basic_machine=i686-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3d) - basic_machine=alpha-cray - os=-unicos - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - windows32) - basic_machine=i386-pc - os=-windows32-msvcrt - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh3 | sh4 | sh3eb | sh4eb) - basic_machine=sh-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparc | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - c4x*) - basic_machine=c4x-none - os=-coff - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto*) - os=-nto-qnx - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-ibm) - os=-aix - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -vxsim* | -vxworks*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/src/coreclr/src/pal/src/libunwind/aux_/ltmain.sh b/src/coreclr/src/pal/src/libunwind/aux_/ltmain.sh deleted file mode 100644 index 6fc690018edbbb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/aux_/ltmain.sh +++ /dev/null @@ -1,5107 +0,0 @@ -# ltmain.sh - Provide generalized library-building support services. -# NOTE: Changing this file will not affect anything until you rerun configure. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Check that we have a working $echo. -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell, and then maybe $echo will work. - exec $SHELL "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <&2 - echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 -fi - -# Global variables. -mode=$default_mode -nonopt= -prev= -prevopt= -run= -show="$echo" -show_help= -execute_dlfiles= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" - -# Parse our command line options once, thoroughly. -while test $# -gt 0 -do - arg="$1" - shift - - case $arg in - -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - execute_dlfiles) - execute_dlfiles="$execute_dlfiles $arg" - ;; - *) - eval "$prev=\$arg" - ;; - esac - - prev= - prevopt= - continue - fi - - # Have we seen a non-optional argument yet? - case $arg in - --help) - show_help=yes - ;; - - --version) - echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" - exit 0 - ;; - - --config) - ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 - exit 0 - ;; - - --debug) - echo "$progname: enabling shell trace mode" - set -x - ;; - - --dry-run | -n) - run=: - ;; - - --features) - echo "host: $host" - if test "$build_libtool_libs" = yes; then - echo "enable shared libraries" - else - echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - echo "enable static libraries" - else - echo "disable static libraries" - fi - exit 0 - ;; - - --finish) mode="finish" ;; - - --mode) prevopt="--mode" prev=mode ;; - --mode=*) mode="$optarg" ;; - - --preserve-dup-deps) duplicate_deps="yes" ;; - - --quiet | --silent) - show=: - ;; - - -dlopen) - prevopt="-dlopen" - prev=execute_dlfiles - ;; - - -*) - $echo "$modename: unrecognized option \`$arg'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - - *) - nonopt="$arg" - break - ;; - esac -done - -if test -n "$prevopt"; then - $echo "$modename: option \`$prevopt' requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 -fi - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -if test -z "$show_help"; then - - # Infer the operation mode. - if test -z "$mode"; then - case $nonopt in - *cc | *++ | gcc* | *-gcc* | g++* | xlc*) - mode=link - for arg - do - case $arg in - -c) - mode=compile - break - ;; - esac - done - ;; - *db | *dbx | *strace | *truss) - mode=execute - ;; - *install*|cp|mv) - mode=install - ;; - *rm) - mode=uninstall - ;; - *) - # If we have no mode, but dlfiles were specified, then do execute mode. - test -n "$execute_dlfiles" && mode=execute - - # Just use the default operation mode. - if test -z "$mode"; then - if test -n "$nonopt"; then - $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 - else - $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 - fi - fi - ;; - esac - fi - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - $echo "$modename: unrecognized option \`-dlopen'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$modename --help --mode=$mode' for more information." - - # These modes are in order of execution frequency so that they run quickly. - case $mode in - # libtool compile mode - compile) - modename="$modename: compile" - # Get the compilation command and the source file. - base_compile= - prev= - lastarg= - srcfile="$nonopt" - suppress_output= - - user_target=no - for arg - do - case $prev in - "") ;; - xcompiler) - # Aesthetically quote the previous argument. - prev= - lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - - case $arg in - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - - # Add the previous argument to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - continue - ;; - esac - - # Accept any command-line options. - case $arg in - -o) - if test "$user_target" != "no"; then - $echo "$modename: you cannot specify \`-o' more than once" 1>&2 - exit 1 - fi - user_target=next - ;; - - -static) - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - lastarg="$lastarg $arg" - done - IFS="$save_ifs" - lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` - - # Add the arguments to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - continue - ;; - esac - - case $user_target in - next) - # The next one is the -o target name - user_target=yes - continue - ;; - yes) - # We got the output file - user_target=set - libobj="$arg" - continue - ;; - esac - - # Accept the current argument as the source file. - lastarg="$srcfile" - srcfile="$arg" - - # Aesthetically quote the previous argument. - - # Backslashify any backslashes, double quotes, and dollar signs. - # These are the only characters that are still specially - # interpreted inside of double-quoted scrings. - lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $lastarg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - lastarg="\"$lastarg\"" - ;; - esac - - # Add the previous argument to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - done - - case $user_target in - set) - ;; - no) - # Get the name of the library object. - libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` - ;; - *) - $echo "$modename: you must specify a target with \`-o'" 1>&2 - exit 1 - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - xform='[cCFSfmso]' - case $libobj in - *.ada) xform=ada ;; - *.adb) xform=adb ;; - *.ads) xform=ads ;; - *.asm) xform=asm ;; - *.c++) xform=c++ ;; - *.cc) xform=cc ;; - *.cpp) xform=cpp ;; - *.cxx) xform=cxx ;; - *.f90) xform=f90 ;; - *.for) xform=for ;; - esac - - libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` - - case $libobj in - *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; - *) - $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 - exit 1 - ;; - esac - - if test -z "$base_compile"; then - $echo "$modename: you must specify a compilation command" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $libobj" - else - removelist="$libobj" - fi - - $run $rm $removelist - trap "$run $rm $removelist; exit 1" 1 2 15 - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - removelist="$removelist $output_obj $lockfile" - trap "$run $rm $removelist; exit 1" 1 2 15 - else - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $run ln "$0" "$lockfile" 2>/dev/null; do - $show "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - echo "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - echo $srcfile > "$lockfile" - fi - - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi - - # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test "$pic_mode" != no; then - # All platforms use -DPIC, to notify preprocessed assembler code. - command="$base_compile $srcfile $pic_flag -DPIC" - else - # Don't build PIC code - command="$base_compile $srcfile" - fi - if test "$build_old_libs" = yes; then - lo_libobj="$libobj" - dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$libobj"; then - dir="$objdir" - else - dir="$dir/$objdir" - fi - libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` - - if test -d "$dir"; then - $show "$rm $libobj" - $run $rm $libobj - else - $show "$mkdir $dir" - $run $mkdir $dir - status=$? - if test $status -ne 0 && test ! -d $dir; then - exit $status - fi - fi - fi - if test "$compiler_o_lo" = yes; then - output_obj="$libobj" - command="$command -o $output_obj" - elif test "$compiler_c_o" = yes; then - output_obj="$obj" - command="$command -o $output_obj" - fi - - $run $rm "$output_obj" - $show "$command" - if $run eval "$command"; then : - else - test -n "$output_obj" && $run $rm $removelist - exit 1 - fi - - if test "$need_locks" = warn && - test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then - echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - - # Just move the object if needed, then go on to compile the next one - if test x"$output_obj" != x"$libobj"; then - $show "$mv $output_obj $libobj" - if $run $mv $output_obj $libobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # If we have no pic_flag, then copy the object into place and finish. - if (test -z "$pic_flag" || test "$pic_mode" != default) && - test "$build_old_libs" = yes; then - # Rename the .lo from within objdir to obj - if test -f $obj; then - $show $rm $obj - $run $rm $obj - fi - - $show "$mv $libobj $obj" - if $run $mv $libobj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` - libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` - # Now arrange that obj and lo_libobj become the same file - $show "(cd $xdir && $LN_S $baseobj $libobj)" - if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - $run $rm "$lockfile" - fi - exit 0 - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Allow error messages only from the first compilation. - suppress_output=' >/dev/null 2>&1' - fi - - # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then - # Don't build PIC code - command="$base_compile $srcfile" - else - # All platforms use -DPIC, to notify preprocessed assembler code. - command="$base_compile $srcfile $pic_flag -DPIC" - fi - if test "$compiler_c_o" = yes; then - command="$command -o $obj" - output_obj="$obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - command="$command$suppress_output" - $run $rm "$output_obj" - $show "$command" - if $run eval "$command"; then : - else - $run $rm $removelist - exit 1 - fi - - if test "$need_locks" = warn && - test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then - echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - - # Just move the object if needed - if test x"$output_obj" != x"$obj"; then - $show "$mv $output_obj $obj" - if $run $mv $output_obj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Create an invalid libtool object if no PIC, so that we do not - # accidentally link it into a program. - if test "$build_libtool_libs" != yes; then - $show "echo timestamp > $libobj" - $run eval "echo timestamp > \$libobj" || exit $? - else - # Move the .lo from within objdir - $show "$mv $libobj $lo_libobj" - if $run $mv $libobj $lo_libobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - fi - - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - $run $rm "$lockfile" - fi - - exit 0 - ;; - - # libtool link mode - link | relink) - modename="$modename: link" - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra - # flag for every libtool invokation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args="$nonopt" - compile_command="$nonopt" - finalize_command="$nonopt" - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - inst_prefix_dir= - - avoid_version=no - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - prefer_static_libs=no - preload=no - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -all-static | -static) - if test "X$arg" = "X-all-static"; then - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then - $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - else - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - fi - build_libtool_libs=no - build_old_libs=yes - prefer_static_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test $# -gt 0; do - arg="$1" - shift - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test - ;; - *) qarg=$arg ;; - esac - libtool_args="$libtool_args $qarg" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - compile_command="$compile_command @OUTPUT@" - finalize_command="$finalize_command @OUTPUT@" - ;; - esac - - case $prev in - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - compile_command="$compile_command @SYMFILE@" - finalize_command="$finalize_command @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - else - dlprefiles="$dlprefiles $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - if test ! -f "$arg"; then - $echo "$modename: symbol file \`$arg' does not exist" - exit 1 - fi - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit 1 - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) rpath="$rpath $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) xrpath="$xrpath $arg" ;; - esac - fi - prev= - continue - ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" - prev= - compile_command="$compile_command $wl$qarg" - finalize_command="$finalize_command $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n $prev - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - compile_command="$compile_command $link_static_flag" - finalize_command="$finalize_command $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 - continue - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: more than one -exported-symbols argument is not allowed" - exit 1 - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | no/*-*-nonstopux*) - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - ;; - esac - continue - ;; - - -L*) - dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 - exit 1 - fi - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "*) ;; - *) - deplibs="$deplibs -L$dir" - lib_search_path="$lib_search_path $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$dir:"*) ;; - *) dllsearchpath="$dllsearchpath:$dir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-pw32* | *-*-beos*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-mingw* | *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - deplibs="$deplibs $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # The PATH hackery in wrapper scripts is required on Windows - # in order for the loader to find any dlls it needs. - $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 - $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -o) prev=output ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit 1 - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - continue - ;; - - -static) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Wl,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $wl$flag" - linker_flags="$linker_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - # Some other compiler flag. - -* | +*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - - *.lo | *.$objext) - # A library or standard object. - if test "$prev" = dlfiles; then - # This file was specified with -dlopen. - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $arg" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` - prev= - else - case $arg in - *.lo) libobjs="$libobjs $arg" ;; - *) objs="$objs $arg" ;; - esac - fi - ;; - - *.$libext) - # An archive. - deplibs="$deplibs $arg" - old_deplibs="$old_deplibs $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - dlfiles="$dlfiles $arg" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - dlprefiles="$dlprefiles $arg" - prev= - else - deplibs="$deplibs $arg" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - done # argument parsing loop - - if test -n "$prev"; then - $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - - # calculate the name of the file, without its directory - outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - # Create the object directory. - if test ! -d $output_objdir; then - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - status=$? - if test $status -ne 0 && test ! -d $output_objdir; then - exit $status - fi - fi - - # Determine the type of output - case $output in - "") - $echo "$modename: you must specify an output file" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if test "X$duplicate_deps" = "Xyes" ; then - case "$libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - libs="$libs $deplib" - done - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - case $linkmode in - lib) - passes="conv link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 - exit 1 - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - for pass in $passes; do - if test $linkmode = prog; then - # Determine which files to process - case $pass in - dlopen) - libs="$dlfiles" - save_deplibs="$deplibs" # Collect dlpreopened libraries - deplibs= - ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - for deplib in $libs; do - lib= - found=no - case $deplib in - -l*) - if test $linkmode = oldlib && test $linkmode = obj; then - $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 - continue - fi - if test $pass = conv; then - deplibs="$deplib $deplibs" - continue - fi - name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` - for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do - # Search the libtool library - lib="$searchdir/lib${name}.la" - if test -f "$lib"; then - found=yes - break - fi - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - ;; # -l - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test $pass = conv && continue - newdependency_libs="$deplib $newdependency_libs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - prog) - if test $pass = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test $pass = scan; then - deplibs="$deplib $deplibs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - ;; - *) - $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test $pass = link; then - dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) lib="$deplib" ;; - *.$libext) - if test $pass = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - if test "$deplibs_check_method" != pass_all; then - echo - echo "*** Warning: Trying to link with static lib archive $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because the file extensions .$libext of this argument makes me believe" - echo "*** that it is just a static archive that I should not used here." - else - echo - echo "*** Warning: Linking the shared library $output against the" - echo "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - continue - ;; - prog) - if test $pass != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - newdlprefiles="$newdlprefiles $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - newdlfiles="$newdlfiles $deplib" - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - if test $found = yes || test -f "$lib"; then : - else - $echo "$modename: cannot find the library \`$lib'" 1>&2 - exit 1 - fi - - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - # If the library was installed with an old release of libtool, - # it will not redefine variable installed. - installed=yes - - # Read the .la file - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test $linkmode = oldlib && test $linkmode = obj; }; then - # Add dl[pre]opened files of deplib - test -n "$dlopen" && dlfiles="$dlfiles $dlopen" - test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" - fi - - if test $pass = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit 1 - fi - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $ladir/$objdir/$old_library" - old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - elif test $linkmode != prog && test $linkmode != lib; then - $echo "$modename: \`$lib' is not a convenience library" 1>&2 - exit 1 - fi - continue - fi # $pass = conv - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - if test -z "$linklib"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit 1 - fi - - # This library was specified with -dlopen. - if test $pass = dlopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 - exit 1 - fi - if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. - dlprefiles="$dlprefiles $lib" - else - newdlfiles="$newdlfiles $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - abs_ladir="$ladir" - fi - ;; - esac - laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - $echo "$modename: warning: library \`$lib' was moved." 1>&2 - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$libdir" - absdir="$libdir" - fi - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - fi # $installed = yes - name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - - # This library was specified with -dlpreopen. - if test $pass = dlpreopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 - exit 1 - fi - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - newdlprefiles="$newdlprefiles $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - newdlprefiles="$newdlprefiles $dir/$dlname" - else - newdlprefiles="$newdlprefiles $dir/$linklib" - fi - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test $linkmode = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" - fi - continue - fi - - if test $linkmode = prog && test $pass != link; then - newlib_search_path="$newlib_search_path $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test - esac - # Need to link against all dependency_libs? - if test $linkalldeplibs = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - link_static=no # Whether the deplib will be linked statically - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - # Link against this shared library - - if test "$linkmode,$pass" = "prog,link" || - { test $linkmode = lib && test $hardcode_into_libs = yes; }; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - if test $linkmode = prog; then - # We need to hardcode the library path - if test -n "$shlibpath_var"; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath " in - *" $dir "*) ;; - *" $absdir "*) ;; - *) temp_rpath="$temp_rpath $dir" ;; - esac - fi - fi - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - - if test "$installed" = no; then - notinst_deplibs="$notinst_deplibs $lib" - need_relink=yes - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - realname="$2" - shift; shift - libname=`eval \\$echo \"$libname_spec\"` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin*) - major=`expr $current - $age` - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - soname=`echo $soroot | ${SED} -e 's/^.*\///'` - newlib="libimp-`echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - $show "extracting exported symbol list from \`$soname'" - save_ifs="$IFS"; IFS='~' - eval cmds=\"$extract_expsyms_cmds\" - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - $show "generating import library for \`$soname'" - save_ifs="$IFS"; IFS='~' - eval cmds=\"$old_archive_from_expsyms_cmds\" - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n $old_archive_from_expsyms_cmds - - if test $linkmode = prog || test "$mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case "$libdir" in - [\/]*) - add_dir="-L$inst_prefix_dir$libdir $add_dir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - $echo "$modename: configuration error: unsupported hardcode properties" - exit 1 - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; - esac - fi - if test $linkmode = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && \ - test "$hardcode_minus_L" != yes && \ - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - fi - fi - fi - - if test $linkmode = prog || test "$mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - add="-l$name" - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case "$libdir" in - [\/]*) - add_dir="-L$inst_prefix_dir$libdir $add_dir" - ;; - esac - fi - add="-l$name" - fi - - if test $linkmode = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test $linkmode = prog; then - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - - # Try to link the static library - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - echo - echo "*** Warning: This system can not link to static lib archive $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - echo "*** But as you try to build a module library, libtool will still create " - echo "*** a static module, that should work as long as the dlopening application" - echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - convenience="$convenience $dir/$old_library" - old_convenience="$old_convenience $dir/$old_library" - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test $linkmode = lib; then - if test -n "$dependency_libs" && - { test $hardcode_into_libs != yes || test $build_old_libs = yes || - test $link_static = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - *) temp_deplibs="$temp_deplibs $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - newlib_search_path="$newlib_search_path $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - - if test $link_all_deplibs != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - case $deplib in - -L*) path="$deplib" ;; - *.la) - dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$deplib" && dir="." - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - fi - ;; - esac - if grep "^installed=no" $deplib > /dev/null; then - path="-L$absdir/$objdir" - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit 1 - fi - if test "$absdir" != "$libdir"; then - $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 - fi - path="-L$absdir" - fi - ;; - *) continue ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$deplibs $path" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test $pass = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test $pass != dlopen; then - test $pass != scan && dependency_libs="$newdependency_libs" - if test $pass != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - *) - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - if test "$pass" = "conv" && - { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then - libs="$deplibs" # reset libs - deplibs= - fi - done # for pass - if test $linkmode = prog; then - dlfiles="$newdlfiles" - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 - fi - - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 - fi - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - objs="$objs$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - eval libname=\"$libname_spec\" - ;; - *) - if test "$module" = no; then - $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - eval libname=\"$libname_spec\" - else - libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 - exit 1 - else - echo - echo "*** Warning: Linking the shared library $output against the non-libtool" - echo "*** objects $objs is not portable!" - libobjs="$libobjs $objs" - fi - fi - - if test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 - fi - - set dummy $rpath - if test $# -gt 2; then - $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 - fi - install_libdir="$2" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - libext=al - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 - fi - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - IFS="$save_ifs" - - if test -n "$8"; then - $echo "$modename: too many parameters to \`-version-info'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - current="$2" - revision="$3" - age="$4" - - # Check that each of the things are valid numbers. - case $current in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - case $revision in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - case $age in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - if test $age -gt $current; then - $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - minor_current=`expr $current + 1` - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current"; - ;; - - irix | nonstopux) - major=`expr $current - $age + 1` - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test $loop != 0; do - iface=`expr $revision - $loop` - loop=`expr $loop - 1` - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - ;; - - osf) - major=.`expr $current - $age` - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test $loop != 0; do - iface=`expr $current - $loop` - loop=`expr $loop - 1` - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - verstring="$verstring:${current}.0" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - major=`expr $current - $age` - versuffix="-$major" - ;; - - *) - $echo "$modename: unknown library version type \`$version_type'" 1>&2 - echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - verstring="0.0" - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring="" - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - fi - - if test "$mode" != relink; then - # Remove our outputs. - $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" - $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - oldlibs="$oldlibs $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - for path in $notinst_path; do - lib_search_path=`echo "$lib_search_path " | ${SED} -e 's% $path % %g'` - deplibs=`echo "$deplibs " | ${SED} -e 's% -L$path % %g'` - dependency_libs=`echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` - done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - if test $hardcode_into_libs != yes || test $build_old_libs = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) dlfiles="$dlfiles $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) dlprefiles="$dlprefiles $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - deplibs="$deplibs -framework System" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd*) - # Do not include libc due to us having libc/libc_r. - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test $build_libtool_need_lc = "yes"; then - deplibs="$deplibs -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behaviour. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $rm conftest.c - cat > conftest.c </dev/null` - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null \ - | grep " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ - | ${SED} 10q \ - | egrep "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - echo "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - echo "*** with $libname but no candidates were found. (...for file magic test)" - else - echo "*** with $libname and none of the candidates passed a file format test" - echo "*** using a file magic. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - for a_deplib in $deplibs; do - name="`expr $a_deplib : '-l\(.*\)'`" - # If $name is empty we are operating on a -L argument. - if test -n "$name" && test "$name" != "0"; then - libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check below in file_magic test - if eval echo \"$potent_lib\" 2>/dev/null \ - | ${SED} 10q \ - | egrep "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - echo "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - echo "*** with $libname but no candidates were found. (...for regex pattern test)" - else - echo "*** with $libname and none of the candidates passed a file format test" - echo "*** using a regex pattern. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ - -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | - grep . >/dev/null; then - echo - if test "X$deplibs_check_method" = "Xnone"; then - echo "*** Warning: inter-library dependencies are not supported in this platform." - else - echo "*** Warning: inter-library dependencies are not known to be supported." - fi - echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - fi - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - echo - echo "*** Warning: libtool could not satisfy all declared inter-library" - echo "*** dependencies of module $libname. Therefore, libtool will create" - echo "*** a static module, that should work as long as the dlopening" - echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - echo "*** The inter-library dependencies that have been dropped here will be" - echo "*** automatically added whenever a program is linked with this library" - echo "*** or is declared to -dlopen it." - - if test $allow_undefined = no; then - echo - echo "*** Since this library must not contain undefined symbols," - echo "*** because either the platform does not support them or" - echo "*** it was explicitly requested with -no-undefined," - echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test $hardcode_into_libs = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval library_names=\"$library_names_spec\" - set dummy $library_names - realname="$2" - shift; shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - test -z "$dlname" && dlname=$soname - - lib="$output_objdir/$realname" - for link - do - linknames="$linknames $link" - done - - # Ensure that we have .o objects for linkers which dislike .lo - # (e.g. aix) in case we are running --disable-static - for obj in $libobjs; do - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` - if test ! -f $xdir/$oldobj; then - $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" - $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? - fi - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - eval cmds=\"$export_symbols_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - if test -n "$export_symbols_regex"; then - $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" - $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - $show "$mv \"${export_symbols}T\" \"$export_symbols\"" - $run eval '$mv "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' - fi - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${outputname}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - for xlib in $convenience; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` - done - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval cmds=\"$archive_expsym_cmds\" - else - save_deplibs="$deplibs" - for conv in $convenience; do - tmp_deplibs= - for test_deplib in $deplibs; do - if test "$test_deplib" != "$conv"; then - tmp_deplibs="$tmp_deplibs $test_deplib" - fi - done - deplibs="$tmp_deplibs" - done - eval cmds=\"$archive_cmds\" - deplibs="$save_deplibs" - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? - exit 0 - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 - fi - - case $output in - *.lo) - if test -n "$objs$old_deplibs"; then - $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 - exit 1 - fi - libobj="$output" - obj=`$echo "X$output" | $Xsed -e "$lo2o"` - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $run $rm $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${obj}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - for xlib in $convenience; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` - done - fi - fi - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - eval cmds=\"$reload_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit 0 - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - $show "echo timestamp > $libobj" - $run eval "echo timestamp > $libobj" || exit $? - exit 0 - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - eval cmds=\"$reload_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - else - # Just create a symlink. - $show $rm $libobj - $run $rm $libobj - xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$libobj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` - oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` - $show "(cd $xdir && $LN_S $oldobj $baseobj)" - $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? - fi - - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit 0 - ;; - - prog) - case $host in - *cygwin*) output=`echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; - esac - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 - fi - - if test "$preload" = yes; then - if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && - test "$dlopen_self_static" = unknown; then - $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." - fi - fi - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - case $host in - *darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - compile_command="$compile_command ${wl}-bind_at_load" - finalize_command="$finalize_command ${wl}-bind_at_load" - ;; - esac - ;; - esac - - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$libdir:"*) ;; - *) dllsearchpath="$dllsearchpath:$libdir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - fi - - dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - dlsyms="${outputname}S.c" - else - $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 - fi - fi - - if test -n "$dlsyms"; then - case $dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${outputname}.nm" - - $show "$rm $nlist ${nlist}S ${nlist}T" - $run $rm "$nlist" "${nlist}S" "${nlist}T" - - # Parse the name list into a source file. - $show "creating $output_objdir/$dlsyms" - - test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ -/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ -/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* Prevent the only kind of declaration conflicts we can make. */ -#define lt_preloaded_symbols some_other_symbol - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - $show "generating symbol list for \`$output'" - - test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - for arg in $progfiles; do - $show "extracting global C symbols from \`$arg'" - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - if test -n "$export_symbols_regex"; then - $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$output.exp" - $run $rm $export_symbols - $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - else - $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' - $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' - $run eval 'mv "$nlist"T "$nlist"' - fi - fi - - for arg in $dlprefiles; do - $show "extracting global C symbols from \`$arg'" - name=`echo "$arg" | ${SED} -e 's%^.*/%%'` - $run eval 'echo ": $name " >> "$nlist"' - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -z "$run"; then - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $mv "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if grep -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - grep -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' - else - echo '/* NONE */' >> "$output_objdir/$dlsyms" - fi - - $echo >> "$output_objdir/$dlsyms" "\ - -#undef lt_preloaded_symbols - -#if defined (__STDC__) && __STDC__ -# define lt_ptr void * -#else -# define lt_ptr char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr address; -} -lt_preloaded_symbols[] = -{\ -" - - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" - - $echo >> "$output_objdir/$dlsyms" "\ - {0, (lt_ptr) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - fi - - pic_flag_for_symtable= - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; - esac;; - *-*-hpux*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DPIC";; - esac - esac - - # Now compile the dynamic symbol file. - $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" - $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? - - # Clean up the generated files. - $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" - $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" - - # Transform the symbol file into the correct name. - compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - ;; - *) - $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 - exit 1 - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` - fi - - if test $need_relink = no || test "$build_libtool_libs" != yes; then - # Replace the output file specification. - compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - $show "$link_command" - $run eval "$link_command" - status=$? - - # Delete the generated files. - if test -n "$dlsyms"; then - $show "$rm $output_objdir/${outputname}S.${objext}" - $run $rm "$output_objdir/${outputname}S.${objext}" - fi - - exit $status - fi - - if test -n "$shlibpath_var"; then - # We should set the shlibpath_var - rpath= - for dir in $temp_rpath; do - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) - # Absolute path. - rpath="$rpath$dir:" - ;; - *) - # Relative path: add a thisdir entry. - rpath="$rpath\$thisdir/$dir:" - ;; - esac - done - temp_rpath="$rpath" - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $run $rm $output - # Link the executable and exit - $show "$link_command" - $run eval "$link_command" || exit $? - exit 0 - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 - $echo "$modename: \`$output' will be relinked during installation" 1>&2 - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname - - $show "$link_command" - $run eval "$link_command" || exit $? - - # Now create the wrapper script. - $show "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - fi - - # Quote $echo for shipping. - if test "X$echo" = "X$SHELL $0 --fallback-echo"; then - case $0 in - [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; - *) qecho="$SHELL `pwd`/$0 --fallback-echo";; - esac - qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` - else - qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` - fi - - # Only actually do things if our run command is non-null. - if test -z "$run"; then - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) output=`echo $output|${SED} 's,.exe$,,'` ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) exeext=.exe ;; - *) exeext= ;; - esac - $rm $output - trap "$rm $output; exit 1" 1 2 15 - - $echo > $output "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='$sed_quote_subst' - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variable: - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$echo are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - echo=\"$qecho\" - file=\"\$0\" - # Make sure echo works. - if test \"X\$1\" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then - # Yippee, \$echo works! - : - else - # Restart under the correct shell, and then maybe \$echo will work. - exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} - fi - fi\ -" - $echo >> $output "\ - - # Find the directory that this script lives in. - thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` - done - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - echo >> $output "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || \\ - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $mkdir \"\$progdir\" - else - $rm \"\$progdir/\$file\" - fi" - - echo >> $output "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $echo \"\$relink_command_output\" >&2 - $rm \"\$progdir/\$file\" - exit 1 - fi - fi - - $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $rm \"\$progdir/\$program\"; - $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $rm \"\$progdir/\$file\" - fi" - else - echo >> $output "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - echo >> $output "\ - - if test -f \"\$progdir/\$program\"; then" - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $echo >> $output "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 ${SED} - $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` - - export $shlibpath_var -" - fi - - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $echo >> $output "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - $echo >> $output "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. -" - case $host in - # win32 systems need to use the prog path for dll - # lookup to work - *-*-cygwin* | *-*-pw32*) - $echo >> $output "\ - exec \$progdir/\$program \${1+\"\$@\"} -" - ;; - - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2*) - $echo >> $output "\ - exec \$progdir\\\\\$program \${1+\"\$@\"} -" - ;; - - *) - $echo >> $output "\ - # Export the path to the program. - PATH=\"\$progdir:\$PATH\" - export PATH - - exec \$program \${1+\"\$@\"} -" - ;; - esac - $echo >> $output "\ - \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" - exit 1 - fi - else - # The program doesn't exist. - \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 - \$echo \"This script is just a wrapper for \$program.\" 1>&2 - echo \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" - chmod +x $output - fi - exit 0 - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - # Add in members from convenience archives. - for xlib in $addlibs; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` - done - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - eval cmds=\"$old_archive_from_new_cmds\" - else - # Ensure that we have .o objects in place in case we decided - # not to build a shared library, and have fallen back to building - # static libs even though --disable-static was passed! - for oldobj in $oldobjs; do - if test ! -f $oldobj; then - xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$oldobj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` - obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` - $show "(cd $xdir && ${LN_S} $obj $baseobj)" - $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? - fi - done - - eval cmds=\"$old_archive_cmds\" - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$generated"; then - $show "${rm}r$generated" - $run ${rm}r$generated - fi - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - $show "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - - # Only create the output if not a dry run. - if test -z "$run"; then - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdependency_libs="$newdependency_libs $libdir/$name" - ;; - *) newdependency_libs="$newdependency_libs $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - for lib in $dlfiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdlfiles="$newdlfiles $libdir/$name" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdlprefiles="$newdlprefiles $libdir/$name" - done - dlprefiles="$newdlprefiles" - fi - $rm $output - # place dlname in correct position for cygwin - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; - esac - $echo > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test $need_relink = yes; then - $echo >> $output "\ -relink_command=\"$relink_command\"" - fi - done - fi - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" - $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? - ;; - esac - exit 0 - ;; - - # libtool install mode - install) - modename="$modename: install" - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then - # Aesthetically quote it. - arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$arg " - arg="$1" - shift - else - install_prog= - arg="$nonopt" - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog$arg" - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - for arg - do - if test -n "$dest"; then - files="$files $dest" - dest="$arg" - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) prev="-f" ;; - -g) prev="-g" ;; - -m) prev="-m" ;; - -o) prev="-o" ;; - -s) - stripme=" -s" - continue - ;; - -*) ;; - - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - prev= - else - dest="$arg" - continue - fi - ;; - esac - - # Aesthetically quote the argument. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog $arg" - done - - if test -z "$install_prog"; then - $echo "$modename: you must specify an install program" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test -n "$prev"; then - $echo "$modename: the \`$prev' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test -z "$files"; then - if test -z "$dest"; then - $echo "$modename: no file or destination specified" 1>&2 - else - $echo "$modename: you must specify a destination" 1>&2 - fi - $echo "$help" 1>&2 - exit 1 - fi - - # Strip any trailing slash from the destination. - dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` - test "X$destdir" = "X$dest" && destdir=. - destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` - - # Not a directory, so check to see that there is only one file specified. - set dummy $files - if test $# -gt 2; then - $echo "$modename: \`$dest' is not a directory" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - staticlibs="$staticlibs $file" - ;; - - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - library_names= - old_library= - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; - esac - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ - test "X$dir" = "X$file/" && dir= - dir="$dir$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$echo "$destdir" | sed "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - if test "$inst_prefix_dir" = "$destdir"; then - $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 - exit 1 - fi - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%%"` - fi - - $echo "$modename: warning: relinking \`$file'" 1>&2 - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - exit 1 - fi - fi - - # See the names of the shared library. - set dummy $library_names - if test -n "$2"; then - realname="$2" - shift - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - $show "$install_prog $dir/$srcname $destdir/$realname" - $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? - if test -n "$stripme" && test -n "$striplib"; then - $show "$striplib $destdir/$realname" - $run eval "$striplib $destdir/$realname" || exit $? - fi - - if test $# -gt 0; then - # Delete the old symlinks, and create new ones. - for linkname - do - if test "$linkname" != "$realname"; then - $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" - fi - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - eval cmds=\"$postinstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Install the pseudo-library for information purposes. - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - instname="$dir/$name"i - $show "$install_prog $instname $destdir/$name" - $run eval "$install_prog $instname $destdir/$name" || exit $? - - # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - esac - - # Install the libtool object if requested. - if test -n "$destfile"; then - $show "$install_prog $file $destfile" - $run eval "$install_prog $file $destfile" || exit $? - fi - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` - - $show "$install_prog $staticobj $staticdest" - $run eval "$install_prog \$staticobj \$staticdest" || exit $? - fi - exit 0 - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin*|*mingw*) - wrapper=`echo $file | ${SED} -e 's,.exe$,,'` - ;; - *) - wrapper=$file - ;; - esac - if (${SED} -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then - notinst_deplibs= - relink_command= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $wrapper ;; - *) . ./$wrapper ;; - esac - - # Check the variables that should have been set. - if test -z "$notinst_deplibs"; then - $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 - exit 1 - fi - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - # If there is no directory component, then add one. - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - fi - libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 - finalize=no - fi - done - - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $wrapper ;; - *) . ./$wrapper ;; - esac - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - if test "$finalize" = yes && test -z "$run"; then - tmpdir="/tmp" - test -n "$TMPDIR" && tmpdir="$TMPDIR" - tmpdir="$tmpdir/libtool-$$" - if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : - else - $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 - continue - fi - file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` - - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - ${rm}r "$tmpdir" - continue - fi - file="$outputname" - else - $echo "$modename: warning: cannot relink \`$file'" 1>&2 - fi - else - # Install the binary that we compiled earlier. - file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyways - case $install_prog,$host in - /usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - destfile=`echo $destfile | ${SED} -e 's,.exe$,,'` - ;; - esac - ;; - esac - $show "$install_prog$stripme $file $destfile" - $run eval "$install_prog\$stripme \$file \$destfile" || exit $? - test -n "$outputname" && ${rm}r "$tmpdir" - ;; - esac - done - - for file in $staticlibs; do - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - $show "$install_prog $file $oldlib" - $run eval "$install_prog \$file \$oldlib" || exit $? - - if test -n "$stripme" && test -n "$striplib"; then - $show "$old_striplib $oldlib" - $run eval "$old_striplib $oldlib" || exit $? - fi - - # Do each command in the postinstall commands. - eval cmds=\"$old_postinstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$future_libdirs"; then - $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 - fi - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - test -n "$run" && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $0 --finish$current_libdirs' - else - exit 0 - fi - ;; - - # libtool finish mode - finish) - modename="$modename: finish" - libdirs="$nonopt" - admincmds= - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done - - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - eval cmds=\"$finish_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || admincmds="$admincmds - $cmd" - done - IFS="$save_ifs" - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $run eval "$cmds" || admincmds="$admincmds - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - test "$show" = ":" && exit 0 - - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - echo " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - echo " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - echo " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - echo - echo "See any operating system documentation about shared libraries for" - echo "more information, such as the ld(1) and ld.so(8) manual pages." - echo "----------------------------------------------------------------------" - exit 0 - ;; - - # libtool execute mode - execute) - modename="$modename: execute" - - # The first argument is the command name. - cmd="$nonopt" - if test -z "$cmd"; then - $echo "$modename: you must specify a COMMAND" 1>&2 - $echo "$help" - exit 1 - fi - - # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do - if test ! -f "$file"; then - $echo "$modename: \`$file' is not a file" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - dir= - case $file in - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Read the libtool library. - dlname= - library_names= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" - continue - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - - if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" - else - $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 - exit 1 - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - ;; - - *) - $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -*) ;; - *) - # Do a test to see if this is really a libtool program. - if (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` - args="$args \"$file\"" - done - - if test -z "$run"; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved enviroment variables - if test "${save_LC_ALL+set}" = set; then - LC_ALL="$save_LC_ALL"; export LC_ALL - fi - if test "${save_LANG+set}" = set; then - LANG="$save_LANG"; export LANG - fi - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" - fi - $echo "$cmd$args" - exit 0 - fi - ;; - - # libtool clean and uninstall mode - clean | uninstall) - modename="$modename: $mode" - rm="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) rm="$rm $arg"; rmforce=yes ;; - -*) rm="$rm $arg" ;; - *) files="$files $arg" ;; - esac - done - - if test -z "$rm"; then - $echo "$modename: you must specify an RM program" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - rmdirs= - - for file in $files; do - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$file"; then - dir=. - objdir="$objdir" - else - objdir="$dir/$objdir" - fi - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - test $mode = uninstall && objdir="$dir" - - # Remember objdir for removal later, being careful to avoid duplicates - if test $mode = clean; then - case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if (test -L "$file") >/dev/null 2>&1 \ - || (test -h "$file") >/dev/null 2>&1 \ - || test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - . $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" - done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" - test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - - if test $mode = uninstall; then - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - eval cmds=\"$postuninstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - if test $? != 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - eval cmds=\"$old_postuninstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - if test $? != 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - # FIXME: should reinstall the best remaining shared library. - fi - fi - ;; - - *.lo) - if test "$build_old_libs" = yes; then - oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` - rmfiles="$rmfiles $dir/$oldobj" - fi - ;; - - *) - # Do a test to see if this is a libtool program. - if test $mode = clean && - (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - relink_command= - . $dir/$file - - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" - fi - fi - ;; - esac - $show "$rm $rmfiles" - $run $rm $rmfiles || exit_status=1 - done - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - $show "rmdir $dir" - $run rmdir $dir >/dev/null 2>&1 - fi - done - - exit $exit_status - ;; - - "") - $echo "$modename: you must specify a MODE" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 - ;; - esac - - if test -z "$exec_cmd"; then - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 - fi -fi # test -z "$show_help" - -if test -n "$exec_cmd"; then - eval exec $exec_cmd - exit 1 -fi - -# We need to display help for each of the modes. -case $mode in -"") $echo \ -"Usage: $modename [OPTION]... [MODE-ARG]... - -Provide generalized library-building support services. - - --config show all configuration variables - --debug enable verbose shell tracing --n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --finish same as \`--mode=finish' - --help display this help message and exit - --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] - --quiet same as \`--silent' - --silent don't print informational messages - --version print version information - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for -a more detailed description of MODE." - exit 0 - ;; - -clean) - $echo \ -"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - -compile) - $echo \ -"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -prefer-pic try to building PIC objects only - -prefer-non-pic try to building non-PIC objects only - -static always build a \`.o' file suitable for static linking - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - -execute) - $echo \ -"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - -finish) - $echo \ -"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - -install) - $echo \ -"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - -link) - $echo \ -"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -static do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - -uninstall) - $echo \ -"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - -*) - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; -esac - -echo -$echo "Try \`$modename --help' for more information about other modes." - -exit 0 - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/src/coreclr/src/pal/src/libunwind/configure.ac b/src/coreclr/src/pal/src/libunwind/configure.ac deleted file mode 100644 index 0c5125971f7c6c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/configure.ac +++ /dev/null @@ -1,445 +0,0 @@ -define(pkg_major, 1) -define(pkg_minor, 3) -define(pkg_extra, -rc1) -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 -m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) -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 - -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 ]) -AC_CHECK_TYPES([struct elf_prstatus, struct prstatus], [], [], -[$ac_includes_default -#if HAVE_SYS_PROCFS_H -# include -#endif -]) - -AC_CHECK_DECLS([PTRACE_POKEUSER, PTRACE_POKEDATA, PTRACE_SETREGSET, -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 -#endif -#include -]) - -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], - [aarch64*],[$2=aarch64], - [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], - [tile*],[$2=tilegx], - [$2=$1]) -]) dnl SET_ARCH - -SET_ARCH([$build_cpu],[build_arch]) -SET_ARCH([$host_cpu],[host_arch]) -SET_ARCH([$target_cpu],[target_arch]) - -# Check for Android -AC_MSG_CHECKING([for Android]) -android="no" -case "$host_os" in - *android*) - android="yes" - AC_MSG_RESULT([yes]) - ;; - *) - AC_MSG_RESULT([no]) - ;; -esac - -AC_ARG_ENABLE(coredump, - AS_HELP_STRING([--enable-coredump],[building libunwind-coredump library]),, - [AS_CASE([$host_arch], [aarch64*|arm*|mips*|sh*|x86*|tile*], [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_ARG_ENABLE(documentation, - AS_HELP_STRING([--disable-documentation],[Disable generating the man pages]),, - [enable_documentation=yes]) - -AC_ARG_ENABLE(tests, - AS_HELP_STRING([--disable-tests],[Disable tests build]),, - [enable_tests=yes]) - -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(NO_PTRACE_TEST, test x$build_arch != x$host_arch) -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(ARCH_TILEGX, test x$target_arch = xtilegx) -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|tilegx) 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;; - tile*) 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;; - (aarch64) 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) - -AC_MSG_CHECKING([whether to support UNW_CACHE_PER_THREAD]) -AC_ARG_ENABLE([per-thread-cache], -AS_HELP_STRING([--enable-per-thread-cache], [build with support for UNW_CACHE_PER_THREAD (which imposes a hight TLS memory usage) (default: disabled)])) -AC_MSG_RESULT([$enable_per_thread_cache]) -AS_IF([test x$enable_per_thread_cache = xyes], [ - LIBUNWIND___THREAD - AS_IF([test x$libc_cv_gcc___thread = xno], [ - AC_MSG_FAILURE([UNW_CACHE_PER_THREAD requires __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 -a x$android != xyes; then - LIBCRTS="-lgcc_s" -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" -case "$ac_cv_search_backtrace" in - -l*) BACKTRACELIB=$ac_cv_search_backtrace;; - *) BACKTRACELIB="";; -esac - - -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_SUBST(BACKTRACELIB) - -AC_PATH_PROG([LATEX2MAN],[latex2man]) -if test "x$LATEX2MAN" = "x"; then - AC_MSG_WARN([latex2man not found. Install latex2man. Disabling docs.]) - enable_documentation="no"; -fi - -AM_CONDITIONAL([CONFIG_DOCS], [test x$enable_documentation = xyes]) -if test "x$enable_documentation" = "xyes"; then - AC_CONFIG_FILES(doc/Makefile doc/common.tex) -fi - -AM_CONDITIONAL([CONFIG_TESTS], [test x$enable_tests = xyes]) -if test "x$enable_tests" = "xyes"; then - AC_CONFIG_FILES(tests/Makefile tests/check-namespace.sh) -fi - -AC_CONFIG_FILES(Makefile src/Makefile - 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 diff --git a/src/coreclr/src/pal/src/libunwind/doc/Makefile.am b/src/coreclr/src/pal/src/libunwind/doc/Makefile.am deleted file mode 100644 index bfe46691245e1f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/Makefile.am +++ /dev/null @@ -1,80 +0,0 @@ -# man pages that go into section 3: -man3_MANS = libunwind.man libunwind-dynamic.man libunwind-ia64.man \ - libunwind-ptrace.man libunwind-setjmp.man \ - unw_apply_reg_state.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_init_local2.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_reg_states_iterate.man \ - unw_set_caching_policy.man \ - unw_set_cache_size.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_apply_reg_state.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_reg_states_iterate.tex \ - unw_set_cache_size.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 diff --git a/src/coreclr/src/pal/src/libunwind/doc/NOTES b/src/coreclr/src/pal/src/libunwind/doc/NOTES deleted file mode 100644 index 3f3caa95bb5d6a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/NOTES +++ /dev/null @@ -1,127 +0,0 @@ -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 . For example, to get the IA-64-specific register -names, an application would do: - - #include - -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 , 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 , 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 - and bar.c might include 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 - diff --git a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.man b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.man deleted file mode 100644 index a420a6deaf3e09..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.man +++ /dev/null @@ -1,66 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.tex b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.tex deleted file mode 100644 index ca5a12a76eede5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.tex +++ /dev/null @@ -1,46 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.man b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.man deleted file mode 100644 index 107e5fd0e18d8c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.man +++ /dev/null @@ -1,68 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.tex b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.tex deleted file mode 100644 index ab23b5c6213634..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.tex +++ /dev/null @@ -1,47 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/common.tex.in b/src/coreclr/src/pal/src/libunwind/doc/common.tex.in deleted file mode 100644 index 91c96a9df48d60..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/common.tex.in +++ /dev/null @@ -1,11 +0,0 @@ -\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 diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.man b/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.man deleted file mode 100644 index 7c7507cb1089da..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.man +++ /dev/null @@ -1,538 +0,0 @@ -'\" 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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.tex b/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.tex deleted file mode 100644 index 21e895a34f30ca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.tex +++ /dev/null @@ -1,401 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.man b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.man deleted file mode 100644 index 06b141eb3e2b70..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.man +++ /dev/null @@ -1,314 +0,0 @@ -'\" 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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.tex b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.tex deleted file mode 100644 index c08946dc4b327d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.tex +++ /dev/null @@ -1,216 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.man b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.man deleted file mode 100644 index 985fcae275333c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.man +++ /dev/null @@ -1,220 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.tex b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.tex deleted file mode 100644 index fe074d8619174a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.tex +++ /dev/null @@ -1,134 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.man b/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.man deleted file mode 100644 index 1faa38e475ddba..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.man +++ /dev/null @@ -1,132 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.tex b/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.tex deleted file mode 100644 index 17ce073186a6c3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.tex +++ /dev/null @@ -1,87 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind.man b/src/coreclr/src/pal/src/libunwind/doc/libunwind.man deleted file mode 100644 index 02ab6b89374818..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind.man +++ /dev/null @@ -1,508 +0,0 @@ -'\" t -.\" Manual page created with latex2man on Thu Jan 12 06:50:29 PST 2017 -.\" NOTE: This file is generated, DO NOT EDIT. -.de Vb -.ft CW -.nf -.. -.de Ve -.ft R - -.fi -.. -.TH "LIBUNWIND" "3" "12 January 2017" "Programming Library " "Programming Library " -.SH NAME -libunwind -\-\- a (mostly) platform\-independent unwind API -.PP -.SH SYNOPSIS - -.PP -#include -.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 -int -unw_set_cache_size(unw_addr_space_t, -size_t, -int); -.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 -\&. -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 - -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 -and uses the linker switch -\fB\-l\fPunwind\&. -For cross\-platform unwinding, a program -includes -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. The cache size can be dynamically changed with -unw_set_cache_size(), -which also fluches the current cache. -.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_cache_size(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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind.tex b/src/coreclr/src/pal/src/libunwind/doc/libunwind.tex deleted file mode 100644 index 6cbb4766336dd1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind.tex +++ /dev/null @@ -1,359 +0,0 @@ -\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{int} \Func{unw\_set\_cache\_size}(\Type{unw\_addr\_space\_t}, \Type{size\_t}, \Type{int});\\ - -\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 - -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. The cache size can be dynamically changed with -\Func{unw\_set\_cache\_size}(), which also fluches the current cache. - - -\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\_cache\_size(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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind.trans b/src/coreclr/src/pal/src/libunwind/doc/libunwind.trans deleted file mode 100644 index a514e5a081d73f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/libunwind.trans +++ /dev/null @@ -1,34 +0,0 @@ -$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'} = "$htmlMacro1a{File}"; - $htmlMacro2c{'SeeAlso'} = "$htmlMacro1b{File}"; -$texiMacro1a{'SeeAlso'} = $texiMacro1a{File}; - $texiMacro1b{'SeeAlso'} = $texiMacro1b{File}; - diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.man b/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.man deleted file mode 100644 index 457f0c4dd17a47..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.man +++ /dev/null @@ -1,90 +0,0 @@ -'\" t -.\" Manual page created with latex2man on Wed Aug 16 11:09:44 PDT 2017 -.\" NOTE: This file is generated, DO NOT EDIT. -.de Vb -.ft CW -.nf -.. -.de Ve -.ft R - -.fi -.. -.TH "UNW\\_APPLY\\_REG\\_STATE" "3" "16 August 2017" "Programming Library " "Programming Library " -.SH NAME -unw_apply_reg_state -\-\- apply a register state update to a cursor -.PP -.SH SYNOPSIS - -.PP -#include -.br -.PP -int -unw_apply_reg_state(unw_cursor_t *cp, -void *reg_states_data); -.br -.PP -.SH DESCRIPTION - -.PP -The unw_apply_reg_state() -routine updates the register values -of a cursor according to the instructions in reg_states_data, -which have been obtained by calling unw_reg_states_iterate\&. -.PP -.SH RETURN VALUE - -.PP -On successful completion, unw_apply_reg_state() -returns 0. -Otherwise the negative value of one of the error\-codes below is -returned. -.PP -.SH THREAD AND SIGNAL SAFETY - -.PP -unw_apply_reg_state() -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_apply_reg_state() -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_reg_states_iterate(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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.tex deleted file mode 100644 index c67cc3ebfafdeb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.tex +++ /dev/null @@ -1,63 +0,0 @@ -\documentclass{article} -\usepackage[fancyhdr,pdf]{latex2man} - -\input{common.tex} - -\begin{document} - -\begin{Name}{3}{unw\_apply\_reg\_state}{David Mosberger-Tang}{Programming Library}{unw\_apply\_reg\_state}unw\_apply\_reg\_state -- apply a register state update to a cursor -\end{Name} - -\section{Synopsis} - -\File{\#include $<$libunwind.h$>$}\\ - -\Type{int} -\Func{unw\_apply\_reg\_state}(\Type{unw\_cursor\_t~*}\Var{cp}, -\Type{void~*}\Var{reg\_states\_data});\\ - -\section{Description} - -The \Func{unw\_apply\_reg\_state}() routine updates the register values -of a cursor according to the instructions in \Var{reg\_states\_data}, -which have been obtained by calling \Var{unw\_reg\_states\_iterate}. - -\section{Return Value} - -On successful completion, \Func{unw\_apply\_reg\_state}() returns 0. -Otherwise the negative value of one of the error-codes below is -returned. - -\section{Thread and Signal Safety} - -\Func{unw\_apply\_reg\_state}() 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\_apply\_reg\_state}() 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\_reg\_states\_iterate(3)} - -\section{Author} - -\noindent -David Mosberger-Tang\\ -Email: \Email{dmosberger@gmail.com}\\ -WWW: \URL{http://www.nongnu.org/libunwind/}. -\LatexManEnd - -\end{document} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.man b/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.man deleted file mode 100644 index 5699bbfe2881d2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.man +++ /dev/null @@ -1,86 +0,0 @@ -'\" 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 -.br -.PP -int -unw_backtrace(void **buffer, -int size); -.br -.PP -#include -.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 -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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.tex deleted file mode 100644 index c383eeb37a166f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.tex +++ /dev/null @@ -1,54 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.man b/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.man deleted file mode 100644 index 4aca13ecd8297e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.man +++ /dev/null @@ -1,457 +0,0 @@ -'\" 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 -.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 -\&. -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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.tex deleted file mode 100644 index 8de0691f3a9206..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.tex +++ /dev/null @@ -1,265 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.man b/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.man deleted file mode 100644 index 90c9777efbadd9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.man +++ /dev/null @@ -1,57 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.tex deleted file mode 100644 index a66b10b4b0bb4e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.tex +++ /dev/null @@ -1,40 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.man b/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.man deleted file mode 100644 index 627449effe2ad9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.man +++ /dev/null @@ -1,93 +0,0 @@ -'\" t -.\" Manual page created with latex2man on Fri Dec 2 16:09:33 PST 2016 -.\" NOTE: This file is generated, DO NOT EDIT. -.de Vb -.ft CW -.nf -.. -.de Ve -.ft R - -.fi -.. -.TH "UNW\\_FLUSH\\_CACHE" "3" "02 December 2016" "Programming Library " "Programming Library " -.SH NAME -unw_flush_cache -\-\- flush cached info -.PP -.SH SYNOPSIS - -.PP -#include -.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) -unw_set_cache_size(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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.tex deleted file mode 100644 index 32319db5d15872..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.tex +++ /dev/null @@ -1,58 +0,0 @@ -\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)} -\SeeAlso{unw\_set\_cache\_size(3)} - -\section{Author} - -\noindent -David Mosberger-Tang\\ -Email: \Email{dmosberger@gmail.com}\\ -WWW: \URL{http://www.nongnu.org/libunwind/}. -\LatexManEnd - -\end{document} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.man deleted file mode 100644 index 83fe4fcea6d673..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.man +++ /dev/null @@ -1,79 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.tex deleted file mode 100644 index bf344a32de2e61..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.tex +++ /dev/null @@ -1,55 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.man deleted file mode 100644 index 5e54ca13d3bb52..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.man +++ /dev/null @@ -1,111 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.tex deleted file mode 100644 index dd679adc06ab75..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.tex +++ /dev/null @@ -1,77 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.man deleted file mode 100644 index 09eadee27ad1a1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.man +++ /dev/null @@ -1,203 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.tex deleted file mode 100644 index 72621f1a6510f7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.tex +++ /dev/null @@ -1,123 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.man deleted file mode 100644 index a347a1d0089119..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.man +++ /dev/null @@ -1,134 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.tex deleted file mode 100644 index 5e1d5d247ebf29..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.tex +++ /dev/null @@ -1,91 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.man deleted file mode 100644 index 8b2bd06eaf084a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.man +++ /dev/null @@ -1,123 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.tex deleted file mode 100644 index c413990880dcd6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.tex +++ /dev/null @@ -1,82 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.man deleted file mode 100644 index 83e8bb43b64f4b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.man +++ /dev/null @@ -1,112 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.tex deleted file mode 100644 index b66e8c0dbb4265..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.tex +++ /dev/null @@ -1,77 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.man b/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.man deleted file mode 100644 index 13725df9570cfa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.man +++ /dev/null @@ -1,93 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.tex deleted file mode 100644 index fa3eb814b3f650..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.tex +++ /dev/null @@ -1,63 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.man b/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.man deleted file mode 100644 index 301dd6f93bdf00..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.man +++ /dev/null @@ -1,124 +0,0 @@ -'\" t -.\" Manual page created with latex2man on Wed Aug 16 12:11:05 PDT 2017 -.\" 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 2017" "Programming Library " "Programming Library " -.SH NAME -unw_init_local -\-\- initialize cursor for local unwinding -.PP -.SH SYNOPSIS - -.PP -#include -.br -.PP -int -unw_init_local(unw_cursor_t *c, -unw_context_t *ctxt); -.br -int -unw_init_local2(unw_cursor_t *c, -unw_context_t *ctxt, -int -flag); -.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 is expected to be one provided by a call to -unw_getcontext; as such, the instruction pointer may point to the -instruction after the last instruction of a function, and libunwind -will back\-up the instruction pointer before beginning a walk up the -call stack. 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. -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 , -whereas unw_init_remote() -is not. -.PP -If the unw_context_t is known to be a signal frame (i.e., from the -third argument in a sigaction handler on linux), -unw_init_local2() -should be used for correct initialization -on some platforms, passing the UNW_INIT_SIGNAL_FRAME flag. -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.tex deleted file mode 100644 index ff0d03bc77db0e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.tex +++ /dev/null @@ -1,80 +0,0 @@ -\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});\\ -\Type{int} \Func{unw\_init\_local2}(\Type{unw\_cursor\_t~*}\Var{c}, \Type{unw\_context\_t~*}\Var{ctxt}, \Type{int} \Var{flag});\\ - -\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 is expected to be one provided by a call to -unw_getcontext; as such, the instruction pointer may point to the -instruction after the last instruction of a function, and libunwind -will back-up the instruction pointer before beginning a walk up the -call stack. 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. -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. - -If the unw_context_t is known to be a signal frame (i.e., from the -third argument in a sigaction handler on linux), -\Func{unw\_init\_local2}() should be used for correct initialization -on some platforms, passing the UNW_INIT_SIGNAL_FRAME flag. - -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_init_local2.man b/src/coreclr/src/pal/src/libunwind/doc/unw_init_local2.man deleted file mode 100644 index 6cbbf008ab6a84..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_init_local2.man +++ /dev/null @@ -1 +0,0 @@ -.so man3/unw_init_local.3 diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.man b/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.man deleted file mode 100644 index 0acdac9617b75d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.man +++ /dev/null @@ -1,123 +0,0 @@ -'\" 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 -.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 -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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.tex deleted file mode 100644 index 9b4dc7997ae61f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.tex +++ /dev/null @@ -1,79 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.man b/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.man deleted file mode 100644 index 0c26ec1bc740a2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.man +++ /dev/null @@ -1,73 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.tex deleted file mode 100644 index c28cdc9be4fd23..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.tex +++ /dev/null @@ -1,52 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.man b/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.man deleted file mode 100644 index d9a7cda7b5fe1c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.man +++ /dev/null @@ -1,88 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.tex deleted file mode 100644 index f262e5600c1df7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.tex +++ /dev/null @@ -1,67 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.man b/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.man deleted file mode 100644 index e328ad2e38cdff..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.man +++ /dev/null @@ -1,137 +0,0 @@ -'\" t -.\" Manual page created with latex2man on Wed Aug 16 11:09:44 PDT 2017 -.\" NOTE: This file is generated, DO NOT EDIT. -.de Vb -.ft CW -.nf -.. -.de Ve -.ft R - -.fi -.. -.TH "UNW\\_REG\\_STATES\\_ITERATE" "3" "16 August 2017" "Programming Library " "Programming Library " -.SH NAME -unw_reg_states_iterate -\-\- get register state info on current procedure -.PP -.SH SYNOPSIS - -.PP -#include -.br -.PP -int -unw_reg_states_iterate(unw_cursor_t *cp, -unw_reg_states_callbackcb, -void *token); -.br -.PP -.SH DESCRIPTION - -.PP -The unw_reg_states_iterate() -routine provides -information about the procedure that created the stack frame -identified by argument cp\&. -The cb -argument is a pointer -to a function of type unw_reg_states_callback -which is used to -return the information. The function unw_reg_states_callback -has the -following definition: -.PP -int -( *unw_reg_states_callback)(void *token, -void *reg_states_data, -size_t -reg_states_data_size, -unw_word_t -start_ip, -unw_word_t -end_ip); -.PP -The callback function may be invoked several times for each call of unw_reg_states_iterate\&. -Each call is associcated with a instruction address range and a set of instructions on how to update register values when returning from the procedure in that address range. For each invocation, the arguments to the callback function are: -.TP -void * token - The token value passed to unw_reg_states_callback\&. -.br -.TP -void * reg_states_data - A pointer to data about -updating register values. This data, or a copy of it, can be passed -to unw_apply_reg_state\&. -.br -.TP -int reg_states_data_size - The size of the register update data. -.br -.TP -unw_word_t start_ip - The address of the first -instruction of the address range. -.br -.TP -unw_word_t end_ip - The address of the first -instruction \fIbeyond\fP -the end of the address range. -.br -.PP -.SH RETURN VALUE - -.PP -On successful completion, unw_reg_states_iterate() -returns -0. If the callback function returns a nonzero value, that indicates -failure and the function returns immediately. Otherwise the negative -value of one of the error\-codes below is returned. -.PP -.SH THREAD AND SIGNAL SAFETY - -.PP -unw_reg_states_iterate() -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_reg_states_iterate() -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_apply_reg_state(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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.tex deleted file mode 100644 index 36c9b548a25d74..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.tex +++ /dev/null @@ -1,83 +0,0 @@ -\documentclass{article} -\usepackage[fancyhdr,pdf]{latex2man} - -\input{common.tex} - -\begin{document} - -\begin{Name}{3}{unw\_reg\_states\_iterate}{David Mosberger-Tang}{Programming Library}{unw\_reg\_states\_iterate}unw\_reg\_states\_iterate -- get register state info on current procedure -\end{Name} - -\section{Synopsis} - -\File{\#include $<$libunwind.h$>$}\\ - -\Type{int} \Func{unw\_reg\_states\_iterate}(\Type{unw\_cursor\_t~*}\Var{cp}, \Type{unw\_reg\_states\_callback}\Var{cb}, \Type{void~*}\Var{token});\\ - -\section{Description} - -The \Func{unw\_reg\_states\_iterate}() routine provides -information about the procedure that created the stack frame -identified by argument \Var{cp}. The \Var{cb} argument is a pointer -to a function of type \Type{unw\_reg\_states\_callback} which is used to -return the information. The function \Type{unw\_reg\_states\_callback} has the -following definition: - -\Type{int} (~*\Var{unw\_reg\_states\_callback})(\Type{void~*}\Var{token}, - \Type{void~*}\Var{reg\_states\_data}, - \Type{size\_t} \Var{reg\_states\_data\_size}, - \Type{unw\_word\_t} \Var{start\_ip}, \Type{unw\_word\_t} \Var{end\_ip}); - -The callback function may be invoked several times for each call of \Func{unw\_reg\_states\_iterate}. Each call is associcated with a instruction address range and a set of instructions on how to update register values when returning from the procedure in that address range. For each invocation, the arguments to the callback function are: -\begin{description} -\item[\Type{void~*} \Var{token}] The token value passed to \Var{unw\_reg\_states\_callback}. \\ -\item[\Type{void~*} \Var{reg\_states\_data}] A pointer to data about - updating register values. This data, or a copy of it, can be passed - to \Var{unw\_apply\_reg\_state}.\\ -\item[\Type{int} \Var{reg\_states\_data\_size}] The size of the register update data. \\ -\item[\Type{unw\_word\_t} \Var{start\_ip}] The address of the first - instruction of the address range. \\ -\item[\Type{unw\_word\_t} \Var{end\_ip}] The address of the first - instruction \emph{beyond} the end of the address range. \\ -\end{description} - -\section{Return Value} - -On successful completion, \Func{unw\_reg\_states\_iterate}() returns -0. If the callback function returns a nonzero value, that indicates -failure and the function returns immediately. Otherwise the negative -value of one of the error-codes below is returned. - -\section{Thread and Signal Safety} - -\Func{unw\_reg\_states\_iterate}() 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\_reg\_states\_iterate}() 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\_apply\_reg\_state(3)} - -\section{Author} - -\noindent -David Mosberger-Tang\\ -Email: \Email{dmosberger@gmail.com}\\ -WWW: \URL{http://www.nongnu.org/libunwind/}. -\LatexManEnd - -\end{document} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_regname.man b/src/coreclr/src/pal/src/libunwind/doc/unw_regname.man deleted file mode 100644 index 1e3e2dbc6ea1fe..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_regname.man +++ /dev/null @@ -1,68 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_regname.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_regname.tex deleted file mode 100644 index 94b6434194d6f2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_regname.tex +++ /dev/null @@ -1,47 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_resume.man b/src/coreclr/src/pal/src/libunwind/doc/unw_resume.man deleted file mode 100644 index 1bf38327bf00ed..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_resume.man +++ /dev/null @@ -1,146 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_resume.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_resume.tex deleted file mode 100644 index 38b18248ab66f2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_resume.tex +++ /dev/null @@ -1,99 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.man b/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.man deleted file mode 100644 index 34bbc53961450c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.man +++ /dev/null @@ -1,88 +0,0 @@ -'\" t -.\" Manual page created with latex2man on Fri Jan 13 08:33:21 PST 2017 -.\" NOTE: This file is generated, DO NOT EDIT. -.de Vb -.ft CW -.nf -.. -.de Ve -.ft R - -.fi -.. -.TH "UNW\\_SET\\_CACHE\\_SIZE" "3" "13 January 2017" "Programming Library " "Programming Library " -.SH NAME -unw_set_cache_size -\-\- set unwind cache size -.PP -.SH SYNOPSIS - -.PP -#include -.br -.PP -int -unw_set_cache_size(unw_addr_space_t -as, -size_t -size, -int -flag); -.br -.PP -.SH DESCRIPTION - -.PP -The unw_set_cache_size() -routine sets the cache size of -address space as -to hold at least as many items as given by -argument size\&. -It may hold more items as determined by the -implementation. To disable caching, call -unw_set_caching_policy) -with a policy of -UNW_CACHE_NONE\&. -Flag is currently unused and must be 0. -.PP -.SH RETURN VALUE - -.PP -On successful completion, unw_set_cache_size() -returns 0. -Otherwise the negative value of one of the error\-codes below is -returned. -.PP -.SH THREAD AND SIGNAL SAFETY - -.PP -unw_set_cache_size() -is thread\-safe but \fInot\fP -safe -to use from a signal handler. -.PP -.SH ERRORS - -.PP -.TP -UNW_ENOMEM - The desired cache size could not be -established because the application is out of memory. -.PP -.SH SEE ALSO - -.PP -libunwind(3), -unw_create_addr_space(3), -unw_set_caching_policy(3), -unw_flush_cache(3) -.PP -.SH AUTHOR - -.PP -Dave Watson -.br -Email: \fBdade.watson@gmail.com\fP -.br -WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&. -.\" NOTE: This file is generated, DO NOT EDIT. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.tex deleted file mode 100644 index 1bd7e00df7c231..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.tex +++ /dev/null @@ -1,59 +0,0 @@ -\documentclass{article} -\usepackage[fancyhdr,pdf]{latex2man} - -\input{common.tex} - -\begin{document} - -\begin{Name}{3}{unw\_set\_cache\_size}{Dave Watson}{Programming Library}{unw\_set\_cache\_size}unw\_set\_cache\_size -- set unwind cache size -\end{Name} - -\section{Synopsis} - -\File{\#include $<$libunwind.h$>$}\\ - -\Type{int} \Func{unw\_set\_cache\_size}(\Type{unw\_addr\_space\_t} \Var{as}, \Type{size\_t} \Var{size}, \Type{int} \Var{flag});\\ - -\section{Description} - -The \Func{unw\_set\_cache\_size}() routine sets the cache size of -address space \Var{as} to hold at least as many items as given by -argument \Var{size}. It may hold more items as determined by the -implementation. To disable caching, call -\Func{unw\_set\_caching\_policy}) with a policy of -\Const{UNW\_CACHE\_NONE}. Flag is currently unused and must be 0. - -\section{Return Value} - -On successful completion, \Func{unw\_set\_cache\_size}() returns 0. -Otherwise the negative value of one of the error-codes below is -returned. - -\section{Thread and Signal Safety} - -\Func{unw\_set\_cache\_size}() is thread-safe but \emph{not} safe -to use from a signal handler. - -\section{Errors} - -\begin{Description} -\item[\Const{UNW\_ENOMEM}] The desired cache size 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\_set\_caching\_policy(3)}, -\SeeAlso{unw\_flush\_cache(3)} - -\section{Author} - -\noindent -Dave Watson\\ -Email: \Email{dade.watson@gmail.com}\\ -WWW: \URL{http://www.nongnu.org/libunwind/}. -\LatexManEnd - -\end{document} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.man b/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.man deleted file mode 100644 index 4862ea545e5d45..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.man +++ /dev/null @@ -1,119 +0,0 @@ -'\" t -.\" Manual page created with latex2man on Fri Dec 2 16:09:33 PST 2016 -.\" NOTE: This file is generated, DO NOT EDIT. -.de Vb -.ft CW -.nf -.. -.de Ve -.ft R - -.fi -.. -.TH "UNW\\_SET\\_CACHING\\_POLICY" "3" "02 December 2016" "Programming Library " "Programming Library " -.SH NAME -unw_set_caching_policy -\-\- set unwind caching policy -.PP -.SH SYNOPSIS - -.PP -#include -.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_set_cache_size(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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.tex deleted file mode 100644 index 3a4b07e84af0f3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.tex +++ /dev/null @@ -1,81 +0,0 @@ -\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\_set\_cache\_size(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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.man b/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.man deleted file mode 100644 index 6cefa54623ca2f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.man +++ /dev/null @@ -1,117 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.tex deleted file mode 100644 index aaf7fb25a761eb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.tex +++ /dev/null @@ -1,79 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.man b/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.man deleted file mode 100644 index 5d57045f747515..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.man +++ /dev/null @@ -1,117 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.tex deleted file mode 100644 index 2421846be59e78..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.tex +++ /dev/null @@ -1,79 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_step.man b/src/coreclr/src/pal/src/libunwind/doc/unw_step.man deleted file mode 100644 index 54da1b2f3d62a1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_step.man +++ /dev/null @@ -1,106 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_step.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_step.tex deleted file mode 100644 index 106bd9ba99c0c7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_step.tex +++ /dev/null @@ -1,68 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.man b/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.man deleted file mode 100644 index 467c44d26204c3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.man +++ /dev/null @@ -1,63 +0,0 @@ -'\" 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 -.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.tex deleted file mode 100644 index 7cad011768d73d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.tex +++ /dev/null @@ -1,42 +0,0 @@ -\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} diff --git a/src/coreclr/src/pal/src/libunwind/include/compiler.h b/src/coreclr/src/pal/src/libunwind/include/compiler.h deleted file mode 100644 index 2fa59eff7fbd86..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/compiler.h +++ /dev/null @@ -1,72 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2005 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - -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 ALIAS2(name) #name -# define ALIAS(name) __attribute__((alias (ALIAS2(name)))) -# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) -# define ALWAYS_INLINE inline __attribute__((always_inline)) -# define HIDDEN __attribute__((visibility ("hidden"))) -# else -# define ALWAYS_INLINE -# define HIDDEN -# 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 WEAK -# define likely(x) (x) -# define unlikely(x) (x) -#endif - -#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) - -#endif /* COMPILER_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h b/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h deleted file mode 100644 index e03750760c529e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h +++ /dev/null @@ -1,128 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -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 __attribute__((packed)) dwarf_eh_frame_hdr - { - unsigned char version; - unsigned char eh_frame_ptr_enc; - unsigned char fde_count_enc; - unsigned char table_enc; - Elf_W (Addr) eh_frame; - /* The rest of the header is variable-length and consists of the - following members: - - 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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf.h b/src/coreclr/src/pal/src/libunwind/include/dwarf.h deleted file mode 100644 index fab93c614518e3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/dwarf.h +++ /dev/null @@ -1,450 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -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 - -struct dwarf_cursor; /* forward-declaration */ -struct elf_dyn_info; - -#include "dwarf-config.h" - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifndef UNW_REMOTE_ONLY - #if defined(HAVE_LINK_H) - #include - #elif defined(HAVE_SYS_LINK_H) - #include - #else - #error Could not find - #endif -#endif - -#include - -/* 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 -#define DWARF_CIE_VERSION_MAX 4 - -#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_val_expression = 0x16, - 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_VAL_EXPR, /* register has computed value */ - } -dwarf_where_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_only_state - { - char where[DWARF_NUM_PRESERVED_REGS + 2]; /* how is the register saved? */ - unw_word_t val[DWARF_NUM_PRESERVED_REGS + 2]; /* where it's saved */ - } -dwarf_reg_only_state_t; - -typedef struct dwarf_reg_state - { - unw_word_t ret_addr_column; /* which column in rule table represents return address */ - dwarf_reg_only_state_t reg; - } -dwarf_reg_state_t; - -typedef struct dwarf_stackable_reg_state - { - struct dwarf_stackable_reg_state *next; /* for rs_stack */ - dwarf_reg_state_t state; - } -dwarf_stackable_reg_state_t; - -typedef struct dwarf_reg_cache_entry - { - unw_word_t ip; /* ip this rs is for */ - 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_cache_entry_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 eh_args[UNW_TDEP_NUM_EH_REGS]; - unsigned int eh_valid_mask; - - 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_DEFAULT_LOG_UNW_CACHE_SIZE 7 -#define DWARF_DEFAULT_UNW_CACHE_SIZE (1 << DWARF_DEFAULT_LOG_UNW_CACHE_SIZE) - -#define DWARF_DEFAULT_LOG_UNW_HASH_SIZE (DWARF_DEFAULT_LOG_UNW_CACHE_SIZE + 1) -#define DWARF_DEFAULT_UNW_HASH_SIZE (1 << DWARF_DEFAULT_LOG_UNW_HASH_SIZE) - -typedef unsigned char unw_hash_index_t; - -struct dwarf_rs_cache - { - pthread_mutex_t lock; - unsigned short rr_head; /* index of least-recently allocated rs */ - - unsigned short log_size; - unsigned short prev_log_size; - - /* hash table that maps instruction pointer to rs index: */ - unsigned short *hash; - - uint32_t generation; /* generation number */ - - /* rs cache: */ - dwarf_reg_state_t *buckets; - dwarf_reg_cache_entry_t *links; - - /* default memory, loaded in BSS segment */ - unsigned short default_hash[DWARF_DEFAULT_UNW_HASH_SIZE]; - dwarf_reg_state_t default_buckets[DWARF_DEFAULT_UNW_CACHE_SIZE]; - dwarf_reg_cache_entry_t default_links[DWARF_DEFAULT_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; - /* Index (for binary search). */ - struct table_entry *index; - size_t index_size; - /* Pointer to next descriptor. */ - struct unw_debug_frame_list *next; - }; - -/* 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_stack_aligned UNW_OBJ (dwarf_stack_aligned) -#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_make_proc_info UNW_OBJ (dwarf_make_proc_info) -#define dwarf_apply_reg_state UNW_OBJ (dwarf_apply_reg_state) -#define dwarf_reg_states_iterate UNW_OBJ (dwarf_reg_states_iterate) -#define dwarf_read_encoded_pointer UNW_OBJ (dwarf_read_encoded_pointer) -#define dwarf_step UNW_OBJ (dwarf_step) -#define dwarf_flush_rs_cache UNW_OBJ (dwarf_flush_rs_cache) - -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); - -extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, - char *path, unw_word_t segbase, unw_word_t mapoff, - unw_word_t ip); -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_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr, - unw_word_t rbp_addr, unw_word_t *offset); - -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, - unw_word_t base, - int need_unwind_info, - int is_debug_frame, - void *arg); -extern int dwarf_find_save_locs (struct dwarf_cursor *c); -extern int dwarf_make_proc_info (struct dwarf_cursor *c); -extern int dwarf_apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs); -extern int dwarf_reg_states_iterate (struct dwarf_cursor *c, unw_reg_states_callback cb, void *token); -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); -extern int dwarf_flush_rs_cache (struct dwarf_rs_cache *cache); - -#endif /* dwarf_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf_i.h b/src/coreclr/src/pal/src/libunwind/include/dwarf_i.h deleted file mode 100644 index 983b9f5c2afbc7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/dwarf_i.h +++ /dev/null @@ -1,490 +0,0 @@ -#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 = 0; - int32_t sval32 = 0; - int64_t sval64 = 0; - 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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h deleted file mode 100644 index 85812e151d7829..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h +++ /dev/null @@ -1,210 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - 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 -#include -#include - -#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 512 - -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 */ - } -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. */ - } -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" - -#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__ ( \ - "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, x13, [%[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" \ - "stp x1, x30, [%[base], #248]\n" \ - : [base] "+r" (unw_base) : : "x1", "memory"); \ - }), 0) -#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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-arm.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-arm.h deleted file mode 100644 index 6709b7abaeefa4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-arm.h +++ /dev/null @@ -1,303 +0,0 @@ -/* 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 -#include - -#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. */ - } -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]\n" \ - ".code 16\n" \ - : [base] "+r" (unw_base) : : "memory", "cc"); \ - }), 0) -#endif - -#include "libunwind-dynamic.h" - -typedef struct - { - /* no arm-specific auxiliary proc-info */ - } -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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in b/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in deleted file mode 100644 index 8d96ddca2abc30..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in +++ /dev/null @@ -1,281 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 enum - { - UNW_INIT_SIGNAL_FRAME = 1, /* We know this is a signal frame */ - } -unw_init_local2_flags_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 */ -#if defined(NEED_LAST_IP) - unw_word_t last_ip; /* first IP that could begin another procedure */ -#endif - 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; - -typedef int (*unw_reg_states_callback)(void *token, - void *reg_states_data, - size_t reg_states_data_size, - unw_word_t start_ip, unw_word_t end_ip); - -/* 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_get_accessors_int UNW_ARCH_OBJ(get_accessors_int) -#define unw_init_local UNW_OBJ(init_local) -#define unw_init_local2 UNW_OBJ(init_local2) -#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_reg_states_iterate UNW_OBJ(reg_states_iterate) -#define unw_apply_reg_state UNW_OBJ(apply_reg_state) -#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_set_cache_size UNW_OBJ(set_cache_size) -#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 unw_accessors_t *unw_get_accessors_int (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 int unw_set_cache_size (unw_addr_space_t, size_t, int); -extern const char *unw_regname (unw_regnum_t); - -extern int unw_init_local (unw_cursor_t *, unw_context_t *); -extern int unw_init_local2 (unw_cursor_t *, unw_context_t *, int); -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_reg_states_iterate (unw_cursor_t *, unw_reg_states_callback, void *); -extern int unw_apply_reg_state (unw_cursor_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; diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-coredump.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-coredump.h deleted file mode 100644 index 3c7814140f940d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-coredump.h +++ /dev/null @@ -1,73 +0,0 @@ -/* 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 - -#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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-dynamic.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-dynamic.h deleted file mode 100644 index edb0bbd343db7f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-dynamic.h +++ /dev/null @@ -1,214 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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_INFO_FORMAT_IP_OFFSET, /* Like UNW_INFO_FORMAT_REMOTE_TABLE, but - table entries are considered - relative to di->start_ip, rather - than di->segbase */ - } -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 diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-hppa.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-hppa.h deleted file mode 100644 index 7013aa772682db..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-hppa.h +++ /dev/null @@ -1,125 +0,0 @@ -/* 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 -#include - -#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. */ - } -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 */ - } -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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-ia64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-ia64.h deleted file mode 100644 index 0cc4f39eaab1e4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-ia64.h +++ /dev/null @@ -1,194 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 -#include - -#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 */ - } -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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h deleted file mode 100644 index 97c95e2463ac1f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h +++ /dev/null @@ -1,160 +0,0 @@ -/* 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 -#include - -#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, which are 32-bit wide for O32 and N32 - ABIs, and 64-bit wide for N64 ABI. */ -#if _MIPS_SIM == _ABI64 -typedef uint64_t unw_word_t; -#else -typedef uint32_t unw_word_t; -#endif -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_PC, - - 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. */ - } -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 */ - } -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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc32.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc32.h deleted file mode 100644 index 47ebfde5a3cf3a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc32.h +++ /dev/null @@ -1,207 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - - Copied from libunwind-x86_64.h, modified slightly for building - frysk successfully on ppc64, by Wu Zhou - 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 -#include - -#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. */ - } -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 */ - } -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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc64.h deleted file mode 100644 index 9944628da02f72..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc64.h +++ /dev/null @@ -1,271 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - - Copied from libunwind-x86_64.h, modified slightly for building - frysk successfully on ppc64, by Wu Zhou - 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 -#include - -#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; - -typedef enum - { - UNW_PPC64_ABI_ELFv1, - UNW_PPC64_ABI_ELFv2 - } -ppc64_abi_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. */ - } -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 */ - } -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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-ptrace.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-ptrace.h deleted file mode 100644 index 801325c4d4d00c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-ptrace.h +++ /dev/null @@ -1,63 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 - -#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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-sh.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-sh.h deleted file mode 100644 index 927f61ff42bdad..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-sh.h +++ /dev/null @@ -1,114 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - -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 -#include -#include - -#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. */ - } -unw_tdep_save_loc_t; - -#include "libunwind-dynamic.h" - -typedef struct - { - /* no sh-specific auxiliary proc-info */ - } -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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-tilegx.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-tilegx.h deleted file mode 100644 index 0f84ea65ee3657..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-tilegx.h +++ /dev/null @@ -1,161 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 -#include - -#define UNW_TARGET tilegx -#define UNW_TARGET_TILEGX 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 - -/* The size of a "word" varies on TILEGX. This type is used for memory - addresses and register values. */ -typedef uint64_t unw_word_t; -typedef int64_t unw_sword_t; - -typedef long double unw_tdep_fpreg_t; - -typedef enum -{ - UNW_TILEGX_R0, - UNW_TILEGX_R1, - UNW_TILEGX_R2, - UNW_TILEGX_R3, - UNW_TILEGX_R4, - UNW_TILEGX_R5, - UNW_TILEGX_R6, - UNW_TILEGX_R7, - UNW_TILEGX_R8, - UNW_TILEGX_R9, - UNW_TILEGX_R10, - UNW_TILEGX_R11, - UNW_TILEGX_R12, - UNW_TILEGX_R13, - UNW_TILEGX_R14, - UNW_TILEGX_R15, - UNW_TILEGX_R16, - UNW_TILEGX_R17, - UNW_TILEGX_R18, - UNW_TILEGX_R19, - UNW_TILEGX_R20, - UNW_TILEGX_R21, - UNW_TILEGX_R22, - UNW_TILEGX_R23, - UNW_TILEGX_R24, - UNW_TILEGX_R25, - UNW_TILEGX_R26, - UNW_TILEGX_R27, - UNW_TILEGX_R28, - UNW_TILEGX_R29, - UNW_TILEGX_R30, - UNW_TILEGX_R31, - UNW_TILEGX_R32, - UNW_TILEGX_R33, - UNW_TILEGX_R34, - UNW_TILEGX_R35, - UNW_TILEGX_R36, - UNW_TILEGX_R37, - UNW_TILEGX_R38, - UNW_TILEGX_R39, - UNW_TILEGX_R40, - UNW_TILEGX_R41, - UNW_TILEGX_R42, - UNW_TILEGX_R43, - UNW_TILEGX_R44, - UNW_TILEGX_R45, - UNW_TILEGX_R46, - UNW_TILEGX_R47, - UNW_TILEGX_R48, - UNW_TILEGX_R49, - UNW_TILEGX_R50, - UNW_TILEGX_R51, - UNW_TILEGX_R52, - UNW_TILEGX_R53, - UNW_TILEGX_R54, - UNW_TILEGX_R55, - - /* FIXME: Other registers! */ - - UNW_TILEGX_PC, - /* For TILEGX, the CFA is the value of SP (r54) at the call site in the - previous frame. */ - UNW_TILEGX_CFA, - - UNW_TDEP_LAST_REG = UNW_TILEGX_PC, - - UNW_TDEP_IP = UNW_TILEGX_R55, /* R55 is link register for Tilegx */ - UNW_TDEP_SP = UNW_TILEGX_R54, - UNW_TDEP_EH = UNW_TILEGX_R0 /* FIXME. */ -} tilegx_regnum_t; - -typedef enum -{ - UNW_TILEGX_ABI_N64 = 2 -} tilegx_abi_t; - -#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for TILEGX. */ - -typedef struct unw_tdep_save_loc -{ - /* Additional target-dependent info on a save location. */ -} unw_tdep_save_loc_t; - -typedef ucontext_t unw_tdep_context_t; - -#include "libunwind-dynamic.h" - -typedef struct -{ - /* no tilegx-specific auxiliary proc-info */ -} unw_tdep_proc_info_t; - -#include "libunwind-common.h" - -#define unw_tdep_getcontext getcontext - -#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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-x86.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-x86.h deleted file mode 100644 index 40fe0464f2f6c2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-x86.h +++ /dev/null @@ -1,187 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 -#include -#include - -#define UNW_TARGET x86 -#define UNW_TARGET_X86 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 127 - -typedef uint32_t unw_word_t; -typedef int32_t unw_sword_t; - -typedef union { - struct { uint8_t b[4]; } val32; - struct { uint8_t b[10]; } val80; - struct { uint8_t b[16]; } val128; -} 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. - - The described register usage convention is based on "System V - Application Binary Interface, Intel386 Architecture Processor - Supplement, Fourth Edition" at - - http://www.linuxbase.org/spec/refspecs/elf/abi386-4.pdf - - It would have been nice to use the same register numbering as - DWARF, but that doesn't work because the libunwind requires - that the exception argument registers be consecutive, which the - wouldn't be with the DWARF numbering. */ - UNW_X86_EAX, /* scratch (exception argument 1) */ - UNW_X86_EDX, /* scratch (exception argument 2) */ - UNW_X86_ECX, /* scratch */ - UNW_X86_EBX, /* preserved */ - UNW_X86_ESI, /* preserved */ - UNW_X86_EDI, /* preserved */ - UNW_X86_EBP, /* (optional) frame-register */ - UNW_X86_ESP, /* (optional) frame-register */ - UNW_X86_EIP, /* frame-register */ - UNW_X86_EFLAGS, /* scratch (except for "direction", which is fixed */ - UNW_X86_TRAPNO, /* scratch */ - - /* MMX/stacked-fp registers */ - UNW_X86_ST0, /* fp return value */ - UNW_X86_ST1, /* scratch */ - UNW_X86_ST2, /* scratch */ - UNW_X86_ST3, /* scratch */ - UNW_X86_ST4, /* scratch */ - UNW_X86_ST5, /* scratch */ - UNW_X86_ST6, /* scratch */ - UNW_X86_ST7, /* scratch */ - - UNW_X86_FCW, /* scratch */ - UNW_X86_FSW, /* scratch */ - UNW_X86_FTW, /* scratch */ - UNW_X86_FOP, /* scratch */ - UNW_X86_FCS, /* scratch */ - UNW_X86_FIP, /* scratch */ - UNW_X86_FEA, /* scratch */ - UNW_X86_FDS, /* scratch */ - - /* SSE registers */ - UNW_X86_XMM0_lo, /* scratch */ - UNW_X86_XMM0_hi, /* scratch */ - UNW_X86_XMM1_lo, /* scratch */ - UNW_X86_XMM1_hi, /* scratch */ - UNW_X86_XMM2_lo, /* scratch */ - UNW_X86_XMM2_hi, /* scratch */ - UNW_X86_XMM3_lo, /* scratch */ - UNW_X86_XMM3_hi, /* scratch */ - UNW_X86_XMM4_lo, /* scratch */ - UNW_X86_XMM4_hi, /* scratch */ - UNW_X86_XMM5_lo, /* scratch */ - UNW_X86_XMM5_hi, /* scratch */ - UNW_X86_XMM6_lo, /* scratch */ - UNW_X86_XMM6_hi, /* scratch */ - UNW_X86_XMM7_lo, /* scratch */ - UNW_X86_XMM7_hi, /* scratch */ - - UNW_X86_MXCSR, /* scratch */ - - /* segment registers */ - UNW_X86_GS, /* special */ - UNW_X86_FS, /* special */ - UNW_X86_ES, /* special */ - UNW_X86_DS, /* special */ - UNW_X86_SS, /* special */ - UNW_X86_CS, /* special */ - UNW_X86_TSS, /* special */ - UNW_X86_LDT, /* special */ - - /* frame info (read-only) */ - UNW_X86_CFA, - - UNW_X86_XMM0, /* scratch */ - UNW_X86_XMM1, /* scratch */ - UNW_X86_XMM2, /* scratch */ - UNW_X86_XMM3, /* scratch */ - UNW_X86_XMM4, /* scratch */ - UNW_X86_XMM5, /* scratch */ - UNW_X86_XMM6, /* scratch */ - UNW_X86_XMM7, /* scratch */ - - UNW_TDEP_LAST_REG = UNW_X86_XMM7, - - UNW_TDEP_IP = UNW_X86_EIP, - UNW_TDEP_SP = UNW_X86_ESP, - UNW_TDEP_EH = UNW_X86_EAX - } -x86_regnum_t; - -#define UNW_TDEP_NUM_EH_REGS 2 /* eax and edx are exception args */ - -typedef struct unw_tdep_save_loc - { - /* Additional target-dependent info on a save location. */ - } -unw_tdep_save_loc_t; - -/* On x86, we can directly use ucontext_t as the unwind context. */ -typedef ucontext_t unw_tdep_context_t; - -#include "libunwind-dynamic.h" - -typedef struct - { - /* no x86-specific auxiliary proc-info */ - } -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 *); - -#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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-x86_64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-x86_64.h deleted file mode 100644 index 78eb541afb303c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-x86_64.h +++ /dev/null @@ -1,141 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -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 -#include -#include - -#define UNW_TARGET x86_64 -#define UNW_TARGET_X86_64 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 127 - -typedef uint64_t unw_word_t; -typedef int64_t unw_sword_t; - -typedef long double unw_tdep_fpreg_t; - -typedef enum - { - UNW_X86_64_RAX, - UNW_X86_64_RDX, - UNW_X86_64_RCX, - UNW_X86_64_RBX, - UNW_X86_64_RSI, - UNW_X86_64_RDI, - UNW_X86_64_RBP, - UNW_X86_64_RSP, - UNW_X86_64_R8, - UNW_X86_64_R9, - UNW_X86_64_R10, - UNW_X86_64_R11, - UNW_X86_64_R12, - UNW_X86_64_R13, - UNW_X86_64_R14, - UNW_X86_64_R15, - UNW_X86_64_RIP, -#ifdef CONFIG_MSABI_SUPPORT - UNW_X86_64_XMM0, - UNW_X86_64_XMM1, - UNW_X86_64_XMM2, - UNW_X86_64_XMM3, - UNW_X86_64_XMM4, - UNW_X86_64_XMM5, - UNW_X86_64_XMM6, - UNW_X86_64_XMM7, - UNW_X86_64_XMM8, - UNW_X86_64_XMM9, - UNW_X86_64_XMM10, - UNW_X86_64_XMM11, - UNW_X86_64_XMM12, - UNW_X86_64_XMM13, - UNW_X86_64_XMM14, - UNW_X86_64_XMM15, - UNW_TDEP_LAST_REG = UNW_X86_64_XMM15, -#else - UNW_TDEP_LAST_REG = UNW_X86_64_RIP, -#endif - - /* XXX Add other regs here */ - - /* frame info (read-only) */ - UNW_X86_64_CFA, - - UNW_TDEP_IP = UNW_X86_64_RIP, - UNW_TDEP_SP = UNW_X86_64_RSP, - UNW_TDEP_BP = UNW_X86_64_RBP, - UNW_TDEP_EH = UNW_X86_64_RAX - } -x86_64_regnum_t; - -#define UNW_TDEP_NUM_EH_REGS 2 /* XXX Not sure what this means */ - -typedef struct unw_tdep_save_loc - { - /* Additional target-dependent info on a save location. */ - char unused; - } -unw_tdep_save_loc_t; - -/* On x86_64, we can directly use ucontext_t as the unwind context. */ -typedef ucontext_t unw_tdep_context_t; - -typedef struct - { - /* no x86-64-specific auxiliary proc-info */ - char unused; - } -unw_tdep_proc_info_t; - -#include "libunwind-dynamic.h" -#include "libunwind-common.h" - -#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) -#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) - -extern int unw_tdep_getcontext (unw_tdep_context_t *); -extern int unw_tdep_is_fpreg (int); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* LIBUNWIND_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in b/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in deleted file mode 100644 index 7a56168c8b2723..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in +++ /dev/null @@ -1,36 +0,0 @@ -/* Provide a real file - not a symlink - as it would cause multiarch conflicts - when multiple different arch releases are installed simultaneously. */ - -#ifndef UNW_REMOTE_ONLY - -#if defined __aarch64__ -#include "libunwind-aarch64.h" -#elif defined __arm__ -# include "libunwind-arm.h" -#elif defined __hppa__ -# include "libunwind-hppa.h" -#elif defined __ia64__ -# include "libunwind-ia64.h" -#elif defined __mips__ -# include "libunwind-mips.h" -#elif defined __powerpc__ && !defined __powerpc64__ -# include "libunwind-ppc32.h" -#elif defined __powerpc64__ -# include "libunwind-ppc64.h" -#elif defined __sh__ -# include "libunwind-sh.h" -#elif defined __i386__ -# include "libunwind-x86.h" -#elif defined __x86_64__ -# include "libunwind-x86_64.h" -#elif defined __tilegx__ -# include "libunwind-tilegx.h" -#else -# error "Unsupported arch" -#endif - -#else /* UNW_REMOTE_ONLY */ - -# include "libunwind-@arch@.h" - -#endif /* UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h deleted file mode 100644 index 0fcf32695e2bae..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h +++ /dev/null @@ -1,366 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2005 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - -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 files contains libunwind-internal definitions which are - subject to frequent change and are not to be exposed to - libunwind-users. */ - -#ifndef libunwind_i_h -#define libunwind_i_h - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "compiler.h" - -#if defined(HAVE___THREAD) && HAVE___THREAD -#define UNWI_DEFAULT_CACHING_POLICY UNW_CACHE_PER_THREAD -#else -#define UNWI_DEFAULT_CACHING_POLICY UNW_CACHE_GLOBAL -#endif - -/* Platform-independent libunwind-internal declarations. */ - -#include /* HP-UX needs this before include of pthread.h */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(HAVE_ELF_H) -# include -#elif defined(HAVE_SYS_ELF_H) -# include -#else -# error Could not locate -#endif - -#if defined(HAVE_ENDIAN_H) -# include -#elif defined(HAVE_SYS_ENDIAN_H) -# include -# if defined(_LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) -# define __LITTLE_ENDIAN _LITTLE_ENDIAN -# endif -# if defined(_BIG_ENDIAN) && !defined(__BIG_ENDIAN) -# define __BIG_ENDIAN _BIG_ENDIAN -# endif -# if defined(_BYTE_ORDER) && !defined(__BYTE_ORDER) -# define __BYTE_ORDER _BYTE_ORDER -# endif -#else -# define __LITTLE_ENDIAN 1234 -# define __BIG_ENDIAN 4321 -# if defined(__hpux) -# define __BYTE_ORDER __BIG_ENDIAN -# elif defined(__QNX__) -# if defined(__BIGENDIAN__) -# define __BYTE_ORDER __BIG_ENDIAN -# elif defined(__LITTLEENDIAN__) -# define __BYTE_ORDER __LITTLE_ENDIAN -# else -# error Host has unknown byte-order. -# endif -# else -# error Host has unknown byte-order. -# endif -#endif - -#if defined(HAVE__BUILTIN_UNREACHABLE) -# define unreachable() __builtin_unreachable() -#else -# define unreachable() do { } while (1) -#endif - -#ifdef DEBUG -# define UNW_DEBUG 1 -#else -# define UNW_DEBUG 0 -#endif - -/* Make it easy to write thread-safe code which may or may not be - linked against libpthread. The macros below can be used - unconditionally and if -lpthread is around, they'll call the - corresponding routines otherwise, they do nothing. */ - -#pragma weak pthread_mutex_init -#pragma weak pthread_mutex_lock -#pragma weak pthread_mutex_unlock - -#define mutex_init(l) \ - (pthread_mutex_init != NULL ? pthread_mutex_init ((l), NULL) : 0) -#define mutex_lock(l) \ - (pthread_mutex_lock != NULL ? pthread_mutex_lock (l) : 0) -#define mutex_unlock(l) \ - (pthread_mutex_unlock != NULL ? pthread_mutex_unlock (l) : 0) - -#ifdef HAVE_ATOMIC_OPS_H -# include -static inline int -cmpxchg_ptr (void *addr, void *old, void *new) -{ - union - { - void *vp; - AO_t *aop; - } - u; - - u.vp = addr; - return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new); -} -# define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr) -# define fetch_and_add(_ptr, value) AO_fetch_and_add(_ptr, value) - /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */ -# if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2) -# define HAVE_CMPXCHG -# endif -# define HAVE_FETCH_AND_ADD -#elif defined(HAVE_SYNC_ATOMICS) || defined(HAVE_IA64INTRIN_H) -# ifdef HAVE_IA64INTRIN_H -# include -# endif -static inline int -cmpxchg_ptr (void *addr, void *old, void *new) -{ - union - { - void *vp; - long *vlp; - } - u; - - u.vp = addr; - return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new); -} -# define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1) -# define fetch_and_add(_ptr, value) __sync_fetch_and_add(_ptr, value) -# define HAVE_CMPXCHG -# define HAVE_FETCH_AND_ADD -#endif -#define atomic_read(ptr) (*(ptr)) - -#define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn)) -#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn) - -#define unwi_full_mask UNWI_ARCH_OBJ(full_mask) - -/* Type of a mask that can be used to inhibit preemption. At the - userlevel, preemption is caused by signals and hence sigset_t is - appropriate. In constrast, the Linux kernel uses "unsigned long" - to hold the processor "flags" instead. */ -typedef sigset_t intrmask_t; - -extern intrmask_t unwi_full_mask; - -/* Silence compiler warnings about variables which are used only if libunwind - is configured in a certain way */ -static inline void mark_as_used(void *v UNUSED) { -} - -#if defined(CONFIG_BLOCK_SIGNALS) -# define SIGPROCMASK(how, new_mask, old_mask) \ - sigprocmask((how), (new_mask), (old_mask)) -#else -# define SIGPROCMASK(how, new_mask, old_mask) mark_as_used(old_mask) -#endif - -/* Prefer adaptive mutexes if available */ -#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP -#define UNW_PTHREAD_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP -#else -#define UNW_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER -#endif - -#define define_lock(name) \ - pthread_mutex_t name = UNW_PTHREAD_MUTEX_INITIALIZER -#define lock_init(l) mutex_init (l) -#define lock_acquire(l,m) \ -do { \ - SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m)); \ - mutex_lock (l); \ -} while (0) -#define lock_release(l,m) \ -do { \ - mutex_unlock (l); \ - SIGPROCMASK (SIG_SETMASK, &(m), NULL); \ -} while (0) - -#define SOS_MEMORY_SIZE 16384 /* see src/mi/mempool.c */ - -#ifndef MAP_ANONYMOUS -# define MAP_ANONYMOUS MAP_ANON -#endif -#define GET_MEMORY(mem, size) \ -do { \ - /* Hopefully, mmap() goes straight through to a system call stub... */ \ - mem = mmap (NULL, size, PROT_READ | PROT_WRITE, \ - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ - if (mem == MAP_FAILED) \ - mem = NULL; \ -} while (0) - -#define unwi_find_dynamic_proc_info UNWI_OBJ(find_dynamic_proc_info) -#define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info) -#define unwi_put_dynamic_unwind_info UNWI_OBJ(put_dynamic_unwind_info) -#define unwi_dyn_remote_find_proc_info UNWI_OBJ(dyn_remote_find_proc_info) -#define unwi_dyn_remote_put_unwind_info UNWI_OBJ(dyn_remote_put_unwind_info) -#define unwi_dyn_validate_cache UNWI_OBJ(dyn_validate_cache) - -extern int unwi_find_dynamic_proc_info (unw_addr_space_t as, - unw_word_t ip, - unw_proc_info_t *pi, - int need_unwind_info, void *arg); -extern int unwi_extract_dynamic_proc_info (unw_addr_space_t as, - unw_word_t ip, - unw_proc_info_t *pi, - unw_dyn_info_t *di, - int need_unwind_info, - void *arg); -extern void unwi_put_dynamic_unwind_info (unw_addr_space_t as, - unw_proc_info_t *pi, void *arg); - -/* These handle the remote (cross-address-space) case of accessing - dynamic unwind info. */ - -extern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as, - unw_word_t ip, - unw_proc_info_t *pi, - int need_unwind_info, - void *arg); -extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as, - unw_proc_info_t *pi, - void *arg); -extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg); - -extern unw_dyn_info_list_t _U_dyn_info_list; -extern pthread_mutex_t _U_dyn_info_list_lock; - -#if UNW_DEBUG -#define unwi_debug_level UNWI_ARCH_OBJ(debug_level) -extern long unwi_debug_level; - -# include -# define Debug(level,format...) \ -do { \ - if (unwi_debug_level >= level) \ - { \ - int _n = level; \ - if (_n > 16) \ - _n = 16; \ - fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \ - fprintf (stderr, format); \ - } \ -} while (0) -# define Dprintf(format...) fprintf (stderr, format) -#else -# define Debug(level,format...) -# define Dprintf(format...) -#endif - -static ALWAYS_INLINE int -print_error (const char *string) -{ - return write (2, string, strlen (string)); -} - -#define mi_init UNWI_ARCH_OBJ(mi_init) - -extern void mi_init (void); /* machine-independent initializations */ -extern unw_word_t _U_dyn_info_list_addr (void); - -/* This is needed/used by ELF targets only. */ - -struct elf_image - { - void *image; /* pointer to mmap'd image */ - size_t size; /* (file-) size of the image */ - }; - -struct elf_dyn_info - { - struct elf_image ei; - unw_dyn_info_t di_cache; - unw_dyn_info_t di_debug; /* additional table info for .debug_frame */ -#if UNW_TARGET_IA64 - unw_dyn_info_t ktab; -#endif -#if UNW_TARGET_ARM - unw_dyn_info_t di_arm; /* additional table info for .ARM.exidx */ -#endif - }; - -static inline void invalidate_edi (struct elf_dyn_info *edi) -{ - if (edi->ei.image) - munmap (edi->ei.image, edi->ei.size); - memset (edi, 0, sizeof (*edi)); - edi->di_cache.format = -1; - edi->di_debug.format = -1; -#if UNW_TARGET_ARM - edi->di_arm.format = -1; -#endif -} - - -/* Provide a place holder for architecture to override for fast access - to memory when known not to need to validate and know the access - will be local to the process. A suitable override will improve - unw_tdep_trace() performance in particular. */ -#define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ - do { (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); } \ - while (0) - -/* Define GNU and processor specific values for the Phdr p_type field in case - they aren't defined by . */ -#ifndef PT_GNU_EH_FRAME -# define PT_GNU_EH_FRAME 0x6474e550 -#endif /* !PT_GNU_EH_FRAME */ -#ifndef PT_ARM_EXIDX -# define PT_ARM_EXIDX 0x70000001 /* ARM unwind segment */ -#endif /* !PT_ARM_EXIDX */ - -#include "tdep/libunwind_i.h" - -#ifndef tdep_get_func_addr -# define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0) -#endif - -#ifndef DWARF_VAL_LOC -# define DWARF_IS_VAL_LOC(l) 0 -# define DWARF_VAL_LOC(c,v) DWARF_NULL_LOC -#endif - -#define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) - -#endif /* libunwind_i_h */ - diff --git a/src/coreclr/src/pal/src/libunwind/include/mempool.h b/src/coreclr/src/pal/src/libunwind/include/mempool.h deleted file mode 100644 index 1f1c77009933f2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/mempool.h +++ /dev/null @@ -1,89 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 mempool_h -#define mempool_h - -/* Memory pools provide simple memory management of fixed-size - objects. Memory pools are used for two purposes: - - o To ensure a stack can be unwound even when a process - is out of memory. - - o To ensure a stack can be unwound at any time in a - multi-threaded process (e.g., even at a time when the normal - malloc-lock is taken, possibly by the very thread that is - being unwind). - - - To achieve the second objective, memory pools allocate memory - directly via mmap() system call (or an equivalent facility). - - The first objective is accomplished by reserving memory ahead of - time. Since the memory requirements of stack unwinding generally - depends on the complexity of the procedures being unwind, there is - no absolute guarantee that unwinding will always work, but in - practice, this should not be a serious problem. */ - -#include - -#include "libunwind_i.h" - -#define sos_alloc(s) UNWI_ARCH_OBJ(_sos_alloc)(s) -#define mempool_init(p,s,r) UNWI_ARCH_OBJ(_mempool_init)(p,s,r) -#define mempool_alloc(p) UNWI_ARCH_OBJ(_mempool_alloc)(p) -#define mempool_free(p,o) UNWI_ARCH_OBJ(_mempool_free)(p,o) - -/* The mempool structure should be treated as an opaque object. It's - declared here only to enable static allocation of mempools. */ -struct mempool - { - pthread_mutex_t lock; - size_t obj_size; /* object size (rounded up for alignment) */ - size_t chunk_size; /* allocation granularity */ - unsigned int reserve; /* minimum (desired) size of the free-list */ - unsigned int num_free; /* number of objects on the free-list */ - struct object - { - struct object *next; - } - *free_list; - }; - -/* Emergency allocation for one-time stuff that doesn't fit the memory - pool model. A limited amount of memory is available in this - fashion and once allocated, there is no way to free it. */ -extern void *sos_alloc (size_t size); - -/* Initialize POOL for an object size of OBJECT_SIZE bytes. RESERVE - is the number of objects that should be reserved for use under - tight memory situations. If it is zero, mempool attempts to pick a - reasonable default value. */ -extern void mempool_init (struct mempool *pool, - size_t obj_size, size_t reserve); -extern void *mempool_alloc (struct mempool *pool); -extern void mempool_free (struct mempool *pool, void *object); - -#endif /* mempool_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/remote.h b/src/coreclr/src/pal/src/libunwind/include/remote.h deleted file mode 100644 index 064d6309adb7ec..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/remote.h +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef REMOTE_H -#define REMOTE_H - -/* Helper functions for accessing (remote) memory. These functions - assume that all addresses are naturally aligned (e.g., 32-bit - quantity is stored at a 32-bit-aligned address. */ - -#ifdef UNW_LOCAL_ONLY - -static inline int -fetch8 (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, int8_t *valp, void *arg) -{ - *valp = *(int8_t *) (uintptr_t) *addr; - *addr += 1; - return 0; -} - -static inline int -fetch16 (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, int16_t *valp, void *arg) -{ - *valp = *(int16_t *) (uintptr_t) *addr; - *addr += 2; - return 0; -} - -static inline int -fetch32 (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, int32_t *valp, void *arg) -{ - *valp = *(int32_t *) (uintptr_t) *addr; - *addr += 4; - return 0; -} - -static inline int -fetchw (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, unw_word_t *valp, void *arg) -{ - *valp = *(unw_word_t *) (uintptr_t) *addr; - *addr += sizeof (unw_word_t); - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ - -#define WSIZE (sizeof (unw_word_t)) - -static inline int -fetch8 (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, int8_t *valp, void *arg) -{ - unw_word_t val, aligned_addr = *addr & -WSIZE, 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*(WSIZE - 1 - off); -#endif - *valp = val & 0xff; - return ret; -} - -static inline int -fetch16 (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, int16_t *valp, void *arg) -{ - unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; - int ret; - - if ((off & 0x1) != 0) - return -UNW_EINVAL; - - *addr += 2; - - ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); - -#if __BYTE_ORDER == __LITTLE_ENDIAN - val >>= 8*off; -#else - val >>= 8*(WSIZE - 2 - off); -#endif - *valp = val & 0xffff; - return ret; -} - -static inline int -fetch32 (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, int32_t *valp, void *arg) -{ - unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; - int ret; - - if ((off & 0x3) != 0) - return -UNW_EINVAL; - - *addr += 4; - - ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); - -#if __BYTE_ORDER == __LITTLE_ENDIAN - val >>= 8*off; -#else - val >>= 8*(WSIZE - 4 - off); -#endif - *valp = val & 0xffffffff; - return ret; -} - -static inline int -fetchw (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, unw_word_t *valp, void *arg) -{ - int ret; - - ret = (*a->access_mem) (as, *addr, valp, 0, arg); - *addr += WSIZE; - return ret; -} - -#endif /* !UNW_LOCAL_ONLY */ - -#endif /* REMOTE_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/dwarf-config.h deleted file mode 100644 index f65db17ee65888..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/dwarf-config.h +++ /dev/null @@ -1,52 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - 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 dwarf_config_h -#define dwarf_config_h - -/* This matches the value udes by GCC (see - gcc/config/aarch64/aarch64.h:DWARF_FRAME_REGISTERS. */ -#define DWARF_NUM_PRESERVED_REGS 97 - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) 0 - -#define dwarf_to_unw_regnum(reg) (((reg) <= UNW_AARCH64_V31) ? (reg) : 0) - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; -#ifndef UNW_LOCAL_ONLY - unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ -#endif - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/jmpbuf.h deleted file mode 100644 index 3f01a442baf909..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/jmpbuf.h +++ /dev/null @@ -1,33 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - 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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -/* FIXME for AArch64 */ - -#define JB_SP 13 -#define JB_RP 14 -#define JB_MASK_SAVED 15 -#define JB_MASK 16 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/libunwind_i.h deleted file mode 100644 index b91273fa1c5525..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/libunwind_i.h +++ /dev/null @@ -1,320 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - 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 AARCH64_LIBUNWIND_I_H -#define AARCH64_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#include "elf64.h" -#include "mempool.h" -#include "dwarf.h" - -typedef enum - { - UNW_AARCH64_FRAME_STANDARD = -2, /* regular fp, sp +/- offset */ - UNW_AARCH64_FRAME_SIGRETURN = -1, /* special sigreturn frame */ - UNW_AARCH64_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */ - UNW_AARCH64_FRAME_GUESSED = 1 /* guessed it was regular, but not known */ - } -unw_tdep_frame_type_t; - -typedef struct - { - uint64_t virtual_address; - int64_t frame_type : 2; /* unw_tdep_frame_type_t classification */ - int64_t last_frame : 1; /* non-zero if last frame in chain */ - int64_t cfa_reg_sp : 1; /* cfa dwarf base register is sp vs. fp */ - int64_t cfa_reg_offset : 30; /* cfa is at this offset from base register value */ - int64_t fp_cfa_offset : 30; /* fp saved at this offset from cfa (-1 = not saved) */ - int64_t lr_cfa_offset : 30; /* lr saved at this offset from cfa (-1 = not saved) */ - int64_t sp_cfa_offset : 30; /* sp saved at this offset from cfa (-1 = not saved) */ - } -unw_tdep_frame_t; - -#ifdef UNW_LOCAL_ONLY - -typedef unw_word_t aarch64_loc_t; - -#else /* !UNW_LOCAL_ONLY */ - -typedef struct aarch64_loc - { - unw_word_t w0, w1; - } -aarch64_loc_t; - -#endif /* !UNW_LOCAL_ONLY */ - -struct unw_addr_space - { - struct unw_accessors acc; - int big_endian; - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; - }; - -struct cursor - { - struct dwarf_cursor dwarf; /* must be first */ - - unw_tdep_frame_t frame_info; /* quick tracing assist info */ - - enum - { - AARCH64_SCF_NONE, - AARCH64_SCF_LINUX_RT_SIGFRAME, - } - sigcontext_format; - unw_word_t sigcontext_addr; - unw_word_t sigcontext_sp; - unw_word_t sigcontext_pc; - int validate; - }; - -#define DWARF_GET_LOC(l) ((l).val) - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) -# define DWARF_IS_REG_LOC(l) 0 -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_word_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_word_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - val, 0, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 0, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, - c->as_arg); -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - &val, 1, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 1, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, - 1, c->as_arg); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - - - -#define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace) -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_uc_addr UNW_OBJ(uc_addr) -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,frame) do {} while(0) -#define tdep_stash_frame UNW_OBJ(tdep_stash_frame) -#define tdep_trace UNW_OBJ(tdep_trace) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) -#define tdep_big_endian(as) ((as)->big_endian) - -extern int tdep_init_done; - -extern void tdep_init (void); -extern int tdep_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); -extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t *valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t *valp, int write); -extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); -extern void tdep_stash_frame (struct dwarf_cursor *c, - struct dwarf_reg_state *rs); -extern int tdep_getcontext_trace (unw_tdep_context_t *); - -#endif /* AARCH64_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/dwarf-config.h deleted file mode 100644 index f50228975ecbb6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/dwarf-config.h +++ /dev/null @@ -1,51 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - -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_config_h -#define dwarf_config_h - -/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not - explicitly defined. */ -#define DWARF_NUM_PRESERVED_REGS 128 - -#define dwarf_to_unw_regnum(reg) (((reg) < 16) ? (reg) : 0) - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) 0 - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; -#ifndef UNW_LOCAL_ONLY - unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ -#endif - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/ex_tables.h b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/ex_tables.h deleted file mode 100644 index 9df5e0a9fa4b9b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/ex_tables.h +++ /dev/null @@ -1,55 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright 2011 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 ARM_EX_TABLES_H -#define ARM_EX_TABLES_H - -typedef enum arm_exbuf_cmd { - ARM_EXIDX_CMD_FINISH, - ARM_EXIDX_CMD_DATA_PUSH, - ARM_EXIDX_CMD_DATA_POP, - ARM_EXIDX_CMD_REG_POP, - ARM_EXIDX_CMD_REG_TO_SP, - ARM_EXIDX_CMD_VFP_POP, - ARM_EXIDX_CMD_WREG_POP, - ARM_EXIDX_CMD_WCGR_POP, - ARM_EXIDX_CMD_RESERVED, - ARM_EXIDX_CMD_REFUSED, -} arm_exbuf_cmd_t; - -struct arm_exbuf_data -{ - arm_exbuf_cmd_t cmd; - uint32_t data; -}; - -#define arm_exidx_extract UNW_OBJ(arm_exidx_extract) -#define arm_exidx_decode UNW_OBJ(arm_exidx_decode) -#define arm_exidx_apply_cmd UNW_OBJ(arm_exidx_apply_cmd) - -int arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf); -int arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c); -int arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c); - -#endif // ARM_EX_TABLES_H diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/jmpbuf.h deleted file mode 100644 index 008e77f79600b7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/jmpbuf.h +++ /dev/null @@ -1,32 +0,0 @@ -/* 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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -/* FIXME for ARM! */ - -#define JB_SP 4 -#define JB_RP 5 -#define JB_MASK_SAVED 6 -#define JB_MASK 7 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h deleted file mode 100644 index 2602f41c4f79fc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h +++ /dev/null @@ -1,326 +0,0 @@ -/* 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 ARM_LIBUNWIND_I_H -#define ARM_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#include "elf32.h" -#include "mempool.h" -#include "dwarf.h" -#include "ex_tables.h" - -typedef enum - { - UNW_ARM_FRAME_SYSCALL = -3, /* r7 saved in r12, sp offset zero */ - UNW_ARM_FRAME_STANDARD = -2, /* regular r7, sp +/- offset */ - UNW_ARM_FRAME_SIGRETURN = -1, /* special sigreturn frame */ - UNW_ARM_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */ - UNW_ARM_FRAME_GUESSED = 1 /* guessed it was regular, but not known */ - } -unw_tdep_frame_type_t; - -typedef struct - { - uint32_t virtual_address; - int32_t frame_type : 3; /* unw_tdep_frame_type_t classification */ - int32_t last_frame : 1; /* non-zero if last frame in chain */ - int32_t cfa_reg_sp : 1; /* cfa dwarf base register is sp vs. r7 */ - int32_t cfa_reg_offset : 30; /* cfa is at this offset from base register value */ - int32_t r7_cfa_offset : 30; /* r7 saved at this offset from cfa (-1 = not saved) */ - int32_t lr_cfa_offset : 30; /* lr saved at this offset from cfa (-1 = not saved) */ - int32_t sp_cfa_offset : 30; /* sp saved at this offset from cfa (-1 = not saved) */ - } -unw_tdep_frame_t; - -struct unw_addr_space - { - struct unw_accessors acc; - int big_endian; - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; - }; - -struct cursor - { - struct dwarf_cursor dwarf; /* must be first */ - - unw_tdep_frame_t frame_info; /* quick tracing assist info */ - - enum - { - ARM_SCF_NONE, /* no signal frame */ - ARM_SCF_LINUX_SIGFRAME, /* non-RT signal frame, kernel >=2.6.18 */ - ARM_SCF_LINUX_RT_SIGFRAME, /* RT signal frame, kernel >=2.6.18 */ - ARM_SCF_LINUX_OLD_SIGFRAME, /* non-RT signal frame, kernel < 2.6.18 */ - ARM_SCF_LINUX_OLD_RT_SIGFRAME, /* RT signal frame, kernel < 2.6.18 */ - ARM_SCF_FREEBSD_SIGFRAME, /* FreeBSD sigframe */ - ARM_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall stub */ - } - sigcontext_format; - unw_word_t sigcontext_addr; - unw_word_t sigcontext_sp; - unw_word_t sigcontext_pc; - int validate; - }; - -#define DWARF_GET_LOC(l) ((l).val) - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) -# define DWARF_IS_REG_LOC(l) 0 -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_word_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_word_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - val, 0, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 0, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, - c->as_arg); -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - &val, 1, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 1, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, - 1, c->as_arg); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_init UNW_OBJ(init) -#define arm_find_proc_info UNW_OBJ(find_proc_info) -#define arm_put_unwind_info UNW_OBJ(put_unwind_info) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table UNW_OBJ(search_unwind_table) -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,frame) do {} while(0) -#define tdep_stash_frame UNW_OBJ(tdep_stash_frame) -#define tdep_trace UNW_OBJ(tdep_trace) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - arm_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - arm_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) -#define tdep_big_endian(as) ((as)->big_endian) - -extern int tdep_init_done; - -extern void tdep_init (void); -extern int arm_find_proc_info (unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, int need_unwind_info, - void *arg); -extern void arm_put_unwind_info (unw_addr_space_t as, - unw_proc_info_t *pi, void *arg); -extern int tdep_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); -extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t *valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t *valp, int write); -extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); -extern void tdep_stash_frame (struct dwarf_cursor *c, - struct dwarf_reg_state *rs); - -/* unwinding method selection support */ -#define UNW_ARM_METHOD_ALL 0xFF -#define UNW_ARM_METHOD_DWARF 0x01 -#define UNW_ARM_METHOD_FRAME 0x02 -#define UNW_ARM_METHOD_EXIDX 0x04 - -#define unwi_unwind_method UNW_OBJ(unwind_method) -extern int unwi_unwind_method; - -#define UNW_TRY_METHOD(x) (unwi_unwind_method & x) - -#endif /* ARM_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/dwarf-config.h deleted file mode 100644 index fb963c7d30778a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/dwarf-config.h +++ /dev/null @@ -1,54 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -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_config_h -#define dwarf_config_h - -/* See DWARF_FRAME_REGNUM() macro in gcc/config/pa/pa32-regs.h: */ -#define dwarf_to_unw_regnum(reg) \ - (((reg) < DWARF_NUM_PRESERVED_REGS) ? (reg) : 0) - -/* This matches the value used by GCC (see - gcc/config/pa/pa32-regs.h:FIRST_PSEUDO_REGISTER), which leaves - plenty of room for expansion. */ -#define DWARF_NUM_PRESERVED_REGS 89 - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) 1 - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; -#ifndef UNW_LOCAL_ONLY - unw_word_t type; /* see X86_LOC_TYPE_* macros. */ -#endif - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/jmpbuf.h deleted file mode 100644 index 91f062ff7dffb6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/jmpbuf.h +++ /dev/null @@ -1,33 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -#ifndef JB_SP -# define JB_SP 19 -#endif -#define JB_RP 20 -#define JB_MASK_SAVED 21 -#define JB_MASK 22 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/libunwind_i.h deleted file mode 100644 index 72649aa3ecc559..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/libunwind_i.h +++ /dev/null @@ -1,279 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 HPPA_LIBUNWIND_I_H -#define HPPA_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#include "elf32.h" -#include "mempool.h" -#include "dwarf.h" - -typedef struct - { - /* no hppa-specific fast trace */ - } -unw_tdep_frame_t; - -struct unw_addr_space - { - struct unw_accessors acc; - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; - }; - -struct cursor - { - struct dwarf_cursor dwarf; /* must be first */ - - /* Format of sigcontext structure and address at which it is - stored: */ - enum - { - HPPA_SCF_NONE, /* no signal frame encountered */ - HPPA_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ - } - sigcontext_format; - unw_word_t sigcontext_addr; - }; - -#define DWARF_GET_LOC(l) ((l).val) - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) -# define DWARF_IS_REG_LOC(l) 0 -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_word_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_word_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - val, 0, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 0, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, - c->as_arg); -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - &val, 1, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 1, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, - 1, c->as_arg); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,frame) do {} while(0) -#define tdep_stash_frame(c,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) -#define tdep_big_endian(as) 1 - -extern int tdep_init_done; - -extern void tdep_init (void); -extern int tdep_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); -extern void *tdep_uc_addr (ucontext_t *uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t *valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t *valp, int write); - -#endif /* HPPA_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/jmpbuf.h deleted file mode 100644 index d642af2075a165..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/jmpbuf.h +++ /dev/null @@ -1,32 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP and BSP: */ - -#define JB_SP 0 -#define JB_RP 8 -#define JB_BSP 17 -#define JB_MASK_SAVED 70 -#define JB_MASK 71 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/libunwind_i.h deleted file mode 100644 index 1d9770bab8564f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/libunwind_i.h +++ /dev/null @@ -1,281 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 IA64_LIBUNWIND_I_H -#define IA64_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include "elf64.h" -#include "mempool.h" - -typedef struct - { - /* no ia64-specific fast trace */ - } -unw_tdep_frame_t; - -enum ia64_pregnum - { - /* primary unat: */ - IA64_REG_PRI_UNAT_GR, - IA64_REG_PRI_UNAT_MEM, - - /* memory stack (order matters: see build_script() */ - IA64_REG_PSP, /* previous memory stack pointer */ - /* register stack */ - IA64_REG_BSP, /* register stack pointer */ - IA64_REG_BSPSTORE, - IA64_REG_PFS, /* previous function state */ - IA64_REG_RNAT, - /* instruction pointer: */ - IA64_REG_IP, - - /* preserved registers: */ - IA64_REG_R4, IA64_REG_R5, IA64_REG_R6, IA64_REG_R7, - IA64_REG_NAT4, IA64_REG_NAT5, IA64_REG_NAT6, IA64_REG_NAT7, - IA64_REG_UNAT, IA64_REG_PR, IA64_REG_LC, IA64_REG_FPSR, - IA64_REG_B1, IA64_REG_B2, IA64_REG_B3, IA64_REG_B4, IA64_REG_B5, - IA64_REG_F2, IA64_REG_F3, IA64_REG_F4, IA64_REG_F5, - IA64_REG_F16, IA64_REG_F17, IA64_REG_F18, IA64_REG_F19, - IA64_REG_F20, IA64_REG_F21, IA64_REG_F22, IA64_REG_F23, - IA64_REG_F24, IA64_REG_F25, IA64_REG_F26, IA64_REG_F27, - IA64_REG_F28, IA64_REG_F29, IA64_REG_F30, IA64_REG_F31, - IA64_NUM_PREGS - }; - -#ifdef UNW_LOCAL_ONLY - -typedef unw_word_t ia64_loc_t; - -#else /* !UNW_LOCAL_ONLY */ - -typedef struct ia64_loc - { - unw_word_t w0, w1; - } -ia64_loc_t; - -#endif /* !UNW_LOCAL_ONLY */ - -#include "script.h" - -#define ABI_UNKNOWN 0 -#define ABI_LINUX 1 -#define ABI_HPUX 2 -#define ABI_FREEBSD 3 -#define ABI_OPENVMS 4 -#define ABI_NSK 5 /* Tandem/HP Non-Stop Kernel */ -#define ABI_WINDOWS 6 - -struct unw_addr_space - { - struct unw_accessors acc; - int big_endian; - int abi; /* abi < 0 => unknown, 0 => SysV, 1 => HP-UX, 2 => Windows */ - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ -#ifndef UNW_REMOTE_ONLY - unsigned long long shared_object_removals; -#endif - - struct ia64_script_cache global_cache; - }; - -/* Note: The ABI numbers in the ABI-markers (.unwabi directive) are - not the same as the above ABI numbers. */ -#define ABI_MARKER_OLD_LINUX_SIGTRAMP ((0 << 8) | 's') -#define ABI_MARKER_OLD_LINUX_INTERRUPT ((0 << 8) | 'i') -#define ABI_MARKER_HP_UX_SIGTRAMP ((1 << 8) | 1) -#define ABI_MARKER_LINUX_SIGTRAMP ((3 << 8) | 's') -#define ABI_MARKER_LINUX_INTERRUPT ((3 << 8) | 'i') - -struct cursor - { - void *as_arg; /* argument to address-space callbacks */ - unw_addr_space_t as; /* reference to per-address-space info */ - - /* IP, CFM, and predicate cache (these are always equal to the - values stored in ip_loc, cfm_loc, and pr_loc, - respectively). */ - unw_word_t ip; /* instruction pointer value */ - unw_word_t cfm; /* current frame mask */ - unw_word_t pr; /* current predicate values */ - - /* current frame info: */ - unw_word_t bsp; /* backing store pointer value */ - unw_word_t sp; /* stack pointer value */ - unw_word_t psp; /* previous sp value */ - ia64_loc_t cfm_loc; /* cfm save location (or NULL) */ - ia64_loc_t ec_loc; /* ar.ec save location (usually cfm_loc) */ - ia64_loc_t loc[IA64_NUM_PREGS]; - - unw_word_t eh_args[4]; /* exception handler arguments */ - unw_word_t sigcontext_addr; /* address of sigcontext or 0 */ - unw_word_t sigcontext_off; /* sigcontext-offset relative to signal sp */ - - short hint; - short prev_script; - - uint8_t nat_bitnr[4]; /* NaT bit numbers for r4-r7 */ - uint16_t abi_marker; /* abi_marker for current frame (if any) */ - uint16_t last_abi_marker; /* last abi_marker encountered so far */ - uint8_t eh_valid_mask; - - 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 */ - - /* In case of stack-discontiguities, such as those introduced by - signal-delivery on an alternate signal-stack (see - sigaltstack(2)), we use the following data-structure to keep - track of the register-backing-store areas across on which the - current frame may be backed up. Since there are at most 96 - stacked registers and since we only have to track the current - frame and only areas that are not empty, this puts an upper - limit on the # of backing-store areas we have to track. - - Note that the rbs-area indexed by rbs_curr identifies the - rbs-area that was in effect at the time AR.BSP had the value - c->bsp. However, this rbs area may not actually contain the - value in the register that c->bsp corresponds to because that - register may not have gotten spilled until much later, when a - possibly different rbs-area might have been in effect - already. */ - uint8_t rbs_curr; /* index of curr. rbs-area (contains c->bsp) */ - uint8_t rbs_left_edge; /* index of inner-most valid rbs-area */ - struct rbs_area - { - unw_word_t end; - unw_word_t size; - ia64_loc_t rnat_loc; - } - rbs_area[96 + 2]; /* 96 stacked regs + 1 extra stack on each side... */ -}; - -struct ia64_global_unwind_state - { - pthread_mutex_t lock; /* global data lock */ - - volatile char init_done; - - /* Table of registers that prologues can save (and order in which - they're saved). */ - const unsigned char save_order[8]; - - /* - * uc_addr() may return pointers to these variables. We need to - * make sure they don't get written via ia64_put() or - * ia64_putfp(). To make it possible to test for these variables - * quickly, we collect them in a single sub-structure. - */ - struct - { - unw_word_t r0; /* r0 is byte-order neutral */ - unw_fpreg_t f0; /* f0 is byte-order neutral */ - unw_fpreg_t f1_le, f1_be; /* f1 is byte-order dependent */ - } - read_only; - unw_fpreg_t nat_val_le, nat_val_be; - unw_fpreg_t int_val_le, int_val_be; - - struct mempool reg_state_pool; - struct mempool labeled_state_pool; - -# if UNW_DEBUG - const char *preg_name[IA64_NUM_PREGS]; -# endif - }; - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done unw.init_done -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table unw_search_ia64_unwind_table -#define tdep_find_unwind_table ia64_find_unwind_table -#define tdep_find_proc_info UNW_OBJ(find_proc_info) -#define tdep_uc_addr UNW_OBJ(uc_addr) -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,frame) do {} while(0) -#define tdep_stash_frame(c,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) -#define tdep_get_as(c) ((c)->as) -#define tdep_get_as_arg(c) ((c)->as_arg) -#define tdep_get_ip(c) ((c)->ip) -#define tdep_big_endian(as) ((c)->as->big_endian != 0) - -#ifndef UNW_LOCAL_ONLY -# define tdep_put_unwind_info UNW_OBJ(put_unwind_info) -#endif - -/* This can't be an UNW_ARCH_OBJ() because we need separate - unw.initialized flags for the local-only and generic versions of - the library. Also, if we wanted to have a single, shared global - data structure, we couldn't declare "unw" as HIDDEN. */ -#define unw UNW_OBJ(data) - -extern void tdep_init (void); -extern int tdep_find_unwind_table (struct elf_dyn_info *edi, - unw_addr_space_t as, char *path, - unw_word_t segbase, unw_word_t mapoff, - unw_word_t ip); -extern int tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, int need_unwind_info, - void *arg); -extern void tdep_put_unwind_info (unw_addr_space_t as, - unw_proc_info_t *pi, void *arg); -extern void *tdep_uc_addr (ucontext_t *uc, unw_regnum_t regnum, - uint8_t *nat_bitnr); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t *valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t *valp, int write); - -extern struct ia64_global_unwind_state unw; - -/* In user-level, we have no reasonable way of determining the base of - an arbitrary backing-store. We default to half the - address-space. */ -#define rbs_get_base(c,bspstore,rbs_basep) \ - (*(rbs_basep) = (bspstore) - (((unw_word_t) 1) << 63), 0) - -#endif /* IA64_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/rse.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/rse.h deleted file mode 100644 index ee521a5917abf8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/rse.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 1998, 1999, 2002, 2003, 2005 Hewlett-Packard Co - * David Mosberger-Tang - * - * Register stack engine related helper functions. This file may be - * used in applications, so be careful about the name-space and give - * some consideration to non-GNU C compilers (though __inline__ is - * fine). - */ -#ifndef RSE_H -#define RSE_H - -#include - -static inline uint64_t -rse_slot_num (uint64_t addr) -{ - return (addr >> 3) & 0x3f; -} - -/* - * Return TRUE if ADDR is the address of an RNAT slot. - */ -static inline uint64_t -rse_is_rnat_slot (uint64_t addr) -{ - return rse_slot_num (addr) == 0x3f; -} - -/* - * Returns the address of the RNAT slot that covers the slot at - * address SLOT_ADDR. - */ -static inline uint64_t -rse_rnat_addr (uint64_t slot_addr) -{ - return slot_addr | (0x3f << 3); -} - -/* - * Calculate the number of registers in the dirty partition starting at - * BSPSTORE and ending at BSP. This isn't simply (BSP-BSPSTORE)/8 - * because every 64th slot stores ar.rnat. - */ -static inline uint64_t -rse_num_regs (uint64_t bspstore, uint64_t bsp) -{ - uint64_t slots = (bsp - bspstore) >> 3; - - return slots - (rse_slot_num(bspstore) + slots)/0x40; -} - -/* - * The inverse of the above: given bspstore and the number of - * registers, calculate ar.bsp. - */ -static inline uint64_t -rse_skip_regs (uint64_t addr, long num_regs) -{ - long delta = rse_slot_num(addr) + num_regs; - - if (num_regs < 0) - delta -= 0x3e; - return addr + ((num_regs + delta/0x3f) << 3); -} - -#endif /* RSE_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/script.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/script.h deleted file mode 100644 index fe3360bf5829d3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/script.h +++ /dev/null @@ -1,85 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -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 IA64_LOG_UNW_CACHE_SIZE 7 -#define IA64_UNW_CACHE_SIZE (1 << IA64_LOG_UNW_CACHE_SIZE) - -#define IA64_LOG_UNW_HASH_SIZE (IA64_LOG_UNW_CACHE_SIZE + 1) -#define IA64_UNW_HASH_SIZE (1 << IA64_LOG_UNW_HASH_SIZE) - -typedef unsigned char unw_hash_index_t; - -struct ia64_script_insn - { - unsigned int opc; /* see enum ia64_script_insn_opcode */ - unsigned int dst; - unw_word_t val; - }; - -/* Updating each preserved register may result in one script - instruction each. At the end of the script, psp gets popped, - accounting for one more instruction. */ -#define IA64_MAX_SCRIPT_LEN (IA64_NUM_PREGS + 1) - -struct ia64_script - { - unw_word_t ip; /* ip this script is for */ - unw_word_t pr_mask; /* mask of predicates script depends on */ - unw_word_t pr_val; /* predicate values this script is for */ - unw_proc_info_t pi; /* info about underlying procedure */ - unsigned short lru_chain; /* used for least-recently-used chain */ - unsigned short coll_chain; /* used for hash collisions */ - unsigned short hint; /* hint for next script to try (or -1) */ - unsigned short count; /* number of instructions in script */ - unsigned short abi_marker; - struct ia64_script_insn insn[IA64_MAX_SCRIPT_LEN]; - }; - -struct ia64_script_cache - { -#ifdef HAVE_ATOMIC_OPS_H - AO_TS_t busy; /* is the script-cache busy? */ -#else - pthread_mutex_t lock; -#endif - unsigned short lru_head; /* index of lead-recently used script */ - unsigned short lru_tail; /* index of most-recently used script */ - - /* hash table that maps instruction pointer to script index: */ - unsigned short hash[IA64_UNW_HASH_SIZE]; - - uint32_t generation; /* generation number */ - - /* script cache: */ - struct ia64_script buckets[IA64_UNW_CACHE_SIZE]; - }; - -#define ia64_cache_proc_info UNW_OBJ(cache_proc_info) -#define ia64_get_cached_proc_info UNW_OBJ(get_cached_proc_info) - -struct cursor; /* forward declaration */ - -extern int ia64_cache_proc_info (struct cursor *c); -extern int ia64_get_cached_proc_info (struct cursor *c); diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h deleted file mode 100644 index 8006d0b8dd4fe2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h +++ /dev/null @@ -1,54 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - -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_config_h -#define dwarf_config_h - -/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not - explicitly defined. */ -#define DWARF_NUM_PRESERVED_REGS 188 - -#define dwarf_to_unw_regnum(reg) (((reg) < 32) ? (reg) : 0) - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) - -/* Return the size of an address, for DWARF purposes. */ -#define dwarf_addr_size(addr_space) ((addr_space)->addr_size) - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; -#ifndef UNW_LOCAL_ONLY - unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ -#endif - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/jmpbuf.h deleted file mode 100644 index c099f9267e204b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/jmpbuf.h +++ /dev/null @@ -1,32 +0,0 @@ -/* 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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -/* FIXME for MIPS! */ - -#define JB_SP 4 -#define JB_RP 5 -#define JB_MASK_SAVED 6 -#define JB_MASK 7 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h deleted file mode 100644 index 3fe40c0c053195..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h +++ /dev/null @@ -1,331 +0,0 @@ -/* 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 MIPS_LIBUNWIND_I_H -#define MIPS_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#if !defined(UNW_REMOTE_ONLY) && _MIPS_SIM == _ABI64 -# include "elf64.h" -#else -# include "elf32.h" -#endif -#include "mempool.h" -#include "dwarf.h" - -typedef struct - { - /* no mips-specific fast trace */ - } -unw_tdep_frame_t; - -struct unw_addr_space - { - struct unw_accessors acc; - - int big_endian; - mips_abi_t abi; - unsigned int addr_size; - - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; -}; - -#define tdep_big_endian(as) ((as)->big_endian) - -struct cursor - { - struct dwarf_cursor dwarf; /* must be first */ - unw_word_t sigcontext_addr; - }; - -#define DWARF_GET_LOC(l) ((l).val) - -#ifndef UNW_REMOTE_ONLY -# if _MIPS_SIM == _ABIN32 -typedef long long mips_reg_t; -# else -typedef long mips_reg_t; -# endif -#endif - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) -# define DWARF_IS_REG_LOC(l) 0 -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) - -/* FIXME: Implement these for the MIPS FPU. */ -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_fpreg_t *) (intptr_t) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_fpreg_t *) (intptr_t) DWARF_GET_LOC (loc) = val; - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(mips_reg_t *) (intptr_t) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(mips_reg_t *) (intptr_t) DWARF_GET_LOC (loc) = val; - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -static inline int -read_s32 (struct dwarf_cursor *c, unw_word_t addr, unw_word_t *val) -{ - int offset = addr & 4; - int ret; - unw_word_t memval; - - ret = (*c->as->acc.access_mem) (c->as, addr - offset, &memval, 0, c->as_arg); - if (ret < 0) - return ret; - - if ((offset != 0) == tdep_big_endian (c->as)) - *val = (int32_t) memval; - else - *val = (int32_t) (memval >> 32); - - return 0; -} - -static inline int -write_s32 (struct dwarf_cursor *c, unw_word_t addr, const unw_word_t *val) -{ - int offset = addr & 4; - int ret; - unw_word_t memval; - - ret = (*c->as->acc.access_mem) (c->as, addr - offset, &memval, 0, c->as_arg); - if (ret < 0) - return ret; - - if ((offset != 0) == tdep_big_endian (c->as)) - memval = (memval & ~0xffffffffLL) | (uint32_t) *val; - else - memval = (memval & 0xffffffffLL) | (uint32_t) (*val << 32); - - return (*c->as->acc.access_mem) (c->as, addr - offset, &memval, 1, c->as_arg); -} - -/* FIXME: Implement these for the MIPS FPU. */ -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - val, 0, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 0, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, - c->as_arg); -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - &val, 1, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 1, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, - 1, c->as_arg); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - else if (c->as->abi == UNW_MIPS_ABI_O32) - return read_s32 (c, DWARF_GET_LOC (loc), val); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - else if (c->as->abi == UNW_MIPS_ABI_O32) - return write_s32 (c, DWARF_GET_LOC (loc), &val); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,frame) do {} while(0) -#define tdep_stash_frame(c,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) - -extern int tdep_init_done; - -extern void tdep_init (void); -extern int tdep_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); -extern void *tdep_uc_addr (ucontext_t *uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t *valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t *valp, int write); - -#endif /* MIPS_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/dwarf-config.h deleted file mode 100644 index bf6886b066b135..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/dwarf-config.h +++ /dev/null @@ -1,56 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - - Copied from libunwind-x86_64.h, modified slightly for building - frysk successfully on ppc64, by Wu Zhou - 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 dwarf_config_h -#define dwarf_config_h - -/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */ -#define DWARF_NUM_PRESERVED_REGS 115 - -#define DWARF_REGNUM_MAP_LENGTH 115 - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) 1 - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; -#ifndef UNW_LOCAL_ONLY - unw_word_t type; /* see X86_LOC_TYPE_* macros. */ -#endif - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/jmpbuf.h deleted file mode 100644 index 861e94d9712fea..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/jmpbuf.h +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - - Copied from libunwind-x86_64.h, modified slightly for building - frysk successfully on ppc64, by Wu Zhou - 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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -#define JB_SP 6 -#define JB_RP 7 -#define JB_MASK_SAVED 8 -#define JB_MASK 9 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/libunwind_i.h deleted file mode 100644 index 4cf6d135f63ff6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/libunwind_i.h +++ /dev/null @@ -1,314 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - - Copied from libunwind-x86_64.h, modified slightly for building - frysk successfully on ppc64, by Wu Zhou - 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 PPC32_LIBUNWIND_I_H -#define PPC32_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#include "elf32.h" -#include "mempool.h" -#include "dwarf.h" - -typedef struct - { - /* no ppc32-specific fast trace */ - } -unw_tdep_frame_t; - -struct unw_addr_space -{ - struct unw_accessors acc; - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; - int validate; -}; - -struct cursor -{ - struct dwarf_cursor dwarf; /* must be first */ - - /* Format of sigcontext structure and address at which it is - stored: */ - enum - { - PPC_SCF_NONE, /* no signal frame encountered */ - PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ - } - sigcontext_format; - unw_word_t sigcontext_addr; -}; - -#define DWARF_GET_LOC(l) ((l).val) - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) -# define DWARF_IS_REG_LOC(l) 0 -# define DWARF_IS_FP_LOC(l) 0 -# define DWARF_IS_V_LOC(l) 0 -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -#else /* !UNW_LOCAL_ONLY */ - -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_LOC_TYPE_V (1 << 2) -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) -# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_V)) - -#endif /* !UNW_LOCAL_ONLY */ - -static inline int -dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) -{ - unw_word_t *valp = (unw_word_t *) val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - assert (DWARF_IS_V_LOC (loc)); - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - val, 0, c->as_arg); - - addr = DWARF_GET_LOC (loc); - - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, - 0, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg); -} - -static inline int -dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - unw_word_t *valp = (unw_word_t *) & val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - assert (DWARF_IS_V_LOC (loc)); - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - &val, 1, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, - 1, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg); -} - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) -{ - unw_word_t *valp = (unw_word_t *) val; - unw_word_t addr; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - assert (DWARF_IS_FP_LOC (loc)); - assert (!DWARF_IS_V_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - val, 0, c->as_arg); - - addr = DWARF_GET_LOC (loc); - return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg); - -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - unw_word_t *valp = (unw_word_t *) & val; - unw_word_t addr; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - assert (DWARF_IS_FP_LOC (loc)); - assert (!DWARF_IS_V_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - &val, 1, c->as_arg); - - addr = DWARF_GET_LOC (loc); - - return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 1, c->as_arg); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - assert (!DWARF_IS_V_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - assert (!DWARF_IS_V_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,frame) do {} while(0) -#define tdep_stash_frame(c,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) -#define tdep_get_func_addr UNW_OBJ(get_func_addr) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip, - int need_unwind_info); - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) -#define tdep_big_endian(as) 1 - -extern int tdep_init_done; - -extern void tdep_init (void); -extern int tdep_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); -extern void *tdep_uc_addr (ucontext_t * uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t * valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t * valp, int write); -extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, - unw_word_t *entry_point); - -#endif /* PPC64_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/dwarf-config.h deleted file mode 100644 index 6d8ef0a9404749..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/dwarf-config.h +++ /dev/null @@ -1,56 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - - Copied from libunwind-x86_64.h, modified slightly for building - frysk successfully on ppc64, by Wu Zhou - 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 dwarf_config_h -#define dwarf_config_h - -/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */ -#define DWARF_NUM_PRESERVED_REGS 115 - -#define DWARF_REGNUM_MAP_LENGTH 115 - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; -#ifndef UNW_LOCAL_ONLY - unw_word_t type; /* see X86_LOC_TYPE_* macros. */ -#endif - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/jmpbuf.h deleted file mode 100644 index 861e94d9712fea..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/jmpbuf.h +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - - Copied from libunwind-x86_64.h, modified slightly for building - frysk successfully on ppc64, by Wu Zhou - 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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -#define JB_SP 6 -#define JB_RP 7 -#define JB_MASK_SAVED 8 -#define JB_MASK 9 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/libunwind_i.h deleted file mode 100644 index 975f3bb3662add..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/libunwind_i.h +++ /dev/null @@ -1,369 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - - Copied from libunwind-x86_64.h, modified slightly for building - frysk successfully on ppc64, by Wu Zhou - 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 PPC64_LIBUNWIND_I_H -#define PPC64_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#include "elf64.h" -#include "mempool.h" -#include "dwarf.h" - -typedef struct - { - /* no ppc64-specific fast trace */ - } -unw_tdep_frame_t; - -struct unw_addr_space -{ - struct unw_accessors acc; - int big_endian; - ppc64_abi_t abi; - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; - int validate; -}; - -struct cursor -{ - struct dwarf_cursor dwarf; /* must be first */ - - /* Format of sigcontext structure and address at which it is - stored: */ - enum - { - PPC_SCF_NONE, /* no signal frame encountered */ - PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ - } - sigcontext_format; - unw_word_t sigcontext_addr; -}; - -#define DWARF_GET_LOC(l) ((l).val) - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) -# define DWARF_IS_REG_LOC(l) 0 -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) - -static inline int -dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_word_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_word_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ - -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_LOC_TYPE_V (1 << 2) -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) -# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_V)) - -static inline int -dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) -{ - unw_word_t *valp = (unw_word_t *) val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - assert (DWARF_IS_V_LOC (loc)); - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - val, 0, c->as_arg); - - addr = DWARF_GET_LOC (loc); - - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, - 0, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg); -} - -static inline int -dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - unw_word_t *valp = (unw_word_t *) & val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - assert (DWARF_IS_V_LOC (loc)); - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - &val, 1, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, - 1, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg); -} - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) -{ - unw_word_t *valp = (unw_word_t *) val; - unw_word_t addr; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - assert (DWARF_IS_FP_LOC (loc)); - assert (!DWARF_IS_V_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - val, 0, c->as_arg); - - addr = DWARF_GET_LOC (loc); - return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg); - -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - unw_word_t *valp = (unw_word_t *) & val; - unw_word_t addr; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - assert (DWARF_IS_FP_LOC (loc)); - assert (!DWARF_IS_V_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - &val, 1, c->as_arg); - - addr = DWARF_GET_LOC (loc); - - return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 1, c->as_arg); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - assert (!DWARF_IS_V_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - assert (!DWARF_IS_V_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,frame) do {} while(0) -#define tdep_stash_frame(c,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) -#define tdep_get_func_addr UNW_OBJ(get_func_addr) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip, - int need_unwind_info); - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) -#define tdep_big_endian(as) ((as)->big_endian) - -extern int tdep_init_done; - -extern void tdep_init (void); -extern int tdep_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); -extern void *tdep_uc_addr (ucontext_t * uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t * valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t * valp, int write); -extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, - unw_word_t *entry_point); - -#endif /* PPC64_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-sh/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-sh/dwarf-config.h deleted file mode 100644 index 2f76f5be7f4c3b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-sh/dwarf-config.h +++ /dev/null @@ -1,49 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - -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_config_h -#define dwarf_config_h - -#define DWARF_NUM_PRESERVED_REGS 18 - -#define dwarf_to_unw_regnum(reg) (((reg) <= UNW_SH_PR) ? (reg) : 0) - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; -#ifndef UNW_LOCAL_ONLY - unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ -#endif - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-sh/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-sh/jmpbuf.h deleted file mode 100644 index 8b44b5b219a289..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-sh/jmpbuf.h +++ /dev/null @@ -1,48 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - -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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -/* SH4 glibc jump buffer contents: - * 0. r8 - * 1. r9 - * 2. r10 - * 3. r11 - * 4. r12 - * 5. r13 - * 6. r14 - * 7. r15 - * 8. pr/pc - * 9. gbr - * 10. fpscr - * 11. fr12 - * 12. fr13 - * 13. fr14 - * 14. fr15 - */ - -#define JB_SP 7 -#define JB_RP 8 -#define JB_MASK_SAVED 15 -#define JB_MASK 16 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-sh/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-sh/libunwind_i.h deleted file mode 100644 index 8ced49104b5c82..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-sh/libunwind_i.h +++ /dev/null @@ -1,280 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - -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 SH_LIBUNWIND_I_H -#define SH_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#include "elf32.h" -#include "mempool.h" -#include "dwarf.h" - -typedef struct - { - /* no sh-specific fast trace */ - } -unw_tdep_frame_t; - -struct unw_addr_space - { - struct unw_accessors acc; - int big_endian; - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; - }; - -struct cursor - { - struct dwarf_cursor dwarf; /* must be first */ - enum - { - SH_SCF_NONE, /* no signal frame */ - SH_SCF_LINUX_SIGFRAME, /* non-RT signal frame */ - SH_SCF_LINUX_RT_SIGFRAME, /* RT signal frame */ - } - sigcontext_format; - unw_word_t sigcontext_addr; - unw_word_t sigcontext_sp; - unw_word_t sigcontext_pc; - }; - -#define DWARF_GET_LOC(l) ((l).val) - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) -# define DWARF_IS_REG_LOC(l) 0 -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_word_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_word_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - val, 0, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 0, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, - c->as_arg); -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - &val, 1, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 1, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, - 1, c->as_arg); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,frame) do {} while(0) -#define tdep_stash_frame(c,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) -#define tdep_big_endian(as) ((as)->big_endian) - -extern int tdep_init_done; - -extern void tdep_init (void); -extern int tdep_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); -extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t *valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t *valp, int write); - -#endif /* SH_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/dwarf-config.h deleted file mode 100644 index 93bc6aaecced65..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/dwarf-config.h +++ /dev/null @@ -1,50 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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_config_h -#define dwarf_config_h - -/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not - explicitly defined. */ -#define DWARF_NUM_PRESERVED_REGS 188 - -#define DWARF_REGNUM_MAP_LENGTH (56 + 2) - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc -{ - unw_word_t val; -#ifndef UNW_LOCAL_ONLY - unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ -#endif -} dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/jmpbuf.h deleted file mode 100644 index 3afe9e46cc499a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/jmpbuf.h +++ /dev/null @@ -1,33 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -/* FIXME for Tilegx! */ - -#define JB_SP 4 -#define JB_RP 5 -#define JB_MASK_SAVED 6 -#define JB_MASK 7 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/libunwind_i.h deleted file mode 100644 index 2cfed456a70fdd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/libunwind_i.h +++ /dev/null @@ -1,263 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -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 TILEGX_LIBUNWIND_I_H -#define TILEGX_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -# include "elf64.h" -#include "mempool.h" -#include "dwarf.h" - -typedef struct -{ - /* no Tilegx-specific fast trace */ -} unw_tdep_frame_t; - -struct unw_addr_space -{ - struct unw_accessors acc; - - int big_endian; - tilegx_abi_t abi; - unsigned int addr_size; - - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; -}; - -#define tdep_big_endian(as) ((as)->big_endian) - -struct cursor -{ - struct dwarf_cursor dwarf; /* must be first */ - unw_word_t sigcontext_addr; - unw_word_t sigcontext_sp; - unw_word_t sigcontext_pc; -}; - -#define DWARF_GET_LOC(l) ((l).val) - -#ifndef UNW_REMOTE_ONLY -typedef long tilegx_reg_t; -#endif - -#ifdef UNW_LOCAL_ONLY -#define DWARF_NULL_LOC DWARF_LOC (0, 0) -#define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -#define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) -#define DWARF_IS_REG_LOC(l) 0 -#define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) -#define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -#define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ - tdep_uc_addr((c)->as_arg, (r)), 0)) - -/* Tilegx has no FP. */ -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - Debug (1, "Tielgx has no fp!\n"); - abort(); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - Debug (1, "Tielgx has no fp!\n"); - abort(); - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - - *val = *(tilegx_reg_t *) (intptr_t) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - - *(tilegx_reg_t *) (intptr_t) DWARF_GET_LOC (loc) = val; - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ -#define DWARF_LOC_TYPE_FP (1 << 0) -#define DWARF_LOC_TYPE_REG (1 << 1) -#define DWARF_NULL_LOC DWARF_LOC (0, 0) -#define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -#define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -#define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -#define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -#define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -#define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -#define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -/* TILEGX has no fp. */ -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - Debug (1, "Tielgx has no fp!\n"); - abort(); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - Debug (1, "Tielgx has no fp!\n"); - abort(); - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_needs_initialization UNW_OBJ(needs_initialization) -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,frame) do {} while(0) -#define tdep_stash_frame(c,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) - -#ifdef UNW_LOCAL_ONLY -#define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -#define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -#define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -#define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) - -extern int tdep_init_done; - -extern void tdep_init (void); -extern int tdep_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); -extern void *tdep_uc_addr (ucontext_t *uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, - pid_t pid, unw_word_t ip, - unsigned long *segbase, - unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, - unw_regnum_t reg, - unw_word_t *valp, - int write); -extern int tdep_access_fpreg (struct cursor *c, - unw_regnum_t reg, - unw_fpreg_t *valp, - int write); - -#endif /* TILEGX_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86/dwarf-config.h deleted file mode 100644 index f76f9c1c4eb2fe..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86/dwarf-config.h +++ /dev/null @@ -1,52 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -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_config_h -#define dwarf_config_h - -/* This matches the value used by GCC (see - gcc/config/i386.h:DWARF_FRAME_REGISTERS), which leaves plenty of - room for expansion. */ -#define DWARF_NUM_PRESERVED_REGS 17 - -#define DWARF_REGNUM_MAP_LENGTH 19 - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) 0 - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; -#ifndef UNW_LOCAL_ONLY - unw_word_t type; /* see X86_LOC_TYPE_* macros. */ -#endif - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86/jmpbuf.h deleted file mode 100644 index 521dfa6992b36e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86/jmpbuf.h +++ /dev/null @@ -1,42 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -#if defined __linux__ - -#define JB_SP 4 -#define JB_RP 5 -#define JB_MASK_SAVED 6 -#define JB_MASK 7 - -#elif defined __FreeBSD__ - -#define JB_SP 2 -#define JB_RP 0 -#define JB_MASK_SAVED 11 -#define JB_MASK 7 - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86/libunwind_i.h deleted file mode 100644 index 5231189a499c16..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86/libunwind_i.h +++ /dev/null @@ -1,293 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 X86_LIBUNWIND_I_H -#define X86_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#include "elf32.h" -#include "mempool.h" -#include "dwarf.h" - -typedef struct - { - /* no x86-specific fast trace */ - } -unw_tdep_frame_t; - -struct unw_addr_space - { - struct unw_accessors acc; - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; - }; - -struct cursor - { - struct dwarf_cursor dwarf; /* must be first */ - - /* Format of sigcontext structure and address at which it is - stored: */ - enum - { - X86_SCF_NONE, /* no signal frame encountered */ - X86_SCF_LINUX_SIGFRAME, /* Linux x86 sigcontext */ - X86_SCF_LINUX_RT_SIGFRAME, /* POSIX ucontext_t */ - X86_SCF_FREEBSD_SIGFRAME, /* FreeBSD x86 sigcontext */ - X86_SCF_FREEBSD_SIGFRAME4, /* FreeBSD 4.x x86 sigcontext */ - X86_SCF_FREEBSD_OSIGFRAME, /* FreeBSD pre-4.x x86 sigcontext */ - X86_SCF_FREEBSD_SYSCALL, /* FreeBSD x86 syscall */ - } - sigcontext_format; - unw_word_t sigcontext_addr; - int validate; - ucontext_t *uc; - }; - -static inline ucontext_t * -dwarf_get_uc(const struct dwarf_cursor *cursor) -{ - const struct cursor *c = (struct cursor *) cursor->as_arg; - return c->uc; -} - -#define DWARF_GET_LOC(l) ((l).val) - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) -# define DWARF_IS_REG_LOC(l) 0 -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; - return 0; -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (!DWARF_GET_LOC (loc)) - return -1; - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#else /* !UNW_LOCAL_ONLY */ -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - val, 0, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 0, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, - c->as_arg); -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - char *valp = (char *) &val; - unw_word_t addr; - int ret; - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), - &val, 1, c->as_arg); - - addr = DWARF_GET_LOC (loc); - if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, - 1, c->as_arg)) < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, - 1, c->as_arg); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - /* If a code-generator were to save a value of type unw_word_t in a - floating-point register, we would have to support this case. I - suppose it could happen with MMX registers, but does it really - happen? */ - assert (!DWARF_IS_FP_LOC (loc)); - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,frame) do {} while(0) -#define tdep_stash_frame(c,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) -#define tdep_big_endian(as) 0 - -extern int tdep_init_done; - -extern void tdep_init (void); -extern int tdep_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); -extern void *tdep_uc_addr (ucontext_t *uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t *valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t *valp, int write); - -#endif /* X86_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/dwarf-config.h deleted file mode 100644 index ff77808e069464..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/dwarf-config.h +++ /dev/null @@ -1,57 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -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. */ - -/* copy of include/tdep-x86/dwarf-config.h, modified slightly for x86-64 - some consolidation is possible here */ - -#ifndef dwarf_config_h -#define dwarf_config_h - -/* XXX need to verify if this value is correct */ -#ifdef CONFIG_MSABI_SUPPORT -#define DWARF_NUM_PRESERVED_REGS 33 -#else -#define DWARF_NUM_PRESERVED_REGS 17 -#endif - -#define DWARF_REGNUM_MAP_LENGTH DWARF_NUM_PRESERVED_REGS - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) 0 - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; - unw_word_t type; /* see X86_LOC_TYPE_* macros. */ - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h deleted file mode 100644 index d57196676db20c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h +++ /dev/null @@ -1,43 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -#if defined __linux__ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -#define JB_SP 6 -#define JB_RP 7 -#define JB_MASK_SAVED 8 -#define JB_MASK 9 - -#elif defined __FreeBSD__ - -#define JB_SP 2 -#define JB_RP 0 -/* Pretend the ip cannot be 0 and mask is always saved */ -#define JB_MASK_SAVED 0 -#define JB_MASK 9 - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h deleted file mode 100644 index 283525c16a38d5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h +++ /dev/null @@ -1,264 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -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 X86_64_LIBUNWIND_I_H -#define X86_64_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#include "elf64.h" -#include "mempool.h" -#include "dwarf.h" - -typedef enum - { - UNW_X86_64_FRAME_ALIGNED = -3, /* frame stack pointer aligned */ - UNW_X86_64_FRAME_STANDARD = -2, /* regular rbp, rsp +/- offset */ - UNW_X86_64_FRAME_SIGRETURN = -1, /* special sigreturn frame */ - UNW_X86_64_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */ - UNW_X86_64_FRAME_GUESSED = 1 /* guessed it was regular, but not known */ - } -unw_tdep_frame_type_t; - -typedef struct - { - uint64_t virtual_address; - int64_t frame_type : 3; /* unw_tdep_frame_type_t classification */ - int64_t last_frame : 1; /* non-zero if last frame in chain */ - int64_t cfa_reg_rsp : 1; /* cfa dwarf base register is rsp vs. rbp */ - int64_t cfa_reg_offset : 29; /* cfa is at this offset from base register value */ - int64_t rbp_cfa_offset : 15; /* rbp saved at this offset from cfa (-1 = not saved) */ - int64_t rsp_cfa_offset : 15; /* rsp saved at this offset from cfa (-1 = not saved) */ - } -unw_tdep_frame_t; - -struct unw_addr_space - { - struct unw_accessors acc; - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; - }; - -struct cursor - { - struct dwarf_cursor dwarf; /* must be first */ - - unw_tdep_frame_t frame_info; /* quick tracing assist info */ - - /* Format of sigcontext structure and address at which it is - stored: */ - enum - { - X86_64_SCF_NONE, /* no signal frame encountered */ - X86_64_SCF_LINUX_RT_SIGFRAME, /* Linux ucontext_t */ - X86_64_SCF_FREEBSD_SIGFRAME, /* FreeBSD signal frame */ - X86_64_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall */ - } - sigcontext_format; - unw_word_t sigcontext_addr; - int validate; - ucontext_t *uc; - }; - -static inline ucontext_t * -dwarf_get_uc(const struct dwarf_cursor *cursor) -{ - const struct cursor *c = (struct cursor *) cursor->as_arg; - return c->uc; -} - -#define DWARF_GET_LOC(l) ((l).val) -# define DWARF_LOC_TYPE_MEM (0 << 0) -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_LOC_TYPE_VAL (1 << 2) - -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_IS_MEM_LOC(l) ((l).type == DWARF_LOC_TYPE_MEM) -# define DWARF_IS_VAL_LOC(l) (((l).type & DWARF_LOC_TYPE_VAL) != 0) - -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_VAL_LOC(c,v) DWARF_LOC ((v), DWARF_LOC_TYPE_VAL) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), DWARF_LOC_TYPE_MEM) - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0)) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0)) - -#else /* !UNW_LOCAL_ONLY */ - -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -#endif /* !UNW_LOCAL_ONLY */ - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - abort (); -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - abort (); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - if (DWARF_IS_MEM_LOC (loc)) - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - assert(DWARF_IS_VAL_LOC (loc)); - *val = DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - assert(!DWARF_IS_VAL_LOC (loc)); - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace) -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#if __linux__ -# define tdep_fetch_frame UNW_OBJ(fetch_frame) -# define tdep_cache_frame UNW_OBJ(cache_frame) -# define tdep_reuse_frame UNW_OBJ(reuse_frame) -#else -# define tdep_fetch_frame(c,ip,n) do {} while(0) -# define tdep_cache_frame(c) 0 -# define tdep_reuse_frame(c,frame) do {} while(0) -#endif -#define tdep_stash_frame UNW_OBJ(stash_frame) -#define tdep_trace UNW_OBJ(tdep_trace) -#define x86_64_r_uc_addr UNW_OBJ(r_uc_addr) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) -#define tdep_big_endian(as) 0 - -extern int tdep_init_done; - -extern void tdep_init (void); -extern void tdep_init_mem_validate (void); -extern int tdep_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); -extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t *valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t *valp, int write); -#if __linux__ -extern void tdep_fetch_frame (struct dwarf_cursor *c, unw_word_t ip, - int need_unwind_info); -extern int tdep_cache_frame (struct dwarf_cursor *c); -extern void tdep_reuse_frame (struct dwarf_cursor *c, - int frame); -extern void tdep_stash_frame (struct dwarf_cursor *c, - struct dwarf_reg_state *rs); -#endif - -extern int tdep_getcontext_trace (unw_tdep_context_t *); -extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); - -#endif /* X86_64_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep/dwarf-config.h deleted file mode 100644 index c759a46c63b9da..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep/dwarf-config.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Provide a real file - not a symlink - as it would cause multiarch conflicts - when multiple different arch releases are installed simultaneously. */ - -#if defined __aarch64__ -# include "tdep-aarch64/dwarf-config.h" -#elif defined __arm__ -# include "tdep-arm/dwarf-config.h" -#elif defined __hppa__ -# include "tdep-hppa/dwarf-config.h" -#elif defined __ia64__ -# include "tdep-ia64/dwarf-config.h" -#elif defined __mips__ -# include "tdep-mips/dwarf-config.h" -#elif defined __powerpc__ && !defined __powerpc64__ -# include "tdep-ppc32/dwarf-config.h" -#elif defined __powerpc64__ -# include "tdep-ppc64/dwarf-config.h" -#elif defined __sh__ -# include "tdep-sh/dwarf-config.h" -#elif defined __i386__ -# include "tdep-x86/dwarf-config.h" -#elif defined __x86_64__ || defined __amd64__ -# include "tdep-x86_64/dwarf-config.h" -#elif defined __tilegx__ -# include "tdep-tilegx/dwarf-config.h" -#else -# error "Unsupported arch" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep/jmpbuf.h deleted file mode 100644 index 13093a0cdc3fa0..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep/jmpbuf.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Provide a real file - not a symlink - as it would cause multiarch conflicts - when multiple different arch releases are installed simultaneously. */ - -#ifndef UNW_REMOTE_ONLY - -#if defined __aarch64__ -# include "tdep-aarch64/jmpbuf.h" -#elif defined __arm__ -# include "tdep-arm/jmpbuf.h" -#elif defined __hppa__ -# include "tdep-hppa/jmpbuf.h" -#elif defined __ia64__ -# include "tdep-ia64/jmpbuf.h" -#elif defined __mips__ -# include "tdep-mips/jmpbuf.h" -#elif defined __powerpc__ && !defined __powerpc64__ -# include "tdep-ppc32/jmpbuf.h" -#elif defined __powerpc64__ -# include "tdep-ppc64/jmpbuf.h" -#elif defined __i386__ -# include "tdep-x86/jmpbuf.h" -#elif defined __x86_64__ -# include "tdep-x86_64/jmpbuf.h" -#elif defined __tilegx__ -# include "tdep-tilegx/jmpbuf.h" -#else -# error "Unsupported arch" -#endif - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in b/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in deleted file mode 100644 index af05a7fba24f99..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in +++ /dev/null @@ -1,37 +0,0 @@ -/* Provide a real file - not a symlink - as it would cause multiarch conflicts - when multiple different arch releases are installed simultaneously. */ - -#ifndef UNW_REMOTE_ONLY - -#if defined __aarch64__ -# include "tdep-aarch64/libunwind_i.h" -#elif defined __arm__ -# include "tdep-arm/libunwind_i.h" -#elif defined __hppa__ -# include "tdep-hppa/libunwind_i.h" -#elif defined __ia64__ -# include "tdep-ia64/libunwind_i.h" -#elif defined __mips__ -# include "tdep-mips/libunwind_i.h" -#elif defined __powerpc__ && !defined __powerpc64__ -# include "tdep-ppc32/libunwind_i.h" -#elif defined __powerpc64__ -# include "tdep-ppc64/libunwind_i.h" -#elif defined __sh__ -# include "tdep-sh/libunwind_i.h" -#elif defined __i386__ -# include "tdep-x86/libunwind_i.h" -#elif defined __x86_64__ -# include "tdep-x86_64/libunwind_i.h" -#elif defined __tilegx__ -# include "tdep-tilegx/libunwind_i.h" -#else -# error "Unsupported arch" -#endif - - -#else /* UNW_REMOTE_ONLY */ - -# include "tdep-@arch@/libunwind_i.h" - -#endif /* UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/include/unwind.h b/src/coreclr/src/pal/src/libunwind/include/unwind.h deleted file mode 100644 index 7cf128deca3079..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/unwind.h +++ /dev/null @@ -1,154 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 _UNWIND_H -#define _UNWIND_H - -/* For uint64_t */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Minimal interface as per C++ ABI draft standard: - - http://www.codesourcery.com/cxx-abi/abi-eh.html */ - -typedef enum - { - _URC_NO_REASON = 0, - _URC_FOREIGN_EXCEPTION_CAUGHT = 1, - _URC_FATAL_PHASE2_ERROR = 2, - _URC_FATAL_PHASE1_ERROR = 3, - _URC_NORMAL_STOP = 4, - _URC_END_OF_STACK = 5, - _URC_HANDLER_FOUND = 6, - _URC_INSTALL_CONTEXT = 7, - _URC_CONTINUE_UNWIND = 8 - } -_Unwind_Reason_Code; - -typedef int _Unwind_Action; - -#define _UA_SEARCH_PHASE 1 -#define _UA_CLEANUP_PHASE 2 -#define _UA_HANDLER_FRAME 4 -#define _UA_FORCE_UNWIND 8 - -struct _Unwind_Context; /* opaque data-structure */ -struct _Unwind_Exception; /* forward-declaration */ - -typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, - struct _Unwind_Exception *); - -typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int, _Unwind_Action, - uint64_t, - struct _Unwind_Exception *, - struct _Unwind_Context *, - void *); - -/* The C++ ABI requires exception_class, private_1, and private_2 to - be of type uint64 and the entire structure to be - double-word-aligned. Please note that exception_class stays 64-bit - even on 32-bit machines for gcc compatibility. */ -struct _Unwind_Exception - { - uint64_t exception_class; - _Unwind_Exception_Cleanup_Fn exception_cleanup; - unsigned long private_1; - unsigned long private_2; - } __attribute__((__aligned__)); - -extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); -extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, - _Unwind_Stop_Fn, void *); -extern void _Unwind_Resume (struct _Unwind_Exception *); -extern void _Unwind_DeleteException (struct _Unwind_Exception *); -extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int); -extern void _Unwind_SetGR (struct _Unwind_Context *, int, unsigned long); -extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); -extern unsigned long _Unwind_GetIPInfo (struct _Unwind_Context *, int *); -extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned long); -extern unsigned long _Unwind_GetLanguageSpecificData (struct _Unwind_Context*); -extern unsigned long _Unwind_GetRegionStart (struct _Unwind_Context *); - -#ifdef _GNU_SOURCE - -/* Callback for _Unwind_Backtrace(). The backtrace stops immediately - if the callback returns any value other than _URC_NO_REASON. */ -typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *, - void *); - -/* See http://gcc.gnu.org/ml/gcc-patches/2001-09/msg00082.html for why - _UA_END_OF_STACK exists. */ -# define _UA_END_OF_STACK 16 - -/* If the unwind was initiated due to a forced unwind, resume that - operation, else re-raise the exception. This is used by - __cxa_rethrow(). */ -extern _Unwind_Reason_Code - _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); - -/* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why - _Unwind_GetBSP() exists. */ -extern unsigned long _Unwind_GetBSP (struct _Unwind_Context *); - -/* Return the "canonical frame address" for the given context. - This is used by NPTL... */ -extern unsigned long _Unwind_GetCFA (struct _Unwind_Context *); - -/* Return the base-address for data references. */ -extern unsigned long _Unwind_GetDataRelBase (struct _Unwind_Context *); - -/* Return the base-address for text references. */ -extern unsigned long _Unwind_GetTextRelBase (struct _Unwind_Context *); - -/* Call _Unwind_Trace_Fn once for each stack-frame, without doing any - cleanup. The first frame for which the callback is invoked is the - one for the caller of _Unwind_Backtrace(). _Unwind_Backtrace() - returns _URC_END_OF_STACK when the backtrace stopped due to - reaching the end of the call-chain or _URC_FATAL_PHASE1_ERROR if it - stops for any other reason. */ -extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); - -/* Find the start-address of the procedure containing the specified IP - or NULL if it cannot be found (e.g., because the function has no - unwind info). Note: there is not necessarily a one-to-one - correspondence between source-level functions and procedures: some - functions don't have unwind-info and others are split into multiple - procedures. */ -extern void *_Unwind_FindEnclosingFunction (void *); - -/* See also Linux Standard Base Spec: - http://www.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/libgcc-s.html */ - -#endif /* _GNU_SOURCE */ - -#ifdef __cplusplus -}; -#endif - -#endif /* _UNWIND_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/x86/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/x86/jmpbuf.h deleted file mode 100644 index 94d5984f08c496..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/x86/jmpbuf.h +++ /dev/null @@ -1,31 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -#define JB_SP 4 -#define JB_RP 5 -#define JB_MASK_SAVED 6 -#define JB_MASK 7 diff --git a/src/coreclr/src/pal/src/libunwind/scripts/kernel-diff.sh b/src/coreclr/src/pal/src/libunwind/scripts/kernel-diff.sh deleted file mode 100755 index 459194e15a31c7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/scripts/kernel-diff.sh +++ /dev/null @@ -1,10 +0,0 @@ -kdir=${1:-../kernel} -scriptdir=$(dirname $0) -udir=$(dirname $scriptdir) -cat $scriptdir/kernel-files.txt | \ -(while read l r; do - left=$(eval echo $l) - right=$(eval echo $r) -# echo $left $right - diff -up $left $right -done) diff --git a/src/coreclr/src/pal/src/libunwind/scripts/kernel-files.txt b/src/coreclr/src/pal/src/libunwind/scripts/kernel-files.txt deleted file mode 100644 index d79e453a33ac7a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/scripts/kernel-files.txt +++ /dev/null @@ -1,19 +0,0 @@ -$udir/include/tdep-ia64/rse.h $kdir/arch/ia64/unwind/rse.h -$udir/src/ia64/Ginit_local.c $kdir/arch/ia64/unwind/init_local.c -$udir/src/ia64/Gis_signal_frame.c $kdir/arch/ia64/unwind/is_signal_frame.c -$udir/src/ia64/Gparser.c $kdir/arch/ia64/unwind/parser.c -$udir/src/ia64/Grbs.c $kdir/arch/ia64/unwind/rbs.c -$udir/src/ia64/Gregs.c $kdir/arch/ia64/unwind/regs.c -$udir/src/ia64/Gscript.c $kdir/arch/ia64/unwind/script.c -$udir/src/ia64/Gstep.c $kdir/arch/ia64/unwind/step.c -$udir/src/ia64/init.h $kdir/arch/ia64/unwind/init.h -$udir/src/ia64/offsets.h $kdir/arch/ia64/unwind/offsets.h -$udir/src/ia64/regname.c $kdir/arch/ia64/unwind/regname.c -$udir/src/ia64/regs.h $kdir/arch/ia64/unwind/regs.h -$udir/src/ia64/unwind_decoder.h $kdir/arch/ia64/unwind/unwind_decoder.h -$udir/src/mi/Gget_fpreg.c $kdir/unwind/get_fpreg.c -$udir/src/mi/Gget_reg.c $kdir/unwind/get_reg.c -$udir/src/mi/Gset_fpreg.c $kdir/unwind/set_fpreg.c -$udir/src/mi/Gset_reg.c $kdir/unwind/set_reg.c -$udir/src/mi/flush_cache.c $kdir/unwind/flush_cache.c -$udir/src/mi/mempool.c $kdir/unwind/mempool.c diff --git a/src/coreclr/src/pal/src/libunwind/scripts/make-L-files b/src/coreclr/src/pal/src/libunwind/scripts/make-L-files deleted file mode 100755 index 8280e3d76ae1a1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/scripts/make-L-files +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -cwd=`pwd` -dir=`basename ${cwd}` -# -# When compiling a file that goes into libunwind, we only -# need to compile it when we really do support UNW_LOCAL_ONLY. -# In contrast, libunwind-tests should always get compiled. -# -if test $dir = "tests"; then - local_only_test="" -else - local_only_test="defined(UNW_LOCAL_ONLY) && " -fi -for gname in `ls G*.c G*.cxx G*.S 2>/dev/null`; do - lname="L$(expr $gname : '.\(.*\)')" - bk edit $lname >/dev/null 2>&1 - ext=$(expr $gname : '[^.]*[.]\(.*\)') - if [ "$ext" = "S" ]; then - include="" - else - include="#include " - fi - echo -e "\ -#define UNW_LOCAL_ONLY\n\ -$include\n\ -#if ${local_only_test}!defined(UNW_REMOTE_ONLY)\n\ -#include \"$gname\"\n\ -#endif" > $lname - echo created $lname -done diff --git a/src/coreclr/src/pal/src/libunwind/src/Makefile.am b/src/coreclr/src/pal/src/libunwind/src/Makefile.am deleted file mode 100644 index a557d8d1f4fb31..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/Makefile.am +++ /dev/null @@ -1,750 +0,0 @@ -SOVERSION=8:1:0 # See comments at end of file. -SETJMP_SO_VERSION=0:0:0 -COREDUMP_SO_VERSION=0:0:0 -# -# Don't link with start-files since we don't use any constructors/destructors: -# -COMMON_SO_LDFLAGS = $(LDFLAGS_NOSTARTFILES) - -lib_LIBRARIES = -lib_LTLIBRARIES = -if !REMOTE_ONLY -lib_LTLIBRARIES += libunwind.la -if BUILD_PTRACE -lib_LTLIBRARIES += libunwind-ptrace.la -endif -if BUILD_COREDUMP -lib_LTLIBRARIES += libunwind-coredump.la -endif -endif - -noinst_HEADERS = -noinst_LTLIBRARIES = - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libunwind-generic.pc - -if !REMOTE_ONLY -pkgconfig_DATA += unwind/libunwind.pc -endif - -if BUILD_PTRACE -pkgconfig_DATA += ptrace/libunwind-ptrace.pc -endif - -if BUILD_SETJMP -pkgconfig_DATA += setjmp/libunwind-setjmp.pc -endif - -if BUILD_COREDUMP -pkgconfig_DATA += coredump/libunwind-coredump.pc -endif - -### libunwind-ptrace: -libunwind_ptrace_la_SOURCES = \ - ptrace/_UPT_elf.c \ - ptrace/_UPT_accessors.c ptrace/_UPT_access_fpreg.c \ - ptrace/_UPT_access_mem.c ptrace/_UPT_access_reg.c \ - ptrace/_UPT_create.c ptrace/_UPT_destroy.c \ - ptrace/_UPT_find_proc_info.c ptrace/_UPT_get_dyn_info_list_addr.c \ - ptrace/_UPT_put_unwind_info.c ptrace/_UPT_get_proc_name.c \ - ptrace/_UPT_reg_offset.c ptrace/_UPT_resume.c -noinst_HEADERS += ptrace/_UPT_internal.h - -### libunwind-coredump: -libunwind_coredump_la_SOURCES = \ - coredump/_UCD_accessors.c \ - coredump/_UCD_create.c \ - coredump/_UCD_destroy.c \ - coredump/_UCD_access_mem.c \ - coredump/_UCD_elf_map_image.c \ - coredump/_UCD_find_proc_info.c \ - coredump/_UCD_get_proc_name.c \ - \ - coredump/_UPT_elf.c \ - coredump/_UPT_access_fpreg.c \ - coredump/_UPT_get_dyn_info_list_addr.c \ - coredump/_UPT_put_unwind_info.c \ - coredump/_UPT_resume.c -libunwind_coredump_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ - -version-info $(COREDUMP_SO_VERSION) -libunwind_coredump_la_LIBADD = $(LIBLZMA) -noinst_HEADERS += coredump/_UCD_internal.h coredump/_UCD_lib.h - -### libunwind-setjmp: -libunwind_setjmp_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ - -version-info $(SETJMP_SO_VERSION) - -if USE_ELF32 -LIBUNWIND_ELF = libunwind-elf32.la -endif -if USE_ELF64 -LIBUNWIND_ELF = libunwind-elf64.la -endif -if USE_ELFXX -LIBUNWIND_ELF = libunwind-elfxx.la -endif - -libunwind_setjmp_la_LIBADD = $(LIBUNWIND_ELF) \ - libunwind-$(arch).la \ - libunwind.la -lc -libunwind_setjmp_la_SOURCES = setjmp/longjmp.c \ - setjmp/siglongjmp.c -noinst_HEADERS += setjmp/setjmp_i.h - -### libunwind: -libunwind_la_LIBADD = - -# List of arch-independent files needed by both local-only and generic -# libraries: -libunwind_la_SOURCES_common = \ - $(libunwind_la_SOURCES_os) \ - mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c - -# List of arch-independent files needed by generic library (libunwind-$ARCH): -libunwind_la_SOURCES_generic = \ - mi/Gdyn-extract.c mi/Gdyn-remote.c mi/Gfind_dynamic_proc_info.c \ - mi/Gget_accessors.c \ - mi/Gget_proc_info_by_ip.c mi/Gget_proc_name.c \ - mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \ - mi/Gget_reg.c mi/Gset_reg.c \ - mi/Gget_fpreg.c mi/Gset_fpreg.c \ - mi/Gset_caching_policy.c \ - mi/Gset_cache_size.c - -if SUPPORT_CXX_EXCEPTIONS -libunwind_la_SOURCES_local_unwind = \ - unwind/Backtrace.c unwind/DeleteException.c \ - unwind/FindEnclosingFunction.c unwind/ForcedUnwind.c \ - unwind/GetBSP.c unwind/GetCFA.c unwind/GetDataRelBase.c \ - unwind/GetGR.c unwind/GetIP.c unwind/GetLanguageSpecificData.c \ - unwind/GetRegionStart.c unwind/GetTextRelBase.c \ - unwind/RaiseException.c unwind/Resume.c \ - unwind/Resume_or_Rethrow.c unwind/SetGR.c unwind/SetIP.c \ - unwind/GetIPInfo.c - -# _ReadULEB()/_ReadSLEB() are needed for Intel C++ 8.0 compatibility -libunwind_la_SOURCES_os_linux_local = mi/_ReadULEB.c mi/_ReadSLEB.c -endif - -# List of arch-independent files needed by local-only library (libunwind): -libunwind_la_SOURCES_local_nounwind = \ - $(libunwind_la_SOURCES_os_local) \ - mi/backtrace.c \ - mi/dyn-cancel.c mi/dyn-info-list.c mi/dyn-register.c \ - mi/Ldyn-extract.c mi/Lfind_dynamic_proc_info.c \ - mi/Lget_accessors.c \ - mi/Lget_proc_info_by_ip.c mi/Lget_proc_name.c \ - mi/Lput_dynamic_unwind_info.c mi/Ldestroy_addr_space.c \ - mi/Lget_reg.c mi/Lset_reg.c \ - mi/Lget_fpreg.c mi/Lset_fpreg.c \ - mi/Lset_caching_policy.c \ - mi/Lset_cache_size.c - -libunwind_la_SOURCES_local = \ - $(libunwind_la_SOURCES_local_nounwind) \ - $(libunwind_la_SOURCES_local_unwind) - -noinst_HEADERS += os-linux.h -libunwind_la_SOURCES_os_linux = os-linux.c - -libunwind_la_SOURCES_os_hpux = os-hpux.c - -libunwind_la_SOURCES_os_freebsd = os-freebsd.c - -libunwind_la_SOURCES_os_qnx = os-qnx.c - -libunwind_dwarf_common_la_SOURCES = dwarf/global.c - -libunwind_dwarf_local_la_SOURCES = \ - dwarf/Lexpr.c dwarf/Lfde.c dwarf/Lparser.c dwarf/Lpe.c \ - dwarf/Lfind_proc_info-lsb.c \ - dwarf/Lfind_unwind_table.c -libunwind_dwarf_local_la_LIBADD = libunwind-dwarf-common.la - -libunwind_dwarf_generic_la_SOURCES = \ - dwarf/Gexpr.c dwarf/Gfde.c dwarf/Gparser.c dwarf/Gpe.c \ - dwarf/Gfind_proc_info-lsb.c \ - dwarf/Gfind_unwind_table.c -libunwind_dwarf_generic_la_LIBADD = libunwind-dwarf-common.la - -if USE_DWARF - noinst_LTLIBRARIES += libunwind-dwarf-common.la libunwind-dwarf-generic.la -if !REMOTE_ONLY - noinst_LTLIBRARIES += libunwind-dwarf-local.la -endif - libunwind_la_LIBADD += libunwind-dwarf-local.la -endif - -noinst_HEADERS += elf32.h elf64.h elfxx.h - -libunwind_elf32_la_SOURCES = elf32.c -libunwind_elf64_la_SOURCES = elf64.c -libunwind_elfxx_la_SOURCES = elfxx.c -libunwind_elf32_la_LIBADD = $(LIBLZMA) -libunwind_elf64_la_LIBADD = $(LIBLZMA) -libunwind_elfxx_la_LIBADD = $(LIBLZMA) - -noinst_LTLIBRARIES += $(LIBUNWIND_ELF) -libunwind_la_LIBADD += $(LIBUNWIND_ELF) - -# The list of files that go into libunwind and libunwind-aarch64: -noinst_HEADERS += aarch64/init.h aarch64/offsets.h aarch64/unwind_i.h -libunwind_la_SOURCES_aarch64_common = $(libunwind_la_SOURCES_common) \ - aarch64/is_fpreg.c aarch64/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \ - $(libunwind_la_SOURCES_local) \ - aarch64/Lapply_reg_state.c aarch64/Lreg_states_iterate.c \ - aarch64/Lcreate_addr_space.c aarch64/Lget_proc_info.c \ - aarch64/Lget_save_loc.c aarch64/Lglobal.c aarch64/Linit.c \ - aarch64/Linit_local.c aarch64/Linit_remote.c \ - aarch64/Lis_signal_frame.c aarch64/Lregs.c aarch64/Lresume.c \ - aarch64/Lstash_frame.c aarch64/Lstep.c aarch64/Ltrace.c \ - aarch64/getcontext.S - -libunwind_aarch64_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \ - $(libunwind_la_SOURCES_generic) \ - aarch64/Gapply_reg_state.c aarch64/Greg_states_iterate.c \ - aarch64/Gcreate_addr_space.c aarch64/Gget_proc_info.c \ - aarch64/Gget_save_loc.c aarch64/Gglobal.c aarch64/Ginit.c \ - aarch64/Ginit_local.c aarch64/Ginit_remote.c \ - aarch64/Gis_signal_frame.c aarch64/Gregs.c aarch64/Gresume.c \ - aarch64/Gstash_frame.c aarch64/Gstep.c aarch64/Gtrace.c - -# The list of files that go into libunwind and libunwind-arm: -noinst_HEADERS += arm/init.h arm/offsets.h arm/unwind_i.h -libunwind_la_SOURCES_arm_common = $(libunwind_la_SOURCES_common) \ - arm/is_fpreg.c arm/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_arm = $(libunwind_la_SOURCES_arm_common) \ - $(libunwind_la_SOURCES_arm_os_local) \ - $(libunwind_la_SOURCES_local) \ - arm/getcontext.S \ - arm/Lapply_reg_state.c arm/Lreg_states_iterate.c \ - arm/Lcreate_addr_space.c arm/Lget_proc_info.c arm/Lget_save_loc.c \ - arm/Lglobal.c arm/Linit.c arm/Linit_local.c arm/Linit_remote.c \ - arm/Lregs.c arm/Lresume.c arm/Lstep.c \ - arm/Lex_tables.c arm/Lstash_frame.c arm/Ltrace.c - -# The list of files that go into libunwind-arm: -libunwind_arm_la_SOURCES_arm = $(libunwind_la_SOURCES_arm_common) \ - $(libunwind_la_SOURCES_arm_os) \ - $(libunwind_la_SOURCES_generic) \ - arm/Gapply_reg_state.c arm/Greg_states_iterate.c \ - arm/Gcreate_addr_space.c arm/Gget_proc_info.c arm/Gget_save_loc.c \ - arm/Gglobal.c arm/Ginit.c arm/Ginit_local.c arm/Ginit_remote.c \ - arm/Gregs.c arm/Gresume.c arm/Gstep.c \ - arm/Gex_tables.c arm/Gstash_frame.c arm/Gtrace.c - -# The list of files that go both into libunwind and libunwind-ia64: -noinst_HEADERS += ia64/init.h ia64/offsets.h ia64/regs.h \ - ia64/ucontext_i.h ia64/unwind_decoder.h ia64/unwind_i.h -libunwind_la_SOURCES_ia64_common = $(libunwind_la_SOURCES_common) \ - ia64/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \ - $(libunwind_la_SOURCES_local) \ - \ - ia64/dyn_info_list.S ia64/getcontext.S \ - \ - ia64/Lapply_reg_state.c ia64/Lreg_states_iterate.c \ - ia64/Lcreate_addr_space.c ia64/Lget_proc_info.c ia64/Lget_save_loc.c \ - ia64/Lglobal.c ia64/Linit.c ia64/Linit_local.c ia64/Linit_remote.c \ - ia64/Linstall_cursor.S ia64/Lis_signal_frame.c ia64/Lparser.c \ - ia64/Lrbs.c ia64/Lregs.c ia64/Lresume.c ia64/Lscript.c ia64/Lstep.c \ - ia64/Ltables.c ia64/Lfind_unwind_table.c - -# The list of files that go into libunwind-ia64: -libunwind_ia64_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \ - $(libunwind_la_SOURCES_generic) \ - ia64/Gapply_reg_state.c ia64/Greg_states_iterate.c \ - ia64/Gcreate_addr_space.c ia64/Gget_proc_info.c ia64/Gget_save_loc.c \ - ia64/Gglobal.c ia64/Ginit.c ia64/Ginit_local.c ia64/Ginit_remote.c \ - ia64/Ginstall_cursor.S ia64/Gis_signal_frame.c ia64/Gparser.c \ - ia64/Grbs.c ia64/Gregs.c ia64/Gresume.c ia64/Gscript.c ia64/Gstep.c \ - ia64/Gtables.c ia64/Gfind_unwind_table.c - -# The list of files that go both into libunwind and libunwind-hppa: -noinst_HEADERS += hppa/init.h hppa/offsets.h hppa/unwind_i.h -libunwind_la_SOURCES_hppa_common = $(libunwind_la_SOURCES_common) \ - hppa/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \ - $(libunwind_la_SOURCES_local) \ - hppa/getcontext.S hppa/setcontext.S \ - hppa/Lapply_reg_state.c hppa/Lreg_states_iterate.c \ - hppa/Lcreate_addr_space.c hppa/Lget_save_loc.c hppa/Lglobal.c \ - hppa/Linit.c hppa/Linit_local.c hppa/Linit_remote.c \ - hppa/Lis_signal_frame.c hppa/Lget_proc_info.c hppa/Lregs.c \ - hppa/Lresume.c hppa/Lstep.c - -# The list of files that go into libunwind-hppa: -libunwind_hppa_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \ - $(libunwind_la_SOURCES_generic) \ - hppa/Gapply_reg_state.c hppa/Greg_states_iterate.c \ - hppa/Gcreate_addr_space.c hppa/Gget_save_loc.c hppa/Gglobal.c \ - hppa/Ginit.c hppa/Ginit_local.c hppa/Ginit_remote.c \ - hppa/Gis_signal_frame.c hppa/Gget_proc_info.c hppa/Gregs.c \ - hppa/Gresume.c hppa/Gstep.c - -# The list of files that go info libunwind and libunwind-mips: -noinst_HEADERS += mips/init.h mips/offsets.h mips/unwind_i.h -libunwind_la_SOURCES_mips_common = $(libunwind_la_SOURCES_common) \ - mips/is_fpreg.c mips/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \ - $(libunwind_la_SOURCES_local) \ - mips/getcontext.S \ - mips/Lapply_reg_state.c mips/Lreg_states_iterate.c \ - mips/Lcreate_addr_space.c mips/Lget_proc_info.c mips/Lget_save_loc.c \ - mips/Lglobal.c mips/Linit.c mips/Linit_local.c mips/Linit_remote.c \ - mips/Lis_signal_frame.c mips/Lregs.c mips/Lresume.c mips/Lstep.c - -libunwind_mips_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \ - $(libunwind_la_SOURCES_generic) \ - mips/Gapply_reg_state.c mips/Greg_states_iterate.c \ - mips/Gcreate_addr_space.c mips/Gget_proc_info.c mips/Gget_save_loc.c \ - mips/Gglobal.c mips/Ginit.c mips/Ginit_local.c mips/Ginit_remote.c \ - mips/Gis_signal_frame.c mips/Gregs.c mips/Gresume.c mips/Gstep.c - -# The list of files that go info libunwind and libunwind-tilegx: -noinst_HEADERS += tilegx/init.h tilegx/offsets.h tilegx/unwind_i.h -libunwind_la_SOURCES_tilegx_common = $(libunwind_la_SOURCES_common) \ - tilegx/is_fpreg.c tilegx/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \ - $(libunwind_la_SOURCES_local) \ - tilegx/getcontext.S \ - tilegx/Lapply_reg_state.c tilegx/Lreg_states_iterate.c \ - tilegx/Lcreate_addr_space.c tilegx/Lget_proc_info.c tilegx/Lget_save_loc.c \ - tilegx/Lglobal.c tilegx/Linit.c tilegx/Linit_local.c tilegx/Linit_remote.c \ - tilegx/Lis_signal_frame.c tilegx/Lregs.c tilegx/Lresume.c tilegx/Lstep.c - -libunwind_tilegx_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \ - $(libunwind_la_SOURCES_generic) \ - tilegx/Gapply_reg_state.c tilegx/Greg_states_iterate.c \ - tilegx/Gcreate_addr_space.c tilegx/Gget_proc_info.c tilegx/Gget_save_loc.c \ - tilegx/Gglobal.c tilegx/Ginit.c tilegx/Ginit_local.c tilegx/Ginit_remote.c \ - tilegx/Gis_signal_frame.c tilegx/Gregs.c tilegx/Gresume.c tilegx/Gstep.c - - -# The list of files that go both into libunwind and libunwind-x86: -noinst_HEADERS += x86/init.h x86/offsets.h x86/unwind_i.h -libunwind_la_SOURCES_x86_common = $(libunwind_la_SOURCES_common) \ - x86/is_fpreg.c x86/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ - $(libunwind_la_SOURCES_x86_os_local) \ - $(libunwind_la_SOURCES_local) \ - x86/Lapply_reg_state.c x86/Lreg_states_iterate.c \ - x86/Lcreate_addr_space.c x86/Lget_save_loc.c x86/Lglobal.c \ - x86/Linit.c x86/Linit_local.c x86/Linit_remote.c \ - x86/Lget_proc_info.c x86/Lregs.c \ - x86/Lresume.c x86/Lstep.c - -# The list of files that go into libunwind-x86: -libunwind_x86_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ - $(libunwind_la_SOURCES_x86_os) \ - $(libunwind_la_SOURCES_generic) \ - x86/Gapply_reg_state.c x86/Greg_states_iterate.c \ - x86/Gcreate_addr_space.c x86/Gget_save_loc.c x86/Gglobal.c \ - x86/Ginit.c x86/Ginit_local.c x86/Ginit_remote.c \ - x86/Gget_proc_info.c x86/Gregs.c \ - x86/Gresume.c x86/Gstep.c - -# The list of files that go both into libunwind and libunwind-x86_64: -noinst_HEADERS += x86_64/offsets.h \ - x86_64/init.h x86_64/unwind_i.h x86_64/ucontext_i.h -libunwind_la_SOURCES_x86_64_common = $(libunwind_la_SOURCES_common) \ - x86_64/is_fpreg.c x86_64/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \ - $(libunwind_la_SOURCES_x86_64_os_local) \ - $(libunwind_la_SOURCES_local) \ - x86_64/setcontext.S \ - x86_64/Lapply_reg_state.c x86_64/Lreg_states_iterate.c \ - x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \ - x86_64/Linit.c x86_64/Linit_local.c x86_64/Linit_remote.c \ - x86_64/Lget_proc_info.c x86_64/Lregs.c x86_64/Lresume.c \ - x86_64/Lstash_frame.c x86_64/Lstep.c x86_64/Ltrace.c x86_64/getcontext.S - -# The list of files that go into libunwind-x86_64: -libunwind_x86_64_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \ - $(libunwind_la_SOURCES_x86_64_os) \ - $(libunwind_la_SOURCES_generic) \ - x86_64/Gapply_reg_state.c x86_64/Greg_states_iterate.c \ - x86_64/Gcreate_addr_space.c x86_64/Gget_save_loc.c x86_64/Gglobal.c \ - x86_64/Ginit.c x86_64/Ginit_local.c x86_64/Ginit_remote.c \ - x86_64/Gget_proc_info.c x86_64/Gregs.c x86_64/Gresume.c \ - x86_64/Gstash_frame.c x86_64/Gstep.c x86_64/Gtrace.c - -# The list of local files that go to Power 64 and 32: -libunwind_la_SOURCES_ppc = \ - ppc/Lget_proc_info.c ppc/Lget_save_loc.c ppc/Linit_local.c \ - ppc/Linit_remote.c ppc/Lis_signal_frame.c - -# The list of generic files that go to Power 64 and 32: -libunwind_ppc_la_SOURCES_ppc_generic = \ - ppc/Gget_proc_info.c ppc/Gget_save_loc.c ppc/Ginit_local.c \ - ppc/Ginit_remote.c ppc/Gis_signal_frame.c - -# The list of files that go both into libunwind and libunwind-ppc32: -noinst_HEADERS += ppc32/init.h ppc32/unwind_i.h ppc32/ucontext_i.h -libunwind_la_SOURCES_ppc32_common = $(libunwind_la_SOURCES_common) \ - ppc32/is_fpreg.c ppc32/regname.c ppc32/get_func_addr.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ - $(libunwind_la_SOURCES_local) \ - $(libunwind_la_SOURCES_ppc) \ - ppc32/Lapply_reg_state.c ppc32/Lreg_states_iterate.c \ - ppc32/Lcreate_addr_space.c \ - ppc32/Lglobal.c ppc32/Linit.c \ - ppc32/Lregs.c ppc32/Lresume.c ppc32/Lstep.c - -# The list of files that go into libunwind-ppc32: -libunwind_ppc32_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ - $(libunwind_la_SOURCES_generic) \ - $(libunwind_ppc_la_SOURCES_ppc_generic) \ - ppc32/Gapply_reg_state.c ppc32/Greg_states_iterate.c \ - ppc32/Gcreate_addr_space.c \ - ppc32/Gglobal.c ppc32/Ginit.c \ - ppc32/Gregs.c ppc32/Gresume.c ppc32/Gstep.c - -# The list of files that go both into libunwind and libunwind-ppc64: -noinst_HEADERS += ppc64/init.h ppc64/unwind_i.h ppc64/ucontext_i.h -libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \ - ppc64/is_fpreg.c ppc64/regname.c ppc64/get_func_addr.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ - $(libunwind_la_SOURCES_local) \ - $(libunwind_la_SOURCES_ppc) \ - ppc64/Lapply_reg_state.c ppc64/Lreg_states_iterate.c \ - ppc64/Lcreate_addr_space.c \ - ppc64/Lglobal.c ppc64/Linit.c \ - ppc64/Lregs.c ppc64/Lresume.c ppc64/Lstep.c - -# The list of files that go into libunwind-ppc64: -libunwind_ppc64_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ - $(libunwind_la_SOURCES_generic) \ - $(libunwind_ppc_la_SOURCES_ppc_generic) \ - ppc64/Gapply_reg_state.c ppc64/Greg_states_iterate.c \ - ppc64/Gcreate_addr_space.c \ - ppc64/Gglobal.c ppc64/Ginit.c \ - ppc64/Gregs.c ppc64/Gresume.c ppc64/Gstep.c - -# The list of files that go into libunwind and libunwind-sh: -noinst_HEADERS += sh/init.h sh/offsets.h sh/unwind_i.h -libunwind_la_SOURCES_sh_common = $(libunwind_la_SOURCES_common) \ - sh/is_fpreg.c sh/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ - $(libunwind_la_SOURCES_local) \ - sh/Lapply_reg_state.c sh/Lreg_states_iterate.c \ - sh/Lcreate_addr_space.c sh/Lget_proc_info.c sh/Lget_save_loc.c \ - sh/Lglobal.c sh/Linit.c sh/Linit_local.c sh/Linit_remote.c \ - sh/Lis_signal_frame.c sh/Lregs.c sh/Lresume.c sh/Lstep.c - -libunwind_sh_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ - $(libunwind_la_SOURCES_generic) \ - sh/Gapply_reg_state.c sh/Greg_states_iterate.c \ - sh/Gcreate_addr_space.c sh/Gget_proc_info.c sh/Gget_save_loc.c \ - sh/Gglobal.c sh/Ginit.c sh/Ginit_local.c sh/Ginit_remote.c \ - sh/Gis_signal_frame.c sh/Gregs.c sh/Gresume.c sh/Gstep.c - -if REMOTE_ONLY -install-exec-hook: -# Nothing to do here.... -else -# -# This is not ideal, but I know of no other way to install an -# alias for a library. For the shared version, we have to do -# a file check before creating the link, because it isn't going -# to be there if the user configured with --disable-shared. -# -install-exec-hook: - if test -f $(DESTDIR)$(libdir)/libunwind-$(arch).a; then \ - cd $(DESTDIR)$(libdir) && $(LN_S) -f libunwind-$(arch).a libunwind-generic.a; \ - fi - if test -f $(DESTDIR)$(libdir)/libunwind-$(arch).so; then \ - cd $(DESTDIR)$(libdir) && $(LN_S) -f libunwind-$(arch).so \ - libunwind-generic.so; \ - fi -endif - -if OS_LINUX - libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_linux) - libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_linux_local) - libunwind_la_SOURCES_x86_os = x86/Gos-linux.c - libunwind_x86_la_SOURCES_os = x86/getcontext-linux.S - libunwind_la_SOURCES_x86_os_local = x86/Los-linux.c - libunwind_la_SOURCES_x86_64_os = x86_64/Gos-linux.c - libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-linux.c - libunwind_la_SOURCES_arm_os = arm/Gos-linux.c - libunwind_la_SOURCES_arm_os_local = arm/Los-linux.c - libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_linux.c -endif - -if OS_HPUX - libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_hpux) - libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_hpux_local) -endif - -if OS_FREEBSD - libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_freebsd) - libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_freebsd_local) - libunwind_la_SOURCES_x86_os = x86/Gos-freebsd.c - libunwind_x86_la_SOURCES_os = x86/getcontext-freebsd.S - libunwind_la_SOURCES_x86_os_local = x86/Los-freebsd.c - libunwind_la_SOURCES_x86_64_os = x86_64/Gos-freebsd.c - libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-freebsd.c - libunwind_la_SOURCES_arm_os = arm/Gos-freebsd.c - libunwind_la_SOURCES_arm_os_local = arm/Los-freebsd.c - libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c -endif - -if OS_QNX - libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_qnx) - libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_qnx_local) - libunwind_la_SOURCES_arm_os = arm/Gos-other.c - libunwind_la_SOURCES_arm_os_local = arm/Los-other.c -endif - -if ARCH_AARCH64 - lib_LTLIBRARIES += libunwind-aarch64.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_aarch64) - libunwind_aarch64_la_SOURCES = $(libunwind_aarch64_la_SOURCES_aarch64) - libunwind_aarch64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_aarch64_la_LIBADD = libunwind-dwarf-generic.la - libunwind_aarch64_la_LIBADD += libunwind-elf64.la -if !REMOTE_ONLY - libunwind_aarch64_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += aarch64/siglongjmp.S -else -if ARCH_ARM - lib_LTLIBRARIES += libunwind-arm.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_arm) - libunwind_arm_la_SOURCES = $(libunwind_arm_la_SOURCES_arm) - libunwind_arm_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_arm_la_LIBADD = libunwind-dwarf-generic.la - libunwind_arm_la_LIBADD += libunwind-elf32.la -if !REMOTE_ONLY - libunwind_arm_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += arm/siglongjmp.S -else -if ARCH_IA64 - BUILT_SOURCES = Gcursor_i.h Lcursor_i.h -mk_Gcursor_i.s: $(srcdir)/ia64/mk_Gcursor_i.c - $(COMPILE) -S "$(srcdir)/ia64/mk_Gcursor_i.c" -o mk_Gcursor_i.s -mk_Lcursor_i.s: $(srcdir)/ia64/mk_Lcursor_i.c - $(COMPILE) -S "$(srcdir)/ia64/mk_Lcursor_i.c" -o mk_Lcursor_i.s -Gcursor_i.h: mk_Gcursor_i.s - "$(srcdir)/ia64/mk_cursor_i" mk_Gcursor_i.s > Gcursor_i.h -Lcursor_i.h: mk_Lcursor_i.s - "$(srcdir)/ia64/mk_cursor_i" mk_Lcursor_i.s > Lcursor_i.h - - lib_LTLIBRARIES += libunwind-ia64.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_ia64) - libunwind_ia64_la_SOURCES = $(libunwind_ia64_la_SOURCES_ia64) - libunwind_ia64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_ia64_la_LIBADD = libunwind-elf64.la -if !REMOTE_ONLY - libunwind_ia64_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += ia64/setjmp.S ia64/sigsetjmp.S \ - ia64/longjmp.S ia64/siglongjmp.S -else -if ARCH_HPPA - lib_LTLIBRARIES += libunwind-hppa.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_hppa) - libunwind_hppa_la_SOURCES = $(libunwind_hppa_la_SOURCES_hppa) - libunwind_hppa_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_hppa_la_LIBADD = libunwind-dwarf-generic.la - libunwind_hppa_la_LIBADD += libunwind-elf32.la -if !REMOTE_ONLY - libunwind_hppa_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += hppa/siglongjmp.S -else -if ARCH_MIPS - lib_LTLIBRARIES += libunwind-mips.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_mips) - libunwind_mips_la_SOURCES = $(libunwind_mips_la_SOURCES_mips) - libunwind_mips_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_mips_la_LIBADD = libunwind-dwarf-generic.la - libunwind_mips_la_LIBADD += libunwind-elfxx.la -if !REMOTE_ONLY - libunwind_mips_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += mips/siglongjmp.S -else -if ARCH_TILEGX - lib_LTLIBRARIES += libunwind-tilegx.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_tilegx) - libunwind_tilegx_la_SOURCES = $(libunwind_tilegx_la_SOURCES_tilegx) - libunwind_tilegx_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_tilegx_la_LIBADD = libunwind-dwarf-generic.la - libunwind_tilegx_la_LIBADD += libunwind-elfxx.la -if !REMOTE_ONLY - libunwind_tilegx_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += tilegx/siglongjmp.S -else -if ARCH_X86 - lib_LTLIBRARIES += libunwind-x86.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86) $(libunwind_x86_la_SOURCES_os) - libunwind_x86_la_SOURCES = $(libunwind_x86_la_SOURCES_x86) - libunwind_x86_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_x86_la_LIBADD = libunwind-dwarf-generic.la - libunwind_x86_la_LIBADD += libunwind-elf32.la -if !REMOTE_ONLY - libunwind_x86_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += x86/longjmp.S x86/siglongjmp.S -else -if ARCH_X86_64 - lib_LTLIBRARIES += libunwind-x86_64.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86_64) - libunwind_x86_64_la_SOURCES = $(libunwind_x86_64_la_SOURCES_x86_64) - libunwind_x86_64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_x86_64_la_LIBADD = libunwind-dwarf-generic.la - libunwind_x86_64_la_LIBADD += libunwind-elf64.la -if !REMOTE_ONLY - libunwind_x86_64_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += x86_64/longjmp.S x86_64/siglongjmp.S -else -if ARCH_PPC32 - lib_LTLIBRARIES += libunwind-ppc32.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc32) - libunwind_ppc32_la_SOURCES = $(libunwind_ppc32_la_SOURCES_ppc32) - libunwind_ppc32_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_ppc32_la_LIBADD = libunwind-dwarf-generic.la - libunwind_ppc32_la_LIBADD += libunwind-elf32.la -if !REMOTE_ONLY - libunwind_ppc32_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S -else -if ARCH_PPC64 - lib_LTLIBRARIES += libunwind-ppc64.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc64) - libunwind_ppc64_la_SOURCES = $(libunwind_ppc64_la_SOURCES_ppc64) - libunwind_ppc64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_ppc64_la_LIBADD = libunwind-dwarf-generic.la - libunwind_ppc64_la_LIBADD += libunwind-elf64.la -if !REMOTE_ONLY - libunwind_ppc64_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S -else -if ARCH_SH - lib_LTLIBRARIES += libunwind-sh.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_sh) - libunwind_sh_la_SOURCES = $(libunwind_sh_la_SOURCES_sh) - libunwind_sh_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_sh_la_LIBADD = libunwind-dwarf-generic.la - libunwind_sh_la_LIBADD += libunwind-elf32.la -if !REMOTE_ONLY - libunwind_sh_la_LIBADD += libunwind.la -lc -endif - libunwind_setjmp_la_SOURCES += sh/siglongjmp.S - -endif # ARCH_SH -endif # ARCH_PPC64 -endif # ARCH_PPC32 -endif # ARCH_X86_64 -endif # ARCH_X86 -endif # ARCH_TILEGX -endif # ARCH_MIPS -endif # ARCH_HPPA -endif # ARCH_IA64 -endif # ARCH_ARM -endif # ARCH_AARCH64 - -# libunwind-setjmp depends on libunwind-$(arch). Therefore must be added -# at the end. -if BUILD_SETJMP -lib_LTLIBRARIES += libunwind-setjmp.la -endif - -# -# Don't link with standard libraries, because those may mention -# libunwind already. -# -libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -XCClinker -nostdlib \ - $(LDFLAGS_STATIC_LIBCXA) -version-info $(SOVERSION) -libunwind_la_LIBADD += -lc $(LIBCRTS) -libunwind_la_LIBADD += $(LIBLZMA) - -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I. -AM_CCASFLAGS = $(AM_CPPFLAGS) -noinst_HEADERS += unwind/unwind-internal.h - -EXTRA_DIST = $(libunwind_la_SOURCES_aarch64) \ - $(libunwind_la_SOURCES_arm) \ - $(libunwind_la_SOURCES_hppa) \ - $(libunwind_la_SOURCES_ia64) \ - $(libunwind_la_SOURCES_mips) \ - $(libunwind_la_SOURCES_sh) \ - $(libunwind_la_SOURCES_x86) \ - $(libunwind_la_SOURCES_os_freebsd) \ - $(libunwind_la_SOURCES_os_linux) \ - $(libunwind_la_SOURCES_os_hpux) \ - $(libunwind_la_SOURCES_os_qnx) \ - $(libunwind_la_SOURCES_common) \ - $(libunwind_la_SOURCES_local) \ - $(libunwind_la_SOURCES_generic) \ - $(libunwind_aarch64_la_SOURCES_aarch64) \ - $(libunwind_arm_la_SOURCES_arm) \ - $(libunwind_hppa_la_SOURCES_hppa) \ - $(libunwind_ia64_la_SOURCES_ia64) \ - $(libunwind_mips_la_SOURCES_mips) \ - $(libunwind_sh_la_SOURCES_sh) \ - $(libunwind_x86_la_SOURCES_x86) \ - $(libunwind_x86_64_la_SOURCES_x86_64) - -MAINTAINERCLEANFILES = Makefile.in - -# The -version-info flag accepts an argument of the form -# `current[:revision[:age]]'. So, passing `-version-info 3:12:1' sets -# current to 3, revision to 12, and age to 1. - -# If either revision or age are omitted, they default to 0. Also note -# that age must be less than or equal to the current interface number. - -# Here are a set of rules to help you update your library version -# information: - -# 1. Start with version information of `0:0:0' for each libtool -# library. - -# 2. Update the version information only immediately before a public -# release of your software. More frequent updates are unnecessary, -# and only guarantee that the current interface number gets larger -# faster. - -# 3. If the library source code has changed at all since the last -# update, then increment revision (`c:r:a' becomes `c:r+1:a'). - -# 4. If any interfaces have been added, removed, or changed since the -# last update, increment current, and set revision to 0. - -# 5. If any interfaces have been added since the last public release, -# then increment age. - -# 6. If any interfaces have been removed since the last public -# release, then set age to 0. diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gcreate_addr_space.c deleted file mode 100644 index f217adc745540b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gcreate_addr_space.c +++ /dev/null @@ -1,60 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - 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. */ - -#include -#include - -#include "unwind_i.h" - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* AArch64 supports little-endian and big-endian. */ - if (byte_order != 0 && byte_order != __LITTLE_ENDIAN - && byte_order != __BIG_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - /* Default to little-endian for AArch64. */ - if (byte_order == 0 || byte_order == __LITTLE_ENDIAN) - as->big_endian = 0; - else - as->big_endian = 1; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_proc_info.c deleted file mode 100644 index c363d2405d748a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_proc_info.c +++ /dev/null @@ -1,39 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - ret = dwarf_make_proc_info (&c->dwarf); - if (ret < 0) - return ret; - - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_save_loc.c deleted file mode 100644 index 86bbbd03d11b3b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_save_loc.c +++ /dev/null @@ -1,100 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - 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. */ - -#include "unwind_i.h" - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - struct cursor *c = (struct cursor *) cursor; - dwarf_loc_t loc; - - switch (reg) - { - case UNW_AARCH64_X0: - case UNW_AARCH64_X1: - case UNW_AARCH64_X2: - case UNW_AARCH64_X3: - case UNW_AARCH64_X4: - case UNW_AARCH64_X5: - case UNW_AARCH64_X6: - case UNW_AARCH64_X7: - case UNW_AARCH64_X8: - case UNW_AARCH64_X9: - case UNW_AARCH64_X10: - case UNW_AARCH64_X11: - case UNW_AARCH64_X12: - case UNW_AARCH64_X13: - case UNW_AARCH64_X14: - case UNW_AARCH64_X15: - case UNW_AARCH64_X16: - case UNW_AARCH64_X17: - case UNW_AARCH64_X18: - case UNW_AARCH64_X19: - case UNW_AARCH64_X20: - case UNW_AARCH64_X21: - case UNW_AARCH64_X22: - case UNW_AARCH64_X23: - case UNW_AARCH64_X24: - case UNW_AARCH64_X25: - case UNW_AARCH64_X26: - case UNW_AARCH64_X27: - case UNW_AARCH64_X28: - case UNW_AARCH64_X29: - case UNW_AARCH64_X30: - case UNW_AARCH64_SP: - case UNW_AARCH64_PC: - case UNW_AARCH64_PSTATE: - loc = c->dwarf.loc[reg]; - break; - - default: - loc = DWARF_NULL_LOC; /* default to "not saved" */ - break; - } - - memset (sloc, 0, sizeof (*sloc)); - - if (DWARF_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (DWARF_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = DWARF_GET_LOC (loc); - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = DWARF_GET_LOC (loc); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gglobal.c deleted file mode 100644 index 72e36b2d4d67a8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gglobal.c +++ /dev/null @@ -1,57 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - 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. */ - -#include "unwind_i.h" -#include "dwarf_i.h" - -HIDDEN define_lock (aarch64_lock); -HIDDEN int tdep_init_done; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&aarch64_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - dwarf_init (); - -#ifndef UNW_REMOTE_ONLY - aarch64_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&aarch64_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c deleted file mode 100644 index 9c4eae8298ee31..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c +++ /dev/null @@ -1,190 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - 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. */ - -#include -#include - -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -static inline void * -uc_addr (ucontext_t *uc, int reg) -{ - if (reg >= UNW_AARCH64_X0 && reg < UNW_AARCH64_V0) - return &uc->uc_mcontext.regs[reg]; - else if (reg >= UNW_AARCH64_V0 && reg <= UNW_AARCH64_V31) - return &GET_FPCTX(uc)->vregs[reg - UNW_AARCH64_V0]; - else - return NULL; -} - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) -{ - return uc_addr (uc, reg); -} - -# endif /* UNW_LOCAL_ONLY */ - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (write) - { - Debug (16, "mem[%lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - *val = *(unw_word_t *) addr; - Debug (16, "mem[%lx] -> %lx\n", addr, *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = arg; - - if (unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - *(unw_word_t *) addr = *val; - Debug (12, "%s <- %lx\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> %lx\n", unw_regname (reg), *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = arg; - unw_fpreg_t *addr; - - if (!unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - *(unw_fpreg_t *) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -aarch64_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = aarch64_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c deleted file mode 100644 index cd60ca840f5085..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c +++ /dev/null @@ -1,78 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2011-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. */ - -#include "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local_common (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = uc; - - return common_init (c, use_prev_instr); -} - -int -unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_remote.c deleted file mode 100644 index 9b8ba5b89def1a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_remote.c +++ /dev/null @@ -1,45 +0,0 @@ -/* 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. */ - -#include "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - c->dwarf.as_arg = as_arg; - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gis_signal_frame.c deleted file mode 100644 index 67159d83961431..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gis_signal_frame.c +++ /dev/null @@ -1,64 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - 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. */ - -#include "unwind_i.h" - -/* The restorer stub will always have the form: - - d2801168 movz x8, #0x8b - d4000001 svc #0x0 -*/ - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ -#ifdef __linux__ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - ip = c->dwarf.ip; - - ret = (*a->access_mem) (as, ip, &w0, 0, arg); - if (ret < 0) - return ret; - - /* FIXME: distinguish 32bit insn vs 64bit registers. */ - if (w0 != 0xd4000001d2801168) - return 0; - - return 1; - -#else - return -UNW_ENOINFO; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gregs.c deleted file mode 100644 index a8843734459b57..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gregs.c +++ /dev/null @@ -1,118 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - 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. */ - -#include "unwind_i.h" - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - unsigned int mask; - - switch (reg) - { - case UNW_AARCH64_X0: - case UNW_AARCH64_X1: - case UNW_AARCH64_X2: - case UNW_AARCH64_X3: - mask = 1 << reg; - if (write) - { - c->dwarf.eh_args[reg] = *valp; - c->dwarf.eh_valid_mask |= mask; - return 0; - } - else if ((c->dwarf.eh_valid_mask & mask) != 0) - { - *valp = c->dwarf.eh_args[reg]; - return 0; - } - else - loc = c->dwarf.loc[reg]; - break; - - case UNW_AARCH64_X30: - if (write) - c->dwarf.ip = *valp; /* update the IP cache */ - case UNW_AARCH64_X4: - case UNW_AARCH64_X5: - case UNW_AARCH64_X6: - case UNW_AARCH64_X7: - case UNW_AARCH64_X8: - case UNW_AARCH64_X9: - case UNW_AARCH64_X10: - case UNW_AARCH64_X11: - case UNW_AARCH64_X12: - case UNW_AARCH64_X13: - case UNW_AARCH64_X14: - case UNW_AARCH64_X15: - case UNW_AARCH64_X16: - case UNW_AARCH64_X17: - case UNW_AARCH64_X18: - case UNW_AARCH64_X19: - case UNW_AARCH64_X20: - case UNW_AARCH64_X21: - case UNW_AARCH64_X22: - case UNW_AARCH64_X23: - case UNW_AARCH64_X24: - case UNW_AARCH64_X25: - case UNW_AARCH64_X26: - case UNW_AARCH64_X27: - case UNW_AARCH64_X28: - case UNW_AARCH64_X29: - case UNW_AARCH64_PC: - case UNW_AARCH64_PSTATE: - loc = c->dwarf.loc[reg]; - break; - - case UNW_AARCH64_SP: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - dwarf_loc_t loc = c->dwarf.loc[reg]; - if (write) - return dwarf_putfp (&c->dwarf, loc, *valp); - else - return dwarf_getfp (&c->dwarf, loc, valp); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c deleted file mode 100644 index 3d82739293e11a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c +++ /dev/null @@ -1,198 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2011-2013 Linaro Limited - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" - -#ifndef UNW_REMOTE_ONLY - -HIDDEN inline int -aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ -#ifdef __linux__ - struct cursor *c = (struct cursor *) cursor; - unw_tdep_context_t *uc = c->dwarf.as_arg; - - if (c->sigcontext_format == AARCH64_SCF_NONE) - { - /* Since there are no signals involved here we restore EH and non scratch - registers only. */ - unsigned long regs[24]; - regs[0] = uc->uc_mcontext.regs[0]; - regs[1] = uc->uc_mcontext.regs[1]; - regs[2] = uc->uc_mcontext.regs[2]; - regs[3] = uc->uc_mcontext.regs[3]; - regs[4] = uc->uc_mcontext.regs[19]; - regs[5] = uc->uc_mcontext.regs[20]; - regs[6] = uc->uc_mcontext.regs[21]; - regs[7] = uc->uc_mcontext.regs[22]; - regs[8] = uc->uc_mcontext.regs[23]; - regs[9] = uc->uc_mcontext.regs[24]; - regs[10] = uc->uc_mcontext.regs[25]; - regs[11] = uc->uc_mcontext.regs[26]; - regs[12] = uc->uc_mcontext.regs[27]; - regs[13] = uc->uc_mcontext.regs[28]; - regs[14] = uc->uc_mcontext.regs[29]; /* FP */ - regs[15] = uc->uc_mcontext.regs[30]; /* LR */ - regs[16] = GET_FPCTX(uc)->vregs[8]; - regs[17] = GET_FPCTX(uc)->vregs[9]; - regs[18] = GET_FPCTX(uc)->vregs[10]; - regs[19] = GET_FPCTX(uc)->vregs[11]; - regs[20] = GET_FPCTX(uc)->vregs[12]; - regs[21] = GET_FPCTX(uc)->vregs[13]; - regs[22] = GET_FPCTX(uc)->vregs[14]; - regs[23] = GET_FPCTX(uc)->vregs[15]; - unsigned long sp = uc->uc_mcontext.sp; - - struct regs_overlay { - char x[sizeof(regs)]; - }; - - asm volatile ( - "mov x4, %0\n" - "mov x5, %1\n" - "ldp x0, x1, [x4]\n" - "ldp x2, x3, [x4,16]\n" - "ldp x19, x20, [x4,32]\n" - "ldp x21, x22, [x4,48]\n" - "ldp x23, x24, [x4,64]\n" - "ldp x25, x26, [x4,80]\n" - "ldp x27, x28, [x4,96]\n" - "ldp x29, x30, [x4,112]\n" - "ldp d8, d9, [x4,128]\n" - "ldp d10, d11, [x4,144]\n" - "ldp d12, d13, [x4,160]\n" - "ldp d14, d15, [x4,176]\n" - "mov sp, x5\n" - "ret \n" - : - : "r" (regs), - "r" (sp), - "m" (*(struct regs_overlay *)regs) - ); - } - else - { - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - - if (c->dwarf.eh_valid_mask & 0x1) sc->regs[0] = c->dwarf.eh_args[0]; - if (c->dwarf.eh_valid_mask & 0x2) sc->regs[1] = c->dwarf.eh_args[1]; - if (c->dwarf.eh_valid_mask & 0x4) sc->regs[2] = c->dwarf.eh_args[2]; - if (c->dwarf.eh_valid_mask & 0x8) sc->regs[3] = c->dwarf.eh_args[3]; - - sc->regs[4] = uc->uc_mcontext.regs[4]; - sc->regs[5] = uc->uc_mcontext.regs[5]; - sc->regs[6] = uc->uc_mcontext.regs[6]; - sc->regs[7] = uc->uc_mcontext.regs[7]; - sc->regs[8] = uc->uc_mcontext.regs[8]; - sc->regs[9] = uc->uc_mcontext.regs[9]; - sc->regs[10] = uc->uc_mcontext.regs[10]; - sc->regs[11] = uc->uc_mcontext.regs[11]; - sc->regs[12] = uc->uc_mcontext.regs[12]; - sc->regs[13] = uc->uc_mcontext.regs[13]; - sc->regs[14] = uc->uc_mcontext.regs[14]; - sc->regs[15] = uc->uc_mcontext.regs[15]; - sc->regs[16] = uc->uc_mcontext.regs[16]; - sc->regs[17] = uc->uc_mcontext.regs[17]; - sc->regs[18] = uc->uc_mcontext.regs[18]; - sc->regs[19] = uc->uc_mcontext.regs[19]; - sc->regs[20] = uc->uc_mcontext.regs[20]; - sc->regs[21] = uc->uc_mcontext.regs[21]; - sc->regs[22] = uc->uc_mcontext.regs[22]; - sc->regs[23] = uc->uc_mcontext.regs[23]; - sc->regs[24] = uc->uc_mcontext.regs[24]; - sc->regs[25] = uc->uc_mcontext.regs[25]; - sc->regs[26] = uc->uc_mcontext.regs[26]; - sc->regs[27] = uc->uc_mcontext.regs[27]; - sc->regs[28] = uc->uc_mcontext.regs[28]; - sc->regs[29] = uc->uc_mcontext.regs[29]; - sc->regs[30] = uc->uc_mcontext.regs[30]; - sc->sp = uc->uc_mcontext.sp; - sc->pc = uc->uc_mcontext.pc; - sc->pstate = uc->uc_mcontext.pstate; - - asm volatile ( - "mov sp, %0\n" - "ret %1\n" - : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) - ); - } - unreachable(); -#else - printf ("%s: implement me\n", __FUNCTION__); -#endif - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ - -static inline void -establish_machine_state (struct cursor *c) -{ - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_AARCH64_V31; ++reg) - { - Debug (16, "copying %s %d\n", unw_regname (reg), reg); - if (unw_is_fpreg (reg)) - { - if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) - as->acc.access_fpreg (as, reg, &fpval, 1, arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - as->acc.access_reg (as, reg, &val, 1, arg); - } - } -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - - Debug (1, "(cursor=%p)\n", c); - - if (!c->dwarf.ip) - { - /* This can happen easily when the frame-chain gets truncated - due to bad or missing unwind-info. */ - Debug (1, "refusing to resume execution at address 0\n"); - return -UNW_EINVAL; - } - - establish_machine_state (c); - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstash_frame.c deleted file mode 100644 index 6689af1a61d565..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstash_frame.c +++ /dev/null @@ -1,89 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY - Copyright (C) 2014 CERN and Aalto University - Contributed by Filip Nyback - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -HIDDEN void -tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) -{ - struct cursor *c = (struct cursor *) dwarf_to_cursor (d); - unw_tdep_frame_t *f = &c->frame_info; - - Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld" - " ra=0x%lx fp [where=%d val=%ld @0x%lx] lr [where=%d val=%ld @0x%lx] " - "sp [where=%d val=%ld @0x%lx]\n", - d->ip, d->cfa, f->frame_type, - rs->reg.where[DWARF_CFA_REG_COLUMN], - rs->reg.val[DWARF_CFA_REG_COLUMN], - rs->reg.val[DWARF_CFA_OFF_COLUMN], - DWARF_GET_LOC(d->loc[rs->ret_addr_column]), - rs->reg.where[FP], rs->reg.val[FP], DWARF_GET_LOC(d->loc[FP]), - rs->reg.where[LR], rs->reg.val[LR], DWARF_GET_LOC(d->loc[LR]), - rs->reg.where[SP], rs->reg.val[SP], DWARF_GET_LOC(d->loc[SP])); - - /* A standard frame is defined as: - - CFA is register-relative offset off FP or SP; - - Return address is saved in LR; - - FP is unsaved or saved at CFA+offset, offset != -1; - - LR is unsaved or saved at CFA+offset, offset != -1; - - SP is unsaved or saved at CFA+offset, offset != -1. */ - if (f->frame_type == UNW_AARCH64_FRAME_OTHER - && (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG) - && (rs->reg.val[DWARF_CFA_REG_COLUMN] == FP - || rs->reg.val[DWARF_CFA_REG_COLUMN] == SP) - && labs(rs->reg.val[DWARF_CFA_OFF_COLUMN]) < (1 << 29) - && rs->ret_addr_column == LR - && (rs->reg.where[FP] == DWARF_WHERE_UNDEF - || rs->reg.where[FP] == DWARF_WHERE_SAME - || (rs->reg.where[FP] == DWARF_WHERE_CFAREL - && labs(rs->reg.val[FP]) < (1 << 29) - && rs->reg.val[FP]+1 != 0)) - && (rs->reg.where[LR] == DWARF_WHERE_UNDEF - || rs->reg.where[LR] == DWARF_WHERE_SAME - || (rs->reg.where[LR] == DWARF_WHERE_CFAREL - && labs(rs->reg.val[LR]) < (1 << 29) - && rs->reg.val[LR]+1 != 0)) - && (rs->reg.where[SP] == DWARF_WHERE_UNDEF - || rs->reg.where[SP] == DWARF_WHERE_SAME - || (rs->reg.where[SP] == DWARF_WHERE_CFAREL - && labs(rs->reg.val[SP]) < (1 << 29) - && rs->reg.val[SP]+1 != 0))) - { - /* Save information for a standard frame. */ - f->frame_type = UNW_AARCH64_FRAME_STANDARD; - f->cfa_reg_sp = (rs->reg.val[DWARF_CFA_REG_COLUMN] == SP); - f->cfa_reg_offset = rs->reg.val[DWARF_CFA_OFF_COLUMN]; - if (rs->reg.where[FP] == DWARF_WHERE_CFAREL) - f->fp_cfa_offset = rs->reg.val[FP]; - if (rs->reg.where[LR] == DWARF_WHERE_CFAREL) - f->lr_cfa_offset = rs->reg.val[LR]; - if (rs->reg.where[SP] == DWARF_WHERE_CFAREL) - f->sp_cfa_offset = rs->reg.val[SP]; - Debug (4, " standard frame\n"); - } - else - Debug (4, " unusual frame\n"); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstep.c deleted file mode 100644 index fdf64a73f3304a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstep.c +++ /dev/null @@ -1,189 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2011-2013 Linaro Limited - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" - -/* Recognise PLT entries such as: - 40ddf0: b0000570 adrp x16, 4ba000 <_GLOBAL_OFFSET_TABLE_+0x2a8> - 40ddf4: f9433611 ldr x17, [x16,#1640] - 40ddf8: 9119a210 add x16, x16, #0x668 - 40ddfc: d61f0220 br x17 */ -static int -is_plt_entry (struct dwarf_cursor *c) -{ - unw_word_t w0, w1; - unw_accessors_t *a; - int ret; - - a = unw_get_accessors_int (c->as); - if ((ret = (*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg)) < 0 - || (ret = (*a->access_mem) (c->as, c->ip + 8, &w1, 0, c->as_arg)) < 0) - return 0; - - ret = (((w0 & 0xff0000009f000000) == 0xf900000090000000) - && ((w1 & 0xffffffffff000000) == 0xd61f022091000000)); - - Debug (14, "ip=0x%lx => 0x%016lx 0x%016lx, ret = %d\n", c->ip, w0, w1, ret); - return ret; -} - -static int -aarch64_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; - struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); - - if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) - return -UNW_EUNSPEC; - - ret = unw_is_signal_frame (cursor); - Debug(1, "unw_is_signal_frame()=%d\n", ret); - - /* Save the SP and PC to be able to return execution at this point - later in time (unw_resume). */ - c->sigcontext_sp = c->dwarf.cfa; - c->sigcontext_pc = c->dwarf.ip; - - if (ret) - { - c->sigcontext_format = AARCH64_SCF_LINUX_RT_SIGFRAME; - sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; - } - else - return -UNW_EUNSPEC; - - c->sigcontext_addr = sc_addr; - c->frame_info.frame_type = UNW_AARCH64_FRAME_SIGRETURN; - c->frame_info.cfa_reg_offset = sc_addr - sp_addr; - - /* Update the dwarf cursor. - Set the location of the registers to the corresponding addresses of the - uc_mcontext / sigcontext structure contents. */ - c->dwarf.loc[UNW_AARCH64_X0] = DWARF_LOC (sc_addr + LINUX_SC_X0_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X1] = DWARF_LOC (sc_addr + LINUX_SC_X1_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X2] = DWARF_LOC (sc_addr + LINUX_SC_X2_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X3] = DWARF_LOC (sc_addr + LINUX_SC_X3_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X4] = DWARF_LOC (sc_addr + LINUX_SC_X4_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X5] = DWARF_LOC (sc_addr + LINUX_SC_X5_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X6] = DWARF_LOC (sc_addr + LINUX_SC_X6_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X7] = DWARF_LOC (sc_addr + LINUX_SC_X7_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X8] = DWARF_LOC (sc_addr + LINUX_SC_X8_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X9] = DWARF_LOC (sc_addr + LINUX_SC_X9_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X10] = DWARF_LOC (sc_addr + LINUX_SC_X10_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X11] = DWARF_LOC (sc_addr + LINUX_SC_X11_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X12] = DWARF_LOC (sc_addr + LINUX_SC_X12_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X13] = DWARF_LOC (sc_addr + LINUX_SC_X13_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X14] = DWARF_LOC (sc_addr + LINUX_SC_X14_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X15] = DWARF_LOC (sc_addr + LINUX_SC_X15_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X16] = DWARF_LOC (sc_addr + LINUX_SC_X16_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X17] = DWARF_LOC (sc_addr + LINUX_SC_X17_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X18] = DWARF_LOC (sc_addr + LINUX_SC_X18_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X19] = DWARF_LOC (sc_addr + LINUX_SC_X19_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X20] = DWARF_LOC (sc_addr + LINUX_SC_X20_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X21] = DWARF_LOC (sc_addr + LINUX_SC_X21_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X22] = DWARF_LOC (sc_addr + LINUX_SC_X22_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X23] = DWARF_LOC (sc_addr + LINUX_SC_X23_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X24] = DWARF_LOC (sc_addr + LINUX_SC_X24_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X25] = DWARF_LOC (sc_addr + LINUX_SC_X25_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X26] = DWARF_LOC (sc_addr + LINUX_SC_X26_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X27] = DWARF_LOC (sc_addr + LINUX_SC_X27_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X28] = DWARF_LOC (sc_addr + LINUX_SC_X28_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X29] = DWARF_LOC (sc_addr + LINUX_SC_X29_OFF, 0); - c->dwarf.loc[UNW_AARCH64_X30] = DWARF_LOC (sc_addr + LINUX_SC_X30_OFF, 0); - c->dwarf.loc[UNW_AARCH64_SP] = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0); - c->dwarf.loc[UNW_AARCH64_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); - c->dwarf.loc[UNW_AARCH64_PSTATE] = DWARF_LOC (sc_addr + LINUX_SC_PSTATE_OFF, 0); - - /* Set SP/CFA and PC/IP. */ - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_SP], &c->dwarf.cfa); - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); - - c->dwarf.pi_valid = 0; - c->dwarf.use_prev_instr = 0; - - return 1; -} - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx))\n", - c, c->dwarf.ip, c->dwarf.cfa); - - /* Check if this is a signal frame. */ - if (unw_is_signal_frame (cursor) > 0) - return aarch64_handle_signal_frame (cursor); - - ret = dwarf_step (&c->dwarf); - Debug(1, "dwarf_step()=%d\n", ret); - - if (unlikely (ret == -UNW_ESTOPUNWIND)) - return ret; - - if (unlikely (ret < 0)) - { - /* DWARF failed. */ - if (is_plt_entry (&c->dwarf)) - { - Debug (2, "found plt entry\n"); - c->frame_info.frame_type = UNW_AARCH64_FRAME_STANDARD; - } - else - { - Debug (2, "fallback\n"); - c->frame_info.frame_type = UNW_AARCH64_FRAME_GUESSED; - } - /* Use link register (X30). */ - c->frame_info.cfa_reg_offset = 0; - c->frame_info.cfa_reg_sp = 0; - c->frame_info.fp_cfa_offset = -1; - c->frame_info.lr_cfa_offset = -1; - c->frame_info.sp_cfa_offset = -1; - c->dwarf.loc[UNW_AARCH64_PC] = c->dwarf.loc[UNW_AARCH64_X30]; - c->dwarf.loc[UNW_AARCH64_X30] = DWARF_NULL_LOC; - if (!DWARF_IS_NULL_LOC (c->dwarf.loc[UNW_AARCH64_PC])) - { - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); - if (ret < 0) - { - Debug (2, "failed to get pc from link register: %d\n", ret); - return ret; - } - Debug (2, "link register (x30) = 0x%016lx\n", c->dwarf.ip); - ret = 1; - } - else - c->dwarf.ip = 0; - } - - return (c->dwarf.ip == 0) ? 0 : 1; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gtrace.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gtrace.c deleted file mode 100644 index c67faf0e357938..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gtrace.c +++ /dev/null @@ -1,548 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY - Copyright (C) 2014 CERN and Aalto University - Contributed by Filip Nyback - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" -#include -#include - -#pragma weak pthread_once -#pragma weak pthread_key_create -#pragma weak pthread_getspecific -#pragma weak pthread_setspecific - -/* Initial hash table size. Table expands by 2 bits (times four). */ -#define HASH_MIN_BITS 14 - -typedef struct -{ - unw_tdep_frame_t *frames; - size_t log_size; - size_t used; - size_t dtor_count; /* Counts how many times our destructor has already - been called. */ -} unw_trace_cache_t; - -static const unw_tdep_frame_t empty_frame = { 0, UNW_AARCH64_FRAME_OTHER, -1, -1, 0, -1, -1, -1 }; -static define_lock (trace_init_lock); -static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; -static sig_atomic_t trace_cache_once_happen; -static pthread_key_t trace_cache_key; -static struct mempool trace_cache_pool; -static __thread unw_trace_cache_t *tls_cache; -static __thread int tls_cache_destroyed; - -/* Free memory for a thread's trace cache. */ -static void -trace_cache_free (void *arg) -{ - unw_trace_cache_t *cache = arg; - if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS) - { - /* Not yet our turn to get destroyed. Re-install ourselves into the key. */ - pthread_setspecific(trace_cache_key, cache); - Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, - PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); - return; - } - tls_cache_destroyed = 1; - tls_cache = NULL; - munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); - mempool_free (&trace_cache_pool, cache); - Debug(5, "freed cache %p\n", cache); -} - -/* Initialise frame tracing for threaded use. */ -static void -trace_cache_init_once (void) -{ - pthread_key_create (&trace_cache_key, &trace_cache_free); - mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); - trace_cache_once_happen = 1; -} - -static unw_tdep_frame_t * -trace_cache_buckets (size_t n) -{ - unw_tdep_frame_t *frames; - size_t i; - - GET_MEMORY(frames, n * sizeof (unw_tdep_frame_t)); - if (likely(frames != NULL)) - for (i = 0; i < n; ++i) - frames[i] = empty_frame; - - return frames; -} - -/* Allocate and initialise hash table for frame cache lookups. - Returns the cache initialised with (1u << HASH_LOW_BITS) hash - buckets, or NULL if there was a memory allocation problem. */ -static unw_trace_cache_t * -trace_cache_create (void) -{ - unw_trace_cache_t *cache; - - if (tls_cache_destroyed) - { - /* The current thread is in the process of exiting. Don't recreate - cache, as we wouldn't have another chance to free it. */ - Debug(5, "refusing to reallocate cache: " - "thread-locals are being deallocated\n"); - return NULL; - } - - if (! (cache = mempool_alloc(&trace_cache_pool))) - { - Debug(5, "failed to allocate cache\n"); - return NULL; - } - - if (! (cache->frames = trace_cache_buckets(1u << HASH_MIN_BITS))) - { - Debug(5, "failed to allocate buckets\n"); - mempool_free(&trace_cache_pool, cache); - return NULL; - } - - cache->log_size = HASH_MIN_BITS; - cache->used = 0; - cache->dtor_count = 0; - tls_cache_destroyed = 0; /* Paranoia: should already be 0. */ - Debug(5, "allocated cache %p\n", cache); - return cache; -} - -/* Expand the hash table in the frame cache if possible. This always - quadruples the hash size, and clears all previous frame entries. */ -static int -trace_cache_expand (unw_trace_cache_t *cache) -{ - size_t old_size = (1u << cache->log_size); - size_t new_log_size = cache->log_size + 2; - unw_tdep_frame_t *new_frames = trace_cache_buckets (1u << new_log_size); - - if (unlikely(! new_frames)) - { - Debug(5, "failed to expand cache to 2^%lu buckets\n", new_log_size); - return -UNW_ENOMEM; - } - - Debug(5, "expanded cache from 2^%lu to 2^%lu buckets\n", cache->log_size, new_log_size); - munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); - cache->frames = new_frames; - cache->log_size = new_log_size; - cache->used = 0; - return 0; -} - -static unw_trace_cache_t * -trace_cache_get_unthreaded (void) -{ - unw_trace_cache_t *cache; - intrmask_t saved_mask; - static unw_trace_cache_t *global_cache = NULL; - lock_acquire (&trace_init_lock, saved_mask); - if (! global_cache) - { - mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); - global_cache = trace_cache_create (); - } - cache = global_cache; - lock_release (&trace_init_lock, saved_mask); - Debug(5, "using cache %p\n", cache); - return cache; -} - -/* Get the frame cache for the current thread. Create it if there is none. */ -static unw_trace_cache_t * -trace_cache_get (void) -{ - unw_trace_cache_t *cache; - if (likely (pthread_once != NULL)) - { - pthread_once(&trace_cache_once, &trace_cache_init_once); - if (!trace_cache_once_happen) - { - return trace_cache_get_unthreaded(); - } - if (! (cache = tls_cache)) - { - cache = trace_cache_create(); - pthread_setspecific(trace_cache_key, cache); - tls_cache = cache; - } - Debug(5, "using cache %p\n", cache); - return cache; - } - else - { - return trace_cache_get_unthreaded(); - } -} - -/* Initialise frame properties for address cache slot F at address - PC using current CFA, FP and SP values. Modifies CURSOR to - that location, performs one unw_step(), and fills F with what - was discovered about the location. Returns F. - - FIXME: This probably should tell DWARF handling to never evaluate - or use registers other than FP, SP and PC in case there is - highly unusual unwind info which uses these creatively. */ -static unw_tdep_frame_t * -trace_init_addr (unw_tdep_frame_t *f, - unw_cursor_t *cursor, - unw_word_t cfa, - unw_word_t pc, - unw_word_t fp, - unw_word_t sp) -{ - struct cursor *c = (struct cursor *) cursor; - struct dwarf_cursor *d = &c->dwarf; - int ret = -UNW_EINVAL; - - /* Initialise frame properties: unknown, not last. */ - f->virtual_address = pc; - f->frame_type = UNW_AARCH64_FRAME_OTHER; - f->last_frame = 0; - f->cfa_reg_sp = -1; - f->cfa_reg_offset = 0; - f->fp_cfa_offset = -1; - f->lr_cfa_offset = -1; - f->sp_cfa_offset = -1; - - /* Reinitialise cursor to this instruction - but undo next/prev PC - adjustment because unw_step will redo it - and force PC, FP and - SP into register locations (=~ ucontext we keep), then set - their desired values. Then perform the step. */ - d->ip = pc + d->use_prev_instr; - d->cfa = cfa; - d->loc[UNW_AARCH64_X29] = DWARF_REG_LOC (d, UNW_AARCH64_X29); - d->loc[UNW_AARCH64_SP] = DWARF_REG_LOC (d, UNW_AARCH64_SP); - d->loc[UNW_AARCH64_PC] = DWARF_REG_LOC (d, UNW_AARCH64_PC); - c->frame_info = *f; - - if (likely(dwarf_put (d, d->loc[UNW_AARCH64_X29], fp) >= 0) - && likely(dwarf_put (d, d->loc[UNW_AARCH64_SP], sp) >= 0) - && likely(dwarf_put (d, d->loc[UNW_AARCH64_PC], pc) >= 0) - && likely((ret = unw_step (cursor)) >= 0)) - *f = c->frame_info; - - /* If unw_step() stopped voluntarily, remember that, even if it - otherwise could not determine anything useful. This avoids - failing trace if we hit frames without unwind info, which is - common for the outermost frame (CRT stuff) on many systems. - This avoids failing trace in very common circumstances; failing - to unw_step() loop wouldn't produce any better result. */ - if (ret == 0) - f->last_frame = -1; - - Debug (3, "frame va %lx type %d last %d cfa %s+%d fp @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", - f->virtual_address, f->frame_type, f->last_frame, - f->cfa_reg_sp ? "sp" : "fp", f->cfa_reg_offset, - f->fp_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); - - return f; -} - -/* Look up and if necessary fill in frame attributes for address PC - in CACHE using current CFA, FP and SP values. Uses CURSOR to - perform any unwind steps necessary to fill the cache. Returns the - frame cache slot which describes RIP. */ -static unw_tdep_frame_t * -trace_lookup (unw_cursor_t *cursor, - unw_trace_cache_t *cache, - unw_word_t cfa, - unw_word_t pc, - unw_word_t fp, - unw_word_t sp) -{ - /* First look up for previously cached information using cache as - linear probing hash table with probe step of 1. Majority of - lookups should be completed within few steps, but it is very - important the hash table does not fill up, or performance falls - off the cliff. */ - uint64_t i, addr; - uint64_t cache_size = 1u << cache->log_size; - uint64_t slot = ((pc * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); - unw_tdep_frame_t *frame; - - for (i = 0; i < 16; ++i) - { - frame = &cache->frames[slot]; - addr = frame->virtual_address; - - /* Return if we found the address. */ - if (likely(addr == pc)) - { - Debug (4, "found address after %ld steps\n", i); - return frame; - } - - /* If slot is empty, reuse it. */ - if (likely(! addr)) - break; - - /* Linear probe to next slot candidate, step = 1. */ - if (++slot >= cache_size) - slot -= cache_size; - } - - /* If we collided after 16 steps, or if the hash is more than half - full, force the hash to expand. Fill the selected slot, whether - it's free or collides. Note that hash expansion drops previous - contents; further lookups will refill the hash. */ - Debug (4, "updating slot %lu after %ld steps, replacing 0x%lx\n", slot, i, addr); - if (unlikely(addr || cache->used >= cache_size / 2)) - { - if (unlikely(trace_cache_expand (cache) < 0)) - return NULL; - - cache_size = 1u << cache->log_size; - slot = ((pc * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); - frame = &cache->frames[slot]; - addr = frame->virtual_address; - } - - if (! addr) - ++cache->used; - - return trace_init_addr (frame, cursor, cfa, pc, fp, sp); -} - -/* Fast stack backtrace for AArch64. - - This is used by backtrace() implementation to accelerate frequent - queries for current stack, without any desire to unwind. It fills - BUFFER with the call tree from CURSOR upwards for at most SIZE - stack levels. The first frame, backtrace itself, is omitted. When - called, SIZE should give the maximum number of entries that can be - stored into BUFFER. Uses an internal thread-specific cache to - accelerate queries. - - The caller should fall back to a unw_step() loop if this function - fails by returning -UNW_ESTOPUNWIND, meaning the routine hit a - stack frame that is too complex to be traced in the fast path. - - This function is tuned for clients which only need to walk the - stack to get the call tree as fast as possible but without any - other details, for example profilers sampling the stack thousands - to millions of times per second. The routine handles the most - common AArch64 ABI stack layouts: CFA is FP or SP plus/minus - constant offset, return address is in LR, and FP, LR and SP are - either unchanged or saved on stack at constant offset from the CFA; - the signal return frame; and frames without unwind info provided - they are at the outermost (final) frame or can conservatively be - assumed to be frame-pointer based. - - Any other stack layout will cause the routine to give up. There - are only a handful of relatively rarely used functions which do - not have a stack in the standard form: vfork, longjmp, setcontext - and _dl_runtime_profile on common linux systems for example. - - On success BUFFER and *SIZE reflect the trace progress up to *SIZE - stack levels or the outermost frame, which ever is less. It may - stop short of outermost frame if unw_step() loop would also do so, - e.g. if there is no more unwind information; this is not reported - as an error. - - The function returns a negative value for errors, -UNW_ESTOPUNWIND - if tracing stopped because of an unusual frame unwind info. The - BUFFER and *SIZE reflect tracing progress up to the error frame. - - Callers of this function would normally look like this: - - unw_cursor_t cur; - unw_context_t ctx; - void addrs[128]; - int depth = 128; - int ret; - - unw_getcontext(&ctx); - unw_init_local(&cur, &ctx); - if ((ret = unw_tdep_trace(&cur, addrs, &depth)) < 0) - { - depth = 0; - unw_getcontext(&ctx); - unw_init_local(&cur, &ctx); - while ((ret = unw_step(&cur)) > 0 && depth < 128) - { - unw_word_t ip; - unw_get_reg(&cur, UNW_REG_IP, &ip); - addresses[depth++] = (void *) ip; - } - } -*/ -HIDDEN int -tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) -{ - struct cursor *c = (struct cursor *) cursor; - struct dwarf_cursor *d = &c->dwarf; - unw_trace_cache_t *cache; - unw_word_t fp, sp, pc, cfa, lr; - int maxdepth = 0; - int depth = 0; - int ret; - - /* Check input parametres. */ - if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) - return -UNW_EINVAL; - - Debug (1, "begin ip 0x%lx cfa 0x%lx\n", d->ip, d->cfa); - - /* Tell core dwarf routines to call back to us. */ - d->stash_frames = 1; - - /* Determine initial register values. These are direct access safe - because we know they come from the initial machine context. */ - pc = d->ip; - sp = cfa = d->cfa; - ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_AARCH64_X29]), fp); - assert(ret == 0); - lr = 0; - - /* Get frame cache. */ - if (unlikely(! (cache = trace_cache_get()))) - { - Debug (1, "returning %d, cannot get trace cache\n", -UNW_ENOMEM); - *size = 0; - d->stash_frames = 0; - return -UNW_ENOMEM; - } - - /* Trace the stack upwards, starting from current RIP. Adjust - the RIP address for previous/next instruction as the main - unwinding logic would also do. We undo this before calling - back into unw_step(). */ - while (depth < maxdepth) - { - pc -= d->use_prev_instr; - Debug (2, "depth %d cfa 0x%lx pc 0x%lx sp 0x%lx fp 0x%lx\n", - depth, cfa, pc, sp, fp); - - /* See if we have this address cached. If not, evaluate enough of - the dwarf unwind information to fill the cache line data, or to - decide this frame cannot be handled in fast trace mode. We - cache negative results too to prevent unnecessary dwarf parsing - for common failures. */ - unw_tdep_frame_t *f = trace_lookup (cursor, cache, cfa, pc, fp, sp); - - /* If we don't have information for this frame, give up. */ - if (unlikely(! f)) - { - ret = -UNW_ENOINFO; - break; - } - - Debug (3, "frame va %lx type %d last %d cfa %s+%d fp @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", - f->virtual_address, f->frame_type, f->last_frame, - f->cfa_reg_sp ? "sp" : "fp", f->cfa_reg_offset, - f->fp_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); - - assert (f->virtual_address == pc); - - /* Stop if this was the last frame. In particular don't evaluate - new register values as it may not be safe - we don't normally - run with full validation on, and do not want to - and there's - enough bad unwind info floating around that we need to trust - what unw_step() previously said, in potentially bogus frames. */ - if (f->last_frame) - break; - - /* Evaluate CFA and registers for the next frame. */ - switch (f->frame_type) - { - case UNW_AARCH64_FRAME_GUESSED: - /* Fall thru to standard processing after forcing validation. */ - c->validate = 1; - - case UNW_AARCH64_FRAME_STANDARD: - /* Advance standard traceable frame. */ - cfa = (f->cfa_reg_sp ? sp : fp) + f->cfa_reg_offset; - if (likely(f->lr_cfa_offset != -1)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc); - else if (lr != 0) - { - /* Use the saved link register as the new pc. */ - pc = lr; - lr = 0; - } - if (likely(ret >= 0) && likely(f->fp_cfa_offset != -1)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->fp_cfa_offset, fp); - - /* Don't bother reading SP from DWARF, CFA becomes new SP. */ - sp = cfa; - - /* Next frame needs to back up for unwind info lookup. */ - d->use_prev_instr = 1; - break; - - case UNW_AARCH64_FRAME_SIGRETURN: - cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ - - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_PC_OFF, pc); - if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_X29_OFF, fp); - if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_SP_OFF, sp); - /* Save the link register here in case we end up in a function that - doesn't save the link register in the prologue, e.g. kill. */ - if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_X30_OFF, lr); - - /* Resume stack at signal restoration point. The stack is not - necessarily continuous here, especially with sigaltstack(). */ - cfa = sp; - - /* Next frame should not back up. */ - d->use_prev_instr = 0; - break; - - default: - /* We cannot trace through this frame, give up and tell the - caller we had to stop. Data collected so far may still be - useful to the caller, so let it know how far we got. */ - ret = -UNW_ESTOPUNWIND; - break; - } - - Debug (4, "new cfa 0x%lx pc 0x%lx sp 0x%lx fp 0x%lx\n", - cfa, pc, sp, fp); - - /* If we failed or ended up somewhere bogus, stop. */ - if (unlikely(ret < 0 || pc < 0x4000)) - break; - - /* Record this address in stack trace. We skipped the first address. */ - buffer[depth++] = (void *) (pc - d->use_prev_instr); - } - -#if UNW_DEBUG - Debug (1, "returning %d, depth %d\n", ret, depth); -#endif - *size = depth; - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lglobal.c deleted file mode 100644 index 6d7b489e14bd9f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lglobal.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9fa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstash_frame.c deleted file mode 100644 index 77587803d083d7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstash_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstash_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ltrace.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ltrace.c deleted file mode 100644 index fcd3f239c9e422..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ltrace.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gtrace.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/gen-offsets.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/gen-offsets.c deleted file mode 100644 index eadc2377d8f7a7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/gen-offsets.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include - -#define UC(N,X) \ - printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) - -#define SC(N,X) \ - printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) - -int -main (void) -{ - printf ( -"/* Linux-specific definitions: */\n\n" - -"/* Define various structure offsets to simplify cross-compilation. */\n\n" - -"/* Offsets for AArch64 Linux \"ucontext_t\": */\n\n"); - - UC ("FLAGS", uc_flags); - UC ("LINK", uc_link); - UC ("STACK", uc_stack); - UC ("MCONTEXT", uc_mcontext); - UC ("SIGMASK", uc_sigmask); - - printf ("\n/* Offsets for AArch64 Linux \"struct sigcontext\": */\n\n"); - - SC ("R0", regs[0]); - SC ("R1", regs[1]); - SC ("R2", regs[2]); - SC ("R3", regs[3]); - SC ("R4", regs[4]); - SC ("R5", regs[5]); - SC ("R6", regs[6]); - SC ("R7", regs[7]); - SC ("R8", regs[8]); - SC ("R9", regs[9]); - SC ("R10", regs[10]); - SC ("R11", regs[11]); - SC ("R12", regs[12]); - SC ("R13", regs[13]); - SC ("R14", regs[14]); - SC ("R15", regs[15]); - SC ("R16", regs[16]); - SC ("R17", regs[17]); - SC ("R18", regs[18]); - SC ("R19", regs[19]); - SC ("R20", regs[20]); - SC ("R21", regs[21]); - SC ("R22", regs[22]); - SC ("R23", regs[23]); - SC ("R24", regs[24]); - SC ("R25", regs[25]); - SC ("R26", regs[26]); - SC ("R27", regs[27]); - SC ("R28", regs[28]); - SC ("R29", regs[29]); - SC ("R30", regs[30]); - SC ("R31", regs[31]); - - SC ("PC", pc); - SC ("SP", sp); - SC ("Fault", fault_address); - SC ("state", pstate); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/aarch64/getcontext.S deleted file mode 100644 index 25ed5b66be73ea..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/getcontext.S +++ /dev/null @@ -1,52 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 Google, Inc - Contributed by Paul Pluzhnikov - Copyright (C) 2010 Konstantin Belousov - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "offsets.h" - -/* int _Uaarch64_getcontext_trace (unw_tdep_context_t *ucp) - - Saves limited machine context in UCP necessary for fast trace. If fast trace - fails, caller will have to get the full context. -*/ - - .global _Uaarch64_getcontext_trace - .hidden _Uaarch64_getcontext_trace - .type _Uaarch64_getcontext_trace, @function -_Uaarch64_getcontext_trace: - .cfi_startproc - - /* Save only FP, SP, PC - exclude this call. */ - str x29, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_X29_OFF)] - mov x9, sp - str x9, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_SP_OFF)] - str x30, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_PC_OFF)] - - ret - .cfi_endproc - .size _Uaarch64_getcontext_trace, . - _Uaarch64_getcontext_trace - - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/init.h b/src/coreclr/src/pal/src/libunwind/src/aarch64/init.h deleted file mode 100644 index 5dab60bb64ed71..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/init.h +++ /dev/null @@ -1,126 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - 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. */ - -#include "unwind_i.h" - -static inline int -common_init (struct cursor *c, unsigned use_prev_instr) -{ - int ret, i; - - c->dwarf.loc[UNW_AARCH64_X0] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X0); - c->dwarf.loc[UNW_AARCH64_X1] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X1); - c->dwarf.loc[UNW_AARCH64_X2] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X2); - c->dwarf.loc[UNW_AARCH64_X3] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X3); - c->dwarf.loc[UNW_AARCH64_X4] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X4); - c->dwarf.loc[UNW_AARCH64_X5] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X5); - c->dwarf.loc[UNW_AARCH64_X6] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X6); - c->dwarf.loc[UNW_AARCH64_X7] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X7); - c->dwarf.loc[UNW_AARCH64_X8] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X8); - c->dwarf.loc[UNW_AARCH64_X9] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X9); - c->dwarf.loc[UNW_AARCH64_X10] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X10); - c->dwarf.loc[UNW_AARCH64_X11] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X11); - c->dwarf.loc[UNW_AARCH64_X12] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X12); - c->dwarf.loc[UNW_AARCH64_X13] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X13); - c->dwarf.loc[UNW_AARCH64_X14] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X14); - c->dwarf.loc[UNW_AARCH64_X15] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X15); - c->dwarf.loc[UNW_AARCH64_X16] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X16); - c->dwarf.loc[UNW_AARCH64_X17] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X17); - c->dwarf.loc[UNW_AARCH64_X18] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X18); - c->dwarf.loc[UNW_AARCH64_X19] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X19); - c->dwarf.loc[UNW_AARCH64_X20] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X20); - c->dwarf.loc[UNW_AARCH64_X21] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X21); - c->dwarf.loc[UNW_AARCH64_X22] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X22); - c->dwarf.loc[UNW_AARCH64_X23] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X23); - c->dwarf.loc[UNW_AARCH64_X24] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X24); - c->dwarf.loc[UNW_AARCH64_X25] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X25); - c->dwarf.loc[UNW_AARCH64_X26] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X26); - c->dwarf.loc[UNW_AARCH64_X27] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X27); - c->dwarf.loc[UNW_AARCH64_X28] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X28); - c->dwarf.loc[UNW_AARCH64_X29] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X29); - c->dwarf.loc[UNW_AARCH64_X30] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X30); - c->dwarf.loc[UNW_AARCH64_SP] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_SP); - c->dwarf.loc[UNW_AARCH64_PC] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_PC); - c->dwarf.loc[UNW_AARCH64_PSTATE] = DWARF_REG_LOC (&c->dwarf, - UNW_AARCH64_PSTATE); - c->dwarf.loc[UNW_AARCH64_V0] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V0); - c->dwarf.loc[UNW_AARCH64_V1] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V1); - c->dwarf.loc[UNW_AARCH64_V2] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V2); - c->dwarf.loc[UNW_AARCH64_V3] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V3); - c->dwarf.loc[UNW_AARCH64_V4] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V4); - c->dwarf.loc[UNW_AARCH64_V5] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V5); - c->dwarf.loc[UNW_AARCH64_V6] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V6); - c->dwarf.loc[UNW_AARCH64_V7] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V7); - c->dwarf.loc[UNW_AARCH64_V8] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V8); - c->dwarf.loc[UNW_AARCH64_V9] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V9); - c->dwarf.loc[UNW_AARCH64_V10] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V10); - c->dwarf.loc[UNW_AARCH64_V11] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V11); - c->dwarf.loc[UNW_AARCH64_V12] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V12); - c->dwarf.loc[UNW_AARCH64_V13] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V13); - c->dwarf.loc[UNW_AARCH64_V14] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V14); - c->dwarf.loc[UNW_AARCH64_V15] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V15); - c->dwarf.loc[UNW_AARCH64_V16] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V16); - c->dwarf.loc[UNW_AARCH64_V17] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V17); - c->dwarf.loc[UNW_AARCH64_V18] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V18); - c->dwarf.loc[UNW_AARCH64_V19] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V19); - c->dwarf.loc[UNW_AARCH64_V20] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V20); - c->dwarf.loc[UNW_AARCH64_V21] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V21); - c->dwarf.loc[UNW_AARCH64_V22] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V22); - c->dwarf.loc[UNW_AARCH64_V23] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V23); - c->dwarf.loc[UNW_AARCH64_V24] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V24); - c->dwarf.loc[UNW_AARCH64_V25] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V25); - c->dwarf.loc[UNW_AARCH64_V26] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V26); - c->dwarf.loc[UNW_AARCH64_V27] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V27); - c->dwarf.loc[UNW_AARCH64_V28] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V28); - c->dwarf.loc[UNW_AARCH64_V29] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V29); - c->dwarf.loc[UNW_AARCH64_V30] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V30); - c->dwarf.loc[UNW_AARCH64_V31] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V31); - - for (i = UNW_AARCH64_PSTATE + 1; i < UNW_AARCH64_V0; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); - if (ret < 0) - return ret; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_SP], &c->dwarf.cfa); - if (ret < 0) - return ret; - - c->sigcontext_format = AARCH64_SCF_NONE; - c->sigcontext_addr = 0; - c->sigcontext_sp = 0; - c->sigcontext_pc = 0; - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/is_fpreg.c deleted file mode 100644 index 2981d27520bb9b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/is_fpreg.c +++ /dev/null @@ -1,32 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - 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. */ - -#include "libunwind_i.h" - -int -unw_is_fpreg (int regnum) -{ - return (regnum >= UNW_AARCH64_V0 && regnum <= UNW_AARCH64_V31); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/offsets.h b/src/coreclr/src/pal/src/libunwind/src/aarch64/offsets.h deleted file mode 100644 index e78251d0a8f82c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/offsets.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Linux-specific definitions: */ - -/* Define various structure offsets to simplify cross-compilation. */ - -/* Offsets for AArch64 Linux "ucontext_t": */ - -#define LINUX_UC_FLAGS_OFF 0x0 -#define LINUX_UC_LINK_OFF 0x8 -#define LINUX_UC_STACK_OFF 0x10 -#define LINUX_UC_SIGMASK_OFF 0x28 -#define LINUX_UC_MCONTEXT_OFF 0xb0 - -/* Offsets for AArch64 Linux "struct sigcontext": */ - -#define LINUX_SC_FAULTADDRESS_OFF 0x00 -#define LINUX_SC_X0_OFF 0x008 -#define LINUX_SC_X1_OFF 0x010 -#define LINUX_SC_X2_OFF 0x018 -#define LINUX_SC_X3_OFF 0x020 -#define LINUX_SC_X4_OFF 0x028 -#define LINUX_SC_X5_OFF 0x030 -#define LINUX_SC_X6_OFF 0x038 -#define LINUX_SC_X7_OFF 0x040 -#define LINUX_SC_X8_OFF 0x048 -#define LINUX_SC_X9_OFF 0x050 -#define LINUX_SC_X10_OFF 0x058 -#define LINUX_SC_X11_OFF 0x060 -#define LINUX_SC_X12_OFF 0x068 -#define LINUX_SC_X13_OFF 0x070 -#define LINUX_SC_X14_OFF 0x078 -#define LINUX_SC_X15_OFF 0x080 -#define LINUX_SC_X16_OFF 0x088 -#define LINUX_SC_X17_OFF 0x090 -#define LINUX_SC_X18_OFF 0x098 -#define LINUX_SC_X19_OFF 0x0a0 -#define LINUX_SC_X20_OFF 0x0a8 -#define LINUX_SC_X21_OFF 0x0b0 -#define LINUX_SC_X22_OFF 0x0b8 -#define LINUX_SC_X23_OFF 0x0c0 -#define LINUX_SC_X24_OFF 0x0c8 -#define LINUX_SC_X25_OFF 0x0d0 -#define LINUX_SC_X26_OFF 0x0d8 -#define LINUX_SC_X27_OFF 0x0e0 -#define LINUX_SC_X28_OFF 0x0e8 -#define LINUX_SC_X29_OFF 0x0f0 -#define LINUX_SC_X30_OFF 0x0f8 -#define LINUX_SC_SP_OFF 0x100 -#define LINUX_SC_PC_OFF 0x108 -#define LINUX_SC_PSTATE_OFF 0x110 diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/regname.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/regname.c deleted file mode 100644 index 0f7a8bdcfbf559..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/regname.c +++ /dev/null @@ -1,106 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - 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. */ - -#include "unwind_i.h" - -static const char *const regname[] = - { - [UNW_AARCH64_X0] = "x0", - [UNW_AARCH64_X1] = "x1", - [UNW_AARCH64_X2] = "x2", - [UNW_AARCH64_X3] = "x3", - [UNW_AARCH64_X4] = "x4", - [UNW_AARCH64_X5] = "x5", - [UNW_AARCH64_X6] = "x6", - [UNW_AARCH64_X7] = "x7", - [UNW_AARCH64_X8] = "x8", - [UNW_AARCH64_X9] = "x9", - [UNW_AARCH64_X10] = "x10", - [UNW_AARCH64_X11] = "x11", - [UNW_AARCH64_X12] = "x12", - [UNW_AARCH64_X13] = "x13", - [UNW_AARCH64_X14] = "x14", - [UNW_AARCH64_X15] = "x15", - [UNW_AARCH64_X16] = "ip0", - [UNW_AARCH64_X17] = "ip1", - [UNW_AARCH64_X18] = "x18", - [UNW_AARCH64_X19] = "x19", - [UNW_AARCH64_X20] = "x20", - [UNW_AARCH64_X21] = "x21", - [UNW_AARCH64_X22] = "x22", - [UNW_AARCH64_X23] = "x23", - [UNW_AARCH64_X24] = "x24", - [UNW_AARCH64_X25] = "x25", - [UNW_AARCH64_X26] = "x26", - [UNW_AARCH64_X27] = "x27", - [UNW_AARCH64_X28] = "x28", - [UNW_AARCH64_X29] = "fp", - [UNW_AARCH64_X30] = "lr", - [UNW_AARCH64_SP] = "sp", - [UNW_AARCH64_PC] = "pc", - [UNW_AARCH64_V0] = "v0", - [UNW_AARCH64_V1] = "v1", - [UNW_AARCH64_V2] = "v2", - [UNW_AARCH64_V3] = "v3", - [UNW_AARCH64_V4] = "v4", - [UNW_AARCH64_V5] = "v5", - [UNW_AARCH64_V6] = "v6", - [UNW_AARCH64_V7] = "v7", - [UNW_AARCH64_V8] = "v8", - [UNW_AARCH64_V9] = "v9", - [UNW_AARCH64_V10] = "v10", - [UNW_AARCH64_V11] = "v11", - [UNW_AARCH64_V12] = "v12", - [UNW_AARCH64_V13] = "v13", - [UNW_AARCH64_V14] = "v14", - [UNW_AARCH64_V15] = "v15", - [UNW_AARCH64_V16] = "v16", - [UNW_AARCH64_V17] = "v17", - [UNW_AARCH64_V18] = "v18", - [UNW_AARCH64_V19] = "v19", - [UNW_AARCH64_V20] = "v20", - [UNW_AARCH64_V21] = "v21", - [UNW_AARCH64_V22] = "v22", - [UNW_AARCH64_V23] = "v23", - [UNW_AARCH64_V24] = "v24", - [UNW_AARCH64_V25] = "v25", - [UNW_AARCH64_V26] = "v26", - [UNW_AARCH64_V27] = "v27", - [UNW_AARCH64_V28] = "v28", - [UNW_AARCH64_V29] = "v29", - [UNW_AARCH64_V30] = "v30", - [UNW_AARCH64_V31] = "v31", - [UNW_AARCH64_FPSR] = "fpsr", - [UNW_AARCH64_FPCR] = "fpcr", - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname) && regname[reg] != NULL) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/aarch64/siglongjmp.S deleted file mode 100644 index 9985c4b4aab378..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/siglongjmp.S +++ /dev/null @@ -1,12 +0,0 @@ - /* Dummy implementation for now. */ - - .global _UI_siglongjmp_cont - .global _UI_longjmp_cont - -_UI_siglongjmp_cont: -_UI_longjmp_cont: - ret -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h deleted file mode 100644 index 3d324c2b08bd54..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h +++ /dev/null @@ -1,64 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - 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 unwind_i_h -#define unwind_i_h - -#include - -#include - -#include "libunwind_i.h" - -/* DWARF column numbers for AArch64: */ -#define X29 29 -#define FP 29 -#define X30 30 -#define LR 30 -#define SP 31 - -#define aarch64_lock UNW_OBJ(lock) -#define aarch64_local_resume UNW_OBJ(local_resume) -#define aarch64_local_addr_space_init UNW_OBJ(local_addr_space_init) - -extern void aarch64_local_addr_space_init (void); -extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, - void *arg); - -/* By-pass calls to access_mem() when known to be safe. */ -#ifdef UNW_LOCAL_ONLY -# undef ACCESS_MEM_FAST -# define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ - do { \ - if (unlikely(validate)) \ - (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); \ - else \ - (ret) = 0, (to) = *(unw_word_t *)(addr); \ - } while (0) -#endif - -#define GET_FPCTX(uc) ((struct fpsimd_context *)(&uc->uc_mcontext.__reserved)) - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gcreate_addr_space.c deleted file mode 100644 index 7b2d6bacfdcd7d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gcreate_addr_space.c +++ /dev/null @@ -1,60 +0,0 @@ -/* 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. */ - -#include - -#include "unwind_i.h" - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* - * ARM supports little-endian and big-endian. - */ - if (byte_order != 0 && byte_order != __LITTLE_ENDIAN - && byte_order != __BIG_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - /* Default to little-endian for ARM. */ - if (byte_order == 0 || byte_order == __LITTLE_ENDIAN) - as->big_endian = 0; - else - as->big_endian = 1; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c deleted file mode 100644 index e79903cd87d3fe..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c +++ /dev/null @@ -1,548 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright 2011 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. */ - -/* This file contains functionality for parsing and interpreting the ARM -specific unwind information. Documentation about the exception handling -ABI for the ARM architecture can be found at: -http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf -*/ - -#include "libunwind_i.h" - -#define ARM_EXBUF_START(x) (((x) >> 4) & 0x0f) -#define ARM_EXBUF_COUNT(x) ((x) & 0x0f) -#define ARM_EXBUF_END(x) (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x)) - -#define ARM_EXIDX_CANT_UNWIND 0x00000001 -#define ARM_EXIDX_COMPACT 0x80000000 - -#define ARM_EXTBL_OP_FINISH 0xb0 - -enum arm_exbuf_cmd_flags { - ARM_EXIDX_VFP_SHIFT_16 = 1 << 16, - ARM_EXIDX_VFP_DOUBLE = 1 << 17, -}; - -struct arm_cb_data - { - /* in: */ - unw_word_t ip; /* instruction-pointer we're looking for */ - unw_proc_info_t *pi; /* proc-info pointer */ - /* out: */ - unw_dyn_info_t di; /* info about the ARM exidx segment */ - }; - -static inline uint32_t CONST_ATTR -prel31_read (uint32_t prel31) -{ - return ((int32_t)prel31 << 1) >> 1; -} - -static inline int -prel31_to_addr (unw_addr_space_t as, void *arg, unw_word_t prel31, - unw_word_t *val) -{ - unw_word_t offset; - - if ((*as->acc.access_mem)(as, prel31, &offset, 0, arg) < 0) - return -UNW_EINVAL; - - offset = ((long)offset << 1) >> 1; - *val = prel31 + offset; - - return 0; -} - -/** - * Applies the given command onto the new state to the given dwarf_cursor. - */ -HIDDEN int -arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c) -{ - int ret = 0; - unsigned i; - - switch (edata->cmd) - { - case ARM_EXIDX_CMD_FINISH: - /* Set LR to PC if not set already. */ - if (DWARF_IS_NULL_LOC (c->loc[UNW_ARM_R15])) - c->loc[UNW_ARM_R15] = c->loc[UNW_ARM_R14]; - /* Set IP. */ - dwarf_get (c, c->loc[UNW_ARM_R15], &c->ip); - break; - case ARM_EXIDX_CMD_DATA_PUSH: - Debug (2, "vsp = vsp - %d\n", edata->data); - c->cfa -= edata->data; - break; - case ARM_EXIDX_CMD_DATA_POP: - Debug (2, "vsp = vsp + %d\n", edata->data); - c->cfa += edata->data; - break; - case ARM_EXIDX_CMD_REG_POP: - for (i = 0; i < 16; i++) - if (edata->data & (1 << i)) - { - Debug (2, "pop {r%d}\n", i); - c->loc[UNW_ARM_R0 + i] = DWARF_LOC (c->cfa, 0); - c->cfa += 4; - } - /* Set cfa in case the SP got popped. */ - if (edata->data & (1 << 13)) - dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa); - break; - case ARM_EXIDX_CMD_REG_TO_SP: - assert (edata->data < 16); - Debug (2, "vsp = r%d\n", edata->data); - c->loc[UNW_ARM_R13] = c->loc[UNW_ARM_R0 + edata->data]; - dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa); - break; - case ARM_EXIDX_CMD_VFP_POP: - /* Skip VFP registers, but be sure to adjust stack */ - for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data); - i++) - c->cfa += 8; - if (!(edata->data & ARM_EXIDX_VFP_DOUBLE)) - c->cfa += 4; - break; - case ARM_EXIDX_CMD_WREG_POP: - for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data); - i++) - c->cfa += 8; - break; - case ARM_EXIDX_CMD_WCGR_POP: - for (i = 0; i < 4; i++) - if (edata->data & (1 << i)) - c->cfa += 4; - break; - case ARM_EXIDX_CMD_REFUSED: - case ARM_EXIDX_CMD_RESERVED: - ret = -1; - break; - } - return ret; -} - -/** - * Decodes the given unwind instructions into arm_exbuf_data and calls - * arm_exidx_apply_cmd that applies the command onto the dwarf_cursor. - */ -HIDDEN int -arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c) -{ -#define READ_OP() *buf++ - assert(buf != NULL); - assert(len > 0); - const uint8_t *end = buf + len; - int ret; - struct arm_exbuf_data edata; - - while (buf < end) - { - uint8_t op = READ_OP (); - if ((op & 0xc0) == 0x00) - { - edata.cmd = ARM_EXIDX_CMD_DATA_POP; - edata.data = (((int)op & 0x3f) << 2) + 4; - } - else if ((op & 0xc0) == 0x40) - { - edata.cmd = ARM_EXIDX_CMD_DATA_PUSH; - edata.data = (((int)op & 0x3f) << 2) + 4; - } - else if ((op & 0xf0) == 0x80) - { - uint8_t op2 = READ_OP (); - if (op == 0x80 && op2 == 0x00) - edata.cmd = ARM_EXIDX_CMD_REFUSED; - else - { - edata.cmd = ARM_EXIDX_CMD_REG_POP; - edata.data = ((op & 0xf) << 8) | op2; - edata.data = edata.data << 4; - } - } - else if ((op & 0xf0) == 0x90) - { - if (op == 0x9d || op == 0x9f) - edata.cmd = ARM_EXIDX_CMD_RESERVED; - else - { - edata.cmd = ARM_EXIDX_CMD_REG_TO_SP; - edata.data = op & 0x0f; - } - } - else if ((op & 0xf0) == 0xa0) - { - unsigned end = (op & 0x07); - edata.data = (1 << (end + 1)) - 1; - edata.data = edata.data << 4; - if (op & 0x08) - edata.data |= 1 << 14; - edata.cmd = ARM_EXIDX_CMD_REG_POP; - } - else if (op == ARM_EXTBL_OP_FINISH) - { - edata.cmd = ARM_EXIDX_CMD_FINISH; - buf = end; - } - else if (op == 0xb1) - { - uint8_t op2 = READ_OP (); - if (op2 == 0 || (op2 & 0xf0)) - edata.cmd = ARM_EXIDX_CMD_RESERVED; - else - { - edata.cmd = ARM_EXIDX_CMD_REG_POP; - edata.data = op2 & 0x0f; - } - } - else if (op == 0xb2) - { - uint32_t offset = 0; - uint8_t byte, shift = 0; - do - { - byte = READ_OP (); - offset |= (byte & 0x7f) << shift; - shift += 7; - } - while (byte & 0x80); - edata.data = offset * 4 + 0x204; - edata.cmd = ARM_EXIDX_CMD_DATA_POP; - } - else if (op == 0xb3 || op == 0xc8 || op == 0xc9) - { - edata.cmd = ARM_EXIDX_CMD_VFP_POP; - edata.data = READ_OP (); - if (op == 0xc8) - edata.data |= ARM_EXIDX_VFP_SHIFT_16; - if (op != 0xb3) - edata.data |= ARM_EXIDX_VFP_DOUBLE; - } - else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0) - { - edata.cmd = ARM_EXIDX_CMD_VFP_POP; - edata.data = 0x80 | (op & 0x07); - if ((op & 0xf8) == 0xd0) - edata.data |= ARM_EXIDX_VFP_DOUBLE; - } - else if (op >= 0xc0 && op <= 0xc5) - { - edata.cmd = ARM_EXIDX_CMD_WREG_POP; - edata.data = 0xa0 | (op & 0x07); - } - else if (op == 0xc6) - { - edata.cmd = ARM_EXIDX_CMD_WREG_POP; - edata.data = READ_OP (); - } - else if (op == 0xc7) - { - uint8_t op2 = READ_OP (); - if (op2 == 0 || (op2 & 0xf0)) - edata.cmd = ARM_EXIDX_CMD_RESERVED; - else - { - edata.cmd = ARM_EXIDX_CMD_WCGR_POP; - edata.data = op2 & 0x0f; - } - } - else - edata.cmd = ARM_EXIDX_CMD_RESERVED; - - ret = arm_exidx_apply_cmd (&edata, c); - if (ret < 0) - return ret; - } - return 0; -} - -/** - * Reads the entry from the given cursor and extracts the unwind instructions - * into buf. Returns the number of the extracted unwind insns or - * -UNW_ESTOPUNWIND if the special bit pattern ARM_EXIDX_CANT_UNWIND (0x1) was - * found. - */ -HIDDEN int -arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf) -{ - int nbuf = 0; - unw_word_t entry = (unw_word_t) c->pi.unwind_info; - unw_word_t addr; - uint32_t data; - - /* An ARM unwind entry consists of a prel31 offset to the start of a - function followed by 31bits of data: - * if set to 0x1: the function cannot be unwound (EXIDX_CANTUNWIND) - * if bit 31 is one: this is a table entry itself (ARM_EXIDX_COMPACT) - * if bit 31 is zero: this is a prel31 offset of the start of the - table entry for this function */ - if (prel31_to_addr(c->as, c->as_arg, entry, &addr) < 0) - return -UNW_EINVAL; - - if ((*c->as->acc.access_mem)(c->as, entry + 4, &data, 0, c->as_arg) < 0) - return -UNW_EINVAL; - - if (data == ARM_EXIDX_CANT_UNWIND) - { - Debug (2, "0x1 [can't unwind]\n"); - nbuf = -UNW_ESTOPUNWIND; - } - else if (data & ARM_EXIDX_COMPACT) - { - Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, - (data >> 24) & 0x7f, data); - buf[nbuf++] = data >> 16; - buf[nbuf++] = data >> 8; - buf[nbuf++] = data; - } - else - { - unw_word_t extbl_data; - unsigned int n_table_words = 0; - - if (prel31_to_addr(c->as, c->as_arg, entry + 4, &extbl_data) < 0) - return -UNW_EINVAL; - - if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0, c->as_arg) < 0) - return -UNW_EINVAL; - - if (data & ARM_EXIDX_COMPACT) - { - int pers = (data >> 24) & 0x0f; - Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, pers, data); - if (pers == 1 || pers == 2) - { - n_table_words = (data >> 16) & 0xff; - extbl_data += 4; - } - else - buf[nbuf++] = data >> 16; - buf[nbuf++] = data >> 8; - buf[nbuf++] = data; - } - else - { - unw_word_t pers; - if (prel31_to_addr (c->as, c->as_arg, extbl_data, &pers) < 0) - return -UNW_EINVAL; - Debug (2, "%p Personality routine: %8p\n", (void *)addr, - (void *)pers); - if ((*c->as->acc.access_mem)(c->as, extbl_data + 4, &data, 0, - c->as_arg) < 0) - return -UNW_EINVAL; - n_table_words = data >> 24; - buf[nbuf++] = data >> 16; - buf[nbuf++] = data >> 8; - buf[nbuf++] = data; - extbl_data += 8; - } - assert (n_table_words <= 5); - unsigned j; - for (j = 0; j < n_table_words; j++) - { - if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0, - c->as_arg) < 0) - return -UNW_EINVAL; - extbl_data += 4; - buf[nbuf++] = data >> 24; - buf[nbuf++] = data >> 16; - buf[nbuf++] = data >> 8; - buf[nbuf++] = data >> 0; - } - } - - if (nbuf > 0 && buf[nbuf - 1] != ARM_EXTBL_OP_FINISH) - buf[nbuf++] = ARM_EXTBL_OP_FINISH; - - return nbuf; -} - -int -arm_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) -{ - /* The .ARM.exidx section contains a sorted list of key-value pairs - - the unwind entries. The 'key' is a prel31 offset to the start of a - function. We binary search this section in order to find the - appropriate unwind entry. */ - unw_word_t first = di->u.rti.table_data; - unw_word_t last = di->u.rti.table_data + di->u.rti.table_len - 8; - unw_word_t entry, val; - - if (prel31_to_addr (as, arg, first, &val) < 0 || ip < val) - return -UNW_ENOINFO; - - if (prel31_to_addr (as, arg, last, &val) < 0) - return -UNW_EINVAL; - - if (ip >= val) - { - entry = last; - - if (prel31_to_addr (as, arg, last, &pi->start_ip) < 0) - return -UNW_EINVAL; - - pi->end_ip = di->end_ip -1; - } - else - { - while (first < last - 8) - { - entry = first + (((last - first) / 8 + 1) >> 1) * 8; - - if (prel31_to_addr (as, arg, entry, &val) < 0) - return -UNW_EINVAL; - - if (ip < val) - last = entry; - else - first = entry; - } - - entry = first; - - if (prel31_to_addr (as, arg, entry, &pi->start_ip) < 0) - return -UNW_EINVAL; - - if (prel31_to_addr (as, arg, entry + 8, &pi->end_ip) < 0) - return -UNW_EINVAL; - - pi->end_ip--; - } - - if (need_unwind_info) - { - pi->unwind_info_size = 8; - pi->unwind_info = (void *) entry; - pi->format = UNW_INFO_FORMAT_ARM_EXIDX; - } - return 0; -} - -int -tdep_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) -{ - if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX) - && di->format == UNW_INFO_FORMAT_ARM_EXIDX) - return arm_search_unwind_table (as, ip, di, pi, need_unwind_info, arg); - else if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) - && di->format != UNW_INFO_FORMAT_ARM_EXIDX) - return dwarf_search_unwind_table (as, ip, di, pi, need_unwind_info, arg); - - return -UNW_ENOINFO; -} - -#ifndef UNW_REMOTE_ONLY -/** - * Callback to dl_iterate_phdr to find infos about the ARM exidx segment. - */ -static int -arm_phdr_cb (struct dl_phdr_info *info, size_t size, void *data) -{ - struct arm_cb_data *cb_data = data; - const Elf_W(Phdr) *p_text = NULL; - const Elf_W(Phdr) *p_arm_exidx = NULL; - const Elf_W(Phdr) *phdr = info->dlpi_phdr; - long n; - - for (n = info->dlpi_phnum; --n >= 0; phdr++) - { - switch (phdr->p_type) - { - case PT_LOAD: - if (cb_data->ip >= phdr->p_vaddr + info->dlpi_addr && - cb_data->ip < phdr->p_vaddr + info->dlpi_addr + phdr->p_memsz) - p_text = phdr; - break; - - case PT_ARM_EXIDX: - p_arm_exidx = phdr; - break; - - default: - break; - } - } - - if (p_text && p_arm_exidx) - { - cb_data->di.format = UNW_INFO_FORMAT_ARM_EXIDX; - cb_data->di.start_ip = p_text->p_vaddr + info->dlpi_addr; - cb_data->di.end_ip = cb_data->di.start_ip + p_text->p_memsz; - cb_data->di.u.rti.name_ptr = (unw_word_t) info->dlpi_name; - cb_data->di.u.rti.table_data = p_arm_exidx->p_vaddr + info->dlpi_addr; - cb_data->di.u.rti.table_len = p_arm_exidx->p_memsz; - return 1; - } - - return 0; -} - -HIDDEN int -arm_find_proc_info (unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, int need_unwind_info, void *arg) -{ - int ret = -1; - intrmask_t saved_mask; - - Debug (14, "looking for IP=0x%lx\n", (long) ip); - - if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)) - ret = dwarf_find_proc_info (as, ip, pi, need_unwind_info, arg); - - if (ret < 0 && UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) - { - struct arm_cb_data cb_data; - - memset (&cb_data, 0, sizeof (cb_data)); - cb_data.ip = ip; - cb_data.pi = pi; - cb_data.di.format = -1; - - SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); - ret = dl_iterate_phdr (arm_phdr_cb, &cb_data); - SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); - - if (cb_data.di.format != -1) - ret = arm_search_unwind_table (as, ip, &cb_data.di, pi, - need_unwind_info, arg); - else - ret = -UNW_ENOINFO; - } - - return ret; -} - -HIDDEN void -arm_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} -#endif /* !UNW_REMOTE_ONLY */ - diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gget_proc_info.c deleted file mode 100644 index 4051a10766e474..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gget_proc_info.c +++ /dev/null @@ -1,41 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - /* We can only unwind using Dwarf into on ARM: return failure code - if it's not present. */ - ret = dwarf_make_proc_info (&c->dwarf); - if (ret < 0) - return ret; - - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gget_save_loc.c deleted file mode 100644 index 9fb070489cd52b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gget_save_loc.c +++ /dev/null @@ -1,81 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - struct cursor *c = (struct cursor *) cursor; - dwarf_loc_t loc; - - loc = DWARF_NULL_LOC; /* default to "not saved" */ - - switch (reg) - { - case UNW_ARM_R0: - case UNW_ARM_R1: - case UNW_ARM_R2: - case UNW_ARM_R3: - case UNW_ARM_R4: - case UNW_ARM_R5: - case UNW_ARM_R6: - case UNW_ARM_R7: - case UNW_ARM_R8: - case UNW_ARM_R9: - case UNW_ARM_R10: - case UNW_ARM_R11: - case UNW_ARM_R12: - case UNW_ARM_R13: - case UNW_ARM_R14: - case UNW_ARM_R15: - loc = c->dwarf.loc[reg - UNW_ARM_R0]; - break; - - default: - break; - } - - memset (sloc, 0, sizeof (*sloc)); - - if (DWARF_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (DWARF_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = DWARF_GET_LOC (loc); - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = DWARF_GET_LOC (loc); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gglobal.c deleted file mode 100644 index 7b93fbd89a1850..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gglobal.c +++ /dev/null @@ -1,65 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" -#include "dwarf_i.h" - -HIDDEN define_lock (arm_lock); -HIDDEN int tdep_init_done; - -/* Unwinding methods to use. See UNW_METHOD_ enums */ -HIDDEN int unwi_unwind_method = UNW_ARM_METHOD_ALL; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&arm_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - /* read ARM unwind method setting */ - const char* str = getenv ("UNW_ARM_UNWIND_METHOD"); - if (str) - { - unwi_unwind_method = atoi (str); - } - - mi_init (); - - dwarf_init (); - -#ifndef UNW_REMOTE_ONLY - arm_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&arm_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c deleted file mode 100644 index 2720d063a2424f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c +++ /dev/null @@ -1,235 +0,0 @@ -/* 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. */ - -#include -#include - -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -static inline void * -uc_addr (unw_tdep_context_t *uc, int reg) -{ - if (reg >= UNW_ARM_R0 && reg < UNW_ARM_R0 + 16) - return &uc->regs[reg - UNW_ARM_R0]; - else - return NULL; -} - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (unw_tdep_context_t *uc, int reg) -{ - return uc_addr (uc, reg); -} - -# endif /* UNW_LOCAL_ONLY */ - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; - return 0; -} - -#define PAGE_SIZE 4096 -#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) - -/* Cache of already validated addresses */ -#define NLGA 4 -static unw_word_t last_good_addr[NLGA]; -static int lga_victim; - -static int -validate_mem (unw_word_t addr) -{ - int i, victim; - size_t len; - - if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) - len = PAGE_SIZE; - else - len = PAGE_SIZE * 2; - - addr = PAGE_START(addr); - - if (addr == 0) - return -1; - - for (i = 0; i < NLGA; i++) - { - if (last_good_addr[i] && (addr == last_good_addr[i])) - return 0; - } - - if (msync ((void *) addr, len, MS_ASYNC) == -1) - return -1; - - victim = lga_victim; - for (i = 0; i < NLGA; i++) { - if (!last_good_addr[victim]) { - last_good_addr[victim++] = addr; - return 0; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - last_good_addr[victim] = addr; - victim = (victim + 1) % NLGA; - lga_victim = victim; - - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - /* validate address */ - const struct cursor *c = (const struct cursor *) arg; - if (c && validate_mem(addr)) - return -1; - - if (write) - { - Debug (16, "mem[%x] <- %x\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - *val = *(unw_word_t *) addr; - Debug (16, "mem[%x] -> %x\n", addr, *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr; - unw_tdep_context_t *uc = arg; - - if (unw_is_fpreg (reg)) - goto badreg; - -Debug (16, "reg = %s\n", unw_regname (reg)); - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - *(unw_word_t *) addr = *val; - Debug (12, "%s <- %x\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> %x\n", unw_regname (reg), *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - unw_tdep_context_t *uc = arg; - unw_fpreg_t *addr; - - if (!unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - *(unw_fpreg_t *) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -arm_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = arm_find_proc_info; - local_addr_space.acc.put_unwind_info = arm_put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = arm_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_local.c deleted file mode 100644 index e13519b79a9e6e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_local.c +++ /dev/null @@ -1,78 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright 2011 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. */ - -#include "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local_common (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = uc; - - return common_init (c, use_prev_instr); -} - -int -unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, unw_context_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_remote.c deleted file mode 100644 index 9b8ba5b89def1a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_remote.c +++ /dev/null @@ -1,45 +0,0 @@ -/* 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. */ - -#include "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - c->dwarf.as_arg = as_arg; - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gos-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gos-freebsd.c deleted file mode 100644 index a1069223a507dc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gos-freebsd.c +++ /dev/null @@ -1,129 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright 2011 Linaro Limited - Copyright (C) 2012 Tommi Rantala - Copyright 2015 The FreeBSD Foundation - - Portions of this software were developed by Konstantin Belousov - under sponsorship from the FreeBSD Foundation. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include "unwind_i.h" -#include "offsets.h" -#include "ex_tables.h" - -HIDDEN int -arm_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret, fmt; - unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; - struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); - - if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) - return -UNW_EUNSPEC; - fmt = unw_is_signal_frame(cursor); - - c->dwarf.pi_valid = 0; - - if (fmt == UNW_ARM_FRAME_SYSCALL) - { - c->sigcontext_format = ARM_SCF_FREEBSD_SYSCALL; - c->frame_info.frame_type = UNW_ARM_FRAME_SYSCALL; - c->frame_info.cfa_reg_offset = 0; - c->dwarf.loc[UNW_ARM_R7] = c->dwarf.loc[UNW_ARM_R12]; - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R14], &c->dwarf.ip); - return 1; - } - - c->sigcontext_format = ARM_SCF_FREEBSD_SIGFRAME; - sc_addr = sp_addr; - - /* Save the SP and PC to be able to return execution at this point - later in time (unw_resume). */ - c->sigcontext_sp = c->dwarf.cfa; - c->sigcontext_pc = c->dwarf.ip; - - c->sigcontext_addr = sc_addr; - c->frame_info.frame_type = UNW_ARM_FRAME_SIGRETURN; - c->frame_info.cfa_reg_offset = sc_addr - sp_addr; - - /* Update the dwarf cursor. - Set the location of the registers to the corresponding addresses of the - uc_mcontext / sigcontext structure contents. */ -#define ROFF(n) (FREEBSD_SC_UCONTEXT_OFF + FREEBSD_UC_MCONTEXT_OFF + \ - FREEBSD_MC_R0_OFF + (n) * 4) -#define SL(n) \ - c->dwarf.loc[UNW_ARM_R ## n] = DWARF_LOC (sc_addr + ROFF(n), 0); - SL(0); SL(1); SL(2); SL(3); SL(4); SL(5); SL(6); SL(7); - SL(8); SL(9); SL(10); SL(11); SL(12); SL(13); SL(14); SL(15); -#undef SL -#undef ROFF - - /* Set SP/CFA and PC/IP. */ - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R13], &c->dwarf.cfa); - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); - - return 1; -} - -/* Returns 1 in case of a non-RT signal frame and 2 in case of a RT signal - frame. */ -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, w1, w2, w3, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - ip = c->dwarf.ip; - - if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) - return ret; - if ((ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0) - return ret; - if ((ret = (*a->access_mem) (as, ip + 8, &w2, 0, arg)) < 0) - return ret; - if ((ret = (*a->access_mem) (as, ip + 12, &w3, 0, arg)) < 0) - return ret; - - if (w0 == 0xe1a0000d && w1 == 0xe2800040 && w2 == 0xe59f700c && - w3 == 0xef0001a1) - return UNW_ARM_FRAME_SIGRETURN; - - if ((ret = (*a->access_mem) (as, ip - 4, &w0, 0, arg)) < 0) - return ret; - if (w0 == 0xef000000) - return UNW_ARM_FRAME_SYSCALL; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gos-linux.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gos-linux.c deleted file mode 100644 index 260e086f6953ea..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gos-linux.c +++ /dev/null @@ -1,182 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright 2011 Linaro Limited - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include "unwind_i.h" -#include "offsets.h" - -HIDDEN int -arm_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; - struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); - - if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) - return -UNW_EUNSPEC; - - /* Obtain signal frame type (non-RT or RT). */ - ret = unw_is_signal_frame (cursor); - - /* Save the SP and PC to be able to return execution at this point - later in time (unw_resume). */ - c->sigcontext_sp = c->dwarf.cfa; - c->sigcontext_pc = c->dwarf.ip; - - /* Since kernel version 2.6.18 the non-RT signal frame starts with a - ucontext while the RT signal frame starts with a siginfo, followed - by a sigframe whose first element is an ucontext. - Prior 2.6.18 the non-RT signal frame starts with a sigcontext while - the RT signal frame starts with two pointers followed by a siginfo - and an ucontext. The first pointer points to the start of the siginfo - structure and the second one to the ucontext structure. */ - - if (ret == 1) - { - /* Handle non-RT signal frames. Check if the first word on the stack - is the magic number. */ - if (sp == 0x5ac3c35a) - { - c->sigcontext_format = ARM_SCF_LINUX_SIGFRAME; - sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF; - } - else - { - c->sigcontext_format = ARM_SCF_LINUX_OLD_SIGFRAME; - sc_addr = sp_addr; - } - } - else if (ret == 2) - { - /* Handle RT signal frames. Check if the first word on the stack is a - pointer to the siginfo structure. */ - if (sp == sp_addr + 8) - { - c->sigcontext_format = ARM_SCF_LINUX_OLD_RT_SIGFRAME; - sc_addr = sp_addr + 8 + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; - } - else - { - c->sigcontext_format = ARM_SCF_LINUX_RT_SIGFRAME; - sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; - } - } - else - return -UNW_EUNSPEC; - - c->sigcontext_addr = sc_addr; - c->frame_info.frame_type = UNW_ARM_FRAME_SIGRETURN; - c->frame_info.cfa_reg_offset = sc_addr - sp_addr; - - /* Update the dwarf cursor. - Set the location of the registers to the corresponding addresses of the - uc_mcontext / sigcontext structure contents. */ - c->dwarf.loc[UNW_ARM_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); - c->dwarf.loc[UNW_ARM_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); - c->dwarf.loc[UNW_ARM_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); - c->dwarf.loc[UNW_ARM_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); - c->dwarf.loc[UNW_ARM_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); - c->dwarf.loc[UNW_ARM_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); - c->dwarf.loc[UNW_ARM_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); - c->dwarf.loc[UNW_ARM_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); - c->dwarf.loc[UNW_ARM_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); - c->dwarf.loc[UNW_ARM_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); - c->dwarf.loc[UNW_ARM_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); - c->dwarf.loc[UNW_ARM_R11] = DWARF_LOC (sc_addr + LINUX_SC_FP_OFF, 0); - c->dwarf.loc[UNW_ARM_R12] = DWARF_LOC (sc_addr + LINUX_SC_IP_OFF, 0); - c->dwarf.loc[UNW_ARM_R13] = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0); - c->dwarf.loc[UNW_ARM_R14] = DWARF_LOC (sc_addr + LINUX_SC_LR_OFF, 0); - c->dwarf.loc[UNW_ARM_R15] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); - - /* Set SP/CFA and PC/IP. */ - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R13], &c->dwarf.cfa); - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); - - c->dwarf.pi_valid = 0; - - return 1; -} - -#define ARM_NR_sigreturn 119 -#define ARM_NR_rt_sigreturn 173 -#define ARM_NR_OABI_SYSCALL_BASE 0x900000 - -/* ARM EABI sigreturn (the syscall number is loaded into r7) */ -#define MOV_R7_SIGRETURN (0xe3a07000UL | ARM_NR_sigreturn) -#define MOV_R7_RT_SIGRETURN (0xe3a07000UL | ARM_NR_rt_sigreturn) - -/* ARM OABI sigreturn (using SWI) */ -#define ARM_SIGRETURN \ - (0xef000000UL | ARM_NR_sigreturn | ARM_NR_OABI_SYSCALL_BASE) -#define ARM_RT_SIGRETURN \ - (0xef000000UL | ARM_NR_rt_sigreturn | ARM_NR_OABI_SYSCALL_BASE) - -/* Thumb sigreturn (two insns, syscall number is loaded into r7) */ -#define THUMB_SIGRETURN (0xdf00UL << 16 | 0x2700 | ARM_NR_sigreturn) -#define THUMB_RT_SIGRETURN (0xdf00UL << 16 | 0x2700 | ARM_NR_rt_sigreturn) - -/* Thumb2 sigreturn (mov.w r7, $SYS_ify(rt_sigreturn/sigreturn)) */ -#define THUMB2_SIGRETURN (((0x0700 | ARM_NR_sigreturn) << 16) | \ - 0xf04f) -#define THUMB2_RT_SIGRETURN (((0x0700 | ARM_NR_rt_sigreturn) << 16) | \ - 0xf04f) -/* TODO: with different toolchains, there are a lot more possibilities */ - -/* Returns 1 in case of a non-RT signal frame and 2 in case of a RT signal - frame. */ -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - /* The least bit denotes thumb/arm mode. Do not read there. */ - ip = c->dwarf.ip & ~0x1; - - if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) - return ret; - - /* Return 1 if the IP points to a non-RT sigreturn sequence. */ - if (w0 == MOV_R7_SIGRETURN || w0 == ARM_SIGRETURN || w0 == THUMB_SIGRETURN - || w0 == THUMB2_SIGRETURN) - return 1; - /* Return 2 if the IP points to a RT sigreturn sequence. */ - else if (w0 == MOV_R7_RT_SIGRETURN || w0 == ARM_RT_SIGRETURN - || w0 == THUMB_RT_SIGRETURN || w0 == THUMB2_RT_SIGRETURN) - return 2; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gos-other.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gos-other.c deleted file mode 100644 index 73c102c3d26f03..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gos-other.c +++ /dev/null @@ -1,48 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright 2011 Linaro Limited - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include "unwind_i.h" -#include "offsets.h" - -HIDDEN int -arm_handle_signal_frame (unw_cursor_t *cursor) -{ - return -UNW_EUNSPEC; -} - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ -#if defined(__QNX__) - /* Not supported yet */ - return 0; -#else - printf ("%s: implement me\n", __FUNCTION__); - return -UNW_ENOINFO; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/arm/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gregs.c deleted file mode 100644 index 0d52f0b2225225..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gregs.c +++ /dev/null @@ -1,83 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - - switch (reg) - { - case UNW_ARM_R15: - if (write) - c->dwarf.ip = *valp; /* update the IP cache */ - case UNW_ARM_R0: - case UNW_ARM_R1: - case UNW_ARM_R2: - case UNW_ARM_R3: - case UNW_ARM_R4: - case UNW_ARM_R5: - case UNW_ARM_R6: - case UNW_ARM_R7: - case UNW_ARM_R8: - case UNW_ARM_R9: - case UNW_ARM_R10: - case UNW_ARM_R11: - case UNW_ARM_R12: - case UNW_ARM_R14: - loc = c->dwarf.loc[reg - UNW_ARM_R0]; - break; - - case UNW_ARM_R13: - case UNW_ARM_CFA: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - /* FIXME: Initialise coprocessor & shadow registers? */ - - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -/* FIXME for ARM. */ - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c deleted file mode 100644 index a8288628a6cd61..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c +++ /dev/null @@ -1,154 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright 2011 Linaro Limited - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" - -#ifndef UNW_REMOTE_ONLY - -HIDDEN inline int -arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ -#ifdef __linux__ - struct cursor *c = (struct cursor *) cursor; - unw_tdep_context_t *uc = c->dwarf.as_arg; - - if (c->sigcontext_format == ARM_SCF_NONE) - { - /* Since there are no signals involved here we restore the non scratch - registers only. */ - unsigned long regs[10]; - regs[0] = uc->regs[4]; - regs[1] = uc->regs[5]; - regs[2] = uc->regs[6]; - regs[3] = uc->regs[7]; - regs[4] = uc->regs[8]; - regs[5] = uc->regs[9]; - regs[6] = uc->regs[10]; - regs[7] = uc->regs[11]; /* FP */ - regs[8] = uc->regs[13]; /* SP */ - regs[9] = uc->regs[14]; /* LR */ - - struct regs_overlay { - char x[sizeof(regs)]; - }; - - asm __volatile__ ( - "ldmia %0, {r4-r12, lr}\n" - "mov sp, r12\n" - "bx lr\n" - : : "r" (regs), - "m" (*(struct regs_overlay *)regs) - ); - } - else - { - /* In case a signal frame is involved, we're using its trampoline which - calls sigreturn. */ - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - sc->arm_r0 = uc->regs[0]; - sc->arm_r1 = uc->regs[1]; - sc->arm_r2 = uc->regs[2]; - sc->arm_r3 = uc->regs[3]; - sc->arm_r4 = uc->regs[4]; - sc->arm_r5 = uc->regs[5]; - sc->arm_r6 = uc->regs[6]; - sc->arm_r7 = uc->regs[7]; - sc->arm_r8 = uc->regs[8]; - sc->arm_r9 = uc->regs[9]; - sc->arm_r10 = uc->regs[10]; - sc->arm_fp = uc->regs[11]; /* FP */ - sc->arm_ip = uc->regs[12]; /* IP */ - sc->arm_sp = uc->regs[13]; /* SP */ - sc->arm_lr = uc->regs[14]; /* LR */ - sc->arm_pc = uc->regs[15]; /* PC */ - /* clear the ITSTATE bits. */ - sc->arm_cpsr &= 0xf9ff03ffUL; - - /* Set the SP and the PC in order to continue execution at the modified - trampoline which restores the signal mask and the registers. */ - asm __volatile__ ( - "mov sp, %0\n" - "bx %1\n" - : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) - ); - } - unreachable(); -#else - printf ("%s: implement me\n", __FUNCTION__); -#endif - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ - -static inline void -establish_machine_state (struct cursor *c) -{ - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_REG_LAST; ++reg) - { - Debug (16, "copying %s %d\n", unw_regname (reg), reg); - if (unw_is_fpreg (reg)) - { - if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) - as->acc.access_fpreg (as, reg, &fpval, 1, arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - as->acc.access_reg (as, reg, &val, 1, arg); - } - } -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - - Debug (1, "(cursor=%p)\n", c); - - if (!c->dwarf.ip) - { - /* This can happen easily when the frame-chain gets truncated - due to bad or missing unwind-info. */ - Debug (1, "refusing to resume execution at address 0\n"); - return -UNW_EINVAL; - } - - establish_machine_state (c); - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gstash_frame.c deleted file mode 100644 index c5a76b86d0a96a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gstash_frame.c +++ /dev/null @@ -1,90 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY - Copyright (C) 2014 CERN and Aalto University - Contributed by Filip Nyback - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -HIDDEN void -tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) -{ - struct cursor *c = (struct cursor *) dwarf_to_cursor (d); - unw_tdep_frame_t *f = &c->frame_info; - - Debug (4, "ip=0x%x cfa=0x%x type %d cfa [where=%d val=%d] cfaoff=%d" - " ra=0x%x r7 [where=%d val=%d @0x%x] lr [where=%d val=%d @0x%x] " - "sp [where=%d val=%d @0x%x]\n", - d->ip, d->cfa, f->frame_type, - rs->reg.where[DWARF_CFA_REG_COLUMN], - rs->reg.val[DWARF_CFA_REG_COLUMN], - rs->reg.val[DWARF_CFA_OFF_COLUMN], - DWARF_GET_LOC(d->loc[rs->ret_addr_column]), - rs->reg.where[R7], rs->reg.val[R7], DWARF_GET_LOC(d->loc[R7]), - rs->reg.where[LR], rs->reg.val[LR], DWARF_GET_LOC(d->loc[LR]), - rs->reg.where[SP], rs->reg.val[SP], DWARF_GET_LOC(d->loc[SP])); - - /* A standard frame is defined as: - - CFA is register-relative offset off R7 or SP; - - Return address is saved in LR; - - R7 is unsaved or saved at CFA+offset, offset != -1; - - LR is unsaved or saved at CFA+offset, offset != -1; - - SP is unsaved or saved at CFA+offset, offset != -1. */ - if (f->frame_type == UNW_ARM_FRAME_OTHER - && (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG) - && (rs->reg.val[DWARF_CFA_REG_COLUMN] == R7 - || rs->reg.val[DWARF_CFA_REG_COLUMN] == SP) - && labs(rs->reg.val[DWARF_CFA_OFF_COLUMN]) < (1 << 29) - && rs->ret_addr_column == LR - && (rs->reg.where[R7] == DWARF_WHERE_UNDEF - || rs->reg.where[R7] == DWARF_WHERE_SAME - || (rs->reg.where[R7] == DWARF_WHERE_CFAREL - && labs(rs->reg.val[R7]) < (1 << 29) - && rs->reg.val[R7]+1 != 0)) - && (rs->reg.where[LR] == DWARF_WHERE_UNDEF - || rs->reg.where[LR] == DWARF_WHERE_SAME - || (rs->reg.where[LR] == DWARF_WHERE_CFAREL - && labs(rs->reg.val[LR]) < (1 << 29) - && rs->reg.val[LR]+1 != 0)) - && (rs->reg.where[SP] == DWARF_WHERE_UNDEF - || rs->reg.where[SP] == DWARF_WHERE_SAME - || (rs->reg.where[SP] == DWARF_WHERE_CFAREL - && labs(rs->reg.val[SP]) < (1 << 29) - && rs->reg.val[SP]+1 != 0))) - { - /* Save information for a standard frame. */ - f->frame_type = UNW_ARM_FRAME_STANDARD; - f->cfa_reg_sp = (rs->reg.val[DWARF_CFA_REG_COLUMN] == SP); - f->cfa_reg_offset = rs->reg.val[DWARF_CFA_OFF_COLUMN]; - if (rs->reg.where[R7] == DWARF_WHERE_CFAREL) - f->r7_cfa_offset = rs->reg.val[R7]; - if (rs->reg.where[LR] == DWARF_WHERE_CFAREL) - f->lr_cfa_offset = rs->reg.val[LR]; - if (rs->reg.where[SP] == DWARF_WHERE_CFAREL) - f->sp_cfa_offset = rs->reg.val[SP]; - Debug (4, " standard frame\n"); - } - else - Debug (4, " unusual frame\n"); -} - diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c deleted file mode 100644 index 516c9f4d1837d1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c +++ /dev/null @@ -1,192 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright 2011 Linaro Limited - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" -#include "ex_tables.h" - -#include - -#define arm_exidx_step UNW_OBJ(arm_exidx_step) - -static inline int -arm_exidx_step (struct cursor *c) -{ - unw_word_t old_ip, old_cfa; - uint8_t buf[32]; - int ret; - - old_ip = c->dwarf.ip; - old_cfa = c->dwarf.cfa; - - /* mark PC unsaved */ - c->dwarf.loc[UNW_ARM_R15] = DWARF_NULL_LOC; - unw_word_t ip = c->dwarf.ip; - if (c->dwarf.use_prev_instr) - --ip; - - /* check dynamic info first --- it overrides everything else */ - ret = unwi_find_dynamic_proc_info (c->dwarf.as, ip, &c->dwarf.pi, 1, - c->dwarf.as_arg); - if (ret == -UNW_ENOINFO) - { - if ((ret = tdep_find_proc_info (&c->dwarf, ip, 1)) < 0) - return ret; - } - - if (c->dwarf.pi.format != UNW_INFO_FORMAT_ARM_EXIDX) - return -UNW_ENOINFO; - - ret = arm_exidx_extract (&c->dwarf, buf); - if (ret == -UNW_ESTOPUNWIND) - return 0; - else if (ret < 0) - return ret; - - ret = arm_exidx_decode (buf, ret, &c->dwarf); - if (ret < 0) - return ret; - - if (c->dwarf.ip == old_ip && c->dwarf.cfa == old_cfa) - { - Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n", - __FUNCTION__, (long) c->dwarf.ip); - return -UNW_EBADFRAME; - } - - c->dwarf.pi_valid = 0; - - return (c->dwarf.ip == 0) ? 0 : 1; -} - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret = -UNW_EUNSPEC; - - Debug (1, "(cursor=%p)\n", c); - - /* Check if this is a signal frame. */ - if (unw_is_signal_frame (cursor) > 0) - return arm_handle_signal_frame (cursor); - -#ifdef CONFIG_DEBUG_FRAME - /* First, try DWARF-based unwinding. */ - if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)) - { - ret = dwarf_step (&c->dwarf); - Debug(1, "dwarf_step()=%d\n", ret); - - if (likely (ret > 0)) - return 1; - else if (unlikely (ret == -UNW_ESTOPUNWIND)) - return ret; - - if (ret < 0 && ret != -UNW_ENOINFO) - { - Debug (2, "returning %d\n", ret); - return ret; - } - } -#endif /* CONFIG_DEBUG_FRAME */ - - /* Next, try extbl-based unwinding. */ - if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) - { - ret = arm_exidx_step (c); - if (ret > 0) - return 1; - if (ret == -UNW_ESTOPUNWIND || ret == 0) - return ret; - } - - /* Fall back on APCS frame parsing. - Note: This won't work in case the ARM EABI is used. */ -#ifdef __FreeBSD__ - if (0) -#else - if (unlikely (ret < 0)) -#endif - { - if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME)) - { - Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); - ret = UNW_ESUCCESS; - /* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */ - unw_word_t instr, i; - dwarf_loc_t ip_loc, fp_loc; - unw_word_t frame; - /* Mark all registers unsaved, since we don't know where - they are saved (if at all), except for the EBP and - EIP. */ - if (dwarf_get(&c->dwarf, c->dwarf.loc[UNW_ARM_R11], &frame) < 0) - { - return 0; - } - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) { - c->dwarf.loc[i] = DWARF_NULL_LOC; - } - if (frame) - { - if (dwarf_get(&c->dwarf, DWARF_LOC(frame, 0), &instr) < 0) - { - return 0; - } - instr -= 8; - if (dwarf_get(&c->dwarf, DWARF_LOC(instr, 0), &instr) < 0) - { - return 0; - } - if ((instr & 0xFFFFD800) == 0xE92DD800) - { - /* Standard APCS frame. */ - ip_loc = DWARF_LOC(frame - 4, 0); - fp_loc = DWARF_LOC(frame - 12, 0); - } - else - { - /* Codesourcery optimized normal frame. */ - ip_loc = DWARF_LOC(frame, 0); - fp_loc = DWARF_LOC(frame - 4, 0); - } - if (dwarf_get(&c->dwarf, ip_loc, &c->dwarf.ip) < 0) - { - return 0; - } - c->dwarf.loc[UNW_ARM_R12] = ip_loc; - c->dwarf.loc[UNW_ARM_R11] = fp_loc; - c->dwarf.pi_valid = 0; - Debug(15, "ip=%x\n", c->dwarf.ip); - } - else - { - ret = -UNW_ENOINFO; - } - } - } - return ret == -UNW_ENOINFO ? 0 : ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gtrace.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gtrace.c deleted file mode 100644 index 2f277520b36348..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gtrace.c +++ /dev/null @@ -1,557 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY - Copyright (C) 2014 CERN and Aalto University - Contributed by Filip Nyback - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" -#include -#include - -#pragma weak pthread_once -#pragma weak pthread_key_create -#pragma weak pthread_getspecific -#pragma weak pthread_setspecific - -/* Initial hash table size. Table expands by 2 bits (times four). */ -#define HASH_MIN_BITS 14 - -typedef struct -{ - unw_tdep_frame_t *frames; - size_t log_size; - size_t used; - size_t dtor_count; /* Counts how many times our destructor has already - been called. */ -} unw_trace_cache_t; - -static const unw_tdep_frame_t empty_frame = { 0, UNW_ARM_FRAME_OTHER, -1, -1, 0, -1, -1, -1 }; -static define_lock (trace_init_lock); -static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; -static sig_atomic_t trace_cache_once_happen; -static pthread_key_t trace_cache_key; -static struct mempool trace_cache_pool; -static __thread unw_trace_cache_t *tls_cache; -static __thread int tls_cache_destroyed; - -/* Free memory for a thread's trace cache. */ -static void -trace_cache_free (void *arg) -{ - unw_trace_cache_t *cache = arg; - if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS) - { - /* Not yet our turn to get destroyed. Re-install ourselves into the key. */ - pthread_setspecific(trace_cache_key, cache); - Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, - PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); - return; - } - tls_cache_destroyed = 1; - tls_cache = NULL; - munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); - mempool_free (&trace_cache_pool, cache); - Debug(5, "freed cache %p\n", cache); -} - -/* Initialise frame tracing for threaded use. */ -static void -trace_cache_init_once (void) -{ - pthread_key_create (&trace_cache_key, &trace_cache_free); - mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); - trace_cache_once_happen = 1; -} - -static unw_tdep_frame_t * -trace_cache_buckets (size_t n) -{ - unw_tdep_frame_t *frames; - size_t i; - - GET_MEMORY(frames, n * sizeof (unw_tdep_frame_t)); - if (likely(frames != NULL)) - for (i = 0; i < n; ++i) - frames[i] = empty_frame; - - return frames; -} - -/* Allocate and initialise hash table for frame cache lookups. - Returns the cache initialised with (1u << HASH_LOW_BITS) hash - buckets, or NULL if there was a memory allocation problem. */ -static unw_trace_cache_t * -trace_cache_create (void) -{ - unw_trace_cache_t *cache; - - if (tls_cache_destroyed) - { - /* The current thread is in the process of exiting. Don't recreate - cache, as we wouldn't have another chance to free it. */ - Debug(5, "refusing to reallocate cache: " - "thread-locals are being deallocated\n"); - return NULL; - } - - if (! (cache = mempool_alloc(&trace_cache_pool))) - { - Debug(5, "failed to allocate cache\n"); - return NULL; - } - - if (! (cache->frames = trace_cache_buckets(1u << HASH_MIN_BITS))) - { - Debug(5, "failed to allocate buckets\n"); - mempool_free(&trace_cache_pool, cache); - return NULL; - } - - cache->log_size = HASH_MIN_BITS; - cache->used = 0; - cache->dtor_count = 0; - tls_cache_destroyed = 0; /* Paranoia: should already be 0. */ - Debug(5, "allocated cache %p\n", cache); - return cache; -} - -/* Expand the hash table in the frame cache if possible. This always - quadruples the hash size, and clears all previous frame entries. */ -static int -trace_cache_expand (unw_trace_cache_t *cache) -{ - size_t old_size = (1u << cache->log_size); - size_t new_log_size = cache->log_size + 2; - unw_tdep_frame_t *new_frames = trace_cache_buckets (1u << new_log_size); - - if (unlikely(! new_frames)) - { - Debug(5, "failed to expand cache to 2^%u buckets\n", new_log_size); - return -UNW_ENOMEM; - } - - Debug(5, "expanded cache from 2^%u to 2^%u buckets\n", cache->log_size, - new_log_size); - munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); - cache->frames = new_frames; - cache->log_size = new_log_size; - cache->used = 0; - return 0; -} - -static unw_trace_cache_t * -trace_cache_get_unthreaded (void) -{ - unw_trace_cache_t *cache; - intrmask_t saved_mask; - static unw_trace_cache_t *global_cache = NULL; - lock_acquire (&trace_init_lock, saved_mask); - if (! global_cache) - { - mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); - global_cache = trace_cache_create (); - } - cache = global_cache; - lock_release (&trace_init_lock, saved_mask); - Debug(5, "using cache %p\n", cache); - return cache; -} - -/* Get the frame cache for the current thread. Create it if there is none. */ -static unw_trace_cache_t * -trace_cache_get (void) -{ - unw_trace_cache_t *cache; - if (likely (pthread_once != NULL)) - { - pthread_once(&trace_cache_once, &trace_cache_init_once); - if (!trace_cache_once_happen) - { - return trace_cache_get_unthreaded(); - } - if (! (cache = tls_cache)) - { - cache = trace_cache_create(); - pthread_setspecific(trace_cache_key, cache); - tls_cache = cache; - } - Debug(5, "using cache %p\n", cache); - return cache; - } - else - { - return trace_cache_get_unthreaded(); - } -} - -/* Initialise frame properties for address cache slot F at address - PC using current CFA, R7 and SP values. Modifies CURSOR to - that location, performs one unw_step(), and fills F with what - was discovered about the location. Returns F. - - FIXME: This probably should tell DWARF handling to never evaluate - or use registers other than R7, SP and PC in case there is - highly unusual unwind info which uses these creatively. */ -static unw_tdep_frame_t * -trace_init_addr (unw_tdep_frame_t *f, - unw_cursor_t *cursor, - unw_word_t cfa, - unw_word_t pc, - unw_word_t r7, - unw_word_t sp) -{ - struct cursor *c = (struct cursor *) cursor; - struct dwarf_cursor *d = &c->dwarf; - int ret = -UNW_EINVAL; - - /* Initialise frame properties: unknown, not last. */ - f->virtual_address = pc; - f->frame_type = UNW_ARM_FRAME_OTHER; - f->last_frame = 0; - f->cfa_reg_sp = -1; - f->cfa_reg_offset = 0; - f->r7_cfa_offset = -1; - f->lr_cfa_offset = -1; - f->sp_cfa_offset = -1; - - /* Reinitialise cursor to this instruction - but undo next/prev RIP - adjustment because unw_step will redo it - and force PC, R7 and - SP into register locations (=~ ucontext we keep), then set - their desired values. Then perform the step. */ - d->ip = pc + d->use_prev_instr; - d->cfa = cfa; - d->loc[UNW_ARM_R7] = DWARF_REG_LOC (d, UNW_ARM_R7); - d->loc[UNW_ARM_R13] = DWARF_REG_LOC (d, UNW_ARM_R13); - d->loc[UNW_ARM_R15] = DWARF_REG_LOC (d, UNW_ARM_R15); - c->frame_info = *f; - - if (likely(dwarf_put (d, d->loc[UNW_ARM_R7], r7) >= 0) - && likely(dwarf_put (d, d->loc[UNW_ARM_R13], sp) >= 0) - && likely(dwarf_put (d, d->loc[UNW_ARM_R15], pc) >= 0) - && likely((ret = unw_step (cursor)) >= 0)) - *f = c->frame_info; - - /* If unw_step() stopped voluntarily, remember that, even if it - otherwise could not determine anything useful. This avoids - failing trace if we hit frames without unwind info, which is - common for the outermost frame (CRT stuff) on many systems. - This avoids failing trace in very common circumstances; failing - to unw_step() loop wouldn't produce any better result. */ - if (ret == 0) - f->last_frame = -1; - - Debug (3, "frame va %x type %d last %d cfa %s+%d r7 @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", - f->virtual_address, f->frame_type, f->last_frame, - f->cfa_reg_sp ? "sp" : "r7", f->cfa_reg_offset, - f->r7_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); - - return f; -} - -/* Look up and if necessary fill in frame attributes for address PC - in CACHE using current CFA, R7 and SP values. Uses CURSOR to - perform any unwind steps necessary to fill the cache. Returns the - frame cache slot which describes RIP. */ -static unw_tdep_frame_t * -trace_lookup (unw_cursor_t *cursor, - unw_trace_cache_t *cache, - unw_word_t cfa, - unw_word_t pc, - unw_word_t r7, - unw_word_t sp) -{ - /* First look up for previously cached information using cache as - linear probing hash table with probe step of 1. Majority of - lookups should be completed within few steps, but it is very - important the hash table does not fill up, or performance falls - off the cliff. */ - uint32_t i, addr; - uint32_t cache_size = 1u << cache->log_size; - uint32_t slot = ((pc * 0x9e3779b9) >> 11) & (cache_size-1); - unw_tdep_frame_t *frame; - - for (i = 0; i < 16; ++i) - { - frame = &cache->frames[slot]; - addr = frame->virtual_address; - - /* Return if we found the address. */ - if (likely(addr == pc)) - { - Debug (4, "found address after %d steps\n", i); - return frame; - } - - /* If slot is empty, reuse it. */ - if (likely(! addr)) - break; - - /* Linear probe to next slot candidate, step = 1. */ - if (++slot >= cache_size) - slot -= cache_size; - } - - /* If we collided after 16 steps, or if the hash is more than half - full, force the hash to expand. Fill the selected slot, whether - it's free or collides. Note that hash expansion drops previous - contents; further lookups will refill the hash. */ - Debug (4, "updating slot %u after %d steps, replacing 0x%x\n", slot, i, addr); - if (unlikely(addr || cache->used >= cache_size / 2)) - { - if (unlikely(trace_cache_expand (cache) < 0)) - return NULL; - - cache_size = 1u << cache->log_size; - slot = ((pc * 0x9e3779b9) >> 11) & (cache_size-1); - frame = &cache->frames[slot]; - addr = frame->virtual_address; - } - - if (! addr) - ++cache->used; - - return trace_init_addr (frame, cursor, cfa, pc, r7, sp); -} - -/* Fast stack backtrace for ARM. - - This is used by backtrace() implementation to accelerate frequent - queries for current stack, without any desire to unwind. It fills - BUFFER with the call tree from CURSOR upwards for at most SIZE - stack levels. The first frame, backtrace itself, is omitted. When - called, SIZE should give the maximum number of entries that can be - stored into BUFFER. Uses an internal thread-specific cache to - accelerate queries. - - The caller should fall back to a unw_step() loop if this function - fails by returning -UNW_ESTOPUNWIND, meaning the routine hit a - stack frame that is too complex to be traced in the fast path. - - This function is tuned for clients which only need to walk the - stack to get the call tree as fast as possible but without any - other details, for example profilers sampling the stack thousands - to millions of times per second. The routine handles the most - common ARM ABI stack layouts: CFA is R7 or SP plus/minus - constant offset, return address is in LR, and R7, LR and SP are - either unchanged or saved on stack at constant offset from the CFA; - the signal return frame; and frames without unwind info provided - they are at the outermost (final) frame or can conservatively be - assumed to be frame-pointer based. - - Any other stack layout will cause the routine to give up. There - are only a handful of relatively rarely used functions which do - not have a stack in the standard form: vfork, longjmp, setcontext - and _dl_runtime_profile on common linux systems for example. - - On success BUFFER and *SIZE reflect the trace progress up to *SIZE - stack levels or the outermost frame, which ever is less. It may - stop short of outermost frame if unw_step() loop would also do so, - e.g. if there is no more unwind information; this is not reported - as an error. - - The function returns a negative value for errors, -UNW_ESTOPUNWIND - if tracing stopped because of an unusual frame unwind info. The - BUFFER and *SIZE reflect tracing progress up to the error frame. - - Callers of this function would normally look like this: - - unw_cursor_t cur; - unw_context_t ctx; - void addrs[128]; - int depth = 128; - int ret; - - unw_getcontext(&ctx); - unw_init_local(&cur, &ctx); - if ((ret = unw_tdep_trace(&cur, addrs, &depth)) < 0) - { - depth = 0; - unw_getcontext(&ctx); - unw_init_local(&cur, &ctx); - while ((ret = unw_step(&cur)) > 0 && depth < 128) - { - unw_word_t ip; - unw_get_reg(&cur, UNW_REG_IP, &ip); - addresses[depth++] = (void *) ip; - } - } -*/ -HIDDEN int -tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) -{ - struct cursor *c = (struct cursor *) cursor; - struct dwarf_cursor *d = &c->dwarf; - unw_trace_cache_t *cache; - unw_word_t sp, pc, cfa, r7, lr; - int maxdepth = 0; - int depth = 0; - int ret; - - /* Check input parametres. */ - if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) - return -UNW_EINVAL; - - Debug (1, "begin ip 0x%x cfa 0x%x\n", d->ip, d->cfa); - - /* Tell core dwarf routines to call back to us. */ - d->stash_frames = 1; - - /* Determine initial register values. These are direct access safe - because we know they come from the initial machine context. */ - pc = d->ip; - sp = cfa = d->cfa; - ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_ARM_R7]), r7); - assert(ret == 0); - lr = 0; - - /* Get frame cache. */ - if (unlikely(! (cache = trace_cache_get()))) - { - Debug (1, "returning %d, cannot get trace cache\n", -UNW_ENOMEM); - *size = 0; - d->stash_frames = 0; - return -UNW_ENOMEM; - } - - /* Trace the stack upwards, starting from current PC. Adjust - the PC address for previous/next instruction as the main - unwinding logic would also do. We undo this before calling - back into unw_step(). */ - while (depth < maxdepth) - { - pc -= d->use_prev_instr; - Debug (2, "depth %d cfa 0x%x pc 0x%x sp 0x%x r7 0x%x\n", - depth, cfa, pc, sp, r7); - - /* See if we have this address cached. If not, evaluate enough of - the dwarf unwind information to fill the cache line data, or to - decide this frame cannot be handled in fast trace mode. We - cache negative results too to prevent unnecessary dwarf parsing - for common failures. */ - unw_tdep_frame_t *f = trace_lookup (cursor, cache, cfa, pc, r7, sp); - - /* If we don't have information for this frame, give up. */ - if (unlikely(! f)) - { - ret = -UNW_ENOINFO; - break; - } - - Debug (3, "frame va %x type %d last %d cfa %s+%d r7 @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", - f->virtual_address, f->frame_type, f->last_frame, - f->cfa_reg_sp ? "sp" : "r7", f->cfa_reg_offset, - f->r7_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); - - assert (f->virtual_address == pc); - - /* Stop if this was the last frame. In particular don't evaluate - new register values as it may not be safe - we don't normally - run with full validation on, and do not want to - and there's - enough bad unwind info floating around that we need to trust - what unw_step() previously said, in potentially bogus frames. */ - if (f->last_frame) - break; - - /* Evaluate CFA and registers for the next frame. */ - switch (f->frame_type) - { - case UNW_ARM_FRAME_GUESSED: - /* Fall thru to standard processing after forcing validation. */ - c->validate = 1; - - case UNW_ARM_FRAME_STANDARD: - /* Advance standard traceable frame. */ - cfa = (f->cfa_reg_sp ? sp : r7) + f->cfa_reg_offset; - if (likely(f->lr_cfa_offset != -1)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc); - else if (lr != 0) - { - /* Use the saved link register as the new pc. */ - pc = lr; - lr = 0; - } - if (likely(ret >= 0) && likely(f->r7_cfa_offset != -1)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->r7_cfa_offset, r7); - - /* Don't bother reading SP from DWARF, CFA becomes new SP. */ - sp = cfa; - - /* Next frame needs to back up for unwind info lookup. */ - d->use_prev_instr = 1; - break; - - case UNW_ARM_FRAME_SIGRETURN: - cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ -#if defined(__linux__) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_PC_OFF, pc); - if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_R7_OFF, r7); - if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_SP_OFF, sp); - /* Save the link register here in case we end up in a function that - doesn't save the link register in the prologue, e.g. kill. */ - if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_LR_OFF, lr); -#elif defined(__FreeBSD__) - printf("XXX\n"); -#endif - - /* Resume stack at signal restoration point. The stack is not - necessarily continuous here, especially with sigaltstack(). */ - cfa = sp; - - /* Next frame should not back up. */ - d->use_prev_instr = 0; - break; - - case UNW_ARM_FRAME_SYSCALL: - printf("XXX1\n"); - break; - - default: - /* We cannot trace through this frame, give up and tell the - caller we had to stop. Data collected so far may still be - useful to the caller, so let it know how far we got. */ - ret = -UNW_ESTOPUNWIND; - break; - } - - Debug (4, "new cfa 0x%x pc 0x%x sp 0x%x r7 0x%x\n", - cfa, pc, sp, r7); - - /* If we failed or ended up somewhere bogus, stop. */ - if (unlikely(ret < 0 || pc < 0x4000)) - break; - - /* Record this address in stack trace. We skipped the first address. */ - buffer[depth++] = (void *) (pc - d->use_prev_instr); - } - -#if UNW_DEBUG - Debug (1, "returning %d, depth %d\n", ret, depth); -#endif - *size = depth; - return ret; -} - diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lex_tables.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lex_tables.c deleted file mode 100644 index 4a4f925c9c3256..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lex_tables.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gex_tables.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lglobal.c deleted file mode 100644 index 6d7b489e14bd9f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lglobal.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Linit.c b/src/coreclr/src/pal/src/libunwind/src/arm/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/arm/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/arm/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9fa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Los-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/arm/Los-freebsd.c deleted file mode 100644 index a75a205df19c01..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Los-freebsd.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gos-freebsd.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Los-linux.c b/src/coreclr/src/pal/src/libunwind/src/arm/Los-linux.c deleted file mode 100644 index 3cc18aabcc399c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Los-linux.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gos-linux.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Los-other.c b/src/coreclr/src/pal/src/libunwind/src/arm/Los-other.c deleted file mode 100644 index a75a205df19c01..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Los-other.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gos-freebsd.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lstash_frame.c deleted file mode 100644 index 77587803d083d7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lstash_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstash_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ltrace.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ltrace.c deleted file mode 100644 index 24b7b3cfa62df4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Ltrace.c +++ /dev/null @@ -1,6 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gtrace.c" -#endif - diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/gen-offsets.c b/src/coreclr/src/pal/src/libunwind/src/arm/gen-offsets.c deleted file mode 100644 index 7d6bf2f1c57043..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/gen-offsets.c +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include -#include - -#define UC(N,X) \ - printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) - -#define SC(N,X) \ - printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) - -int -main (void) -{ - printf ( -"/* Linux-specific definitions: */\n\n" - -"/* Define various structure offsets to simplify cross-compilation. */\n\n" - -"/* Offsets for ARM Linux \"ucontext_t\": */\n\n"); - - UC ("FLAGS", uc_flags); - UC ("LINK", uc_link); - UC ("STACK", uc_stack); - UC ("MCONTEXT", uc_mcontext); - UC ("SIGMASK", uc_sigmask); - UC ("REGSPACE", uc_regspace); - - printf ("\n/* Offsets for ARM Linux \"struct sigcontext\": */\n\n"); - - SC ("TRAPNO", trap_no); - SC ("ERRORCODE", error_code); - SC ("OLDMASK", oldmask); - SC ("R0", arm_r0); - SC ("R1", arm_r1); - SC ("R2", arm_r2); - SC ("R3", arm_r3); - SC ("R4", arm_r4); - SC ("R5", arm_r5); - SC ("R6", arm_r6); - SC ("R7", arm_r7); - SC ("R8", arm_r8); - SC ("R9", arm_r9); - SC ("R10", arm_r10); - SC ("FP", arm_fp); - SC ("IP", arm_ip); - SC ("SP", arm_sp); - SC ("LR", arm_lr); - SC ("PC", arm_pc); - SC ("CPSR", arm_cpsr); - SC ("FAULTADDR", fault_address); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/arm/getcontext.S deleted file mode 100644 index 7e18784477d8f3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/getcontext.S +++ /dev/null @@ -1,63 +0,0 @@ -/* 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. */ - -#include "offsets.h" - - .text - .arm - - .global _Uarm_getcontext - .type _Uarm_getcontext, %function - @ This is a stub version of getcontext() for ARM which only stores core - @ registers. It must be called in a special way, not as a regular - @ function -- see also the libunwind-arm.h:unw_tdep_getcontext macro. -_Uarm_getcontext: - stmfd sp!, {r0, r1} - @ store r0 -#if defined(__linux__) - str r0, [r0, #LINUX_UC_MCONTEXT_OFF + LINUX_SC_R0_OFF] - add r0, r0, #LINUX_UC_MCONTEXT_OFF + LINUX_SC_R0_OFF -#elif defined(__FreeBSD__) - str r0, [r0, #FREEBSD_UC_MCONTEXT_OFF + FREEBSD_MC_R0_OFF] - add r0, r0, #FREEBSD_UC_MCONTEXT_OFF + FREEBSD_MC_R0_OFF -#else -#error Fix me -#endif - @ store r1 to r12 - stmib r0, {r1-r12} - @ reconstruct r13 at call site, then store - add r1, sp, #12 - str r1, [r0, #13 * 4] - @ retrieve r14 from call site, then store - ldr r1, [sp, #8] - str r1, [r0, #14 * 4] - @ point lr to instruction after call site's stack adjustment - add r1, lr, #4 - str r1, [r0, #15 * 4] - ldmfd sp!, {r0, r1} - bx lr -#if defined(__linux__) || defined(__FreeBSD__) - /* We do not need executable stack. */ - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/init.h b/src/coreclr/src/pal/src/libunwind/src/arm/init.h deleted file mode 100644 index 7d765ecf097f6f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/init.h +++ /dev/null @@ -1,77 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -static inline int -common_init (struct cursor *c, unsigned use_prev_instr) -{ - int ret, i; - - c->dwarf.loc[UNW_ARM_R0] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R0); - c->dwarf.loc[UNW_ARM_R1] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R1); - c->dwarf.loc[UNW_ARM_R2] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R2); - c->dwarf.loc[UNW_ARM_R3] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R3); - c->dwarf.loc[UNW_ARM_R4] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R4); - c->dwarf.loc[UNW_ARM_R5] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R5); - c->dwarf.loc[UNW_ARM_R6] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R6); - c->dwarf.loc[UNW_ARM_R7] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R7); - c->dwarf.loc[UNW_ARM_R8] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R8); - c->dwarf.loc[UNW_ARM_R9] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R9); - c->dwarf.loc[UNW_ARM_R10] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R10); - c->dwarf.loc[UNW_ARM_R11] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R11); - c->dwarf.loc[UNW_ARM_R12] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R12); - c->dwarf.loc[UNW_ARM_R13] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13); - c->dwarf.loc[UNW_ARM_R14] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R14); - c->dwarf.loc[UNW_ARM_R15] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R15); - for (i = UNW_ARM_R15 + 1; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); - if (ret < 0) - return ret; - - /* FIXME: correct for ARM? */ - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13), - &c->dwarf.cfa); - if (ret < 0) - return ret; - - c->sigcontext_format = ARM_SCF_NONE; - c->sigcontext_addr = 0; - c->sigcontext_sp = 0; - c->sigcontext_pc = 0; - - /* FIXME: Initialisation for other registers. */ - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/arm/is_fpreg.c deleted file mode 100644 index e55bcff03edaac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/is_fpreg.c +++ /dev/null @@ -1,39 +0,0 @@ -/* 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. */ - -#include "libunwind_i.h" - -/* FIXME: I'm not sure if libunwind's GP/FP register distinction is very useful - on ARM. Count all the FP or coprocessor registers we know about for now. */ - -int -unw_is_fpreg (int regnum) -{ - return ((regnum >= UNW_ARM_S0 && regnum <= UNW_ARM_S31) - || (regnum >= UNW_ARM_F0 && regnum <= UNW_ARM_F7) - || (regnum >= UNW_ARM_wCGR0 && regnum <= UNW_ARM_wCGR7) - || (regnum >= UNW_ARM_wR0 && regnum <= UNW_ARM_wR15) - || (regnum >= UNW_ARM_wC0 && regnum <= UNW_ARM_wC7) - || (regnum >= UNW_ARM_D0 && regnum <= UNW_ARM_D31)); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/offsets.h b/src/coreclr/src/pal/src/libunwind/src/arm/offsets.h deleted file mode 100644 index 621701106c4e59..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/offsets.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Linux-specific definitions: */ - -/* Define various structure offsets to simplify cross-compilation. */ - -/* Offsets for ARM Linux "ucontext_t": */ - -#define LINUX_UC_FLAGS_OFF 0x00 -#define LINUX_UC_LINK_OFF 0x04 -#define LINUX_UC_STACK_OFF 0x08 -#define LINUX_UC_MCONTEXT_OFF 0x14 -#define LINUX_UC_SIGMASK_OFF 0x68 -#define LINUX_UC_REGSPACE_OFF 0xE8 - -/* Offsets for ARM Linux "struct sigcontext": */ - -#define LINUX_SC_TRAPNO_OFF 0x00 -#define LINUX_SC_ERRORCODE_OFF 0x04 -#define LINUX_SC_OLDMASK_OFF 0x08 -#define LINUX_SC_R0_OFF 0x0C -#define LINUX_SC_R1_OFF 0x10 -#define LINUX_SC_R2_OFF 0x14 -#define LINUX_SC_R3_OFF 0x18 -#define LINUX_SC_R4_OFF 0x1C -#define LINUX_SC_R5_OFF 0x20 -#define LINUX_SC_R6_OFF 0x24 -#define LINUX_SC_R7_OFF 0x28 -#define LINUX_SC_R8_OFF 0x2C -#define LINUX_SC_R9_OFF 0x30 -#define LINUX_SC_R10_OFF 0x34 -#define LINUX_SC_FP_OFF 0x38 -#define LINUX_SC_IP_OFF 0x3C -#define LINUX_SC_SP_OFF 0x40 -#define LINUX_SC_LR_OFF 0x44 -#define LINUX_SC_PC_OFF 0x48 -#define LINUX_SC_CPSR_OFF 0x4C -#define LINUX_SC_FAULTADDR_OFF 0x50 - -/* FreeBSD-specific definitions: */ - -#define FREEBSD_SC_UCONTEXT_OFF 0x40 -#define FREEBSD_UC_MCONTEXT_OFF 0x10 -#define FREEBSD_MC_R0_OFF 0 diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/regname.c b/src/coreclr/src/pal/src/libunwind/src/arm/regname.c deleted file mode 100644 index 7cac630c177113..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/regname.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "unwind_i.h" - -static const char *regname[] = - { - /* 0. */ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - /* 8. */ - "r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc", - /* 16. Obsolete FPA names. */ - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - /* 24. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 32. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 40. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 48. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 56. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 64. */ - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - /* 72. */ - "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", - /* 80. */ - "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", - /* 88. */ - "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", - /* 96. */ - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - /* 104. */ - "wCGR0", "wCGR1", "wCGR2", "wCGR3", "wCGR4", "wCGR5", "wCGR6", "wCGR7", - /* 112. */ - "wR0", "wR1", "wR2", "wR3", "wR4", "wR5", "wR6", "wR7", - /* 128. */ - "spsr", "spsr_fiq", "spsr_irq", "spsr_abt", "spsr_und", "spsr_svc", 0, 0, - /* 136. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 144. */ - "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "r13_usr", "r14_usr", - /* 151. */ - "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "r14_fiq", - /* 158. */ - "r13_irq", "r14_irq", - /* 160. */ - "r13_abt", "r14_abt", - /* 162. */ - "r13_und", "r14_und", - /* 164. */ - "r13_svc", "r14_svc", 0, 0, - /* 168. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 176. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 184. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 192. */ - "wC0", "wC1", "wC2", "wC3", "wC4", "wC5", "wC6", "wC7", - /* 200. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 208. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 216. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 224. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 232. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 240. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 248. */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 256. */ - "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", - /* 264. */ - "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", - /* 272. */ - "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", - /* 280. */ - "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/arm/siglongjmp.S deleted file mode 100644 index 4df07366831914..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/siglongjmp.S +++ /dev/null @@ -1,12 +0,0 @@ - /* Dummy implementation for now. */ - - .globl _UI_siglongjmp_cont - .globl _UI_longjmp_cont - -_UI_siglongjmp_cont: -_UI_longjmp_cont: - bx lr -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/arm/unwind_i.h deleted file mode 100644 index fe0bca005b1637..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/arm/unwind_i.h +++ /dev/null @@ -1,62 +0,0 @@ -/* 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 unwind_i_h -#define unwind_i_h - -#include - -#include - -#include "libunwind_i.h" - -/* DWARF column numbers for ARM: */ -#define R7 7 -#define SP 13 -#define LR 14 -#define PC 15 - -#define arm_lock UNW_OBJ(lock) -#define arm_local_resume UNW_OBJ(local_resume) -#define arm_local_addr_space_init UNW_OBJ(local_addr_space_init) - -extern void arm_local_addr_space_init (void); -extern int arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, - void *arg); -#define arm_handle_signal_frame UNW_OBJ(handle_signal_frame) -extern int arm_handle_signal_frame(unw_cursor_t *cursor); - -/* By-pass calls to access_mem() when known to be safe. */ -#ifdef UNW_LOCAL_ONLY -# undef ACCESS_MEM_FAST -# define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ - do { \ - if (unlikely(validate)) \ - (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); \ - else \ - (ret) = 0, (to) = *(unw_word_t *)(addr); \ - } while (0) -#endif - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/README b/src/coreclr/src/pal/src/libunwind/src/coredump/README deleted file mode 100644 index 204493c93e91a2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/README +++ /dev/null @@ -1,8 +0,0 @@ -This code is based on "unwinding via ptrace" code from ptrace/ -directory. - -Files with names starting with _UCD_ are substantially changed -from their ptrace/_UPT_... progenitors. - -Files which still have _UPT_... names are either verbiatim copies -from ptrace/, or unimplemented stubs. diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_mem.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_mem.c deleted file mode 100644 index 1fdbd128ffc1e4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_mem.c +++ /dev/null @@ -1,98 +0,0 @@ -/* 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. */ - -#include "_UCD_lib.h" -#include "_UCD_internal.h" - -int -_UCD_access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *val, - int write, void *arg) -{ - if (write) - { - Debug(0, "write is not supported\n"); - return -UNW_EINVAL; - } - - struct UCD_info *ui = arg; - - unw_word_t addr_last = addr + sizeof(*val)-1; - coredump_phdr_t *phdr; - unsigned i; - for (i = 0; i < ui->phdrs_count; i++) - { - phdr = &ui->phdrs[i]; - if (phdr->p_vaddr <= addr && addr_last < phdr->p_vaddr + phdr->p_memsz) - { - goto found; - } - } - Debug(1, "addr 0x%llx is unmapped\n", (unsigned long long)addr); - return -UNW_EINVAL; - - found: ; - - const char *filename UNUSED; - off_t fileofs; - int fd; - if (addr_last >= phdr->p_vaddr + phdr->p_filesz) - { - /* This part of mapped address space is not present in coredump file */ - /* Do we have it in the backup file? */ - if (phdr->backing_fd < 0) - { - Debug(1, "access to not-present data in phdr[%d]: addr:0x%llx\n", - i, (unsigned long long)addr - ); - return -UNW_EINVAL; - } - filename = phdr->backing_filename; - fileofs = addr - phdr->p_vaddr; - fd = phdr->backing_fd; - goto read; - } - - filename = ui->coredump_filename; - fileofs = phdr->p_offset + (addr - phdr->p_vaddr); - fd = ui->coredump_fd; - read: - if (lseek(fd, fileofs, SEEK_SET) != fileofs) - goto read_error; - if (read(fd, val, sizeof(*val)) != sizeof(*val)) - goto read_error; - - Debug(1, "0x%llx <- [addr:0x%llx fileofs:0x%llx]\n", - (unsigned long long)(*val), - (unsigned long long)addr, - (unsigned long long)fileofs - ); - return 0; - - read_error: - Debug(1, "access out of file: addr:0x%llx fileofs:%llx file:'%s'\n", - (unsigned long long)addr, - (unsigned long long)fileofs, - filename - ); - return -UNW_EINVAL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c deleted file mode 100644 index 0e3a83bdc6ca39..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c +++ /dev/null @@ -1,137 +0,0 @@ -/* 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. */ - -#include "_UCD_lib.h" - -#include "_UCD_internal.h" - -int -_UCD_access_reg (unw_addr_space_t as, - unw_regnum_t regnum, unw_word_t *valp, - int write, void *arg) -{ - if (write) - { - Debug(0, "write is not supported\n"); - return -UNW_EINVAL; - } - - struct UCD_info *ui = arg; - -#if defined(UNW_TARGET_X86) - switch (regnum) { - case UNW_X86_EAX: - *valp = ui->prstatus->pr_reg.r_eax; - break; - case UNW_X86_EDX: - *valp = ui->prstatus->pr_reg.r_edx; - break; - case UNW_X86_ECX: - *valp = ui->prstatus->pr_reg.r_ecx; - break; - case UNW_X86_EBX: - *valp = ui->prstatus->pr_reg.r_ebx; - break; - case UNW_X86_ESI: - *valp = ui->prstatus->pr_reg.r_esi; - break; - case UNW_X86_EDI: - *valp = ui->prstatus->pr_reg.r_edi; - break; - case UNW_X86_EBP: - *valp = ui->prstatus->pr_reg.r_ebp; - break; - case UNW_X86_ESP: - *valp = ui->prstatus->pr_reg.r_esp; - break; - case UNW_X86_EIP: - *valp = ui->prstatus->pr_reg.r_eip; - break; - case UNW_X86_EFLAGS: - *valp = ui->prstatus->pr_reg.r_eflags; - break; - case UNW_X86_TRAPNO: - *valp = ui->prstatus->pr_reg.r_trapno; - break; - default: - Debug(0, "bad regnum:%d\n", regnum); - return -UNW_EINVAL; - } -#elif defined(UNW_TARGET_X86_64) - switch (regnum) { - case UNW_X86_64_RAX: - *valp = ui->prstatus->pr_reg.r_rax; - break; - case UNW_X86_64_RDX: - *valp = ui->prstatus->pr_reg.r_rdx; - break; - case UNW_X86_64_RCX: - *valp = ui->prstatus->pr_reg.r_rcx; - break; - case UNW_X86_64_RBX: - *valp = ui->prstatus->pr_reg.r_rbx; - break; - case UNW_X86_64_RSI: - *valp = ui->prstatus->pr_reg.r_rsi; - break; - case UNW_X86_64_RDI: - *valp = ui->prstatus->pr_reg.r_rdi; - break; - case UNW_X86_64_RBP: - *valp = ui->prstatus->pr_reg.r_rbp; - break; - case UNW_X86_64_RSP: - *valp = ui->prstatus->pr_reg.r_rsp; - break; - case UNW_X86_64_RIP: - *valp = ui->prstatus->pr_reg.r_rip; - break; - default: - Debug(0, "bad regnum:%d\n", regnum); - return -UNW_EINVAL; - } -#elif defined(UNW_TARGET_ARM) - if (regnum >= UNW_ARM_R0 && regnum <= UNW_ARM_R12) { - *valp = ui->prstatus->pr_reg.r[regnum]; - } else { - switch (regnum) { - case UNW_ARM_R13: - *valp = ui->prstatus->pr_reg.r_sp; - break; - case UNW_ARM_R14: - *valp = ui->prstatus->pr_reg.r_lr; - break; - case UNW_ARM_R15: - *valp = ui->prstatus->pr_reg.r_pc; - break; - default: - Debug(0, "bad regnum:%d\n", regnum); - return -UNW_EINVAL; - } - } -#else -#error Port me -#endif - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c deleted file mode 100644 index 208d8d27b6581f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c +++ /dev/null @@ -1,146 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UCD_lib.h" - -#include "_UCD_internal.h" - -int -_UCD_access_reg (unw_addr_space_t as, - unw_regnum_t regnum, unw_word_t *valp, - int write, void *arg) -{ - struct UCD_info *ui = arg; - - if (write) - { - Debug(0, "write is not supported\n"); - return -UNW_EINVAL; - } - - if (regnum < 0) - goto badreg; - -#if defined(UNW_TARGET_AARCH64) - if (regnum >= UNW_AARCH64_FPCR) - goto badreg; -#elif defined(UNW_TARGET_ARM) - if (regnum >= 16) - goto badreg; -#elif defined(UNW_TARGET_SH) - if (regnum > UNW_SH_PR) - goto badreg; -#elif defined(UNW_TARGET_TILEGX) - if (regnum > UNW_TILEGX_CFA) - goto badreg; -#else -#if defined(UNW_TARGET_MIPS) - static const uint8_t remap_regs[] = - { - [UNW_MIPS_R0] = EF_REG0, - [UNW_MIPS_R1] = EF_REG1, - [UNW_MIPS_R2] = EF_REG2, - [UNW_MIPS_R3] = EF_REG3, - [UNW_MIPS_R4] = EF_REG4, - [UNW_MIPS_R5] = EF_REG5, - [UNW_MIPS_R6] = EF_REG6, - [UNW_MIPS_R7] = EF_REG7, - [UNW_MIPS_R8] = EF_REG8, - [UNW_MIPS_R9] = EF_REG9, - [UNW_MIPS_R10] = EF_REG10, - [UNW_MIPS_R11] = EF_REG11, - [UNW_MIPS_R12] = EF_REG12, - [UNW_MIPS_R13] = EF_REG13, - [UNW_MIPS_R14] = EF_REG14, - [UNW_MIPS_R15] = EF_REG15, - [UNW_MIPS_R16] = EF_REG16, - [UNW_MIPS_R17] = EF_REG17, - [UNW_MIPS_R18] = EF_REG18, - [UNW_MIPS_R19] = EF_REG19, - [UNW_MIPS_R20] = EF_REG20, - [UNW_MIPS_R21] = EF_REG21, - [UNW_MIPS_R22] = EF_REG22, - [UNW_MIPS_R23] = EF_REG23, - [UNW_MIPS_R24] = EF_REG24, - [UNW_MIPS_R25] = EF_REG25, - [UNW_MIPS_R28] = EF_REG28, - [UNW_MIPS_R29] = EF_REG29, - [UNW_MIPS_R30] = EF_REG30, - [UNW_MIPS_R31] = EF_REG31, - [UNW_MIPS_PC] = EF_CP0_EPC, - }; -#elif defined(UNW_TARGET_X86) - static const uint8_t remap_regs[] = - { - /* names from libunwind-x86.h */ - [UNW_X86_EAX] = offsetof(struct user_regs_struct, eax) / sizeof(long), - [UNW_X86_EDX] = offsetof(struct user_regs_struct, edx) / sizeof(long), - [UNW_X86_ECX] = offsetof(struct user_regs_struct, ecx) / sizeof(long), - [UNW_X86_EBX] = offsetof(struct user_regs_struct, ebx) / sizeof(long), - [UNW_X86_ESI] = offsetof(struct user_regs_struct, esi) / sizeof(long), - [UNW_X86_EDI] = offsetof(struct user_regs_struct, edi) / sizeof(long), - [UNW_X86_EBP] = offsetof(struct user_regs_struct, ebp) / sizeof(long), - [UNW_X86_ESP] = offsetof(struct user_regs_struct, esp) / sizeof(long), - [UNW_X86_EIP] = offsetof(struct user_regs_struct, eip) / sizeof(long), - [UNW_X86_EFLAGS] = offsetof(struct user_regs_struct, eflags) / sizeof(long), - [UNW_X86_TRAPNO] = offsetof(struct user_regs_struct, orig_eax) / sizeof(long), - }; -#elif defined(UNW_TARGET_X86_64) - static const int8_t remap_regs[] = - { - [UNW_X86_64_RAX] = offsetof(struct user_regs_struct, rax) / sizeof(long), - [UNW_X86_64_RDX] = offsetof(struct user_regs_struct, rdx) / sizeof(long), - [UNW_X86_64_RCX] = offsetof(struct user_regs_struct, rcx) / sizeof(long), - [UNW_X86_64_RBX] = offsetof(struct user_regs_struct, rbx) / sizeof(long), - [UNW_X86_64_RSI] = offsetof(struct user_regs_struct, rsi) / sizeof(long), - [UNW_X86_64_RDI] = offsetof(struct user_regs_struct, rdi) / sizeof(long), - [UNW_X86_64_RBP] = offsetof(struct user_regs_struct, rbp) / sizeof(long), - [UNW_X86_64_RSP] = offsetof(struct user_regs_struct, rsp) / sizeof(long), - [UNW_X86_64_RIP] = offsetof(struct user_regs_struct, rip) / sizeof(long), - }; -#else -#error Port me -#endif - - if (regnum >= (unw_regnum_t)ARRAY_SIZE(remap_regs)) - goto badreg; - - regnum = remap_regs[regnum]; -#endif - - /* pr_reg is a long[] array, but it contains struct user_regs_struct's - * image. - */ - Debug(1, "pr_reg[%d]:%ld (0x%lx)\n", regnum, - (long)ui->prstatus->pr_reg[regnum], - (long)ui->prstatus->pr_reg[regnum] - ); - *valp = ui->prstatus->pr_reg[regnum]; - - return 0; - -badreg: - Debug(0, "bad regnum:%d\n", regnum); - return -UNW_EINVAL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_accessors.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_accessors.c deleted file mode 100644 index ae5c23d21940b9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_accessors.c +++ /dev/null @@ -1,36 +0,0 @@ -/* 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. */ - -#include "_UCD_internal.h" - -unw_accessors_t _UCD_accessors = - { - .find_proc_info = _UCD_find_proc_info, - .put_unwind_info = _UCD_put_unwind_info, - .get_dyn_info_list_addr = _UCD_get_dyn_info_list_addr, - .access_mem = _UCD_access_mem, - .access_reg = _UCD_access_reg, - .access_fpreg = _UCD_access_fpreg, - .resume = _UCD_resume, - .get_proc_name = _UCD_get_proc_name - }; diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c deleted file mode 100644 index 62f6ee05c793b1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c +++ /dev/null @@ -1,417 +0,0 @@ -/* 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. */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -/* Endian detection */ -#include -#if defined(HAVE_BYTESWAP_H) -#include -#endif -#if defined(HAVE_ENDIAN_H) -# include -#elif defined(HAVE_SYS_ENDIAN_H) -# include -#endif -#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN -# define WE_ARE_BIG_ENDIAN 1 -# define WE_ARE_LITTLE_ENDIAN 0 -#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN -# define WE_ARE_BIG_ENDIAN 0 -# define WE_ARE_LITTLE_ENDIAN 1 -#elif defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN -# define WE_ARE_BIG_ENDIAN 1 -# define WE_ARE_LITTLE_ENDIAN 0 -#elif defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN -# define WE_ARE_BIG_ENDIAN 0 -# define WE_ARE_LITTLE_ENDIAN 1 -#elif defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN -# define WE_ARE_BIG_ENDIAN 1 -# define WE_ARE_LITTLE_ENDIAN 0 -#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN -# define WE_ARE_BIG_ENDIAN 0 -# define WE_ARE_LITTLE_ENDIAN 1 -#elif defined(__386__) -# define WE_ARE_BIG_ENDIAN 0 -# define WE_ARE_LITTLE_ENDIAN 1 -#else -# error "Can't determine endianness" -#endif - -#include -#include /* struct elf_prstatus */ - -#include "_UCD_lib.h" -#include "_UCD_internal.h" - -#define NOTE_DATA(_hdr) STRUCT_MEMBER_P((_hdr), sizeof (Elf32_Nhdr) + UNW_ALIGN((_hdr)->n_namesz, 4)) -#define NOTE_SIZE(_hdr) (sizeof (Elf32_Nhdr) + UNW_ALIGN((_hdr)->n_namesz, 4) + UNW_ALIGN((_hdr)->n_descsz, 4)) -#define NOTE_NEXT(_hdr) STRUCT_MEMBER_P((_hdr), NOTE_SIZE(_hdr)) -#define NOTE_FITS_IN(_hdr, _size) ((_size) >= sizeof (Elf32_Nhdr) && (_size) >= NOTE_SIZE (_hdr)) -#define NOTE_FITS(_hdr, _end) NOTE_FITS_IN((_hdr), (unsigned long)((char *)(_end) - (char *)(_hdr))) - -struct UCD_info * -_UCD_create(const char *filename) -{ - union - { - Elf32_Ehdr h32; - Elf64_Ehdr h64; - } elf_header; -#define elf_header32 elf_header.h32 -#define elf_header64 elf_header.h64 - bool _64bits; - - struct UCD_info *ui = memset(malloc(sizeof(*ui)), 0, sizeof(*ui)); - ui->edi.di_cache.format = -1; - ui->edi.di_debug.format = -1; -#if UNW_TARGET_IA64 - ui->edi.ktab.format = -1; -#endif - - int fd = ui->coredump_fd = open(filename, O_RDONLY); - if (fd < 0) - goto err; - ui->coredump_filename = strdup(filename); - - /* No sane ELF32 file is going to be smaller then ELF64 _header_, - * so let's just read 64-bit sized one. - */ - if (read(fd, &elf_header64, sizeof(elf_header64)) != sizeof(elf_header64)) - { - Debug(0, "'%s' is not an ELF file\n", filename); - goto err; - } - - if (memcmp(&elf_header32, ELFMAG, SELFMAG) != 0) - { - Debug(0, "'%s' is not an ELF file\n", filename); - goto err; - } - - if (elf_header32.e_ident[EI_CLASS] != ELFCLASS32 - && elf_header32.e_ident[EI_CLASS] != ELFCLASS64) - { - Debug(0, "'%s' is not a 32/64 bit ELF file\n", filename); - goto err; - } - - if (WE_ARE_LITTLE_ENDIAN != (elf_header32.e_ident[EI_DATA] == ELFDATA2LSB)) - { - Debug(0, "'%s' is endian-incompatible\n", filename); - goto err; - } - - _64bits = (elf_header32.e_ident[EI_CLASS] == ELFCLASS64); - if (_64bits && sizeof(elf_header64.e_entry) > sizeof(off_t)) - { - Debug(0, "Can't process '%s': 64-bit file " - "while only %ld bits are supported", - filename, 8L * sizeof(off_t)); - goto err; - } - - /* paranoia check */ - if (_64bits - ? 0 /* todo: (elf_header64.e_ehsize != NN || elf_header64.e_phentsize != NN) */ - : (elf_header32.e_ehsize != 52 || elf_header32.e_phentsize != 32) - ) - { - Debug(0, "'%s' has wrong e_ehsize or e_phentsize\n", filename); - goto err; - } - - off_t ofs = (_64bits ? elf_header64.e_phoff : elf_header32.e_phoff); - if (lseek(fd, ofs, SEEK_SET) != ofs) - { - Debug(0, "Can't read phdrs from '%s'\n", filename); - goto err; - } - unsigned size = ui->phdrs_count = (_64bits ? elf_header64.e_phnum : elf_header32.e_phnum); - coredump_phdr_t *phdrs = ui->phdrs = memset(malloc(size * sizeof(phdrs[0])), 0, size * sizeof(phdrs[0])); - if (_64bits) - { - coredump_phdr_t *cur = phdrs; - unsigned i = 0; - while (i < size) - { - Elf64_Phdr hdr64; - if (read(fd, &hdr64, sizeof(hdr64)) != sizeof(hdr64)) - { - Debug(0, "Can't read phdrs from '%s'\n", filename); - goto err; - } - cur->p_type = hdr64.p_type ; - cur->p_flags = hdr64.p_flags ; - cur->p_offset = hdr64.p_offset; - cur->p_vaddr = hdr64.p_vaddr ; - /*cur->p_paddr = hdr32.p_paddr ; always 0 */ -//TODO: check that and abort if it isn't? - cur->p_filesz = hdr64.p_filesz; - cur->p_memsz = hdr64.p_memsz ; - cur->p_align = hdr64.p_align ; - /* cur->backing_filename = NULL; - done by memset */ - cur->backing_fd = -1; - cur->backing_filesize = hdr64.p_filesz; - i++; - cur++; - } - } else { - coredump_phdr_t *cur = phdrs; - unsigned i = 0; - while (i < size) - { - Elf32_Phdr hdr32; - if (read(fd, &hdr32, sizeof(hdr32)) != sizeof(hdr32)) - { - Debug(0, "Can't read phdrs from '%s'\n", filename); - goto err; - } - cur->p_type = hdr32.p_type ; - cur->p_flags = hdr32.p_flags ; - cur->p_offset = hdr32.p_offset; - cur->p_vaddr = hdr32.p_vaddr ; - /*cur->p_paddr = hdr32.p_paddr ; always 0 */ - cur->p_filesz = hdr32.p_filesz; - cur->p_memsz = hdr32.p_memsz ; - cur->p_align = hdr32.p_align ; - /* cur->backing_filename = NULL; - done by memset */ - cur->backing_fd = -1; - cur->backing_filesize = hdr32.p_memsz; - i++; - cur++; - } - } - - unsigned i = 0; - coredump_phdr_t *cur = phdrs; - while (i < size) - { - Debug(2, "phdr[%03d]: type:%d", i, cur->p_type); - if (cur->p_type == PT_NOTE) - { - Elf32_Nhdr *note_hdr, *note_end; - unsigned n_threads; - - ui->note_phdr = malloc(cur->p_filesz); - if (lseek(fd, cur->p_offset, SEEK_SET) != (off_t)cur->p_offset - || (uoff_t)read(fd, ui->note_phdr, cur->p_filesz) != cur->p_filesz) - { - Debug(0, "Can't read PT_NOTE from '%s'\n", filename); - goto err; - } - - note_end = STRUCT_MEMBER_P (ui->note_phdr, cur->p_filesz); - - /* Count number of threads */ - n_threads = 0; - note_hdr = (Elf32_Nhdr *)ui->note_phdr; - while (NOTE_FITS (note_hdr, note_end)) - { - if (note_hdr->n_type == NT_PRSTATUS) - n_threads++; - - note_hdr = NOTE_NEXT (note_hdr); - } - - ui->n_threads = n_threads; - ui->threads = malloc(sizeof (void *) * n_threads); - - n_threads = 0; - note_hdr = (Elf32_Nhdr *)ui->note_phdr; - while (NOTE_FITS (note_hdr, note_end)) - { - if (note_hdr->n_type == NT_PRSTATUS) - ui->threads[n_threads++] = NOTE_DATA (note_hdr); - - note_hdr = NOTE_NEXT (note_hdr); - } - } - if (cur->p_type == PT_LOAD) - { - Debug(2, " ofs:%08llx va:%08llx filesize:%08llx memsize:%08llx flg:%x", - (unsigned long long) cur->p_offset, - (unsigned long long) cur->p_vaddr, - (unsigned long long) cur->p_filesz, - (unsigned long long) cur->p_memsz, - cur->p_flags - ); - if (cur->p_filesz < cur->p_memsz) - Debug(2, " partial"); - if (cur->p_flags & PF_X) - Debug(2, " executable"); - } - Debug(2, "\n"); - i++; - cur++; - } - - if (ui->n_threads == 0) - { - Debug(0, "No NT_PRSTATUS note found in '%s'\n", filename); - goto err; - } - - ui->prstatus = ui->threads[0]; - - return ui; - - err: - _UCD_destroy(ui); - return NULL; -} - -int _UCD_get_num_threads(struct UCD_info *ui) -{ - return ui->n_threads; -} - -void _UCD_select_thread(struct UCD_info *ui, int n) -{ - if (n >= 0 && n < ui->n_threads) - ui->prstatus = ui->threads[n]; -} - -pid_t _UCD_get_pid(struct UCD_info *ui) -{ - return ui->prstatus->pr_pid; -} - -int _UCD_get_cursig(struct UCD_info *ui) -{ - return ui->prstatus->pr_cursig; -} - -int _UCD_add_backing_file_at_segment(struct UCD_info *ui, int phdr_no, const char *filename) -{ - if ((unsigned)phdr_no >= ui->phdrs_count) - { - Debug(0, "There is no segment %d in this coredump\n", phdr_no); - return -1; - } - - struct coredump_phdr *phdr = &ui->phdrs[phdr_no]; - if (phdr->backing_filename) - { - Debug(0, "Backing file already added to segment %d\n", phdr_no); - return -1; - } - - int fd = open(filename, O_RDONLY); - if (fd < 0) - { - Debug(0, "Can't open '%s'\n", filename); - return -1; - } - - phdr->backing_fd = fd; - phdr->backing_filename = strdup(filename); - - struct stat statbuf; - if (fstat(fd, &statbuf) != 0) - { - Debug(0, "Can't stat '%s'\n", filename); - goto err; - } - phdr->backing_filesize = (uoff_t)statbuf.st_size; - - if (phdr->p_flags != (PF_X | PF_R)) - Debug(1, "Note: phdr[%u] is not r-x: flags are 0x%x\n", phdr_no, phdr->p_flags); - - if (phdr->backing_filesize > phdr->p_memsz) - { - /* This is expected */ - Debug(2, "Note: phdr[%u] is %lld bytes, file is larger: %lld bytes\n", - phdr_no, - (unsigned long long)phdr->p_memsz, - (unsigned long long)phdr->backing_filesize - ); - } -//TODO: else loudly complain? Maybe even fail? - - if (phdr->p_filesz != 0) - { -//TODO: loop and compare in smaller blocks - char *core_buf = malloc(phdr->p_filesz); - char *file_buf = malloc(phdr->p_filesz); - if (lseek(ui->coredump_fd, phdr->p_offset, SEEK_SET) != (off_t)phdr->p_offset - || (uoff_t)read(ui->coredump_fd, core_buf, phdr->p_filesz) != phdr->p_filesz - ) - { - Debug(0, "Error reading from coredump file\n"); - err_read: - free(core_buf); - free(file_buf); - goto err; - } - if ((uoff_t)read(fd, file_buf, phdr->p_filesz) != phdr->p_filesz) - { - Debug(0, "Error reading from '%s'\n", filename); - goto err_read; - } - int r = memcmp(core_buf, file_buf, phdr->p_filesz); - free(core_buf); - free(file_buf); - if (r != 0) - { - Debug(1, "Note: phdr[%u] first %lld bytes in core dump and in file do not match\n", - phdr_no, (unsigned long long)phdr->p_filesz - ); - } else { - Debug(1, "Note: phdr[%u] first %lld bytes in core dump and in file match\n", - phdr_no, (unsigned long long)phdr->p_filesz - ); - } - } - - /* Success */ - return 0; - - err: - if (phdr->backing_fd >= 0) - { - close(phdr->backing_fd); - phdr->backing_fd = -1; - } - free(phdr->backing_filename); - phdr->backing_filename = NULL; - return -1; -} - -int _UCD_add_backing_file_at_vaddr(struct UCD_info *ui, - unsigned long vaddr, - const char *filename) -{ - unsigned i; - for (i = 0; i < ui->phdrs_count; i++) - { - struct coredump_phdr *phdr = &ui->phdrs[i]; - if (phdr->p_vaddr != vaddr) - continue; - /* It seems to match. Add it. */ - return _UCD_add_backing_file_at_segment(ui, i, filename); - } - return -1; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_destroy.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_destroy.c deleted file mode 100644 index ddc36ec8986aad..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_destroy.c +++ /dev/null @@ -1,52 +0,0 @@ -/* 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. */ - -#include "_UCD_internal.h" - -void -_UCD_destroy (struct UCD_info *ui) -{ - if (!ui) - return; - - if (ui->coredump_fd >= 0) - close(ui->coredump_fd); - free(ui->coredump_filename); - - invalidate_edi (&ui->edi); - - unsigned i; - for (i = 0; i < ui->phdrs_count; i++) - { - struct coredump_phdr *phdr = &ui->phdrs[i]; - free(phdr->backing_filename); - if (phdr->backing_fd >= 0) - close(phdr->backing_fd); - } - - free(ui->phdrs); - free(ui->note_phdr); - free(ui->threads); - - free(ui); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_elf_map_image.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_elf_map_image.c deleted file mode 100644 index 4b3db0bbff7ee2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_elf_map_image.c +++ /dev/null @@ -1,98 +0,0 @@ -/* 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. */ - -#include - -#include "_UCD_lib.h" -#include "_UCD_internal.h" - -static coredump_phdr_t * -CD_elf_map_image(struct UCD_info *ui, coredump_phdr_t *phdr) -{ - struct elf_image *ei = &ui->edi.ei; - - if (phdr->backing_fd < 0) - { - /* Note: coredump file contains only phdr->p_filesz bytes. - * We want to map bigger area (phdr->p_memsz bytes) to make sure - * these pages are allocated, but non-accessible. - */ - /* addr, length, prot, flags, fd, fd_offset */ - ei->image = mmap(NULL, phdr->p_memsz, PROT_READ, MAP_PRIVATE, ui->coredump_fd, phdr->p_offset); - if (ei->image == MAP_FAILED) - { - ei->image = NULL; - return NULL; - } - ei->size = phdr->p_filesz; - size_t remainder_len = phdr->p_memsz - phdr->p_filesz; - if (remainder_len > 0) - { - void *remainder_base = (char*) ei->image + phdr->p_filesz; - munmap(remainder_base, remainder_len); - } - } else { - /* We have a backing file for this segment. - * This file is always longer than phdr->p_memsz, - * and if phdr->p_filesz !=0, first phdr->p_filesz bytes in coredump - * are the same as first bytes in the file. (Thus no need to map coredump) - * We map the entire file: - * unwinding may need data which is past phdr->p_memsz bytes. - */ - /* addr, length, prot, flags, fd, fd_offset */ - ei->image = mmap(NULL, phdr->backing_filesize, PROT_READ, MAP_PRIVATE, phdr->backing_fd, 0); - if (ei->image == MAP_FAILED) - { - ei->image = NULL; - return NULL; - } - ei->size = phdr->backing_filesize; - } - - /* Check ELF header for sanity */ - if (!elf_w(valid_object)(ei)) - { - munmap(ei->image, ei->size); - ei->image = NULL; - ei->size = 0; - return NULL; - } - - return phdr; -} - -HIDDEN coredump_phdr_t * -_UCD_get_elf_image(struct UCD_info *ui, unw_word_t ip) -{ - unsigned i; - for (i = 0; i < ui->phdrs_count; i++) - { - coredump_phdr_t *phdr = &ui->phdrs[i]; - if (phdr->p_vaddr <= ip && ip < phdr->p_vaddr + phdr->p_memsz) - { - phdr = CD_elf_map_image(ui, phdr); - return phdr; - } - } - return NULL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_find_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_find_proc_info.c deleted file mode 100644 index 33b66c8edbe1dc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_find_proc_info.c +++ /dev/null @@ -1,163 +0,0 @@ -/* 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. */ - -#include - -#include "_UCD_lib.h" -#include "_UCD_internal.h" - -static int -get_unwind_info(struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip) -{ - unsigned long segbase, mapoff; - -#if UNW_TARGET_IA64 && defined(__linux) - if (!ui->edi.ktab.start_ip && _Uia64_get_kernel_table (&ui->edi.ktab) < 0) - return -UNW_ENOINFO; - - if (ui->edi.ktab.format != -1 && ip >= ui->edi.ktab.start_ip && ip < ui->edi.ktab.end_ip) - return 0; -#endif - - if ((ui->edi.di_cache.format != -1 - && ip >= ui->edi.di_cache.start_ip && ip < ui->edi.di_cache.end_ip) -#if UNW_TARGET_ARM - || (ui->edi.di_debug.format != -1 - && ip >= ui->edi.di_arm.start_ip && ip < ui->edi.di_arm.end_ip) -#endif - || (ui->edi.di_debug.format != -1 - && ip >= ui->edi.di_debug.start_ip && ip < ui->edi.di_debug.end_ip)) - return 0; - - invalidate_edi (&ui->edi); - - /* Used to be tdep_get_elf_image() in ptrace unwinding code */ - coredump_phdr_t *phdr = _UCD_get_elf_image(ui, ip); - if (!phdr) - { - Debug(1, "returns error: _UCD_get_elf_image failed\n"); - return -UNW_ENOINFO; - } - /* segbase: where it is mapped in virtual memory */ - /* mapoff: offset in the file */ - segbase = phdr->p_vaddr; - /*mapoff = phdr->p_offset; WRONG! phdr->p_offset is the offset in COREDUMP file */ - mapoff = 0; -///FIXME. text segment is USUALLY, not always, at offset 0 in the binary/.so file. -// ensure that at initialization. - - /* Here, SEGBASE is the starting-address of the (mmap'ped) segment - which covers the IP we're looking for. */ - if (tdep_find_unwind_table(&ui->edi, as, phdr->backing_filename, segbase, mapoff, ip) < 0) - { - Debug(1, "returns error: tdep_find_unwind_table failed\n"); - return -UNW_ENOINFO; - } - - /* This can happen in corner cases where dynamically generated - code falls into the same page that contains the data-segment - and the page-offset of the code is within the first page of - the executable. */ - if (ui->edi.di_cache.format != -1 - && (ip < ui->edi.di_cache.start_ip || ip >= ui->edi.di_cache.end_ip)) - ui->edi.di_cache.format = -1; - - if (ui->edi.di_debug.format != -1 - && (ip < ui->edi.di_debug.start_ip || ip >= ui->edi.di_debug.end_ip)) - ui->edi.di_debug.format = -1; - - if (ui->edi.di_cache.format == -1 -#if UNW_TARGET_ARM - && ui->edi.di_arm.format == -1 -#endif - && ui->edi.di_debug.format == -1) - { - Debug(1, "returns error: all formats are -1\n"); - return -UNW_ENOINFO; - } - - Debug(1, "returns success\n"); - return 0; -} - -int -_UCD_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, - int need_unwind_info, void *arg) -{ - struct UCD_info *ui = arg; - - Debug(1, "entering\n"); - - int ret = -UNW_ENOINFO; - - if (get_unwind_info(ui, as, ip) < 0) { - Debug(1, "returns error: get_unwind_info failed\n"); - return -UNW_ENOINFO; - } - -#if UNW_TARGET_IA64 - if (ui->edi.ktab.format != -1) - { - /* The kernel unwind table resides in local memory, so we have - to use the local address space to search it. Since - _UCD_put_unwind_info() has no easy way of detecting this - case, we simply make a copy of the unwind-info, so - _UCD_put_unwind_info() can always free() the unwind-info - without ill effects. */ - ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi, - need_unwind_info, arg); - if (ret >= 0) - { - if (!need_unwind_info) - pi->unwind_info = NULL; - else - { - void *mem = malloc (pi->unwind_info_size); - - if (!mem) - return -UNW_ENOMEM; - memcpy (mem, pi->unwind_info, pi->unwind_info_size); - pi->unwind_info = mem; - } - } - } -#endif - - if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1) - ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache, - pi, need_unwind_info, arg); - -#if UNW_TARGET_ARM - if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1) - ret = tdep_search_unwind_table (as, ip, &ui->edi.di_arm, pi, - need_unwind_info, arg); -#endif - - if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1) - ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi, - need_unwind_info, arg); - - Debug(1, "returns %d\n", ret); - - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c deleted file mode 100644 index 00096c48d0770c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c +++ /dev/null @@ -1,70 +0,0 @@ -/* 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. */ - -#include "_UCD_lib.h" -#include "_UCD_internal.h" - - -/* Find the ELF image that contains IP and return the "closest" - procedure name, if there is one. With some caching, this could be - sped up greatly, but until an application materializes that's - sensitive to the performance of this routine, why bother... */ -static int -elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp) -{ - unsigned long segbase, mapoff; - int ret; - - /* Used to be tdep_get_elf_image() in ptrace unwinding code */ - coredump_phdr_t *cphdr = _UCD_get_elf_image(ui, ip); - if (!cphdr) - { - Debug(1, "returns error: _UCD_get_elf_image failed\n"); - return -UNW_ENOINFO; - } - /* segbase: where it is mapped in virtual memory */ - /* mapoff: offset in the file */ - segbase = cphdr->p_vaddr; - /*mapoff = phdr->p_offset; WRONG! phdr->p_offset is the offset in COREDUMP file */ - mapoff = 0; - - ret = elf_w (get_proc_name_in_image) (as, &ui->edi.ei, segbase, mapoff, ip, buf, buf_len, offp); - - return ret; -} - -int -_UCD_get_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, void *arg) -{ - struct UCD_info *ui = arg; - -#if ELF_CLASS == ELFCLASS64 - return _Uelf64_CD_get_proc_name (ui, as, ip, buf, buf_len, offp); -#elif ELF_CLASS == ELFCLASS32 - return _Uelf32_CD_get_proc_name (ui, as, ip, buf, buf_len, offp); -#else - return -UNW_ENOINFO; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_internal.h b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_internal.h deleted file mode 100644 index 3c95a2a0038c7a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_internal.h +++ /dev/null @@ -1,105 +0,0 @@ -/* 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 _UCD_internal_h -#define _UCD_internal_h - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_PROCFS_H -#include /* struct elf_prstatus */ -#endif -#include -#include -#include -#include -#include - -#include - -#include "libunwind_i.h" - - -#if SIZEOF_OFF_T == 4 -typedef uint32_t uoff_t; -#elif SIZEOF_OFF_T == 8 -typedef uint64_t uoff_t; -#else -# error Unknown size of off_t! -#endif - - -/* Similar to ELF phdrs. p_paddr element is absent, - * since it's always 0 in coredumps. - */ -struct coredump_phdr - { - uint32_t p_type; - uint32_t p_flags; - uoff_t p_offset; - uoff_t p_vaddr; - uoff_t p_filesz; - uoff_t p_memsz; - uoff_t p_align; - /* Data for backing file. If backing_fd < 0, there is no file */ - uoff_t backing_filesize; - char *backing_filename; /* for error meesages only */ - int backing_fd; - }; - -typedef struct coredump_phdr coredump_phdr_t; - -#if defined(HAVE_STRUCT_ELF_PRSTATUS) -#define PRSTATUS_STRUCT elf_prstatus -#elif defined(HAVE_STRUCT_PRSTATUS) -#define PRSTATUS_STRUCT prstatus -#else -#define PRSTATUS_STRUCT non_existent -#endif - -struct UCD_info - { - int big_endian; /* bool */ - int coredump_fd; - char *coredump_filename; /* for error meesages only */ - coredump_phdr_t *phdrs; /* array, allocated */ - unsigned phdrs_count; - void *note_phdr; /* allocated or NULL */ - struct PRSTATUS_STRUCT *prstatus; /* points inside note_phdr */ - int n_threads; - struct PRSTATUS_STRUCT **threads; - - struct elf_dyn_info edi; - }; - -extern coredump_phdr_t * _UCD_get_elf_image(struct UCD_info *ui, unw_word_t ip); - -#define STRUCT_MEMBER_P(struct_p, struct_offset) ((void *) ((char*) (struct_p) + (long) (struct_offset))) -#define STRUCT_MEMBER(member_type, struct_p, struct_offset) (*(member_type*) STRUCT_MEMBER_P ((struct_p), (struct_offset))) - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_lib.h b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_lib.h deleted file mode 100644 index 22be32ed1efa1c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_lib.h +++ /dev/null @@ -1,57 +0,0 @@ -/* 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 _UCD_lib_h -#define _UCD_lib_h - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_access_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_access_fpreg.c deleted file mode 100644 index 0b8b86ac9072aa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_access_fpreg.c +++ /dev/null @@ -1,34 +0,0 @@ -/* 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. */ - -#include "_UCD_lib.h" -#include "_UCD_internal.h" - -int -_UCD_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - print_error (__func__); - print_error (" not implemented\n"); - return -UNW_EINVAL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_elf.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_elf.c deleted file mode 100644 index fb7b19a7cbd8ba..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_elf.c +++ /dev/null @@ -1,5 +0,0 @@ -/* We need to get a separate copy of the ELF-code into - libunwind-coredump since it cannot (and must not) have any ELF - dependencies on libunwind. */ -#include "libunwind_i.h" /* get ELFCLASS defined */ -#include "../elfxx.c" diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c deleted file mode 100644 index 0d11905566c30a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c +++ /dev/null @@ -1,108 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UCD_lib.h" -#include "_UCD_internal.h" - -#if UNW_TARGET_IA64 && defined(__linux) -# include "elf64.h" -# include "os-linux.h" - -static inline int -get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, - int *countp) -{ - unsigned long lo, hi, off; - struct UPT_info *ui = arg; - struct map_iterator mi; - char path[PATH_MAX]; - unw_dyn_info_t *di; - unw_word_t res; - int count = 0; - - maps_init (&mi, ui->pid); - while (maps_next (&mi, &lo, &hi, &off)) - { - if (off) - continue; - - invalidate_edi (&ui->edi); - - if (elf_map_image (&ui->ei, path) < 0) - /* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */ - continue; - - Debug (16, "checking object %s\n", path); - - di = tdep_find_unwind_table (&ui->edi, as, path, lo, off); - if (di) - { - res = _Uia64_find_dyn_list (as, di, arg); - if (res && count++ == 0) - { - Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res); - *dil_addr = res; - } - } - } - maps_close (&mi); - *countp = count; - return 0; -} - -#else - -static inline int -get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, - int *countp) -{ -# warning Implement get_list_addr(), please. - *countp = 0; - return 0; -} - -#endif - -int -_UCD_get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, - void *arg) -{ - int count, ret; - - Debug (12, "looking for dyn_info list\n"); - - if ((ret = get_list_addr (as, dil_addr, arg, &count)) < 0) - return ret; - - /* If multiple dynamic-info list addresses are found, we would have - to determine which was is the one actually in use (since the - dynamic name resolution algorithm will pick one "winner"). - Perhaps we'd have to track them all until we find one that's - non-empty. Hopefully, this case simply will never arise, since - only libunwind defines the dynamic info list head. */ - assert (count <= 1); - - return (count > 0) ? 0 : -UNW_ENOINFO; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_put_unwind_info.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_put_unwind_info.c deleted file mode 100644 index 462e1d048c3906..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_put_unwind_info.c +++ /dev/null @@ -1,36 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UCD_lib.h" -#include "_UCD_internal.h" - -void -_UCD_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) -{ - if (!pi->unwind_info) - return; - free (pi->unwind_info); - pi->unwind_info = NULL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_resume.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_resume.c deleted file mode 100644 index a729c908cb123e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_resume.c +++ /dev/null @@ -1,35 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UCD_lib.h" -#include "_UCD_internal.h" - -int -_UCD_resume (unw_addr_space_t as, unw_cursor_t *c, void *arg) -{ - print_error (__func__); - print_error (" not implemented\n"); - return -UNW_EINVAL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/libunwind-coredump.pc.in b/src/coreclr/src/pal/src/libunwind/src/coredump/libunwind-coredump.pc.in deleted file mode 100644 index 9cb62c086d23c3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/libunwind-coredump.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libunwind-coredump -Description: libunwind coredump library -Version: @VERSION@ -Requires: libunwind-generic libunwind -Libs: -L${libdir} -lunwind-coredump -Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c deleted file mode 100644 index f63c3d220c6bde..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c +++ /dev/null @@ -1,696 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "dwarf_i.h" -#include "libunwind_i.h" - -/* The "pick" operator provides an index range of 0..255 indicating - that the stack could at least have a depth of up to 256 elements, - but the GCC unwinder restricts the depth to 64, which seems - reasonable so we use the same value here. */ -#define MAX_EXPR_STACK_SIZE 64 - -#define NUM_OPERANDS(signature) (((signature) >> 6) & 0x3) -#define OPND1_TYPE(signature) (((signature) >> 3) & 0x7) -#define OPND2_TYPE(signature) (((signature) >> 0) & 0x7) - -#define OPND_SIGNATURE(n, t1, t2) (((n) << 6) | ((t1) << 3) | ((t2) << 0)) -#define OPND1(t1) OPND_SIGNATURE(1, t1, 0) -#define OPND2(t1, t2) OPND_SIGNATURE(2, t1, t2) - -#define VAL8 0x0 -#define VAL16 0x1 -#define VAL32 0x2 -#define VAL64 0x3 -#define ULEB128 0x4 -#define SLEB128 0x5 -#define OFFSET 0x6 /* 32-bit offset for 32-bit DWARF, 64-bit otherwise */ -#define ADDR 0x7 /* Machine address. */ - -static const uint8_t operands[256] = - { - [DW_OP_addr] = OPND1 (ADDR), - [DW_OP_const1u] = OPND1 (VAL8), - [DW_OP_const1s] = OPND1 (VAL8), - [DW_OP_const2u] = OPND1 (VAL16), - [DW_OP_const2s] = OPND1 (VAL16), - [DW_OP_const4u] = OPND1 (VAL32), - [DW_OP_const4s] = OPND1 (VAL32), - [DW_OP_const8u] = OPND1 (VAL64), - [DW_OP_const8s] = OPND1 (VAL64), - [DW_OP_pick] = OPND1 (VAL8), - [DW_OP_plus_uconst] = OPND1 (ULEB128), - [DW_OP_skip] = OPND1 (VAL16), - [DW_OP_bra] = OPND1 (VAL16), - [DW_OP_breg0 + 0] = OPND1 (SLEB128), - [DW_OP_breg0 + 1] = OPND1 (SLEB128), - [DW_OP_breg0 + 2] = OPND1 (SLEB128), - [DW_OP_breg0 + 3] = OPND1 (SLEB128), - [DW_OP_breg0 + 4] = OPND1 (SLEB128), - [DW_OP_breg0 + 5] = OPND1 (SLEB128), - [DW_OP_breg0 + 6] = OPND1 (SLEB128), - [DW_OP_breg0 + 7] = OPND1 (SLEB128), - [DW_OP_breg0 + 8] = OPND1 (SLEB128), - [DW_OP_breg0 + 9] = OPND1 (SLEB128), - [DW_OP_breg0 + 10] = OPND1 (SLEB128), - [DW_OP_breg0 + 11] = OPND1 (SLEB128), - [DW_OP_breg0 + 12] = OPND1 (SLEB128), - [DW_OP_breg0 + 13] = OPND1 (SLEB128), - [DW_OP_breg0 + 14] = OPND1 (SLEB128), - [DW_OP_breg0 + 15] = OPND1 (SLEB128), - [DW_OP_breg0 + 16] = OPND1 (SLEB128), - [DW_OP_breg0 + 17] = OPND1 (SLEB128), - [DW_OP_breg0 + 18] = OPND1 (SLEB128), - [DW_OP_breg0 + 19] = OPND1 (SLEB128), - [DW_OP_breg0 + 20] = OPND1 (SLEB128), - [DW_OP_breg0 + 21] = OPND1 (SLEB128), - [DW_OP_breg0 + 22] = OPND1 (SLEB128), - [DW_OP_breg0 + 23] = OPND1 (SLEB128), - [DW_OP_breg0 + 24] = OPND1 (SLEB128), - [DW_OP_breg0 + 25] = OPND1 (SLEB128), - [DW_OP_breg0 + 26] = OPND1 (SLEB128), - [DW_OP_breg0 + 27] = OPND1 (SLEB128), - [DW_OP_breg0 + 28] = OPND1 (SLEB128), - [DW_OP_breg0 + 29] = OPND1 (SLEB128), - [DW_OP_breg0 + 30] = OPND1 (SLEB128), - [DW_OP_breg0 + 31] = OPND1 (SLEB128), - [DW_OP_regx] = OPND1 (ULEB128), - [DW_OP_fbreg] = OPND1 (SLEB128), - [DW_OP_bregx] = OPND2 (ULEB128, SLEB128), - [DW_OP_piece] = OPND1 (ULEB128), - [DW_OP_deref_size] = OPND1 (VAL8), - [DW_OP_xderef_size] = OPND1 (VAL8), - [DW_OP_call2] = OPND1 (VAL16), - [DW_OP_call4] = OPND1 (VAL32), - [DW_OP_call_ref] = OPND1 (OFFSET) - }; - -static inline unw_sword_t -sword (unw_addr_space_t as, unw_word_t val) -{ - switch (dwarf_addr_size (as)) - { - case 1: return (int8_t) val; - case 2: return (int16_t) val; - case 4: return (int32_t) val; - case 8: return (int64_t) val; - default: abort (); - } -} - -static inline unw_word_t -read_operand (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, int operand_type, unw_word_t *val, void *arg) -{ - uint8_t u8; - uint16_t u16; - uint32_t u32; - uint64_t u64; - int ret; - - if (operand_type == ADDR) - switch (dwarf_addr_size (as)) - { - case 1: operand_type = VAL8; break; - case 2: operand_type = VAL16; break; - case 4: operand_type = VAL32; break; - case 8: operand_type = VAL64; break; - default: abort (); - } - - switch (operand_type) - { - case VAL8: - ret = dwarf_readu8 (as, a, addr, &u8, arg); - if (ret < 0) - return ret; - *val = u8; - break; - - case VAL16: - ret = dwarf_readu16 (as, a, addr, &u16, arg); - if (ret < 0) - return ret; - *val = u16; - break; - - case VAL32: - ret = dwarf_readu32 (as, a, addr, &u32, arg); - if (ret < 0) - return ret; - *val = u32; - break; - - case VAL64: - ret = dwarf_readu64 (as, a, addr, &u64, arg); - if (ret < 0) - return ret; - *val = u64; - break; - - case ULEB128: - ret = dwarf_read_uleb128 (as, a, addr, val, arg); - break; - - case SLEB128: - ret = dwarf_read_sleb128 (as, a, addr, val, arg); - break; - - case OFFSET: /* only used by DW_OP_call_ref, which we don't implement */ - default: - Debug (1, "Unexpected operand type %d\n", operand_type); - ret = -UNW_EINVAL; - } - return ret; -} - -HIDDEN int -dwarf_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr, - unw_word_t rbp_addr, unw_word_t *cfa_offset) { - unw_accessors_t *a; - int ret; - void *arg; - unw_word_t len; - uint8_t opcode; - unw_word_t operand1; - - a = unw_get_accessors_int (c->as); - arg = c->as_arg; - - ret = dwarf_read_uleb128(c->as, a, &rbp_addr, &len, arg); - if (len != 2 || ret < 0) - return 0; - - ret = dwarf_readu8(c->as, a, &rbp_addr, &opcode, arg); - if (ret < 0 || opcode != DW_OP_breg6) - return 0; - - ret = read_operand(c->as, a, &rbp_addr, - OPND1_TYPE(operands[opcode]), &operand1, arg); - - if (ret < 0 || operand1 != 0) - return 0; - - ret = dwarf_read_uleb128(c->as, a, &cfa_addr, &len, arg); - if (ret < 0 || len != 3) - return 0; - - ret = dwarf_readu8(c->as, a, &cfa_addr, &opcode, arg); - if (ret < 0 || opcode != DW_OP_breg6) - return 0; - - ret = read_operand(c->as, a, &cfa_addr, - OPND1_TYPE(operands[opcode]), &operand1, arg); - if (ret < 0) - return 0; - - ret = dwarf_readu8(c->as, a, &cfa_addr, &opcode, arg); - if (ret < 0 || opcode != DW_OP_deref) - return 0; - - *cfa_offset = operand1; - return 1; -} - -HIDDEN int -dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len, - unw_word_t *valp, int *is_register) -{ - unw_word_t operand1 = 0, operand2 = 0, tmp1, tmp2 = 0, tmp3, end_addr; - uint8_t opcode, operands_signature, u8; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - unw_word_t stack[MAX_EXPR_STACK_SIZE]; - unsigned int tos = 0; - uint16_t u16; - uint32_t u32; - uint64_t u64; - int ret; -# define pop() \ -({ \ - if ((tos - 1) >= MAX_EXPR_STACK_SIZE) \ - { \ - Debug (1, "Stack underflow\n"); \ - return -UNW_EINVAL; \ - } \ - stack[--tos]; \ -}) -# define push(x) \ -do { \ - unw_word_t _x = (x); \ - if (tos >= MAX_EXPR_STACK_SIZE) \ - { \ - Debug (1, "Stack overflow\n"); \ - return -UNW_EINVAL; \ - } \ - stack[tos++] = _x; \ -} while (0) -# define pick(n) \ -({ \ - unsigned int _index = tos - 1 - (n); \ - if (_index >= MAX_EXPR_STACK_SIZE) \ - { \ - Debug (1, "Out-of-stack pick\n"); \ - return -UNW_EINVAL; \ - } \ - stack[_index]; \ -}) - - as = c->as; - arg = c->as_arg; - a = unw_get_accessors_int (as); - end_addr = *addr + len; - *is_register = 0; - - Debug (14, "len=%lu, pushing cfa=0x%lx\n", - (unsigned long) len, (unsigned long) c->cfa); - - push (c->cfa); /* push current CFA as required by DWARF spec */ - - while (*addr < end_addr) - { - if ((ret = dwarf_readu8 (as, a, addr, &opcode, arg)) < 0) - return ret; - - operands_signature = operands[opcode]; - - if (unlikely (NUM_OPERANDS (operands_signature) > 0)) - { - if ((ret = read_operand (as, a, addr, - OPND1_TYPE (operands_signature), - &operand1, arg)) < 0) - return ret; - if (NUM_OPERANDS (operands_signature) > 1) - if ((ret = read_operand (as, a, addr, - OPND2_TYPE (operands_signature), - &operand2, arg)) < 0) - return ret; - } - - switch ((dwarf_expr_op_t) opcode) - { - case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: - case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: - case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: - case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: - case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: - case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: - case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: - case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: - case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: - case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: - case DW_OP_lit30: case DW_OP_lit31: - Debug (15, "OP_lit(%d)\n", (int) opcode - DW_OP_lit0); - push (opcode - DW_OP_lit0); - break; - - case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: - case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: - case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: - case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: - case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: - case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: - case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: - case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: - case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: - case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: - case DW_OP_breg30: case DW_OP_breg31: - Debug (15, "OP_breg(r%d,0x%lx)\n", - (int) opcode - DW_OP_breg0, (unsigned long) operand1); - if ((ret = unw_get_reg (dwarf_to_cursor (c), - dwarf_to_unw_regnum (opcode - DW_OP_breg0), - &tmp1)) < 0) - return ret; - push (tmp1 + operand1); - break; - - case DW_OP_bregx: - Debug (15, "OP_bregx(r%d,0x%lx)\n", - (int) operand1, (unsigned long) operand2); - if ((ret = unw_get_reg (dwarf_to_cursor (c), - dwarf_to_unw_regnum (operand1), &tmp1)) < 0) - return ret; - push (tmp1 + operand2); - break; - - case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: - case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: - case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: - case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: - case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: - case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: - case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: - case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: - case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: - case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: - case DW_OP_reg30: case DW_OP_reg31: - Debug (15, "OP_reg(r%d)\n", (int) opcode - DW_OP_reg0); - *valp = dwarf_to_unw_regnum (opcode - DW_OP_reg0); - *is_register = 1; - return 0; - - case DW_OP_regx: - Debug (15, "OP_regx(r%d)\n", (int) operand1); - *valp = dwarf_to_unw_regnum (operand1); - *is_register = 1; - return 0; - - case DW_OP_addr: - case DW_OP_const1u: - case DW_OP_const2u: - case DW_OP_const4u: - case DW_OP_const8u: - case DW_OP_constu: - case DW_OP_const8s: - case DW_OP_consts: - Debug (15, "OP_const(0x%lx)\n", (unsigned long) operand1); - push (operand1); - break; - - case DW_OP_const1s: - if (operand1 & 0x80) - operand1 |= ((unw_word_t) -1) << 8; - Debug (15, "OP_const1s(%ld)\n", (long) operand1); - push (operand1); - break; - - case DW_OP_const2s: - if (operand1 & 0x8000) - operand1 |= ((unw_word_t) -1) << 16; - Debug (15, "OP_const2s(%ld)\n", (long) operand1); - push (operand1); - break; - - case DW_OP_const4s: - if (operand1 & 0x80000000) - operand1 |= (((unw_word_t) -1) << 16) << 16; - Debug (15, "OP_const4s(%ld)\n", (long) operand1); - push (operand1); - break; - - case DW_OP_deref: - Debug (15, "OP_deref\n"); - tmp1 = pop (); - if ((ret = dwarf_readw (as, a, &tmp1, &tmp2, arg)) < 0) - return ret; - push (tmp2); - break; - - case DW_OP_deref_size: - Debug (15, "OP_deref_size(%d)\n", (int) operand1); - tmp1 = pop (); - switch (operand1) - { - default: - Debug (1, "Unexpected DW_OP_deref_size size %d\n", - (int) operand1); - return -UNW_EINVAL; - - case 1: - if ((ret = dwarf_readu8 (as, a, &tmp1, &u8, arg)) < 0) - return ret; - tmp2 = u8; - break; - - case 2: - if ((ret = dwarf_readu16 (as, a, &tmp1, &u16, arg)) < 0) - return ret; - tmp2 = u16; - break; - - case 3: - case 4: - if ((ret = dwarf_readu32 (as, a, &tmp1, &u32, arg)) < 0) - return ret; - tmp2 = u32; - if (operand1 == 3) - { - if (dwarf_is_big_endian (as)) - tmp2 >>= 8; - else - tmp2 &= 0xffffff; - } - break; - case 5: - case 6: - case 7: - case 8: - if ((ret = dwarf_readu64 (as, a, &tmp1, &u64, arg)) < 0) - return ret; - tmp2 = u64; - if (operand1 != 8) - { - if (dwarf_is_big_endian (as)) - tmp2 >>= 64 - 8 * operand1; - else - tmp2 &= (~ (unw_word_t) 0) << (8 * operand1); - } - break; - } - push (tmp2); - break; - - case DW_OP_dup: - Debug (15, "OP_dup\n"); - push (pick (0)); - break; - - case DW_OP_drop: - Debug (15, "OP_drop\n"); - (void) pop (); - break; - - case DW_OP_pick: - Debug (15, "OP_pick(%d)\n", (int) operand1); - push (pick (operand1)); - break; - - case DW_OP_over: - Debug (15, "OP_over\n"); - push (pick (1)); - break; - - case DW_OP_swap: - Debug (15, "OP_swap\n"); - tmp1 = pop (); - tmp2 = pop (); - push (tmp1); - push (tmp2); - break; - - case DW_OP_rot: - Debug (15, "OP_rot\n"); - tmp1 = pop (); - tmp2 = pop (); - tmp3 = pop (); - push (tmp1); - push (tmp3); - push (tmp2); - break; - - case DW_OP_abs: - Debug (15, "OP_abs\n"); - tmp1 = pop (); - if (tmp1 & ((unw_word_t) 1 << (8 * dwarf_addr_size (as) - 1))) - tmp1 = -tmp1; - push (tmp1); - break; - - case DW_OP_and: - Debug (15, "OP_and\n"); - tmp1 = pop (); - tmp2 = pop (); - push (tmp1 & tmp2); - break; - - case DW_OP_div: - Debug (15, "OP_div\n"); - tmp1 = pop (); - tmp2 = pop (); - if (tmp1) - tmp1 = sword (as, tmp2) / sword (as, tmp1); - push (tmp1); - break; - - case DW_OP_minus: - Debug (15, "OP_minus\n"); - tmp1 = pop (); - tmp2 = pop (); - tmp1 = tmp2 - tmp1; - push (tmp1); - break; - - case DW_OP_mod: - Debug (15, "OP_mod\n"); - tmp1 = pop (); - tmp2 = pop (); - if (tmp1) - tmp1 = tmp2 % tmp1; - push (tmp1); - break; - - case DW_OP_mul: - Debug (15, "OP_mul\n"); - tmp1 = pop (); - tmp2 = pop (); - if (tmp1) - tmp1 = tmp2 * tmp1; - push (tmp1); - break; - - case DW_OP_neg: - Debug (15, "OP_neg\n"); - push (-pop ()); - break; - - case DW_OP_not: - Debug (15, "OP_not\n"); - push (~pop ()); - break; - - case DW_OP_or: - Debug (15, "OP_or\n"); - tmp1 = pop (); - tmp2 = pop (); - push (tmp1 | tmp2); - break; - - case DW_OP_plus: - Debug (15, "OP_plus\n"); - tmp1 = pop (); - tmp2 = pop (); - push (tmp1 + tmp2); - break; - - case DW_OP_plus_uconst: - Debug (15, "OP_plus_uconst(%lu)\n", (unsigned long) operand1); - tmp1 = pop (); - push (tmp1 + operand1); - break; - - case DW_OP_shl: - Debug (15, "OP_shl\n"); - tmp1 = pop (); - tmp2 = pop (); - push (tmp2 << tmp1); - break; - - case DW_OP_shr: - Debug (15, "OP_shr\n"); - tmp1 = pop (); - tmp2 = pop (); - push (tmp2 >> tmp1); - break; - - case DW_OP_shra: - Debug (15, "OP_shra\n"); - tmp1 = pop (); - tmp2 = pop (); - push (sword (as, tmp2) >> tmp1); - break; - - case DW_OP_xor: - Debug (15, "OP_xor\n"); - tmp1 = pop (); - tmp2 = pop (); - push (tmp1 ^ tmp2); - break; - - case DW_OP_le: - Debug (15, "OP_le\n"); - tmp1 = pop (); - tmp2 = pop (); - push (sword (as, tmp2) <= sword (as, tmp1)); - break; - - case DW_OP_ge: - Debug (15, "OP_ge\n"); - tmp1 = pop (); - tmp2 = pop (); - push (sword (as, tmp2) >= sword (as, tmp1)); - break; - - case DW_OP_eq: - Debug (15, "OP_eq\n"); - tmp1 = pop (); - tmp2 = pop (); - push (sword (as, tmp2) == sword (as, tmp1)); - break; - - case DW_OP_lt: - Debug (15, "OP_lt\n"); - tmp1 = pop (); - tmp2 = pop (); - push (sword (as, tmp2) < sword (as, tmp1)); - break; - - case DW_OP_gt: - Debug (15, "OP_gt\n"); - tmp1 = pop (); - tmp2 = pop (); - push (sword (as, tmp2) > sword (as, tmp1)); - break; - - case DW_OP_ne: - Debug (15, "OP_ne\n"); - tmp1 = pop (); - tmp2 = pop (); - push (sword (as, tmp2) != sword (as, tmp1)); - break; - - case DW_OP_skip: - Debug (15, "OP_skip(%d)\n", (int16_t) operand1); - *addr += (int16_t) operand1; - break; - - case DW_OP_bra: - Debug (15, "OP_skip(%d)\n", (int16_t) operand1); - tmp1 = pop (); - if (tmp1) - *addr += (int16_t) operand1; - break; - - case DW_OP_nop: - Debug (15, "OP_nop\n"); - break; - - case DW_OP_call2: - case DW_OP_call4: - case DW_OP_call_ref: - case DW_OP_fbreg: - case DW_OP_piece: - case DW_OP_push_object_address: - case DW_OP_xderef: - case DW_OP_xderef_size: - default: - Debug (1, "Unexpected opcode 0x%x\n", opcode); - return -UNW_EINVAL; - } - } - *valp = pop (); - Debug (14, "final value = 0x%lx\n", (unsigned long) *valp); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfde.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfde.c deleted file mode 100644 index 9250b895eabebd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfde.c +++ /dev/null @@ -1,359 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "dwarf_i.h" - -static inline int -is_cie_id (unw_word_t val, int is_debug_frame) -{ - /* The CIE ID is normally 0xffffffff (for 32-bit ELF) or - 0xffffffffffffffff (for 64-bit ELF). However, .eh_frame - uses 0. */ - if (is_debug_frame) - return (val == (uint32_t)(-1) || val == (uint64_t)(-1)); - else - return (val == 0); -} - -/* Note: we don't need to keep track of more than the first four - characters of the augmentation string, because we (a) ignore any - augmentation string contents once we find an unrecognized character - and (b) those characters that we do recognize, can't be - repeated. */ -static inline int -parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr, - const unw_proc_info_t *pi, struct dwarf_cie_info *dci, - int is_debug_frame, void *arg) -{ - uint8_t version, ch, augstr[5], fde_encoding, handler_encoding; - unw_word_t len, cie_end_addr, aug_size; - uint32_t u32val; - uint64_t u64val; - size_t i; - int ret; -# define STR2(x) #x -# define STR(x) STR2(x) - - /* Pick appropriate default for FDE-encoding. DWARF spec says - start-IP (initial_location) and the code-size (address_range) are - "address-unit sized constants". The `R' augmentation can be used - to override this, but by default, we pick an address-sized unit - for fde_encoding. */ - switch (dwarf_addr_size (as)) - { - case 4: fde_encoding = DW_EH_PE_udata4; break; - case 8: fde_encoding = DW_EH_PE_udata8; break; - default: fde_encoding = DW_EH_PE_omit; break; - } - - dci->lsda_encoding = DW_EH_PE_omit; - dci->handler = 0; - - if ((ret = dwarf_readu32 (as, a, &addr, &u32val, arg)) < 0) - return ret; - - if (u32val != 0xffffffff) - { - /* the CIE is in the 32-bit DWARF format */ - uint32_t cie_id; - /* DWARF says CIE id should be 0xffffffff, but in .eh_frame, it's 0 */ - const uint32_t expected_id = (is_debug_frame) ? 0xffffffff : 0; - - len = u32val; - cie_end_addr = addr + len; - if ((ret = dwarf_readu32 (as, a, &addr, &cie_id, arg)) < 0) - return ret; - if (cie_id != expected_id) - { - Debug (1, "Unexpected CIE id %x\n", cie_id); - return -UNW_EINVAL; - } - } - else - { - /* the CIE is in the 64-bit DWARF format */ - uint64_t cie_id; - /* DWARF says CIE id should be 0xffffffffffffffff, but in - .eh_frame, it's 0 */ - const uint64_t expected_id = (is_debug_frame) ? 0xffffffffffffffffull : 0; - - if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0) - return ret; - len = u64val; - cie_end_addr = addr + len; - if ((ret = dwarf_readu64 (as, a, &addr, &cie_id, arg)) < 0) - return ret; - if (cie_id != expected_id) - { - Debug (1, "Unexpected CIE id %llx\n", (long long) cie_id); - return -UNW_EINVAL; - } - } - dci->cie_instr_end = cie_end_addr; - - if ((ret = dwarf_readu8 (as, a, &addr, &version, arg)) < 0) - return ret; - - /* GCC emits version 1??? */ - if (version != 1 && (version < DWARF_CIE_VERSION || version > DWARF_CIE_VERSION_MAX)) - { - Debug (1, "Got CIE version %u, expected version 1 or between " - STR (DWARF_CIE_VERSION) " and " STR (DWARF_CIE_VERSION_MAX) "\n", version); - return -UNW_EBADVERSION; - } - - /* read and parse the augmentation string: */ - memset (augstr, 0, sizeof (augstr)); - for (i = 0;;) - { - if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) - return ret; - - if (!ch) - break; /* end of augmentation string */ - - if (i < sizeof (augstr) - 1) - augstr[i++] = ch; - } - - if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->code_align, arg)) < 0 - || (ret = dwarf_read_sleb128 (as, a, &addr, &dci->data_align, arg)) < 0) - return ret; - - /* Read the return-address column either as a u8 or as a uleb128. */ - if (version == 1) - { - if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) - return ret; - dci->ret_addr_column = ch; - } - else if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->ret_addr_column, - arg)) < 0) - return ret; - - i = 0; - if (augstr[0] == 'z') - { - dci->sized_augmentation = 1; - if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0) - return ret; - i++; - } - - for (; i < sizeof (augstr) && augstr[i]; ++i) - switch (augstr[i]) - { - case 'L': - /* read the LSDA pointer-encoding format. */ - if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) - return ret; - dci->lsda_encoding = ch; - break; - - case 'R': - /* read the FDE pointer-encoding format. */ - if ((ret = dwarf_readu8 (as, a, &addr, &fde_encoding, arg)) < 0) - return ret; - break; - - case 'P': - /* read the personality-routine pointer-encoding format. */ - if ((ret = dwarf_readu8 (as, a, &addr, &handler_encoding, arg)) < 0) - return ret; - if ((ret = dwarf_read_encoded_pointer (as, a, &addr, handler_encoding, - pi, &dci->handler, arg)) < 0) - return ret; - break; - - case 'S': - /* This is a signal frame. */ - dci->signal_frame = 1; - - /* Temporarily set it to one so dwarf_parse_fde() knows that - it should fetch the actual ABI/TAG pair from the FDE. */ - dci->have_abi_marker = 1; - break; - - default: - Debug (1, "Unexpected augmentation string `%s'\n", augstr); - if (dci->sized_augmentation) - /* If we have the size of the augmentation body, we can skip - over the parts that we don't understand, so we're OK. */ - goto done; - else - return -UNW_EINVAL; - } - done: - dci->fde_encoding = fde_encoding; - dci->cie_instr_start = addr; - Debug (15, "CIE parsed OK, augmentation = \"%s\", handler=0x%lx\n", - augstr, (long) dci->handler); - return 0; -} - -/* Extract proc-info from the FDE starting at adress ADDR. - - Pass BASE as zero for eh_frame behaviour, or a pointer to - debug_frame base for debug_frame behaviour. */ - -HIDDEN int -dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addrp, unw_proc_info_t *pi, - unw_word_t base, - int need_unwind_info, int is_debug_frame, - void *arg) -{ - unw_word_t fde_end_addr, cie_addr, cie_offset_addr, aug_end_addr = 0; - unw_word_t start_ip, ip_range, aug_size, addr = *addrp; - int ret, ip_range_encoding; - struct dwarf_cie_info dci; - uint64_t u64val; - uint32_t u32val; - - Debug (12, "FDE @ 0x%lx\n", (long) addr); - - memset (&dci, 0, sizeof (dci)); - - if ((ret = dwarf_readu32 (as, a, &addr, &u32val, arg)) < 0) - return ret; - - if (u32val != 0xffffffff) - { - int32_t cie_offset = 0; - - /* In some configurations, an FDE with a 0 length indicates the - end of the FDE-table. */ - if (u32val == 0) - return -UNW_ENOINFO; - - /* the FDE is in the 32-bit DWARF format */ - - *addrp = fde_end_addr = addr + u32val; - cie_offset_addr = addr; - - if ((ret = dwarf_reads32 (as, a, &addr, &cie_offset, arg)) < 0) - return ret; - - if (is_cie_id (cie_offset, is_debug_frame)) - /* ignore CIEs (happens during linear searches) */ - return 0; - - if (is_debug_frame) - cie_addr = base + cie_offset; - else - /* DWARF says that the CIE_pointer in the FDE is a - .debug_frame-relative offset, but the GCC-generated .eh_frame - sections instead store a "pcrelative" offset, which is just - as fine as it's self-contained. */ - cie_addr = cie_offset_addr - cie_offset; - } - else - { - int64_t cie_offset = 0; - - /* the FDE is in the 64-bit DWARF format */ - - if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0) - return ret; - - *addrp = fde_end_addr = addr + u64val; - cie_offset_addr = addr; - - if ((ret = dwarf_reads64 (as, a, &addr, &cie_offset, arg)) < 0) - return ret; - - if (is_cie_id (cie_offset, is_debug_frame)) - /* ignore CIEs (happens during linear searches) */ - return 0; - - if (is_debug_frame) - cie_addr = base + cie_offset; - else - /* DWARF says that the CIE_pointer in the FDE is a - .debug_frame-relative offset, but the GCC-generated .eh_frame - sections instead store a "pcrelative" offset, which is just - as fine as it's self-contained. */ - cie_addr = (unw_word_t) ((uint64_t) cie_offset_addr - cie_offset); - } - - Debug (15, "looking for CIE at address %lx\n", (long) cie_addr); - - if ((ret = parse_cie (as, a, cie_addr, pi, &dci, is_debug_frame, arg)) < 0) - return ret; - - /* IP-range has same encoding as FDE pointers, except that it's - always an absolute value: */ - ip_range_encoding = dci.fde_encoding & DW_EH_PE_FORMAT_MASK; - - if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.fde_encoding, - pi, &start_ip, arg)) < 0 - || (ret = dwarf_read_encoded_pointer (as, a, &addr, ip_range_encoding, - pi, &ip_range, arg)) < 0) - return ret; - pi->start_ip = start_ip; - pi->end_ip = start_ip + ip_range; - pi->handler = dci.handler; - - if (dci.sized_augmentation) - { - if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0) - return ret; - aug_end_addr = addr + aug_size; - } - - if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.lsda_encoding, - pi, &pi->lsda, arg)) < 0) - return ret; - - Debug (15, "FDE covers IP 0x%lx-0x%lx, LSDA=0x%lx\n", - (long) pi->start_ip, (long) pi->end_ip, (long) pi->lsda); - - if (need_unwind_info) - { - pi->format = UNW_INFO_FORMAT_TABLE; - pi->unwind_info_size = sizeof (dci); - pi->unwind_info = mempool_alloc (&dwarf_cie_info_pool); - if (!pi->unwind_info) - return -UNW_ENOMEM; - - if (dci.have_abi_marker) - { - if ((ret = dwarf_readu16 (as, a, &addr, &dci.abi, arg)) < 0 - || (ret = dwarf_readu16 (as, a, &addr, &dci.tag, arg)) < 0) - return ret; - Debug (13, "Found ABI marker = (abi=%u, tag=%u)\n", - dci.abi, dci.tag); - } - - if (dci.sized_augmentation) - dci.fde_instr_start = aug_end_addr; - else - dci.fde_instr_start = addr; - dci.fde_instr_end = fde_end_addr; - - memcpy (pi->unwind_info, &dci, sizeof (dci)); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c deleted file mode 100644 index 509ceff47cbe38..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c +++ /dev/null @@ -1,935 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -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. */ - -/* Locate an FDE via the ELF data-structures defined by LSB v1.3 - (http://www.linuxbase.org/spec/). */ - -#include -#include -#include - -#include "dwarf_i.h" -#include "dwarf-eh.h" -#include "libunwind_i.h" - -struct table_entry - { - int32_t start_ip_offset; - int32_t fde_offset; - }; - -#ifndef UNW_REMOTE_ONLY - -#ifdef __linux -#include "os-linux.h" -#endif - -static ALIAS(dwarf_search_unwind_table) int -dwarf_search_unwind_table_int (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); -static int -linear_search (unw_addr_space_t as, unw_word_t ip, - unw_word_t eh_frame_start, unw_word_t eh_frame_end, - unw_word_t fde_count, - unw_proc_info_t *pi, int need_unwind_info, void *arg) -{ - unw_accessors_t *a = unw_get_accessors_int (unw_local_addr_space); - unw_word_t i = 0, fde_addr, addr = eh_frame_start; - int ret; - - while (i++ < fde_count && addr < eh_frame_end) - { - fde_addr = addr; - if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, - eh_frame_start, - 0, 0, arg)) < 0) - return ret; - - if (ip >= pi->start_ip && ip < pi->end_ip) - { - if (!need_unwind_info) - return 1; - addr = fde_addr; - if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, - eh_frame_start, - need_unwind_info, 0, - arg)) - < 0) - return ret; - return 1; - } - } - return -UNW_ENOINFO; -} -#endif /* !UNW_REMOTE_ONLY */ - -#ifdef CONFIG_DEBUG_FRAME -/* Load .debug_frame section from FILE. Allocates and returns space - in *BUF, and sets *BUFSIZE to its size. IS_LOCAL is 1 if using the - local process, in which case we can search the system debug file - directory; 0 for other address spaces, in which case we do - not. Returns 0 on success, 1 on error. Succeeds even if the file - contains no .debug_frame. */ -/* XXX: Could use mmap; but elf_map_image keeps tons mapped in. */ - -static int -load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local) -{ - struct elf_image ei; - Elf_W (Shdr) *shdr; - int ret; - - ei.image = NULL; - - ret = elf_w (load_debuglink) (file, &ei, is_local); - if (ret != 0) - return ret; - - shdr = elf_w (find_section) (&ei, ".debug_frame"); - if (!shdr || - (shdr->sh_offset + shdr->sh_size > ei.size)) - { - munmap(ei.image, ei.size); - return 1; - } - - *bufsize = shdr->sh_size; - *buf = malloc (*bufsize); - - memcpy(*buf, shdr->sh_offset + ei.image, *bufsize); - - Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", - *bufsize, shdr->sh_offset); - - munmap(ei.image, ei.size); - return 0; -} - -/* Locate the binary which originated the contents of address ADDR. Return - the name of the binary in *name (space is allocated by the caller) - Returns 0 if a binary is successfully found, or 1 if an error occurs. */ - -static int -find_binary_for_address (unw_word_t ip, char *name, size_t name_size) -{ -#if defined(__linux) && (!UNW_REMOTE_ONLY) - struct map_iterator mi; - int found = 0; - int pid = getpid (); - unsigned long segbase, mapoff, hi; - - if (maps_init (&mi, pid) != 0) - return 1; - - while (maps_next (&mi, &segbase, &hi, &mapoff)) - if (ip >= segbase && ip < hi) - { - size_t len = strlen (mi.path); - - if (len + 1 <= name_size) - { - memcpy (name, mi.path, len + 1); - found = 1; - } - break; - } - maps_close (&mi); - return !found; -#endif - - return 1; -} - -/* Locate and/or try to load a debug_frame section for address ADDR. Return - pointer to debug frame descriptor, or zero if not found. */ - -static struct unw_debug_frame_list * -locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, - unw_word_t start, unw_word_t end) -{ - struct unw_debug_frame_list *w, *fdesc = 0; - char path[PATH_MAX]; - char *name = path; - int err; - char *buf; - size_t bufsize; - - /* First, see if we loaded this frame already. */ - - for (w = as->debug_frames; w; w = w->next) - { - Debug (4, "checking %p: %lx-%lx\n", w, (long)w->start, (long)w->end); - if (addr >= w->start && addr < w->end) - return w; - } - - /* If the object name we receive is blank, there's still a chance of locating - the file by parsing /proc/self/maps. */ - - if (strcmp (dlname, "") == 0) - { - err = find_binary_for_address (addr, name, sizeof(path)); - if (err) - { - Debug (15, "tried to locate binary for 0x%" PRIx64 ", but no luck\n", - (uint64_t) addr); - return 0; - } - } - else - name = (char*) dlname; - - err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space); - - if (!err) - { - fdesc = malloc (sizeof (struct unw_debug_frame_list)); - - fdesc->start = start; - fdesc->end = end; - fdesc->debug_frame = buf; - fdesc->debug_frame_size = bufsize; - fdesc->index = NULL; - fdesc->next = as->debug_frames; - - as->debug_frames = fdesc; - } - - return fdesc; -} - -struct debug_frame_tab - { - struct table_entry *tab; - uint32_t length; - uint32_t size; - }; - -static void -debug_frame_tab_append (struct debug_frame_tab *tab, - unw_word_t fde_offset, unw_word_t start_ip) -{ - unsigned int length = tab->length; - - if (length == tab->size) - { - tab->size *= 2; - tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->size); - } - - tab->tab[length].fde_offset = fde_offset; - tab->tab[length].start_ip_offset = start_ip; - - tab->length = length + 1; -} - -static void -debug_frame_tab_shrink (struct debug_frame_tab *tab) -{ - if (tab->size > tab->length) - { - tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->length); - tab->size = tab->length; - } -} - -static int -debug_frame_tab_compare (const void *a, const void *b) -{ - const struct table_entry *fa = a, *fb = b; - - if (fa->start_ip_offset > fb->start_ip_offset) - return 1; - else if (fa->start_ip_offset < fb->start_ip_offset) - return -1; - else - return 0; -} - -HIDDEN 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) -{ - unw_dyn_info_t *di; - struct unw_debug_frame_list *fdesc = 0; - unw_accessors_t *a; - unw_word_t addr; - - Debug (15, "Trying to find .debug_frame for %s\n", obj_name); - di = di_debug; - - fdesc = locate_debug_info (unw_local_addr_space, ip, obj_name, start, end); - - if (!fdesc) - { - Debug (15, "couldn't load .debug_frame\n"); - return found; - } - else - { - char *buf; - size_t bufsize; - unw_word_t item_start, item_end = 0; - uint32_t u32val = 0; - uint64_t cie_id = 0; - struct debug_frame_tab tab; - - Debug (15, "loaded .debug_frame\n"); - - buf = fdesc->debug_frame; - bufsize = fdesc->debug_frame_size; - - if (bufsize == 0) - { - Debug (15, "zero-length .debug_frame\n"); - return found; - } - - /* Now create a binary-search table, if it does not already exist. */ - if (!fdesc->index) - { - addr = (unw_word_t) (uintptr_t) buf; - - a = unw_get_accessors_int (unw_local_addr_space); - - /* Find all FDE entries in debug_frame, and make into a sorted - index. */ - - tab.length = 0; - tab.size = 16; - tab.tab = calloc (tab.size, sizeof (struct table_entry)); - - while (addr < (unw_word_t) (uintptr_t) (buf + bufsize)) - { - uint64_t id_for_cie; - item_start = addr; - - dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL); - - if (u32val == 0) - break; - else if (u32val != 0xffffffff) - { - uint32_t cie_id32 = 0; - item_end = addr + u32val; - dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32, - NULL); - cie_id = cie_id32; - id_for_cie = 0xffffffff; - } - else - { - uint64_t u64val = 0; - /* Extended length. */ - dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL); - item_end = addr + u64val; - - dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL); - id_for_cie = 0xffffffffffffffffull; - } - - /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/ - - if (cie_id == id_for_cie) - ; - /*Debug (1, "Found CIE at %.8x.\n", item_start);*/ - else - { - unw_word_t fde_addr = item_start; - unw_proc_info_t this_pi; - int err; - - /*Debug (1, "Found FDE at %.8x\n", item_start);*/ - - err = dwarf_extract_proc_info_from_fde (unw_local_addr_space, - a, &fde_addr, - &this_pi, - (uintptr_t) buf, 0, 1, - NULL); - if (err == 0) - { - Debug (15, "start_ip = %lx, end_ip = %lx\n", - (long) this_pi.start_ip, (long) this_pi.end_ip); - debug_frame_tab_append (&tab, - item_start - (unw_word_t) (uintptr_t) buf, - this_pi.start_ip); - } - /*else - Debug (1, "FDE parse failed\n");*/ - } - - addr = item_end; - } - - debug_frame_tab_shrink (&tab); - qsort (tab.tab, tab.length, sizeof (struct table_entry), - debug_frame_tab_compare); - /* for (i = 0; i < tab.length; i++) - { - fprintf (stderr, "ip %x, fde offset %x\n", - (int) tab.tab[i].start_ip_offset, - (int) tab.tab[i].fde_offset); - }*/ - fdesc->index = tab.tab; - fdesc->index_size = tab.length; - } - - di->format = UNW_INFO_FORMAT_TABLE; - di->start_ip = fdesc->start; - di->end_ip = fdesc->end; - di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name; - di->u.ti.table_data = (unw_word_t *) fdesc; - di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t); - di->u.ti.segbase = segbase; - - found = 1; - Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, " - "gp=0x%lx, table_data=0x%lx\n", - (char *) (uintptr_t) di->u.ti.name_ptr, - (long) di->u.ti.segbase, (long) di->u.ti.table_len, - (long) di->gp, (long) di->u.ti.table_data); - } - return found; -} - -#endif /* CONFIG_DEBUG_FRAME */ - -#ifndef UNW_REMOTE_ONLY - -static Elf_W (Addr) -dwarf_find_eh_frame_section(struct dl_phdr_info *info) -{ - int rc; - struct elf_image ei; - Elf_W (Addr) eh_frame = 0; - Elf_W (Shdr)* shdr; - const char *file = info->dlpi_name; - char exepath[PATH_MAX]; - - if (strlen(file) == 0) - { - tdep_get_exe_image_path(exepath); - file = exepath; - } - - Debug (1, "looking for .eh_frame section in %s\n", - file); - - rc = elf_map_image (&ei, file); - if (rc != 0) - return 0; - - shdr = elf_w (find_section) (&ei, ".eh_frame"); - if (!shdr) - goto out; - - eh_frame = shdr->sh_addr + info->dlpi_addr; - Debug (4, "found .eh_frame at address %lx\n", - eh_frame); - -out: - munmap (ei.image, ei.size); - - return eh_frame; -} - -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 */ - }; - -/* ptr is a pointer to a dwarf_callback_data structure and, on entry, - member ip contains the instruction-pointer we're looking - for. */ -HIDDEN int -dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) -{ - struct dwarf_callback_data *cb_data = ptr; - unw_dyn_info_t *di = &cb_data->di; - const Elf_W(Phdr) *phdr, *p_eh_hdr, *p_dynamic, *p_text; - unw_word_t addr, eh_frame_start, eh_frame_end, fde_count, ip; - Elf_W(Addr) load_base, max_load_addr = 0; - int ret, need_unwind_info = cb_data->need_unwind_info; - unw_proc_info_t *pi = cb_data->pi; - struct dwarf_eh_frame_hdr *hdr = NULL; - unw_accessors_t *a; - long n; - int found = 0; - struct dwarf_eh_frame_hdr synth_eh_frame_hdr; -#ifdef CONFIG_DEBUG_FRAME - unw_word_t start, end; -#endif /* CONFIG_DEBUG_FRAME*/ - - ip = cb_data->ip; - - /* Make sure struct dl_phdr_info is at least as big as we need. */ - if (size < offsetof (struct dl_phdr_info, dlpi_phnum) - + sizeof (info->dlpi_phnum)) - return -1; - - Debug (15, "checking %s, base=0x%lx)\n", - info->dlpi_name, (long) info->dlpi_addr); - - phdr = info->dlpi_phdr; - load_base = info->dlpi_addr; - p_text = NULL; - p_eh_hdr = NULL; - p_dynamic = NULL; - - /* See if PC falls into one of the loaded segments. Find the - eh-header segment at the same time. */ - for (n = info->dlpi_phnum; --n >= 0; phdr++) - { - if (phdr->p_type == PT_LOAD) - { - Elf_W(Addr) vaddr = phdr->p_vaddr + load_base; - - if (ip >= vaddr && ip < vaddr + phdr->p_memsz) - p_text = phdr; - - if (vaddr + phdr->p_filesz > max_load_addr) - max_load_addr = vaddr + phdr->p_filesz; - } - else if (phdr->p_type == PT_GNU_EH_FRAME) - p_eh_hdr = phdr; - else if (phdr->p_type == PT_DYNAMIC) - p_dynamic = phdr; - } - - if (!p_text) - return 0; - - if (p_eh_hdr) - { - hdr = (struct dwarf_eh_frame_hdr *) (p_eh_hdr->p_vaddr + load_base); - } - else - { - Elf_W (Addr) eh_frame; - Debug (1, "no .eh_frame_hdr section found\n"); - eh_frame = dwarf_find_eh_frame_section (info); - if (eh_frame) - { - Debug (1, "using synthetic .eh_frame_hdr section for %s\n", - info->dlpi_name); - synth_eh_frame_hdr.version = DW_EH_VERSION; - synth_eh_frame_hdr.eh_frame_ptr_enc = DW_EH_PE_absptr | - ((sizeof(Elf_W (Addr)) == 4) ? DW_EH_PE_udata4 : DW_EH_PE_udata8); - synth_eh_frame_hdr.fde_count_enc = DW_EH_PE_omit; - synth_eh_frame_hdr.table_enc = DW_EH_PE_omit; - synth_eh_frame_hdr.eh_frame = eh_frame; - hdr = &synth_eh_frame_hdr; - } - } - - if (hdr) - { - if (p_dynamic) - { - /* For dynamicly linked executables and shared libraries, - DT_PLTGOT is the value that data-relative addresses are - relative to for that object. We call this the "gp". */ - Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(p_dynamic->p_vaddr + load_base); - for (; dyn->d_tag != DT_NULL; ++dyn) - if (dyn->d_tag == DT_PLTGOT) - { - /* Assume that _DYNAMIC is writable and GLIBC has - relocated it (true for x86 at least). */ - di->gp = dyn->d_un.d_ptr; - break; - } - } - else - /* Otherwise this is a static executable with no _DYNAMIC. Assume - that data-relative addresses are relative to 0, i.e., - absolute. */ - di->gp = 0; - pi->gp = di->gp; - - if (hdr->version != DW_EH_VERSION) - { - Debug (1, "table `%s' has unexpected version %d\n", - info->dlpi_name, hdr->version); - return 0; - } - - a = unw_get_accessors_int (unw_local_addr_space); - addr = (unw_word_t) (uintptr_t) (&hdr->eh_frame); - - /* (Optionally) read eh_frame_ptr: */ - if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, - &addr, hdr->eh_frame_ptr_enc, pi, - &eh_frame_start, NULL)) < 0) - return ret; - - /* (Optionally) read fde_count: */ - if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, - &addr, hdr->fde_count_enc, pi, - &fde_count, NULL)) < 0) - return ret; - - if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) - { - /* If there is no search table or it has an unsupported - encoding, fall back on linear search. */ - if (hdr->table_enc == DW_EH_PE_omit) - Debug (4, "table `%s' lacks search table; doing linear search\n", - info->dlpi_name); - else - Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", - info->dlpi_name, hdr->table_enc); - - eh_frame_end = max_load_addr; /* XXX can we do better? */ - - if (hdr->fde_count_enc == DW_EH_PE_omit) - fde_count = ~0UL; - if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) - abort (); - - Debug (1, "eh_frame_start = %lx eh_frame_end = %lx\n", - eh_frame_start, eh_frame_end); - - /* XXX we know how to build a local binary search table for - .debug_frame, so we could do that here too. */ - found = linear_search (unw_local_addr_space, ip, - eh_frame_start, eh_frame_end, fde_count, - pi, need_unwind_info, NULL); - if (found != 1) - found = 0; - else - cb_data->single_fde = 1; - } - else - { - di->format = UNW_INFO_FORMAT_REMOTE_TABLE; - di->start_ip = p_text->p_vaddr + load_base; - di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz; - di->u.rti.name_ptr = (unw_word_t) (uintptr_t) info->dlpi_name; - di->u.rti.table_data = addr; - assert (sizeof (struct table_entry) % sizeof (unw_word_t) == 0); - di->u.rti.table_len = (fde_count * sizeof (struct table_entry) - / sizeof (unw_word_t)); - /* For the binary-search table in the eh_frame_hdr, data-relative - means relative to the start of that section... */ - di->u.rti.segbase = (unw_word_t) (uintptr_t) hdr; - - found = 1; - Debug (15, "found table `%s': segbase=0x%lx, len=%lu, gp=0x%lx, " - "table_data=0x%lx\n", (char *) (uintptr_t) di->u.rti.name_ptr, - (long) di->u.rti.segbase, (long) di->u.rti.table_len, - (long) di->gp, (long) di->u.rti.table_data); - } - } - -#ifdef CONFIG_DEBUG_FRAME - /* Find the start/end of the described region by parsing the phdr_info - structure. */ - start = (unw_word_t) -1; - end = 0; - - for (n = 0; n < info->dlpi_phnum; n++) - { - if (info->dlpi_phdr[n].p_type == PT_LOAD) - { - unw_word_t seg_start = info->dlpi_addr + info->dlpi_phdr[n].p_vaddr; - unw_word_t seg_end = seg_start + info->dlpi_phdr[n].p_memsz; - - if (seg_start < start) - start = seg_start; - - if (seg_end > end) - end = seg_end; - } - } - - found = dwarf_find_debug_frame (found, &cb_data->di_debug, ip, - info->dlpi_addr, info->dlpi_name, start, - end); -#endif /* CONFIG_DEBUG_FRAME */ - - return found; -} - -HIDDEN 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) -{ - struct dwarf_callback_data cb_data; - intrmask_t saved_mask; - int ret; - - Debug (14, "looking for IP=0x%lx\n", (long) ip); - - memset (&cb_data, 0, sizeof (cb_data)); - cb_data.ip = ip; - cb_data.pi = pi; - cb_data.need_unwind_info = need_unwind_info; - cb_data.di.format = -1; - cb_data.di_debug.format = -1; - - SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); - ret = dl_iterate_phdr (dwarf_callback, &cb_data); - SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); - - if (ret > 0) - { - if (cb_data.single_fde) - /* already got the result in *pi */ - return 0; - - /* search the table: */ - if (cb_data.di.format != -1) - ret = dwarf_search_unwind_table_int (as, ip, &cb_data.di, - pi, need_unwind_info, arg); - else - ret = -UNW_ENOINFO; - - if (ret == -UNW_ENOINFO && cb_data.di_debug.format != -1) - ret = dwarf_search_unwind_table_int (as, ip, &cb_data.di_debug, pi, - need_unwind_info, arg); - } - else - ret = -UNW_ENOINFO; - - return ret; -} - -static inline const struct table_entry * -lookup (const struct table_entry *table, size_t table_size, int32_t rel_ip) -{ - unsigned long table_len = table_size / sizeof (struct table_entry); - const struct table_entry *e = NULL; - unsigned long lo, hi, mid; - - /* do a binary search for right entry: */ - for (lo = 0, hi = table_len; lo < hi;) - { - mid = (lo + hi) / 2; - e = table + mid; - Debug (15, "e->start_ip_offset = %lx\n", (long) e->start_ip_offset); - if (rel_ip < e->start_ip_offset) - hi = mid; - else - lo = mid + 1; - } - if (hi <= 0) - return NULL; - e = table + hi - 1; - return e; -} - -#endif /* !UNW_REMOTE_ONLY */ - -#ifndef UNW_LOCAL_ONLY - -/* Lookup an unwind-table entry in remote memory. Returns 1 if an - entry is found, 0 if no entry is found, negative if an error - occurred reading remote memory. */ -static int -remote_lookup (unw_addr_space_t as, - unw_word_t table, size_t table_size, int32_t rel_ip, - struct table_entry *e, int32_t *last_ip_offset, void *arg) -{ - unsigned long table_len = table_size / sizeof (struct table_entry); - unw_accessors_t *a = unw_get_accessors_int (as); - unsigned long lo, hi, mid; - unw_word_t e_addr = 0; - int32_t start = 0; - int ret; - - /* do a binary search for right entry: */ - for (lo = 0, hi = table_len; lo < hi;) - { - mid = (lo + hi) / 2; - e_addr = table + mid * sizeof (struct table_entry); - if ((ret = dwarf_reads32 (as, a, &e_addr, &start, arg)) < 0) - return ret; - - if (rel_ip < start) - hi = mid; - else - lo = mid + 1; - } - if (hi <= 0) - return 0; - e_addr = table + (hi - 1) * sizeof (struct table_entry); - if ((ret = dwarf_reads32 (as, a, &e_addr, &e->start_ip_offset, arg)) < 0 - || (ret = dwarf_reads32 (as, a, &e_addr, &e->fde_offset, arg)) < 0 - || (hi < table_len && - (ret = dwarf_reads32 (as, a, &e_addr, last_ip_offset, arg)) < 0)) - return ret; - return 1; -} - -#endif /* !UNW_LOCAL_ONLY */ - -static int is_remote_table(int format) -{ - return (format == UNW_INFO_FORMAT_REMOTE_TABLE || - format == UNW_INFO_FORMAT_IP_OFFSET); -} - -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) -{ - const struct table_entry *e = NULL, *table; - unw_word_t ip_base = 0, segbase = 0, last_ip, fde_addr; - unw_accessors_t *a; -#ifndef UNW_LOCAL_ONLY - struct table_entry ent; -#endif - int ret; - unw_word_t debug_frame_base; - size_t table_len; - -#ifdef UNW_REMOTE_ONLY - assert (is_remote_table(di->format)); -#else - assert (is_remote_table(di->format) - || di->format == UNW_INFO_FORMAT_TABLE); -#endif - assert (ip >= di->start_ip && ip < di->end_ip); - - if (is_remote_table(di->format)) - { - table = (const struct table_entry *) (uintptr_t) di->u.rti.table_data; - table_len = di->u.rti.table_len * sizeof (unw_word_t); - debug_frame_base = 0; - } - else - { - assert(di->format == UNW_INFO_FORMAT_TABLE); -#ifndef UNW_REMOTE_ONLY - struct unw_debug_frame_list *fdesc = (void *) di->u.ti.table_data; - - /* UNW_INFO_FORMAT_TABLE (i.e. .debug_frame) is read from local address - space. Both the index and the unwind tables live in local memory, but - the address space to check for properties like the address size and - endianness is the target one. */ - as = unw_local_addr_space; - table = fdesc->index; - table_len = fdesc->index_size * sizeof (struct table_entry); - debug_frame_base = (uintptr_t) fdesc->debug_frame; -#endif - } - - a = unw_get_accessors_int (as); - - segbase = di->u.rti.segbase; - if (di->format == UNW_INFO_FORMAT_IP_OFFSET) { - ip_base = di->start_ip; - } else { - ip_base = segbase; - } - -#ifndef UNW_REMOTE_ONLY - if (as == unw_local_addr_space) - { - e = lookup (table, table_len, ip - ip_base); - if (e && &e[1] < &table[table_len]) - last_ip = e[1].start_ip_offset + ip_base; - else - last_ip = di->end_ip; - } - else -#endif - { -#ifndef UNW_LOCAL_ONLY - int32_t last_ip_offset = di->end_ip - ip_base; - segbase = di->u.rti.segbase; - if ((ret = remote_lookup (as, (uintptr_t) table, table_len, - ip - ip_base, &ent, &last_ip_offset, arg)) < 0) - return ret; - if (ret) - { - e = &ent; - last_ip = last_ip_offset + ip_base; - } - else - e = NULL; /* no info found */ -#endif - } - if (!e) - { - Debug (1, "IP %lx inside range %lx-%lx, but no explicit unwind info found\n", - (long) ip, (long) di->start_ip, (long) di->end_ip); - /* IP is inside this table's range, but there is no explicit - unwind info. */ - return -UNW_ENOINFO; - } - Debug (15, "ip=0x%lx, start_ip=0x%lx\n", - (long) ip, (long) (e->start_ip_offset)); - if (debug_frame_base) - fde_addr = e->fde_offset + debug_frame_base; - else - fde_addr = e->fde_offset + segbase; - Debug (1, "e->fde_offset = %lx, segbase = %lx, debug_frame_base = %lx, " - "fde_addr = %lx\n", (long) e->fde_offset, (long) segbase, - (long) debug_frame_base, (long) fde_addr); - if ((ret = dwarf_extract_proc_info_from_fde (as, a, &fde_addr, pi, - debug_frame_base ? - debug_frame_base : segbase, - need_unwind_info, - debug_frame_base != 0, arg)) < 0) - return ret; - - /* .debug_frame uses an absolute encoding that does not know about any - shared library relocation. */ - if (di->format == UNW_INFO_FORMAT_TABLE) - { - pi->start_ip += segbase; - pi->end_ip += segbase; - pi->flags = UNW_PI_FLAG_DEBUG_FRAME; - } - -#if defined(NEED_LAST_IP) - pi->last_ip = last_ip; -#else - (void)last_ip; -#endif - if (ip < pi->start_ip || ip >= pi->end_ip) - return -UNW_ENOINFO; - - return 0; -} - -HIDDEN void -dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) -{ - return; /* always a nop */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c deleted file mode 100644 index 6a2ad504078af2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c +++ /dev/null @@ -1,230 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include - -#include - -#include "libunwind_i.h" -#include "dwarf-eh.h" -#include "dwarf_i.h" - -#define to_unw_word(p) ((unw_word_t) (uintptr_t) (p)) - -int -dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, - char *path, unw_word_t segbase, unw_word_t mapoff, - unw_word_t ip) -{ - Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL; - unw_word_t addr, eh_frame_start, fde_count, load_base; - unw_word_t max_load_addr = 0; - unw_word_t start_ip = to_unw_word (-1); - unw_word_t end_ip = 0; - struct dwarf_eh_frame_hdr *hdr; - unw_proc_info_t pi; - unw_accessors_t *a; - Elf_W(Ehdr) *ehdr; -#if UNW_TARGET_ARM - const Elf_W(Phdr) *parm_exidx = NULL; -#endif - int i, ret, found = 0; - - /* XXX: Much of this code is Linux/LSB-specific. */ - - if (!elf_w(valid_object) (&edi->ei)) - return -UNW_ENOINFO; - - ehdr = edi->ei.image; - phdr = (Elf_W(Phdr) *) ((char *) edi->ei.image + ehdr->e_phoff); - - for (i = 0; i < ehdr->e_phnum; ++i) - { - switch (phdr[i].p_type) - { - case PT_LOAD: - if (phdr[i].p_vaddr < start_ip) - start_ip = phdr[i].p_vaddr; - - if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip) - end_ip = phdr[i].p_vaddr + phdr[i].p_memsz; - - if (phdr[i].p_offset == mapoff) - ptxt = phdr + i; - if ((uintptr_t) edi->ei.image + phdr->p_filesz > max_load_addr) - max_load_addr = (uintptr_t) edi->ei.image + phdr->p_filesz; - break; - - case PT_GNU_EH_FRAME: - peh_hdr = phdr + i; - break; - - case PT_DYNAMIC: - pdyn = phdr + i; - break; - -#if UNW_TARGET_ARM - case PT_ARM_EXIDX: - parm_exidx = phdr + i; - break; -#endif - - default: - break; - } - } - - if (!ptxt) - return 0; - - load_base = segbase - ptxt->p_vaddr; - start_ip += load_base; - end_ip += load_base; - - if (peh_hdr) - { - if (pdyn) - { - /* For dynamicly linked executables and shared libraries, - DT_PLTGOT is the value that data-relative addresses are - relative to for that object. We call this the "gp". */ - Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset - + (char *) edi->ei.image); - for (; dyn->d_tag != DT_NULL; ++dyn) - if (dyn->d_tag == DT_PLTGOT) - { - /* Assume that _DYNAMIC is writable and GLIBC has - relocated it (true for x86 at least). */ - edi->di_cache.gp = dyn->d_un.d_ptr; - break; - } - } - else - /* Otherwise this is a static executable with no _DYNAMIC. Assume - that data-relative addresses are relative to 0, i.e., - absolute. */ - edi->di_cache.gp = 0; - - hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset - + (char *) edi->ei.image); - if (hdr->version != DW_EH_VERSION) - { - Debug (1, "table `%s' has unexpected version %d\n", - path, hdr->version); - return -UNW_ENOINFO; - } - - a = unw_get_accessors_int (unw_local_addr_space); - addr = to_unw_word (&hdr->eh_frame); - - /* Fill in a dummy proc_info structure. We just need to fill in - enough to ensure that dwarf_read_encoded_pointer() can do it's - job. Since we don't have a procedure-context at this point, all - we have to do is fill in the global-pointer. */ - memset (&pi, 0, sizeof (pi)); - pi.gp = edi->di_cache.gp; - - /* (Optionally) read eh_frame_ptr: */ - if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, - &addr, hdr->eh_frame_ptr_enc, &pi, - &eh_frame_start, NULL)) < 0) - return -UNW_ENOINFO; - - /* (Optionally) read fde_count: */ - if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, - &addr, hdr->fde_count_enc, &pi, - &fde_count, NULL)) < 0) - return -UNW_ENOINFO; - - if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) - { - #if 1 - abort (); - #else - unw_word_t eh_frame_end; - - /* If there is no search table or it has an unsupported - encoding, fall back on linear search. */ - if (hdr->table_enc == DW_EH_PE_omit) - Debug (4, "EH lacks search table; doing linear search\n"); - else - Debug (4, "EH table has encoding 0x%x; doing linear search\n", - hdr->table_enc); - - eh_frame_end = max_load_addr; /* XXX can we do better? */ - - if (hdr->fde_count_enc == DW_EH_PE_omit) - fde_count = ~0UL; - if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) - abort (); - - return linear_search (unw_local_addr_space, ip, - eh_frame_start, eh_frame_end, fde_count, - pi, need_unwind_info, NULL); - #endif - } - - edi->di_cache.start_ip = start_ip; - edi->di_cache.end_ip = end_ip; - edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE; - edi->di_cache.u.rti.name_ptr = 0; - /* two 32-bit values (ip_offset/fde_offset) per table-entry: */ - edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); - edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr) - + (addr - to_unw_word (edi->ei.image) - - peh_hdr->p_offset)); - - /* For the binary-search table in the eh_frame_hdr, data-relative - means relative to the start of that section... */ - edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr) - + (to_unw_word (hdr) - - to_unw_word (edi->ei.image) - - peh_hdr->p_offset)); - found = 1; - } - -#if UNW_TARGET_ARM - if (parm_exidx) - { - edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX; - edi->di_arm.start_ip = start_ip; - edi->di_arm.end_ip = end_ip; - edi->di_arm.u.rti.name_ptr = to_unw_word (path); - edi->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr; - edi->di_arm.u.rti.table_len = parm_exidx->p_memsz; - found = 1; - } -#endif - -#ifdef CONFIG_DEBUG_FRAME - /* Try .debug_frame. */ - found = dwarf_find_debug_frame (found, &edi->di_debug, ip, load_base, path, - start_ip, end_ip); -#endif - - return found; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c deleted file mode 100644 index 7d255aeeaf3c92..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c +++ /dev/null @@ -1,1059 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "dwarf_i.h" -#include "libunwind_i.h" -#include -#include - -#define alloc_reg_state() (mempool_alloc (&dwarf_reg_state_pool)) -#define free_reg_state(rs) (mempool_free (&dwarf_reg_state_pool, rs)) - -#define DWARF_UNW_CACHE_SIZE(log_size) (1 << log_size) -#define DWARF_UNW_HASH_SIZE(log_size) (1 << (log_size + 1)) - -static inline int -read_regnum (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, - unw_word_t *valp, void *arg) -{ - int ret; - - if ((ret = dwarf_read_uleb128 (as, a, addr, valp, arg)) < 0) - return ret; - - if (*valp >= DWARF_NUM_PRESERVED_REGS) - { - Debug (1, "Invalid register number %u\n", (unsigned int) *valp); - return -UNW_EBADREG; - } - return 0; -} - -static inline void -set_reg (dwarf_state_record_t *sr, unw_word_t regnum, dwarf_where_t where, - unw_word_t val) -{ - sr->rs_current.reg.where[regnum] = where; - sr->rs_current.reg.val[regnum] = val; -} - -static inline int -push_rstate_stack(dwarf_stackable_reg_state_t **rs_stack) -{ - dwarf_stackable_reg_state_t *old_rs = *rs_stack; - if (NULL == (*rs_stack = alloc_reg_state ())) - { - *rs_stack = old_rs; - return -1; - } - (*rs_stack)->next = old_rs; - return 0; -} - -static inline void -pop_rstate_stack(dwarf_stackable_reg_state_t **rs_stack) -{ - dwarf_stackable_reg_state_t *old_rs = *rs_stack; - *rs_stack = old_rs->next; - free_reg_state (old_rs); -} - -static inline void -empty_rstate_stack(dwarf_stackable_reg_state_t **rs_stack) -{ - while (*rs_stack) - pop_rstate_stack(rs_stack); -} - -/* Run a CFI program to update the register state. */ -static int -run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr, - unw_word_t *ip, unw_word_t end_ip, - unw_word_t *addr, unw_word_t end_addr, - dwarf_stackable_reg_state_t **rs_stack, - struct dwarf_cie_info *dci) -{ - unw_addr_space_t as; - void *arg; - - if (c->pi.flags & UNW_PI_FLAG_DEBUG_FRAME) - { - /* .debug_frame CFI is stored in local address space. */ - as = unw_local_addr_space; - arg = NULL; - } - else - { - as = c->as; - arg = c->as_arg; - } - unw_accessors_t *a = unw_get_accessors_int (as); - int ret = 0; - - while (*ip <= end_ip && *addr < end_addr && ret >= 0) - { - unw_word_t operand = 0, regnum, val, len; - uint8_t u8, op; - uint16_t u16; - uint32_t u32; - - if ((ret = dwarf_readu8 (as, a, addr, &op, arg)) < 0) - break; - - if (op & DWARF_CFA_OPCODE_MASK) - { - operand = op & DWARF_CFA_OPERAND_MASK; - op &= ~DWARF_CFA_OPERAND_MASK; - } - switch ((dwarf_cfa_t) op) - { - case DW_CFA_advance_loc: - *ip += operand * dci->code_align; - Debug (15, "CFA_advance_loc to 0x%lx\n", (long) *ip); - break; - - case DW_CFA_advance_loc1: - if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0) - break; - *ip += u8 * dci->code_align; - Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) *ip); - break; - - case DW_CFA_advance_loc2: - if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0) - break; - *ip += u16 * dci->code_align; - Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) *ip); - break; - - case DW_CFA_advance_loc4: - if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0) - break; - *ip += u32 * dci->code_align; - Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) *ip); - break; - - case DW_CFA_MIPS_advance_loc8: -#ifdef UNW_TARGET_MIPS - { - uint64_t u64 = 0; - - if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0) - break; - *ip += u64 * dci->code_align; - Debug (15, "CFA_MIPS_advance_loc8\n"); - break; - } -#else - Debug (1, "DW_CFA_MIPS_advance_loc8 on non-MIPS target\n"); - ret = -UNW_EINVAL; - break; -#endif - - case DW_CFA_offset: - regnum = operand; - if (regnum >= DWARF_NUM_PRESERVED_REGS) - { - Debug (1, "Invalid register number %u in DW_cfa_OFFSET\n", - (unsigned int) regnum); - ret = -UNW_EBADREG; - break; - } - if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) - break; - set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); - Debug (15, "CFA_offset r%lu at cfa+0x%lx\n", - (long) regnum, (long) (val * dci->data_align)); - break; - - case DW_CFA_offset_extended: - if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) - break; - set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); - Debug (15, "CFA_offset_extended r%lu at cf+0x%lx\n", - (long) regnum, (long) (val * dci->data_align)); - break; - - case DW_CFA_offset_extended_sf: - if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)) - break; - set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); - Debug (15, "CFA_offset_extended_sf r%lu at cf+0x%lx\n", - (long) regnum, (long) (val * dci->data_align)); - break; - - case DW_CFA_restore: - regnum = operand; - if (regnum >= DWARF_NUM_PRESERVED_REGS) - { - Debug (1, "Invalid register number %u in DW_CFA_restore\n", - (unsigned int) regnum); - ret = -UNW_EINVAL; - break; - } - sr->rs_current.reg.where[regnum] = sr->rs_initial.reg.where[regnum]; - sr->rs_current.reg.val[regnum] = sr->rs_initial.reg.val[regnum]; - Debug (15, "CFA_restore r%lu\n", (long) regnum); - break; - - case DW_CFA_restore_extended: - if ((ret = dwarf_read_uleb128 (as, a, addr, ®num, arg)) < 0) - break; - if (regnum >= DWARF_NUM_PRESERVED_REGS) - { - Debug (1, "Invalid register number %u in " - "DW_CFA_restore_extended\n", (unsigned int) regnum); - ret = -UNW_EINVAL; - break; - } - sr->rs_current.reg.where[regnum] = sr->rs_initial.reg.where[regnum]; - sr->rs_current.reg.val[regnum] = sr->rs_initial.reg.val[regnum]; - Debug (15, "CFA_restore_extended r%lu\n", (long) regnum); - break; - - case DW_CFA_nop: - break; - - case DW_CFA_set_loc: - if ((ret = dwarf_read_encoded_pointer (as, a, addr, dci->fde_encoding, - &c->pi, ip, - arg)) < 0) - break; - Debug (15, "CFA_set_loc to 0x%lx\n", (long) *ip); - break; - - case DW_CFA_undefined: - if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - break; - set_reg (sr, regnum, DWARF_WHERE_UNDEF, 0); - Debug (15, "CFA_undefined r%lu\n", (long) regnum); - break; - - case DW_CFA_same_value: - if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - break; - set_reg (sr, regnum, DWARF_WHERE_SAME, 0); - Debug (15, "CFA_same_value r%lu\n", (long) regnum); - break; - - case DW_CFA_register: - if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) - break; - set_reg (sr, regnum, DWARF_WHERE_REG, val); - Debug (15, "CFA_register r%lu to r%lu\n", (long) regnum, (long) val); - break; - - case DW_CFA_remember_state: - if (push_rstate_stack(rs_stack) < 0) - { - Debug (1, "Out of memory in DW_CFA_remember_state\n"); - ret = -UNW_ENOMEM; - break; - } - (*rs_stack)->state = sr->rs_current; - Debug (15, "CFA_remember_state\n"); - break; - - case DW_CFA_restore_state: - if (!*rs_stack) - { - Debug (1, "register-state stack underflow\n"); - ret = -UNW_EINVAL; - break; - } - sr->rs_current = (*rs_stack)->state; - pop_rstate_stack(rs_stack); - Debug (15, "CFA_restore_state\n"); - break; - - case DW_CFA_def_cfa: - if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) - break; - set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); - set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */ - Debug (15, "CFA_def_cfa r%lu+0x%lx\n", (long) regnum, (long) val); - break; - - case DW_CFA_def_cfa_sf: - if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)) - break; - set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); - set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, - val * dci->data_align); /* factored! */ - Debug (15, "CFA_def_cfa_sf r%lu+0x%lx\n", - (long) regnum, (long) (val * dci->data_align)); - break; - - case DW_CFA_def_cfa_register: - if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - break; - set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); - Debug (15, "CFA_def_cfa_register r%lu\n", (long) regnum); - break; - - case DW_CFA_def_cfa_offset: - if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) - break; - set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */ - Debug (15, "CFA_def_cfa_offset 0x%lx\n", (long) val); - break; - - case DW_CFA_def_cfa_offset_sf: - if ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0) - break; - set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, - val * dci->data_align); /* factored! */ - Debug (15, "CFA_def_cfa_offset_sf 0x%lx\n", - (long) (val * dci->data_align)); - break; - - case DW_CFA_def_cfa_expression: - /* Save the address of the DW_FORM_block for later evaluation. */ - set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_EXPR, *addr); - - if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) - break; - - Debug (15, "CFA_def_cfa_expr @ 0x%lx [%lu bytes]\n", - (long) *addr, (long) len); - *addr += len; - break; - - case DW_CFA_expression: - if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - break; - - /* Save the address of the DW_FORM_block for later evaluation. */ - set_reg (sr, regnum, DWARF_WHERE_EXPR, *addr); - - if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) - break; - - Debug (15, "CFA_expression r%lu @ 0x%lx [%lu bytes]\n", - (long) regnum, (long) addr, (long) len); - *addr += len; - break; - - case DW_CFA_val_expression: - if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - break; - - /* Save the address of the DW_FORM_block for later evaluation. */ - set_reg (sr, regnum, DWARF_WHERE_VAL_EXPR, *addr); - - if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) - break; - - Debug (15, "CFA_val_expression r%lu @ 0x%lx [%lu bytes]\n", - (long) regnum, (long) addr, (long) len); - *addr += len; - break; - - case DW_CFA_GNU_args_size: - if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) - break; - sr->args_size = val; - Debug (15, "CFA_GNU_args_size %lu\n", (long) val); - break; - - case DW_CFA_GNU_negative_offset_extended: - /* A comment in GCC says that this is obsoleted by - DW_CFA_offset_extended_sf, but that it's used by older - PowerPC code. */ - if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) - || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) - break; - set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dci->data_align)); - Debug (15, "CFA_GNU_negative_offset_extended cfa+0x%lx\n", - (long) -(val * dci->data_align)); - break; - - case DW_CFA_GNU_window_save: -#ifdef UNW_TARGET_SPARC - /* This is a special CFA to handle all 16 windowed registers - on SPARC. */ - for (regnum = 16; regnum < 32; ++regnum) - set_reg (sr, regnum, DWARF_WHERE_CFAREL, - (regnum - 16) * sizeof (unw_word_t)); - Debug (15, "CFA_GNU_window_save\n"); - break; -#else - /* FALL THROUGH */ -#endif - case DW_CFA_lo_user: - case DW_CFA_hi_user: - Debug (1, "Unexpected CFA opcode 0x%x\n", op); - ret = -UNW_EINVAL; - break; - } - } - - if (ret > 0) - ret = 0; - return ret; -} - -static int -fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip) -{ - int ret, dynamic = 1; - - /* The 'ip' can point either to the previous or next instruction - depending on what type of frame we have: normal call or a place - to resume execution (e.g. after signal frame). - - For a normal call frame we need to back up so we point within the - call itself; this is important because a) the call might be the - very last instruction of the function and the edge of the FDE, - and b) so that run_cfi_program() runs locations up to the call - but not more. - - For signal frame, we need to do the exact opposite and look - up using the current 'ip' value. That is where execution will - continue, and it's important we get this right, as 'ip' could be - right at the function entry and hence FDE edge, or at instruction - that manipulates CFA (push/pop). */ - if (c->use_prev_instr) - --ip; - - memset (&c->pi, 0, sizeof (c->pi)); - - /* check dynamic info first --- it overrides everything else */ - ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, 1, - c->as_arg); - if (ret == -UNW_ENOINFO) - { - dynamic = 0; - if ((ret = tdep_find_proc_info (c, ip, 1)) < 0) - return ret; - } - - if (c->pi.format != UNW_INFO_FORMAT_DYNAMIC - && c->pi.format != UNW_INFO_FORMAT_TABLE - && c->pi.format != UNW_INFO_FORMAT_REMOTE_TABLE) - return -UNW_ENOINFO; - - c->pi_valid = 1; - c->pi_is_dynamic = dynamic; - - /* Let system/machine-dependent code determine frame-specific attributes. */ - if (ret >= 0) - tdep_fetch_frame (c, ip, 1); - - return ret; -} - -static int -parse_dynamic (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr) -{ - Debug (1, "Not yet implemented\n"); - return -UNW_ENOINFO; -} - -static inline void -put_unwind_info (struct dwarf_cursor *c, unw_proc_info_t *pi) -{ - if (c->pi_is_dynamic) - unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg); - else if (pi->unwind_info && pi->format == UNW_INFO_FORMAT_TABLE) - { - mempool_free (&dwarf_cie_info_pool, pi->unwind_info); - pi->unwind_info = NULL; - } - c->pi_valid = 0; -} - -static inline int -setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr) -{ - int i, ret; - - assert (c->pi_valid); - - memset (sr, 0, sizeof (*sr)); - for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i) - set_reg (sr, i, DWARF_WHERE_SAME, 0); - - struct dwarf_cie_info *dci = c->pi.unwind_info; - sr->rs_current.ret_addr_column = dci->ret_addr_column; - unw_word_t addr = dci->cie_instr_start; - unw_word_t curr_ip = 0; - dwarf_stackable_reg_state_t *rs_stack = NULL; - ret = run_cfi_program (c, sr, &curr_ip, ~(unw_word_t) 0, &addr, - dci->cie_instr_end, - &rs_stack, dci); - empty_rstate_stack(&rs_stack); - if (ret < 0) - return ret; - - memcpy (&sr->rs_initial, &sr->rs_current, sizeof (sr->rs_initial)); - return 0; -} - -static inline int -parse_fde (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr) -{ - int ret; - struct dwarf_cie_info *dci = c->pi.unwind_info; - unw_word_t addr = dci->fde_instr_start; - unw_word_t curr_ip = c->pi.start_ip; - dwarf_stackable_reg_state_t *rs_stack = NULL; - /* Process up to current `ip` for signal frame and `ip - 1` for normal call frame - See `c->use_prev_instr` use in `fetch_proc_info` for details. */ - ret = run_cfi_program (c, sr, &curr_ip, ip - c->use_prev_instr, &addr, dci->fde_instr_end, - &rs_stack, dci); - empty_rstate_stack(&rs_stack); - if (ret < 0) - return ret; - - return 0; -} - -HIDDEN int -dwarf_flush_rs_cache (struct dwarf_rs_cache *cache) -{ - int i; - - if (cache->log_size == DWARF_DEFAULT_LOG_UNW_CACHE_SIZE - || !cache->hash) { - cache->hash = cache->default_hash; - cache->buckets = cache->default_buckets; - cache->links = cache->default_links; - cache->log_size = DWARF_DEFAULT_LOG_UNW_CACHE_SIZE; - } else { - if (cache->hash && cache->hash != cache->default_hash) - munmap(cache->hash, DWARF_UNW_HASH_SIZE(cache->prev_log_size) - * sizeof (cache->hash[0])); - if (cache->buckets && cache->buckets != cache->default_buckets) - munmap(cache->buckets, DWARF_UNW_CACHE_SIZE(cache->prev_log_size) - * sizeof (cache->buckets[0])); - if (cache->links && cache->links != cache->default_links) - munmap(cache->links, DWARF_UNW_CACHE_SIZE(cache->prev_log_size) - * sizeof (cache->links[0])); - GET_MEMORY(cache->hash, DWARF_UNW_HASH_SIZE(cache->log_size) - * sizeof (cache->hash[0])); - GET_MEMORY(cache->buckets, DWARF_UNW_CACHE_SIZE(cache->log_size) - * sizeof (cache->buckets[0])); - GET_MEMORY(cache->links, DWARF_UNW_CACHE_SIZE(cache->log_size) - * sizeof (cache->links[0])); - if (!cache->hash || !cache->buckets || !cache->links) - { - Debug (1, "Unable to allocate cache memory"); - return -UNW_ENOMEM; - } - cache->prev_log_size = cache->log_size; - } - - cache->rr_head = 0; - - for (i = 0; i < DWARF_UNW_CACHE_SIZE(cache->log_size); ++i) - { - cache->links[i].coll_chain = -1; - cache->links[i].ip = 0; - cache->links[i].valid = 0; - } - for (i = 0; i< DWARF_UNW_HASH_SIZE(cache->log_size); ++i) - cache->hash[i] = -1; - - return 0; -} - -static inline struct dwarf_rs_cache * -get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp) -{ - struct dwarf_rs_cache *cache = &as->global_cache; - unw_caching_policy_t caching = as->caching_policy; - - if (caching == UNW_CACHE_NONE) - return NULL; - -#if defined(HAVE___THREAD) && HAVE___THREAD - if (likely (caching == UNW_CACHE_PER_THREAD)) - { - static __thread struct dwarf_rs_cache tls_cache __attribute__((tls_model("initial-exec"))); - Debug (16, "using TLS cache\n"); - cache = &tls_cache; - } - else -#else - if (likely (caching == UNW_CACHE_GLOBAL)) -#endif - { - Debug (16, "acquiring lock\n"); - lock_acquire (&cache->lock, *saved_maskp); - } - - if ((atomic_read (&as->cache_generation) != atomic_read (&cache->generation)) - || !cache->hash) - { - /* cache_size is only set in the global_cache, copy it over before flushing */ - cache->log_size = as->global_cache.log_size; - if (dwarf_flush_rs_cache (cache) < 0) - return NULL; - cache->generation = as->cache_generation; - } - - return cache; -} - -static inline void -put_rs_cache (unw_addr_space_t as, struct dwarf_rs_cache *cache, - intrmask_t *saved_maskp) -{ - assert (as->caching_policy != UNW_CACHE_NONE); - - Debug (16, "unmasking signals/interrupts and releasing lock\n"); - if (likely (as->caching_policy == UNW_CACHE_GLOBAL)) - lock_release (&cache->lock, *saved_maskp); -} - -static inline unw_hash_index_t CONST_ATTR -hash (unw_word_t ip, unsigned short log_size) -{ - /* based on (sqrt(5)/2-1)*2^64 */ -# define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL) - - return ip * magic >> ((sizeof(unw_word_t) * 8) - (log_size + 1)); -} - -static inline long -cache_match (struct dwarf_rs_cache *cache, unsigned short index, unw_word_t ip) -{ - return (cache->links[index].valid && (ip == cache->links[index].ip)); -} - -static dwarf_reg_state_t * -rs_lookup (struct dwarf_rs_cache *cache, struct dwarf_cursor *c) -{ - unsigned short index; - unw_word_t ip = c->ip; - - if (c->hint > 0) - { - index = c->hint - 1; - if (cache_match (cache, index, ip)) - return &cache->buckets[index]; - } - - for (index = cache->hash[hash (ip, cache->log_size)]; - index < DWARF_UNW_CACHE_SIZE(cache->log_size); - index = cache->links[index].coll_chain) - { - if (cache_match (cache, index, ip)) - return &cache->buckets[index]; - } - return NULL; -} - -static inline dwarf_reg_state_t * -rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c) -{ - unw_hash_index_t index; - unsigned short head; - - head = cache->rr_head; - cache->rr_head = (head + 1) & (DWARF_UNW_CACHE_SIZE(cache->log_size) - 1); - - /* remove the old rs from the hash table (if it's there): */ - if (cache->links[head].ip) - { - unsigned short *pindex; - for (pindex = &cache->hash[hash (cache->links[head].ip, cache->log_size)]; - *pindex < DWARF_UNW_CACHE_SIZE(cache->log_size); - pindex = &cache->links[*pindex].coll_chain) - { - if (*pindex == head) - { - *pindex = cache->links[*pindex].coll_chain; - break; - } - } - } - - /* enter new rs in the hash table */ - index = hash (c->ip, cache->log_size); - cache->links[head].coll_chain = cache->hash[index]; - cache->hash[index] = head; - - cache->links[head].ip = c->ip; - cache->links[head].valid = 1; - cache->links[head].signal_frame = tdep_cache_frame(c); - return cache->buckets + head; -} - -static int -create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr, - unw_word_t ip) -{ - int ret; - switch (c->pi.format) - { - case UNW_INFO_FORMAT_TABLE: - case UNW_INFO_FORMAT_REMOTE_TABLE: - if ((ret = setup_fde(c, sr)) < 0) - return ret; - ret = parse_fde (c, ip, sr); - break; - - case UNW_INFO_FORMAT_DYNAMIC: - ret = parse_dynamic (c, ip, sr); - break; - - default: - Debug (1, "Unexpected unwind-info format %d\n", c->pi.format); - ret = -UNW_EINVAL; - } - return ret; -} - -static inline int -eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as, - unw_accessors_t *a, unw_word_t addr, - dwarf_loc_t *locp, void *arg) -{ - int ret, is_register; - unw_word_t len, val; - - /* read the length of the expression: */ - if ((ret = dwarf_read_uleb128 (as, a, &addr, &len, arg)) < 0) - return ret; - - /* evaluate the expression: */ - if ((ret = dwarf_eval_expr (c, &addr, len, &val, &is_register)) < 0) - return ret; - - if (is_register) - *locp = DWARF_REG_LOC (c, dwarf_to_unw_regnum (val)); - else - *locp = DWARF_MEM_LOC (c, val); - - return 0; -} - -static int -apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) -{ - unw_word_t regnum, addr, cfa, ip; - unw_word_t prev_ip, prev_cfa; - unw_addr_space_t as; - dwarf_loc_t cfa_loc; - unw_accessors_t *a; - int i, ret; - void *arg; - - prev_ip = c->ip; - prev_cfa = c->cfa; - - as = c->as; - arg = c->as_arg; - a = unw_get_accessors_int (as); - - /* Evaluate the CFA first, because it may be referred to by other - expressions. */ - - if (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG) - { - /* CFA is equal to [reg] + offset: */ - - /* As a special-case, if the stack-pointer is the CFA and the - stack-pointer wasn't saved, popping the CFA implicitly pops - the stack-pointer as well. */ - if ((rs->reg.val[DWARF_CFA_REG_COLUMN] == UNW_TDEP_SP) - && (UNW_TDEP_SP < ARRAY_SIZE(rs->reg.val)) - && (rs->reg.where[UNW_TDEP_SP] == DWARF_WHERE_SAME)) - cfa = c->cfa; - else - { - regnum = dwarf_to_unw_regnum (rs->reg.val[DWARF_CFA_REG_COLUMN]); - if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0) - return ret; - } - cfa += rs->reg.val[DWARF_CFA_OFF_COLUMN]; - } - else - { - /* CFA is equal to EXPR: */ - - assert (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR); - - addr = rs->reg.val[DWARF_CFA_REG_COLUMN]; - if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0) - return ret; - /* the returned location better be a memory location... */ - if (DWARF_IS_REG_LOC (cfa_loc)) - return -UNW_EBADFRAME; - cfa = DWARF_GET_LOC (cfa_loc); - } - - dwarf_loc_t new_loc[DWARF_NUM_PRESERVED_REGS]; - memcpy(new_loc, c->loc, sizeof(new_loc)); - - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - { - switch ((dwarf_where_t) rs->reg.where[i]) - { - case DWARF_WHERE_UNDEF: - new_loc[i] = DWARF_NULL_LOC; - break; - - case DWARF_WHERE_SAME: - break; - - case DWARF_WHERE_CFAREL: - new_loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg.val[i]); - break; - - case DWARF_WHERE_REG: - new_loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg.val[i])); - break; - - case DWARF_WHERE_EXPR: - addr = rs->reg.val[i]; - if ((ret = eval_location_expr (c, as, a, addr, new_loc + i, arg)) < 0) - return ret; - break; - - case DWARF_WHERE_VAL_EXPR: - addr = rs->reg.val[i]; - if ((ret = eval_location_expr (c, as, a, addr, new_loc + i, arg)) < 0) - return ret; - new_loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (new_loc[i])); - break; - } - } - - memcpy(c->loc, new_loc, sizeof(new_loc)); - - c->cfa = cfa; - /* DWARF spec says undefined return address location means end of stack. */ - if (DWARF_IS_NULL_LOC (c->loc[rs->ret_addr_column])) - { - c->ip = 0; - ret = 0; - } - else - { - ret = dwarf_get (c, c->loc[rs->ret_addr_column], &ip); - if (ret < 0) - return ret; - c->ip = ip; - ret = 1; - } - - /* XXX: check for ip to be code_aligned */ - if (c->ip == prev_ip && c->cfa == prev_cfa) - { - Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n", - __FUNCTION__, (long) c->ip); - return -UNW_EBADFRAME; - } - - if (c->stash_frames) - tdep_stash_frame (c, rs); - - return ret; -} - -/* Find the saved locations. */ -static int -find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr) -{ - dwarf_reg_state_t *rs; - struct dwarf_rs_cache *cache; - int ret = 0; - intrmask_t saved_mask; - - if ((cache = get_rs_cache(c->as, &saved_mask)) && - (rs = rs_lookup(cache, c))) - { - /* update hint; no locking needed: single-word writes are atomic */ - unsigned short index = rs - cache->buckets; - c->use_prev_instr = ! cache->links[index].signal_frame; - memcpy (&sr->rs_current, rs, sizeof (*rs)); - } - else - { - ret = fetch_proc_info (c, c->ip); - int next_use_prev_instr = c->use_prev_instr; - if (ret >= 0) - { - /* Update use_prev_instr for the next frame. */ - assert(c->pi.unwind_info); - struct dwarf_cie_info *dci = c->pi.unwind_info; - next_use_prev_instr = ! dci->signal_frame; - ret = create_state_record_for (c, sr, c->ip); - } - put_unwind_info (c, &c->pi); - c->use_prev_instr = next_use_prev_instr; - - if (cache && ret >= 0) - { - rs = rs_new (cache, c); - cache->links[rs - cache->buckets].hint = 0; - memcpy(rs, &sr->rs_current, sizeof(*rs)); - } - } - - unsigned short index = -1; - if (cache) - { - put_rs_cache (c->as, cache, &saved_mask); - if (rs) - { - index = rs - cache->buckets; - c->hint = cache->links[index].hint; - cache->links[c->prev_rs].hint = index + 1; - c->prev_rs = index; - } - } - if (ret < 0) - return ret; - if (cache) - tdep_reuse_frame (c, cache->links[index].signal_frame); - return 0; -} - -/* The function finds the saved locations and applies the register - state as well. */ -HIDDEN int -dwarf_step (struct dwarf_cursor *c) -{ - int ret; - dwarf_state_record_t sr; - if ((ret = find_reg_state (c, &sr)) < 0) - return ret; - return apply_reg_state (c, &sr.rs_current); -} - -HIDDEN int -dwarf_make_proc_info (struct dwarf_cursor *c) -{ -#if 0 - if (c->as->caching_policy == UNW_CACHE_NONE - || get_cached_proc_info (c) < 0) -#endif - /* Need to check if current frame contains - args_size, and set cursor appropriately. Only - needed for unw_resume */ - dwarf_state_record_t sr; - int ret; - - /* Lookup it up the slow way... */ - ret = fetch_proc_info (c, c->ip); - if (ret >= 0) - ret = create_state_record_for (c, &sr, c->ip); - put_unwind_info (c, &c->pi); - if (ret < 0) - return ret; - c->args_size = sr.args_size; - - return 0; -} - -static int -dwarf_reg_states_dynamic_iterate(struct dwarf_cursor *c, - unw_reg_states_callback cb, - void *token) -{ - Debug (1, "Not yet implemented\n"); - return -UNW_ENOINFO; -} - -static int -dwarf_reg_states_table_iterate(struct dwarf_cursor *c, - unw_reg_states_callback cb, - void *token) -{ - dwarf_state_record_t sr; - int ret = setup_fde(c, &sr); - struct dwarf_cie_info *dci = c->pi.unwind_info; - unw_word_t addr = dci->fde_instr_start; - unw_word_t curr_ip = c->pi.start_ip; - dwarf_stackable_reg_state_t *rs_stack = NULL; - while (ret >= 0 && curr_ip < c->pi.end_ip && addr < dci->fde_instr_end) - { - unw_word_t prev_ip = curr_ip; - ret = run_cfi_program (c, &sr, &curr_ip, prev_ip, &addr, dci->fde_instr_end, - &rs_stack, dci); - if (ret >= 0 && prev_ip < curr_ip) - ret = cb(token, &sr.rs_current, sizeof(sr.rs_current), prev_ip, curr_ip); - } - empty_rstate_stack(&rs_stack); -#if defined(NEED_LAST_IP) - if (ret >= 0 && curr_ip < c->pi.last_ip) - /* report the dead zone after the procedure ends */ - ret = cb(token, &sr.rs_current, sizeof(sr.rs_current), curr_ip, c->pi.last_ip); -#else - if (ret >= 0 && curr_ip < c->pi.end_ip) - /* report for whatever is left before procedure end */ - ret = cb(token, &sr.rs_current, sizeof(sr.rs_current), curr_ip, c->pi.end_ip); -#endif - return ret; -} - -HIDDEN int -dwarf_reg_states_iterate(struct dwarf_cursor *c, - unw_reg_states_callback cb, - void *token) -{ - int ret = fetch_proc_info (c, c->ip); - int next_use_prev_instr = c->use_prev_instr; - if (ret >= 0) - { - /* Update use_prev_instr for the next frame. */ - assert(c->pi.unwind_info); - struct dwarf_cie_info *dci = c->pi.unwind_info; - next_use_prev_instr = ! dci->signal_frame; - switch (c->pi.format) - { - case UNW_INFO_FORMAT_TABLE: - case UNW_INFO_FORMAT_REMOTE_TABLE: - ret = dwarf_reg_states_table_iterate(c, cb, token); - break; - - case UNW_INFO_FORMAT_DYNAMIC: - ret = dwarf_reg_states_dynamic_iterate (c, cb, token); - break; - - default: - Debug (1, "Unexpected unwind-info format %d\n", c->pi.format); - ret = -UNW_EINVAL; - } - } - put_unwind_info (c, &c->pi); - c->use_prev_instr = next_use_prev_instr; - return ret; -} - -HIDDEN int -dwarf_apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) -{ - return apply_reg_state(c, rs); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gpe.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gpe.c deleted file mode 100644 index a0e37ba2329df5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gpe.c +++ /dev/null @@ -1,39 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "dwarf_i.h" -#include "libunwind_i.h" - -#include - -HIDDEN 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) -{ - return dwarf_read_encoded_pointer_inlined (as, a, addr, encoding, - pi, valp, arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lexpr.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lexpr.c deleted file mode 100644 index 245970c9e3f293..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lexpr.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gexpr.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfde.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfde.c deleted file mode 100644 index e779e8f192e9ab..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfde.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gfde.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_proc_info-lsb.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_proc_info-lsb.c deleted file mode 100644 index 27a5eeac188d06..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_proc_info-lsb.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gfind_proc_info-lsb.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_unwind_table.c deleted file mode 100644 index 68e269f1d7f95f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_unwind_table.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gfind_unwind_table.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lparser.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lparser.c deleted file mode 100644 index f23aaf48e9c27d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lparser.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gparser.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lpe.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lpe.c deleted file mode 100644 index a672358f063f80..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lpe.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gpe.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/global.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/global.c deleted file mode 100644 index 70985071425d39..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/global.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "dwarf_i.h" - -HIDDEN struct mempool dwarf_reg_state_pool; -HIDDEN struct mempool dwarf_cie_info_pool; - -HIDDEN int -dwarf_init (void) -{ - mempool_init (&dwarf_reg_state_pool, sizeof (dwarf_stackable_reg_state_t), 0); - mempool_init (&dwarf_cie_info_pool, sizeof (struct dwarf_cie_info), 0); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/elf32.c b/src/coreclr/src/pal/src/libunwind/src/elf32.c deleted file mode 100644 index a70bb58f24dee1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/elf32.c +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef UNW_REMOTE_ONLY -# include "elf32.h" -# include "elfxx.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/elf32.h b/src/coreclr/src/pal/src/libunwind/src/elf32.h deleted file mode 100644 index 2c7bca4c9dcca4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/elf32.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef elf32_h -#define elf32_h - -#ifndef ELF_CLASS -#define ELF_CLASS ELFCLASS32 -#endif -#include "elfxx.h" - -#endif /* elf32_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/elf64.c b/src/coreclr/src/pal/src/libunwind/src/elf64.c deleted file mode 100644 index 195b88794867e9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/elf64.c +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef UNW_REMOTE_ONLY -# include "elf64.h" -# include "elfxx.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/elf64.h b/src/coreclr/src/pal/src/libunwind/src/elf64.h deleted file mode 100644 index 091fba8e1f84e0..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/elf64.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef elf64_h -#define elf64_h - -#ifndef ELF_CLASS -#define ELF_CLASS ELFCLASS64 -#endif -#include "elfxx.h" - -#endif /* elf64_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/elfxx.c b/src/coreclr/src/pal/src/libunwind/src/elfxx.c deleted file mode 100644 index b03dfcb734cdaa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/elfxx.c +++ /dev/null @@ -1,481 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -#include -#include - -#ifdef HAVE_LZMA -#include -#endif /* HAVE_LZMA */ - -static Elf_W (Shdr)* -elf_w (section_table) (struct elf_image *ei) -{ - Elf_W (Ehdr) *ehdr = ei->image; - Elf_W (Off) soff; - - soff = ehdr->e_shoff; - if (soff + ehdr->e_shnum * ehdr->e_shentsize > ei->size) - { - Debug (1, "section table outside of image? (%lu > %lu)\n", - (unsigned long) (soff + ehdr->e_shnum * ehdr->e_shentsize), - (unsigned long) ei->size); - return NULL; - } - - return (Elf_W (Shdr) *) ((char *) ei->image + soff); -} - -static char* -elf_w (string_table) (struct elf_image *ei, int section) -{ - Elf_W (Ehdr) *ehdr = ei->image; - Elf_W (Off) soff, str_soff; - Elf_W (Shdr) *str_shdr; - - /* this offset is assumed to be OK */ - soff = ehdr->e_shoff; - - str_soff = soff + (section * ehdr->e_shentsize); - if (str_soff + ehdr->e_shentsize > ei->size) - { - Debug (1, "string shdr table outside of image? (%lu > %lu)\n", - (unsigned long) (str_soff + ehdr->e_shentsize), - (unsigned long) ei->size); - return NULL; - } - str_shdr = (Elf_W (Shdr) *) ((char *) ei->image + str_soff); - - if (str_shdr->sh_offset + str_shdr->sh_size > ei->size) - { - Debug (1, "string table outside of image? (%lu > %lu)\n", - (unsigned long) (str_shdr->sh_offset + str_shdr->sh_size), - (unsigned long) ei->size); - return NULL; - } - - Debug (16, "strtab=0x%lx\n", (long) str_shdr->sh_offset); - return ei->image + str_shdr->sh_offset; -} - -static int -elf_w (lookup_symbol) (unw_addr_space_t as, - unw_word_t ip, struct elf_image *ei, - Elf_W (Addr) load_offset, - char *buf, size_t buf_len, Elf_W (Addr) *min_dist) -{ - size_t syment_size; - Elf_W (Ehdr) *ehdr = ei->image; - Elf_W (Sym) *sym, *symtab, *symtab_end; - Elf_W (Shdr) *shdr; - Elf_W (Addr) val; - int i, ret = -UNW_ENOINFO; - char *strtab; - - if (!elf_w (valid_object) (ei)) - return -UNW_ENOINFO; - - shdr = elf_w (section_table) (ei); - if (!shdr) - return -UNW_ENOINFO; - - for (i = 0; i < ehdr->e_shnum; ++i) - { - switch (shdr->sh_type) - { - case SHT_SYMTAB: - case SHT_DYNSYM: - symtab = (Elf_W (Sym) *) ((char *) ei->image + shdr->sh_offset); - symtab_end = (Elf_W (Sym) *) ((char *) symtab + shdr->sh_size); - syment_size = shdr->sh_entsize; - - strtab = elf_w (string_table) (ei, shdr->sh_link); - if (!strtab) - break; - - Debug (16, "symtab=0x%lx[%d]\n", - (long) shdr->sh_offset, shdr->sh_type); - - for (sym = symtab; - sym < symtab_end; - sym = (Elf_W (Sym) *) ((char *) sym + syment_size)) - { - if (ELF_W (ST_TYPE) (sym->st_info) == STT_FUNC - && sym->st_shndx != SHN_UNDEF) - { - val = sym->st_value; - if (sym->st_shndx != SHN_ABS) - val += load_offset; - if (tdep_get_func_addr (as, val, &val) < 0) - continue; - Debug (16, "0x%016lx info=0x%02x %s\n", - (long) val, sym->st_info, strtab + sym->st_name); - - if ((Elf_W (Addr)) (ip - val) < *min_dist) - { - *min_dist = (Elf_W (Addr)) (ip - val); - strncpy (buf, strtab + sym->st_name, buf_len); - buf[buf_len - 1] = '\0'; - ret = (strlen (strtab + sym->st_name) >= buf_len - ? -UNW_ENOMEM : 0); - } - } - } - break; - - default: - break; - } - shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize); - } - return ret; -} - -static Elf_W (Addr) -elf_w (get_load_offset) (struct elf_image *ei, unsigned long segbase, - unsigned long mapoff) -{ - Elf_W (Addr) offset = 0; - Elf_W (Ehdr) *ehdr; - Elf_W (Phdr) *phdr; - int i; - - ehdr = ei->image; - phdr = (Elf_W (Phdr) *) ((char *) ei->image + ehdr->e_phoff); - - for (i = 0; i < ehdr->e_phnum; ++i) - if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == mapoff) - { - offset = segbase - phdr[i].p_vaddr; - break; - } - - return offset; -} - -#if HAVE_LZMA -static size_t -xz_uncompressed_size (uint8_t *compressed, size_t length) -{ - uint64_t memlimit = UINT64_MAX; - size_t ret = 0, pos = 0; - lzma_stream_flags options; - lzma_index *index; - - if (length < LZMA_STREAM_HEADER_SIZE) - return 0; - - uint8_t *footer = compressed + length - LZMA_STREAM_HEADER_SIZE; - if (lzma_stream_footer_decode (&options, footer) != LZMA_OK) - return 0; - - if (length < LZMA_STREAM_HEADER_SIZE + options.backward_size) - return 0; - - uint8_t *indexdata = footer - options.backward_size; - if (lzma_index_buffer_decode (&index, &memlimit, NULL, indexdata, - &pos, options.backward_size) != LZMA_OK) - return 0; - - if (lzma_index_size (index) == options.backward_size) - { - ret = lzma_index_uncompressed_size (index); - } - - lzma_index_end (index, NULL); - return ret; -} - -static int -elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) -{ - Elf_W (Shdr) *shdr; - uint8_t *compressed = NULL; - uint64_t memlimit = UINT64_MAX; /* no memory limit */ - size_t compressed_len, uncompressed_len; - - shdr = elf_w (find_section) (ei, ".gnu_debugdata"); - if (!shdr) - return 0; - - compressed = ((uint8_t *) ei->image) + shdr->sh_offset; - compressed_len = shdr->sh_size; - - uncompressed_len = xz_uncompressed_size (compressed, compressed_len); - if (uncompressed_len == 0) - { - Debug (1, "invalid .gnu_debugdata contents\n"); - return 0; - } - - mdi->size = uncompressed_len; - mdi->image = mmap (NULL, uncompressed_len, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - - if (mdi->image == MAP_FAILED) - return 0; - - size_t in_pos = 0, out_pos = 0; - lzma_ret lret; - lret = lzma_stream_buffer_decode (&memlimit, 0, NULL, - compressed, &in_pos, compressed_len, - mdi->image, &out_pos, mdi->size); - if (lret != LZMA_OK) - { - Debug (1, "LZMA decompression failed: %d\n", lret); - munmap (mdi->image, mdi->size); - return 0; - } - - return 1; -} -#else -static int -elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) -{ - return 0; -} -#endif /* !HAVE_LZMA */ - -/* Find the ELF image that contains IP and return the "closest" - procedure name, if there is one. With some caching, this could be - sped up greatly, but until an application materializes that's - sensitive to the performance of this routine, why bother... */ - -HIDDEN int -elf_w (get_proc_name_in_image) (unw_addr_space_t as, struct elf_image *ei, - unsigned long segbase, - unsigned long mapoff, - unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp) -{ - Elf_W (Addr) load_offset; - Elf_W (Addr) min_dist = ~(Elf_W (Addr))0; - int ret; - - load_offset = elf_w (get_load_offset) (ei, segbase, mapoff); - ret = elf_w (lookup_symbol) (as, ip, ei, load_offset, buf, buf_len, &min_dist); - - /* If the ELF image has MiniDebugInfo embedded in it, look up the symbol in - there as well and replace the previously found if it is closer. */ - struct elf_image mdi; - if (elf_w (extract_minidebuginfo) (ei, &mdi)) - { - int ret_mdi = elf_w (lookup_symbol) (as, ip, &mdi, load_offset, buf, - buf_len, &min_dist); - - /* Closer symbol was found (possibly truncated). */ - if (ret_mdi == 0 || ret_mdi == -UNW_ENOMEM) - { - ret = ret_mdi; - } - - munmap (mdi.image, mdi.size); - } - - if (min_dist >= ei->size) - return -UNW_ENOINFO; /* not found */ - if (offp) - *offp = min_dist; - return ret; -} - -HIDDEN int -elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp) -{ - unsigned long segbase, mapoff; - struct elf_image ei; - int ret; - char file[PATH_MAX]; - - ret = tdep_get_elf_image (&ei, pid, ip, &segbase, &mapoff, file, PATH_MAX); - if (ret < 0) - return ret; - - ret = elf_w (load_debuglink) (file, &ei, 1); - if (ret < 0) - return ret; - - ret = elf_w (get_proc_name_in_image) (as, &ei, segbase, mapoff, ip, buf, buf_len, offp); - - munmap (ei.image, ei.size); - ei.image = NULL; - - return ret; -} - -HIDDEN Elf_W (Shdr)* -elf_w (find_section) (struct elf_image *ei, const char* secname) -{ - Elf_W (Ehdr) *ehdr = ei->image; - Elf_W (Shdr) *shdr; - char *strtab; - int i; - - if (!elf_w (valid_object) (ei)) - return 0; - - shdr = elf_w (section_table) (ei); - if (!shdr) - return 0; - - strtab = elf_w (string_table) (ei, ehdr->e_shstrndx); - if (!strtab) - return 0; - - for (i = 0; i < ehdr->e_shnum; ++i) - { - if (strcmp (strtab + shdr->sh_name, secname) == 0) - { - if (shdr->sh_offset + shdr->sh_size > ei->size) - { - Debug (1, "section \"%s\" outside image? (0x%lu > 0x%lu)\n", - secname, - (unsigned long) shdr->sh_offset + shdr->sh_size, - (unsigned long) ei->size); - return 0; - } - - Debug (16, "found section \"%s\" at 0x%lx\n", - secname, (unsigned long) shdr->sh_offset); - return shdr; - } - - shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize); - } - - /* section not found */ - return 0; -} - -/* Load a debug section, following .gnu_debuglink if appropriate - * Loads ei from file if not already mapped. - * If is_local, will also search sys directories /usr/local/dbg - * - * Returns 0 on success, failure otherwise. - * ei will be mapped to file or the located .gnu_debuglink from file - */ -HIDDEN int -elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local) -{ - int ret; - Elf_W (Shdr) *shdr; - Elf_W (Ehdr) *prev_image; - off_t prev_size; - - if (!ei->image) - { - ret = elf_map_image(ei, file); - if (ret) - return ret; - } - - prev_image = ei->image; - prev_size = ei->size; - - /* Ignore separate debug files which contain a .gnu_debuglink section. */ - if (is_local == -1) { - return 0; - } - - shdr = elf_w (find_section) (ei, ".gnu_debuglink"); - if (shdr) { - if (shdr->sh_size >= PATH_MAX || - (shdr->sh_offset + shdr->sh_size > ei->size)) - { - return 0; - } - - { - char linkbuf[shdr->sh_size]; - char *link = ((char *) ei->image) + shdr->sh_offset; - char *p; - static const char *debugdir = "/usr/lib/debug"; - char basedir[strlen(file) + 1]; - char newname[shdr->sh_size + strlen (debugdir) + strlen (file) + 9]; - - memcpy(linkbuf, link, shdr->sh_size); - - if (memchr (linkbuf, 0, shdr->sh_size) == NULL) - return 0; - - ei->image = NULL; - - Debug(1, "Found debuglink section, following %s\n", linkbuf); - - p = strrchr (file, '/'); - if (p != NULL) - { - memcpy (basedir, file, p - file); - basedir[p - file] = '\0'; - } - else - basedir[0] = 0; - - strcpy (newname, basedir); - strcat (newname, "/"); - strcat (newname, linkbuf); - ret = elf_w (load_debuglink) (newname, ei, -1); - - if (ret == -1) - { - strcpy (newname, basedir); - strcat (newname, "/.debug/"); - strcat (newname, linkbuf); - ret = elf_w (load_debuglink) (newname, ei, -1); - } - - if (ret == -1 && is_local == 1) - { - strcpy (newname, debugdir); - strcat (newname, basedir); - strcat (newname, "/"); - strcat (newname, linkbuf); - ret = elf_w (load_debuglink) (newname, ei, -1); - } - - if (ret == -1) - { - /* No debuglink file found even though .gnu_debuglink existed */ - ei->image = prev_image; - ei->size = prev_size; - - return 0; - } - else - { - munmap (prev_image, prev_size); - } - - return ret; - } - } - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/elfxx.h b/src/coreclr/src/pal/src/libunwind/src/elfxx.h deleted file mode 100644 index 830432c2ed1c9e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/elfxx.h +++ /dev/null @@ -1,101 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003, 2005 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include - -#include -#include - -#include "libunwind_i.h" - -#if ELF_CLASS == ELFCLASS32 -# define ELF_W(x) ELF32_##x -# define Elf_W(x) Elf32_##x -# define elf_w(x) _Uelf32_##x -#else -# define ELF_W(x) ELF64_##x -# define Elf_W(x) Elf64_##x -# define elf_w(x) _Uelf64_##x -#endif - -extern int elf_w (get_proc_name) (unw_addr_space_t as, - pid_t pid, unw_word_t ip, - char *buf, size_t len, - unw_word_t *offp); - -extern int elf_w (get_proc_name_in_image) (unw_addr_space_t as, - struct elf_image *ei, - unsigned long segbase, - unsigned long mapoff, - unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp); - -extern Elf_W (Shdr)* elf_w (find_section) (struct elf_image *ei, const char* secname); -extern int elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local); - -static inline int -elf_w (valid_object) (struct elf_image *ei) -{ - if (ei->size <= EI_VERSION) - return 0; - - return (memcmp (ei->image, ELFMAG, SELFMAG) == 0 - && ((uint8_t *) ei->image)[EI_CLASS] == ELF_CLASS - && ((uint8_t *) ei->image)[EI_VERSION] != EV_NONE - && ((uint8_t *) ei->image)[EI_VERSION] <= EV_CURRENT); -} - -static inline int -elf_map_image (struct elf_image *ei, const char *path) -{ - struct stat stat; - int fd; - - fd = open (path, O_RDONLY); - if (fd < 0) - return -1; - - if (fstat (fd, &stat) < 0) - { - close (fd); - return -1; - } - - ei->size = stat.st_size; - ei->image = mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0); - close (fd); - if (ei->image == MAP_FAILED) - return -1; - - if (!elf_w (valid_object) (ei)) - { - munmap(ei->image, ei->size); - return -1; - } - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gcreate_addr_space.c deleted file mode 100644 index 8a6cb8b4e67a59..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Gcreate_addr_space.c +++ /dev/null @@ -1,54 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* - * hppa supports only big-endian. - */ - if (byte_order != 0 && byte_order != __BIG_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_proc_info.c deleted file mode 100644 index e10efcfca0d945..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_proc_info.c +++ /dev/null @@ -1,46 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - - if (dwarf_make_proc_info (&c->dwarf) < 0) - { - /* On hppa, some key routines such as _start() and _dl_start() - are missing DWARF unwind info. We don't want to fail in that - case, because those frames are uninteresting and just mark - the end of the frame-chain anyhow. */ - memset (pi, 0, sizeof (*pi)); - pi->start_ip = c->dwarf.ip; - pi->end_ip = c->dwarf.ip + 4; - return 0; - } - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_save_loc.c deleted file mode 100644 index 02dfa3084f9117..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_save_loc.c +++ /dev/null @@ -1,59 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - /* struct cursor *c = (struct cursor *) cursor; */ - dwarf_loc_t loc; - - loc = DWARF_NULL_LOC; /* default to "not saved" */ - -#warning FIX ME! - - memset (sloc, 0, sizeof (*sloc)); - - if (DWARF_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (DWARF_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = DWARF_GET_LOC (loc); - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = DWARF_GET_LOC (loc); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gglobal.c deleted file mode 100644 index 351a5015d6869b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Gglobal.c +++ /dev/null @@ -1,55 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -HIDDEN define_lock (hppa_lock); -HIDDEN int tdep_init_done; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&hppa_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - dwarf_init (); - -#ifndef UNW_REMOTE_ONLY - hppa_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&hppa_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c deleted file mode 100644 index 461e4b93da65fb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c +++ /dev/null @@ -1,194 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002, 2004 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include - -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -static inline void * -uc_addr (ucontext_t *uc, int reg) -{ - void *addr; - - if ((unsigned) (reg - UNW_HPPA_GR) < 32) - addr = &uc->uc_mcontext.sc_gr[reg - UNW_HPPA_GR]; - else if ((unsigned) (reg - UNW_HPPA_FR) < 32) - addr = &uc->uc_mcontext.sc_fr[reg - UNW_HPPA_FR]; - else - addr = NULL; - return addr; -} - -# ifdef UNW_LOCAL_ONLY - -void * -_Uhppa_uc_addr (ucontext_t *uc, int reg) -{ - return uc_addr (uc, reg); -} - -# endif /* UNW_LOCAL_ONLY */ - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (write) - { - Debug (12, "mem[%x] <- %x\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "mem[%x] -> %x\n", addr, *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = arg; - - if ((unsigned int) (reg - UNW_HPPA_FR) < 32) - goto badreg; - - addr = uc_addr (uc, reg); - if (!addr) - goto badreg; - - if (write) - { - *(unw_word_t *) addr = *val; - Debug (12, "%s <- %x\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> %x\n", unw_regname (reg), *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = arg; - unw_fpreg_t *addr; - - if ((unsigned) (reg - UNW_HPPA_FR) > 32) - goto badreg; - - addr = uc_addr (uc, reg); - if (!addr) - goto badreg; - - if (write) - { - Debug (12, "%s <- %08x.%08x\n", - unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); - *(unw_fpreg_t *) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %08x.%08x\n", - unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -hppa_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = hppa_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_local.c deleted file mode 100644 index 1fdc7716fd5e09..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_local.c +++ /dev/null @@ -1,77 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by ... - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = uc; - return common_init (c, use_prev_instr); -} - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_remote.c deleted file mode 100644 index 71096ce0e61813..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_remote.c +++ /dev/null @@ -1,46 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - c->dwarf.as_arg = as_arg; - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gis_signal_frame.c deleted file mode 100644 index addb551818a450..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Gis_signal_frame.c +++ /dev/null @@ -1,74 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ -#ifdef __linux__ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, w1, w2, w3, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - /* Check if IP points at sigreturn() sequence. On Linux, this normally is: - - rt_sigreturn: - 0x34190000 ldi 0, %r25 - 0x3414015a ldi __NR_rt_sigreturn,%r20 - 0xe4008200 be,l 0x100(%sr2,%r0),%sr0,%r31 - 0x08000240 nop - - When a signal interrupts a system call, the first word is instead: - - 0x34190002 ldi 1, %r25 - */ - ip = c->dwarf.ip; - if (!ip) - return 0; - if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 - || (ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0 - || (ret = (*a->access_mem) (as, ip + 8, &w2, 0, arg)) < 0 - || (ret = (*a->access_mem) (as, ip + 12, &w3, 0, arg)) < 0) - { - Debug (1, "failed to read sigreturn code (ret=%d)\n", ret); - return ret; - } - ret = ((w0 == 0x34190000 || w0 == 0x34190002) - && w1 == 0x3414015a && w2 == 0xe4008200 && w3 == 0x08000240); - Debug (1, "(cursor=%p, ip=0x%08lx) -> %d\n", c, (unsigned) ip, ret); - return ret; -#else - printf ("%s: implement me\n", __FUNCTION__); -#endif - return -UNW_ENOINFO; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gregs.c deleted file mode 100644 index da0542c81ff4b1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Gregs.c +++ /dev/null @@ -1,87 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - struct dwarf_loc loc; - - switch (reg) - { - case UNW_HPPA_IP: - if (write) - c->dwarf.ip = *valp; /* update the IP cache */ - if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip - || *valp >= c->dwarf.pi.end_ip)) - c->dwarf.pi_valid = 0; /* new IP outside of current proc */ - break; - - case UNW_HPPA_CFA: - case UNW_HPPA_SP: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - /* Do the exception-handling register remapping: */ - case UNW_HPPA_EH0: reg = UNW_HPPA_GR + 20; break; - case UNW_HPPA_EH1: reg = UNW_HPPA_GR + 21; break; - case UNW_HPPA_EH2: reg = UNW_HPPA_GR + 22; break; - case UNW_HPPA_EH3: reg = UNW_HPPA_GR + 31; break; - - default: - break; - } - - if ((unsigned) (reg - UNW_HPPA_GR) >= 32) - return -UNW_EBADREG; - - loc = c->dwarf.loc[reg]; - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - struct dwarf_loc loc; - - if ((unsigned) (reg - UNW_HPPA_FR) >= 32) - return -UNW_EBADREG; - - loc = c->dwarf.loc[reg]; - - if (write) - return dwarf_putfp (&c->dwarf, loc, *valp); - else - return dwarf_getfp (&c->dwarf, loc, valp); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gresume.c deleted file mode 100644 index 6c11f140364b90..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Gresume.c +++ /dev/null @@ -1,145 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -#ifndef UNW_REMOTE_ONLY - -#if defined(__linux) - -# include - -static NORETURN inline long -my_rt_sigreturn (void *new_sp, int in_syscall) -{ - register unsigned long r25 __asm__ ("r25") = (in_syscall != 0); - register unsigned long r20 __asm__ ("r20") = SYS_rt_sigreturn; - - __asm__ __volatile__ ("copy %0, %%sp\n" - "be,l 0x100(%%sr2,%%r0),%%sr0,%%r31\n" - "nop" - : - : "r"(new_sp), "r"(r20), "r"(r25) - : "memory"); - abort (); -} - -#endif /* __linux */ - -HIDDEN inline int -hppa_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ -#if defined(__linux) - struct cursor *c = (struct cursor *) cursor; - ucontext_t *uc = c->dwarf.as_arg; - - /* Ensure c->pi is up-to-date. On PA-RISC, it's relatively common to be - missing DWARF unwind info. We don't want to fail in that case, - because the frame-chain still would let us do a backtrace at - least. */ - dwarf_make_proc_info (&c->dwarf); - - if (unlikely (c->sigcontext_format != HPPA_SCF_NONE)) - { - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - - Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); - my_rt_sigreturn (sc, (sc->sc_flags & PARISC_SC_FLAG_IN_SYSCALL) != 0); - } - else - { - Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); - setcontext (uc); - } -#else -# warning Implement me! -#endif - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ - -/* This routine is responsible for copying the register values in - cursor C and establishing them as the current machine state. */ - -static inline int -establish_machine_state (struct cursor *c) -{ - int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, - int write, void *); - int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, - int write, void *); - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - access_reg = as->acc.access_reg; - access_fpreg = as->acc.access_fpreg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_REG_LAST; ++reg) - { - Debug (16, "copying %s %d\n", unw_regname (reg), reg); - if (unw_is_fpreg (reg)) - { - if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) - (*access_fpreg) (as, reg, &fpval, 1, arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - (*access_reg) (as, reg, &val, 1, arg); - } - } - return 0; -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p)\n", c); - - if (!c->dwarf.ip) - { - /* This can happen easily when the frame-chain gets truncated - due to bad or missing unwind-info. */ - Debug (1, "refusing to resume execution at address 0\n"); - return -UNW_EINVAL; - } - - if ((ret = establish_machine_state (c)) < 0) - return ret; - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gstep.c deleted file mode 100644 index 4fc8a8776bff59..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Gstep.c +++ /dev/null @@ -1,95 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret, i; - - Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip); - - /* Try DWARF-based unwinding... */ - ret = dwarf_step (&c->dwarf); - - if (ret < 0 && ret != -UNW_ENOINFO) - { - Debug (2, "returning %d\n", ret); - return ret; - } - - if (unlikely (ret < 0)) - { - /* DWARF failed, let's see if we can follow the frame-chain - or skip over the signal trampoline. */ - - Debug (13, "dwarf_step() failed (ret=%d), trying fallback\n", ret); - - if (unw_is_signal_frame (cursor)) - { -#ifdef __linux__ - /* Assume that the trampoline is at the beginning of the - sigframe. */ - unw_word_t ip, sc_addr = c->dwarf.ip + LINUX_RT_SIGFRAME_UC_OFF; - dwarf_loc_t iaoq_loc = DWARF_LOC (sc_addr + LINUX_SC_IAOQ_OFF, 0); - - c->sigcontext_format = HPPA_SCF_LINUX_RT_SIGFRAME; - c->sigcontext_addr = sc_addr; - - if ((ret = dwarf_get (&c->dwarf, iaoq_loc, &ip)) < 0) - { - Debug (2, "failed to read IAOQ[1] (ret=%d)\n", ret); - return ret; - } - c->dwarf.ip = ip & ~0x3; /* mask out the privilege level */ - - for (i = 0; i < 32; ++i) - { - c->dwarf.loc[UNW_HPPA_GR + i] - = DWARF_LOC (sc_addr + LINUX_SC_GR_OFF + 4*i, 0); - c->dwarf.loc[UNW_HPPA_FR + i] - = DWARF_LOC (sc_addr + LINUX_SC_FR_OFF + 4*i, 0); - } - - if ((ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_SP], - &c->dwarf.cfa)) < 0) - { - Debug (2, "failed to read SP (ret=%d)\n", ret); - return ret; - } -#else -# error Implement me! -#endif - } - else - c->dwarf.ip = 0; - } - ret = (c->dwarf.ip == 0) ? 0 : 1; - Debug (2, "returning %d\n", ret); - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lglobal.c deleted file mode 100644 index 6d7b489e14bd9f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Lglobal.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Linit.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9fa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/get_accessors.c b/src/coreclr/src/pal/src/libunwind/src/hppa/get_accessors.c deleted file mode 100644 index 24795801b286e2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/get_accessors.c +++ /dev/null @@ -1,38 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by ... - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -HIDDEN ALIAS(unw_get_accessors) unw_accessors_t * -unw_get_accessors_int (unw_addr_space_t as); - -unw_accessors_t * -unw_get_accessors (unw_addr_space_t as) -{ - if (!tdep_init_done) - tdep_init (); - - return &as->acc; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/hppa/getcontext.S deleted file mode 100644 index ec7554a0259336..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/getcontext.S +++ /dev/null @@ -1,74 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 SPILL(n) stw %r##n, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_GR_OFF+4*(n))(%r26) - -#include "offsets.h" - - .align 4 - .protected _Uhppa_getcontext - .global _Uhppa_getcontext - .proc - .callinfo -_Uhppa_getcontext: - SPILL (2) /* return-pointer */ - SPILL (3) /* frame pointer */ - SPILL (4) /* 2nd-ary frame pointer */ - SPILL (5) /* preserved register */ - SPILL (6) /* preserved register */ - SPILL (7) /* preserved register */ - SPILL (8) /* preserved register */ - SPILL (9) /* preserved register */ - SPILL (10) /* preserved register */ - SPILL (11) /* preserved register */ - SPILL (12) /* preserved register */ - SPILL (13) /* preserved register */ - SPILL (14) /* preserved register */ - SPILL (15) /* preserved register */ - SPILL (16) /* preserved register */ - SPILL (17) /* preserved register */ - SPILL (18) /* preserved register */ - SPILL (19) /* linkage-table register */ - SPILL (27) /* global-data pointer */ - SPILL (30) /* stack pointer */ - - ldo (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FR_OFF)(%r26), %r29 - fstds,ma %fr12, 8(%r29) - fstds,ma %fr13, 8(%r29) - fstds,ma %fr14, 8(%r29) - fstds,ma %fr15, 8(%r29) - fstds,ma %fr16, 8(%r29) - fstds,ma %fr17, 8(%r29) - fstds,ma %fr18, 8(%r29) - fstds,ma %fr19, 8(%r29) - fstds,ma %fr20, 8(%r29) - fstds %fr21, 8(%r29) - - bv,n %r0(%rp) - .procend -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/init.h b/src/coreclr/src/pal/src/libunwind/src/hppa/init.h deleted file mode 100644 index 4e23b8613273e9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/init.h +++ /dev/null @@ -1,47 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by ... - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static inline int -common_init (struct cursor *c, unsigned use_prev_instr) -{ - int ret; - - c->dwarf.loc[UNW_HPPA_IP] = DWARF_REG_LOC (&c->dwarf, UNW_HPPA_IP); - c->dwarf.loc[UNW_HPPA_SP] = DWARF_REG_LOC (&c->dwarf, UNW_HPPA_SP); - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_IP], &c->dwarf.ip); - if (ret < 0) - return ret; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_SP], &c->dwarf.cfa); - if (ret < 0) - return ret; - - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/offsets.h b/src/coreclr/src/pal/src/libunwind/src/hppa/offsets.h deleted file mode 100644 index 24e6453ac4f546..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/offsets.h +++ /dev/null @@ -1,17 +0,0 @@ -#define LINUX_UC_FLAGS_OFF 0x000 -#define LINUX_UC_LINK_OFF 0x004 -#define LINUX_UC_STACK_OFF 0x008 -#define LINUX_UC_MCONTEXT_OFF 0x018 -#define LINUX_UC_SIGMASK_OFF 0x1b8 - -#define LINUX_SC_FLAGS_OFF 0x000 -#define LINUX_SC_GR_OFF 0x004 -#define LINUX_SC_FR_OFF 0x088 -#define LINUX_SC_IASQ_OFF 0x188 -#define LINUX_SC_IAOQ_OFF 0x190 -#define LINUX_SC_SAR_OFF 0x198 - -/* The signal frame contains 4 words of space for the sigreturn - trampoline, the siginfo structure, and then the sigcontext - structure. See include/asm-parisc/compat_rt_sigframe.h. */ -#define LINUX_RT_SIGFRAME_UC_OFF 0xac diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/regname.c b/src/coreclr/src/pal/src/libunwind/src/hppa/regname.c deleted file mode 100644 index 5698a58ada9c8e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/regname.c +++ /dev/null @@ -1,50 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static const char *regname[] = - { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", - "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", - "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", - "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31", - "ip", - "eh0", "eh1", "eh2", "eh3", - "cfa" - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/hppa/setcontext.S deleted file mode 100644 index a36ea35cc613ef..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/setcontext.S +++ /dev/null @@ -1,77 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* The setcontext() in glibc is a no-op (as of 4 Dec 2004), so we have - to implement something useful on our own here. */ - -#define FILL(n) ldw (LINUX_UC_MCONTEXT_OFF+LINUX_SC_GR_OFF+4*(n))(%r26),%r##n - -#include "offsets.h" - - .align 4 - .global _Uhppa_setcontext - .protected _Uhppa_setcontext - .proc - .callinfo -_Uhppa_setcontext: - FILL (2) /* return-pointer */ - FILL (3) /* frame pointer */ - FILL (4) /* 2nd-ary frame pointer */ - FILL (5) /* preserved register */ - FILL (6) /* preserved register */ - FILL (7) /* preserved register */ - FILL (8) /* preserved register */ - FILL (9) /* preserved register */ - FILL (10) /* preserved register */ - FILL (11) /* preserved register */ - FILL (12) /* preserved register */ - FILL (13) /* preserved register */ - FILL (14) /* preserved register */ - FILL (15) /* preserved register */ - FILL (16) /* preserved register */ - FILL (17) /* preserved register */ - FILL (18) /* preserved register */ - FILL (19) /* linkage-table register */ - FILL (27) /* global-data pointer */ - FILL (30) /* stack pointer */ - - ldo (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FR_OFF)(%r26), %r29 - fldds,ma 8(%r29), %fr12 - fldds,ma 8(%r29), %fr13 - fldds,ma 8(%r29), %fr14 - fldds,ma 8(%r29), %fr15 - fldds,ma 8(%r29), %fr16 - fldds,ma 8(%r29), %fr17 - fldds,ma 8(%r29), %fr18 - fldds,ma 8(%r29), %fr19 - fldds,ma 8(%r29), %fr20 - fldds 8(%r29), %fr21 - - bv,n %r0(%rp) - .procend -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/hppa/siglongjmp.S deleted file mode 100644 index 34878dbe8f374a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/siglongjmp.S +++ /dev/null @@ -1,16 +0,0 @@ - /* Dummy implementation for now. */ - - .globl _UI_siglongjmp_cont - .globl _UI_longjmp_cont - -_UI_siglongjmp_cont: -_UI_longjmp_cont: - .proc - .callinfo -#warning fix me - bv %r0(%rp) - .procend -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/tables.c b/src/coreclr/src/pal/src/libunwind/src/hppa/tables.c deleted file mode 100644 index 5104d4d342971d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/tables.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "unwind_i.h" - -static inline int -is_local_addr_space (unw_addr_space_t as) -{ - extern unw_addr_space_t _ULhppa_local_addr_space; - - return (as == _Uhppa_local_addr_space -#ifndef UNW_REMOTE_ONLY - || as == _ULhppa_local_addr_space -#endif - ); -} - -HIDDEN int -tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, int need_unwind_info, void *arg) -{ - printf ("%s: begging to get implemented...\n", __FUNCTION__); - return 0; -} - -HIDDEN int -tdep_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) -{ - printf ("%s: the biggest beggar of them all...\n", __FUNCTION__); - return 0; -} - -HIDDEN void -tdep_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) -{ - if (!pi->unwind_info) - return; - - if (!is_local_addr_space (as)) - { - free (pi->unwind_info); - pi->unwind_info = NULL; - } -} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/hppa/unwind_i.h deleted file mode 100644 index cafeab57b88312..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/unwind_i.h +++ /dev/null @@ -1,47 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 unwind_i_h -#define unwind_i_h - -#include - -#include - -#include "libunwind_i.h" - -#define hppa_lock UNW_OBJ(lock) -#define hppa_local_resume UNW_OBJ(local_resume) -#define hppa_local_addr_space_init UNW_OBJ(local_addr_space_init) -#define hppa_scratch_loc UNW_OBJ(scratch_loc) -#define setcontext UNW_ARCH_OBJ (setcontext) - -extern void hppa_local_addr_space_init (void); -extern int hppa_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, - void *arg); -extern dwarf_loc_t hppa_scratch_loc (struct cursor *c, unw_regnum_t reg); -extern int setcontext (const ucontext_t *ucp); - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gapply_reg_state.c deleted file mode 100644 index b45d1b5d9cc411..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gapply_reg_state.c +++ /dev/null @@ -1,39 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - // Needs dwarf support on ia64 - // return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); - return -UNW_EINVAL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gcreate_addr_space.c deleted file mode 100644 index 7ad29cbbd39357..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gcreate_addr_space.c +++ /dev/null @@ -1,63 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* - * IA-64 supports only big or little-endian, not weird stuff like - * PDP_ENDIAN. - */ - if (byte_order != 0 - && byte_order != __LITTLE_ENDIAN - && byte_order != __BIG_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - if (byte_order == 0) - /* use host default: */ - as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); - else - as->big_endian = (byte_order == __BIG_ENDIAN); - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gfind_unwind_table.c deleted file mode 100644 index 9fd2707ace499f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gfind_unwind_table.c +++ /dev/null @@ -1,143 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include -#include -#include -#include - -#include - -#include "libunwind_i.h" -#include "elf64.h" - -static unw_word_t -find_gp (struct elf_dyn_info *edi, Elf64_Phdr *pdyn, Elf64_Addr load_base) -{ - Elf64_Off soff, str_soff; - Elf64_Ehdr *ehdr = edi->ei.image; - Elf64_Shdr *shdr; - Elf64_Shdr *str_shdr; - Elf64_Addr gp = 0; - char *strtab; - int i; - - if (pdyn) - { - /* If we have a PT_DYNAMIC program header, fetch the gp-value - from the DT_PLTGOT entry. */ - Elf64_Dyn *dyn = (Elf64_Dyn *) (pdyn->p_offset + (char *) edi->ei.image); - for (; dyn->d_tag != DT_NULL; ++dyn) - if (dyn->d_tag == DT_PLTGOT) - { - gp = (Elf64_Addr) dyn->d_un.d_ptr + load_base; - goto done; - } - } - - /* Without a PT_DYAMIC header, lets try to look for a non-empty .opd - section. If there is such a section, we know it's full of - function descriptors, and we can simply pick up the gp from the - second word of the first entry in this table. */ - - soff = ehdr->e_shoff; - str_soff = soff + (ehdr->e_shstrndx * ehdr->e_shentsize); - - if (soff + ehdr->e_shnum * ehdr->e_shentsize > edi->ei.size) - { - Debug (1, "section table outside of image? (%lu > %lu)", - soff + ehdr->e_shnum * ehdr->e_shentsize, - edi->ei.size); - goto done; - } - - shdr = (Elf64_Shdr *) ((char *) edi->ei.image + soff); - str_shdr = (Elf64_Shdr *) ((char *) edi->ei.image + str_soff); - strtab = (char *) edi->ei.image + str_shdr->sh_offset; - for (i = 0; i < ehdr->e_shnum; ++i) - { - if (strcmp (strtab + shdr->sh_name, ".opd") == 0 - && shdr->sh_size >= 16) - { - gp = ((Elf64_Addr *) ((char *) edi->ei.image + shdr->sh_offset))[1]; - goto done; - } - shdr = (Elf64_Shdr *) (((char *) shdr) + ehdr->e_shentsize); - } - - done: - Debug (16, "image at %p, gp = %lx\n", edi->ei.image, gp); - return gp; -} - -int -ia64_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, - char *path, unw_word_t segbase, unw_word_t mapoff, - unw_word_t ip) -{ - Elf64_Phdr *phdr, *ptxt = NULL, *punw = NULL, *pdyn = NULL; - Elf64_Ehdr *ehdr; - int i; - - if (!_Uelf64_valid_object (&edi->ei)) - return -UNW_ENOINFO; - - ehdr = edi->ei.image; - phdr = (Elf64_Phdr *) ((char *) edi->ei.image + ehdr->e_phoff); - - for (i = 0; i < ehdr->e_phnum; ++i) - { - switch (phdr[i].p_type) - { - case PT_LOAD: - if (phdr[i].p_offset == mapoff) - ptxt = phdr + i; - break; - - case PT_IA_64_UNWIND: - punw = phdr + i; - break; - - case PT_DYNAMIC: - pdyn = phdr + i; - break; - - default: - break; - } - } - if (!ptxt || !punw) - return 0; - - edi->di_cache.start_ip = segbase; - edi->di_cache.end_ip = edi->di_cache.start_ip + ptxt->p_memsz; - edi->di_cache.gp = find_gp (edi, pdyn, segbase - ptxt->p_vaddr); - edi->di_cache.format = UNW_INFO_FORMAT_TABLE; - edi->di_cache.u.ti.name_ptr = 0; - edi->di_cache.u.ti.segbase = segbase; - edi->di_cache.u.ti.table_len = punw->p_memsz / sizeof (unw_word_t); - edi->di_cache.u.ti.table_data = (unw_word_t *) - ((char *) edi->ei.image + (punw->p_vaddr - ptxt->p_vaddr)); - return 1; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_proc_info.c deleted file mode 100644 index 3ec82b9f82c238..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_proc_info.c +++ /dev/null @@ -1,38 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - if ((ret = ia64_make_proc_info (c)) < 0) - return ret; - *pi = c->pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_save_loc.c deleted file mode 100644 index 34efe99a752fc6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_save_loc.c +++ /dev/null @@ -1,168 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2003, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "rse.h" - -#include "offsets.h" -#include "regs.h" - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - struct cursor *c = (struct cursor *) cursor; - ia64_loc_t loc, reg_loc; - uint8_t nat_bitnr; - int ret; - - loc = IA64_NULL_LOC; /* default to "not saved" */ - - switch (reg) - { - /* frame registers */ - case UNW_IA64_BSP: - case UNW_REG_SP: - default: - break; - - case UNW_REG_IP: - loc = c->loc[IA64_REG_IP]; - break; - - /* preserved registers: */ - case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: - loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_GR + 4))]; - break; - - case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7: - loc = c->loc[IA64_REG_NAT4 + (reg - (UNW_IA64_NAT + 4))]; - reg_loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_NAT + 4))]; - nat_bitnr = c->nat_bitnr[reg - (UNW_IA64_NAT + 4)]; - if (IA64_IS_FP_LOC (reg_loc)) - /* NaT bit saved as a NaTVal. */ - loc = reg_loc; - break; - - case UNW_IA64_FR + 2: loc = c->loc[IA64_REG_F2]; break; - case UNW_IA64_FR + 3: loc = c->loc[IA64_REG_F3]; break; - case UNW_IA64_FR + 4: loc = c->loc[IA64_REG_F4]; break; - case UNW_IA64_FR + 5: loc = c->loc[IA64_REG_F5]; break; - case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: - loc = c->loc[IA64_REG_F16 + (reg - (UNW_IA64_FR + 16))]; - break; - - case UNW_IA64_AR_BSP: loc = c->loc[IA64_REG_BSP]; break; - case UNW_IA64_AR_BSPSTORE: loc = c->loc[IA64_REG_BSPSTORE]; break; - case UNW_IA64_AR_PFS: loc = c->loc[IA64_REG_PFS]; break; - case UNW_IA64_AR_RNAT: loc = c->loc[IA64_REG_RNAT]; break; - case UNW_IA64_AR_UNAT: loc = c->loc[IA64_REG_UNAT]; break; - case UNW_IA64_AR_LC: loc = c->loc[IA64_REG_LC]; break; - case UNW_IA64_AR_FPSR: loc = c->loc[IA64_REG_FPSR]; break; - case UNW_IA64_BR + 1: loc = c->loc[IA64_REG_B1]; break; - case UNW_IA64_BR + 2: loc = c->loc[IA64_REG_B2]; break; - case UNW_IA64_BR + 3: loc = c->loc[IA64_REG_B3]; break; - case UNW_IA64_BR + 4: loc = c->loc[IA64_REG_B4]; break; - case UNW_IA64_BR + 5: loc = c->loc[IA64_REG_B5]; break; - case UNW_IA64_CFM: loc = c->cfm_loc; break; - case UNW_IA64_PR: loc = c->loc[IA64_REG_PR]; break; - - case UNW_IA64_GR + 32 ... UNW_IA64_GR + 127: /* stacked reg */ - reg = rotate_gr (c, reg - UNW_IA64_GR); - ret = ia64_get_stacked (c, reg, &loc, NULL); - if (ret < 0) - return ret; - break; - - case UNW_IA64_NAT + 32 ... UNW_IA64_NAT + 127: /* stacked reg */ - reg = rotate_gr (c, reg - UNW_IA64_NAT); - ret = ia64_get_stacked (c, reg, NULL, &loc); - break; - - case UNW_IA64_AR_EC: - loc = c->cfm_loc; - break; - - /* scratch & special registers: */ - - case UNW_IA64_GR + 0: - case UNW_IA64_GR + 1: /* global pointer */ - case UNW_IA64_NAT + 0: - case UNW_IA64_NAT + 1: /* global pointer */ - case UNW_IA64_FR + 0: - case UNW_IA64_FR + 1: - break; - - case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: - case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: - loc = ia64_scratch_loc (c, reg, &nat_bitnr); - break; - - case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: - case UNW_IA64_GR + 8 ... UNW_IA64_GR + 31: - case UNW_IA64_BR + 0: - case UNW_IA64_BR + 6: - case UNW_IA64_BR + 7: - case UNW_IA64_AR_RSC: - case UNW_IA64_AR_CSD: - case UNW_IA64_AR_SSD: - case UNW_IA64_AR_CCV: - loc = ia64_scratch_loc (c, reg, NULL); - break; - - case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: - loc = ia64_scratch_loc (c, reg, NULL); - break; - - case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: - reg = rotate_fr (c, reg - UNW_IA64_FR) + UNW_IA64_FR; - loc = ia64_scratch_loc (c, reg, NULL); - break; - } - - memset (sloc, 0, sizeof (*sloc)); - - if (IA64_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (IA64_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = IA64_GET_REG (loc); - sloc->extra.nat_bitnr = nat_bitnr; - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = IA64_GET_ADDR (loc); - sloc->extra.nat_bitnr = nat_bitnr; - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gglobal.c deleted file mode 100644 index 5c6156f0e22f57..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gglobal.c +++ /dev/null @@ -1,122 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -HIDDEN struct ia64_global_unwind_state unw = - { - .lock = PTHREAD_MUTEX_INITIALIZER, - .save_order = { - IA64_REG_IP, IA64_REG_PFS, IA64_REG_PSP, IA64_REG_PR, - IA64_REG_UNAT, IA64_REG_LC, IA64_REG_FPSR, IA64_REG_PRI_UNAT_GR - }, -#if UNW_DEBUG - .preg_name = { - "pri_unat_gr", "pri_unat_mem", "psp", "bsp", "bspstore", - "ar.pfs", "ar.rnat", "rp", - "r4", "r5", "r6", "r7", - "nat4", "nat5", "nat6", "nat7", - "ar.unat", "pr", "ar.lc", "ar.fpsr", - "b1", "b2", "b3", "b4", "b5", - "f2", "f3", "f4", "f5", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" - } -#endif -}; - -HIDDEN void -tdep_init (void) -{ - const uint8_t f1_bytes[16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - const uint8_t nat_val_bytes[16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - const uint8_t int_val_bytes[16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - intrmask_t saved_mask; - uint8_t *lep, *bep; - long i; - - sigfillset (&unwi_full_mask); - - lock_acquire (&unw.lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - mempool_init (&unw.reg_state_pool, sizeof (struct ia64_reg_state), 0); - mempool_init (&unw.labeled_state_pool, - sizeof (struct ia64_labeled_state), 0); - - unw.read_only.r0 = 0; - unw.read_only.f0.raw.bits[0] = 0; - unw.read_only.f0.raw.bits[1] = 0; - - lep = (uint8_t *) &unw.read_only.f1_le + 16; - bep = (uint8_t *) &unw.read_only.f1_be; - for (i = 0; i < 16; ++i) - { - *--lep = f1_bytes[i]; - *bep++ = f1_bytes[i]; - } - - lep = (uint8_t *) &unw.nat_val_le + 16; - bep = (uint8_t *) &unw.nat_val_be; - for (i = 0; i < 16; ++i) - { - *--lep = nat_val_bytes[i]; - *bep++ = nat_val_bytes[i]; - } - - lep = (uint8_t *) &unw.int_val_le + 16; - bep = (uint8_t *) &unw.int_val_be; - for (i = 0; i < 16; ++i) - { - *--lep = int_val_bytes[i]; - *bep++ = int_val_bytes[i]; - } - - assert (8*sizeof(unw_hash_index_t) >= IA64_LOG_UNW_HASH_SIZE); - -#ifndef UNW_REMOTE_ONLY - ia64_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&unw.lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c deleted file mode 100644 index b09a2ad57c7a72..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c +++ /dev/null @@ -1,505 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2005 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -#ifdef HAVE_SYS_UC_ACCESS_H -# include -#endif - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -#ifdef HAVE_SYS_UC_ACCESS_H - -#else /* !HAVE_SYS_UC_ACCESS_H */ - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg, uint8_t *nat_bitnr) -{ - return inlined_uc_addr (uc, reg, nat_bitnr); -} - -#endif /* !HAVE_SYS_UC_ACCESS_H */ - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - *dyn_info_list_addr = _U_dyn_info_list_addr (); - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (write) - { - Debug (12, "mem[%lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "mem[%lx] -> %lx\n", addr, *val); - } - return 0; -} - -#ifdef HAVE_SYS_UC_ACCESS_H - -#define SYSCALL_CFM_SAVE_REG 11 /* on a syscall, ar.pfs is saved in r11 */ -#define REASON_SYSCALL 0 - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - ucontext_t *uc = arg; - unsigned int nat, mask; - uint64_t value; - uint16_t reason; - int ret; - - __uc_get_reason (uc, &reason); - - switch (reg) - { - case UNW_IA64_GR ... UNW_IA64_GR + 31: - if ((ret = __uc_get_grs (uc, (reg - UNW_IA64_GR), 1, &value, &nat))) - break; - - if (write) - ret = __uc_set_grs (uc, (reg - UNW_IA64_GR), 1, val, nat); - else - *val = value; - break; - - case UNW_IA64_NAT ... UNW_IA64_NAT + 31: - if ((ret = __uc_get_grs (uc, (reg - UNW_IA64_GR), 1, &value, &nat))) - break; - - mask = 1 << (reg - UNW_IA64_GR); - - if (write) - { - if (*val) - nat |= mask; - else - nat &= ~mask; - ret = __uc_set_grs (uc, (reg - UNW_IA64_GR), 1, &value, nat); - } - else - *val = (nat & mask) != 0; - break; - - case UNW_IA64_AR ... UNW_IA64_AR + 127: - if (reg == UNW_IA64_AR_BSP) - { - if (write) - ret = __uc_set_ar (uc, (reg - UNW_IA64_AR), *val); - else - ret = __uc_get_ar (uc, (reg - UNW_IA64_AR), val); - } - else if (reg == UNW_IA64_AR_PFS && reason == REASON_SYSCALL) - { - /* As of HP-UX 11.22, getcontext() does not have unwind info - and because of that, we need to hack thins manually here. - Hopefully, this is OK because the HP-UX kernel also needs - to know where AR.PFS has been saved, so the use of - register r11 for this purpose is pretty much nailed - down. */ - if (write) - ret = __uc_set_grs (uc, SYSCALL_CFM_SAVE_REG, 1, val, 0); - else - ret = __uc_get_grs (uc, SYSCALL_CFM_SAVE_REG, 1, val, &nat); - } - else - { - if (write) - ret = __uc_set_ar (uc, (reg - UNW_IA64_AR), *val); - else - ret = __uc_get_ar (uc, (reg - UNW_IA64_AR), val); - } - break; - - case UNW_IA64_BR ... UNW_IA64_BR + 7: - if (write) - ret = __uc_set_brs (uc, (reg - UNW_IA64_BR), 1, val); - else - ret = __uc_get_brs (uc, (reg - UNW_IA64_BR), 1, val); - break; - - case UNW_IA64_PR: - if (write) - ret = __uc_set_prs (uc, *val); - else - ret = __uc_get_prs (uc, val); - break; - - case UNW_IA64_IP: - if (write) - ret = __uc_set_ip (uc, *val); - else - ret = __uc_get_ip (uc, val); - break; - - case UNW_IA64_CFM: - if (write) - ret = __uc_set_cfm (uc, *val); - else - ret = __uc_get_cfm (uc, val); - break; - - case UNW_IA64_FR ... UNW_IA64_FR + 127: - default: - ret = EINVAL; - break; - } - - if (ret != 0) - { - Debug (1, "failed to %s %s (ret = %d)\n", - write ? "write" : "read", unw_regname (reg), ret); - return -UNW_EBADREG; - } - - if (write) - Debug (12, "%s <- %lx\n", unw_regname (reg), *val); - else - Debug (12, "%s -> %lx\n", unw_regname (reg), *val); - return 0; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = arg; - fp_regval_t fp_regval; - int ret; - - switch (reg) - { - case UNW_IA64_FR ... UNW_IA64_FR + 127: - if (write) - { - memcpy (&fp_regval, val, sizeof (fp_regval)); - ret = __uc_set_frs (uc, (reg - UNW_IA64_FR), 1, &fp_regval); - } - else - { - ret = __uc_get_frs (uc, (reg - UNW_IA64_FR), 1, &fp_regval); - memcpy (val, &fp_regval, sizeof (*val)); - } - break; - - default: - ret = EINVAL; - break; - } - if (ret != 0) - return -UNW_EBADREG; - - return 0; -} - -#else /* !HAVE_SYS_UC_ACCESS_H */ - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr, mask; - ucontext_t *uc = arg; - - if (reg >= UNW_IA64_NAT + 4 && reg <= UNW_IA64_NAT + 7) - { - mask = ((unw_word_t) 1) << (reg - UNW_IA64_NAT); - if (write) - { - if (*val) - uc->uc_mcontext.sc_nat |= mask; - else - uc->uc_mcontext.sc_nat &= ~mask; - } - else - *val = (uc->uc_mcontext.sc_nat & mask) != 0; - - if (write) - Debug (12, "%s <- %lx\n", unw_regname (reg), *val); - else - Debug (12, "%s -> %lx\n", unw_regname (reg), *val); - return 0; - } - - addr = tdep_uc_addr (uc, reg, NULL); - if (!addr) - goto badreg; - - if (write) - { - if (ia64_read_only_reg (addr)) - { - Debug (16, "attempt to write read-only register\n"); - return -UNW_EREADONLYREG; - } - *addr = *val; - Debug (12, "%s <- %lx\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> %lx\n", unw_regname (reg), *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = arg; - unw_fpreg_t *addr; - - if (reg < UNW_IA64_FR || reg >= UNW_IA64_FR + 128) - goto badreg; - - addr = tdep_uc_addr (uc, reg, NULL); - if (!addr) - goto badreg; - - if (write) - { - if (ia64_read_only_reg (addr)) - { - Debug (16, "attempt to write read-only register\n"); - return -UNW_EREADONLYREG; - } - *addr = *val; - Debug (12, "%s <- %016lx.%016lx\n", - unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %016lx.%016lx\n", - unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -#endif /* !HAVE_SYS_UC_ACCESS_H */ - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -ia64_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); -#if defined(__linux) - local_addr_space.abi = ABI_LINUX; -#elif defined(__hpux) - local_addr_space.abi = ABI_HPUX; -#endif - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = tdep_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = ia64_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ - -#ifndef UNW_LOCAL_ONLY - -HIDDEN int -ia64_uc_access_reg (struct cursor *c, ia64_loc_t loc, unw_word_t *valp, - int write) -{ -#ifdef HAVE_SYS_UC_ACCESS_H - unw_word_t uc_addr = IA64_GET_AUX_ADDR (loc); - ucontext_t *ucp; - int ret; - - Debug (16, "%s location %s\n", - write ? "writing" : "reading", ia64_strloc (loc)); - - if (c->as == unw_local_addr_space) - ucp = (ucontext_t *) uc_addr; - else - { - unw_word_t *dst, src; - - /* Need to copy-in ucontext_t first. */ - ucp = alloca (sizeof (ucontext_t)); - if (!ucp) - return -UNW_ENOMEM; - - /* For now, there is no non-HP-UX implementation of the - uc_access(3) interface. Because of that, we cannot, e.g., - unwind an HP-UX program from a Linux program. Should that - become possible at some point in the future, the - copy-in/copy-out needs to be adjusted to do byte-swapping if - necessary. */ - assert (c->as->big_endian == (__BYTE_ORDER == __BIG_ENDIAN)); - - dst = (unw_word_t *) ucp; - for (src = uc_addr; src < uc_addr + sizeof (ucontext_t); src += 8) - if ((ret = (*c->as->acc.access_mem) (c->as, src, dst++, 0, c->as_arg)) - < 0) - return ret; - } - - if (IA64_IS_REG_LOC (loc)) - ret = access_reg (unw_local_addr_space, IA64_GET_REG (loc), valp, write, - ucp); - else - { - /* Must be an access to the RSE backing store in ucontext_t. */ - unw_word_t addr = IA64_GET_ADDR (loc); - - if (write) - ret = __uc_set_rsebs (ucp, (uint64_t *) addr, 1, valp); - else - ret = __uc_get_rsebs (ucp, (uint64_t *) addr, 1, valp); - if (ret != 0) - ret = -UNW_EBADREG; - } - if (ret < 0) - return ret; - - if (write && c->as != unw_local_addr_space) - { - /* need to copy-out ucontext_t: */ - unw_word_t dst, *src = (unw_word_t *) ucp; - for (dst = uc_addr; dst < uc_addr + sizeof (ucontext_t); dst += 8) - if ((ret = (*c->as->acc.access_mem) (c->as, dst, src++, 1, c->as_arg)) - < 0) - return ret; - } - return 0; -#else /* !HAVE_SYS_UC_ACCESS_H */ - return -UNW_EINVAL; -#endif /* !HAVE_SYS_UC_ACCESS_H */ -} - -HIDDEN int -ia64_uc_access_fpreg (struct cursor *c, ia64_loc_t loc, unw_fpreg_t *valp, - int write) -{ -#ifdef HAVE_SYS_UC_ACCESS_H - unw_word_t uc_addr = IA64_GET_AUX_ADDR (loc); - ucontext_t *ucp; - int ret; - - if (c->as == unw_local_addr_space) - ucp = (ucontext_t *) uc_addr; - else - { - unw_word_t *dst, src; - - /* Need to copy-in ucontext_t first. */ - ucp = alloca (sizeof (ucontext_t)); - if (!ucp) - return -UNW_ENOMEM; - - /* For now, there is no non-HP-UX implementation of the - uc_access(3) interface. Because of that, we cannot, e.g., - unwind an HP-UX program from a Linux program. Should that - become possible at some point in the future, the - copy-in/copy-out needs to be adjusted to do byte-swapping if - necessary. */ - assert (c->as->big_endian == (__BYTE_ORDER == __BIG_ENDIAN)); - - dst = (unw_word_t *) ucp; - for (src = uc_addr; src < uc_addr + sizeof (ucontext_t); src += 8) - if ((ret = (*c->as->acc.access_mem) (c->as, src, dst++, 0, c->as_arg)) - < 0) - return ret; - } - - if ((ret = access_fpreg (unw_local_addr_space, IA64_GET_REG (loc), valp, - write, ucp)) < 0) - return ret; - - if (write && c->as != unw_local_addr_space) - { - /* need to copy-out ucontext_t: */ - unw_word_t dst, *src = (unw_word_t *) ucp; - for (dst = uc_addr; dst < uc_addr + sizeof (ucontext_t); dst += 8) - if ((ret = (*c->as->acc.access_mem) (c->as, dst, src++, 1, c->as_arg)) - < 0) - return ret; - } - return 0; -#else /* !HAVE_SYS_UC_ACCESS_H */ - return -UNW_EINVAL; -#endif /* !HAVE_SYS_UC_ACCESS_H */ -} - -#endif /* UNW_LOCAL_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_local.c deleted file mode 100644 index 8fe1c679b29e94..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_local.c +++ /dev/null @@ -1,110 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2003, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "init.h" -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static inline void -set_as_arg (struct cursor *c, unw_context_t *uc) -{ -#if defined(__linux) && defined(__KERNEL__) - c->task = current; - c->as_arg = &uc->sw; -#else - c->as_arg = uc; -#endif -} - -static inline int -get_initial_stack_pointers (struct cursor *c, unw_context_t *uc, - unw_word_t *sp, unw_word_t *bsp) -{ -#if defined(__linux) - unw_word_t sol, bspstore; - -#ifdef __KERNEL__ - sol = (uc->sw.ar_pfs >> 7) & 0x7f; - bspstore = uc->sw.ar_bspstore; - *sp = uc->ksp; -# else - sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f; - bspstore = uc->uc_mcontext.sc_ar_bsp; - *sp = uc->uc_mcontext.sc_gr[12]; -# endif - *bsp = rse_skip_regs (bspstore, -sol); -#elif defined(__hpux) - int ret; - - if ((ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_GR + 12), sp)) < 0 - || (ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_AR_BSP), bsp)) < 0) - return ret; -#else -# error Fix me. -#endif - return 0; -} - -int -unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t sp, bsp; - int ret; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->as = unw_local_addr_space; - set_as_arg (c, uc); - - if ((ret = get_initial_stack_pointers (c, uc, &sp, &bsp)) < 0) - return ret; - - Debug (4, "initial bsp=%lx, sp=%lx\n", bsp, sp); - - if ((ret = common_init (c, sp, bsp)) < 0) - return ret; - -#ifdef __hpux - /* On HP-UX, the context created by getcontext() points to the - getcontext() system call stub. Step over it: */ - ret = unw_step (cursor); -#endif - return ret; -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_remote.c deleted file mode 100644 index b570c7eab39ead..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_remote.c +++ /dev/null @@ -1,61 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002, 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - unw_word_t sp, bsp; - int ret; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - if (as == unw_local_addr_space) - /* This special-casing is unfortunate and shouldn't be needed; - however, both Linux and HP-UX need to adjust the context a bit - before it's usable. Try to think of a cleaner way of doing - this. Not sure it's possible though, as long as we want to be - able to use the context returned by getcontext() et al. */ - return unw_init_local (cursor, as_arg); - - c->as = as; - c->as_arg = as_arg; - - if ((ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_GR + 12), &sp)) < 0 - || (ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_AR_BSP), &bsp)) < 0) - return ret; - - return common_init (c, sp, bsp); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginstall_cursor.S b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginstall_cursor.S deleted file mode 100644 index 6fb4401faa2373..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginstall_cursor.S +++ /dev/null @@ -1,348 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "ucontext_i.h" - -#ifdef UNW_LOCAL_ONLY -# include "Lcursor_i.h" -# define ia64_install_cursor _ULia64_install_cursor -#else -# include "Gcursor_i.h" -# define ia64_install_cursor _Uia64_install_cursor -#endif - -#define SYS_sigreturn 1181 - -#ifndef UNW_REMOTE_ONLY - -/* ia64_install_cursor (const cursor *c, long pri_unat, long *extra, - long bspstore, long dirty_size, long *dirty_partition, - long dirty_rnat) - - Restores the machine-state represented by C and thereby resumes execution - in that frame. If the frame or one of its descendants was interrupted - by a signal, all registers are restored (including the signal mask). - Otherwise, only the preserved registers, the global-pointer (r1), and - the exception-arguments (r15-r18) are restored. */ - -#define pRet p6 -#define pSig p7 - - .align 32 - .hidden ia64_install_cursor - .global ia64_install_cursor - .proc ia64_install_cursor -ia64_install_cursor: - alloc r3 = ar.pfs, 7, 0, 0, 0 - invala - add r2 = FR_LOC_OFF, in0 - ;; - - ld8 r16 = [r2], LOC_SIZE // r16 = loc[IA64_REG_FR16] - mov.m r10 = ar.rsc // (ar.rsc: ~ 12 cycle latency) - add r3 = FR_LOC_OFF + 16, in0 - ;; - - ld8 r17 = [r2], 2*LOC_SIZE // r17 = loc[IA64_REG_FR17] - ld8 r18 = [r3], 2*LOC_SIZE // r18 = loc[IA64_REG_FR18] - and r16 = -4, r16 - ;; - - ld8 r19 = [r2], 2*LOC_SIZE // r19 = loc[IA64_REG_FR19] - ld8 r20 = [r3], 2*LOC_SIZE // r20 = loc[IA64_REG_FR20] - and r17 = -4, r17 - ;; - - ldf.fill f16 = [r16] // f16 restored (don't touch no more) - ldf.fill f17 = [r17] // f17 restored (don't touch no more) - and r18 = -4, r18 - - ld8 r21 = [r2], 2*LOC_SIZE // r21 = loc[IA64_REG_FR21] - ld8 r22 = [r3], 2*LOC_SIZE // r22 = loc[IA64_REG_FR22] - and r19 = -4, r19 - ;; - - ldf.fill f18 = [r18] // f18 restored (don't touch no more) - ldf.fill f19 = [r19] // f19 restored (don't touch no more) - and r20 = -4, r20 - - ld8 r23 = [r2], 2*LOC_SIZE // r23 = loc[IA64_REG_FR23] - ld8 r24 = [r3], 2*LOC_SIZE // r24 = loc[IA64_REG_FR24] - and r21 = -4, r21 - ;; - - ldf.fill f20 = [r20] // f20 restored (don't touch no more) - ldf.fill f21 = [r21] // f21 restored (don't touch no more) - and r22 = -4, r22 - - ld8 r25 = [r2], 2*LOC_SIZE // r25 = loc[IA64_REG_FR25] - ld8 r26 = [r3], 2*LOC_SIZE // r26 = loc[IA64_REG_FR26] - and r23 = -4, r23 - ;; - - ldf.fill f22 = [r22] // f22 restored (don't touch no more) - ldf.fill f23 = [r23] // f23 restored (don't touch no more) - and r24 = -4, r24 - - ld8 r27 = [r2], 2*LOC_SIZE // r27 = loc[IA64_REG_FR27] - ld8 r28 = [r3], 2*LOC_SIZE // r28 = loc[IA64_REG_FR28] - and r25 = -4, r25 - ;; - - ldf.fill f24 = [r24] // f24 restored (don't touch no more) - ldf.fill f25 = [r25] // f25 restored (don't touch no more) - and r26 = -4, r26 - - ld8 r29 = [r2], 2*LOC_SIZE // r29 = loc[IA64_REG_FR29] - ld8 r30 = [r3], 2*LOC_SIZE // r30 = loc[IA64_REG_FR30] - and r27 = -4, r27 - ;; - - ldf.fill f26 = [r26] // f26 restored (don't touch no more) - ldf.fill f27 = [r27] // f27 restored (don't touch no more) - and r28 = -4, r28 - - ld8 r31 = [r2] // r31 = loc[IA64_REG_FR31] - mov.m ar.unat = in1 - and r29 = -4, r29 - ;; - - ldf.fill f28 = [r28] // f28 restored (don't touch no more) - ldf.fill f29 = [r29] // f29 restored (don't touch no more) - and r30 = -4, r30 - - ld8 r1 = [in2], 8 // gp restored (don't touch no more) - add r8 = SIGCONTEXT_ADDR_OFF, in0 - and r31 = -4, r31 - ;; - - ld8 r8 = [r8] // r8 = sigcontext_addr - and r11 = 0x1c, r10 // clear all but rsc.be and rsc.pl - add r2 = PFS_LOC_OFF, in0 - - ldf.fill f30 = [r30] // f30 restored (don't touch no more) - ldf.fill f31 = [r31] // f31 restored (don't touch no more) - add r3 = 8, in2 - ;; - - ld8.fill r4 = [in2], 16 // r4 restored (don't touch no more) - ld8.fill r5 = [r3], 16 // r5 restored (don't touch no more) - cmp.eq pRet, pSig = r0, r8 // sigcontext_addr == NULL? - ;; - ld8.fill r6 = [in2], 16 // r6 restored (don't touch no more) - ld8.fill r7 = [r3] // r7 restored (don't touch no more) - add r3 = IP_OFF, in0 - ;; - - ld8 r14 = [r2], (B1_LOC_OFF - PFS_LOC_OFF) // r14 = pfs_loc - ld8 r15 = [r3] // r15 = ip - add r3 = (B2_LOC_OFF - IP_OFF), r3 - ;; - - ld8 r16 = [r2], (B3_LOC_OFF - B1_LOC_OFF) // r16 = b1_loc - ld8 r17= [r3], (B4_LOC_OFF - B2_LOC_OFF) // r17 = b2_loc - and r14 = -4, r14 - ;; - - ld8 r18 = [r2], (B5_LOC_OFF - B3_LOC_OFF) // r18 = b3_loc - ld8 r19 = [r3], (F2_LOC_OFF - B4_LOC_OFF) // r19 = b4_loc - and r16 = -4, r16 - ;; - - ld8 r20 = [r2], (F3_LOC_OFF - B5_LOC_OFF) // r20 = b5_loc - ld8 r21 = [r3], (F4_LOC_OFF - F2_LOC_OFF) // r21 = f2_loc - and r17 = -4, r17 - ;; - - ld8 r16 = [r16] // r16 = *b1_loc - ld8 r17 = [r17] // r17 = *b2_loc - and r18 = -4, r18 - - ld8 r22 = [r2], (F5_LOC_OFF - F3_LOC_OFF) // r21 = f3_loc - ld8 r23 = [r3], (UNAT_LOC_OFF - F4_LOC_OFF) // r22 = f4_loc - and r19 = -4, r19 - ;; - - ld8 r18 = [r18] // r18 = *b3_loc - ld8 r19 = [r19] // r19 = *b4_loc - and r20 = -4, r20 - - ld8 r24 = [r2], (LC_LOC_OFF - F5_LOC_OFF) // r24 = f5_loc - ld8 r25 = [r3], (FPSR_LOC_OFF - UNAT_LOC_OFF) // r25 = unat_loc - and r21 = -4, r21 - ;; - - and r22 = -4, r22 - and r23 = -4, r23 - and r24 = -4, r24 - - ld8 r20 = [r20] // r20 = *b5_loc - ldf.fill f2 = [r21] // f2 restored (don't touch no more) - mov b1 = r16 // b1 restored (don't touch no more) - ;; - - ldf.fill f3 = [r22] // f3 restored (don't touch no more) - ldf.fill f4 = [r23] // f4 restored (don't touch no more) - mov b2 = r17 // b2 restored (don't touch no more) - - ld8 r26 = [r2], (RNAT_LOC_OFF - LC_LOC_OFF) // r26 = lc_loc - ld8 r27 = [r3] // r27 = fpsr_loc - and r25 = -4, r25 - - add r3 = (PSP_OFF - FPSR_LOC_OFF), r3 - nop 0 - nop 0 - ;; - - ldf.fill f5 = [r24] // f5 restored (don't touch no more) -(pRet) ld8 r25 = [r25] // r25 = *unat_loc - mov b3 = r18 // b3 restored (don't touch no more) - - ld8 r28 = [r2], (BSP_OFF - RNAT_LOC_OFF) // r28 = rnat_loc - ld8 r29 = [r3], (PR_OFF - PSP_OFF) // r29 = sp - mov b4 = r19 // b4 restored (don't touch no more) - - and r26 = -4, r26 - and r27 = -4, r27 - mov b5 = r20 // b5 restored (don't touch no more) - ;; - - ld8 r26 = [r26] // r26 = *lc_loc - ld8 r27 = [r27] // r27 = *fpsr_loc - and r28 = -4, r28 - - mov r30 = in3 // make backup-copy of new bsp - ld8 r31 = [r3] // r31 = pr - mov rp = r15 - ;; - - ld8 r28 = [r28] // r28 = rnat - mov.m ar.rsc = r11 // put RSE into enforced lazy mode - mov.i ar.lc = r26 // lc restored (don't touch no more) - ;; - - loadrs // drop dirty partition - mov r9 = in2 // make backup-copy of &extra[r16] - cmp.eq p8, p0 = in4, r0 // dirty-size == 0? -(p8) br.cond.dpnt.many .skip_load_dirty - - mov r2 = in4 // make backup-copy of dirty_size - mov r15 = in5 // make backup-copy of dirty_partition - mov r16 = in6 // make backup-copy of dirty_rnat - ;; - - alloc r3 = ar.pfs, 0, 0, 0, 0 // drop register frame - dep r11 = r2, r11, 16, 16 - ;; - mov.m ar.bspstore = r15 - ;; - mov.m ar.rnat = r16 - mov.m ar.rsc = r11 // 14 cycles latency to loadrs - ;; - loadrs // loadup new dirty partition - ;; - -.skip_load_dirty: - mov.m ar.bspstore = r30 // restore register backing-store - add r3 = 8, r9 // r3 = &extra[r16] - ;; - -(pRet) mov.m ar.fpsr = r27 // fpsr restored (don't touch no more) - mov.m ar.rnat = r28 -(pSig) br.cond.dpnt.many .next - -/****** Return via br.ret: */ - - ld8 r14 = [r14] // r14 = *pfs_loc - ld8 r15 = [r9], 16 // r15 restored (don't touch no more) - mov pr = r31, -1 // pr restored (don't touch no more) - ;; - - ld8 r16 = [r3], 16 // r16 restored (don't touch no more) - ld8 r17 = [r9] // r17 restored (don't touch no more) - nop.i 0 - ;; - - ld8 r18 = [r3] // r18 restored (don't touch no more) - mov.m ar.rsc = r10 // restore original ar.rsc - mov sp = r29 - - mov.m ar.unat = r25 // unat restored (don't touch no more) - mov.i ar.pfs = r14 - br.ret.sptk.many rp - ;; - -/****** Return via sigreturn(): */ - -.next: mov.m ar.rsc = r10 // restore original ar.rsc - add r2 = (SC_FR + 6*16), r8 - add r3 = (SC_FR + 7*16), r8 - ;; - - ldf.fill f6 = [r2], 32 - ldf.fill f7 = [r3], 32 - nop 0 - ;; - - ldf.fill f8 = [r2], 32 - ldf.fill f9 = [r3], 32 - nop 0 - ;; - - ldf.fill f10 = [r2], 32 - ldf.fill f11 = [r3], 32 - nop 0 - ;; - - ldf.fill f12 = [r2], 32 - ldf.fill f13 = [r3], 32 - nop 0 - ;; - - ldf.fill f14 = [r2], 32 - ldf.fill f15 = [r3], 32 - mov sp = r29 - ;; - -#if NEW_SYSCALL - add r2 = 8, tp;; - ld8 r2 = [r2] - mov r15 = SYS_sigreturn - mov b7 = r2 - br.call.sptk.many b6 = b7 - ;; -#else - mov r15 = SYS_sigreturn - break 0x100000 -#endif - break 0 // bug out if sigreturn() returns - - .endp ia64_install_cursor - -#endif /* !UNW_REMOTE_ONLY */ -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gis_signal_frame.c deleted file mode 100644 index e268a0629986ae..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gis_signal_frame.c +++ /dev/null @@ -1,54 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - struct ia64_state_record sr; - int ret; - - /* Crude and slow, but we need to peek ahead into the unwind - descriptors to find out if the current IP is inside the signal - trampoline. */ - ret = ia64_fetch_proc_info (c, c->ip, 1); - if (ret < 0) - return ret; - - ret = ia64_create_state_record (c, &sr); - if (ret < 0) - return ret; - - /* For now, we assume that any non-zero abi marker implies a signal frame. - This should get us pretty far. */ - ret = (sr.abi_marker != 0); - - ia64_free_state_record (&sr); - - Debug (1, "(cursor=%p, ip=0x%016lx) -> %d\n", c, c->ip, ret); - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gparser.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gparser.c deleted file mode 100644 index b1f0f4a11826f2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gparser.c +++ /dev/null @@ -1,1131 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -/* forward declaration: */ -static int create_state_record_for (struct cursor *c, - struct ia64_state_record *sr, - unw_word_t ip); - -typedef unsigned long unw_word; - -#define alloc_reg_state() (mempool_alloc (&unw.reg_state_pool)) -#define free_reg_state(rs) (mempool_free (&unw.reg_state_pool, rs)) -#define alloc_labeled_state() (mempool_alloc (&unw.labeled_state_pool)) -#define free_labeled_state(s) (mempool_free (&unw.labeled_state_pool, s)) - -/* Routines to manipulate the state stack. */ - -static inline void -push (struct ia64_state_record *sr) -{ - struct ia64_reg_state *rs; - - rs = alloc_reg_state (); - if (!rs) - { - print_error ("libunwind: cannot stack reg state!\n"); - return; - } - memcpy (rs, &sr->curr, sizeof (*rs)); - sr->curr.next = rs; -} - -static void -pop (struct ia64_state_record *sr) -{ - struct ia64_reg_state *rs = sr->curr.next; - - if (!rs) - { - print_error ("libunwind: stack underflow!\n"); - return; - } - memcpy (&sr->curr, rs, sizeof (*rs)); - free_reg_state (rs); -} - -/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */ -static struct ia64_reg_state * -dup_state_stack (struct ia64_reg_state *rs) -{ - struct ia64_reg_state *copy, *prev = NULL, *first = NULL; - - while (rs) - { - copy = alloc_reg_state (); - if (!copy) - { - print_error ("unwind.dup_state_stack: out of memory\n"); - return NULL; - } - memcpy (copy, rs, sizeof (*copy)); - if (first) - prev->next = copy; - else - first = copy; - rs = rs->next; - prev = copy; - } - return first; -} - -/* Free all stacked register states (but not RS itself). */ -static void -free_state_stack (struct ia64_reg_state *rs) -{ - struct ia64_reg_state *p, *next; - - for (p = rs->next; p != NULL; p = next) - { - next = p->next; - free_reg_state (p); - } - rs->next = NULL; -} - -/* Unwind decoder routines */ - -static enum ia64_pregnum CONST_ATTR -decode_abreg (unsigned char abreg, int memory) -{ - switch (abreg) - { - case 0x04 ... 0x07: - return IA64_REG_R4 + (abreg - 0x04); - case 0x22 ... 0x25: - return IA64_REG_F2 + (abreg - 0x22); - case 0x30 ... 0x3f: - return IA64_REG_F16 + (abreg - 0x30); - case 0x41 ... 0x45: - return IA64_REG_B1 + (abreg - 0x41); - case 0x60: - return IA64_REG_PR; - case 0x61: - return IA64_REG_PSP; - case 0x62: - return memory ? IA64_REG_PRI_UNAT_MEM : IA64_REG_PRI_UNAT_GR; - case 0x63: - return IA64_REG_IP; - case 0x64: - return IA64_REG_BSP; - case 0x65: - return IA64_REG_BSPSTORE; - case 0x66: - return IA64_REG_RNAT; - case 0x67: - return IA64_REG_UNAT; - case 0x68: - return IA64_REG_FPSR; - case 0x69: - return IA64_REG_PFS; - case 0x6a: - return IA64_REG_LC; - default: - break; - } - Dprintf ("libunwind: bad abreg=0x%x\n", abreg); - return IA64_REG_LC; -} - -static void -set_reg (struct ia64_reg_info *reg, enum ia64_where where, int when, - unsigned long val) -{ - reg->val = val; - reg->where = where; - if (reg->when == IA64_WHEN_NEVER) - reg->when = when; -} - -static void -alloc_spill_area (unsigned long *offp, unsigned long regsize, - struct ia64_reg_info *lo, struct ia64_reg_info *hi) -{ - struct ia64_reg_info *reg; - - for (reg = hi; reg >= lo; --reg) - { - if (reg->where == IA64_WHERE_SPILL_HOME) - { - reg->where = IA64_WHERE_PSPREL; - *offp -= regsize; - reg->val = *offp; - } - } -} - -static inline void -spill_next_when (struct ia64_reg_info **regp, struct ia64_reg_info *lim, - unw_word t) -{ - struct ia64_reg_info *reg; - - for (reg = *regp; reg <= lim; ++reg) - { - if (reg->where == IA64_WHERE_SPILL_HOME) - { - reg->when = t; - *regp = reg + 1; - return; - } - } - Dprintf ("libunwind: excess spill!\n"); -} - -static inline void -finish_prologue (struct ia64_state_record *sr) -{ - struct ia64_reg_info *reg; - unsigned long off; - int i; - - /* First, resolve implicit register save locations (see Section - "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */ - for (i = 0; i < (int) ARRAY_SIZE (unw.save_order); ++i) - { - reg = sr->curr.reg + unw.save_order[i]; - if (reg->where == IA64_WHERE_GR_SAVE) - { - reg->where = IA64_WHERE_GR; - reg->val = sr->gr_save_loc++; - } - } - - /* Next, compute when the fp, general, and branch registers get - saved. This must come before alloc_spill_area() because we need - to know which registers are spilled to their home locations. */ - - if (sr->imask) - { - unsigned char kind, mask = 0, *cp = sr->imask; - unsigned long t; - static const unsigned char limit[3] = - { - IA64_REG_F31, IA64_REG_R7, IA64_REG_B5 - }; - struct ia64_reg_info *(regs[3]); - - regs[0] = sr->curr.reg + IA64_REG_F2; - regs[1] = sr->curr.reg + IA64_REG_R4; - regs[2] = sr->curr.reg + IA64_REG_B1; - - for (t = 0; (int) t < sr->region_len; ++t) - { - if ((t & 3) == 0) - mask = *cp++; - kind = (mask >> 2 * (3 - (t & 3))) & 3; - if (kind > 0) - spill_next_when (®s[kind - 1], sr->curr.reg + limit[kind - 1], - sr->region_start + t); - } - } - - /* Next, lay out the memory stack spill area. */ - - if (sr->any_spills) - { - off = sr->spill_offset; - alloc_spill_area (&off, 16, sr->curr.reg + IA64_REG_F2, - sr->curr.reg + IA64_REG_F31); - alloc_spill_area (&off, 8, sr->curr.reg + IA64_REG_B1, - sr->curr.reg + IA64_REG_B5); - alloc_spill_area (&off, 8, sr->curr.reg + IA64_REG_R4, - sr->curr.reg + IA64_REG_R7); - } -} - -/* Region header descriptors. */ - -static void -desc_prologue (int body, unw_word rlen, unsigned char mask, - unsigned char grsave, struct ia64_state_record *sr) -{ - int i, region_start; - - if (!(sr->in_body || sr->first_region)) - finish_prologue (sr); - sr->first_region = 0; - - /* check if we're done: */ - if (sr->when_target < sr->region_start + sr->region_len) - { - sr->done = 1; - return; - } - - region_start = sr->region_start + sr->region_len; - - for (i = 0; i < sr->epilogue_count; ++i) - pop (sr); - sr->epilogue_count = 0; - sr->when_sp_restored = IA64_WHEN_NEVER; - - sr->region_start = region_start; - sr->region_len = rlen; - sr->in_body = body; - - if (!body) - { - push (sr); - - if (mask) - for (i = 0; i < 4; ++i) - { - if (mask & 0x8) - set_reg (sr->curr.reg + unw.save_order[i], IA64_WHERE_GR, - sr->region_start + sr->region_len - 1, grsave++); - mask <<= 1; - } - sr->gr_save_loc = grsave; - sr->any_spills = 0; - sr->imask = 0; - sr->spill_offset = 0x10; /* default to psp+16 */ - } -} - -/* Prologue descriptors. */ - -static inline void -desc_abi (unsigned char abi, unsigned char context, - struct ia64_state_record *sr) -{ - sr->abi_marker = (abi << 8) | context; -} - -static inline void -desc_br_gr (unsigned char brmask, unsigned char gr, - struct ia64_state_record *sr) -{ - int i; - - for (i = 0; i < 5; ++i) - { - if (brmask & 1) - set_reg (sr->curr.reg + IA64_REG_B1 + i, IA64_WHERE_GR, - sr->region_start + sr->region_len - 1, gr++); - brmask >>= 1; - } -} - -static inline void -desc_br_mem (unsigned char brmask, struct ia64_state_record *sr) -{ - int i; - - for (i = 0; i < 5; ++i) - { - if (brmask & 1) - { - set_reg (sr->curr.reg + IA64_REG_B1 + i, IA64_WHERE_SPILL_HOME, - sr->region_start + sr->region_len - 1, 0); - sr->any_spills = 1; - } - brmask >>= 1; - } -} - -static inline void -desc_frgr_mem (unsigned char grmask, unw_word frmask, - struct ia64_state_record *sr) -{ - int i; - - for (i = 0; i < 4; ++i) - { - if ((grmask & 1) != 0) - { - set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_SPILL_HOME, - sr->region_start + sr->region_len - 1, 0); - sr->any_spills = 1; - } - grmask >>= 1; - } - for (i = 0; i < 20; ++i) - { - if ((frmask & 1) != 0) - { - int base = (i < 4) ? IA64_REG_F2 : IA64_REG_F16 - 4; - set_reg (sr->curr.reg + base + i, IA64_WHERE_SPILL_HOME, - sr->region_start + sr->region_len - 1, 0); - sr->any_spills = 1; - } - frmask >>= 1; - } -} - -static inline void -desc_fr_mem (unsigned char frmask, struct ia64_state_record *sr) -{ - int i; - - for (i = 0; i < 4; ++i) - { - if ((frmask & 1) != 0) - { - set_reg (sr->curr.reg + IA64_REG_F2 + i, IA64_WHERE_SPILL_HOME, - sr->region_start + sr->region_len - 1, 0); - sr->any_spills = 1; - } - frmask >>= 1; - } -} - -static inline void -desc_gr_gr (unsigned char grmask, unsigned char gr, - struct ia64_state_record *sr) -{ - int i; - - for (i = 0; i < 4; ++i) - { - if ((grmask & 1) != 0) - set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_GR, - sr->region_start + sr->region_len - 1, gr++); - grmask >>= 1; - } -} - -static inline void -desc_gr_mem (unsigned char grmask, struct ia64_state_record *sr) -{ - int i; - - for (i = 0; i < 4; ++i) - { - if ((grmask & 1) != 0) - { - set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_SPILL_HOME, - sr->region_start + sr->region_len - 1, 0); - sr->any_spills = 1; - } - grmask >>= 1; - } -} - -static inline void -desc_mem_stack_f (unw_word t, unw_word size, struct ia64_state_record *sr) -{ - set_reg (sr->curr.reg + IA64_REG_PSP, IA64_WHERE_NONE, - sr->region_start + MIN ((int) t, sr->region_len - 1), 16 * size); -} - -static inline void -desc_mem_stack_v (unw_word t, struct ia64_state_record *sr) -{ - sr->curr.reg[IA64_REG_PSP].when = - sr->region_start + MIN ((int) t, sr->region_len - 1); -} - -static inline void -desc_reg_gr (unsigned char reg, unsigned char dst, - struct ia64_state_record *sr) -{ - set_reg (sr->curr.reg + reg, IA64_WHERE_GR, - sr->region_start + sr->region_len - 1, dst); -} - -static inline void -desc_reg_psprel (unsigned char reg, unw_word pspoff, - struct ia64_state_record *sr) -{ - set_reg (sr->curr.reg + reg, IA64_WHERE_PSPREL, - sr->region_start + sr->region_len - 1, 0x10 - 4 * pspoff); -} - -static inline void -desc_reg_sprel (unsigned char reg, unw_word spoff, - struct ia64_state_record *sr) -{ - set_reg (sr->curr.reg + reg, IA64_WHERE_SPREL, - sr->region_start + sr->region_len - 1, 4 * spoff); -} - -static inline void -desc_rp_br (unsigned char dst, struct ia64_state_record *sr) -{ - sr->return_link_reg = dst; -} - -static inline void -desc_reg_when (unsigned char regnum, unw_word t, struct ia64_state_record *sr) -{ - struct ia64_reg_info *reg = sr->curr.reg + regnum; - - if (reg->where == IA64_WHERE_NONE) - reg->where = IA64_WHERE_GR_SAVE; - reg->when = sr->region_start + MIN ((int) t, sr->region_len - 1); -} - -static inline void -desc_spill_base (unw_word pspoff, struct ia64_state_record *sr) -{ - sr->spill_offset = 0x10 - 4 * pspoff; -} - -static inline unsigned char * -desc_spill_mask (unsigned char *imaskp, struct ia64_state_record *sr) -{ - sr->imask = imaskp; - return imaskp + (2 * sr->region_len + 7) / 8; -} - -/* Body descriptors. */ - -static inline void -desc_epilogue (unw_word t, unw_word ecount, struct ia64_state_record *sr) -{ - sr->when_sp_restored = sr->region_start + sr->region_len - 1 - t; - sr->epilogue_count = ecount + 1; -} - -static inline void -desc_copy_state (unw_word label, struct ia64_state_record *sr) -{ - struct ia64_labeled_state *ls; - - for (ls = sr->labeled_states; ls; ls = ls->next) - { - if (ls->label == label) - { - free_state_stack (&sr->curr); - memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr)); - sr->curr.next = dup_state_stack (ls->saved_state.next); - return; - } - } - print_error ("libunwind: failed to find labeled state\n"); -} - -static inline void -desc_label_state (unw_word label, struct ia64_state_record *sr) -{ - struct ia64_labeled_state *ls; - - ls = alloc_labeled_state (); - if (!ls) - { - print_error ("unwind.desc_label_state(): out of memory\n"); - return; - } - ls->label = label; - memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state)); - ls->saved_state.next = dup_state_stack (sr->curr.next); - - /* insert into list of labeled states: */ - ls->next = sr->labeled_states; - sr->labeled_states = ls; -} - -/* General descriptors. */ - -static inline int -desc_is_active (unsigned char qp, unw_word t, struct ia64_state_record *sr) -{ - if (sr->when_target <= sr->region_start + MIN ((int) t, sr->region_len - 1)) - return 0; - if (qp > 0) - { - if ((sr->pr_val & ((unw_word_t) 1 << qp)) == 0) - return 0; - sr->pr_mask |= ((unw_word_t) 1 << qp); - } - return 1; -} - -static inline void -desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg, - struct ia64_state_record *sr) -{ - struct ia64_reg_info *r; - - if (!desc_is_active (qp, t, sr)) - return; - - r = sr->curr.reg + decode_abreg (abreg, 0); - r->where = IA64_WHERE_NONE; - r->when = IA64_WHEN_NEVER; - r->val = 0; -} - -static inline void -desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg, - unsigned char x, unsigned char ytreg, - struct ia64_state_record *sr) -{ - enum ia64_where where = IA64_WHERE_GR; - struct ia64_reg_info *r; - - if (!desc_is_active (qp, t, sr)) - return; - - if (x) - where = IA64_WHERE_BR; - else if (ytreg & 0x80) - where = IA64_WHERE_FR; - - r = sr->curr.reg + decode_abreg (abreg, 0); - r->where = where; - r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); - r->val = (ytreg & 0x7f); -} - -static inline void -desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg, - unw_word pspoff, struct ia64_state_record *sr) -{ - struct ia64_reg_info *r; - - if (!desc_is_active (qp, t, sr)) - return; - - r = sr->curr.reg + decode_abreg (abreg, 1); - r->where = IA64_WHERE_PSPREL; - r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); - r->val = 0x10 - 4 * pspoff; -} - -static inline void -desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, - unw_word spoff, struct ia64_state_record *sr) -{ - struct ia64_reg_info *r; - - if (!desc_is_active (qp, t, sr)) - return; - - r = sr->curr.reg + decode_abreg (abreg, 1); - r->where = IA64_WHERE_SPREL; - r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); - r->val = 4 * spoff; -} - -#define UNW_DEC_BAD_CODE(code) \ - print_error ("libunwind: unknown code encountered\n") - -/* Register names. */ -#define UNW_REG_BSP IA64_REG_BSP -#define UNW_REG_BSPSTORE IA64_REG_BSPSTORE -#define UNW_REG_FPSR IA64_REG_FPSR -#define UNW_REG_LC IA64_REG_LC -#define UNW_REG_PFS IA64_REG_PFS -#define UNW_REG_PR IA64_REG_PR -#define UNW_REG_RNAT IA64_REG_RNAT -#define UNW_REG_PSP IA64_REG_PSP -#define UNW_REG_RP IA64_REG_IP -#define UNW_REG_UNAT IA64_REG_UNAT - -/* Region headers. */ -#define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg) -#define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg) - -/* Prologue descriptors. */ -#define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg) -#define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg) -#define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg) -#define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg) -#define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg) -#define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg) -#define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg) -#define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg) -#define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg) -#define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg) -#define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg) -#define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg) -#define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg) -#define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) \ - desc_reg_when(IA64_REG_PRI_UNAT_GR,t,arg) -#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) \ - desc_reg_when(IA64_REG_PRI_UNAT_MEM,t,arg) -#define UNW_DEC_PRIUNAT_GR(fmt,r,arg) \ - desc_reg_gr(IA64_REG_PRI_UNAT_GR,r,arg) -#define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) \ - desc_reg_psprel(IA64_REG_PRI_UNAT_MEM,o,arg) -#define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) \ - desc_reg_sprel(IA64_REG_PRI_UNAT_MEM,o,arg) -#define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg) -#define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg) -#define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg)) - -/* Body descriptors. */ -#define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg) -#define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg) -#define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg) - -/* General unwind descriptors. */ -#define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg) -#define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg) -#define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) \ - desc_spill_psprel_p(p,t,a,o,arg) -#define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) \ - desc_spill_psprel_p(0,t,a,o,arg) -#define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg) -#define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg) -#define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg) -#define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg) - -#include "unwind_decoder.h" - -#ifdef _U_dyn_op - -/* parse dynamic unwind info */ - -static struct ia64_reg_info * -lookup_preg (int regnum, int memory, struct ia64_state_record *sr) -{ - int preg; - - switch (regnum) - { - case UNW_IA64_AR_BSP: preg = IA64_REG_BSP; break; - case UNW_IA64_AR_BSPSTORE: preg = IA64_REG_BSPSTORE; break; - case UNW_IA64_AR_FPSR: preg = IA64_REG_FPSR; break; - case UNW_IA64_AR_LC: preg = IA64_REG_LC; break; - case UNW_IA64_AR_PFS: preg = IA64_REG_PFS; break; - case UNW_IA64_AR_RNAT: preg = IA64_REG_RNAT; break; - case UNW_IA64_AR_UNAT: preg = IA64_REG_UNAT; break; - case UNW_IA64_BR + 0: preg = IA64_REG_IP; break; - case UNW_IA64_PR: preg = IA64_REG_PR; break; - case UNW_IA64_SP: preg = IA64_REG_PSP; break; - - case UNW_IA64_NAT: - if (memory) - preg = IA64_REG_PRI_UNAT_MEM; - else - preg = IA64_REG_PRI_UNAT_GR; - break; - - case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: - preg = IA64_REG_R4 + (regnum - (UNW_IA64_GR + 4)); - break; - - case UNW_IA64_BR + 1 ... UNW_IA64_BR + 5: - preg = IA64_REG_B1 + (regnum - UNW_IA64_BR); - break; - - case UNW_IA64_FR + 2 ... UNW_IA64_FR + 5: - preg = IA64_REG_F2 + (regnum - (UNW_IA64_FR + 2)); - break; - - case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: - preg = IA64_REG_F16 + (regnum - (UNW_IA64_FR + 16)); - break; - - default: - Dprintf ("%s: invalid register number %d\n", __FUNCTION__, regnum); - return NULL; - } - return sr->curr.reg + preg; -} - -/* An alias directive inside a region of length RLEN is interpreted to - mean that the region behaves exactly like the first RLEN - instructions at the aliased IP. RLEN=0 implies that the current - state matches exactly that of before the instruction at the aliased - IP is executed. */ - -static int -desc_alias (unw_dyn_op_t *op, struct cursor *c, struct ia64_state_record *sr) -{ - struct ia64_state_record orig_sr = *sr; - int i, ret, when, rlen = sr->region_len; - unw_word_t new_ip; - - when = MIN (sr->when_target, rlen); - new_ip = op->val + ((when / 3) * 16 + (when % 3)); - - if ((ret = ia64_fetch_proc_info (c, new_ip, 1)) < 0) - return ret; - - if ((ret = create_state_record_for (c, sr, new_ip)) < 0) - return ret; - - sr->first_region = orig_sr.first_region; - sr->done = 0; - sr->any_spills |= orig_sr.any_spills; - sr->in_body = orig_sr.in_body; - sr->region_start = orig_sr.region_start; - sr->region_len = orig_sr.region_len; - if (sr->when_sp_restored != IA64_WHEN_NEVER) - sr->when_sp_restored = op->when + MIN (orig_sr.when_sp_restored, rlen); - sr->epilogue_count = orig_sr.epilogue_count; - sr->when_target = orig_sr.when_target; - - for (i = 0; i < IA64_NUM_PREGS; ++i) - if (sr->curr.reg[i].when != IA64_WHEN_NEVER) - sr->curr.reg[i].when = op->when + MIN (sr->curr.reg[i].when, rlen); - - ia64_free_state_record (sr); - sr->labeled_states = orig_sr.labeled_states; - sr->curr.next = orig_sr.curr.next; - return 0; -} - -static inline int -parse_dynamic (struct cursor *c, struct ia64_state_record *sr) -{ - unw_dyn_info_t *di = c->pi.unwind_info; - unw_dyn_proc_info_t *proc = &di->u.pi; - unw_dyn_region_info_t *r; - struct ia64_reg_info *ri; - enum ia64_where where; - int32_t when, len; - unw_dyn_op_t *op; - unw_word_t val; - int memory, ret; - int8_t qp; - - for (r = proc->regions; r; r = r->next) - { - len = r->insn_count; - if (len < 0) - { - if (r->next) - { - Debug (1, "negative region length allowed in last region only!"); - return -UNW_EINVAL; - } - len = -len; - /* hack old region info to set the start where we need it: */ - sr->region_start = (di->end_ip - di->start_ip) / 0x10 * 3 - len; - sr->region_len = 0; - } - /* all regions are treated as prologue regions: */ - desc_prologue (0, len, 0, 0, sr); - - if (sr->done) - return 0; - - for (op = r->op; op < r->op + r->op_count; ++op) - { - when = op->when; - val = op->val; - qp = op->qp; - - if (!desc_is_active (qp, when, sr)) - continue; - - when = sr->region_start + MIN ((int) when, sr->region_len - 1); - - switch (op->tag) - { - case UNW_DYN_SAVE_REG: - memory = 0; - if ((unsigned) (val - UNW_IA64_GR) < 128) - where = IA64_WHERE_GR; - else if ((unsigned) (val - UNW_IA64_FR) < 128) - where = IA64_WHERE_FR; - else if ((unsigned) (val - UNW_IA64_BR) < 8) - where = IA64_WHERE_BR; - else - { - Dprintf ("%s: can't save to register number %d\n", - __FUNCTION__, (int) op->reg); - return -UNW_EBADREG; - } - /* fall through */ - update_reg_info: - ri = lookup_preg (op->reg, memory, sr); - if (!ri) - return -UNW_EBADREG; - ri->where = where; - ri->when = when; - ri->val = val; - break; - - case UNW_DYN_SPILL_FP_REL: - memory = 1; - where = IA64_WHERE_PSPREL; - val = 0x10 - val; - goto update_reg_info; - - case UNW_DYN_SPILL_SP_REL: - memory = 1; - where = IA64_WHERE_SPREL; - goto update_reg_info; - - case UNW_DYN_ADD: - if (op->reg == UNW_IA64_SP) - { - if (val & 0xf) - { - Dprintf ("%s: frame-size %ld not an integer " - "multiple of 16\n", - __FUNCTION__, (long) op->val); - return -UNW_EINVAL; - } - desc_mem_stack_f (when, -((int64_t) val / 16), sr); - } - else - { - Dprintf ("%s: can only ADD to stack-pointer\n", - __FUNCTION__); - return -UNW_EBADREG; - } - break; - - case UNW_DYN_POP_FRAMES: - sr->when_sp_restored = when; - sr->epilogue_count = op->val; - break; - - case UNW_DYN_LABEL_STATE: - desc_label_state (op->val, sr); - break; - - case UNW_DYN_COPY_STATE: - desc_copy_state (op->val, sr); - break; - - case UNW_DYN_ALIAS: - if ((ret = desc_alias (op, c, sr)) < 0) - return ret; - - case UNW_DYN_STOP: - goto end_of_ops; - } - } - end_of_ops: - ; - } - return 0; -} -#else -# define parse_dynamic(c,sr) (-UNW_EINVAL) -#endif /* _U_dyn_op */ - - -HIDDEN int -ia64_fetch_proc_info (struct cursor *c, unw_word_t ip, int need_unwind_info) -{ - int ret, dynamic = 1; - - if (c->pi_valid && !need_unwind_info) - return 0; - - /* check dynamic info first --- it overrides everything else */ - ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info, - c->as_arg); - if (ret == -UNW_ENOINFO) - { - dynamic = 0; - ret = ia64_find_proc_info (c, ip, need_unwind_info); - } - - c->pi_valid = 1; - c->pi_is_dynamic = dynamic; - return ret; -} - -static inline void -put_unwind_info (struct cursor *c, unw_proc_info_t *pi) -{ - if (!c->pi_valid) - return; - - if (c->pi_is_dynamic) - unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg); - else - ia64_put_unwind_info (c, pi); -} - -static int -create_state_record_for (struct cursor *c, struct ia64_state_record *sr, - unw_word_t ip) -{ - unw_word_t predicates = c->pr; - struct ia64_reg_info *r; - uint8_t *dp, *desc_end; - int ret; - - assert (c->pi_valid); - - /* build state record */ - memset (sr, 0, sizeof (*sr)); - for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) - r->when = IA64_WHEN_NEVER; - sr->pr_val = predicates; - sr->first_region = 1; - - if (!c->pi.unwind_info) - { - /* No info, return default unwinder (leaf proc, no mem stack, no - saved regs), rp in b0, pfs in ar.pfs. */ - Debug (1, "no unwind info for ip=0x%lx (gp=%lx)\n", - (long) ip, (long) c->pi.gp); - sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR; - sr->curr.reg[IA64_REG_IP].when = -1; - sr->curr.reg[IA64_REG_IP].val = 0; - goto out; - } - - sr->when_target = (3 * ((ip & ~(unw_word_t) 0xf) - c->pi.start_ip) / 16 - + (ip & 0xf)); - - switch (c->pi.format) - { - case UNW_INFO_FORMAT_TABLE: - case UNW_INFO_FORMAT_REMOTE_TABLE: - dp = c->pi.unwind_info; - desc_end = dp + c->pi.unwind_info_size; - while (!sr->done && dp < desc_end) - dp = unw_decode (dp, sr->in_body, sr); - ret = 0; - break; - - case UNW_INFO_FORMAT_DYNAMIC: - ret = parse_dynamic (c, sr); - break; - - default: - ret = -UNW_EINVAL; - } - - put_unwind_info (c, &c->pi); - - if (ret < 0) - return ret; - - if (sr->when_target > sr->when_sp_restored) - { - /* sp has been restored and all values on the memory stack below - psp also have been restored. */ - sr->curr.reg[IA64_REG_PSP].val = 0; - sr->curr.reg[IA64_REG_PSP].where = IA64_WHERE_NONE; - sr->curr.reg[IA64_REG_PSP].when = IA64_WHEN_NEVER; - for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) - if ((r->where == IA64_WHERE_PSPREL && r->val <= 0x10) - || r->where == IA64_WHERE_SPREL) - { - r->val = 0; - r->where = IA64_WHERE_NONE; - r->when = IA64_WHEN_NEVER; - } - } - - /* If RP did't get saved, generate entry for the return link - register. */ - if (sr->curr.reg[IA64_REG_IP].when >= sr->when_target) - { - sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR; - sr->curr.reg[IA64_REG_IP].when = -1; - sr->curr.reg[IA64_REG_IP].val = sr->return_link_reg; - } - - if (sr->when_target > sr->curr.reg[IA64_REG_BSP].when - && sr->when_target > sr->curr.reg[IA64_REG_BSPSTORE].when - && sr->when_target > sr->curr.reg[IA64_REG_RNAT].when) - { - Debug (8, "func 0x%lx may switch the register-backing-store\n", - c->pi.start_ip); - c->pi.flags |= UNW_PI_FLAG_IA64_RBS_SWITCH; - } - out: -#if UNW_DEBUG - if (unwi_debug_level > 2) - { - Dprintf ("%s: state record for func 0x%lx, t=%u (flags=0x%lx):\n", - __FUNCTION__, - (long) c->pi.start_ip, sr->when_target, (long) c->pi.flags); - for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) - { - if (r->where != IA64_WHERE_NONE || r->when != IA64_WHEN_NEVER) - { - Dprintf (" %s <- ", unw.preg_name[r - sr->curr.reg]); - switch (r->where) - { - case IA64_WHERE_GR: - Dprintf ("r%lu", (long) r->val); - break; - case IA64_WHERE_FR: - Dprintf ("f%lu", (long) r->val); - break; - case IA64_WHERE_BR: - Dprintf ("b%lu", (long) r->val); - break; - case IA64_WHERE_SPREL: - Dprintf ("[sp+0x%lx]", (long) r->val); - break; - case IA64_WHERE_PSPREL: - Dprintf ("[psp+0x%lx]", (long) r->val); - break; - case IA64_WHERE_NONE: - Dprintf ("%s+0x%lx", - unw.preg_name[r - sr->curr.reg], (long) r->val); - break; - default: - Dprintf ("BADWHERE(%d)", r->where); - break; - } - Dprintf ("\t\t%d\n", r->when); - } - } - } -#endif - return 0; -} - -/* The proc-info must be valid for IP before this routine can be - called. */ -HIDDEN int -ia64_create_state_record (struct cursor *c, struct ia64_state_record *sr) -{ - return create_state_record_for (c, sr, c->ip); -} - -HIDDEN int -ia64_free_state_record (struct ia64_state_record *sr) -{ - struct ia64_labeled_state *ls, *next; - - /* free labeled register states & stack: */ - - for (ls = sr->labeled_states; ls; ls = next) - { - next = ls->next; - free_state_stack (&ls->saved_state); - free_labeled_state (ls); - } - free_state_stack (&sr->curr); - - return 0; -} - -HIDDEN int -ia64_make_proc_info (struct cursor *c) -{ - int ret, caching = c->as->caching_policy != UNW_CACHE_NONE; - - if (!caching || ia64_get_cached_proc_info (c) < 0) - { - /* Lookup it up the slow way... */ - if ((ret = ia64_fetch_proc_info (c, c->ip, 0)) < 0) - return ret; - if (caching) - ia64_cache_proc_info (c); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Grbs.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Grbs.c deleted file mode 100644 index e7c01fe219e9e5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Grbs.c +++ /dev/null @@ -1,319 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* Logically, we like to think of the stack as a contiguous region of -memory. Unfortunately, this logical view doesn't work for the -register backing store, because the RSE is an asynchronous engine and -because UNIX/Linux allow for stack-switching via sigaltstack(2). -Specifically, this means that any given stacked register may or may -not be backed up by memory in the current stack. If not, then the -backing memory may be found in any of the "more inner" (younger) -stacks. The routines in this file help manage the discontiguous -nature of the register backing store. The routines are completely -independent of UNIX/Linux, but each stack frame that switches the -backing store is expected to reserve 4 words for use by libunwind. For -example, in the Linux sigcontext, sc_fr[0] and sc_fr[1] serve this -purpose. */ - -#include "unwind_i.h" - -#if UNW_DEBUG - -HIDDEN const char * -ia64_strloc (ia64_loc_t loc) -{ - static char buf[128]; - - if (IA64_IS_NULL_LOC (loc)) - return ""; - - buf[0] = '\0'; - - if (IA64_IS_MEMSTK_NAT (loc)) - strcat (buf, "memstk_nat("); - if (IA64_IS_UC_LOC (loc)) - strcat (buf, "uc("); - if (IA64_IS_FP_LOC (loc)) - strcat (buf, "fp("); - - if (IA64_IS_REG_LOC (loc)) - sprintf (buf + strlen (buf), "%s", unw_regname (IA64_GET_REG (loc))); - else - sprintf (buf + strlen (buf), "0x%llx", - (unsigned long long) IA64_GET_ADDR (loc)); - - if (IA64_IS_FP_LOC (loc)) - strcat (buf, ")"); - if (IA64_IS_UC_LOC (loc)) - strcat (buf, ")"); - if (IA64_IS_MEMSTK_NAT (loc)) - strcat (buf, ")"); - - return buf; -} - -#endif /* UNW_DEBUG */ - -HIDDEN int -rbs_switch (struct cursor *c, - unw_word_t saved_bsp, unw_word_t saved_bspstore, - ia64_loc_t saved_rnat_loc) -{ - struct rbs_area *rbs = &c->rbs_area[c->rbs_curr]; - unw_word_t lo, ndirty, rbs_base; - int ret; - - Debug (10, "(left=%u, curr=%u)\n", c->rbs_left_edge, c->rbs_curr); - - /* Calculate address "lo" at which the backing store starts: */ - ndirty = rse_num_regs (saved_bspstore, saved_bsp); - lo = rse_skip_regs (c->bsp, -ndirty); - - rbs->size = (rbs->end - lo); - - /* If the previously-recorded rbs-area is empty we don't need to - track it and we can simply overwrite it... */ - if (rbs->size) - { - Debug (10, "inner=[0x%lx-0x%lx)\n", - (long) (rbs->end - rbs->size), (long) rbs->end); - - c->rbs_curr = (c->rbs_curr + 1) % ARRAY_SIZE (c->rbs_area); - rbs = c->rbs_area + c->rbs_curr; - - if (c->rbs_curr == c->rbs_left_edge) - c->rbs_left_edge = (c->rbs_left_edge + 1) % ARRAY_SIZE (c->rbs_area); - } - - if ((ret = rbs_get_base (c, saved_bspstore, &rbs_base)) < 0) - return ret; - - rbs->end = saved_bspstore; - rbs->size = saved_bspstore - rbs_base; - rbs->rnat_loc = saved_rnat_loc; - - c->bsp = saved_bsp; - - Debug (10, "outer=[0x%llx-0x%llx), rnat@%s\n", (long long) rbs_base, - (long long) rbs->end, ia64_strloc (rbs->rnat_loc)); - return 0; -} - -HIDDEN int -rbs_find_stacked (struct cursor *c, unw_word_t regs_to_skip, - ia64_loc_t *locp, ia64_loc_t *rnat_locp) -{ - unw_word_t nregs, bsp = c->bsp, curr = c->rbs_curr, n; - unw_word_t left_edge = c->rbs_left_edge; -#if UNW_DEBUG - int reg = 32 + regs_to_skip; -#endif - - while (!rbs_contains (&c->rbs_area[curr], bsp)) - { - if (curr == left_edge) - { - Debug (1, "could not find register r%d!\n", reg); - return -UNW_EBADREG; - } - - n = rse_num_regs (c->rbs_area[curr].end, bsp); - curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) % ARRAY_SIZE (c->rbs_area); - bsp = rse_skip_regs (c->rbs_area[curr].end - c->rbs_area[curr].size, n); - } - - while (1) - { - nregs = rse_num_regs (bsp, c->rbs_area[curr].end); - - if (regs_to_skip < nregs) - { - /* found it: */ - unw_word_t addr; - - addr = rse_skip_regs (bsp, regs_to_skip); - if (locp) - *locp = rbs_loc (c->rbs_area + curr, addr); - if (rnat_locp) - *rnat_locp = rbs_get_rnat_loc (c->rbs_area + curr, addr); - return 0; - } - - if (curr == left_edge) - { - Debug (1, "could not find register r%d!\n", reg); - return -UNW_EBADREG; - } - - regs_to_skip -= nregs; - - curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) % ARRAY_SIZE (c->rbs_area); - bsp = c->rbs_area[curr].end - c->rbs_area[curr].size; - } -} - -#ifdef NEED_RBS_COVER_AND_FLUSH - -static inline int -get_rnat (struct cursor *c, struct rbs_area *rbs, unw_word_t bsp, - unw_word_t *__restrict rnatp) -{ - ia64_loc_t rnat_locp = rbs_get_rnat_loc (rbs, bsp); - - return ia64_get (c, rnat_locp, rnatp); -} - -/* Simulate the effect of "cover" followed by a "flushrs" for the - target-frame. However, since the target-frame's backing store - may not have space for the registers that got spilled onto other - rbs-areas, we save those registers to DIRTY_PARTITION where - we can then load them via a single "loadrs". - - This function returns the size of the dirty-partition that was - created or a negative error-code in case of error. - - Note: This does not modify the rbs_area[] structure in any way. */ -HIDDEN int -rbs_cover_and_flush (struct cursor *c, unw_word_t nregs, - unw_word_t *dirty_partition, unw_word_t *dirty_rnat, - unw_word_t *bspstore) -{ - unw_word_t n, src_mask, dst_mask, bsp, *dst, src_rnat, dst_rnat = 0; - unw_word_t curr = c->rbs_curr, left_edge = c->rbs_left_edge; - struct rbs_area *rbs = c->rbs_area + curr; - int ret; - - bsp = c->bsp; - c->bsp = rse_skip_regs (bsp, nregs); - - if (likely (rbs_contains (rbs, bsp))) - { - /* at least _some_ registers are on rbs... */ - n = rse_num_regs (bsp, rbs->end); - if (likely (n >= nregs)) - { - /* common case #1: all registers are on current rbs... */ - /* got lucky: _all_ registers are on rbs... */ - ia64_loc_t rnat_loc = rbs_get_rnat_loc (rbs, c->bsp); - - *bspstore = c->bsp; - - if (IA64_IS_REG_LOC (rnat_loc)) - { - unw_word_t rnat_addr = (unw_word_t) - tdep_uc_addr (c->as_arg, UNW_IA64_AR_RNAT, NULL); - rnat_loc = IA64_LOC_ADDR (rnat_addr, 0); - } - c->loc[IA64_REG_RNAT] = rnat_loc; - return 0; /* all done */ - } - nregs -= n; /* account for registers already on the rbs */ - - assert (rse_skip_regs (c->bsp, -nregs) == rse_skip_regs (rbs->end, 0)); - } - else - /* Earlier frames also didn't get spilled; need to "loadrs" those, - too... */ - nregs += rse_num_regs (rbs->end, bsp); - - /* OK, we need to copy NREGS registers to the dirty partition. */ - - *bspstore = bsp = rbs->end; - c->loc[IA64_REG_RNAT] = rbs->rnat_loc; - assert (!IA64_IS_REG_LOC (rbs->rnat_loc)); - - dst = dirty_partition; - - while (nregs > 0) - { - if (unlikely (!rbs_contains (rbs, bsp))) - { - /* switch to next non-empty rbs-area: */ - do - { - if (curr == left_edge) - { - Debug (0, "rbs-underflow while flushing %lu regs, " - "bsp=0x%lx, dst=0x%p\n", (unsigned long) nregs, - (unsigned long) bsp, dst); - return -UNW_EBADREG; - } - - assert (rse_num_regs (rbs->end, bsp) == 0); - - curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) - % ARRAY_SIZE (c->rbs_area); - rbs = c->rbs_area + curr; - bsp = rbs->end - rbs->size; - } - while (rbs->size == 0); - - if ((ret = get_rnat (c, rbs, bsp, &src_rnat)) < 0) - return ret; - } - - if (unlikely (rse_is_rnat_slot (bsp))) - { - bsp += 8; - if ((ret = get_rnat (c, rbs, bsp, &src_rnat)) < 0) - return ret; - } - if (unlikely (rse_is_rnat_slot ((unw_word_t) dst))) - { - *dst++ = dst_rnat; - dst_rnat = 0; - } - - src_mask = ((unw_word_t) 1) << rse_slot_num (bsp); - dst_mask = ((unw_word_t) 1) << rse_slot_num ((unw_word_t) dst); - - if (src_rnat & src_mask) - dst_rnat |= dst_mask; - else - dst_rnat &= ~dst_mask; - - /* copy one slot: */ - if ((ret = ia64_get (c, rbs_loc (rbs, bsp), dst)) < 0) - return ret; - - /* advance to next slot: */ - --nregs; - bsp += 8; - ++dst; - } - if (unlikely (rse_is_rnat_slot ((unw_word_t) dst))) - { - /* The LOADRS instruction loads "the N bytes below the current - BSP" but BSP can never point to an RNaT slot so if the last - destination word happens to be an RNaT slot, we need to write - that slot now. */ - *dst++ = dst_rnat; - dst_rnat = 0; - } - *dirty_rnat = dst_rnat; - return (char *) dst - (char *) dirty_partition; -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Greg_states_iterate.c deleted file mode 100644 index 3570740af157c7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Greg_states_iterate.c +++ /dev/null @@ -1,39 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - // Needs dwarf support on ia64 - // return dwarf_reg_states_iterate (&c->dwarf, cb, token); - return -UNW_EINVAL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gregs.c deleted file mode 100644 index ac6f738a6cdbdb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gregs.c +++ /dev/null @@ -1,612 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "offsets.h" -#include "regs.h" -#include "unwind_i.h" - -static inline ia64_loc_t -linux_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) -{ -#if !defined(UNW_LOCAL_ONLY) || defined(__linux) - unw_word_t addr = c->sigcontext_addr, flags, tmp_addr; - int i; - - if (ia64_get_abi_marker (c) == ABI_MARKER_LINUX_SIGTRAMP - || ia64_get_abi_marker (c) == ABI_MARKER_OLD_LINUX_SIGTRAMP) - { - switch (reg) - { - case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: - case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: - /* Linux sigcontext contains the NaT bit of scratch register - N in bit position N of the sc_nat member. */ - *nat_bitnr = (reg - UNW_IA64_NAT); - addr += LINUX_SC_NAT_OFF; - break; - - case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: - case UNW_IA64_GR + 8 ... UNW_IA64_GR + 31: - addr += LINUX_SC_GR_OFF + 8 * (reg - UNW_IA64_GR); - break; - - case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: - addr += LINUX_SC_FR_OFF + 16 * (reg - UNW_IA64_FR); - return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); - - case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: - if (ia64_get (c, IA64_LOC_ADDR (addr + LINUX_SC_FLAGS_OFF, 0), - &flags) < 0) - return IA64_NULL_LOC; - - if (!(flags & IA64_SC_FLAG_FPH_VALID)) - { - /* initialize fph partition: */ - tmp_addr = addr + LINUX_SC_FR_OFF + 32*16; - for (i = 32; i < 128; ++i, tmp_addr += 16) - if (ia64_putfp (c, IA64_LOC_ADDR (tmp_addr, 0), - unw.read_only.f0) < 0) - return IA64_NULL_LOC; - /* mark fph partition as valid: */ - if (ia64_put (c, IA64_LOC_ADDR (addr + LINUX_SC_FLAGS_OFF, 0), - flags | IA64_SC_FLAG_FPH_VALID) < 0) - return IA64_NULL_LOC; - } - - addr += LINUX_SC_FR_OFF + 16 * (reg - UNW_IA64_FR); - return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); - - case UNW_IA64_BR + 0: addr += LINUX_SC_BR_OFF + 0; break; - case UNW_IA64_BR + 6: addr += LINUX_SC_BR_OFF + 6*8; break; - case UNW_IA64_BR + 7: addr += LINUX_SC_BR_OFF + 7*8; break; - case UNW_IA64_AR_RSC: addr += LINUX_SC_AR_RSC_OFF; break; - case UNW_IA64_AR_CSD: addr += LINUX_SC_AR_CSD_OFF; break; - case UNW_IA64_AR_SSD: addr += LINUX_SC_AR_SSD_OFF; break; - case UNW_IA64_AR_CCV: addr += LINUX_SC_AR_CCV; break; - - default: - if (unw_is_fpreg (reg)) - return IA64_FPREG_LOC (c, reg); - else - return IA64_REG_LOC (c, reg); - } - return IA64_LOC_ADDR (addr, 0); - } - else - { - int is_nat = 0; - - if ((unsigned) (reg - UNW_IA64_NAT) < 128) - { - is_nat = 1; - reg -= (UNW_IA64_NAT - UNW_IA64_GR); - } - if (ia64_get_abi_marker (c) == ABI_MARKER_LINUX_INTERRUPT) - { - switch (reg) - { - case UNW_IA64_BR + 6 ... UNW_IA64_BR + 7: - addr += LINUX_PT_B6_OFF + 8 * (reg - (UNW_IA64_BR + 6)); - break; - - case UNW_IA64_AR_CSD: addr += LINUX_PT_CSD_OFF; break; - case UNW_IA64_AR_SSD: addr += LINUX_PT_SSD_OFF; break; - - case UNW_IA64_GR + 8 ... UNW_IA64_GR + 11: - addr += LINUX_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8)); - break; - - case UNW_IA64_IP: addr += LINUX_PT_IIP_OFF; break; - case UNW_IA64_CFM: addr += LINUX_PT_IFS_OFF; break; - case UNW_IA64_AR_UNAT: addr += LINUX_PT_UNAT_OFF; break; - case UNW_IA64_AR_PFS: addr += LINUX_PT_PFS_OFF; break; - case UNW_IA64_AR_RSC: addr += LINUX_PT_RSC_OFF; break; - case UNW_IA64_AR_RNAT: addr += LINUX_PT_RNAT_OFF; break; - case UNW_IA64_AR_BSPSTORE: addr += LINUX_PT_BSPSTORE_OFF; break; - case UNW_IA64_PR: addr += LINUX_PT_PR_OFF; break; - case UNW_IA64_BR + 0: addr += LINUX_PT_B0_OFF; break; - - case UNW_IA64_GR + 1: - /* The saved r1 value is valid only in the frame in which - it was saved; for everything else we need to look up - the appropriate gp value. */ - if (c->sigcontext_addr != c->sp + 0x10) - return IA64_NULL_LOC; - addr += LINUX_PT_R1_OFF; - break; - - case UNW_IA64_GR + 12: addr += LINUX_PT_R12_OFF; break; - case UNW_IA64_GR + 13: addr += LINUX_PT_R13_OFF; break; - case UNW_IA64_AR_FPSR: addr += LINUX_PT_FPSR_OFF; break; - case UNW_IA64_GR + 15: addr += LINUX_PT_R15_OFF; break; - case UNW_IA64_GR + 14: addr += LINUX_PT_R14_OFF; break; - case UNW_IA64_GR + 2: addr += LINUX_PT_R2_OFF; break; - case UNW_IA64_GR + 3: addr += LINUX_PT_R3_OFF; break; - - case UNW_IA64_GR + 16 ... UNW_IA64_GR + 31: - addr += LINUX_PT_R16_OFF + 8 * (reg - (UNW_IA64_GR + 16)); - break; - - case UNW_IA64_AR_CCV: addr += LINUX_PT_CCV_OFF; break; - - case UNW_IA64_FR + 6 ... UNW_IA64_FR + 11: - addr += LINUX_PT_F6_OFF + 16 * (reg - (UNW_IA64_FR + 6)); - return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); - - default: - if (unw_is_fpreg (reg)) - return IA64_FPREG_LOC (c, reg); - else - return IA64_REG_LOC (c, reg); - } - } - else if (ia64_get_abi_marker (c) == ABI_MARKER_OLD_LINUX_INTERRUPT) - { - switch (reg) - { - case UNW_IA64_GR + 1: - /* The saved r1 value is valid only in the frame in which - it was saved; for everything else we need to look up - the appropriate gp value. */ - if (c->sigcontext_addr != c->sp + 0x10) - return IA64_NULL_LOC; - addr += LINUX_OLD_PT_R1_OFF; - break; - - case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: - addr += LINUX_OLD_PT_R2_OFF + 8 * (reg - (UNW_IA64_GR + 2)); - break; - - case UNW_IA64_GR + 8 ... UNW_IA64_GR + 11: - addr += LINUX_OLD_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8)); - break; - - case UNW_IA64_GR + 16 ... UNW_IA64_GR + 31: - addr += LINUX_OLD_PT_R16_OFF + 8 * (reg - (UNW_IA64_GR + 16)); - break; - - case UNW_IA64_FR + 6 ... UNW_IA64_FR + 9: - addr += LINUX_OLD_PT_F6_OFF + 16 * (reg - (UNW_IA64_FR + 6)); - return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); - - case UNW_IA64_BR + 0: addr += LINUX_OLD_PT_B0_OFF; break; - case UNW_IA64_BR + 6: addr += LINUX_OLD_PT_B6_OFF; break; - case UNW_IA64_BR + 7: addr += LINUX_OLD_PT_B7_OFF; break; - - case UNW_IA64_AR_RSC: addr += LINUX_OLD_PT_RSC_OFF; break; - case UNW_IA64_AR_CCV: addr += LINUX_OLD_PT_CCV_OFF; break; - - default: - if (unw_is_fpreg (reg)) - return IA64_FPREG_LOC (c, reg); - else - return IA64_REG_LOC (c, reg); - } - } - if (is_nat) - { - /* For Linux pt-regs structure, bit number is determined by - the UNaT slot number (as determined by st8.spill) and the - bits are saved wherever the (primary) UNaT was saved. */ - *nat_bitnr = ia64_unat_slot_num (addr); - return c->loc[IA64_REG_PRI_UNAT_MEM]; - } - return IA64_LOC_ADDR (addr, 0); - } -#endif - return IA64_NULL_LOC; -} - -static inline ia64_loc_t -hpux_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) -{ -#if !defined(UNW_LOCAL_ONLY) || defined(__hpux) - return IA64_LOC_UC_REG (reg, c->sigcontext_addr); -#else - return IA64_NULL_LOC; -#endif -} - -HIDDEN ia64_loc_t -ia64_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) -{ - if (c->sigcontext_addr) - { - if (ia64_get_abi (c) == ABI_LINUX) - return linux_scratch_loc (c, reg, nat_bitnr); - else if (ia64_get_abi (c) == ABI_HPUX) - return hpux_scratch_loc (c, reg, nat_bitnr); - else - return IA64_NULL_LOC; - } - else - return IA64_REG_LOC (c, reg); -} - -static inline int -update_nat (struct cursor *c, ia64_loc_t nat_loc, unw_word_t mask, - unw_word_t *valp, int write) -{ - unw_word_t nat_word; - int ret; - - ret = ia64_get (c, nat_loc, &nat_word); - if (ret < 0) - return ret; - - if (write) - { - if (*valp) - nat_word |= mask; - else - nat_word &= ~mask; - ret = ia64_put (c, nat_loc, nat_word); - } - else - *valp = (nat_word & mask) != 0; - return ret; -} - -static int -access_nat (struct cursor *c, - ia64_loc_t nat_loc, ia64_loc_t reg_loc, uint8_t nat_bitnr, - unw_word_t *valp, int write) -{ - unw_word_t mask = 0; - unw_fpreg_t tmp; - int ret; - - if (IA64_IS_FP_LOC (reg_loc)) - { - /* NaT bit is saved as a NaTVal. This happens when a general - register is saved to a floating-point register. */ - if (write) - { - if (*valp) - { - if (ia64_is_big_endian (c)) - ret = ia64_putfp (c, reg_loc, unw.nat_val_be); - else - ret = ia64_putfp (c, reg_loc, unw.nat_val_le); - } - else - { - unw_word_t *src, *dst; - unw_fpreg_t tmp; - - ret = ia64_getfp (c, reg_loc, &tmp); - if (ret < 0) - return ret; - - /* Reset the exponent to 0x1003e so that the significand - will be interpreted as an integer value. */ - src = (unw_word_t *) &unw.int_val_be; - dst = (unw_word_t *) &tmp; - if (!ia64_is_big_endian (c)) - ++src, ++dst; - *dst = *src; - - ret = ia64_putfp (c, reg_loc, tmp); - } - } - else - { - ret = ia64_getfp (c, reg_loc, &tmp); - if (ret < 0) - return ret; - - if (ia64_is_big_endian (c)) - *valp = (memcmp (&tmp, &unw.nat_val_be, sizeof (tmp)) == 0); - else - *valp = (memcmp (&tmp, &unw.nat_val_le, sizeof (tmp)) == 0); - } - return ret; - } - - if ((IA64_IS_REG_LOC (nat_loc) - && (unsigned) (IA64_GET_REG (nat_loc) - UNW_IA64_NAT) < 128) - || IA64_IS_UC_LOC (reg_loc)) - { - if (write) - return ia64_put (c, nat_loc, *valp); - else - return ia64_get (c, nat_loc, valp); - } - - if (IA64_IS_NULL_LOC (nat_loc)) - { - /* NaT bit is not saved. This happens if a general register is - saved to a branch register. Since the NaT bit gets lost, we - need to drop it here, too. Note that if the NaT bit had been - set when the save occurred, it would have caused a NaT - consumption fault. */ - if (write) - { - if (*valp) - return -UNW_EBADREG; /* can't set NaT bit */ - } - else - *valp = 0; - return 0; - } - - mask = (unw_word_t) 1 << nat_bitnr; - return update_nat (c, nat_loc, mask, valp, write); -} - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - ia64_loc_t loc, reg_loc, nat_loc; - unw_word_t mask, val; - uint8_t nat_bitnr; - int ret; - - switch (reg) - { - /* frame registers: */ - - case UNW_IA64_BSP: - if (write) - c->bsp = *valp; - else - *valp = c->bsp; - return 0; - - case UNW_REG_SP: - if (write) - c->sp = *valp; - else - *valp = c->sp; - return 0; - - case UNW_REG_IP: - if (write) - { - c->ip = *valp; /* also update the IP cache */ - if (c->pi_valid && (*valp < c->pi.start_ip || *valp >= c->pi.end_ip)) - c->pi_valid = 0; /* new IP outside of current proc */ - } - loc = c->loc[IA64_REG_IP]; - break; - - /* preserved registers: */ - - case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: - loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_GR + 4))]; - break; - - case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7: - loc = c->loc[IA64_REG_NAT4 + (reg - (UNW_IA64_NAT + 4))]; - reg_loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_NAT + 4))]; - nat_bitnr = c->nat_bitnr[reg - (UNW_IA64_NAT + 4)]; - return access_nat (c, loc, reg_loc, nat_bitnr, valp, write); - - case UNW_IA64_AR_BSP: loc = c->loc[IA64_REG_BSP]; break; - case UNW_IA64_AR_BSPSTORE: loc = c->loc[IA64_REG_BSPSTORE]; break; - case UNW_IA64_AR_PFS: loc = c->loc[IA64_REG_PFS]; break; - case UNW_IA64_AR_RNAT: loc = c->loc[IA64_REG_RNAT]; break; - case UNW_IA64_AR_UNAT: loc = c->loc[IA64_REG_UNAT]; break; - case UNW_IA64_AR_LC: loc = c->loc[IA64_REG_LC]; break; - case UNW_IA64_AR_FPSR: loc = c->loc[IA64_REG_FPSR]; break; - case UNW_IA64_BR + 1: loc = c->loc[IA64_REG_B1]; break; - case UNW_IA64_BR + 2: loc = c->loc[IA64_REG_B2]; break; - case UNW_IA64_BR + 3: loc = c->loc[IA64_REG_B3]; break; - case UNW_IA64_BR + 4: loc = c->loc[IA64_REG_B4]; break; - case UNW_IA64_BR + 5: loc = c->loc[IA64_REG_B5]; break; - - case UNW_IA64_CFM: - if (write) - c->cfm = *valp; /* also update the CFM cache */ - loc = c->cfm_loc; - break; - - case UNW_IA64_PR: - /* - * Note: broad-side access to the predicates is NOT rotated - * (i.e., it is done as if CFM.rrb.pr == 0. - */ - if (write) - { - c->pr = *valp; /* update the predicate cache */ - return ia64_put (c, c->loc[IA64_REG_PR], *valp); - } - else - return ia64_get (c, c->loc[IA64_REG_PR], valp); - - case UNW_IA64_GR + 32 ... UNW_IA64_GR + 127: /* stacked reg */ - reg = rotate_gr (c, reg - UNW_IA64_GR); - if (reg < 0) - return -UNW_EBADREG; - ret = ia64_get_stacked (c, reg, &loc, NULL); - if (ret < 0) - return ret; - break; - - case UNW_IA64_NAT + 32 ... UNW_IA64_NAT + 127: /* stacked reg */ - reg = rotate_gr (c, reg - UNW_IA64_NAT); - if (reg < 0) - return -UNW_EBADREG; - ret = ia64_get_stacked (c, reg, &loc, &nat_loc); - if (ret < 0) - return ret; - assert (!IA64_IS_REG_LOC (loc)); - mask = (unw_word_t) 1 << rse_slot_num (IA64_GET_ADDR (loc)); - return update_nat (c, nat_loc, mask, valp, write); - - case UNW_IA64_AR_EC: - if ((ret = ia64_get (c, c->ec_loc, &val)) < 0) - return ret; - - if (write) - { - val = ((val & ~((unw_word_t) 0x3f << 52)) | ((*valp & 0x3f) << 52)); - return ia64_put (c, c->ec_loc, val); - } - else - { - *valp = (val >> 52) & 0x3f; - return 0; - } - - /* scratch & special registers: */ - - case UNW_IA64_GR + 0: - if (write) - return -UNW_EREADONLYREG; - *valp = 0; - return 0; - - case UNW_IA64_NAT + 0: - if (write) - return -UNW_EREADONLYREG; - *valp = 0; - return 0; - - case UNW_IA64_NAT + 1: - case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: - case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: - loc = ia64_scratch_loc (c, reg, &nat_bitnr); - if (IA64_IS_NULL_LOC (loc) && reg == UNW_IA64_NAT + 1) - { - /* access to GP */ - if (write) - return -UNW_EREADONLYREG; - *valp = 0; - return 0; - } - if (!(IA64_IS_REG_LOC (loc) || IA64_IS_UC_LOC (loc) - || IA64_IS_FP_LOC (loc))) - /* We're dealing with a NaT bit stored in memory. */ - return update_nat(c, loc, (unw_word_t) 1 << nat_bitnr, valp, write); - break; - - case UNW_IA64_GR + 15 ... UNW_IA64_GR + 18: - mask = 1 << (reg - (UNW_IA64_GR + 15)); - if (write) - { - c->eh_args[reg - (UNW_IA64_GR + 15)] = *valp; - c->eh_valid_mask |= mask; - return 0; - } - else if ((c->eh_valid_mask & mask) != 0) - { - *valp = c->eh_args[reg - (UNW_IA64_GR + 15)]; - return 0; - } - else - loc = ia64_scratch_loc (c, reg, NULL); - break; - - case UNW_IA64_GR + 1: /* global pointer */ - case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: - case UNW_IA64_GR + 8 ... UNW_IA64_GR + 14: - case UNW_IA64_GR + 19 ... UNW_IA64_GR + 31: - case UNW_IA64_BR + 0: - case UNW_IA64_BR + 6: - case UNW_IA64_BR + 7: - case UNW_IA64_AR_RSC: - case UNW_IA64_AR_CSD: - case UNW_IA64_AR_SSD: - case UNW_IA64_AR_CCV: - loc = ia64_scratch_loc (c, reg, NULL); - if (IA64_IS_NULL_LOC (loc) && reg == UNW_IA64_GR + 1) - { - /* access to GP */ - if (write) - return -UNW_EREADONLYREG; - - /* ensure c->pi is up-to-date: */ - if ((ret = ia64_make_proc_info (c)) < 0) - return ret; - *valp = c->pi.gp; - return 0; - } - break; - - default: - Debug (1, "bad register number %d\n", reg); - return -UNW_EBADREG; - } - - if (write) - return ia64_put (c, loc, *valp); - else - return ia64_get (c, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, int reg, unw_fpreg_t *valp, - int write) -{ - ia64_loc_t loc; - - switch (reg) - { - case UNW_IA64_FR + 0: - if (write) - return -UNW_EREADONLYREG; - *valp = unw.read_only.f0; - return 0; - - case UNW_IA64_FR + 1: - if (write) - return -UNW_EREADONLYREG; - - if (ia64_is_big_endian (c)) - *valp = unw.read_only.f1_be; - else - *valp = unw.read_only.f1_le; - return 0; - - case UNW_IA64_FR + 2: loc = c->loc[IA64_REG_F2]; break; - case UNW_IA64_FR + 3: loc = c->loc[IA64_REG_F3]; break; - case UNW_IA64_FR + 4: loc = c->loc[IA64_REG_F4]; break; - case UNW_IA64_FR + 5: loc = c->loc[IA64_REG_F5]; break; - - case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: - loc = c->loc[IA64_REG_F16 + (reg - (UNW_IA64_FR + 16))]; - break; - - case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: - loc = ia64_scratch_loc (c, reg, NULL); - break; - - case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: - reg = rotate_fr (c, reg - UNW_IA64_FR) + UNW_IA64_FR; - loc = ia64_scratch_loc (c, reg, NULL); - break; - - default: - Debug (1, "bad register number %d\n", reg); - return -UNW_EBADREG; - } - - if (write) - return ia64_putfp (c, loc, *valp); - else - return ia64_getfp (c, loc, valp); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gresume.c deleted file mode 100644 index 68fe8a659efa33..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gresume.c +++ /dev/null @@ -1,274 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" -#include "offsets.h" - -#ifndef UNW_REMOTE_ONLY - -static inline int -local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ -#if defined(__linux) - unw_word_t dirty_partition[2048]; /* AR.RSC.LOADRS is a 14-bit field */ - unw_word_t val, sol, sof, pri_unat, n, pfs, bspstore, dirty_rnat; - struct cursor *c = (struct cursor *) cursor; - struct - { - unw_word_t r1; - unw_word_t r4; - unw_word_t r5; - unw_word_t r6; - unw_word_t r7; - unw_word_t r15; - unw_word_t r16; - unw_word_t r17; - unw_word_t r18; - } - extra; - int ret, dirty_size; -# define GET_NAT(n) \ - do \ - { \ - ret = tdep_access_reg (c, UNW_IA64_NAT + (n), &val, 0); \ - if (ret < 0) \ - return ret; \ - if (val) \ - pri_unat |= (unw_word_t) 1 << n; \ - } \ - while (0) - - /* ensure c->pi is up-to-date: */ - if ((ret = ia64_make_proc_info (c)) < 0) - return ret; - - /* Copy contents of r4-r7 into "extra", so that their values end up - contiguous, so we can use a single (primary-) UNaT value. */ - if ((ret = ia64_get (c, c->loc[IA64_REG_R4], &extra.r4)) < 0 - || (ret = ia64_get (c, c->loc[IA64_REG_R5], &extra.r5)) < 0 - || (ret = ia64_get (c, c->loc[IA64_REG_R6], &extra.r6)) < 0 - || (ret = ia64_get (c, c->loc[IA64_REG_R7], &extra.r7)) < 0) - return ret; - - /* Form the primary UNaT value: */ - pri_unat = 0; - GET_NAT (4); GET_NAT(5); - GET_NAT (6); GET_NAT(7); - n = (((uintptr_t) &extra.r4) / 8 - 4) % 64; - pri_unat = (pri_unat << n) | (pri_unat >> (64 - n)); - - if (unlikely (c->sigcontext_addr)) - { - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; -# define PR_SCRATCH 0xffc0 /* p6-p15 are scratch */ -# define PR_PRESERVED (~(PR_SCRATCH | 1)) - - /* We're returning to a frame that was (either directly or - indirectly) interrupted by a signal. We have to restore - _both_ "preserved" and "scratch" registers. That doesn't - leave us any registers to work with, and the only way we can - achieve this is by doing a sigreturn(). - - Note: it might be tempting to think that we don't have to - restore the scratch registers when returning to a frame that - was indirectly interrupted by a signal. However, that is not - safe because that frame and its descendants could have been - using a special convention that stores "preserved" state in - scratch registers. For example, the Linux fsyscall - convention does this with r11 (to save ar.pfs) and b6 (to - save "rp"). */ - - sc->sc_gr[12] = c->psp; - c->psp = c->sigcontext_addr - c->sigcontext_off; - - sof = (c->cfm & 0x7f); - if ((dirty_size = rbs_cover_and_flush (c, sof, dirty_partition, - &dirty_rnat, &bspstore)) < 0) - return dirty_size; - - /* Clear the "in-syscall" flag, because in general we won't be - returning to the interruption-point and we need all registers - restored. */ - sc->sc_flags &= ~IA64_SC_FLAG_IN_SYSCALL; - sc->sc_ip = c->ip; - sc->sc_cfm = c->cfm & (((unw_word_t) 1 << 38) - 1); - sc->sc_pr = (c->pr & ~PR_SCRATCH) | (sc->sc_pr & ~PR_PRESERVED); - if ((ret = ia64_get (c, c->loc[IA64_REG_PFS], &sc->sc_ar_pfs)) < 0 - || (ret = ia64_get (c, c->loc[IA64_REG_FPSR], &sc->sc_ar_fpsr)) < 0 - || (ret = ia64_get (c, c->loc[IA64_REG_UNAT], &sc->sc_ar_unat)) < 0) - return ret; - - sc->sc_gr[1] = c->pi.gp; - if (c->eh_valid_mask & 0x1) sc->sc_gr[15] = c->eh_args[0]; - if (c->eh_valid_mask & 0x2) sc->sc_gr[16] = c->eh_args[1]; - if (c->eh_valid_mask & 0x4) sc->sc_gr[17] = c->eh_args[2]; - if (c->eh_valid_mask & 0x8) sc->sc_gr[18] = c->eh_args[3]; - Debug (9, "sc: r15=%lx,r16=%lx,r17=%lx,r18=%lx\n", - (long) sc->sc_gr[15], (long) sc->sc_gr[16], - (long) sc->sc_gr[17], (long) sc->sc_gr[18]); - } - else - { - /* Account for the fact that _Uia64_install_context() will - return via br.ret, which will decrement bsp by size-of-locals. */ - if ((ret = ia64_get (c, c->loc[IA64_REG_PFS], &pfs)) < 0) - return ret; - sol = (pfs >> 7) & 0x7f; - if ((dirty_size = rbs_cover_and_flush (c, sol, dirty_partition, - &dirty_rnat, &bspstore)) < 0) - return dirty_size; - - extra.r1 = c->pi.gp; - extra.r15 = c->eh_args[0]; - extra.r16 = c->eh_args[1]; - extra.r17 = c->eh_args[2]; - extra.r18 = c->eh_args[3]; - Debug (9, "extra: r15=%lx,r16=%lx,r17=%lx,r18=%lx\n", - (long) extra.r15, (long) extra.r16, - (long) extra.r17, (long) extra.r18); - } - Debug (8, "resuming at ip=%lx\n", (long) c->ip); - ia64_install_cursor (c, pri_unat, (unw_word_t *) &extra, - bspstore, dirty_size, dirty_partition + dirty_size/8, - dirty_rnat); -#elif defined(__hpux) - struct cursor *c = (struct cursor *) cursor; - - setcontext (c->as_arg); /* should not return */ -#endif - return -UNW_EINVAL; -} - -HIDDEN int -ia64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - return local_resume (as, cursor, arg); -} - -#endif /* !UNW_REMOTE_ONLY */ - -#ifndef UNW_LOCAL_ONLY - -static inline int -remote_install_cursor (struct cursor *c) -{ - int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, - int write, void *); - int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, - int write, void *); - unw_fpreg_t fpval; - unw_word_t val; - int reg; - -#if defined(__linux) && !defined(UNW_REMOTE_ONLY) - if (c->as == unw_local_addr_space) - { - /* Take a short-cut: we directly resume out of the cursor and - all we need to do is make sure that all locations point to - memory, not registers. Furthermore, R4-R7 and NAT4-NAT7 are - taken care of by ia64_local_resume() so they don't need to be - handled here. */ -# define MEMIFY(preg, reg) \ - do { \ - if (IA64_IS_REG_LOC (c->loc[(preg)])) \ - c->loc[(preg)] = IA64_LOC_ADDR ((unw_word_t) \ - tdep_uc_addr(c->as_arg, (reg), \ - NULL), 0); \ - } while (0) - MEMIFY (IA64_REG_PR, UNW_IA64_PR); - MEMIFY (IA64_REG_PFS, UNW_IA64_AR_PFS); - MEMIFY (IA64_REG_RNAT, UNW_IA64_AR_RNAT); - MEMIFY (IA64_REG_UNAT, UNW_IA64_AR_UNAT); - MEMIFY (IA64_REG_LC, UNW_IA64_AR_LC); - MEMIFY (IA64_REG_FPSR, UNW_IA64_AR_FPSR); - MEMIFY (IA64_REG_IP, UNW_IA64_BR + 0); - MEMIFY (IA64_REG_B1, UNW_IA64_BR + 1); - MEMIFY (IA64_REG_B2, UNW_IA64_BR + 2); - MEMIFY (IA64_REG_B3, UNW_IA64_BR + 3); - MEMIFY (IA64_REG_B4, UNW_IA64_BR + 4); - MEMIFY (IA64_REG_B5, UNW_IA64_BR + 5); - MEMIFY (IA64_REG_F2, UNW_IA64_FR + 2); - MEMIFY (IA64_REG_F3, UNW_IA64_FR + 3); - MEMIFY (IA64_REG_F4, UNW_IA64_FR + 4); - MEMIFY (IA64_REG_F5, UNW_IA64_FR + 5); - MEMIFY (IA64_REG_F16, UNW_IA64_FR + 16); - MEMIFY (IA64_REG_F17, UNW_IA64_FR + 17); - MEMIFY (IA64_REG_F18, UNW_IA64_FR + 18); - MEMIFY (IA64_REG_F19, UNW_IA64_FR + 19); - MEMIFY (IA64_REG_F20, UNW_IA64_FR + 20); - MEMIFY (IA64_REG_F21, UNW_IA64_FR + 21); - MEMIFY (IA64_REG_F22, UNW_IA64_FR + 22); - MEMIFY (IA64_REG_F23, UNW_IA64_FR + 23); - MEMIFY (IA64_REG_F24, UNW_IA64_FR + 24); - MEMIFY (IA64_REG_F25, UNW_IA64_FR + 25); - MEMIFY (IA64_REG_F26, UNW_IA64_FR + 26); - MEMIFY (IA64_REG_F27, UNW_IA64_FR + 27); - MEMIFY (IA64_REG_F28, UNW_IA64_FR + 28); - MEMIFY (IA64_REG_F29, UNW_IA64_FR + 29); - MEMIFY (IA64_REG_F30, UNW_IA64_FR + 30); - MEMIFY (IA64_REG_F31, UNW_IA64_FR + 31); - } - else -#endif /* __linux && !UNW_REMOTE_ONLY */ - { - access_reg = c->as->acc.access_reg; - access_fpreg = c->as->acc.access_fpreg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_REG_LAST; ++reg) - { - if (unw_is_fpreg (reg)) - { - if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) - (*access_fpreg) (c->as, reg, &fpval, 1, c->as_arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - (*access_reg) (c->as, reg, &val, 1, c->as_arg); - } - } - } - return (*c->as->acc.resume) (c->as, (unw_cursor_t *) c, c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - - Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->ip); - -#ifdef UNW_LOCAL_ONLY - return local_resume (c->as, cursor, c->as_arg); -#else - return remote_install_cursor (c); -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gscript.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gscript.c deleted file mode 100644 index 526aeaf299edc3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gscript.c +++ /dev/null @@ -1,765 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "offsets.h" -#include "regs.h" -#include "unwind_i.h" - -enum ia64_script_insn_opcode - { - IA64_INSN_INC_PSP, /* psp += val */ - IA64_INSN_LOAD_PSP, /* psp = *psp_loc */ - IA64_INSN_ADD_PSP, /* s[dst] = (s.psp + val) */ - IA64_INSN_ADD_PSP_NAT, /* like above, but with NaT info */ - IA64_INSN_ADD_SP, /* s[dst] = (s.sp + val) */ - IA64_INSN_ADD_SP_NAT, /* like above, but with NaT info */ - IA64_INSN_MOVE, /* s[dst] = s[val] */ - IA64_INSN_MOVE_NAT, /* like above, but with NaT info */ - IA64_INSN_MOVE_NO_NAT, /* like above, but clear NaT info */ - IA64_INSN_MOVE_STACKED, /* s[dst] = rse_skip(*s.bsp_loc, val) */ - IA64_INSN_MOVE_STACKED_NAT, /* like above, but with NaT info */ - IA64_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */ - IA64_INSN_MOVE_SCRATCH_NAT, /* like above, but with NaT info */ - IA64_INSN_MOVE_SCRATCH_NO_NAT /* like above, but clear NaT info */ - }; - -#if defined(HAVE___THREAD) && HAVE___THREAD -static __thread struct ia64_script_cache ia64_per_thread_cache = - { -#ifdef HAVE_ATOMIC_OPS_H - .busy = AO_TS_INITIALIZER -#else - .lock = PTHREAD_MUTEX_INITIALIZER -#endif - }; -#endif - -static inline unw_hash_index_t CONST_ATTR -hash (unw_word_t ip) -{ - /* based on (sqrt(5)/2-1)*2^64 */ -# define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL) - - return (ip >> 4) * magic >> (64 - IA64_LOG_UNW_HASH_SIZE); -} - -static inline long -cache_match (struct ia64_script *script, unw_word_t ip, unw_word_t pr) -{ - if (ip == script->ip && ((pr ^ script->pr_val) & script->pr_mask) == 0) - return 1; - return 0; -} - -static inline void -flush_script_cache (struct ia64_script_cache *cache) -{ - int i; - - cache->lru_head = IA64_UNW_CACHE_SIZE - 1; - cache->lru_tail = 0; - - for (i = 0; i < IA64_UNW_CACHE_SIZE; ++i) - { - if (i > 0) - cache->buckets[i].lru_chain = (i - 1); - cache->buckets[i].coll_chain = -1; - cache->buckets[i].ip = 0; - } - for (i = 0; ihash[i] = -1; -} - -static inline struct ia64_script_cache * -get_script_cache (unw_addr_space_t as, intrmask_t *saved_maskp) -{ - struct ia64_script_cache *cache = &as->global_cache; - unw_caching_policy_t caching = as->caching_policy; - - if (caching == UNW_CACHE_NONE) - return NULL; - -#ifdef HAVE_ATOMIC_H - if (!spin_trylock_irqsave (&cache->busy, *saved_maskp)) - return NULL; -#else -# if defined(HAVE___THREAD) && HAVE___THREAD - if (as->caching_policy == UNW_CACHE_PER_THREAD) - cache = &ia64_per_thread_cache; -# endif -# ifdef HAVE_ATOMIC_OPS_H - if (AO_test_and_set (&cache->busy) == AO_TS_SET) - return NULL; -# else - if (likely (caching == UNW_CACHE_GLOBAL)) - { - Debug (16, "acquiring lock\n"); - lock_acquire (&cache->lock, *saved_maskp); - } -# endif -#endif - - if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation)) - { - flush_script_cache (cache); - cache->generation = as->cache_generation; - } - return cache; -} - -static inline void -put_script_cache (unw_addr_space_t as, struct ia64_script_cache *cache, - intrmask_t *saved_maskp) -{ - assert (as->caching_policy != UNW_CACHE_NONE); - - Debug (16, "unmasking signals/interrupts and releasing lock\n"); -#ifdef HAVE_ATOMIC_H - spin_unlock_irqrestore (&cache->busy, *saved_maskp); -#else -# ifdef HAVE_ATOMIC_OPS_H - AO_CLEAR (&cache->busy); -# else - if (likely (as->caching_policy == UNW_CACHE_GLOBAL)) - lock_release (&cache->lock, *saved_maskp); -# endif -#endif -} - -static struct ia64_script * -script_lookup (struct ia64_script_cache *cache, struct cursor *c) -{ - struct ia64_script *script = cache->buckets + c->hint; - unsigned short index; - unw_word_t ip, pr; - - ip = c->ip; - pr = c->pr; - - if (cache_match (script, ip, pr)) - return script; - - index = cache->hash[hash (ip)]; - if (index >= IA64_UNW_CACHE_SIZE) - return 0; - - script = cache->buckets + index; - while (1) - { - if (cache_match (script, ip, pr)) - { - /* update hint; no locking needed: single-word writes are atomic */ - c->hint = cache->buckets[c->prev_script].hint = - (script - cache->buckets); - return script; - } - if (script->coll_chain >= IA64_UNW_HASH_SIZE) - return 0; - script = cache->buckets + script->coll_chain; - } -} - -static inline void -script_init (struct ia64_script *script, unw_word_t ip) -{ - script->ip = ip; - script->hint = 0; - script->count = 0; - script->abi_marker = 0; -} - -static inline struct ia64_script * -script_new (struct ia64_script_cache *cache, unw_word_t ip) -{ - struct ia64_script *script, *prev, *tmp; - unw_hash_index_t index; - unsigned short head; - - head = cache->lru_head; - script = cache->buckets + head; - cache->lru_head = script->lru_chain; - - /* re-insert script at the tail of the LRU chain: */ - cache->buckets[cache->lru_tail].lru_chain = head; - cache->lru_tail = head; - - /* remove the old script from the hash table (if it's there): */ - if (script->ip) - { - index = hash (script->ip); - tmp = cache->buckets + cache->hash[index]; - prev = 0; - while (1) - { - if (tmp == script) - { - if (prev) - prev->coll_chain = tmp->coll_chain; - else - cache->hash[index] = tmp->coll_chain; - break; - } - else - prev = tmp; - if (tmp->coll_chain >= IA64_UNW_CACHE_SIZE) - /* old script wasn't in the hash-table */ - break; - tmp = cache->buckets + tmp->coll_chain; - } - } - - /* enter new script in the hash table */ - index = hash (ip); - script->coll_chain = cache->hash[index]; - cache->hash[index] = script - cache->buckets; - - script_init (script, ip); - return script; -} - -static inline void -script_finalize (struct ia64_script *script, struct cursor *c, - struct ia64_state_record *sr) -{ - script->pr_mask = sr->pr_mask; - script->pr_val = sr->pr_val; - script->pi = c->pi; -} - -static inline void -script_emit (struct ia64_script *script, struct ia64_script_insn insn) -{ - if (script->count >= IA64_MAX_SCRIPT_LEN) - { - Dprintf ("%s: script exceeds maximum size of %u instructions!\n", - __FUNCTION__, IA64_MAX_SCRIPT_LEN); - return; - } - script->insn[script->count++] = insn; -} - -static void -compile_reg (struct ia64_state_record *sr, int i, struct ia64_reg_info *r, - struct ia64_script *script) -{ - enum ia64_script_insn_opcode opc; - unsigned long val, rval; - struct ia64_script_insn insn; - long is_preserved_gr; - - if (r->where == IA64_WHERE_NONE || r->when >= sr->when_target) - return; - - opc = IA64_INSN_MOVE; - val = rval = r->val; - is_preserved_gr = (i >= IA64_REG_R4 && i <= IA64_REG_R7); - - if (r->where == IA64_WHERE_GR) - { - /* Handle most common case first... */ - if (rval >= 32) - { - /* register got spilled to a stacked register */ - if (is_preserved_gr) - opc = IA64_INSN_MOVE_STACKED_NAT; - else - opc = IA64_INSN_MOVE_STACKED; - val = rval; - } - else if (rval >= 4 && rval <= 7) - { - /* register got spilled to a preserved register */ - val = IA64_REG_R4 + (rval - 4); - if (is_preserved_gr) - opc = IA64_INSN_MOVE_NAT; - } - else - { - /* register got spilled to a scratch register */ - if (is_preserved_gr) - opc = IA64_INSN_MOVE_SCRATCH_NAT; - else - opc = IA64_INSN_MOVE_SCRATCH; - val = UNW_IA64_GR + rval; - } - } - else - { - switch (r->where) - { - case IA64_WHERE_FR: - /* Note: There is no need to handle NaT-bit info here - (indepent of is_preserved_gr), because for floating-point - NaTs are represented as NaTVal, so the NaT-info never - needs to be consulated. */ - if (rval >= 2 && rval <= 5) - val = IA64_REG_F2 + (rval - 2); - else if (rval >= 16 && rval <= 31) - val = IA64_REG_F16 + (rval - 16); - else - { - opc = IA64_INSN_MOVE_SCRATCH; - val = UNW_IA64_FR + rval; - } - break; - - case IA64_WHERE_BR: - if (rval >= 1 && rval <= 5) - { - val = IA64_REG_B1 + (rval - 1); - if (is_preserved_gr) - opc = IA64_INSN_MOVE_NO_NAT; - } - else - { - opc = IA64_INSN_MOVE_SCRATCH; - if (is_preserved_gr) - opc = IA64_INSN_MOVE_SCRATCH_NO_NAT; - val = UNW_IA64_BR + rval; - } - break; - - case IA64_WHERE_SPREL: - if (is_preserved_gr) - opc = IA64_INSN_ADD_SP_NAT; - else - { - opc = IA64_INSN_ADD_SP; - if (i >= IA64_REG_F2 && i <= IA64_REG_F31) - val |= IA64_LOC_TYPE_FP; - } - break; - - case IA64_WHERE_PSPREL: - if (is_preserved_gr) - opc = IA64_INSN_ADD_PSP_NAT; - else - { - opc = IA64_INSN_ADD_PSP; - if (i >= IA64_REG_F2 && i <= IA64_REG_F31) - val |= IA64_LOC_TYPE_FP; - } - break; - - default: - Dprintf ("%s: register %u has unexpected `where' value of %u\n", - __FUNCTION__, i, r->where); - break; - } - } - insn.opc = opc; - insn.dst = i; - insn.val = val; - script_emit (script, insn); - - if (i == IA64_REG_PSP) - { - /* c->psp must contain the _value_ of the previous sp, not it's - save-location. We get this by dereferencing the value we - just stored in loc[IA64_REG_PSP]: */ - insn.opc = IA64_INSN_LOAD_PSP; - script_emit (script, insn); - } -} - -/* Sort the registers which got saved in decreasing order of WHEN - value. This is needed to ensure that the save-locations are - updated in the proper order. For example, suppose r4 gets spilled - to memory and then r5 gets saved in r4. In this case, we need to - update the save location of r5 before the one of r4. */ - -static inline int -sort_regs (struct ia64_state_record *sr, int regorder[]) -{ - int r, i, j, max, max_reg, max_when, num_regs = 0; - - assert (IA64_REG_BSP == 3); - - for (r = IA64_REG_BSP; r < IA64_NUM_PREGS; ++r) - { - if (sr->curr.reg[r].where == IA64_WHERE_NONE - || sr->curr.reg[r].when >= sr->when_target) - continue; - - regorder[num_regs++] = r; - } - - /* Simple insertion-sort. Involves about N^2/2 comparisons and N - exchanges. N is often small (say, 2-5) so a fancier sorting - algorithm may not be worthwhile. */ - - for (i = max = 0; i < num_regs - 1; ++i) - { - max_reg = regorder[max]; - max_when = sr->curr.reg[max_reg].when; - - for (j = i + 1; j < num_regs; ++j) - if (sr->curr.reg[regorder[j]].when > max_when) - { - max = j; - max_reg = regorder[j]; - max_when = sr->curr.reg[max_reg].when; - } - if (i != max) - { - regorder[max] = regorder[i]; - regorder[i] = max_reg; - } - } - return num_regs; -} - -/* Build an unwind script that unwinds from state OLD_STATE to the - entrypoint of the function that called OLD_STATE. */ - -static inline int -build_script (struct cursor *c, struct ia64_script *script) -{ - int num_regs, i, ret, regorder[IA64_NUM_PREGS - 3]; - struct ia64_reg_info *pri_unat; - struct ia64_state_record sr; - struct ia64_script_insn insn; - - ret = ia64_create_state_record (c, &sr); - if (ret < 0) - return ret; - - /* First, compile the update for IA64_REG_PSP. This is important - because later save-locations may depend on it's correct (updated) - value. Fixed-size frames are handled specially and variable-size - frames get handled via the normal compile_reg(). */ - - if (sr.when_target > sr.curr.reg[IA64_REG_PSP].when - && (sr.curr.reg[IA64_REG_PSP].where == IA64_WHERE_NONE) - && sr.curr.reg[IA64_REG_PSP].val != 0) - { - /* new psp is psp plus frame size */ - insn.opc = IA64_INSN_INC_PSP; - insn.val = sr.curr.reg[IA64_REG_PSP].val; /* frame size */ - script_emit (script, insn); - } - else - compile_reg (&sr, IA64_REG_PSP, sr.curr.reg + IA64_REG_PSP, script); - - /* Second, compile the update for the primary UNaT, if any: */ - - if (sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_GR].when - || sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when) - { - if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_GR].when) - /* (primary) NaT bits were saved to memory only */ - pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM; - else if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when) - /* (primary) NaT bits were saved to a register only */ - pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_GR; - else if (sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when > - sr.curr.reg[IA64_REG_PRI_UNAT_GR].when) - /* (primary) NaT bits were last saved to memory */ - pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM; - else - /* (primary) NaT bits were last saved to a register */ - pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_GR; - - /* Note: we always store the final primary-UNaT location in UNAT_MEM. */ - compile_reg (&sr, IA64_REG_PRI_UNAT_MEM, pri_unat, script); - } - - /* Third, compile the other register in decreasing order of WHEN values. */ - - num_regs = sort_regs (&sr, regorder); - for (i = 0; i < num_regs; ++i) - compile_reg (&sr, regorder[i], sr.curr.reg + regorder[i], script); - - script->abi_marker = sr.abi_marker; - script_finalize (script, c, &sr); - - ia64_free_state_record (&sr); - return 0; -} - -static inline void -set_nat_info (struct cursor *c, unsigned long dst, - ia64_loc_t nat_loc, uint8_t bitnr) -{ - assert (dst >= IA64_REG_R4 && dst <= IA64_REG_R7); - - c->loc[dst - IA64_REG_R4 + IA64_REG_NAT4] = nat_loc; - c->nat_bitnr[dst - IA64_REG_R4] = bitnr; -} - -/* Apply the unwinding actions represented by OPS and update SR to - reflect the state that existed upon entry to the function that this - unwinder represents. */ - -static inline int -run_script (struct ia64_script *script, struct cursor *c) -{ - struct ia64_script_insn *ip, *limit, next_insn; - ia64_loc_t loc, nat_loc; - unsigned long opc, dst; - uint8_t nat_bitnr; - unw_word_t val; - int ret; - - c->pi = script->pi; - ip = script->insn; - limit = script->insn + script->count; - next_insn = *ip; - c->abi_marker = script->abi_marker; - - while (ip++ < limit) - { - opc = next_insn.opc; - dst = next_insn.dst; - val = next_insn.val; - next_insn = *ip; - - /* This is by far the most common operation: */ - if (likely (opc == IA64_INSN_MOVE_STACKED)) - { - if ((ret = ia64_get_stacked (c, val, &loc, NULL)) < 0) - return ret; - } - else - switch (opc) - { - case IA64_INSN_INC_PSP: - c->psp += val; - continue; - - case IA64_INSN_LOAD_PSP: - if ((ret = ia64_get (c, c->loc[IA64_REG_PSP], &c->psp)) < 0) - return ret; - continue; - - case IA64_INSN_ADD_PSP: - loc = IA64_LOC_ADDR (c->psp + val, (val & IA64_LOC_TYPE_FP)); - break; - - case IA64_INSN_ADD_SP: - loc = IA64_LOC_ADDR (c->sp + val, (val & IA64_LOC_TYPE_FP)); - break; - - case IA64_INSN_MOVE_NO_NAT: - set_nat_info (c, dst, IA64_NULL_LOC, 0); - case IA64_INSN_MOVE: - loc = c->loc[val]; - break; - - case IA64_INSN_MOVE_SCRATCH_NO_NAT: - set_nat_info (c, dst, IA64_NULL_LOC, 0); - case IA64_INSN_MOVE_SCRATCH: - loc = ia64_scratch_loc (c, val, NULL); - break; - - case IA64_INSN_ADD_PSP_NAT: - loc = IA64_LOC_ADDR (c->psp + val, 0); - assert (!IA64_IS_REG_LOC (loc)); - set_nat_info (c, dst, - c->loc[IA64_REG_PRI_UNAT_MEM], - ia64_unat_slot_num (IA64_GET_ADDR (loc))); - break; - - case IA64_INSN_ADD_SP_NAT: - loc = IA64_LOC_ADDR (c->sp + val, 0); - assert (!IA64_IS_REG_LOC (loc)); - set_nat_info (c, dst, - c->loc[IA64_REG_PRI_UNAT_MEM], - ia64_unat_slot_num (IA64_GET_ADDR (loc))); - break; - - case IA64_INSN_MOVE_NAT: - loc = c->loc[val]; - set_nat_info (c, dst, - c->loc[val - IA64_REG_R4 + IA64_REG_NAT4], - c->nat_bitnr[val - IA64_REG_R4]); - break; - - case IA64_INSN_MOVE_STACKED_NAT: - if ((ret = ia64_get_stacked (c, val, &loc, &nat_loc)) < 0) - return ret; - assert (!IA64_IS_REG_LOC (loc)); - set_nat_info (c, dst, nat_loc, rse_slot_num (IA64_GET_ADDR (loc))); - break; - - case IA64_INSN_MOVE_SCRATCH_NAT: - loc = ia64_scratch_loc (c, val, NULL); - nat_loc = ia64_scratch_loc (c, val + (UNW_IA64_NAT - UNW_IA64_GR), - &nat_bitnr); - set_nat_info (c, dst, nat_loc, nat_bitnr); - break; - } - c->loc[dst] = loc; - } - return 0; -} - -static int -uncached_find_save_locs (struct cursor *c) -{ - struct ia64_script script; - int ret = 0; - - if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0) - return ret; - - script_init (&script, c->ip); - if ((ret = build_script (c, &script)) < 0) - { - if (ret != -UNW_ESTOPUNWIND) - Dprintf ("%s: failed to build unwind script for ip %lx\n", - __FUNCTION__, (long) c->ip); - return ret; - } - return run_script (&script, c); -} - -HIDDEN int -ia64_find_save_locs (struct cursor *c) -{ - struct ia64_script_cache *cache = NULL; - struct ia64_script *script = NULL; - intrmask_t saved_mask; - int ret = 0; - - if (c->as->caching_policy == UNW_CACHE_NONE) - return uncached_find_save_locs (c); - - cache = get_script_cache (c->as, &saved_mask); - if (!cache) - { - Debug (1, "contention on script-cache; doing uncached lookup\n"); - return uncached_find_save_locs (c); - } - { - script = script_lookup (cache, c); - Debug (8, "ip %lx %s in script cache\n", (long) c->ip, - script ? "hit" : "missed"); - - if (!script || (script->count == 0 && !script->pi.unwind_info)) - { - if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0) - goto out; - } - - if (!script) - { - script = script_new (cache, c->ip); - if (!script) - { - Dprintf ("%s: failed to create unwind script\n", __FUNCTION__); - ret = -UNW_EUNSPEC; - goto out; - } - } - cache->buckets[c->prev_script].hint = script - cache->buckets; - - if (script->count == 0) - ret = build_script (c, script); - - assert (script->count > 0); - - c->hint = script->hint; - c->prev_script = script - cache->buckets; - - if (ret < 0) - { - if (ret != -UNW_ESTOPUNWIND) - Dprintf ("%s: failed to locate/build unwind script for ip %lx\n", - __FUNCTION__, (long) c->ip); - goto out; - } - - ret = run_script (script, c); - } - out: - put_script_cache (c->as, cache, &saved_mask); - return ret; -} - -HIDDEN void -ia64_validate_cache (unw_addr_space_t as, void *arg) -{ -#ifndef UNW_REMOTE_ONLY - if (as == unw_local_addr_space && ia64_local_validate_cache (as, arg) == 1) - return; -#endif - -#ifndef UNW_LOCAL_ONLY - /* local info is up-to-date, check dynamic info. */ - unwi_dyn_validate_cache (as, arg); -#endif -} - -HIDDEN int -ia64_cache_proc_info (struct cursor *c) -{ - struct ia64_script_cache *cache; - struct ia64_script *script; - intrmask_t saved_mask; - int ret = 0; - - cache = get_script_cache (c->as, &saved_mask); - if (!cache) - return ret; /* cache is busy */ - - /* Re-check to see if a cache entry has been added in the meantime: */ - script = script_lookup (cache, c); - if (script) - goto out; - - script = script_new (cache, c->ip); - if (!script) - { - Dprintf ("%s: failed to create unwind script\n", __FUNCTION__); - ret = -UNW_EUNSPEC; - goto out; - } - - script->pi = c->pi; - - out: - put_script_cache (c->as, cache, &saved_mask); - return ret; -} - -HIDDEN int -ia64_get_cached_proc_info (struct cursor *c) -{ - struct ia64_script_cache *cache; - struct ia64_script *script; - intrmask_t saved_mask; - - cache = get_script_cache (c->as, &saved_mask); - if (!cache) - return -UNW_ENOINFO; /* cache is busy */ - { - script = script_lookup (cache, c); - if (script) - c->pi = script->pi; - } - put_script_cache (c->as, cache, &saved_mask); - return script ? 0 : -UNW_ENOINFO; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gstep.c deleted file mode 100644 index df4ecb8796c6e8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gstep.c +++ /dev/null @@ -1,359 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "offsets.h" -#include "unwind_i.h" - -static inline int -linux_sigtramp (struct cursor *c, ia64_loc_t prev_cfm_loc, - unw_word_t *num_regsp) -{ -#if defined(UNW_LOCAL_ONLY) && !defined(__linux) - return -UNW_EINVAL; -#else - unw_word_t sc_addr; - int ret; - - if ((ret = ia64_get (c, IA64_LOC_ADDR (c->sp + 0x10 - + LINUX_SIGFRAME_ARG2_OFF, 0), - &sc_addr)) < 0) - return ret; - - c->sigcontext_addr = sc_addr; - - if (!IA64_IS_REG_LOC (c->loc[IA64_REG_IP]) - && IA64_GET_ADDR (c->loc[IA64_REG_IP]) == sc_addr + LINUX_SC_BR_OFF + 8) - { - /* Linux kernels before 2.4.19 and 2.5.10 had buggy - unwind info for sigtramp. Fix it up here. */ - c->loc[IA64_REG_IP] = IA64_LOC_ADDR (sc_addr + LINUX_SC_IP_OFF, 0); - c->cfm_loc = IA64_LOC_ADDR (sc_addr + LINUX_SC_CFM_OFF, 0); - } - - /* do what can't be described by unwind directives: */ - c->loc[IA64_REG_PFS] = IA64_LOC_ADDR (sc_addr + LINUX_SC_AR_PFS_OFF, 0); - c->ec_loc = prev_cfm_loc; - *num_regsp = c->cfm & 0x7f; /* size of frame */ - return 0; -#endif -} - -static inline int -linux_interrupt (struct cursor *c, ia64_loc_t prev_cfm_loc, - unw_word_t *num_regsp, int marker) -{ -#if defined(UNW_LOCAL_ONLY) && !(defined(__linux) && defined(__KERNEL__)) - return -UNW_EINVAL; -#else - unw_word_t sc_addr, num_regs; - ia64_loc_t pfs_loc; - - sc_addr = c->sigcontext_addr = c->sp + 0x10; - - if ((c->pr & (1UL << LINUX_PT_P_NONSYS)) != 0) - num_regs = c->cfm & 0x7f; - else - num_regs = 0; - - /* do what can't be described by unwind directives: */ - if (marker == ABI_MARKER_OLD_LINUX_INTERRUPT) - pfs_loc = IA64_LOC_ADDR (sc_addr + LINUX_OLD_PT_PFS_OFF, 0); - else - pfs_loc = IA64_LOC_ADDR (sc_addr + LINUX_PT_PFS_OFF, 0); - c->loc[IA64_REG_PFS] = pfs_loc; - c->ec_loc = prev_cfm_loc; - *num_regsp = num_regs; /* size of frame */ - return 0; -#endif -} - -static inline int -hpux_sigtramp (struct cursor *c, ia64_loc_t prev_cfm_loc, - unw_word_t *num_regsp) -{ -#if defined(UNW_LOCAL_ONLY) && !defined(__hpux) - return -UNW_EINVAL; -#else - unw_word_t sc_addr, bsp, bspstore; - ia64_loc_t sc_loc; - int ret, i; - - /* HP-UX passes the address of ucontext_t in r32: */ - if ((ret = ia64_get_stacked (c, 32, &sc_loc, NULL)) < 0) - return ret; - if ((ret = ia64_get (c, sc_loc, &sc_addr)) < 0) - return ret; - - c->sigcontext_addr = sc_addr; - - /* Now mark all (preserved) registers as coming from the - signal context: */ - c->cfm_loc = IA64_LOC_UC_REG (UNW_IA64_CFM, sc_addr); - c->loc[IA64_REG_PRI_UNAT_MEM] = IA64_NULL_LOC; - c->loc[IA64_REG_PSP] = IA64_LOC_UC_REG (UNW_IA64_GR + 12, sc_addr); - c->loc[IA64_REG_BSP] = IA64_LOC_UC_REG (UNW_IA64_AR_BSP, sc_addr); - c->loc[IA64_REG_BSPSTORE] = IA64_LOC_UC_REG (UNW_IA64_AR_BSPSTORE, sc_addr); - c->loc[IA64_REG_PFS] = IA64_LOC_UC_REG (UNW_IA64_AR_PFS, sc_addr); - c->loc[IA64_REG_RNAT] = IA64_LOC_UC_REG (UNW_IA64_AR_RNAT, sc_addr); - c->loc[IA64_REG_IP] = IA64_LOC_UC_REG (UNW_IA64_IP, sc_addr); - c->loc[IA64_REG_R4] = IA64_LOC_UC_REG (UNW_IA64_GR + 4, sc_addr); - c->loc[IA64_REG_R5] = IA64_LOC_UC_REG (UNW_IA64_GR + 5, sc_addr); - c->loc[IA64_REG_R6] = IA64_LOC_UC_REG (UNW_IA64_GR + 6, sc_addr); - c->loc[IA64_REG_R7] = IA64_LOC_UC_REG (UNW_IA64_GR + 7, sc_addr); - c->loc[IA64_REG_NAT4] = IA64_LOC_UC_REG (UNW_IA64_NAT + 4, sc_addr); - c->loc[IA64_REG_NAT5] = IA64_LOC_UC_REG (UNW_IA64_NAT + 5, sc_addr); - c->loc[IA64_REG_NAT6] = IA64_LOC_UC_REG (UNW_IA64_NAT + 6, sc_addr); - c->loc[IA64_REG_NAT7] = IA64_LOC_UC_REG (UNW_IA64_NAT + 7, sc_addr); - c->loc[IA64_REG_UNAT] = IA64_LOC_UC_REG (UNW_IA64_AR_UNAT, sc_addr); - c->loc[IA64_REG_PR] = IA64_LOC_UC_REG (UNW_IA64_PR, sc_addr); - c->loc[IA64_REG_LC] = IA64_LOC_UC_REG (UNW_IA64_AR_LC, sc_addr); - c->loc[IA64_REG_FPSR] = IA64_LOC_UC_REG (UNW_IA64_AR_FPSR, sc_addr); - c->loc[IA64_REG_B1] = IA64_LOC_UC_REG (UNW_IA64_BR + 1, sc_addr); - c->loc[IA64_REG_B2] = IA64_LOC_UC_REG (UNW_IA64_BR + 2, sc_addr); - c->loc[IA64_REG_B3] = IA64_LOC_UC_REG (UNW_IA64_BR + 3, sc_addr); - c->loc[IA64_REG_B4] = IA64_LOC_UC_REG (UNW_IA64_BR + 4, sc_addr); - c->loc[IA64_REG_B5] = IA64_LOC_UC_REG (UNW_IA64_BR + 5, sc_addr); - c->loc[IA64_REG_F2] = IA64_LOC_UC_REG (UNW_IA64_FR + 2, sc_addr); - c->loc[IA64_REG_F3] = IA64_LOC_UC_REG (UNW_IA64_FR + 3, sc_addr); - c->loc[IA64_REG_F4] = IA64_LOC_UC_REG (UNW_IA64_FR + 4, sc_addr); - c->loc[IA64_REG_F5] = IA64_LOC_UC_REG (UNW_IA64_FR + 5, sc_addr); - for (i = 0; i < 16; ++i) - c->loc[IA64_REG_F16 + i] = IA64_LOC_UC_REG (UNW_IA64_FR + 16 + i, sc_addr); - - c->pi.flags |= UNW_PI_FLAG_IA64_RBS_SWITCH; - - /* update the CFM cache: */ - if ((ret = ia64_get (c, c->cfm_loc, &c->cfm)) < 0) - return ret; - /* update the PSP cache: */ - if ((ret = ia64_get (c, c->loc[IA64_REG_PSP], &c->psp)) < 0) - return ret; - - if ((ret = ia64_get (c, c->loc[IA64_REG_BSP], &bsp)) < 0 - || (ret = ia64_get (c, c->loc[IA64_REG_BSPSTORE], &bspstore)) < 0) - return ret; - if (bspstore < bsp) - /* Dirty partition got spilled into the ucontext_t structure - itself. We'll need to access it via uc_access(3). */ - rbs_switch (c, bsp, bspstore, IA64_LOC_UC_ADDR (bsp | 0x1f8, 0)); - - c->ec_loc = prev_cfm_loc; - - *num_regsp = 0; - return 0; -#endif -} - - -static inline int -check_rbs_switch (struct cursor *c) -{ - unw_word_t saved_bsp, saved_bspstore, loadrs, ndirty; - int ret = 0; - - saved_bsp = c->bsp; - if (c->pi.flags & UNW_PI_FLAG_IA64_RBS_SWITCH) - { - /* Got ourselves a frame that has saved ar.bspstore, ar.bsp, - and ar.rnat, so we're all set for rbs-switching: */ - if ((ret = ia64_get (c, c->loc[IA64_REG_BSP], &saved_bsp)) < 0 - || (ret = ia64_get (c, c->loc[IA64_REG_BSPSTORE], &saved_bspstore))) - return ret; - } - else if ((c->abi_marker == ABI_MARKER_LINUX_SIGTRAMP - || c->abi_marker == ABI_MARKER_OLD_LINUX_SIGTRAMP) - && !IA64_IS_REG_LOC (c->loc[IA64_REG_BSP]) - && (IA64_GET_ADDR (c->loc[IA64_REG_BSP]) - == c->sigcontext_addr + LINUX_SC_AR_BSP_OFF)) - { - /* When Linux delivers a signal on an alternate stack, it - does things a bit differently from what the unwind - conventions allow us to describe: instead of saving - ar.rnat, ar.bsp, and ar.bspstore, it saves the former two - plus the "loadrs" value. Because of this, we need to - detect & record a potential rbs-area switch - manually... */ - - /* If ar.bsp has been saved already AND the current bsp is - not equal to the saved value, then we know for sure that - we're past the point where the backing store has been - switched (and before the point where it's restored). */ - if ((ret = ia64_get (c, IA64_LOC_ADDR (c->sigcontext_addr - + LINUX_SC_AR_BSP_OFF, 0), - &saved_bsp) < 0) - || (ret = ia64_get (c, IA64_LOC_ADDR (c->sigcontext_addr - + LINUX_SC_LOADRS_OFF, 0), - &loadrs) < 0)) - return ret; - loadrs >>= 16; - ndirty = rse_num_regs (c->bsp - loadrs, c->bsp); - saved_bspstore = rse_skip_regs (saved_bsp, -ndirty); - } - - if (saved_bsp == c->bsp) - return 0; - - return rbs_switch (c, saved_bsp, saved_bspstore, c->loc[IA64_REG_RNAT]); -} - -static inline int -update_frame_state (struct cursor *c) -{ - unw_word_t prev_ip, prev_sp, prev_bsp, ip, num_regs; - ia64_loc_t prev_cfm_loc; - int ret; - - prev_cfm_loc = c->cfm_loc; - prev_ip = c->ip; - prev_sp = c->sp; - prev_bsp = c->bsp; - - /* Update the IP cache (do this first: if we reach the end of the - frame-chain, the rest of the info may not be valid/useful - anymore. */ - ret = ia64_get (c, c->loc[IA64_REG_IP], &ip); - if (ret < 0) - return ret; - c->ip = ip; - - if ((ip & 0xc) != 0) - { - /* don't let obviously bad addresses pollute the cache */ - Debug (1, "rejecting bad ip=0x%lx\n", (long) c->ip); - return -UNW_EINVALIDIP; - } - - c->cfm_loc = c->loc[IA64_REG_PFS]; - /* update the CFM cache: */ - ret = ia64_get (c, c->cfm_loc, &c->cfm); - if (ret < 0) - return ret; - - /* Normally, AR.EC is stored in the CFM save-location. That - save-location contains the full function-state as defined by - AR.PFS. However, interruptions only save the frame-marker, not - any other info in CFM. Instead, AR.EC gets saved on the first - call by the interruption-handler. Thus, interruption-related - frames need to track the _previous_ CFM save-location since - that's were AR.EC is saved. We support this by setting ec_loc to - cfm_loc by default and giving frames marked with an ABI-marker - the chance to override this value with prev_cfm_loc. */ - c->ec_loc = c->cfm_loc; - - num_regs = 0; - if (unlikely (c->abi_marker)) - { - c->last_abi_marker = c->abi_marker; - switch (ia64_get_abi_marker (c)) - { - case ABI_MARKER_LINUX_SIGTRAMP: - case ABI_MARKER_OLD_LINUX_SIGTRAMP: - ia64_set_abi (c, ABI_LINUX); - if ((ret = linux_sigtramp (c, prev_cfm_loc, &num_regs)) < 0) - return ret; - break; - - case ABI_MARKER_OLD_LINUX_INTERRUPT: - case ABI_MARKER_LINUX_INTERRUPT: - ia64_set_abi (c, ABI_LINUX); - if ((ret = linux_interrupt (c, prev_cfm_loc, &num_regs, - c->abi_marker)) < 0) - return ret; - break; - - case ABI_MARKER_HP_UX_SIGTRAMP: - ia64_set_abi (c, ABI_HPUX); - if ((ret = hpux_sigtramp (c, prev_cfm_loc, &num_regs)) < 0) - return ret; - break; - - default: - Debug (1, "unknown ABI marker: ABI=%u, context=%u\n", - c->abi_marker >> 8, c->abi_marker & 0xff); - return -UNW_EINVAL; - } - Debug (12, "sigcontext_addr=%lx (ret=%d)\n", - (unsigned long) c->sigcontext_addr, ret); - - c->sigcontext_off = c->sigcontext_addr - c->sp; - - /* update the IP cache: */ - if ((ret = ia64_get (c, c->loc[IA64_REG_IP], &ip)) < 0) - return ret; - c->ip = ip; - if (ip == 0) - /* end of frame-chain reached */ - return 0; - } - else - num_regs = (c->cfm >> 7) & 0x7f; /* size of locals */ - - if (!IA64_IS_NULL_LOC (c->loc[IA64_REG_BSP])) - { - ret = check_rbs_switch (c); - if (ret < 0) - return ret; - } - - c->bsp = rse_skip_regs (c->bsp, -num_regs); - - c->sp = c->psp; - c->abi_marker = 0; - - if (c->ip == prev_ip && c->sp == prev_sp && c->bsp == prev_bsp) - { - Dprintf ("%s: ip, sp, and bsp unchanged; stopping here (ip=0x%lx)\n", - __FUNCTION__, (long) ip); - return -UNW_EBADFRAME; - } - - /* as we unwind, the saved ar.unat becomes the primary unat: */ - c->loc[IA64_REG_PRI_UNAT_MEM] = c->loc[IA64_REG_UNAT]; - - /* restore the predicates: */ - ret = ia64_get (c, c->loc[IA64_REG_PR], &c->pr); - if (ret < 0) - return ret; - - c->pi_valid = 0; - return 0; -} - - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->ip); - - if ((ret = ia64_find_save_locs (c)) >= 0 - && (ret = update_frame_state (c)) >= 0) - ret = (c->ip == 0) ? 0 : 1; - - Debug (2, "returning %d (ip=0x%016lx)\n", ret, (unsigned long) c->ip); - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gtables.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gtables.c deleted file mode 100644 index f5e8f2d8f4da81..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Gtables.c +++ /dev/null @@ -1,731 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2001-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include - -#include "unwind_i.h" - -#ifdef HAVE_IA64INTRIN_H -# include -#endif - -extern unw_addr_space_t _ULia64_local_addr_space; - -struct ia64_table_entry - { - uint64_t start_offset; - uint64_t end_offset; - uint64_t info_offset; - }; - -#ifdef UNW_LOCAL_ONLY - -static inline int -is_local_addr_space (unw_addr_space_t as) -{ - return 1; -} - -static inline int -read_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, void *arg) -{ - *valp = *(unw_word_t *) addr; - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ - -static inline int -is_local_addr_space (unw_addr_space_t as) -{ - return as == unw_local_addr_space; -} - -static inline int -read_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, void *arg) -{ - unw_accessors_t *a = unw_get_accessors_int (as); - - return (*a->access_mem) (as, addr, valp, 0, arg); -} - -/* Helper macro for reading an ia64_table_entry from remote memory. */ -#define remote_read(addr, member) \ - (*a->access_mem) (as, (addr) + offsetof (struct ia64_table_entry, \ - member), &member, 0, arg) - -/* Lookup an unwind-table entry in remote memory. Returns 1 if an - entry is found, 0 if no entry is found, negative if an error - occurred reading remote memory. */ -static int -remote_lookup (unw_addr_space_t as, - unw_word_t table, size_t table_size, unw_word_t rel_ip, - struct ia64_table_entry *e, void *arg) -{ - unw_word_t e_addr = 0, start_offset, end_offset, info_offset; - unw_accessors_t *a = unw_get_accessors_int (as); - unsigned long lo, hi, mid; - int ret; - - /* do a binary search for right entry: */ - for (lo = 0, hi = table_size / sizeof (struct ia64_table_entry); lo < hi;) - { - mid = (lo + hi) / 2; - e_addr = table + mid * sizeof (struct ia64_table_entry); - if ((ret = remote_read (e_addr, start_offset)) < 0) - return ret; - - if (rel_ip < start_offset) - hi = mid; - else - { - if ((ret = remote_read (e_addr, end_offset)) < 0) - return ret; - - if (rel_ip >= end_offset) - lo = mid + 1; - else - break; - } - } - if (rel_ip < start_offset || rel_ip >= end_offset) - return 0; - e->start_offset = start_offset; - e->end_offset = end_offset; - - if ((ret = remote_read (e_addr, info_offset)) < 0) - return ret; - e->info_offset = info_offset; - return 1; -} - -HIDDEN void -tdep_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) -{ - if (!pi->unwind_info) - return; - - if (is_local_addr_space (as)) - { - free (pi->unwind_info); - pi->unwind_info = NULL; - } -} - -unw_word_t -_Uia64_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg) -{ - unw_word_t hdr_addr, info_addr, hdr, directives, pers, cookie, off; - unw_word_t start_offset, end_offset, info_offset, segbase; - struct ia64_table_entry *e; - size_t table_size; - unw_word_t gp = di->gp; - int ret; - - switch (di->format) - { - case UNW_INFO_FORMAT_DYNAMIC: - default: - return 0; - - case UNW_INFO_FORMAT_TABLE: - e = (struct ia64_table_entry *) di->u.ti.table_data; - table_size = di->u.ti.table_len * sizeof (di->u.ti.table_data[0]); - segbase = di->u.ti.segbase; - if (table_size < sizeof (struct ia64_table_entry)) - return 0; - start_offset = e[0].start_offset; - end_offset = e[0].end_offset; - info_offset = e[0].info_offset; - break; - - case UNW_INFO_FORMAT_REMOTE_TABLE: - { - unw_accessors_t *a = unw_get_accessors_int (as); - unw_word_t e_addr = di->u.rti.table_data; - - table_size = di->u.rti.table_len * sizeof (unw_word_t); - segbase = di->u.rti.segbase; - if (table_size < sizeof (struct ia64_table_entry)) - return 0; - - if ( (ret = remote_read (e_addr, start_offset) < 0) - || (ret = remote_read (e_addr, end_offset) < 0) - || (ret = remote_read (e_addr, info_offset) < 0)) - return ret; - } - break; - } - - if (start_offset != end_offset) - /* dyn-list entry cover a zero-length "procedure" and should be - first entry (note: technically a binary could contain code - below the segment base, but this doesn't happen for normal - binaries and certainly doesn't happen when libunwind is a - separate shared object. For weird cases, the application may - have to provide its own (slower) version of this routine. */ - return 0; - - hdr_addr = info_offset + segbase; - info_addr = hdr_addr + 8; - - /* read the header word: */ - if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0) - return ret; - - if (IA64_UNW_VER (hdr) != 1 - || IA64_UNW_FLAG_EHANDLER (hdr) || IA64_UNW_FLAG_UHANDLER (hdr)) - /* dyn-list entry must be version 1 and doesn't have ehandler - or uhandler */ - return 0; - - if (IA64_UNW_LENGTH (hdr) != 1) - /* dyn-list entry must consist of a single word of NOP directives */ - return 0; - - if ( ((ret = read_mem (as, info_addr, &directives, arg)) < 0) - || ((ret = read_mem (as, info_addr + 0x08, &pers, arg)) < 0) - || ((ret = read_mem (as, info_addr + 0x10, &cookie, arg)) < 0) - || ((ret = read_mem (as, info_addr + 0x18, &off, arg)) < 0)) - return 0; - - if (directives != 0 || pers != 0 - || (!as->big_endian && cookie != 0x7473696c2d6e7964ULL) - || ( as->big_endian && cookie != 0x64796e2d6c697374ULL)) - return 0; - - /* OK, we ran the gauntlet and found it: */ - return off + gp; -} - -#endif /* !UNW_LOCAL_ONLY */ - -static inline const struct ia64_table_entry * -lookup (struct ia64_table_entry *table, size_t table_size, unw_word_t rel_ip) -{ - const struct ia64_table_entry *e = 0; - unsigned long lo, hi, mid; - - /* do a binary search for right entry: */ - for (lo = 0, hi = table_size / sizeof (struct ia64_table_entry); lo < hi;) - { - mid = (lo + hi) / 2; - e = table + mid; - if (rel_ip < e->start_offset) - hi = mid; - else if (rel_ip >= e->end_offset) - lo = mid + 1; - else - break; - } - if (rel_ip < e->start_offset || rel_ip >= e->end_offset) - return NULL; - return e; -} - -int -unw_search_ia64_unwind_table (unw_addr_space_t as, unw_word_t ip, - unw_dyn_info_t *di, unw_proc_info_t *pi, - int need_unwind_info, void *arg) -{ - unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp; - const struct ia64_table_entry *e = NULL; - unw_word_t handler_offset, segbase = 0; - int ret, is_local; -#ifndef UNW_LOCAL_ONLY - struct ia64_table_entry ent; -#endif - - assert ((di->format == UNW_INFO_FORMAT_TABLE - || di->format == UNW_INFO_FORMAT_REMOTE_TABLE) - && (ip >= di->start_ip && ip < di->end_ip)); - - pi->flags = 0; - pi->unwind_info = 0; - pi->handler = 0; - - if (likely (di->format == UNW_INFO_FORMAT_TABLE)) - { - segbase = di->u.ti.segbase; - e = lookup ((struct ia64_table_entry *) di->u.ti.table_data, - di->u.ti.table_len * sizeof (unw_word_t), - ip - segbase); - } -#ifndef UNW_LOCAL_ONLY - else - { - segbase = di->u.rti.segbase; - if ((ret = remote_lookup (as, di->u.rti.table_data, - di->u.rti.table_len * sizeof (unw_word_t), - ip - segbase, &ent, arg)) < 0) - return ret; - if (ret) - e = &ent; - } -#endif - if (!e) - { - /* IP is inside this table's range, but there is no explicit - unwind info => use default conventions (i.e., this is NOT an - error). */ - memset (pi, 0, sizeof (*pi)); - pi->start_ip = 0; - pi->end_ip = 0; - pi->gp = di->gp; - pi->lsda = 0; - return 0; - } - - pi->start_ip = e->start_offset + segbase; - pi->end_ip = e->end_offset + segbase; - - hdr_addr = e->info_offset + segbase; - info_addr = hdr_addr + 8; - - /* Read the header word. Note: the actual unwind-info is always - assumed to reside in memory, independent of whether di->format is - UNW_INFO_FORMAT_TABLE or UNW_INFO_FORMAT_REMOTE_TABLE. */ - - if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0) - return ret; - - if (IA64_UNW_VER (hdr) != 1) - { - Debug (1, "Unknown header version %ld (hdr word=0x%lx @ 0x%lx)\n", - IA64_UNW_VER (hdr), (unsigned long) hdr, - (unsigned long) hdr_addr); - return -UNW_EBADVERSION; - } - - info_end_addr = info_addr + 8 * IA64_UNW_LENGTH (hdr); - - is_local = is_local_addr_space (as); - - /* If we must have the unwind-info, return it. Also, if we are in - the local address-space, return the unwind-info because it's so - cheap to do so and it may come in handy later on. */ - if (need_unwind_info || is_local) - { - pi->unwind_info_size = 8 * IA64_UNW_LENGTH (hdr); - - if (is_local) - pi->unwind_info = (void *) (uintptr_t) info_addr; - else - { - /* Internalize unwind info. Note: since we're doing this - only for non-local address spaces, there is no - signal-safety issue and it is OK to use malloc()/free(). */ - pi->unwind_info = malloc (8 * IA64_UNW_LENGTH (hdr)); - if (!pi->unwind_info) - return -UNW_ENOMEM; - - wp = (unw_word_t *) pi->unwind_info; - for (addr = info_addr; addr < info_end_addr; addr += 8, ++wp) - { - if ((ret = read_mem (as, addr, wp, arg)) < 0) - { - free (pi->unwind_info); - return ret; - } - } - } - } - - if (IA64_UNW_FLAG_EHANDLER (hdr) || IA64_UNW_FLAG_UHANDLER (hdr)) - { - /* read the personality routine address (address is gp-relative): */ - if ((ret = read_mem (as, info_end_addr, &handler_offset, arg)) < 0) - return ret; - Debug (4, "handler ptr @ offset=%lx, gp=%lx\n", handler_offset, di->gp); - if ((read_mem (as, handler_offset + di->gp, &pi->handler, arg)) < 0) - return ret; - } - pi->lsda = info_end_addr + 8; - pi->gp = di->gp; - pi->format = di->format; - return 0; -} - -#ifndef UNW_REMOTE_ONLY - -# if defined(HAVE_DL_ITERATE_PHDR) -# include -# include - -# if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) \ - || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && !defined(DT_CONFIG)) -# error You need GLIBC 2.2.4 or later on IA-64 Linux -# endif - -# if defined(HAVE_GETUNWIND) - extern unsigned long getunwind (void *buf, size_t len); -# else /* HAVE_GETUNWIND */ -# include -# include -# ifndef __NR_getunwind -# define __NR_getunwind 1215 -# endif - -static unsigned long -getunwind (void *buf, size_t len) -{ - return syscall (SYS_getunwind, buf, len); -} - -# endif /* HAVE_GETUNWIND */ - -static unw_dyn_info_t kernel_table; - -static int -get_kernel_table (unw_dyn_info_t *di) -{ - struct ia64_table_entry *ktab, *etab; - size_t size; - - Debug (16, "getting kernel table"); - - size = getunwind (NULL, 0); - ktab = sos_alloc (size); - if (!ktab) - { - Dprintf (__FILE__".%s: failed to allocate %zu bytes", - __FUNCTION__, size); - return -UNW_ENOMEM; - } - getunwind (ktab, size); - - /* Determine length of kernel's unwind table & relocate its entries. */ - for (etab = ktab; etab->start_offset; ++etab) - etab->info_offset += (uint64_t) ktab; - - di->format = UNW_INFO_FORMAT_TABLE; - di->gp = 0; - di->start_ip = ktab[0].start_offset; - di->end_ip = etab[-1].end_offset; - di->u.ti.name_ptr = (unw_word_t) ""; - di->u.ti.segbase = 0; - di->u.ti.table_len = ((char *) etab - (char *) ktab) / sizeof (unw_word_t); - di->u.ti.table_data = (unw_word_t *) ktab; - - Debug (16, "found table `%s': [%lx-%lx) segbase=%lx len=%lu\n", - (char *) di->u.ti.name_ptr, di->start_ip, di->end_ip, - di->u.ti.segbase, di->u.ti.table_len); - return 0; -} - -# ifndef UNW_LOCAL_ONLY - -/* This is exported for the benefit of libunwind-ptrace.a. */ -int -_Uia64_get_kernel_table (unw_dyn_info_t *di) -{ - int ret; - - if (!kernel_table.u.ti.table_data) - if ((ret = get_kernel_table (&kernel_table)) < 0) - return ret; - - memcpy (di, &kernel_table, sizeof (*di)); - return 0; -} - -# endif /* !UNW_LOCAL_ONLY */ - -static inline unsigned long -current_gp (void) -{ -# if defined(__GNUC__) && !defined(__INTEL_COMPILER) - register unsigned long gp __asm__("gp"); - return gp; -# elif HAVE_IA64INTRIN_H - return __getReg (_IA64_REG_GP); -# else -# error Implement me. -# endif -} - -static int -callback (struct dl_phdr_info *info, size_t size, void *ptr) -{ - unw_dyn_info_t *di = ptr; - const Elf64_Phdr *phdr, *p_unwind, *p_dynamic, *p_text; - long n; - Elf64_Addr load_base, segbase = 0; - - /* Make sure struct dl_phdr_info is at least as big as we need. */ - if (size < offsetof (struct dl_phdr_info, dlpi_phnum) - + sizeof (info->dlpi_phnum)) - return -1; - - Debug (16, "checking `%s' (load_base=%lx)\n", - info->dlpi_name, info->dlpi_addr); - - phdr = info->dlpi_phdr; - load_base = info->dlpi_addr; - p_text = NULL; - p_unwind = NULL; - p_dynamic = NULL; - - /* See if PC falls into one of the loaded segments. Find the unwind - segment at the same time. */ - for (n = info->dlpi_phnum; --n >= 0; phdr++) - { - if (phdr->p_type == PT_LOAD) - { - Elf64_Addr vaddr = phdr->p_vaddr + load_base; - if (di->u.ti.segbase >= vaddr - && di->u.ti.segbase < vaddr + phdr->p_memsz) - p_text = phdr; - } - else if (phdr->p_type == PT_IA_64_UNWIND) - p_unwind = phdr; - else if (phdr->p_type == PT_DYNAMIC) - p_dynamic = phdr; - } - if (!p_text || !p_unwind) - return 0; - - if (likely (p_unwind->p_vaddr >= p_text->p_vaddr - && p_unwind->p_vaddr < p_text->p_vaddr + p_text->p_memsz)) - /* normal case: unwind table is inside text segment */ - segbase = p_text->p_vaddr + load_base; - else - { - /* Special case: unwind table is in some other segment; this - happens for the Linux kernel's gate DSO, for example. */ - phdr = info->dlpi_phdr; - for (n = info->dlpi_phnum; --n >= 0; phdr++) - { - if (phdr->p_type == PT_LOAD && p_unwind->p_vaddr >= phdr->p_vaddr - && p_unwind->p_vaddr < phdr->p_vaddr + phdr->p_memsz) - { - segbase = phdr->p_vaddr + load_base; - break; - } - } - } - - if (p_dynamic) - { - /* For dynamicly linked executables and shared libraries, - DT_PLTGOT is the gp value for that object. */ - Elf64_Dyn *dyn = (Elf64_Dyn *)(p_dynamic->p_vaddr + load_base); - for (; dyn->d_tag != DT_NULL; ++dyn) - if (dyn->d_tag == DT_PLTGOT) - { - /* On IA-64, _DYNAMIC is writable and GLIBC has relocated it. */ - di->gp = dyn->d_un.d_ptr; - break; - } - } - else - /* Otherwise this is a static executable with no _DYNAMIC. - The gp is constant program-wide. */ - di->gp = current_gp(); - di->format = UNW_INFO_FORMAT_TABLE; - di->start_ip = p_text->p_vaddr + load_base; - di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz; - di->u.ti.name_ptr = (unw_word_t) info->dlpi_name; - di->u.ti.table_data = (void *) (p_unwind->p_vaddr + load_base); - di->u.ti.table_len = p_unwind->p_memsz / sizeof (unw_word_t); - di->u.ti.segbase = segbase; - - Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, " - "table_data=%p\n", (char *) di->u.ti.name_ptr, di->u.ti.segbase, - di->u.ti.table_len, di->gp, di->u.ti.table_data); - return 1; -} - -# ifdef HAVE_DL_PHDR_REMOVALS_COUNTER - -static inline int -validate_cache (unw_addr_space_t as) -{ - /* Note: we don't need to serialize here with respect to - dl_iterate_phdr() because if somebody were to remove an object - that is required to complete the unwind on whose behalf we're - validating the cache here, we'd be hosed anyhow. What we're - guarding against here is the case where library FOO gets mapped, - unwind info for FOO gets cached, FOO gets unmapped, BAR gets - mapped in the place where FOO was and then we unwind across a - function in FOO. Since no thread can execute in BAR before FOO - has been removed, we are guaranteed that - dl_phdr_removals_counter() would have been incremented before we - get here. */ - unsigned long long removals = dl_phdr_removals_counter (); - - if (removals == as->shared_object_removals) - return 1; - - as->shared_object_removals = removals; - unw_flush_cache (as, 0, 0); - return -1; -} - -# else /* !HAVE_DL_PHDR_REMOVALS_COUNTER */ - -/* Check whether any phdrs have been removed since we last flushed the - cache. If so we flush the cache and return -1, if not, we do - nothing and return 1. */ - -static int -check_callback (struct dl_phdr_info *info, size_t size, void *ptr) -{ -# ifdef HAVE_STRUCT_DL_PHDR_INFO_DLPI_SUBS - unw_addr_space_t as = ptr; - - if (size < - offsetof (struct dl_phdr_info, dlpi_subs) + sizeof (info->dlpi_subs)) - /* It would be safer to flush the cache here, but that would - disable caching for older libc's which would be incompatible - with the behavior of older versions of libunwind so we return 1 - instead and hope nobody runs into stale cache info... */ - return 1; - - if (info->dlpi_subs == as->shared_object_removals) - return 1; - - as->shared_object_removals = info->dlpi_subs; - unw_flush_cache (as, 0, 0); - return -1; /* indicate that there were removals */ -# else - return 1; -# endif -} - -static inline int -validate_cache (unw_addr_space_t as) -{ - intrmask_t saved_mask; - int ret; - - SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); - ret = dl_iterate_phdr (check_callback, as); - SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); - return ret; -} - -# endif /* HAVE_DL_PHDR_REMOVALS_COUNTER */ - -# elif defined(HAVE_DLMODINFO) - /* Support for HP-UX-style dlmodinfo() */ -# include - -static inline int -validate_cache (unw_addr_space_t as) -{ - return 1; -} - -# endif /* !HAVE_DLMODINFO */ - -HIDDEN int -tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, int need_unwind_info, void *arg) -{ -# if defined(HAVE_DL_ITERATE_PHDR) - unw_dyn_info_t di, *dip = &di; - intrmask_t saved_mask; - int ret; - - di.u.ti.segbase = ip; /* this is cheap... */ - - SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); - ret = dl_iterate_phdr (callback, &di); - SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); - - if (ret <= 0) - { - if (!kernel_table.u.ti.table_data) - { - if ((ret = get_kernel_table (&kernel_table)) < 0) - return ret; - } - if (ip < kernel_table.start_ip || ip >= kernel_table.end_ip) - return -UNW_ENOINFO; - dip = &kernel_table; - } -# elif defined(HAVE_DLMODINFO) -# define UNWIND_TBL_32BIT 0x8000000000000000 - struct load_module_desc lmd; - unw_dyn_info_t di, *dip = &di; - struct unwind_header - { - uint64_t header_version; - uint64_t start_offset; - uint64_t end_offset; - } - *uhdr; - - if (!dlmodinfo (ip, &lmd, sizeof (lmd), NULL, 0, 0)) - return -UNW_ENOINFO; - - di.format = UNW_INFO_FORMAT_TABLE; - di.start_ip = lmd.text_base; - di.end_ip = lmd.text_base + lmd.text_size; - di.gp = lmd.linkage_ptr; - di.u.ti.name_ptr = 0; /* no obvious table-name available */ - di.u.ti.segbase = lmd.text_base; - - uhdr = (struct unwind_header *) lmd.unwind_base; - - if ((uhdr->header_version & ~UNWIND_TBL_32BIT) != 1 - && (uhdr->header_version & ~UNWIND_TBL_32BIT) != 2) - { - Debug (1, "encountered unknown unwind header version %ld\n", - (long) (uhdr->header_version & ~UNWIND_TBL_32BIT)); - return -UNW_EBADVERSION; - } - if (uhdr->header_version & UNWIND_TBL_32BIT) - { - Debug (1, "32-bit unwind tables are not supported yet\n"); - return -UNW_EINVAL; - } - - di.u.ti.table_data = (unw_word_t *) (di.u.ti.segbase + uhdr->start_offset); - di.u.ti.table_len = ((uhdr->end_offset - uhdr->start_offset) - / sizeof (unw_word_t)); - - Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, " - "table_data=%p\n", (char *) di.u.ti.name_ptr, di.u.ti.segbase, - di.u.ti.table_len, di.gp, di.u.ti.table_data); -# endif - - /* now search the table: */ - return tdep_search_unwind_table (as, ip, dip, pi, need_unwind_info, arg); -} - -/* Returns 1 if the cache is up-to-date or -1 if the cache contained - stale data and had to be flushed. */ - -HIDDEN int -ia64_local_validate_cache (unw_addr_space_t as, void *arg) -{ - return validate_cache (as); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lfind_unwind_table.c deleted file mode 100644 index 68e269f1d7f95f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lfind_unwind_table.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gfind_unwind_table.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lglobal.c deleted file mode 100644 index 6d7b489e14bd9f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lglobal.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Linit.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Linstall_cursor.S b/src/coreclr/src/pal/src/libunwind/src/ia64/Linstall_cursor.S deleted file mode 100644 index 8c7233972521c8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Linstall_cursor.S +++ /dev/null @@ -1,6 +0,0 @@ -#define UNW_LOCAL_ONLY -#include "Ginstall_cursor.S" -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9fa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lparser.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lparser.c deleted file mode 100644 index f23aaf48e9c27d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lparser.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gparser.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lrbs.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lrbs.c deleted file mode 100644 index a91b5f2979a93a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lrbs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Grbs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lscript.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lscript.c deleted file mode 100644 index 57b926bf80124b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lscript.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gscript.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ltables.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ltables.c deleted file mode 100644 index 876b0aac03dd61..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Ltables.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gtables.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/NOTES b/src/coreclr/src/pal/src/libunwind/src/ia64/NOTES deleted file mode 100644 index a5805e8345672b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/NOTES +++ /dev/null @@ -1,65 +0,0 @@ -- the frame state consists of the following: - - - ip current instruction pointer - - sp current stack pointer value - - bsp current backing store pointer - - cfm current frame mask - - these are derived from the next younger (more deeply nested) frame - as follows: - - - ip == saved return-link (may be b0 or an alternate branch-reg) - - sp == if younger frame has a fixed-sized frame, sp + size-of-frame, - else saved sp - - cfm == saved ar.pfs - - bsp == if ar.bsp has been saved, saved ar.bsp, otherwise, - ar.bsp \ominus saved ar.pfs.pfm.sol - -The unwind cursor should represent the machine state as it existed at -the address contained in register ip. This state consists of the -*current* frame state and the save locations in the next younger -frame. - -An unwind script current takes the old save locations and updates them -for the next older frame. With the new setup, we need to update the -frame state first, without updating the other save locations. For this -to work, we need the following info: - - - save location of return-link - - save location of ar.pfs - - save location of bsp (if it has been saved) - - size of stack frame (fixed case) or save location of sp - - -setup: - - func: ... - ... - ... - br.call foo <-- call site - ... <-- ip - ... - -initial state: - - The unwind cursor represents the (preserved) machine state - as it existed at "ip". - - Evaluating the unwind descriptors for "ip" yields the following - info: - - - frame size at call site (or previous sp) - - what registers where saved where by func before - the call site was reached - - - Note that there is some procedure info that needs to be obtained - for the new "ip" which is contained in the unwind descriptors. - Specifically, the following is needed: - - - procedure's start address - - personality address - - pointer to language-specific data area - - This info is stored in a separate proc_info structure and needs - to be obtained right after running the unwind script for func. diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/dyn_info_list.S b/src/coreclr/src/pal/src/libunwind/src/ia64/dyn_info_list.S deleted file mode 100644 index 31265f66a064d7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/dyn_info_list.S +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef UNW_REMOTE_ONLY - -/* - * Create a special unwind-table entry which makes it easy for an - * unwinder to locate the dynamic registration list. The special - * entry covers address range [0-0) and is therefore guaranteed to be - * the first in the unwind-table. - */ - .global _U_dyn_info_list - .hidden _U_dyn_info_list - - .section .IA_64.unwind_info,"a","progbits" -.info: data8 (1<<48) | 1 /* v1, length==1 (8-byte word) */ - data8 0 /* 8 empty .prologue directives (nops) */ - data8 0 /* personality routine (ignored) */ - string "dyn-list" /* lsda */ - data8 @gprel(_U_dyn_info_list) - - .section .IA_64.unwind, "a", "progbits" - data8 0, 0, @segrel(.info) - -#endif -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/ia64/getcontext.S deleted file mode 100644 index d8da732acc8ac9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/getcontext.S +++ /dev/null @@ -1,177 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "ucontext_i.h" - -#define GR(n) (SC_GR + (n)*8) -#define BR(n) (SC_BR + (n)*8) -#define FR(n) (SC_FR + (n)*16) - -/* This should be compatible to the libc's getcontext(), except that - the sc->sc_mask field is always cleared and that the name is - prefixed with _Uia64_ so we don't step on the application's - name-space. */ - - .align 32 - .protected _Uia64_getcontext - .global _Uia64_getcontext - .proc _Uia64_getcontext -_Uia64_getcontext: - .prologue - alloc rPFS = ar.pfs, 1, 0, 0, 0 // M2 - mov rPR = pr // I0, 2 cycles - add r2 = GR(1), in0 // I1 - ;; - - .save ar.unat, rUNAT - mov.m rUNAT = ar.unat // M2, 5 cycles - .body - st8.spill [r2] = r1, (SC_FLAGS - GR(1)) // M3 - dep.z rFLAGS = -1, IA64_SC_FLAG_SYNCHRONOUS_BIT, 1 // I0, 1 cycle - ;; - - mov.m rRSC = ar.rsc // M2, 12 cyc. - st8 [r2] = rFLAGS, (SC_PR - SC_FLAGS) // M3 - add r3 = FR(2), in0 - ;; - - mov.m rBSP = ar.bsp // M2, 12 cyc. - st8 [r2] = rPR, (GR(12) - SC_PR) // M3 - add r8 = FR(16), in0 - ;; - - mov.m rFPSR = ar.fpsr // M2, 12 cyc. - st8.spill [r2] = r12, (GR(4) - GR(12)) // M3 - add r9 = FR(24), in0 - ;; - - stf.spill [r3] = f2 // M2 - stf.spill [r8] = f16 // M3 - add r3 = GR(7), in0 - ;; - - flushrs // M0 - stf.spill [r9] = f24, (FR(31) - FR(24)) // M2 - mov rB0 = b0 // I0, 2 cycles - ;; - - stf.spill [r9] = f31 // M2 - st8.spill [r2] = r4, (GR(5) - GR(4)) // M3, bank 1 - mov rB1 = b1 // I0, 2 cycles - ;; - -.mem.offset 0,0; st8.spill [r2] = r5, (GR(6) - GR(5)) // M4, bank 0 -.mem.offset 8,0; st8.spill [r3] = r7, (BR(0) - GR(7)) // M3, bank 0 - mov rB2 = b2 // I0, 2 cycles - ;; - - st8.spill [r2] = r6, (BR(1) - GR(6)) // M2, bank 1 - st8 [r3] = rB0, (BR(4) - BR(0)) // M3, bank 1 - mov rB4 = b4 // I0, 2 cycles - ;; - - mov.m rNAT = ar.unat // M2, 5 cycles - st8 [r2] = rB1, (BR(2) - BR(1)) // M3, bank 0 - mov rB3 = b3 - ;; - - st8 [r2] = rB2, (BR(3) - BR(2)) // M2, bank 1 - st8 [r3] = rB4, (SC_LC - BR(4)) // M3, bank 1 - mov rB5 = b5 // I0, 2 cycles - ;; - - and rTMP = ~0x3, rRSC // M0 - add rPOS = GR(0), in0 // rPOS <- &sc_gr[0] // M1 - mov.i rLC = ar.lc // I0, 2 cycles - ;; - - mov.m ar.rsc = rTMP // put RSE into lazy mode // M2, ? cycles - st8 [r2] = rB3, (BR(5) - BR(3)) // M3, bank 0 - extr.u rPOS = rPOS, 3, 6 // get NaT bitnr for r0 // I0 - ;; - - mov.m rRNAT = ar.rnat // M2, 5 cycles - st8 [r2] = rB5, (SC_PFS - BR(5)) // M3, bank 0 - sub rCPOS = 64, rPOS // I0 - ;; - - st8 [r2] = rPFS, (SC_UNAT - SC_PFS) // M2 - st8 [r3] = rLC, (SC_BSP - SC_LC) // M3 - shr.u rTMP = rNAT, rPOS // I0, 3 cycles - ;; - - st8 [r2] = rUNAT, (SC_FPSR - SC_UNAT) // M2 - st8 [r3] = rBSP // M3 - add r8 = FR(3), in0 - ;; - - st8 [r2] = rFPSR, (SC_RNAT - SC_FPSR) // M2 - stf.spill [r8] = f3, (FR(4) - FR(3)) // M3 - add r9 = FR(5), in0 - ;; - - stf.spill [r8] = f4, (FR(17) - FR(4)) // M2 - stf.spill [r9] = f5, (FR(19) - FR(5)) // M3 - shl rNAT = rNAT, rCPOS // I0, 3 cycles - ;; - - st8 [r2] = rRNAT, (SC_NAT - SC_RNAT) // M2 - stf.spill [r8] = f17, (FR(18) - FR(17)) // M3 - nop.i 0 - ;; - - stf.spill [r8] = f18, (FR(20) - FR(18)) // M2 - stf.spill [r9] = f19, (FR(21) - FR(19)) // M3 - nop.i 0 - ;; - - stf.spill [r8] = f20, (FR(22) - FR(20)) // M2 - stf.spill [r9] = f21, (FR(23) - FR(21)) // M3 - or rNAT = rNAT, rTMP // I0 - ;; - - st8 [r2] = rNAT // M2 - stf.spill [r8] = f22, (FR(25) - FR(22)) // M3 - ;; - stf.spill [r9] = f23, (FR(26) - FR(23)) // M2 - stf.spill [r8] = f25, (FR(27) - FR(25)) // M3 - ;; - stf.spill [r9] = f26, (FR(28) - FR(26)) // M2 - stf.spill [r8] = f27, (FR(29) - FR(27)) // M3 - ;; - mov.m ar.rsc = rRSC // restore RSE mode // M2 - stf.spill [r9] = f28, (FR(30) - FR(28)) // M3 - ;; - mov.m ar.unat = rUNAT // restore caller's UNaT // M2 - stf.spill [r8] = f29 // M3 - ;; - stf.spill [r9] = f30 // M2 - mov r8 = 0 - br.ret.sptk.many rp - .endp _Uia64_getcontext -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/init.h b/src/coreclr/src/pal/src/libunwind/src/ia64/init.h deleted file mode 100644 index 6628a1d8882481..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/init.h +++ /dev/null @@ -1,132 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static ALWAYS_INLINE int -common_init (struct cursor *c, unw_word_t sp, unw_word_t bsp) -{ - unw_word_t bspstore, rbs_base; - int ret; - - if (c->as->caching_policy != UNW_CACHE_NONE) - /* ensure cache doesn't have any stale contents: */ - ia64_validate_cache (c->as, c->as_arg); - - c->cfm_loc = IA64_REG_LOC (c, UNW_IA64_CFM); - c->loc[IA64_REG_BSP] = IA64_NULL_LOC; - c->loc[IA64_REG_BSPSTORE] = IA64_REG_LOC (c, UNW_IA64_AR_BSPSTORE); - c->loc[IA64_REG_PFS] = IA64_REG_LOC (c, UNW_IA64_AR_PFS); - c->loc[IA64_REG_RNAT] = IA64_REG_LOC (c, UNW_IA64_AR_RNAT); - c->loc[IA64_REG_IP] = IA64_REG_LOC (c, UNW_IA64_IP); - c->loc[IA64_REG_PRI_UNAT_MEM] = IA64_NULL_LOC; /* no primary UNaT location */ - c->loc[IA64_REG_UNAT] = IA64_REG_LOC (c, UNW_IA64_AR_UNAT); - c->loc[IA64_REG_PR] = IA64_REG_LOC (c, UNW_IA64_PR); - c->loc[IA64_REG_LC] = IA64_REG_LOC (c, UNW_IA64_AR_LC); - c->loc[IA64_REG_FPSR] = IA64_REG_LOC (c, UNW_IA64_AR_FPSR); - - c->loc[IA64_REG_R4] = IA64_REG_LOC (c, UNW_IA64_GR + 4); - c->loc[IA64_REG_R5] = IA64_REG_LOC (c, UNW_IA64_GR + 5); - c->loc[IA64_REG_R6] = IA64_REG_LOC (c, UNW_IA64_GR + 6); - c->loc[IA64_REG_R7] = IA64_REG_LOC (c, UNW_IA64_GR + 7); - - c->loc[IA64_REG_NAT4] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 4, &c->nat_bitnr[0]); - c->loc[IA64_REG_NAT5] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 5, &c->nat_bitnr[1]); - c->loc[IA64_REG_NAT6] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 6, &c->nat_bitnr[2]); - c->loc[IA64_REG_NAT7] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 7, &c->nat_bitnr[3]); - - c->loc[IA64_REG_B1] = IA64_REG_LOC (c, UNW_IA64_BR + 1); - c->loc[IA64_REG_B2] = IA64_REG_LOC (c, UNW_IA64_BR + 2); - c->loc[IA64_REG_B3] = IA64_REG_LOC (c, UNW_IA64_BR + 3); - c->loc[IA64_REG_B4] = IA64_REG_LOC (c, UNW_IA64_BR + 4); - c->loc[IA64_REG_B5] = IA64_REG_LOC (c, UNW_IA64_BR + 5); - - c->loc[IA64_REG_F2] = IA64_FPREG_LOC (c, UNW_IA64_FR + 2); - c->loc[IA64_REG_F3] = IA64_FPREG_LOC (c, UNW_IA64_FR + 3); - c->loc[IA64_REG_F4] = IA64_FPREG_LOC (c, UNW_IA64_FR + 4); - c->loc[IA64_REG_F5] = IA64_FPREG_LOC (c, UNW_IA64_FR + 5); - c->loc[IA64_REG_F16] = IA64_FPREG_LOC (c, UNW_IA64_FR + 16); - c->loc[IA64_REG_F17] = IA64_FPREG_LOC (c, UNW_IA64_FR + 17); - c->loc[IA64_REG_F18] = IA64_FPREG_LOC (c, UNW_IA64_FR + 18); - c->loc[IA64_REG_F19] = IA64_FPREG_LOC (c, UNW_IA64_FR + 19); - c->loc[IA64_REG_F20] = IA64_FPREG_LOC (c, UNW_IA64_FR + 20); - c->loc[IA64_REG_F21] = IA64_FPREG_LOC (c, UNW_IA64_FR + 21); - c->loc[IA64_REG_F22] = IA64_FPREG_LOC (c, UNW_IA64_FR + 22); - c->loc[IA64_REG_F23] = IA64_FPREG_LOC (c, UNW_IA64_FR + 23); - c->loc[IA64_REG_F24] = IA64_FPREG_LOC (c, UNW_IA64_FR + 24); - c->loc[IA64_REG_F25] = IA64_FPREG_LOC (c, UNW_IA64_FR + 25); - c->loc[IA64_REG_F26] = IA64_FPREG_LOC (c, UNW_IA64_FR + 26); - c->loc[IA64_REG_F27] = IA64_FPREG_LOC (c, UNW_IA64_FR + 27); - c->loc[IA64_REG_F28] = IA64_FPREG_LOC (c, UNW_IA64_FR + 28); - c->loc[IA64_REG_F29] = IA64_FPREG_LOC (c, UNW_IA64_FR + 29); - c->loc[IA64_REG_F30] = IA64_FPREG_LOC (c, UNW_IA64_FR + 30); - c->loc[IA64_REG_F31] = IA64_FPREG_LOC (c, UNW_IA64_FR + 31); - - ret = ia64_get (c, c->loc[IA64_REG_IP], &c->ip); - if (ret < 0) - return ret; - - ret = ia64_get (c, c->cfm_loc, &c->cfm); - if (ret < 0) - return ret; - - ret = ia64_get (c, c->loc[IA64_REG_PR], &c->pr); - if (ret < 0) - return ret; - - c->sp = c->psp = sp; - c->bsp = bsp; - - ret = ia64_get (c, c->loc[IA64_REG_BSPSTORE], &bspstore); - if (ret < 0) - return ret; - - c->rbs_curr = c->rbs_left_edge = 0; - - /* Try to find a base of the register backing-store. We may default - to a reasonable value (e.g., half the address-space down from - bspstore). If the BSPSTORE looks corrupt, we fail. */ - if ((ret = rbs_get_base (c, bspstore, &rbs_base)) < 0) - return ret; - - c->rbs_area[0].end = bspstore; - c->rbs_area[0].size = bspstore - rbs_base; - c->rbs_area[0].rnat_loc = IA64_REG_LOC (c, UNW_IA64_AR_RNAT); - Debug (10, "initial rbs-area: [0x%llx-0x%llx), rnat@%s\n", - (long long) rbs_base, (long long) c->rbs_area[0].end, - ia64_strloc (c->rbs_area[0].rnat_loc)); - - c->pi.flags = 0; - - c->sigcontext_addr = 0; - c->abi_marker = 0; - c->last_abi_marker = 0; - - c->hint = 0; - c->prev_script = 0; - c->eh_valid_mask = 0; - c->pi_valid = 0; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/longjmp.S b/src/coreclr/src/pal/src/libunwind/src/ia64/longjmp.S deleted file mode 100644 index 2a2f286594bb26..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/longjmp.S +++ /dev/null @@ -1,42 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - - .global _UI_longjmp_cont - - .align 32 - .proc longjmp_continuation -longjmp_continuation: -_UI_longjmp_cont: // non-function label for {sig,}longjmp.c - .prologue - .save rp, r15 - .body - mov rp = r15 - mov r8 = r16 - br.sptk.many rp - .endp longjmp_continuation -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/mk_cursor_i b/src/coreclr/src/pal/src/libunwind/src/ia64/mk_cursor_i deleted file mode 100755 index 9211f91bbbb55c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/mk_cursor_i +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -test -z "$1" && exit 1 -echo "/* GENERATED */" -echo "#ifndef cursor_i_h" -echo "#define cursor_i_h" -sed -ne 's/^->"\(\S*\)" \(\d*\)/#define \1 \2/p' < $1 || exit $? -echo "#endif" diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/offsets.h b/src/coreclr/src/pal/src/libunwind/src/ia64/offsets.h deleted file mode 100644 index 5ab7f8b31e61f9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/offsets.h +++ /dev/null @@ -1,137 +0,0 @@ -/* Linux-specific definitions: */ - -/* Define various structure offsets to simplify cross-compilation. */ - -/* The first three 64-bit words in a signal frame contain the signal - number, siginfo pointer, and sigcontext pointer passed to the - signal handler. We use this to locate the sigcontext pointer. */ - -#define LINUX_SIGFRAME_ARG2_OFF 0x10 - -#define LINUX_SC_FLAGS_OFF 0x000 -#define LINUX_SC_NAT_OFF 0x008 -#define LINUX_SC_STACK_OFF 0x010 -#define LINUX_SC_IP_OFF 0x028 -#define LINUX_SC_CFM_OFF 0x030 -#define LINUX_SC_UM_OFF 0x038 -#define LINUX_SC_AR_RSC_OFF 0x040 -#define LINUX_SC_AR_BSP_OFF 0x048 -#define LINUX_SC_AR_RNAT_OFF 0x050 -#define LINUX_SC_AR_CCV 0x058 -#define LINUX_SC_AR_UNAT_OFF 0x060 -#define LINUX_SC_AR_FPSR_OFF 0x068 -#define LINUX_SC_AR_PFS_OFF 0x070 -#define LINUX_SC_AR_LC_OFF 0x078 -#define LINUX_SC_PR_OFF 0x080 -#define LINUX_SC_BR_OFF 0x088 -#define LINUX_SC_GR_OFF 0x0c8 -#define LINUX_SC_FR_OFF 0x1d0 -#define LINUX_SC_RBS_BASE_OFF 0x9d0 -#define LINUX_SC_LOADRS_OFF 0x9d8 -#define LINUX_SC_AR_CSD_OFF 0x9e0 -#define LINUX_SC_AR_SSD_OFF 0x9e8 -#define LINUX_SC_MASK 0xa50 - -/* Layout of old Linux kernel interrupt frame (struct pt_regs). */ - -#define LINUX_OLD_PT_IPSR_OFF 0x000 -#define LINUX_OLD_PT_IIP_OFF 0x008 -#define LINUX_OLD_PT_IFS_OFF 0x010 -#define LINUX_OLD_PT_UNAT_OFF 0x018 -#define LINUX_OLD_PT_PFS_OFF 0x020 -#define LINUX_OLD_PT_RSC_OFF 0x028 -#define LINUX_OLD_PT_RNAT_OFF 0x030 -#define LINUX_OLD_PT_BSPSTORE_OFF 0x038 -#define LINUX_OLD_PT_PR_OFF 0x040 -#define LINUX_OLD_PT_B6_OFF 0x048 -#define LINUX_OLD_PT_LOADRS_OFF 0x050 -#define LINUX_OLD_PT_R1_OFF 0x058 -#define LINUX_OLD_PT_R2_OFF 0x060 -#define LINUX_OLD_PT_R3_OFF 0x068 -#define LINUX_OLD_PT_R12_OFF 0x070 -#define LINUX_OLD_PT_R13_OFF 0x078 -#define LINUX_OLD_PT_R14_OFF 0x080 -#define LINUX_OLD_PT_R15_OFF 0x088 -#define LINUX_OLD_PT_R8_OFF 0x090 -#define LINUX_OLD_PT_R9_OFF 0x098 -#define LINUX_OLD_PT_R10_OFF 0x0a0 -#define LINUX_OLD_PT_R11_OFF 0x0a8 -#define LINUX_OLD_PT_R16_OFF 0x0b0 -#define LINUX_OLD_PT_R17_OFF 0x0b8 -#define LINUX_OLD_PT_R18_OFF 0x0c0 -#define LINUX_OLD_PT_R19_OFF 0x0c8 -#define LINUX_OLD_PT_R20_OFF 0x0d0 -#define LINUX_OLD_PT_R21_OFF 0x0d8 -#define LINUX_OLD_PT_R22_OFF 0x0e0 -#define LINUX_OLD_PT_R23_OFF 0x0e8 -#define LINUX_OLD_PT_R24_OFF 0x0f0 -#define LINUX_OLD_PT_R25_OFF 0x0f8 -#define LINUX_OLD_PT_R26_OFF 0x100 -#define LINUX_OLD_PT_R27_OFF 0x108 -#define LINUX_OLD_PT_R28_OFF 0x110 -#define LINUX_OLD_PT_R29_OFF 0x118 -#define LINUX_OLD_PT_R30_OFF 0x120 -#define LINUX_OLD_PT_R31_OFF 0x128 -#define LINUX_OLD_PT_CCV_OFF 0x130 -#define LINUX_OLD_PT_FPSR_OFF 0x138 -#define LINUX_OLD_PT_B0_OFF 0x140 -#define LINUX_OLD_PT_B7_OFF 0x148 -#define LINUX_OLD_PT_F6_OFF 0x150 -#define LINUX_OLD_PT_F7_OFF 0x160 -#define LINUX_OLD_PT_F8_OFF 0x170 -#define LINUX_OLD_PT_F9_OFF 0x180 - -/* Layout of new Linux kernel interrupt frame (struct pt_regs). */ - -#define LINUX_PT_B6_OFF 0 -#define LINUX_PT_B7_OFF 8 -#define LINUX_PT_CSD_OFF 16 -#define LINUX_PT_SSD_OFF 24 -#define LINUX_PT_R8_OFF 32 -#define LINUX_PT_R9_OFF 40 -#define LINUX_PT_R10_OFF 48 -#define LINUX_PT_R11_OFF 56 -#define LINUX_PT_IPSR_OFF 64 -#define LINUX_PT_IIP_OFF 72 -#define LINUX_PT_IFS_OFF 80 -#define LINUX_PT_UNAT_OFF 88 -#define LINUX_PT_PFS_OFF 96 -#define LINUX_PT_RSC_OFF 104 -#define LINUX_PT_RNAT_OFF 112 -#define LINUX_PT_BSPSTORE_OFF 120 -#define LINUX_PT_PR_OFF 128 -#define LINUX_PT_B0_OFF 136 -#define LINUX_PT_LOADRS_OFF 144 -#define LINUX_PT_R1_OFF 152 -#define LINUX_PT_R12_OFF 160 -#define LINUX_PT_R13_OFF 168 -#define LINUX_PT_FPSR_OFF 176 -#define LINUX_PT_R15_OFF 184 -#define LINUX_PT_R14_OFF 192 -#define LINUX_PT_R2_OFF 200 -#define LINUX_PT_R3_OFF 208 -#define LINUX_PT_R16_OFF 216 -#define LINUX_PT_R17_OFF 224 -#define LINUX_PT_R18_OFF 232 -#define LINUX_PT_R19_OFF 240 -#define LINUX_PT_R20_OFF 248 -#define LINUX_PT_R21_OFF 256 -#define LINUX_PT_R22_OFF 264 -#define LINUX_PT_R23_OFF 272 -#define LINUX_PT_R24_OFF 280 -#define LINUX_PT_R25_OFF 288 -#define LINUX_PT_R26_OFF 296 -#define LINUX_PT_R27_OFF 304 -#define LINUX_PT_R28_OFF 312 -#define LINUX_PT_R29_OFF 320 -#define LINUX_PT_R30_OFF 328 -#define LINUX_PT_R31_OFF 336 -#define LINUX_PT_CCV_OFF 344 -#define LINUX_PT_F6_OFF 352 -#define LINUX_PT_F7_OFF 368 -#define LINUX_PT_F8_OFF 384 -#define LINUX_PT_F9_OFF 400 -#define LINUX_PT_F10_OFF 416 -#define LINUX_PT_F11_OFF 432 - -#define LINUX_PT_P_NONSYS 5 /* must match pNonSys in entry.h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/regname.c b/src/coreclr/src/pal/src/libunwind/src/ia64/regname.c deleted file mode 100644 index 3636df87de5d9a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/regname.c +++ /dev/null @@ -1,189 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* Logically, we like to think of the stack as a contiguous region of -memory. Unfortunately, this logical view doesn't work for the -register backing store, because the RSE is an asynchronous engine and -because UNIX/Linux allow for stack-switching via sigaltstack(2). -Specifically, this means that any given stacked register may or may -not be backed up by memory in the current stack. If not, then the -backing memory may be found in any of the "more inner" (younger) -stacks. The routines in this file help manage the discontiguous -nature of the register backing store. The routines are completely -independent of UNIX/Linux, but each stack frame that switches the -backing store is expected to reserve 4 words for use by libunwind. For -example, in the Linux sigcontext, sc_fr[0] and sc_fr[1] serve this -purpose. */ - -#include "libunwind_i.h" - -/* Maintain the register names as a single string to keep the number - of dynamic relocations in the shared object to a minimum. */ - -#define regname_len 9 -#define regname_str \ - "r0\0\0\0\0\0\0\0r1\0\0\0\0\0\0\0r2\0\0\0\0\0\0\0r3\0\0\0\0\0\0\0" \ - "r4\0\0\0\0\0\0\0r5\0\0\0\0\0\0\0r6\0\0\0\0\0\0\0r7\0\0\0\0\0\0\0" \ - "r8\0\0\0\0\0\0\0r9\0\0\0\0\0\0\0r10\0\0\0\0\0\0r11\0\0\0\0\0\0" \ - "r12\0\0\0\0\0\0r13\0\0\0\0\0\0r14\0\0\0\0\0\0r15\0\0\0\0\0\0" \ - "r16\0\0\0\0\0\0r17\0\0\0\0\0\0r18\0\0\0\0\0\0r19\0\0\0\0\0\0" \ - "r20\0\0\0\0\0\0r21\0\0\0\0\0\0r22\0\0\0\0\0\0r23\0\0\0\0\0\0" \ - "r24\0\0\0\0\0\0r25\0\0\0\0\0\0r26\0\0\0\0\0\0r27\0\0\0\0\0\0" \ - "r28\0\0\0\0\0\0r29\0\0\0\0\0\0r30\0\0\0\0\0\0r31\0\0\0\0\0\0" \ - "r32\0\0\0\0\0\0r33\0\0\0\0\0\0r34\0\0\0\0\0\0r35\0\0\0\0\0\0" \ - "r36\0\0\0\0\0\0r37\0\0\0\0\0\0r38\0\0\0\0\0\0r39\0\0\0\0\0\0" \ - "r40\0\0\0\0\0\0r41\0\0\0\0\0\0r42\0\0\0\0\0\0r43\0\0\0\0\0\0" \ - "r44\0\0\0\0\0\0r45\0\0\0\0\0\0r46\0\0\0\0\0\0r47\0\0\0\0\0\0" \ - "r48\0\0\0\0\0\0r49\0\0\0\0\0\0r50\0\0\0\0\0\0r51\0\0\0\0\0\0" \ - "r52\0\0\0\0\0\0r53\0\0\0\0\0\0r54\0\0\0\0\0\0r55\0\0\0\0\0\0" \ - "r56\0\0\0\0\0\0r57\0\0\0\0\0\0r58\0\0\0\0\0\0r59\0\0\0\0\0\0" \ - "r60\0\0\0\0\0\0r61\0\0\0\0\0\0r62\0\0\0\0\0\0r63\0\0\0\0\0\0" \ - "r64\0\0\0\0\0\0r65\0\0\0\0\0\0r66\0\0\0\0\0\0r67\0\0\0\0\0\0" \ - "r68\0\0\0\0\0\0r69\0\0\0\0\0\0r70\0\0\0\0\0\0r71\0\0\0\0\0\0" \ - "r72\0\0\0\0\0\0r73\0\0\0\0\0\0r74\0\0\0\0\0\0r75\0\0\0\0\0\0" \ - "r76\0\0\0\0\0\0r77\0\0\0\0\0\0r78\0\0\0\0\0\0r79\0\0\0\0\0\0" \ - "r80\0\0\0\0\0\0r81\0\0\0\0\0\0r82\0\0\0\0\0\0r83\0\0\0\0\0\0" \ - "r84\0\0\0\0\0\0r85\0\0\0\0\0\0r86\0\0\0\0\0\0r87\0\0\0\0\0\0" \ - "r88\0\0\0\0\0\0r89\0\0\0\0\0\0r90\0\0\0\0\0\0r91\0\0\0\0\0\0" \ - "r92\0\0\0\0\0\0r93\0\0\0\0\0\0r94\0\0\0\0\0\0r95\0\0\0\0\0\0" \ - "r96\0\0\0\0\0\0r97\0\0\0\0\0\0r98\0\0\0\0\0\0r99\0\0\0\0\0\0" \ - "r100\0\0\0\0\0r101\0\0\0\0\0r102\0\0\0\0\0r103\0\0\0\0\0" \ - "r104\0\0\0\0\0r105\0\0\0\0\0r106\0\0\0\0\0r107\0\0\0\0\0" \ - "r108\0\0\0\0\0r109\0\0\0\0\0r110\0\0\0\0\0r111\0\0\0\0\0" \ - "r112\0\0\0\0\0r113\0\0\0\0\0r114\0\0\0\0\0r115\0\0\0\0\0" \ - "r116\0\0\0\0\0r117\0\0\0\0\0r118\0\0\0\0\0r119\0\0\0\0\0" \ - "r120\0\0\0\0\0r121\0\0\0\0\0r122\0\0\0\0\0r123\0\0\0\0\0" \ - "r124\0\0\0\0\0r125\0\0\0\0\0r126\0\0\0\0\0r127\0\0\0\0\0" \ - "nat0\0\0\0\0\0nat1\0\0\0\0\0nat2\0\0\0\0\0nat3\0\0\0\0\0" \ - "nat4\0\0\0\0\0nat5\0\0\0\0\0nat6\0\0\0\0\0nat7\0\0\0\0\0" \ - "nat8\0\0\0\0\0nat9\0\0\0\0\0nat10\0\0\0\0nat11\0\0\0\0" \ - "nat12\0\0\0\0nat13\0\0\0\0nat14\0\0\0\0nat15\0\0\0\0" \ - "nat16\0\0\0\0nat17\0\0\0\0nat18\0\0\0\0nat19\0\0\0\0" \ - "nat20\0\0\0\0nat21\0\0\0\0nat22\0\0\0\0nat23\0\0\0\0" \ - "nat24\0\0\0\0nat25\0\0\0\0nat26\0\0\0\0nat27\0\0\0\0" \ - "nat28\0\0\0\0nat29\0\0\0\0nat30\0\0\0\0nat31\0\0\0\0" \ - "nat32\0\0\0\0nat33\0\0\0\0nat34\0\0\0\0nat35\0\0\0\0" \ - "nat36\0\0\0\0nat37\0\0\0\0nat38\0\0\0\0nat39\0\0\0\0" \ - "nat40\0\0\0\0nat41\0\0\0\0nat42\0\0\0\0nat43\0\0\0\0" \ - "nat44\0\0\0\0nat45\0\0\0\0nat46\0\0\0\0nat47\0\0\0\0" \ - "nat48\0\0\0\0nat49\0\0\0\0nat50\0\0\0\0nat51\0\0\0\0" \ - "nat52\0\0\0\0nat53\0\0\0\0nat54\0\0\0\0nat55\0\0\0\0" \ - "nat56\0\0\0\0nat57\0\0\0\0nat58\0\0\0\0nat59\0\0\0\0" \ - "nat60\0\0\0\0nat61\0\0\0\0nat62\0\0\0\0nat63\0\0\0\0" \ - "nat64\0\0\0\0nat65\0\0\0\0nat66\0\0\0\0nat67\0\0\0\0" \ - "nat68\0\0\0\0nat69\0\0\0\0nat70\0\0\0\0nat71\0\0\0\0" \ - "nat72\0\0\0\0nat73\0\0\0\0nat74\0\0\0\0nat75\0\0\0\0" \ - "nat76\0\0\0\0nat77\0\0\0\0nat78\0\0\0\0nat79\0\0\0\0" \ - "nat80\0\0\0\0nat81\0\0\0\0nat82\0\0\0\0nat83\0\0\0\0" \ - "nat84\0\0\0\0nat85\0\0\0\0nat86\0\0\0\0nat87\0\0\0\0" \ - "nat88\0\0\0\0nat89\0\0\0\0nat90\0\0\0\0nat91\0\0\0\0" \ - "nat92\0\0\0\0nat93\0\0\0\0nat94\0\0\0\0nat95\0\0\0\0" \ - "nat96\0\0\0\0nat97\0\0\0\0nat98\0\0\0\0nat99\0\0\0\0" \ - "nat100\0\0\0nat101\0\0\0nat102\0\0\0nat103\0\0\0" \ - "nat104\0\0\0nat105\0\0\0nat106\0\0\0nat107\0\0\0" \ - "nat108\0\0\0nat109\0\0\0nat110\0\0\0nat111\0\0\0" \ - "nat112\0\0\0nat113\0\0\0nat114\0\0\0nat115\0\0\0" \ - "nat116\0\0\0nat117\0\0\0nat118\0\0\0nat119\0\0\0" \ - "nat120\0\0\0nat121\0\0\0nat122\0\0\0nat123\0\0\0" \ - "nat124\0\0\0nat125\0\0\0nat126\0\0\0nat127\0\0\0" \ - "f0\0\0\0\0\0\0\0f1\0\0\0\0\0\0\0f2\0\0\0\0\0\0\0f3\0\0\0\0\0\0\0" \ - "f4\0\0\0\0\0\0\0f5\0\0\0\0\0\0\0f6\0\0\0\0\0\0\0f7\0\0\0\0\0\0\0" \ - "f8\0\0\0\0\0\0\0f9\0\0\0\0\0\0\0f10\0\0\0\0\0\0f11\0\0\0\0\0\0" \ - "f12\0\0\0\0\0\0f13\0\0\0\0\0\0f14\0\0\0\0\0\0f15\0\0\0\0\0\0" \ - "f16\0\0\0\0\0\0f17\0\0\0\0\0\0f18\0\0\0\0\0\0f19\0\0\0\0\0\0" \ - "f20\0\0\0\0\0\0f21\0\0\0\0\0\0f22\0\0\0\0\0\0f23\0\0\0\0\0\0" \ - "f24\0\0\0\0\0\0f25\0\0\0\0\0\0f26\0\0\0\0\0\0f27\0\0\0\0\0\0" \ - "f28\0\0\0\0\0\0f29\0\0\0\0\0\0f30\0\0\0\0\0\0f31\0\0\0\0\0\0" \ - "f32\0\0\0\0\0\0f33\0\0\0\0\0\0f34\0\0\0\0\0\0f35\0\0\0\0\0\0" \ - "f36\0\0\0\0\0\0f37\0\0\0\0\0\0f38\0\0\0\0\0\0f39\0\0\0\0\0\0" \ - "f40\0\0\0\0\0\0f41\0\0\0\0\0\0f42\0\0\0\0\0\0f43\0\0\0\0\0\0" \ - "f44\0\0\0\0\0\0f45\0\0\0\0\0\0f46\0\0\0\0\0\0f47\0\0\0\0\0\0" \ - "f48\0\0\0\0\0\0f49\0\0\0\0\0\0f50\0\0\0\0\0\0f51\0\0\0\0\0\0" \ - "f52\0\0\0\0\0\0f53\0\0\0\0\0\0f54\0\0\0\0\0\0f55\0\0\0\0\0\0" \ - "f56\0\0\0\0\0\0f57\0\0\0\0\0\0f58\0\0\0\0\0\0f59\0\0\0\0\0\0" \ - "f60\0\0\0\0\0\0f61\0\0\0\0\0\0f62\0\0\0\0\0\0f63\0\0\0\0\0\0" \ - "f64\0\0\0\0\0\0f65\0\0\0\0\0\0f66\0\0\0\0\0\0f67\0\0\0\0\0\0" \ - "f68\0\0\0\0\0\0f69\0\0\0\0\0\0f70\0\0\0\0\0\0f71\0\0\0\0\0\0" \ - "f72\0\0\0\0\0\0f73\0\0\0\0\0\0f74\0\0\0\0\0\0f75\0\0\0\0\0\0" \ - "f76\0\0\0\0\0\0f77\0\0\0\0\0\0f78\0\0\0\0\0\0f79\0\0\0\0\0\0" \ - "f80\0\0\0\0\0\0f81\0\0\0\0\0\0f82\0\0\0\0\0\0f83\0\0\0\0\0\0" \ - "f84\0\0\0\0\0\0f85\0\0\0\0\0\0f86\0\0\0\0\0\0f87\0\0\0\0\0\0" \ - "f88\0\0\0\0\0\0f89\0\0\0\0\0\0f90\0\0\0\0\0\0f91\0\0\0\0\0\0" \ - "f92\0\0\0\0\0\0f93\0\0\0\0\0\0f94\0\0\0\0\0\0f95\0\0\0\0\0\0" \ - "f96\0\0\0\0\0\0f97\0\0\0\0\0\0f98\0\0\0\0\0\0f99\0\0\0\0\0\0" \ - "f100\0\0\0\0\0f101\0\0\0\0\0f102\0\0\0\0\0f103\0\0\0\0\0" \ - "f104\0\0\0\0\0f105\0\0\0\0\0f106\0\0\0\0\0f107\0\0\0\0\0" \ - "f108\0\0\0\0\0f109\0\0\0\0\0f110\0\0\0\0\0f111\0\0\0\0\0" \ - "f112\0\0\0\0\0f113\0\0\0\0\0f114\0\0\0\0\0f115\0\0\0\0\0" \ - "f116\0\0\0\0\0f117\0\0\0\0\0f118\0\0\0\0\0f119\0\0\0\0\0" \ - "f120\0\0\0\0\0f121\0\0\0\0\0f122\0\0\0\0\0f123\0\0\0\0\0" \ - "f124\0\0\0\0\0f125\0\0\0\0\0f126\0\0\0\0\0f127\0\0\0\0\0" \ - "ar0\0\0\0\0\0\0ar1\0\0\0\0\0\0ar2\0\0\0\0\0\0ar3\0\0\0\0\0\0" \ - "ar4\0\0\0\0\0\0ar5\0\0\0\0\0\0ar6\0\0\0\0\0\0ar7\0\0\0\0\0\0" \ - "ar8\0\0\0\0\0\0ar9\0\0\0\0\0\0ar10\0\0\0\0\0ar11\0\0\0\0\0" \ - "ar12\0\0\0\0\0ar13\0\0\0\0\0ar14\0\0\0\0\0ar15\0\0\0\0\0" \ - "rsc\0\0\0\0\0\0bsp\0\0\0\0\0\0bspstore\0rnat\0\0\0\0\0" \ - "ar20\0\0\0\0\0ar21\0\0\0\0\0ar22\0\0\0\0\0ar23\0\0\0\0\0" \ - "ar24\0\0\0\0\0ar25\0\0\0\0\0ar26\0\0\0\0\0ar27\0\0\0\0\0" \ - "ar28\0\0\0\0\0ar29\0\0\0\0\0ar30\0\0\0\0\0ar31\0\0\0\0\0" \ - "ccv\0\0\0\0\0\0ar33\0\0\0\0\0ar34\0\0\0\0\0ar35\0\0\0\0\0" \ - "unat\0\0\0\0\0ar37\0\0\0\0\0ar38\0\0\0\0\0ar39\0\0\0\0\0" \ - "fpsr\0\0\0\0\0ar41\0\0\0\0\0ar42\0\0\0\0\0ar43\0\0\0\0\0" \ - "ar44\0\0\0\0\0ar45\0\0\0\0\0ar46\0\0\0\0\0ar47\0\0\0\0\0" \ - "ar48\0\0\0\0\0ar49\0\0\0\0\0ar50\0\0\0\0\0ar51\0\0\0\0\0" \ - "ar52\0\0\0\0\0ar53\0\0\0\0\0ar54\0\0\0\0\0ar55\0\0\0\0\0" \ - "ar56\0\0\0\0\0ar57\0\0\0\0\0ar58\0\0\0\0\0ar59\0\0\0\0\0" \ - "ar60\0\0\0\0\0ar61\0\0\0\0\0ar62\0\0\0\0\0ar63\0\0\0\0\0" \ - "pfs\0\0\0\0\0\0lc\0\0\0\0\0\0\0ec\0\0\0\0\0\0\0ar67\0\0\0\0\0" \ - "ar68\0\0\0\0\0ar69\0\0\0\0\0ar70\0\0\0\0\0ar71\0\0\0\0\0" \ - "ar72\0\0\0\0\0ar73\0\0\0\0\0ar74\0\0\0\0\0ar75\0\0\0\0\0" \ - "ar76\0\0\0\0\0ar77\0\0\0\0\0ar78\0\0\0\0\0ar79\0\0\0\0\0" \ - "ar80\0\0\0\0\0ar81\0\0\0\0\0ar82\0\0\0\0\0ar83\0\0\0\0\0" \ - "ar84\0\0\0\0\0ar85\0\0\0\0\0ar86\0\0\0\0\0ar87\0\0\0\0\0" \ - "ar88\0\0\0\0\0ar89\0\0\0\0\0ar90\0\0\0\0\0ar91\0\0\0\0\0" \ - "ar92\0\0\0\0\0ar93\0\0\0\0\0ar94\0\0\0\0\0ar95\0\0\0\0\0" \ - "ar96\0\0\0\0\0ar97\0\0\0\0\0ar98\0\0\0\0\0ar99\0\0\0\0\0" \ - "ar100\0\0\0\0ar101\0\0\0\0ar102\0\0\0\0ar103\0\0\0\0" \ - "ar104\0\0\0\0ar105\0\0\0\0ar106\0\0\0\0ar107\0\0\0\0" \ - "ar108\0\0\0\0ar109\0\0\0\0ar110\0\0\0\0ar111\0\0\0\0" \ - "ar112\0\0\0\0ar113\0\0\0\0ar114\0\0\0\0ar115\0\0\0\0" \ - "ar116\0\0\0\0ar117\0\0\0\0ar118\0\0\0\0ar119\0\0\0\0" \ - "ar120\0\0\0\0ar121\0\0\0\0ar122\0\0\0\0ar123\0\0\0\0" \ - "ar124\0\0\0\0ar125\0\0\0\0ar126\0\0\0\0ar127\0\0\0\0" \ - "rp\0\0\0\0\0\0\0b1\0\0\0\0\0\0\0b2\0\0\0\0\0\0\0b3\0\0\0\0\0\0\0" \ - "b4\0\0\0\0\0\0\0b5\0\0\0\0\0\0\0b6\0\0\0\0\0\0\0b7\0\0\0\0\0\0\0" \ - "pr\0\0\0\0\0\0\0cfm\0\0\0\0\0\0bsp\0\0\0\0\0\0ip\0\0\0\0\0\0\0" \ - "sp\0\0\0\0\0\0\0" - -#define NREGS ((int) (sizeof (regname_str) - 1) / regname_len) - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < NREGS) - return regname_str + reg * regname_len; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/regs.h b/src/coreclr/src/pal/src/libunwind/src/ia64/regs.h deleted file mode 100644 index a22a818776ffb7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/regs.h +++ /dev/null @@ -1,73 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -/* Apply rotation to a general register. REG must be in the range 0-127. */ - -static inline int -rotate_gr (struct cursor *c, int reg) -{ - unsigned int rrb_gr, sor; - int preg; - - sor = 8 * ((c->cfm >> 14) & 0xf); - rrb_gr = (c->cfm >> 18) & 0x7f; - - if ((unsigned) (reg - 32) >= sor) - preg = reg; - else - { - preg = reg + rrb_gr; /* apply rotation */ - if ((unsigned) (preg - 32) >= sor) - preg -= sor; /* wrap around */ - } - if (sor) - Debug (15, "sor=%u rrb.gr=%u, r%d -> r%d\n", sor, rrb_gr, reg, preg); - return preg; -} - -/* Apply rotation to a floating-point register. The number REG must - be in the range of 0-127. */ - -static inline int -rotate_fr (struct cursor *c, int reg) -{ - unsigned int rrb_fr; - int preg; - - rrb_fr = (c->cfm >> 25) & 0x7f; - if (reg < 32) - preg = reg; /* register not part of the rotating partition */ - else - { - preg = reg + rrb_fr; /* apply rotation */ - if (preg > 127) - preg -= 96; /* wrap around */ - } - if (rrb_fr) - Debug (15, "rrb.fr=%u, f%d -> f%d\n", rrb_fr, reg, preg); - return preg; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/setjmp.S b/src/coreclr/src/pal/src/libunwind/src/ia64/setjmp.S deleted file mode 100644 index 384615b840ece9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/setjmp.S +++ /dev/null @@ -1,51 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "jmpbuf.h" - - .align 32 - - .global _setjmp - - .proc _setjmp - -_setjmp: - mov r2 = ar.bsp - st8 [r32] = r12 // jmp_buf[JB_SP] = sp - mov r3 = rp - - adds r16 = JB_RP*8, r32 - adds r17 = JB_BSP*8, r32 - mov r8 = 0 - ;; - st8 [r16] = r3 // jmp_buf[JB_RP] = rp - st8 [r17] = r2 // jmp_buf[JB_BSP] = bsp - br.ret.sptk.many rp - - .endp _setjmp -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/ia64/siglongjmp.S deleted file mode 100644 index d77b43753bb29d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/siglongjmp.S +++ /dev/null @@ -1,69 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 SIG_SETMASK 2 - - .global _UI_siglongjmp_cont - .global sigprocmask - - .align 32 - .proc siglongjmp_continuation -siglongjmp_continuation: -_UI_siglongjmp_cont: // non-function label for siglongjmp.c - .prologue - .save rp, r15 - .body - nop 0 - nop 0 - br.call.sptk.many b6 = .next - ;; - .prologue - .save ar.pfs, r33 -.next: alloc loc1 = ar.pfs, 0, 3, 3, 0 - /* - * Note: we can use the scratch stack are because the caller - * of sigsetjmp() by definition is not a leaf-procedure. - */ - st8 [sp] = r17 // store signal mask - .save rp, loc0 - mov loc0 = r15 // final continuation point - ;; - .body - mov loc2 = r16 // value to return in r8 - - mov out0 = SIG_SETMASK - mov out1 = sp - mov out2 = r0 - br.call.sptk.many rp = sigprocmask - ;; - mov rp = loc0 - mov ar.pfs = loc1 - mov r8 = loc2 - br.ret.sptk.many rp - .endp siglongjmp_continuation -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/sigsetjmp.S b/src/coreclr/src/pal/src/libunwind/src/ia64/sigsetjmp.S deleted file mode 100644 index 02f7af4b377fab..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/sigsetjmp.S +++ /dev/null @@ -1,69 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "jmpbuf.h" - -#define SIG_BLOCK 0 - - .align 32 - - .global __sigsetjmp - .global sigprocmask - - .proc __sigsetjmp - -__sigsetjmp: - .prologue - .save ar.pfs, r35 - alloc loc1 = ar.pfs, 2, 3, 3, 0 - add out2 = JB_MASK*8, in0 - .save rp, loc0 - mov loc0 = rp - mov out0 = SIG_BLOCK - .body - ;; - cmp.ne p6, p0 = in1, r0 - mov out1 = r0 - mov loc2 = ar.bsp -(p6) br.call.sptk.many rp = sigprocmask // sigjmp_buf[JB_MASK] = sigmask - ;; - - add r16 = JB_MASK_SAVED*8, in0 - st8 [in0] = sp, (JB_RP-JB_SP)*8 // sigjmp_buf[JB_SP] = sp - mov r8 = 0 - ;; - st8 [in0] = loc0, (JB_BSP-JB_RP)*8 // sigjmp_buf[JB_RP] = rp - st8 [r16] = in1 // sigjmp_buf[JB_MASK_SAVED] = savemask - mov rp = loc0 - ;; - st8 [in0] = loc2 // sigjmp_buf[JB_BSP] = bsp - mov.i ar.pfs = loc1 - br.ret.sptk.many rp - - .endp __sigsetjmp -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/ia64/ucontext_i.h deleted file mode 100644 index ea32c8aaa0922f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/ucontext_i.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (C) 2002 Hewlett-Packard Co. - Contributed by David Mosberger-Tang . - -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. */ - -/* Constants shared between setcontext() and getcontext(). Don't - install this header file. */ - -#define SIG_BLOCK 0 -#define SIG_UNBLOCK 1 -#define SIG_SETMASK 2 - -#define IA64_SC_FLAG_SYNCHRONOUS_BIT 63 - -#define SC_FLAGS 0x000 -#define SC_NAT 0x008 -#define SC_BSP 0x048 -#define SC_RNAT 0x050 -#define SC_UNAT 0x060 -#define SC_FPSR 0x068 -#define SC_PFS 0x070 -#define SC_LC 0x078 -#define SC_PR 0x080 -#define SC_BR 0x088 -#define SC_GR 0x0c8 -#define SC_FR 0x1d0 -#define SC_MASK 0x9d0 - - -#define rTMP r10 -#define rPOS r11 -#define rCPOS r14 -#define rNAT r15 -#define rFLAGS r16 - -#define rB5 r18 -#define rB4 r19 -#define rB3 r20 -#define rB2 r21 -#define rB1 r22 -#define rB0 r23 -#define rRSC r24 -#define rBSP r25 -#define rRNAT r26 -#define rUNAT r27 -#define rFPSR r28 -#define rPFS r29 -#define rLC r30 -#define rPR r31 diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_decoder.h b/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_decoder.h deleted file mode 100644 index 7fd41740de808a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_decoder.h +++ /dev/null @@ -1,477 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -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. */ - -/* - * Generic IA-64 unwind info decoder. - * - * This file is used both by the Linux kernel and objdump. Please keep - * the two copies of this file in sync. - * - * You need to customize the decoder by defining the following - * macros/constants before including this file: - * - * Types: - * unw_word Unsigned integer type with at least 64 bits - * - * Register names: - * UNW_REG_BSP - * UNW_REG_BSPSTORE - * UNW_REG_FPSR - * UNW_REG_LC - * UNW_REG_PFS - * UNW_REG_PR - * UNW_REG_RNAT - * UNW_REG_PSP - * UNW_REG_RP - * UNW_REG_UNAT - * - * Decoder action macros: - * UNW_DEC_BAD_CODE(code) - * UNW_DEC_ABI(fmt,abi,context,arg) - * UNW_DEC_BR_GR(fmt,brmask,gr,arg) - * UNW_DEC_BR_MEM(fmt,brmask,arg) - * UNW_DEC_COPY_STATE(fmt,label,arg) - * UNW_DEC_EPILOGUE(fmt,t,ecount,arg) - * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg) - * UNW_DEC_FR_MEM(fmt,frmask,arg) - * UNW_DEC_GR_GR(fmt,grmask,gr,arg) - * UNW_DEC_GR_MEM(fmt,grmask,arg) - * UNW_DEC_LABEL_STATE(fmt,label,arg) - * UNW_DEC_MEM_STACK_F(fmt,t,size,arg) - * UNW_DEC_MEM_STACK_V(fmt,t,arg) - * UNW_DEC_PRIUNAT_GR(fmt,r,arg) - * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) - * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) - * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg) - * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg) - * UNW_DEC_PROLOGUE(fmt,body,rlen,arg) - * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg) - * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg) - * UNW_DEC_REG_REG(fmt,src,dst,arg) - * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg) - * UNW_DEC_REG_WHEN(fmt,reg,t,arg) - * UNW_DEC_RESTORE(fmt,t,abreg,arg) - * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg) - * UNW_DEC_SPILL_BASE(fmt,pspoff,arg) - * UNW_DEC_SPILL_MASK(fmt,imaskp,arg) - * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg) - * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg) - * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg) - * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg) - * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg) - * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg) - */ - -static unw_word -unw_decode_uleb128 (unsigned char **dpp) -{ - unsigned shift = 0; - unw_word byte, result = 0; - unsigned char *bp = *dpp; - - while (1) - { - byte = *bp++; - result |= (byte & 0x7f) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - *dpp = bp; - return result; -} - -static unsigned char * -unw_decode_x1 (unsigned char *dp, unsigned char code, void *arg) -{ - unsigned char byte1, abreg; - unw_word t, off; - - byte1 = *dp++; - t = unw_decode_uleb128 (&dp); - off = unw_decode_uleb128 (&dp); - abreg = (byte1 & 0x7f); - if (byte1 & 0x80) - UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg); - else - UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg); - return dp; -} - -static unsigned char * -unw_decode_x2 (unsigned char *dp, unsigned char code, void *arg) -{ - unsigned char byte1, byte2, abreg, x, ytreg; - unw_word t; - - byte1 = *dp++; byte2 = *dp++; - t = unw_decode_uleb128 (&dp); - abreg = (byte1 & 0x7f); - ytreg = byte2; - x = (byte1 >> 7) & 1; - if ((byte1 & 0x80) == 0 && ytreg == 0) - UNW_DEC_RESTORE(X2, t, abreg, arg); - else - UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg); - return dp; -} - -static unsigned char * -unw_decode_x3 (unsigned char *dp, unsigned char code, void *arg) -{ - unsigned char byte1, byte2, abreg, qp; - unw_word t, off; - - byte1 = *dp++; byte2 = *dp++; - t = unw_decode_uleb128 (&dp); - off = unw_decode_uleb128 (&dp); - - qp = (byte1 & 0x3f); - abreg = (byte2 & 0x7f); - - if (byte1 & 0x80) - UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg); - else - UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg); - return dp; -} - -static unsigned char * -unw_decode_x4 (unsigned char *dp, unsigned char code, void *arg) -{ - unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg; - unw_word t; - - byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; - t = unw_decode_uleb128 (&dp); - - qp = (byte1 & 0x3f); - abreg = (byte2 & 0x7f); - x = (byte2 >> 7) & 1; - ytreg = byte3; - - if ((byte2 & 0x80) == 0 && byte3 == 0) - UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg); - else - UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg); - return dp; -} - -static inline unsigned char * -unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg) -{ - int body = (code & 0x20) != 0; - unw_word rlen; - - rlen = (code & 0x1f); - UNW_DEC_PROLOGUE(R1, body, rlen, arg); - return dp; -} - -static inline unsigned char * -unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg) -{ - unsigned char byte1, mask, grsave; - unw_word rlen; - - byte1 = *dp++; - - mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); - grsave = (byte1 & 0x7f); - rlen = unw_decode_uleb128 (&dp); - UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg); - return dp; -} - -static inline unsigned char * -unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg) -{ - unw_word rlen; - - rlen = unw_decode_uleb128 (&dp); - UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg); - return dp; -} - -static inline unsigned char * -unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg) -{ - unsigned char brmask = (code & 0x1f); - - UNW_DEC_BR_MEM(P1, brmask, arg); - return dp; -} - -static inline unsigned char * -unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg) -{ - if ((code & 0x10) == 0) - { - unsigned char byte1 = *dp++; - - UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1), - (byte1 & 0x7f), arg); - } - else if ((code & 0x08) == 0) - { - unsigned char byte1 = *dp++, r, dst; - - r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); - dst = (byte1 & 0x7f); - switch (r) - { - case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break; - case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break; - case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break; - case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break; - case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break; - case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break; - case 6: UNW_DEC_RP_BR(P3, dst, arg); break; - case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break; - case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break; - case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break; - case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break; - case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break; - default: UNW_DEC_BAD_CODE(r); break; - } - } - else if ((code & 0x7) == 0) - UNW_DEC_SPILL_MASK(P4, dp, arg); - else if ((code & 0x7) == 1) - { - unw_word grmask, frmask, byte1, byte2, byte3; - - byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; - grmask = ((byte1 >> 4) & 0xf); - frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3; - UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg); - } - else - UNW_DEC_BAD_CODE(code); - return dp; -} - -static inline unsigned char * -unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg) -{ - int gregs = (code & 0x10) != 0; - unsigned char mask = (code & 0x0f); - - if (gregs) - UNW_DEC_GR_MEM(P6, mask, arg); - else - UNW_DEC_FR_MEM(P6, mask, arg); - return dp; -} - -static inline unsigned char * -unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg) -{ - unsigned char r, byte1, byte2; - unw_word t, size; - - if ((code & 0x10) == 0) - { - r = (code & 0xf); - t = unw_decode_uleb128 (&dp); - switch (r) - { - case 0: - size = unw_decode_uleb128 (&dp); - UNW_DEC_MEM_STACK_F(P7, t, size, arg); - break; - - case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break; - case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break; - case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break; - case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break; - case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break; - case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break; - case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break; - case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break; - case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break; - case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break; - case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break; - case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break; - case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break; - case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break; - case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break; - default: UNW_DEC_BAD_CODE(r); break; - } - } - else - { - switch (code & 0xf) - { - case 0x0: /* p8 */ - { - r = *dp++; - t = unw_decode_uleb128 (&dp); - switch (r) - { - case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break; - case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break; - case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break; - case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break; - case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break; - case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break; - case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break; - case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break; - case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break; - case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break; - case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break; - case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break; - case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break; - case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break; - case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break; - case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break; - case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break; - case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break; - case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break; - default: UNW_DEC_BAD_CODE(r); break; - } - } - break; - - case 0x1: - byte1 = *dp++; byte2 = *dp++; - UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg); - break; - - case 0xf: /* p10 */ - byte1 = *dp++; byte2 = *dp++; - UNW_DEC_ABI(P10, byte1, byte2, arg); - break; - - case 0x9: - return unw_decode_x1 (dp, code, arg); - - case 0xa: - return unw_decode_x2 (dp, code, arg); - - case 0xb: - return unw_decode_x3 (dp, code, arg); - - case 0xc: - return unw_decode_x4 (dp, code, arg); - - default: - UNW_DEC_BAD_CODE(code); - break; - } - } - return dp; -} - -static inline unsigned char * -unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg) -{ - unw_word label = (code & 0x1f); - - if ((code & 0x20) != 0) - UNW_DEC_COPY_STATE(B1, label, arg); - else - UNW_DEC_LABEL_STATE(B1, label, arg); - return dp; -} - -static inline unsigned char * -unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg) -{ - unw_word t; - - t = unw_decode_uleb128 (&dp); - UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg); - return dp; -} - -static inline unsigned char * -unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg) -{ - unw_word t, ecount, label; - - if ((code & 0x10) == 0) - { - t = unw_decode_uleb128 (&dp); - ecount = unw_decode_uleb128 (&dp); - UNW_DEC_EPILOGUE(B3, t, ecount, arg); - } - else if ((code & 0x07) == 0) - { - label = unw_decode_uleb128 (&dp); - if ((code & 0x08) != 0) - UNW_DEC_COPY_STATE(B4, label, arg); - else - UNW_DEC_LABEL_STATE(B4, label, arg); - } - else - switch (code & 0x7) - { - case 1: return unw_decode_x1 (dp, code, arg); - case 2: return unw_decode_x2 (dp, code, arg); - case 3: return unw_decode_x3 (dp, code, arg); - case 4: return unw_decode_x4 (dp, code, arg); - default: UNW_DEC_BAD_CODE(code); break; - } - return dp; -} - -typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *); - -/* - * Decode one descriptor and return address of next descriptor. - */ -static inline unsigned char * -unw_decode (unsigned char *dp, int inside_body, void *arg) -{ - unsigned char code, primary; - - code = *dp++; - primary = code >> 5; - - if (primary < 2) - dp = unw_decode_r1 (dp, code, arg); - else if (primary == 2) - dp = unw_decode_r2 (dp, code, arg); - else if (primary == 3) - dp = unw_decode_r3 (dp, code, arg); - else if (inside_body) - switch (primary) - { - case 4: - case 5: dp = unw_decode_b1 (dp, code, arg); break; - case 6: dp = unw_decode_b2 (dp, code, arg); break; - case 7: dp = unw_decode_b3_x4 (dp, code, arg); break; - } - else - switch (primary) - { - case 4: dp = unw_decode_p1 (dp, code, arg); break; - case 5: dp = unw_decode_p2_p5 (dp, code, arg); break; - case 6: dp = unw_decode_p6 (dp, code, arg); break; - case 7: dp = unw_decode_p7_p10 (dp, code, arg); break; - } - return dp; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_i.h deleted file mode 100644 index 8ccbb46c93067f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_i.h +++ /dev/null @@ -1,633 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 unwind_i_h -#define unwind_i_h - -#include -#include - -#include - -#include "rse.h" - -#include "libunwind_i.h" - -#define IA64_UNW_VER(x) ((x) >> 48) -#define IA64_UNW_FLAG_MASK ((unw_word_t) 0x0000ffff00000000ULL) -#define IA64_UNW_FLAG_OSMASK ((unw_word_t) 0x0000f00000000000ULL) -#define IA64_UNW_FLAG_EHANDLER(x) ((x) & (unw_word_t) 0x0000000100000000ULL) -#define IA64_UNW_FLAG_UHANDLER(x) ((x) & (unw_word_t) 0x0000000200000000ULL) -#define IA64_UNW_LENGTH(x) ((x) & (unw_word_t) 0x00000000ffffffffULL) - -#ifdef MIN -# undef MIN -#endif -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -#if !defined(HAVE_SYS_UC_ACCESS_H) && !defined(UNW_REMOTE_ONLY) - -static ALWAYS_INLINE void * -inlined_uc_addr (ucontext_t *uc, int reg, uint8_t *nat_bitnr) -{ - unw_word_t reg_addr; - void *addr; - - switch (reg) - { - case UNW_IA64_GR + 0: addr = &unw.read_only.r0; break; - case UNW_IA64_NAT + 0: addr = &unw.read_only.r0; break; - case UNW_IA64_FR + 0: addr = &unw.read_only.f0; break; - case UNW_IA64_FR + 1: - if (__BYTE_ORDER == __BIG_ENDIAN) - addr = &unw.read_only.f1_be; - else - addr = &unw.read_only.f1_le; - break; - case UNW_IA64_IP: addr = &uc->uc_mcontext.sc_br[0]; break; - case UNW_IA64_CFM: addr = &uc->uc_mcontext.sc_ar_pfs; break; - case UNW_IA64_AR_RNAT: addr = &uc->uc_mcontext.sc_ar_rnat; break; - case UNW_IA64_AR_UNAT: addr = &uc->uc_mcontext.sc_ar_unat; break; - case UNW_IA64_AR_LC: addr = &uc->uc_mcontext.sc_ar_lc; break; - case UNW_IA64_AR_FPSR: addr = &uc->uc_mcontext.sc_ar_fpsr; break; - case UNW_IA64_PR: addr = &uc->uc_mcontext.sc_pr; break; - case UNW_IA64_AR_BSPSTORE: addr = &uc->uc_mcontext.sc_ar_bsp; break; - - case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: - case UNW_IA64_GR + 12: - addr = &uc->uc_mcontext.sc_gr[reg - UNW_IA64_GR]; - break; - - case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7: - case UNW_IA64_NAT + 12: - addr = &uc->uc_mcontext.sc_nat; - reg_addr = (unw_word_t) &uc->uc_mcontext.sc_gr[reg - UNW_IA64_NAT]; - *nat_bitnr = reg - UNW_IA64_NAT; - break; - - case UNW_IA64_BR + 1 ... UNW_IA64_BR + 5: - addr = &uc->uc_mcontext.sc_br[reg - UNW_IA64_BR]; - break; - - case UNW_IA64_FR+ 2 ... UNW_IA64_FR+ 5: - case UNW_IA64_FR+16 ... UNW_IA64_FR+31: - addr = &uc->uc_mcontext.sc_fr[reg - UNW_IA64_FR]; - break; - - default: - addr = NULL; - } - return addr; -} - -static inline void * -uc_addr (ucontext_t *uc, int reg, uint8_t *nat_bitnr) -{ - if (__builtin_constant_p (reg)) - return inlined_uc_addr (uc, reg, nat_bitnr); - else - return tdep_uc_addr (uc, reg, nat_bitnr); -} - -/* Return TRUE if ADDR points inside unw.read_only_reg. */ - -static inline long -ia64_read_only_reg (void *addr) -{ - return ((unsigned long) ((char *) addr - (char *) &unw.read_only) - < sizeof (unw.read_only)); -} - -#endif /* !defined(HAVE_SYS_UC_ACCESS_H) && !defined(UNW_REMOTE_ONLY) */ - -/* Bits 0 and 1 of a location are used to encode its type: - bit 0: set if location uses floating-point format. - bit 1: set if location is a NaT bit on memory stack. */ - -#define IA64_LOC_TYPE_FP (1 << 0) -#define IA64_LOC_TYPE_MEMSTK_NAT (1 << 1) - -#ifdef UNW_LOCAL_ONLY -#define IA64_LOC_REG(r,t) (((r) << 2) | (t)) -#define IA64_LOC_ADDR(a,t) (((a) & ~0x3) | (t)) -#define IA64_LOC_UC_ADDR(a,t) IA64_LOC_ADDR(a, t) -#define IA64_NULL_LOC (0) - -#define IA64_GET_REG(l) ((l) >> 2) -#define IA64_GET_ADDR(l) ((l) & ~0x3) -#define IA64_IS_NULL_LOC(l) ((l) == 0) -#define IA64_IS_FP_LOC(l) (((l) & IA64_LOC_TYPE_FP) != 0) -#define IA64_IS_MEMSTK_NAT(l) (((l) & IA64_LOC_TYPE_MEMSTK_NAT) != 0) -#define IA64_IS_REG_LOC(l) 0 -#define IA64_IS_UC_LOC(l) 0 - -#define IA64_REG_LOC(c,r) ((unw_word_t) uc_addr((c)->as_arg, r, NULL)) -#define IA64_REG_NAT_LOC(c,r,n) ((unw_word_t) uc_addr((c)->as_arg, r, n)) -#define IA64_FPREG_LOC(c,r) \ - ((unw_word_t) uc_addr((c)->as_arg, (r), NULL) | IA64_LOC_TYPE_FP) - -# define ia64_find_proc_info(c,ip,n) \ - tdep_find_proc_info(unw_local_addr_space, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define ia64_put_unwind_info(c, pi) do { ; } while (0) - -/* Note: the register accessors (ia64_{get,set}{,fp}()) must check for - NULL locations because uc_addr() returns NULL for unsaved - registers. */ - -static inline int -ia64_getfp (struct cursor *c, unw_word_t loc, unw_fpreg_t *val) -{ - if (IA64_IS_NULL_LOC (loc)) - { - Debug (16, "access to unsaved register\n"); - return -UNW_EBADREG; - } - *val = *(unw_fpreg_t *) IA64_GET_ADDR (loc); - return 0; -} - -static inline int -ia64_putfp (struct cursor *c, unw_word_t loc, unw_fpreg_t val) -{ - unw_fpreg_t *addr = (unw_fpreg_t *) IA64_GET_ADDR (loc); - - if (IA64_IS_NULL_LOC (loc)) - { - Debug (16, "access to unsaved register\n"); - return -UNW_EBADREG; - } - else if (ia64_read_only_reg (addr)) - { - Debug (16, "attempt to read-only register\n"); - return -UNW_EREADONLYREG; - } - *addr = val; - return 0; -} - -static inline int -ia64_get (struct cursor *c, unw_word_t loc, unw_word_t *val) -{ - if (IA64_IS_NULL_LOC (loc)) - { - Debug (16, "access to unsaved register\n"); - return -UNW_EBADREG; - } - *val = *(unw_word_t *) IA64_GET_ADDR (loc); - return 0; -} - -static inline int -ia64_put (struct cursor *c, unw_word_t loc, unw_word_t val) -{ - unw_word_t *addr = (unw_word_t *) IA64_GET_ADDR (loc); - - if (IA64_IS_NULL_LOC (loc)) - { - Debug (16, "access to unsaved register\n"); - return -UNW_EBADREG; - } - else if (ia64_read_only_reg (addr)) - { - Debug (16, "attempt to read-only register\n"); - return -UNW_EREADONLYREG; - } - *addr = val; - return 0; -} - -#else /* !UNW_LOCAL_ONLY */ - -/* Bits 0 and 1 of the second word (w1) of a location are used - to further distinguish what location we're dealing with: - - bit 0: set if the location is a register - bit 1: set of the location is accessed via uc_access(3) */ -#define IA64_LOC_TYPE_REG (1 << 0) -#define IA64_LOC_TYPE_UC (1 << 1) - -#define IA64_LOC_REG(r,t) ((ia64_loc_t) { ((r) << 2) | (t), \ - IA64_LOC_TYPE_REG }) -#define IA64_LOC_ADDR(a,t) ((ia64_loc_t) { ((a) & ~0x3) | (t), 0 }) -#define IA64_LOC_UC_ADDR(a,t) ((ia64_loc_t) { ((a) & ~0x3) | (t), \ - IA64_LOC_TYPE_UC }) -#define IA64_LOC_UC_REG(r,a) ((ia64_loc_t) { ((r) << 2), \ - ((a) | IA64_LOC_TYPE_REG \ - | IA64_LOC_TYPE_UC) }) -#define IA64_NULL_LOC ((ia64_loc_t) { 0, 0 }) - -#define IA64_GET_REG(l) ((l).w0 >> 2) -#define IA64_GET_ADDR(l) ((l).w0 & ~0x3) -#define IA64_GET_AUX_ADDR(l) ((l).w1 & ~0x3) -#define IA64_IS_NULL_LOC(l) (((l).w0 | (l).w1) == 0) -#define IA64_IS_FP_LOC(l) (((l).w0 & IA64_LOC_TYPE_FP) != 0) -#define IA64_IS_MEMSTK_NAT(l) (((l).w0 & IA64_LOC_TYPE_MEMSTK_NAT) != 0) -#define IA64_IS_REG_LOC(l) (((l).w1 & IA64_LOC_TYPE_REG) != 0) -#define IA64_IS_UC_LOC(l) (((l).w1 & IA64_LOC_TYPE_UC) != 0) - -#define IA64_REG_LOC(c,r) IA64_LOC_REG ((r), 0) -#define IA64_REG_NAT_LOC(c,r,n) IA64_LOC_REG ((r), 0) -#define IA64_FPREG_LOC(c,r) IA64_LOC_REG ((r), IA64_LOC_TYPE_FP) - -# define ia64_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define ia64_put_unwind_info(c,pi) \ - (*(c)->as->acc.put_unwind_info)((c)->as, (pi), (c)->as_arg) - -#define ia64_uc_access_reg UNW_OBJ(uc_access_reg) -#define ia64_uc_access_fpreg UNW_OBJ(uc_access_fpreg) - -extern int ia64_uc_access_reg (struct cursor *c, ia64_loc_t loc, - unw_word_t *valp, int write); -extern int ia64_uc_access_fpreg (struct cursor *c, ia64_loc_t loc, - unw_fpreg_t *valp, int write); - -static inline int -ia64_getfp (struct cursor *c, ia64_loc_t loc, unw_fpreg_t *val) -{ - unw_word_t addr; - int ret; - - if (IA64_IS_NULL_LOC (loc)) - { - Debug (16, "access to unsaved register\n"); - return -UNW_EBADREG; - } - - if (IA64_IS_UC_LOC (loc)) - return ia64_uc_access_fpreg (c, loc, val, 0); - - if (IA64_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, IA64_GET_REG (loc), - val, 0, c->as_arg); - - addr = IA64_GET_ADDR (loc); - ret = (*c->as->acc.access_mem) (c->as, addr + 0, &val->raw.bits[0], 0, - c->as_arg); - if (ret < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 8, &val->raw.bits[1], 0, - c->as_arg); -} - -static inline int -ia64_putfp (struct cursor *c, ia64_loc_t loc, unw_fpreg_t val) -{ - unw_word_t addr; - int ret; - - if (IA64_IS_NULL_LOC (loc)) - { - Debug (16, "access to unsaved register\n"); - return -UNW_EBADREG; - } - - if (IA64_IS_UC_LOC (loc)) - return ia64_uc_access_fpreg (c, loc, &val, 1); - - if (IA64_IS_REG_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, IA64_GET_REG (loc), &val, 1, - c->as_arg); - - addr = IA64_GET_ADDR (loc); - ret = (*c->as->acc.access_mem) (c->as, addr + 0, &val.raw.bits[0], 1, - c->as_arg); - if (ret < 0) - return ret; - - return (*c->as->acc.access_mem) (c->as, addr + 8, &val.raw.bits[1], 1, - c->as_arg); -} - -/* Get the 64 data bits from location LOC. If bit 0 is cleared, LOC - is a memory address, otherwise it is a register number. If the - register is a floating-point register, the 64 bits are read from - the significand bits. */ - -static inline int -ia64_get (struct cursor *c, ia64_loc_t loc, unw_word_t *val) -{ - if (IA64_IS_NULL_LOC (loc)) - { - Debug (16, "access to unsaved register\n"); - return -UNW_EBADREG; - } - - if (IA64_IS_FP_LOC (loc)) - { - unw_fpreg_t tmp; - int ret; - - ret = ia64_getfp (c, loc, &tmp); - if (ret < 0) - return ret; - - if (c->as->big_endian) - *val = tmp.raw.bits[1]; - else - *val = tmp.raw.bits[0]; - return 0; - } - - if (IA64_IS_UC_LOC (loc)) - return ia64_uc_access_reg (c, loc, val, 0); - - if (IA64_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg)(c->as, IA64_GET_REG (loc), val, 0, - c->as_arg); - else - return (*c->as->acc.access_mem)(c->as, IA64_GET_ADDR (loc), val, 0, - c->as_arg); -} - -static inline int -ia64_put (struct cursor *c, ia64_loc_t loc, unw_word_t val) -{ - if (IA64_IS_NULL_LOC (loc)) - { - Debug (16, "access to unsaved register\n"); - return -UNW_EBADREG; - } - - if (IA64_IS_FP_LOC (loc)) - { - unw_fpreg_t tmp; - - memset (&tmp, 0, sizeof (tmp)); - if (c->as->big_endian) - tmp.raw.bits[1] = val; - else - tmp.raw.bits[0] = val; - return ia64_putfp (c, loc, tmp); - } - - if (IA64_IS_UC_LOC (loc)) - return ia64_uc_access_reg (c, loc, &val, 1); - - if (IA64_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg)(c->as, IA64_GET_REG (loc), &val, 1, - c->as_arg); - else - return (*c->as->acc.access_mem)(c->as, IA64_GET_ADDR (loc), &val, 1, - c->as_arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -struct ia64_unwind_block - { - unw_word_t header; - unw_word_t desc[0]; /* unwind descriptors */ - - /* Personality routine and language-specific data follow behind - descriptors. */ - }; - -enum ia64_where - { - IA64_WHERE_NONE, /* register isn't saved at all */ - IA64_WHERE_GR, /* register is saved in a general register */ - IA64_WHERE_FR, /* register is saved in a floating-point register */ - IA64_WHERE_BR, /* register is saved in a branch register */ - IA64_WHERE_SPREL, /* register is saved on memstack (sp-relative) */ - IA64_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */ - - /* At the end of each prologue these locations get resolved to - IA64_WHERE_PSPREL and IA64_WHERE_GR, respectively: */ - - IA64_WHERE_SPILL_HOME, /* register is saved in its spill home */ - IA64_WHERE_GR_SAVE /* register is saved in next general register */ - }; - -#define IA64_WHEN_NEVER 0x7fffffff - -struct ia64_reg_info - { - unw_word_t val; /* save location: register number or offset */ - enum ia64_where where; /* where the register gets saved */ - int when; /* when the register gets saved */ - }; - -struct ia64_labeled_state; /* opaque structure */ - -struct ia64_reg_state - { - struct ia64_reg_state *next; /* next (outer) element on state stack */ - struct ia64_reg_info reg[IA64_NUM_PREGS]; /* register save locations */ - }; - -struct ia64_state_record - { - unsigned int first_region : 1; /* is this the first region? */ - unsigned int done : 1; /* are we done scanning descriptors? */ - unsigned int any_spills : 1; /* got any register spills? */ - unsigned int in_body : 1; /* are we inside prologue or body? */ - uint8_t *imask; /* imask of spill_mask record or NULL */ - uint16_t abi_marker; - - unw_word_t pr_val; /* predicate values */ - unw_word_t pr_mask; /* predicate mask */ - - long spill_offset; /* psp-relative offset for spill base */ - int region_start; - int region_len; - int when_sp_restored; - int epilogue_count; - int when_target; - - uint8_t gr_save_loc; /* next save register */ - uint8_t return_link_reg; /* branch register used as return pointer */ - - struct ia64_labeled_state *labeled_states; - struct ia64_reg_state curr; - }; - -struct ia64_labeled_state - { - struct ia64_labeled_state *next; /* next label (or NULL) */ - unsigned long label; /* label for this state */ - struct ia64_reg_state saved_state; - }; - -/* Convenience macros: */ -#define ia64_make_proc_info UNW_OBJ(make_proc_info) -#define ia64_fetch_proc_info UNW_OBJ(fetch_proc_info) -#define ia64_create_state_record UNW_OBJ(create_state_record) -#define ia64_free_state_record UNW_OBJ(free_state_record) -#define ia64_find_save_locs UNW_OBJ(find_save_locs) -#define ia64_validate_cache UNW_OBJ(ia64_validate_cache) -#define ia64_local_validate_cache UNW_OBJ(ia64_local_validate_cache) -#define ia64_per_thread_cache UNW_OBJ(per_thread_cache) -#define ia64_scratch_loc UNW_OBJ(scratch_loc) -#define ia64_local_resume UNW_OBJ(local_resume) -#define ia64_local_addr_space_init UNW_OBJ(local_addr_space_init) -#define ia64_strloc UNW_OBJ(strloc) -#define ia64_install_cursor UNW_OBJ(install_cursor) -#define rbs_switch UNW_OBJ(rbs_switch) -#define rbs_find_stacked UNW_OBJ(rbs_find_stacked) - -extern int ia64_make_proc_info (struct cursor *c); -extern int ia64_fetch_proc_info (struct cursor *c, unw_word_t ip, - int need_unwind_info); -/* The proc-info must be valid for IP before this routine can be - called: */ -extern int ia64_create_state_record (struct cursor *c, - struct ia64_state_record *sr); -extern int ia64_free_state_record (struct ia64_state_record *sr); -extern int ia64_find_save_locs (struct cursor *c); -extern void ia64_validate_cache (unw_addr_space_t as, void *arg); -extern int ia64_local_validate_cache (unw_addr_space_t as, void *arg); -extern void ia64_local_addr_space_init (void); -extern ia64_loc_t ia64_scratch_loc (struct cursor *c, unw_regnum_t reg, - uint8_t *nat_bitnr); - -extern NORETURN void ia64_install_cursor (struct cursor *c, - unw_word_t pri_unat, - unw_word_t *extra, - unw_word_t bspstore, - unw_word_t dirty_size, - unw_word_t *dirty_partition, - unw_word_t dirty_rnat); -extern int ia64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, - void *arg); -extern int rbs_switch (struct cursor *c, - unw_word_t saved_bsp, unw_word_t saved_bspstore, - ia64_loc_t saved_rnat_loc); -extern int rbs_find_stacked (struct cursor *c, unw_word_t regs_to_skip, - ia64_loc_t *locp, ia64_loc_t *rnat_locp); - -#ifndef UNW_REMOTE_ONLY -# define NEED_RBS_COVER_AND_FLUSH -# define rbs_cover_and_flush UNW_OBJ(rbs_cover_and_flush) - extern int rbs_cover_and_flush (struct cursor *c, unw_word_t nregs, - unw_word_t *dirty_partition, - unw_word_t *dirty_rnat, - unw_word_t *bspstore); -#endif - -/* Warning: ia64_strloc() is for debugging only and it is NOT re-entrant! */ -extern const char *ia64_strloc (ia64_loc_t loc); - -/* Return true if the register-backing store is inside a ucontext_t - that needs to be accessed via uc_access(3). */ - -static inline int -rbs_on_uc (struct rbs_area *rbs) -{ - return IA64_IS_UC_LOC (rbs->rnat_loc) && !IA64_IS_REG_LOC (rbs->rnat_loc); -} - -/* Return true if BSP points to a word that's stored on register - backing-store RBS. */ -static inline int -rbs_contains (struct rbs_area *rbs, unw_word_t bsp) -{ - int result; - - /* Caveat: this takes advantage of unsigned arithmetic. The full - test is (bsp >= rbs->end - rbs->size) && (bsp < rbs->end). We - take advantage of the fact that -n == ~n + 1. */ - result = bsp - rbs->end > ~rbs->size; - Debug (16, "0x%lx in [0x%lx-0x%lx) => %d\n", - (long) bsp, (long) (rbs->end - rbs->size), (long) rbs->end, result); - return result; -} - -static inline ia64_loc_t -rbs_get_rnat_loc (struct rbs_area *rbs, unw_word_t bsp) -{ - unw_word_t rnat_addr = rse_rnat_addr (bsp); - ia64_loc_t rnat_loc; - - if (rbs_contains (rbs, rnat_addr)) - { - if (rbs_on_uc (rbs)) - rnat_loc = IA64_LOC_UC_ADDR (rnat_addr, 0); - else - rnat_loc = IA64_LOC_ADDR (rnat_addr, 0); - } - else - rnat_loc = rbs->rnat_loc; - return rnat_loc; -} - -static inline ia64_loc_t -rbs_loc (struct rbs_area *rbs, unw_word_t bsp) -{ - if (rbs_on_uc (rbs)) - return IA64_LOC_UC_ADDR (bsp, 0); - else - return IA64_LOC_ADDR (bsp, 0); -} - -static inline int -ia64_get_stacked (struct cursor *c, unw_word_t reg, - ia64_loc_t *locp, ia64_loc_t *rnat_locp) -{ - struct rbs_area *rbs = c->rbs_area + c->rbs_curr; - unw_word_t addr, regs_to_skip = reg - 32; - int ret = 0; - - assert (reg >= 32 && reg < 128); - - addr = rse_skip_regs (c->bsp, regs_to_skip); - if (locp) - *locp = rbs_loc (rbs, addr); - if (rnat_locp) - *rnat_locp = rbs_get_rnat_loc (rbs, addr); - - if (!rbs_contains (rbs, addr)) - ret = rbs_find_stacked (c, regs_to_skip, locp, rnat_locp); - return ret; -} - -/* The UNaT slot # calculation is identical to the one for RNaT slots, - but for readability/clarity, we don't want to use - ia64_rnat_slot_num() directly. */ -#define ia64_unat_slot_num(addr) rse_slot_num(addr) - -/* The following are helper macros which makes it easier for libunwind - to be used in the kernel. They allow the kernel to optimize away - any unused code without littering everything with #ifdefs. */ -#define ia64_is_big_endian(c) ((c)->as->big_endian) -#define ia64_get_abi(c) ((c)->as->abi) -#define ia64_set_abi(c, v) ((c)->as->abi = (v)) -#define ia64_get_abi_marker(c) ((c)->last_abi_marker) - -/* XXX should be in glibc: */ -#ifndef IA64_SC_FLAG_ONSTACK -# define IA64_SC_FLAG_ONSTACK_BIT 0 /* running on signal stack? */ -# define IA64_SC_FLAG_IN_SYSCALL_BIT 1 /* did signal interrupt a syscall? */ -# define IA64_SC_FLAG_FPH_VALID_BIT 2 /* is state in f[32]-f[127] valid? */ - -# define IA64_SC_FLAG_ONSTACK (1 << IA64_SC_FLAG_ONSTACK_BIT) -# define IA64_SC_FLAG_IN_SYSCALL (1 << IA64_SC_FLAG_IN_SYSCALL_BIT) -# define IA64_SC_FLAG_FPH_VALID (1 << IA64_SC_FLAG_FPH_VALID_BIT) -#endif - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/libunwind-generic.pc.in b/src/coreclr/src/pal/src/libunwind/src/libunwind-generic.pc.in deleted file mode 100644 index 1f3baffe5bd147..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/libunwind-generic.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libunwind-generic -Description: libunwind generic library -Version: @VERSION@ -Requires: libunwind -Libs: -L${libdir} -lunwind-generic -Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gdestroy_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gdestroy_addr_space.c deleted file mode 100644 index 504558e1a7880c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gdestroy_addr_space.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -void -unw_destroy_addr_space (unw_addr_space_t as) -{ -#ifndef UNW_LOCAL_ONLY -# if UNW_DEBUG - memset (as, 0, sizeof (*as)); -# endif - free (as); -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-extract.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-extract.c deleted file mode 100644 index 5f7682e650d794..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-extract.c +++ /dev/null @@ -1,64 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -HIDDEN int -unwi_extract_dynamic_proc_info (unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, unw_dyn_info_t *di, - int need_unwind_info, void *arg) -{ - pi->start_ip = di->start_ip; - pi->end_ip = di->end_ip; - pi->gp = di->gp; - pi->format = di->format; - switch (di->format) - { - case UNW_INFO_FORMAT_DYNAMIC: - pi->handler = di->u.pi.handler; - pi->lsda = 0; - pi->flags = di->u.pi.flags; - pi->unwind_info_size = 0; - if (need_unwind_info) - pi->unwind_info = di; - else - pi->unwind_info = NULL; - return 0; - - case UNW_INFO_FORMAT_TABLE: - case UNW_INFO_FORMAT_REMOTE_TABLE: - case UNW_INFO_FORMAT_ARM_EXIDX: - case UNW_INFO_FORMAT_IP_OFFSET: -#ifdef tdep_search_unwind_table - /* call platform-specific search routine: */ - return tdep_search_unwind_table (as, ip, di, pi, need_unwind_info, arg); -#else - /* fall through */ -#endif - default: - break; - } - return -UNW_EINVAL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-remote.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-remote.c deleted file mode 100644 index 40a5ad8b5aba41..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-remote.c +++ /dev/null @@ -1,326 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "libunwind_i.h" -#include "remote.h" - -static void -free_regions (unw_dyn_region_info_t *region) -{ - if (region->next) - free_regions (region->next); - free (region); -} - -static int -intern_op (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, - unw_dyn_op_t *op, void *arg) -{ - int ret; - - if ((ret = fetch8 (as, a, addr, &op->tag, arg)) < 0 - || (ret = fetch8 (as, a, addr, &op->qp, arg)) < 0 - || (ret = fetch16 (as, a, addr, &op->reg, arg)) < 0 - || (ret = fetch32 (as, a, addr, &op->when, arg)) < 0 - || (ret = fetchw (as, a, addr, &op->val, arg)) < 0) - return ret; - return 0; -} - -static int -intern_regions (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, unw_dyn_region_info_t **regionp, void *arg) -{ - uint32_t insn_count, op_count, i; - unw_dyn_region_info_t *region; - unw_word_t next_addr; - int ret; - - *regionp = NULL; - - if (!*addr) - return 0; /* NULL region-list */ - - if ((ret = fetchw (as, a, addr, &next_addr, arg)) < 0 - || (ret = fetch32 (as, a, addr, (int32_t *) &insn_count, arg)) < 0 - || (ret = fetch32 (as, a, addr, (int32_t *) &op_count, arg)) < 0) - return ret; - - region = calloc (1, _U_dyn_region_info_size (op_count)); - if (!region) - { - ret = -UNW_ENOMEM; - goto out; - } - - region->insn_count = insn_count; - region->op_count = op_count; - for (i = 0; i < op_count; ++i) - if ((ret = intern_op (as, a, addr, region->op + i, arg)) < 0) - goto out; - - if (next_addr) - if ((ret = intern_regions (as, a, &next_addr, ®ion->next, arg)) < 0) - goto out; - - *regionp = region; - return 0; - - out: - if (region) - free_regions (region); - return ret; -} - -static int -intern_array (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, unw_word_t table_len, unw_word_t **table_data, - void *arg) -{ - unw_word_t i, *data = calloc (table_len, WSIZE); - int ret = 0; - - if (!data) - { - ret = -UNW_ENOMEM; - goto out; - } - - for (i = 0; i < table_len; ++i) - if (fetchw (as, a, addr, data + i, arg) < 0) - goto out; - - *table_data = data; - return 0; - - out: - if (data) - free (data); - return ret; -} - -static void -free_dyn_info (unw_dyn_info_t *di) -{ - switch (di->format) - { - case UNW_INFO_FORMAT_DYNAMIC: - if (di->u.pi.regions) - { - free_regions (di->u.pi.regions); - di->u.pi.regions = NULL; - } - break; - - case UNW_INFO_FORMAT_TABLE: - if (di->u.ti.table_data) - { - free (di->u.ti.table_data); - di->u.ti.table_data = NULL; - } - break; - - case UNW_INFO_FORMAT_REMOTE_TABLE: - default: - break; - } -} - -static int -intern_dyn_info (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t *addr, unw_dyn_info_t *di, void *arg) -{ - unw_word_t first_region; - int ret; - - switch (di->format) - { - case UNW_INFO_FORMAT_DYNAMIC: - if ((ret = fetchw (as, a, addr, &di->u.pi.name_ptr, arg)) < 0 - || (ret = fetchw (as, a, addr, &di->u.pi.handler, arg)) < 0 - || (ret = fetch32 (as, a, addr, - (int32_t *) &di->u.pi.flags, arg)) < 0) - goto out; - *addr += 4; /* skip over pad0 */ - if ((ret = fetchw (as, a, addr, &first_region, arg)) < 0 - || (ret = intern_regions (as, a, &first_region, &di->u.pi.regions, - arg)) < 0) - goto out; - break; - - case UNW_INFO_FORMAT_TABLE: - if ((ret = fetchw (as, a, addr, &di->u.ti.name_ptr, arg)) < 0 - || (ret = fetchw (as, a, addr, &di->u.ti.segbase, arg)) < 0 - || (ret = fetchw (as, a, addr, &di->u.ti.table_len, arg)) < 0 - || (ret = intern_array (as, a, addr, di->u.ti.table_len, - &di->u.ti.table_data, arg)) < 0) - goto out; - break; - - case UNW_INFO_FORMAT_REMOTE_TABLE: - if ((ret = fetchw (as, a, addr, &di->u.rti.name_ptr, arg)) < 0 - || (ret = fetchw (as, a, addr, &di->u.rti.segbase, arg)) < 0 - || (ret = fetchw (as, a, addr, &di->u.rti.table_len, arg)) < 0 - || (ret = fetchw (as, a, addr, &di->u.rti.table_data, arg)) < 0) - goto out; - break; - - default: - ret = -UNW_ENOINFO; - goto out; - } - return 0; - - out: - free_dyn_info (di); - return ret; -} - -HIDDEN int -unwi_dyn_remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, - int need_unwind_info, void *arg) -{ - unw_accessors_t *a = unw_get_accessors_int (as); - unw_word_t dyn_list_addr, addr, next_addr, gen1, gen2, start_ip, end_ip; - unw_dyn_info_t *di = NULL; - int ret; - - if (as->dyn_info_list_addr) - dyn_list_addr = as->dyn_info_list_addr; - else - { - if ((*a->get_dyn_info_list_addr) (as, &dyn_list_addr, arg) < 0) - return -UNW_ENOINFO; - if (as->caching_policy != UNW_CACHE_NONE) - as->dyn_info_list_addr = dyn_list_addr; - } - - do - { - addr = dyn_list_addr; - - ret = -UNW_ENOINFO; - - if (fetchw (as, a, &addr, &gen1, arg) < 0 - || fetchw (as, a, &addr, &next_addr, arg) < 0) - return ret; - - for (addr = next_addr; addr != 0; addr = next_addr) - { - if (fetchw (as, a, &addr, &next_addr, arg) < 0) - goto recheck; /* only fail if generation # didn't change */ - - addr += WSIZE; /* skip over prev_addr */ - - if (fetchw (as, a, &addr, &start_ip, arg) < 0 - || fetchw (as, a, &addr, &end_ip, arg) < 0) - goto recheck; /* only fail if generation # didn't change */ - - if (ip >= start_ip && ip < end_ip) - { - if (!di) - di = calloc (1, sizeof (*di)); - - di->start_ip = start_ip; - di->end_ip = end_ip; - - if (fetchw (as, a, &addr, &di->gp, arg) < 0 - || fetch32 (as, a, &addr, &di->format, arg) < 0) - goto recheck; /* only fail if generation # didn't change */ - - addr += 4; /* skip over padding */ - - if (need_unwind_info - && intern_dyn_info (as, a, &addr, di, arg) < 0) - goto recheck; /* only fail if generation # didn't change */ - - if (unwi_extract_dynamic_proc_info (as, ip, pi, di, - need_unwind_info, arg) < 0) - { - free_dyn_info (di); - goto recheck; /* only fail if generation # didn't change */ - } - ret = 0; /* OK, found it */ - break; - } - } - - /* Re-check generation number to ensure the data we have is - consistent. */ - recheck: - addr = dyn_list_addr; - if (fetchw (as, a, &addr, &gen2, arg) < 0) - return ret; - } - while (gen1 != gen2); - - if (ret < 0 && di) - free (di); - - return ret; -} - -HIDDEN void -unwi_dyn_remote_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, - void *arg) -{ - if (!pi->unwind_info) - return; - - free_dyn_info (pi->unwind_info); - free (pi->unwind_info); - pi->unwind_info = NULL; -} - -/* Returns 1 if the cache is up-to-date or -1 if the cache contained - stale data and had to be flushed. */ - -HIDDEN int -unwi_dyn_validate_cache (unw_addr_space_t as, void *arg) -{ - unw_word_t addr, gen; - unw_accessors_t *a; - - if (!as->dyn_info_list_addr) - /* If we don't have the dyn_info_list_addr, we don't have anything - in the cache. */ - return 0; - - a = unw_get_accessors_int (as); - addr = as->dyn_info_list_addr; - - if (fetchw (as, a, &addr, &gen, arg) < 0) - return 1; - - if (gen == as->dyn_generation) - return 1; - - unw_flush_cache (as, 0, 0); - as->dyn_generation = gen; - return -1; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c deleted file mode 100644 index 98d35012861cf6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c +++ /dev/null @@ -1,91 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -static inline int -local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, - int need_unwind_info, void *arg) -{ - return -UNW_ENOINFO; -} - -#else /* !UNW_REMOTE_ONLY */ - -static inline int -local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, - int need_unwind_info, void *arg) -{ - unw_dyn_info_list_t *list; - unw_dyn_info_t *di; - -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - - list = (unw_dyn_info_list_t *) (uintptr_t) _U_dyn_info_list_addr (); - for (di = list->first; di; di = di->next) - if (ip >= di->start_ip && ip < di->end_ip) - return unwi_extract_dynamic_proc_info (as, ip, pi, di, need_unwind_info, - arg); - return -UNW_ENOINFO; -} - -#endif /* !UNW_REMOTE_ONLY */ - -#ifdef UNW_LOCAL_ONLY - -static inline int -remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, - int need_unwind_info, void *arg) -{ - return -UNW_ENOINFO; -} - -#else /* !UNW_LOCAL_ONLY */ - -static inline int -remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, - int need_unwind_info, void *arg) -{ - return unwi_dyn_remote_find_proc_info (as, ip, pi, need_unwind_info, arg); -} - -#endif /* !UNW_LOCAL_ONLY */ - -HIDDEN int -unwi_find_dynamic_proc_info (unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, int need_unwind_info, - void *arg) -{ - if (as == unw_local_addr_space) - return local_find_proc_info (as, ip, pi, need_unwind_info, arg); - else - return remote_find_proc_info (as, ip, pi, need_unwind_info, arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_accessors.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_accessors.c deleted file mode 100644 index 31a6fbaf02f09e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_accessors.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002, 2004-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -HIDDEN ALIAS(unw_get_accessors) unw_accessors_t * -unw_get_accessors_int (unw_addr_space_t as); - -unw_accessors_t * -unw_get_accessors (unw_addr_space_t as) -{ - if (!tdep_init_done) - tdep_init (); - return &as->acc; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_fpreg.c deleted file mode 100644 index f32b12862573b9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_fpreg.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_get_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t *valp) -{ - struct cursor *c = (struct cursor *) cursor; - - return tdep_access_fpreg (c, regnum, valp, 0); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_info_by_ip.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_info_by_ip.c deleted file mode 100644 index 2697ff84e79c33..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_info_by_ip.c +++ /dev/null @@ -1,39 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_get_proc_info_by_ip (unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, void *as_arg) -{ - unw_accessors_t *a = unw_get_accessors_int (as); - int ret; - - ret = unwi_find_dynamic_proc_info (as, ip, pi, 0, as_arg); - if (ret == -UNW_ENOINFO) - ret = (*a->find_proc_info) (as, ip, pi, 0, as_arg); - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c deleted file mode 100644 index 840d9007f4c1d7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c +++ /dev/null @@ -1,118 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" -#include "remote.h" - -static inline int -intern_string (unw_addr_space_t as, unw_accessors_t *a, - unw_word_t addr, char *buf, size_t buf_len, void *arg) -{ - size_t i; - int ret; - - for (i = 0; i < buf_len; ++i) - { - if ((ret = fetch8 (as, a, &addr, (int8_t *) buf + i, arg)) < 0) - return ret; - - if (buf[i] == '\0') - return 0; /* copied full string; return success */ - } - buf[buf_len - 1] = '\0'; /* ensure string is NUL terminated */ - return -UNW_ENOMEM; -} - -static inline int -get_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, void *arg) -{ - unw_accessors_t *a = unw_get_accessors_int (as); - unw_proc_info_t pi; - int ret; - - buf[0] = '\0'; /* always return a valid string, even if it's empty */ - - ret = unwi_find_dynamic_proc_info (as, ip, &pi, 1, arg); - if (ret == 0) - { - unw_dyn_info_t *di = pi.unwind_info; - - if (offp) - *offp = ip - pi.start_ip; - - switch (di->format) - { - case UNW_INFO_FORMAT_DYNAMIC: - ret = intern_string (as, a, di->u.pi.name_ptr, buf, buf_len, arg); - break; - - case UNW_INFO_FORMAT_TABLE: - case UNW_INFO_FORMAT_REMOTE_TABLE: - /* XXX should we create a fake name, e.g.: "tablenameN", - where N is the index of the function in the table??? */ - ret = -UNW_ENOINFO; - break; - - default: - ret = -UNW_EINVAL; - break; - } - unwi_put_dynamic_unwind_info (as, &pi, arg); - return ret; - } - - if (ret != -UNW_ENOINFO) - return ret; - - /* not a dynamic procedure, try to lookup static procedure name: */ - - if (a->get_proc_name) - return (*a->get_proc_name) (as, ip, buf, buf_len, offp, arg); - - return -UNW_ENOINFO; -} - -int -unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len, - unw_word_t *offp) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t ip; - int error; - - ip = tdep_get_ip (c); -#if !defined(__ia64__) - if (c->dwarf.use_prev_instr) - --ip; -#endif - error = get_proc_name (tdep_get_as (c), ip, buf, buf_len, offp, - tdep_get_as_arg (c)); -#if !defined(__ia64__) - if (c->dwarf.use_prev_instr && offp != NULL && error == 0) - *offp += 1; -#endif - return error; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_reg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_reg.c deleted file mode 100644 index 9fc725c9c8e205..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_reg.c +++ /dev/null @@ -1,41 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp) -{ - struct cursor *c = (struct cursor *) cursor; - - // We can get the IP value directly without needing a lookup. - if (regnum == UNW_REG_IP) - { - *valp = tdep_get_ip (c); - return 0; - } - - return tdep_access_reg (c, regnum, valp, 0); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gput_dynamic_unwind_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gput_dynamic_unwind_info.c deleted file mode 100644 index ca377c98a8c489..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gput_dynamic_unwind_info.c +++ /dev/null @@ -1,55 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -HIDDEN void -unwi_put_dynamic_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, - void *arg) -{ - switch (pi->format) - { - case UNW_INFO_FORMAT_DYNAMIC: -#ifndef UNW_LOCAL_ONLY -# ifdef UNW_REMOTE_ONLY - unwi_dyn_remote_put_unwind_info (as, pi, arg); -# else - if (as != unw_local_addr_space) - unwi_dyn_remote_put_unwind_info (as, pi, arg); -# endif -#endif - break; - - case UNW_INFO_FORMAT_TABLE: - case UNW_INFO_FORMAT_REMOTE_TABLE: -#ifdef tdep_put_unwind_info - tdep_put_unwind_info (as, pi, arg); - break; -#endif - /* fall through */ - default: - break; - } -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_cache_size.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_cache_size.c deleted file mode 100644 index 07b282e2c1dce2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_cache_size.c +++ /dev/null @@ -1,72 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2014 - Contributed by Milian Wolff - and Dave Watson - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_set_cache_size (unw_addr_space_t as, size_t size, int flag) -{ - size_t power = 1; - unsigned short log_size = 0; - - if (!tdep_init_done) - tdep_init (); - - if (flag != 0) - return -1; - - /* Currently not supported for per-thread cache due to memory leak */ - /* A pthread-key destructor would work, but is not signal safe */ -#if defined(HAVE___THREAD) && HAVE___THREAD - return -1; -#endif - - /* Round up to next power of two, slowly but portably */ - while(power < size) - { - power *= 2; - log_size++; - /* Largest size currently supported by rs_cache */ - if (log_size >= 15) - break; - } - -#if !defined(__ia64__) - if (log_size == as->global_cache.log_size) - return 0; /* no change */ - - as->global_cache.log_size = log_size; -#endif - - /* Ensure caches are empty (and initialized). */ - unw_flush_cache (as, 0, 0); -#ifdef __ia64__ - return 0; -#else - /* Synchronously purge cache, to ensure memory is allocated */ - return dwarf_flush_rs_cache(&as->global_cache); -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_caching_policy.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_caching_policy.c deleted file mode 100644 index aa3d237146e7a8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_caching_policy.c +++ /dev/null @@ -1,46 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_set_caching_policy (unw_addr_space_t as, unw_caching_policy_t policy) -{ - if (!tdep_init_done) - tdep_init (); - -#if !(defined(HAVE___THREAD) && HAVE___THREAD) - if (policy == UNW_CACHE_PER_THREAD) - policy = UNW_CACHE_GLOBAL; -#endif - - if (policy == as->caching_policy) - return 0; /* no change */ - - as->caching_policy = policy; - /* Ensure caches are empty (and initialized). */ - unw_flush_cache (as, 0, 0); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_fpreg.c deleted file mode 100644 index 8c37afd2267117..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_fpreg.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_set_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t val) -{ - struct cursor *c = (struct cursor *) cursor; - - return tdep_access_fpreg (c, regnum, &val, 1); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_reg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_reg.c deleted file mode 100644 index b1b17703370744..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_reg.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_set_reg (unw_cursor_t *cursor, int regnum, unw_word_t valp) -{ - struct cursor *c = (struct cursor *) cursor; - - return tdep_access_reg (c, regnum, &valp, 1); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Ldestroy_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mi/Ldestroy_addr_space.c deleted file mode 100644 index 5bf9364bc73cd0..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Ldestroy_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gdestroy_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-extract.c b/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-extract.c deleted file mode 100644 index 1802f865f77d30..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-extract.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gdyn-extract.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-remote.c b/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-remote.c deleted file mode 100644 index 260722a04b2d90..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gdyn-remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lfind_dynamic_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lfind_dynamic_proc_info.c deleted file mode 100644 index bc88e1c53f06ce..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lfind_dynamic_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gfind_dynamic_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_accessors.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_accessors.c deleted file mode 100644 index 555e37f30da65e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_accessors.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_accessors.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_fpreg.c deleted file mode 100644 index e3be4414378799..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_fpreg.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_fpreg.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_info_by_ip.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_info_by_ip.c deleted file mode 100644 index 96910d83e45e1c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_info_by_ip.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info_by_ip.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_name.c deleted file mode 100644 index 378097b57a0288..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_name.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_name.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_reg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_reg.c deleted file mode 100644 index effe8a8063531a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_reg.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_reg.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lput_dynamic_unwind_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lput_dynamic_unwind_info.c deleted file mode 100644 index 99597cd5fac12b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lput_dynamic_unwind_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gput_dynamic_unwind_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_cache_size.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_cache_size.c deleted file mode 100644 index 670f64d3a9fea1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_cache_size.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gset_cache_size.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_caching_policy.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_caching_policy.c deleted file mode 100644 index cc18816b377126..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_caching_policy.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gset_caching_policy.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_fpreg.c deleted file mode 100644 index 2497d404f4657c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_fpreg.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gset_fpreg.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_reg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_reg.c deleted file mode 100644 index c7a872b016fb4b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_reg.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gset_reg.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/_ReadSLEB.c b/src/coreclr/src/pal/src/libunwind/src/mi/_ReadSLEB.c deleted file mode 100644 index c041e37a0543f0..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/_ReadSLEB.c +++ /dev/null @@ -1,25 +0,0 @@ -#include - -unw_word_t -_ReadSLEB (unsigned char **dpp) -{ - unsigned shift = 0; - unw_word_t byte, result = 0; - unsigned char *bp = *dpp; - - while (1) - { - byte = *bp++; - result |= (byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) - break; - } - - if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0) - /* sign-extend negative value */ - result |= ((unw_word_t) -1) << shift; - - *dpp = bp; - return result; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/_ReadULEB.c b/src/coreclr/src/pal/src/libunwind/src/mi/_ReadULEB.c deleted file mode 100644 index 116f3e19bc9503..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/_ReadULEB.c +++ /dev/null @@ -1,20 +0,0 @@ -#include - -unw_word_t -_ReadULEB (unsigned char **dpp) -{ - unsigned shift = 0; - unw_word_t byte, result = 0; - unsigned char *bp = *dpp; - - while (1) - { - byte = *bp++; - result |= (byte & 0x7f) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - *dpp = bp; - return result; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c b/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c deleted file mode 100644 index c7aa2bdcdcbf0d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c +++ /dev/null @@ -1,81 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -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 UNW_REMOTE_ONLY - -#define UNW_LOCAL_ONLY -#include -#include -#include - -/* See glibc manual for a description of this function. */ - -static ALWAYS_INLINE int -slow_backtrace (void **buffer, int size, unw_context_t *uc) -{ - unw_cursor_t cursor; - unw_word_t ip; - int n = 0; - - if (unlikely (unw_init_local (&cursor, uc) < 0)) - return 0; - - while (unw_step (&cursor) > 0) - { - if (n >= size) - return n; - - if (unw_get_reg (&cursor, UNW_REG_IP, &ip) < 0) - return n; - buffer[n++] = (void *) (uintptr_t) ip; - } - return n; -} - -int -unw_backtrace (void **buffer, int size) -{ - unw_cursor_t cursor; - unw_context_t uc; - int n = size; - - tdep_getcontext_trace (&uc); - - if (unlikely (unw_init_local (&cursor, &uc) < 0)) - return 0; - - if (unlikely (tdep_trace (&cursor, buffer, &n) < 0)) - { - unw_getcontext (&uc); - return slow_backtrace (buffer, size, &uc); - } - - return n; -} - -extern int backtrace (void **buffer, int size) - WEAK ALIAS(unw_backtrace); - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/dyn-cancel.c b/src/coreclr/src/pal/src/libunwind/src/mi/dyn-cancel.c deleted file mode 100644 index 9d7472d5fdfb6c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/dyn-cancel.c +++ /dev/null @@ -1,46 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -void -_U_dyn_cancel (unw_dyn_info_t *di) -{ - mutex_lock (&_U_dyn_info_list_lock); - { - ++_U_dyn_info_list.generation; - - if (di->prev) - di->prev->next = di->next; - else - _U_dyn_info_list.first = di->next; - - if (di->next) - di->next->prev = di->prev; - } - mutex_unlock (&_U_dyn_info_list_lock); - - di->next = di->prev = NULL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/dyn-info-list.c b/src/coreclr/src/pal/src/libunwind/src/mi/dyn-info-list.c deleted file mode 100644 index 1c7c55090a6711..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/dyn-info-list.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -unw_word_t -_U_dyn_info_list_addr (void) -{ - return (unw_word_t) (uintptr_t) &_U_dyn_info_list; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/dyn-register.c b/src/coreclr/src/pal/src/libunwind/src/mi/dyn-register.c deleted file mode 100644 index efdad3de076be8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/dyn-register.c +++ /dev/null @@ -1,44 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -HIDDEN define_lock (_U_dyn_info_list_lock); - -void -_U_dyn_register (unw_dyn_info_t *di) -{ - mutex_lock (&_U_dyn_info_list_lock); - { - ++_U_dyn_info_list.generation; - - di->next = _U_dyn_info_list.first; - di->prev = NULL; - if (di->next) - di->next->prev = di; - _U_dyn_info_list.first = di; - } - mutex_unlock (&_U_dyn_info_list_lock); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c b/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c deleted file mode 100644 index cbd93e1a11cff8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c +++ /dev/null @@ -1,59 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -void -unw_flush_cache (unw_addr_space_t as, unw_word_t lo, unw_word_t hi) -{ -#if !UNW_TARGET_IA64 - struct unw_debug_frame_list *w = as->debug_frames; -#endif - - /* clear dyn_info_list_addr cache: */ - as->dyn_info_list_addr = 0; - -#if !UNW_TARGET_IA64 - for (; w; w = w->next) - { - if (w->index) - free (w->index); - free (w->debug_frame); - } - as->debug_frames = NULL; -#endif - - /* This lets us flush caches lazily. The implementation currently - ignores the flush range arguments (lo-hi). This is OK because - unw_flush_cache() is allowed to flush more than the requested - range. */ - -#ifdef HAVE_FETCH_AND_ADD - fetch_and_add1 (&as->cache_generation); -#else -# warning unw_flush_cache(): need a way to atomically increment an integer. - ++as->cache_generation; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/init.c b/src/coreclr/src/pal/src/libunwind/src/mi/init.c deleted file mode 100644 index 60a48c58928aa7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/init.c +++ /dev/null @@ -1,60 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -HIDDEN intrmask_t unwi_full_mask; - -static const char rcsid[] UNUSED = - "$Id: " PACKAGE_STRING " --- report bugs to " PACKAGE_BUGREPORT " $"; - -#if UNW_DEBUG - -/* Must not be declared HIDDEN because libunwind.so and - libunwind-PLATFORM.so will both define their own copies of this - variable and we want to use only one or the other when both - libraries are loaded. */ -long unwi_debug_level; - -#endif /* UNW_DEBUG */ - -HIDDEN void -mi_init (void) -{ -#if UNW_DEBUG - const char *str = getenv ("UNW_DEBUG_LEVEL"); - - if (str) - unwi_debug_level = atoi (str); - - if (unwi_debug_level > 0) - { - setbuf (stdout, NULL); - setbuf (stderr, NULL); - } -#endif - - assert (sizeof (struct cursor) <= sizeof (unw_cursor_t)); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/mempool.c b/src/coreclr/src/pal/src/libunwind/src/mi/mempool.c deleted file mode 100644 index 536b64e815760e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/mempool.c +++ /dev/null @@ -1,184 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2003, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -/* From GCC docs: ``Gcc also provides a target specific macro - * __BIGGEST_ALIGNMENT__, which is the largest alignment ever used for any data - * type on the target machine you are compiling for.'' */ -#ifdef __BIGGEST_ALIGNMENT__ -# define MAX_ALIGN __BIGGEST_ALIGNMENT__ -#else -/* Crude hack to check that MAX_ALIGN is power-of-two. - * sizeof(long double) = 12 on i386. */ -# define MAX_ALIGN_(n) (n < 8 ? 8 : \ - n < 16 ? 16 : n) -# define MAX_ALIGN MAX_ALIGN_(sizeof (long double)) -#endif - -static char sos_memory[SOS_MEMORY_SIZE] ALIGNED(MAX_ALIGN); -static size_t sos_memory_freepos; -static size_t pg_size; - -HIDDEN void * -sos_alloc (size_t size) -{ - size_t pos; - - size = UNW_ALIGN(size, MAX_ALIGN); - -#if defined(__GNUC__) && defined(HAVE_FETCH_AND_ADD) - /* Assume `sos_memory' is suitably aligned. */ - assert(((uintptr_t) &sos_memory[0] & (MAX_ALIGN-1)) == 0); - - pos = fetch_and_add (&sos_memory_freepos, size); -#else - static define_lock (sos_lock); - intrmask_t saved_mask; - - lock_acquire (&sos_lock, saved_mask); - { - /* No assumptions about `sos_memory' alignment. */ - if (sos_memory_freepos == 0) - { - unsigned align = UNW_ALIGN((uintptr_t) &sos_memory[0], MAX_ALIGN) - - (uintptr_t) &sos_memory[0]; - sos_memory_freepos = align; - } - pos = sos_memory_freepos; - sos_memory_freepos += size; - } - lock_release (&sos_lock, saved_mask); -#endif - - assert (((uintptr_t) &sos_memory[pos] & (MAX_ALIGN-1)) == 0); - assert ((pos+size) <= SOS_MEMORY_SIZE); - - return &sos_memory[pos]; -} - -/* Must be called while holding the mempool lock. */ - -static void -free_object (struct mempool *pool, void *object) -{ - struct object *obj = object; - - obj->next = pool->free_list; - pool->free_list = obj; - ++pool->num_free; -} - -static void -add_memory (struct mempool *pool, char *mem, size_t size, size_t obj_size) -{ - char *obj; - - for (obj = mem; obj <= mem + size - obj_size; obj += obj_size) - free_object (pool, obj); -} - -static void -expand (struct mempool *pool) -{ - size_t size; - char *mem; - - size = pool->chunk_size; - GET_MEMORY (mem, size); - if (!mem) - { - size = UNW_ALIGN(pool->obj_size, pg_size); - GET_MEMORY (mem, size); - if (!mem) - { - /* last chance: try to allocate one object from the SOS memory */ - size = pool->obj_size; - mem = sos_alloc (size); - } - } - add_memory (pool, mem, size, pool->obj_size); -} - -HIDDEN void -mempool_init (struct mempool *pool, size_t obj_size, size_t reserve) -{ - if (pg_size == 0) - pg_size = getpagesize (); - - memset (pool, 0, sizeof (*pool)); - - lock_init (&pool->lock); - - /* round object-size up to integer multiple of MAX_ALIGN */ - obj_size = UNW_ALIGN(obj_size, MAX_ALIGN); - - if (!reserve) - { - reserve = pg_size / obj_size / 4; - if (!reserve) - reserve = 16; - } - - pool->obj_size = obj_size; - pool->reserve = reserve; - pool->chunk_size = UNW_ALIGN(2*reserve*obj_size, pg_size); - - expand (pool); -} - -HIDDEN void * -mempool_alloc (struct mempool *pool) -{ - intrmask_t saved_mask; - struct object *obj; - - lock_acquire (&pool->lock, saved_mask); - { - if (pool->num_free <= pool->reserve) - expand (pool); - - assert (pool->num_free > 0); - - --pool->num_free; - obj = pool->free_list; - pool->free_list = obj->next; - } - lock_release (&pool->lock, saved_mask); - return obj; -} - -HIDDEN void -mempool_free (struct mempool *pool, void *object) -{ - intrmask_t saved_mask; - - lock_acquire (&pool->lock, saved_mask); - { - free_object (pool, object); - } - lock_release (&pool->lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/strerror.c b/src/coreclr/src/pal/src/libunwind/src/mi/strerror.c deleted file mode 100644 index 2cec73d1db9000..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mi/strerror.c +++ /dev/null @@ -1,51 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 BEA Systems - Contributed by Thomas Hallgren - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -/* Returns the text corresponding to the given err_code or the - text "invalid error code" if the err_code is invalid. */ -const char * -unw_strerror (int err_code) -{ - const char *cp; - unw_error_t error = (unw_error_t)-err_code; - switch (error) - { - case UNW_ESUCCESS: cp = "no error"; break; - case UNW_EUNSPEC: cp = "unspecified (general) error"; break; - case UNW_ENOMEM: cp = "out of memory"; break; - case UNW_EBADREG: cp = "bad register number"; break; - case UNW_EREADONLYREG: cp = "attempt to write read-only register"; break; - case UNW_ESTOPUNWIND: cp = "stop unwinding"; break; - case UNW_EINVALIDIP: cp = "invalid IP"; break; - case UNW_EBADFRAME: cp = "bad frame"; break; - case UNW_EINVAL: cp = "unsupported operation or bad value"; break; - case UNW_EBADVERSION: cp = "unwind info has unsupported version"; break; - case UNW_ENOINFO: cp = "no unwind info found"; break; - default: cp = "invalid error code"; - } - return cp; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c deleted file mode 100644 index 493d03db662b94..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c +++ /dev/null @@ -1,66 +0,0 @@ -/* 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. */ - -#include - -#include "unwind_i.h" - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* - * MIPS supports only big or little-endian, not weird stuff like - * PDP_ENDIAN. - */ - if (byte_order != 0 - && byte_order != __LITTLE_ENDIAN - && byte_order != __BIG_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - if (byte_order == 0) - /* use host default: */ - as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); - else - as->big_endian = (byte_order == __BIG_ENDIAN); - - /* FIXME! There is no way to specify the ABI. */ - as->abi = UNW_MIPS_ABI_O32; - as->addr_size = 4; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c deleted file mode 100644 index 7b84be87b917db..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c +++ /dev/null @@ -1,41 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - /* We can only unwind using Dwarf into on MIPS: return failure code - if it's not present. */ - ret = dwarf_make_proc_info (&c->dwarf); - if (ret < 0) - return ret; - - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_save_loc.c deleted file mode 100644 index c21f9b06d060a1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_save_loc.c +++ /dev/null @@ -1,100 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -/* FIXME for MIPS. */ - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - struct cursor *c = (struct cursor *) cursor; - dwarf_loc_t loc; - - loc = DWARF_NULL_LOC; /* default to "not saved" */ - - switch (reg) - { - case UNW_MIPS_R0: - case UNW_MIPS_R1: - case UNW_MIPS_R2: - case UNW_MIPS_R3: - case UNW_MIPS_R4: - case UNW_MIPS_R5: - case UNW_MIPS_R6: - case UNW_MIPS_R7: - case UNW_MIPS_R8: - case UNW_MIPS_R9: - case UNW_MIPS_R10: - case UNW_MIPS_R11: - case UNW_MIPS_R12: - case UNW_MIPS_R13: - case UNW_MIPS_R14: - case UNW_MIPS_R15: - case UNW_MIPS_R16: - case UNW_MIPS_R17: - case UNW_MIPS_R18: - case UNW_MIPS_R19: - case UNW_MIPS_R20: - case UNW_MIPS_R21: - case UNW_MIPS_R22: - case UNW_MIPS_R23: - case UNW_MIPS_R24: - case UNW_MIPS_R25: - case UNW_MIPS_R26: - case UNW_MIPS_R27: - case UNW_MIPS_R28: - case UNW_MIPS_R29: - case UNW_MIPS_R30: - case UNW_MIPS_R31: - case UNW_MIPS_PC: - loc = c->dwarf.loc[reg - UNW_MIPS_R0]; - break; - - default: - break; - } - - memset (sloc, 0, sizeof (*sloc)); - - if (DWARF_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (DWARF_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = DWARF_GET_LOC (loc); - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = DWARF_GET_LOC (loc); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gglobal.c deleted file mode 100644 index fa9478eebe7050..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gglobal.c +++ /dev/null @@ -1,55 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" -#include "dwarf_i.h" - -HIDDEN define_lock (mips_lock); -HIDDEN int tdep_init_done; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&mips_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - dwarf_init (); - -#ifndef UNW_REMOTE_ONLY - mips_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&mips_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c deleted file mode 100644 index 3df170c754934f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c +++ /dev/null @@ -1,210 +0,0 @@ -/* 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. */ - -#include -#include - -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -/* Return the address of the 64-bit slot in UC for REG (even for o32, - where registers are 32-bit, the slots are still 64-bit). */ - -static inline void * -uc_addr (ucontext_t *uc, int reg) -{ - if (reg >= UNW_MIPS_R0 && reg < UNW_MIPS_R0 + 32) - return &uc->uc_mcontext.gregs[reg - UNW_MIPS_R0]; - else if (reg == UNW_MIPS_PC) - return &uc->uc_mcontext.pc; - else - return NULL; -} - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) -{ - char *addr = uc_addr (uc, reg); - - if (((reg >= UNW_MIPS_R0 && reg <= UNW_MIPS_R31) || reg == UNW_MIPS_PC) - && tdep_big_endian (unw_local_addr_space) - && unw_local_addr_space->abi == UNW_MIPS_ABI_O32) - addr += 4; - - return addr; -} - -# endif /* UNW_LOCAL_ONLY */ - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ - *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list; - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (write) - { - Debug (16, "mem[%llx] <- %llx\n", (long long) addr, (long long) *val); - *(unw_word_t *) (intptr_t) addr = *val; - } - else - { - *val = *(unw_word_t *) (intptr_t) addr; - Debug (16, "mem[%llx] -> %llx\n", (long long) addr, (long long) *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = arg; - - if (unw_is_fpreg (reg)) - goto badreg; - - Debug (16, "reg = %s\n", unw_regname (reg)); - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - *(unw_word_t *) (intptr_t) addr = (mips_reg_t) *val; - Debug (12, "%s <- %llx\n", unw_regname (reg), (long long) *val); - } - else - { - *val = (mips_reg_t) *(unw_word_t *) (intptr_t) addr; - Debug (12, "%s -> %llx\n", unw_regname (reg), (long long) *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = arg; - unw_fpreg_t *addr; - - if (!unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - *(unw_fpreg_t *) (intptr_t) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) (intptr_t) addr; - Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - - return elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -mips_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); -#if _MIPS_SIM == _ABIO32 - local_addr_space.abi = UNW_MIPS_ABI_O32; -#elif _MIPS_SIM == _ABIN32 - local_addr_space.abi = UNW_MIPS_ABI_N32; -#elif _MIPS_SIM == _ABI64 - local_addr_space.abi = UNW_MIPS_ABI_N64; -#else -# error Unsupported ABI -#endif - local_addr_space.addr_size = sizeof (void *); - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = NULL; /* mips_local_resume? FIXME! */ - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_local.c deleted file mode 100644 index f3153b5ba03b34..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_local.c +++ /dev/null @@ -1,76 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = uc; - return common_init (c, use_prev_instr); -} - -int -unw_init_local(unw_cursor_t *cursor, ucontext_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_remote.c deleted file mode 100644 index 9b8ba5b89def1a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_remote.c +++ /dev/null @@ -1,45 +0,0 @@ -/* 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. */ - -#include "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - c->dwarf.as_arg = as_arg; - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gis_signal_frame.c deleted file mode 100644 index c0e3b98368b056..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gis_signal_frame.c +++ /dev/null @@ -1,78 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2015 Imagination Technologies Limited - 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. */ - -#include "unwind_i.h" -#include - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, w1, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - ip = c->dwarf.ip; - - /* syscall */ - if ((ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0) - return 0; - if ((w1 & 0xffffffff) != 0x0c) - return 0; - - /* li v0, 0x1061 (rt) or li v0, 0x1017 */ - if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) - return 0; - - switch (c->dwarf.as->abi) - { - case UNW_MIPS_ABI_O32: - switch (w0 & 0xffffffff) - { - case 0x24021061: - return 1; - case 0x24021017: - return 2; - default: - return 0; - } - case UNW_MIPS_ABI_N64: - switch (w0 & 0xffffffff) - { - case 0x2402145b: - return 1; - default: - return 0; - } - default: - return 0; - } -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/mips/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c deleted file mode 100644 index 95194022d2be1f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c +++ /dev/null @@ -1,105 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -/* FIXME: The following is probably unfinished and/or at least partly bogus. */ - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - - switch (reg) - { - case UNW_MIPS_R0: - case UNW_MIPS_R1: - case UNW_MIPS_R2: - case UNW_MIPS_R3: - case UNW_MIPS_R4: - case UNW_MIPS_R5: - case UNW_MIPS_R6: - case UNW_MIPS_R7: - case UNW_MIPS_R8: - case UNW_MIPS_R9: - case UNW_MIPS_R10: - case UNW_MIPS_R11: - case UNW_MIPS_R12: - case UNW_MIPS_R13: - case UNW_MIPS_R14: - case UNW_MIPS_R15: - case UNW_MIPS_R16: - case UNW_MIPS_R17: - case UNW_MIPS_R18: - case UNW_MIPS_R19: - case UNW_MIPS_R20: - case UNW_MIPS_R21: - case UNW_MIPS_R22: - case UNW_MIPS_R23: - case UNW_MIPS_R24: - case UNW_MIPS_R25: - case UNW_MIPS_R26: - case UNW_MIPS_R27: - case UNW_MIPS_R28: - case UNW_MIPS_R29: - case UNW_MIPS_R30: - case UNW_MIPS_R31: - loc = c->dwarf.loc[reg - UNW_MIPS_R0]; - break; - - case UNW_MIPS_PC: - if (write) - c->dwarf.ip = *valp; /* update the IP cache */ - loc = c->dwarf.loc[reg]; - break; - - case UNW_MIPS_CFA: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - /* FIXME: IP? Copro & shadow registers? */ - - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -/* FIXME for MIPS. */ - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gresume.c deleted file mode 100644 index cb70abc8c5cc99..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gresume.c +++ /dev/null @@ -1,45 +0,0 @@ -/* 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. */ - -/* FIXME for MIPS. */ - -#include - -#include "unwind_i.h" - -#ifndef UNW_REMOTE_ONLY - -HIDDEN inline int -mips_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ - -int -unw_resume (unw_cursor_t *cursor) -{ - return -UNW_EINVAL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c deleted file mode 100644 index 937136aef1f76c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c +++ /dev/null @@ -1,132 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2015 Imagination Technologies Limited - 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. */ - -#include "unwind_i.h" -#include "offsets.h" - -static int -mips_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t sc_addr, sp_addr = c->dwarf.cfa; - unw_word_t ra, fp; - int ret; - - switch (unw_is_signal_frame (cursor)) { - case 1: - sc_addr = sp_addr + LINUX_SF_TRAMP_SIZE + sizeof (siginfo_t) + - LINUX_UC_MCONTEXT_OFF; - break; - case 2: - sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF; - break; - default: - return -UNW_EUNSPEC; - } - - if (tdep_big_endian(c->dwarf.as)) - sc_addr += 4; - - c->sigcontext_addr = sc_addr; - - /* Update the dwarf cursor. */ - c->dwarf.loc[UNW_MIPS_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); - c->dwarf.loc[UNW_MIPS_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); - c->dwarf.loc[UNW_MIPS_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); - c->dwarf.loc[UNW_MIPS_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); - c->dwarf.loc[UNW_MIPS_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); - c->dwarf.loc[UNW_MIPS_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); - c->dwarf.loc[UNW_MIPS_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); - c->dwarf.loc[UNW_MIPS_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); - c->dwarf.loc[UNW_MIPS_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); - c->dwarf.loc[UNW_MIPS_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); - c->dwarf.loc[UNW_MIPS_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); - c->dwarf.loc[UNW_MIPS_R11] = DWARF_LOC (sc_addr + LINUX_SC_R11_OFF, 0); - c->dwarf.loc[UNW_MIPS_R12] = DWARF_LOC (sc_addr + LINUX_SC_R12_OFF, 0); - c->dwarf.loc[UNW_MIPS_R13] = DWARF_LOC (sc_addr + LINUX_SC_R13_OFF, 0); - c->dwarf.loc[UNW_MIPS_R14] = DWARF_LOC (sc_addr + LINUX_SC_R14_OFF, 0); - c->dwarf.loc[UNW_MIPS_R15] = DWARF_LOC (sc_addr + LINUX_SC_R15_OFF, 0); - c->dwarf.loc[UNW_MIPS_R16] = DWARF_LOC (sc_addr + LINUX_SC_R16_OFF, 0); - c->dwarf.loc[UNW_MIPS_R17] = DWARF_LOC (sc_addr + LINUX_SC_R17_OFF, 0); - c->dwarf.loc[UNW_MIPS_R18] = DWARF_LOC (sc_addr + LINUX_SC_R18_OFF, 0); - c->dwarf.loc[UNW_MIPS_R19] = DWARF_LOC (sc_addr + LINUX_SC_R19_OFF, 0); - c->dwarf.loc[UNW_MIPS_R20] = DWARF_LOC (sc_addr + LINUX_SC_R20_OFF, 0); - c->dwarf.loc[UNW_MIPS_R21] = DWARF_LOC (sc_addr + LINUX_SC_R21_OFF, 0); - c->dwarf.loc[UNW_MIPS_R22] = DWARF_LOC (sc_addr + LINUX_SC_R22_OFF, 0); - c->dwarf.loc[UNW_MIPS_R23] = DWARF_LOC (sc_addr + LINUX_SC_R23_OFF, 0); - c->dwarf.loc[UNW_MIPS_R24] = DWARF_LOC (sc_addr + LINUX_SC_R24_OFF, 0); - c->dwarf.loc[UNW_MIPS_R25] = DWARF_LOC (sc_addr + LINUX_SC_R25_OFF, 0); - c->dwarf.loc[UNW_MIPS_R26] = DWARF_LOC (sc_addr + LINUX_SC_R26_OFF, 0); - c->dwarf.loc[UNW_MIPS_R27] = DWARF_LOC (sc_addr + LINUX_SC_R27_OFF, 0); - c->dwarf.loc[UNW_MIPS_R28] = DWARF_LOC (sc_addr + LINUX_SC_R28_OFF, 0); - c->dwarf.loc[UNW_MIPS_R29] = DWARF_LOC (sc_addr + LINUX_SC_R29_OFF, 0); - c->dwarf.loc[UNW_MIPS_R30] = DWARF_LOC (sc_addr + LINUX_SC_R30_OFF, 0); - c->dwarf.loc[UNW_MIPS_R31] = DWARF_LOC (sc_addr + LINUX_SC_R31_OFF, 0); - c->dwarf.loc[UNW_MIPS_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); - - /* Set SP/CFA and PC/IP. */ - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_MIPS_R29], &c->dwarf.cfa); - - if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_PC_OFF, 0), - &c->dwarf.ip)) < 0) - return ret; - - if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_R31_OFF, 0), - &ra)) < 0) - return ret; - if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_R30_OFF, 0), - &fp)) < 0) - return ret; - - Debug (2, "SH (ip=0x%016llx, ra=0x%016llx, sp=0x%016llx, fp=0x%016llx)\n", - (unsigned long long)c->dwarf.ip, (unsigned long long)ra, - (unsigned long long)c->dwarf.cfa, (unsigned long long)fp); - - c->dwarf.pi_valid = 0; - c->dwarf.use_prev_instr = 0; - - return 1; -} - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - ret = mips_handle_signal_frame (cursor); - if (ret < 0) - /* Not a signal frame, try DWARF-based unwinding. */ - ret = dwarf_step (&c->dwarf); - - if (unlikely (ret == -UNW_ESTOPUNWIND)) - return ret; - - /* Dwarf unwinding didn't work, stop. */ - if (unlikely (ret < 0)) - return 0; - - return (c->dwarf.ip == 0) ? 0 : 1; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lglobal.c deleted file mode 100644 index 6d7b489e14bd9f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Lglobal.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Linit.c b/src/coreclr/src/pal/src/libunwind/src/mips/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/mips/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/mips/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9fa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/elfxx.c b/src/coreclr/src/pal/src/libunwind/src/mips/elfxx.c deleted file mode 100644 index 07d3d12b94fe00..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/elfxx.c +++ /dev/null @@ -1,27 +0,0 @@ -/* 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. */ - -#include "libunwind_i.h" - -#include "../src/elfxx.c" diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/gen-offsets.c b/src/coreclr/src/pal/src/libunwind/src/mips/gen-offsets.c deleted file mode 100644 index 448f6945326543..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/gen-offsets.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include - -#define UC(N,X) \ - printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) - -#define SC(N,X) \ - printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) - -int -main (void) -{ - printf ( -"/* Linux-specific definitions: */\n\n" - -"/* Define various structure offsets to simplify cross-compilation. */\n\n" - -"/* Offsets for MIPS Linux \"ucontext_t\": */\n\n"); - - UC ("FLAGS", uc_flags); - UC ("LINK", uc_link); - UC ("STACK", uc_stack); - UC ("MCONTEXT", uc_mcontext); - UC ("SIGMASK", uc_sigmask); - - UC ("MCONTEXT_GREGS", uc_mcontext.gregs); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/mips/getcontext.S deleted file mode 100644 index d1dbd57932d098..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/getcontext.S +++ /dev/null @@ -1,93 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "offsets.h" -#include - - .text - -#if _MIPS_SIM == _ABIO32 -# if __BYTE_ORDER == __BIG_ENDIAN -# define OFFSET 4 -# else -# define OFFSET 0 -# endif -# define SREG(X) \ - sw $X, (LINUX_UC_MCONTEXT_GREGS + 8 * X + OFFSET) ($4); \ - sra $1, $X, 31; \ - sw $1, (LINUX_UC_MCONTEXT_GREGS + 8 * X + 4 - OFFSET) ($4) -/* Yes, we save the return address to PC. */ -# define SPC \ - sw $31, (LINUX_UC_MCONTEXT_PC + OFFSET) ($4); \ - sra $1, $31, 31; \ - sw $1, (LINUX_UC_MCONTEXT_PC + 4 - OFFSET) ($4) -#else -# define SREG(X) sd $X, (LINUX_UC_MCONTEXT_GREGS + 8 * X) ($4) -# define SPC sd $31, (LINUX_UC_MCONTEXT_PC) ($4) -#endif - - .global _Umips_getcontext - .type _Umips_getcontext, %function - # This is a stub version of getcontext() for MIPS which only stores core - # registers. -_Umips_getcontext: - .set noat - SREG (1) - SREG (0) - SREG (2) - SREG (3) - SREG (4) - SREG (5) - SREG (6) - SREG (7) - SREG (8) - SREG (9) - SREG (10) - SREG (11) - SREG (12) - SREG (13) - SREG (14) - SREG (15) - SREG (16) - SREG (17) - SREG (18) - SREG (19) - SREG (20) - SREG (21) - SREG (22) - SREG (23) - SREG (24) - SREG (25) - SREG (26) - SREG (27) - SREG (28) - SREG (29) - SREG (30) - SREG (31) - SPC - li $2, 0 - j $31 - - .size _Umips_getcontext, .-_Umips_getcontext diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/init.h b/src/coreclr/src/pal/src/libunwind/src/mips/init.h deleted file mode 100644 index 30c193a18f7146..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/init.h +++ /dev/null @@ -1,59 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -static inline int -common_init (struct cursor *c, unsigned use_prev_instr) -{ - int ret, i; - - for (i = 0; i < 32; i++) - c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, UNW_MIPS_R0 + i); - for (i = 32; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - c->dwarf.loc[UNW_MIPS_PC] = DWARF_REG_LOC (&c->dwarf, UNW_MIPS_PC); - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_MIPS_PC], &c->dwarf.ip); - if (ret < 0) - return ret; - - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_MIPS_R29), - &c->dwarf.cfa); - if (ret < 0) - return ret; - - /* FIXME: Initialisation for other registers. */ - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/mips/is_fpreg.c deleted file mode 100644 index a92dd5ece7a6dd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/is_fpreg.c +++ /dev/null @@ -1,35 +0,0 @@ -/* 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. */ - -#include "libunwind_i.h" - -/* FIXME: I'm not sure if libunwind's GP/FP register distinction is very useful - on MIPS. */ - -int -unw_is_fpreg (int regnum) -{ - /* FIXME: Support FP. */ - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/offsets.h b/src/coreclr/src/pal/src/libunwind/src/mips/offsets.h deleted file mode 100644 index b506051367720e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/offsets.h +++ /dev/null @@ -1,86 +0,0 @@ -/* Linux-specific definitions: */ - -/* Define various structure offsets to simplify cross-compilation. */ - -/* FIXME: Currently these are only used in getcontext.S, which is only used - for a local unwinder, so we can use the compile-time ABI. At a later date - we will want all three here, to use for signal handlers. Also, because - of the three ABIs, gen-offsets.c can not quite generate this file. */ - -/* Offsets for MIPS Linux "ucontext_t": */ - -/* First 24 bytes in sigframe are argument save space and padding for -what used to be signal trampolines. Ref: arch/mips/kernel/signal.c */ -#define LINUX_SF_TRAMP_SIZE 0x18 - -#if _MIPS_SIM == _ABIO32 - -# define LINUX_UC_FLAGS_OFF 0x0 -# define LINUX_UC_LINK_OFF 0x4 -# define LINUX_UC_STACK_OFF 0x8 -# define LINUX_UC_MCONTEXT_OFF 0x18 -# define LINUX_UC_SIGMASK_OFF 0x268 -# define LINUX_UC_MCONTEXT_PC 0x20 -# define LINUX_UC_MCONTEXT_GREGS 0x28 - -#elif _MIPS_SIM == _ABIN32 - -# define LINUX_UC_FLAGS_OFF 0x0 -# define LINUX_UC_LINK_OFF 0x4 -# define LINUX_UC_STACK_OFF 0x8 -# define LINUX_UC_MCONTEXT_OFF 0x18 -# define LINUX_UC_SIGMASK_OFF 0x270 -# define LINUX_UC_MCONTEXT_PC 0x258 -# define LINUX_UC_MCONTEXT_GREGS 0x18 - -#elif _MIPS_SIM == _ABI64 - -# define LINUX_UC_FLAGS_OFF 0x0 -# define LINUX_UC_LINK_OFF 0x8 -# define LINUX_UC_STACK_OFF 0x10 -# define LINUX_UC_MCONTEXT_OFF 0x28 -# define LINUX_UC_SIGMASK_OFF 0x280 -# define LINUX_UC_MCONTEXT_PC 0x268 -# define LINUX_UC_MCONTEXT_GREGS 0x28 - -#else - -#error Unsupported ABI - -#endif - -#define LINUX_SC_R0_OFF (LINUX_UC_MCONTEXT_GREGS - LINUX_UC_MCONTEXT_OFF) -#define LINUX_SC_R1_OFF (LINUX_SC_R0_OFF + 1*8) -#define LINUX_SC_R2_OFF (LINUX_SC_R0_OFF + 2*8) -#define LINUX_SC_R3_OFF (LINUX_SC_R0_OFF + 3*8) -#define LINUX_SC_R4_OFF (LINUX_SC_R0_OFF + 4*8) -#define LINUX_SC_R5_OFF (LINUX_SC_R0_OFF + 5*8) -#define LINUX_SC_R6_OFF (LINUX_SC_R0_OFF + 6*8) -#define LINUX_SC_R7_OFF (LINUX_SC_R0_OFF + 7*8) -#define LINUX_SC_R8_OFF (LINUX_SC_R0_OFF + 8*8) -#define LINUX_SC_R9_OFF (LINUX_SC_R0_OFF + 9*8) -#define LINUX_SC_R10_OFF (LINUX_SC_R0_OFF + 10*8) -#define LINUX_SC_R11_OFF (LINUX_SC_R0_OFF + 11*8) -#define LINUX_SC_R12_OFF (LINUX_SC_R0_OFF + 12*8) -#define LINUX_SC_R13_OFF (LINUX_SC_R0_OFF + 13*8) -#define LINUX_SC_R14_OFF (LINUX_SC_R0_OFF + 14*8) -#define LINUX_SC_R15_OFF (LINUX_SC_R0_OFF + 15*8) -#define LINUX_SC_R16_OFF (LINUX_SC_R0_OFF + 16*8) -#define LINUX_SC_R17_OFF (LINUX_SC_R0_OFF + 17*8) -#define LINUX_SC_R18_OFF (LINUX_SC_R0_OFF + 18*8) -#define LINUX_SC_R19_OFF (LINUX_SC_R0_OFF + 19*8) -#define LINUX_SC_R20_OFF (LINUX_SC_R0_OFF + 20*8) -#define LINUX_SC_R21_OFF (LINUX_SC_R0_OFF + 21*8) -#define LINUX_SC_R22_OFF (LINUX_SC_R0_OFF + 22*8) -#define LINUX_SC_R23_OFF (LINUX_SC_R0_OFF + 23*8) -#define LINUX_SC_R24_OFF (LINUX_SC_R0_OFF + 24*8) -#define LINUX_SC_R25_OFF (LINUX_SC_R0_OFF + 25*8) -#define LINUX_SC_R26_OFF (LINUX_SC_R0_OFF + 26*8) -#define LINUX_SC_R27_OFF (LINUX_SC_R0_OFF + 27*8) -#define LINUX_SC_R28_OFF (LINUX_SC_R0_OFF + 28*8) -#define LINUX_SC_R29_OFF (LINUX_SC_R0_OFF + 29*8) -#define LINUX_SC_R30_OFF (LINUX_SC_R0_OFF + 30*8) -#define LINUX_SC_R31_OFF (LINUX_SC_R0_OFF + 31*8) - -#define LINUX_SC_SP_OFF LINUX_SC_R29_OFF -#define LINUX_SC_PC_OFF (LINUX_UC_MCONTEXT_PC - LINUX_UC_MCONTEXT_OFF) diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/regname.c b/src/coreclr/src/pal/src/libunwind/src/mips/regname.c deleted file mode 100644 index b137b972b61762..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/regname.c +++ /dev/null @@ -1,48 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -static const char *regname[] = - { - /* 0. */ - "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", - /* 8. */ - "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", - /* 16. */ - "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", - /* 24. */ - "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) - return regname[reg]; - else if (reg == UNW_MIPS_PC) - return "pc"; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/mips/siglongjmp.S deleted file mode 100644 index 9cbcf3dc014d79..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/siglongjmp.S +++ /dev/null @@ -1,8 +0,0 @@ - /* Dummy implementation for now. */ - - .globl _UI_siglongjmp_cont - .globl _UI_longjmp_cont - -_UI_siglongjmp_cont: -_UI_longjmp_cont: - j $31 diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/mips/unwind_i.h deleted file mode 100644 index 3382dcfe58cefc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/mips/unwind_i.h +++ /dev/null @@ -1,43 +0,0 @@ -/* 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 unwind_i_h -#define unwind_i_h - -#include - -#include - -#include "libunwind_i.h" - -#define mips_lock UNW_OBJ(lock) -#define mips_local_resume UNW_OBJ(local_resume) -#define mips_local_addr_space_init UNW_OBJ(local_addr_space_init) - -extern int mips_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, - void *arg); - -extern void mips_local_addr_space_init (void); - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/os-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/os-freebsd.c deleted file mode 100644 index 753e819dfe4f6f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/os-freebsd.c +++ /dev/null @@ -1,166 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010 Konstantin Belousov - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include -#include -#include -#include -#include - -#include "libunwind_i.h" - -static void * -get_mem(size_t sz) -{ - void *res; - - res = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); - if (res == MAP_FAILED) - return (NULL); - return (res); -} - -static void -free_mem(void *ptr, size_t sz) -{ - munmap(ptr, sz); -} - -static int -get_pid_by_tid(int tid) -{ - int mib[3], error; - size_t len, len1; - char *buf; - struct kinfo_proc *kv; - unsigned i, pid; - - len = 0; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_ALL; - - error = sysctl(mib, 3, NULL, &len, NULL, 0); - if (error == -1) - return (-1); - len1 = len * 4 / 3; - buf = get_mem(len1); - if (buf == NULL) - return (-1); - len = len1; - error = sysctl(mib, 3, buf, &len, NULL, 0); - if (error == -1) { - free_mem(buf, len1); - return (-1); - } - pid = -1; - for (i = 0, kv = (struct kinfo_proc *)buf; i < len / sizeof(*kv); - i++, kv++) { - if (kv->ki_tid == tid) { - pid = kv->ki_pid; - break; - } - } - free_mem(buf, len1); - return (pid); -} - -int -tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, char *path, size_t pathlen) -{ - int mib[4], error, ret; - size_t len, len1; - char *buf, *bp, *eb; - struct kinfo_vmentry *kv; - - len = 0; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_VMMAP; - mib[3] = pid; - - error = sysctl(mib, 4, NULL, &len, NULL, 0); - if (error == -1) { - if (errno == ESRCH) { - mib[3] = get_pid_by_tid(pid); - if (mib[3] != -1) - error = sysctl(mib, 4, NULL, &len, NULL, 0); - if (error == -1) - return (-UNW_EUNSPEC); - } else - return (-UNW_EUNSPEC); - } - len1 = len * 4 / 3; - buf = get_mem(len1); - if (buf == NULL) - return (-UNW_EUNSPEC); - len = len1; - error = sysctl(mib, 4, buf, &len, NULL, 0); - if (error == -1) { - free_mem(buf, len1); - return (-UNW_EUNSPEC); - } - ret = -UNW_EUNSPEC; - for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) { - kv = (struct kinfo_vmentry *)(uintptr_t)bp; - if (ip < kv->kve_start || ip >= kv->kve_end) - continue; - if (kv->kve_type != KVME_TYPE_VNODE) - continue; - *segbase = kv->kve_start; - *mapoff = kv->kve_offset; - if (path) - { - strncpy(path, kv->kve_path, pathlen); - } - ret = elf_map_image (ei, kv->kve_path); - break; - } - free_mem(buf, len1); - return (ret); -} - -#ifndef UNW_REMOTE_ONLY - -void -tdep_get_exe_image_path (char *path) -{ - int mib[4], error; - size_t len; - - len = 0; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = getpid(); - - error = sysctl(mib, 4, path, &len, NULL, 0); - if (error == -1) - path[0] = 0; -} - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/os-hpux.c b/src/coreclr/src/pal/src/libunwind/src/os-hpux.c deleted file mode 100644 index 48bfb05cf54a00..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/os-hpux.c +++ /dev/null @@ -1,78 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include - -#include "libunwind_i.h" - -#include "elf64.h" - -HIDDEN int -tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen) -{ - struct load_module_desc lmd; - const char *path2; - - if (pid != getpid ()) - { - printf ("%s: remote case not implemented yet\n", __FUNCTION__); - return -UNW_ENOINFO; - } - - if (!dlmodinfo (ip, &lmd, sizeof (lmd), NULL, 0, 0)) - return -UNW_ENOINFO; - - *segbase = lmd.text_base; - *mapoff = 0; /* XXX fix me? */ - - path2 = dlgetname (&lmd, sizeof (lmd), NULL, 0, 0); - if (!path2) - return -UNW_ENOINFO; - if (path) - { - strncpy(path, path2, pathlen); - path[pathlen - 1] = '\0'; - if (strcmp(path, path2) != 0) - Debug(1, "buffer size (%d) not big enough to hold path\n", pathlen); - } - Debug(1, "segbase=%lx, mapoff=%lx, path=%s\n", *segbase, *mapoff, path); - - return elf_map_image (ei, path); -} - -#ifndef UNW_REMOTE_ONLY - -void -tdep_get_exe_image_path (char *path) -{ - path[0] = 0; /* XXX */ -} - -#endif - diff --git a/src/coreclr/src/pal/src/libunwind/src/os-linux.c b/src/coreclr/src/pal/src/libunwind/src/os-linux.c deleted file mode 100644 index 8a00669fb3c0f2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/os-linux.c +++ /dev/null @@ -1,73 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include - -#include "libunwind_i.h" -#include "os-linux.h" - -int -tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen) -{ - struct map_iterator mi; - int found = 0, rc; - unsigned long hi; - - if (maps_init (&mi, pid) < 0) - return -1; - - while (maps_next (&mi, segbase, &hi, mapoff)) - if (ip >= *segbase && ip < hi) - { - found = 1; - break; - } - - if (!found) - { - maps_close (&mi); - return -1; - } - if (path) - { - strncpy(path, mi.path, pathlen); - } - rc = elf_map_image (ei, mi.path); - maps_close (&mi); - return rc; -} - -#ifndef UNW_REMOTE_ONLY - -void -tdep_get_exe_image_path (char *path) -{ - strcpy(path, "/proc/self/exe"); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/os-linux.h b/src/coreclr/src/pal/src/libunwind/src/os-linux.h deleted file mode 100644 index 3976b38cc293a1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/os-linux.h +++ /dev/null @@ -1,297 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - -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 os_linux_h -#define os_linux_h - -struct map_iterator - { - off_t offset; - int fd; - size_t buf_size; - char *buf; - char *buf_end; - char *path; - }; - -static inline char * -ltoa (char *buf, long val) -{ - char *cp = buf, tmp; - ssize_t i, len; - - do - { - *cp++ = '0' + (val % 10); - val /= 10; - } - while (val); - - /* reverse the order of the digits: */ - len = cp - buf; - --cp; - for (i = 0; i < len / 2; ++i) - { - tmp = buf[i]; - buf[i] = cp[-i]; - cp[-i] = tmp; - } - return buf + len; -} - -static inline int -maps_init (struct map_iterator *mi, pid_t pid) -{ - char path[sizeof ("/proc/0123456789/maps")], *cp; - - memcpy (path, "/proc/", 6); - cp = ltoa (path + 6, pid); - assert (cp + 6 < path + sizeof (path)); - memcpy (cp, "/maps", 6); - - mi->fd = open (path, O_RDONLY); - if (mi->fd >= 0) - { - /* Try to allocate a page-sized buffer. */ - mi->buf_size = getpagesize (); - cp = mmap (NULL, mi->buf_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (cp == MAP_FAILED) - { - close(mi->fd); - mi->fd = -1; - return -1; - } - else - { - mi->offset = 0; - mi->buf = mi->buf_end = cp + mi->buf_size; - return 0; - } - } - return -1; -} - -static inline char * -skip_whitespace (char *cp) -{ - if (!cp) - return NULL; - - while (*cp == ' ' || *cp == '\t') - ++cp; - return cp; -} - -static inline char * -scan_hex (char *cp, unsigned long *valp) -{ - unsigned long num_digits = 0, digit, val = 0; - - cp = skip_whitespace (cp); - if (!cp) - return NULL; - - while (1) - { - digit = *cp; - if ((digit - '0') <= 9) - digit -= '0'; - else if ((digit - 'a') < 6) - digit -= 'a' - 10; - else if ((digit - 'A') < 6) - digit -= 'A' - 10; - else - break; - val = (val << 4) | digit; - ++num_digits; - ++cp; - } - if (!num_digits) - return NULL; - *valp = val; - return cp; -} - -static inline char * -scan_dec (char *cp, unsigned long *valp) -{ - unsigned long num_digits = 0, digit, val = 0; - - if (!(cp = skip_whitespace (cp))) - return NULL; - - while (1) - { - digit = *cp; - if ((digit - '0') <= 9) - { - digit -= '0'; - ++cp; - } - else - break; - val = (10 * val) + digit; - ++num_digits; - } - if (!num_digits) - return NULL; - *valp = val; - return cp; -} - -static inline char * -scan_char (char *cp, char *valp) -{ - if (!cp) - return NULL; - - *valp = *cp; - - /* don't step over NUL terminator */ - if (*cp) - ++cp; - return cp; -} - -/* Scan a string delimited by white-space. Fails on empty string or - if string is doesn't fit in the specified buffer. */ -static inline char * -scan_string (char *cp, char *valp, size_t buf_size) -{ - size_t i = 0; - - if (!(cp = skip_whitespace (cp))) - return NULL; - - while (*cp != ' ' && *cp != '\t' && *cp != '\0') - { - if ((valp != NULL) && (i < buf_size - 1)) - valp[i++] = *cp; - ++cp; - } - if (i == 0 || i >= buf_size) - return NULL; - valp[i] = '\0'; - return cp; -} - -static inline int -maps_next (struct map_iterator *mi, - unsigned long *low, unsigned long *high, unsigned long *offset) -{ - char perm[16], dash = 0, colon = 0, *cp; - unsigned long major, minor, inum; - ssize_t i, nread; - - if (mi->fd < 0) - return 0; - - while (1) - { - ssize_t bytes_left = mi->buf_end - mi->buf; - char *eol = NULL; - - for (i = 0; i < bytes_left; ++i) - { - if (mi->buf[i] == '\n') - { - eol = mi->buf + i; - break; - } - else if (mi->buf[i] == '\0') - break; - } - if (!eol) - { - /* copy down the remaining bytes, if any */ - if (bytes_left > 0) - memmove (mi->buf_end - mi->buf_size, mi->buf, bytes_left); - - mi->buf = mi->buf_end - mi->buf_size; - nread = read (mi->fd, mi->buf + bytes_left, - mi->buf_size - bytes_left); - if (nread <= 0) - return 0; - else if ((size_t) (nread + bytes_left) < mi->buf_size) - { - /* Move contents to the end of the buffer so we - maintain the invariant that all bytes between - mi->buf and mi->buf_end are valid. */ - memmove (mi->buf_end - nread - bytes_left, mi->buf, - nread + bytes_left); - mi->buf = mi->buf_end - nread - bytes_left; - } - - eol = mi->buf + bytes_left + nread - 1; - - for (i = bytes_left; i < bytes_left + nread; ++i) - if (mi->buf[i] == '\n') - { - eol = mi->buf + i; - break; - } - } - cp = mi->buf; - mi->buf = eol + 1; - *eol = '\0'; - - /* scan: "LOW-HIGH PERM OFFSET MAJOR:MINOR INUM PATH" */ - cp = scan_hex (cp, low); - cp = scan_char (cp, &dash); - cp = scan_hex (cp, high); - cp = scan_string (cp, perm, sizeof (perm)); - cp = scan_hex (cp, offset); - cp = scan_hex (cp, &major); - cp = scan_char (cp, &colon); - cp = scan_hex (cp, &minor); - cp = scan_dec (cp, &inum); - cp = mi->path = skip_whitespace (cp); - if (!cp) - continue; - cp = scan_string (cp, NULL, 0); - if (dash != '-' || colon != ':') - continue; /* skip line with unknown or bad format */ - return 1; - } - return 0; -} - -static inline void -maps_close (struct map_iterator *mi) -{ - if (mi->fd < 0) - return; - close (mi->fd); - mi->fd = -1; - if (mi->buf) - { - munmap (mi->buf_end - mi->buf_size, mi->buf_size); - mi->buf = mi->buf_end = NULL; - } -} - -#endif /* os_linux_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/os-qnx.c b/src/coreclr/src/pal/src/libunwind/src/os-qnx.c deleted file mode 100644 index 4a76c7cda41a5f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/os-qnx.c +++ /dev/null @@ -1,117 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2013 Garmin International - Contributed by Matt Fischer - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "libunwind_i.h" - -struct cb_info -{ - unw_word_t ip; - unsigned long segbase; - unsigned long offset; - const char *path; -}; - -static int callback(const struct dl_phdr_info *info, size_t size, void *data) -{ - int i; - struct cb_info *cbi = (struct cb_info*)data; - for(i=0; idlpi_phnum; i++) { - int segbase = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr; - if(cbi->ip >= segbase && cbi->ip < segbase + info->dlpi_phdr[i].p_memsz) - { - cbi->path = info->dlpi_name; - cbi->offset = info->dlpi_phdr[i].p_offset; - cbi->segbase = segbase; - return 1; - } - } - - return 0; -} - -int -tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen) -{ - struct cb_info cbi; - int ret = -1; - cbi.ip = ip; - cbi.segbase = 0; - cbi.offset = 0; - cbi.path = NULL; - - /* QNX's support for accessing symbol maps is severely broken. There is - a devctl() call that can be made on a proc node (DCMD_PROC_MAPDEBUG) - which returns information similar to Linux's /proc//maps - node, however the filename that is returned by this call is not an - absolute path, and there is no foolproof way to map the filename - back to the file that it came from. - - Therefore, the normal approach for implementing this function, - which works equally well for both local and remote unwinding, - will not work here. The only type of image lookup which works - reliably is locally, using dl_iterate_phdr(). However, the only - time that this function is required to look up a remote image is for - ptrace support, which doesn't work on QNX anyway. Local unwinding, - which is the main case that makes use of this function, will work - fine with dl_iterate_phdr(). Therefore, in lieu of any better - platform support for remote image lookup, this function has just - been implemented in terms of dl_iterate_phdr(). - */ - - if (pid != getpid()) - { - /* Return an error if an attempt is made to perform remote image lookup */ - return -1; - } - - if (dl_iterate_phdr (callback, &cbi) != 0) - { - if (path) - { - strncpy (path, cbi.path, pathlen); - } - - *mapoff = cbi.offset; - *segbase = cbi.segbase; - - ret = elf_map_image (ei, cbi.path); - } - - return ret; -} - -#ifndef UNW_REMOTE_ONLY - -void -tdep_get_exe_image_path (char *path) -{ - path[0] = 0; /* XXX */ -} - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_proc_info.c deleted file mode 100644 index 7dfb6d4e4271b1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_proc_info.c +++ /dev/null @@ -1,41 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Copied from src/x86_64/, modified slightly (or made empty stubs) for - building frysk successfully on ppc64, by Wu Zhou - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - ret = dwarf_make_proc_info (&c->dwarf); - if (ret < 0) - return ret; - - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_save_loc.c deleted file mode 100644 index 5343fa4c7f3627..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_save_loc.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Copied from src/x86_64/, modified slightly (or made empty stubs) for - building frysk successfully on ppc64, by Wu Zhou - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - /* XXX: empty stub. */ - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_local.c deleted file mode 100644 index 366cf5bdaf3e36..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_local.c +++ /dev/null @@ -1,88 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Copied from src/x86_64/, modified slightly (or made empty stubs) for - building frysk successfully on ppc64, by Wu Zhou - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#ifdef UNW_TARGET_PPC64 -#include "../ppc64/init.h" -#else -#include "../ppc32/init.h" -#endif - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - /* XXX: empty stub. */ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = uc; - #ifdef UNW_TARGET_PPC64 - return common_init_ppc64 (c, use_prev_instr); - #else - return common_init_ppc32 (c, use_prev_instr); - #endif -} - -int -unw_init_local(unw_cursor_t *cursor, ucontext_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_remote.c deleted file mode 100644 index ed85be8971f061..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_remote.c +++ /dev/null @@ -1,60 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#ifdef UNW_TARGET_PPC64 -#include "../ppc64/init.h" -#else -#include "../ppc32/init.h" -#endif - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - c->dwarf.as_arg = as_arg; - - #ifdef UNW_TARGET_PPC64 - return common_init_ppc64 (c, 0); - #elif UNW_TARGET_PPC32 - return common_init_ppc32 (c, 0); - #else - #error init_remote :: NO VALID PPC ARCH! - #endif -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Gis_signal_frame.c deleted file mode 100644 index 6184dd5d410d71..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Gis_signal_frame.c +++ /dev/null @@ -1,78 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -int -unw_is_signal_frame (unw_cursor_t * cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, w1, i0, i1, i2, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - as->validate = 1; /* Don't trust the ip */ - arg = c->dwarf.as_arg; - - /* Check if return address points at sigreturn sequence. - on ppc64 Linux that is (see libc.so): - 0x38210080 addi r1, r1, 128 // pop the stack - 0x380000ac li r0, 172 // invoke system service 172 - 0x44000002 sc - */ - - ip = c->dwarf.ip; - if (ip == 0) - return 0; - - /* Read up two 8-byte words at the IP. We are only looking at 3 - consecutive 32-bit words, so the second 8-byte word needs to be - shifted right by 32 bits (think big-endian) */ - - a = unw_get_accessors_int (as); - if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 - || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0) - return 0; - - if (tdep_big_endian (as)) - { - i0 = w0 >> 32; - i1 = w0 & 0xffffffffUL; - i2 = w1 >> 32; - } - else - { - i0 = w0 & 0xffffffffUL; - i1 = w0 >> 32; - i2 = w1 & 0xffffffffUL; - } - - return (i0 == 0x38210080 && i1 == 0x380000ac && i2 == 0x44000002); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9fa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/longjmp.S b/src/coreclr/src/pal/src/libunwind/src/ppc/longjmp.S deleted file mode 100644 index d363aef222f404..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/longjmp.S +++ /dev/null @@ -1,36 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Copied from src/x86_64/, modified slightly (or made empty stubs) for - building frysk successfully on ppc64, by Wu Zhou - -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. */ - - .globl _UI_longjmp_cont - - .type _UI_longjmp_cont, @function -_UI_longjmp_cont: - .size _UI_longjmp_cont, .-_UI_longjmp_cont - -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/ppc/siglongjmp.S deleted file mode 100644 index 64be36ce170281..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc/siglongjmp.S +++ /dev/null @@ -1,31 +0,0 @@ -/* 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. */ - - .globl _UI_siglongjmp_cont - - _UI_siglongjmp_cont: - -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gcreate_addr_space.c deleted file mode 100644 index aaa68bb3543d0c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gcreate_addr_space.c +++ /dev/null @@ -1,56 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* - * We support only big-endian on Linux ppc32. - */ - if (byte_order != 0 && byte_order != __BIG_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gglobal.c deleted file mode 100644 index a0f80beec6d95a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gglobal.c +++ /dev/null @@ -1,135 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "dwarf_i.h" - -HIDDEN define_lock (ppc32_lock); -HIDDEN int tdep_init_done; - -/* The API register numbers are exactly the same as the .eh_frame - registers, for now at least. */ -HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] = - { - [UNW_PPC32_R0]=UNW_PPC32_R0, - [UNW_PPC32_R1]=UNW_PPC32_R1, - [UNW_PPC32_R2]=UNW_PPC32_R2, - [UNW_PPC32_R3]=UNW_PPC32_R3, - [UNW_PPC32_R4]=UNW_PPC32_R4, - [UNW_PPC32_R5]=UNW_PPC32_R5, - [UNW_PPC32_R6]=UNW_PPC32_R6, - [UNW_PPC32_R7]=UNW_PPC32_R7, - [UNW_PPC32_R8]=UNW_PPC32_R8, - [UNW_PPC32_R9]=UNW_PPC32_R9, - [UNW_PPC32_R10]=UNW_PPC32_R10, - [UNW_PPC32_R11]=UNW_PPC32_R11, - [UNW_PPC32_R12]=UNW_PPC32_R12, - [UNW_PPC32_R13]=UNW_PPC32_R13, - [UNW_PPC32_R14]=UNW_PPC32_R14, - [UNW_PPC32_R15]=UNW_PPC32_R15, - [UNW_PPC32_R16]=UNW_PPC32_R16, - [UNW_PPC32_R17]=UNW_PPC32_R17, - [UNW_PPC32_R18]=UNW_PPC32_R18, - [UNW_PPC32_R19]=UNW_PPC32_R19, - [UNW_PPC32_R20]=UNW_PPC32_R20, - [UNW_PPC32_R21]=UNW_PPC32_R21, - [UNW_PPC32_R22]=UNW_PPC32_R22, - [UNW_PPC32_R23]=UNW_PPC32_R23, - [UNW_PPC32_R24]=UNW_PPC32_R24, - [UNW_PPC32_R25]=UNW_PPC32_R25, - [UNW_PPC32_R26]=UNW_PPC32_R26, - [UNW_PPC32_R27]=UNW_PPC32_R27, - [UNW_PPC32_R28]=UNW_PPC32_R28, - [UNW_PPC32_R29]=UNW_PPC32_R29, - [UNW_PPC32_R30]=UNW_PPC32_R30, - [UNW_PPC32_R31]=UNW_PPC32_R31, - - [UNW_PPC32_CTR]=UNW_PPC32_CTR, - [UNW_PPC32_XER]=UNW_PPC32_XER, - [UNW_PPC32_CCR]=UNW_PPC32_CCR, - [UNW_PPC32_LR]=UNW_PPC32_LR, - [UNW_PPC32_FPSCR]=UNW_PPC32_FPSCR, - - [UNW_PPC32_F0]=UNW_PPC32_F0, - [UNW_PPC32_F1]=UNW_PPC32_F1, - [UNW_PPC32_F2]=UNW_PPC32_F2, - [UNW_PPC32_F3]=UNW_PPC32_F3, - [UNW_PPC32_F4]=UNW_PPC32_F4, - [UNW_PPC32_F5]=UNW_PPC32_F5, - [UNW_PPC32_F6]=UNW_PPC32_F6, - [UNW_PPC32_F7]=UNW_PPC32_F7, - [UNW_PPC32_F8]=UNW_PPC32_F8, - [UNW_PPC32_F9]=UNW_PPC32_F9, - [UNW_PPC32_F10]=UNW_PPC32_F10, - [UNW_PPC32_F11]=UNW_PPC32_F11, - [UNW_PPC32_F12]=UNW_PPC32_F12, - [UNW_PPC32_F13]=UNW_PPC32_F13, - [UNW_PPC32_F14]=UNW_PPC32_F14, - [UNW_PPC32_F15]=UNW_PPC32_F15, - [UNW_PPC32_F16]=UNW_PPC32_F16, - [UNW_PPC32_F17]=UNW_PPC32_F17, - [UNW_PPC32_F18]=UNW_PPC32_F18, - [UNW_PPC32_F19]=UNW_PPC32_F19, - [UNW_PPC32_F20]=UNW_PPC32_F20, - [UNW_PPC32_F21]=UNW_PPC32_F21, - [UNW_PPC32_F22]=UNW_PPC32_F22, - [UNW_PPC32_F23]=UNW_PPC32_F23, - [UNW_PPC32_F24]=UNW_PPC32_F24, - [UNW_PPC32_F25]=UNW_PPC32_F25, - [UNW_PPC32_F26]=UNW_PPC32_F26, - [UNW_PPC32_F27]=UNW_PPC32_F27, - [UNW_PPC32_F28]=UNW_PPC32_F28, - [UNW_PPC32_F29]=UNW_PPC32_F29, - [UNW_PPC32_F30]=UNW_PPC32_F30, - [UNW_PPC32_F31]=UNW_PPC32_F31, -}; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&ppc32_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - dwarf_init (); - -#ifndef UNW_REMOTE_ONLY - ppc32_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&ppc32_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c deleted file mode 100644 index ba302448a314b6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c +++ /dev/null @@ -1,216 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include - -#include "ucontext_i.h" -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -static void * -uc_addr (ucontext_t *uc, int reg) -{ - void *addr; - - if ((unsigned) (reg - UNW_PPC32_R0) < 32) - addr = &uc->uc_mcontext.uc_regs->gregs[reg - UNW_PPC32_R0]; - - else - if ( ((unsigned) (reg - UNW_PPC32_F0) < 32) && - ((unsigned) (reg - UNW_PPC32_F0) >= 0) ) - addr = &uc->uc_mcontext.uc_regs->fpregs.fpregs[reg - UNW_PPC32_F0]; - - else - { - unsigned gregs_idx; - - switch (reg) - { - case UNW_PPC32_CTR: - gregs_idx = CTR_IDX; - break; - case UNW_PPC32_LR: - gregs_idx = LINK_IDX; - break; - case UNW_PPC32_XER: - gregs_idx = XER_IDX; - break; - case UNW_PPC32_CCR: - gregs_idx = CCR_IDX; - break; - default: - return NULL; - } - addr = &uc->uc_mcontext.uc_regs->gregs[gregs_idx]; - } - return addr; -} - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) -{ - return uc_addr (uc, reg); -} - -# endif /* UNW_LOCAL_ONLY */ - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (write) - { - Debug (12, "mem[%lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "mem[%lx] -> %lx\n", addr, *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, - int write, void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = arg; - - if ( ((unsigned int) (reg - UNW_PPC32_F0) < 32) && - ((unsigned int) (reg - UNW_PPC32_F0) >= 0)) - goto badreg; - - addr = uc_addr (uc, reg); - if (!addr) - goto badreg; - - if (write) - { - *(unw_word_t *) addr = *val; - Debug (12, "%s <- %lx\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> %lx\n", unw_regname (reg), *val); - } - return 0; - -badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = arg; - unw_fpreg_t *addr; - - if ((unsigned) (reg - UNW_PPC32_F0) < 0) - goto badreg; - - addr = uc_addr (uc, reg); - if (!addr) - goto badreg; - - if (write) - { - Debug (12, "%s <- %016Lf\n", unw_regname (reg), *val); - *(unw_fpreg_t *) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %016Lf\n", unw_regname (reg), *val); - } - return 0; - -badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -ppc32_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = ppc32_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gregs.c deleted file mode 100644 index 9344455e6cc467..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gregs.c +++ /dev/null @@ -1,90 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - struct dwarf_loc loc; - - switch (reg) - { - case UNW_TDEP_IP: - if (write) - { - c->dwarf.ip = *valp; /* update the IP cache */ - if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip - || *valp >= c->dwarf.pi.end_ip)) - c->dwarf.pi_valid = 0; /* new IP outside of current proc */ - } - else - *valp = c->dwarf.ip; - return 0; - - case UNW_TDEP_SP: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - - default: - break; - } - - /* make sure it's not an FP or VR register */ - if ((((unsigned) (reg - UNW_PPC32_F0)) <= 31)) - return -UNW_EBADREG; - - loc = c->dwarf.loc[reg]; - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - struct dwarf_loc loc; - - if ((unsigned) (reg - UNW_PPC32_F0) < 32) - { - loc = c->dwarf.loc[reg]; - if (write) - return dwarf_putfp (&c->dwarf, loc, *valp); - else - return dwarf_getfp (&c->dwarf, loc, valp); - } - - return -UNW_EBADREG; -} - diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gresume.c deleted file mode 100644 index c0f95837b33c18..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gresume.c +++ /dev/null @@ -1,77 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford cjashfor@us.ibm.com - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -#ifndef UNW_REMOTE_ONLY - -#include - -/* sigreturn() is a no-op on x86_64 glibc. */ - -static NORETURN inline long -my_rt_sigreturn (void *new_sp) -{ - /* XXX: empty stub. */ - abort (); -} - -HIDDEN inline int -ppc32_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - /* XXX: empty stub. */ - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ - -/* This routine is responsible for copying the register values in - cursor C and establishing them as the current machine state. */ - -static inline int -establish_machine_state (struct cursor *c) -{ - /* XXX: empty stub. */ - return 0; -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p)\n", c); - - if ((ret = establish_machine_state (c)) < 0) - return ret; - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gstep.c deleted file mode 100644 index 478d3a6c1b89f5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gstep.c +++ /dev/null @@ -1,309 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "ucontext_i.h" -#include - -/* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is - defined there only when __KERNEL__ is defined. We reproduce it here for - our use at the user level in order to locate the ucontext record, which - appears to be at this offset relative to the stack pointer when in the - context of the signal handler return trampoline code - - __kernel_sigtramp_rt64. */ -#define __SIGNAL_FRAMESIZE 128 - -/* This definition comes from the document "64-bit PowerPC ELF Application - Binary Interface Supplement 1.9", section 3.2.2. - http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */ - -typedef struct -{ - long unsigned back_chain; - long unsigned lr_save; - /* many more fields here, but they are unused by this code */ -} stack_frame_t; - - -int -unw_step (unw_cursor_t * cursor) -{ - struct cursor *c = (struct cursor *) cursor; - stack_frame_t dummy; - unw_word_t back_chain_offset, lr_save_offset; - struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc; - int ret; - - Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); - - if (c->dwarf.ip == 0) - { - /* Unless the cursor or stack is corrupt or uninitialized, - we've most likely hit the top of the stack */ - return 0; - } - - /* Try DWARF-based unwinding... */ - - ret = dwarf_step (&c->dwarf); - - if (ret < 0 && ret != -UNW_ENOINFO) - { - Debug (2, "returning %d\n", ret); - return ret; - } - - if (unlikely (ret < 0)) - { - if (likely (unw_is_signal_frame (cursor) <= 0)) - { - /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode - produces the mandatory level of traceback record in the code, but - I get the impression that this is transitory, that eventually gcc - will not produce any traceback records at all. So, for now, we - won't bother to try to find and use these records. - - We can, however, attempt to unwind the frame by using the callback - chain. This is very crude, however, and won't be able to unwind - any registers besides the IP, SP, and LR . */ - - back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy); - lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy); - - back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0); - - if ((ret = - dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0) - { - Debug (2, - "Unable to retrieve CFA from back chain in stack frame - %d\n", - ret); - return ret; - } - if (c->dwarf.cfa == 0) - /* Unless the cursor or stack is corrupt or uninitialized we've most - likely hit the top of the stack */ - return 0; - - lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0); - - if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0) - { - Debug (2, - "Unable to retrieve IP from lr save in stack frame - %d\n", - ret); - return ret; - } - ret = 1; - } - else - { - /* Find the sigcontext record by taking the CFA and adjusting by - the dummy signal frame size. - - Note that there isn't any way to determined if SA_SIGINFO was - set in the sa_flags parameter to sigaction when the signal - handler was established. If it was not set, the ucontext - record is not required to be on the stack, in which case the - following code will likely cause a seg fault or other crash - condition. */ - - unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE; - - Debug (1, "signal frame, skip over trampoline\n"); - - c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME; - c->sigcontext_addr = ucontext; - - sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); - ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); - - ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - - /* Instead of just restoring the non-volatile registers, do all - of the registers for now. This will incur a performance hit, - but it's rare enough not to cause too much of a problem, and - might be useful in some cases. */ - c->dwarf.loc[UNW_PPC32_R0] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0); - c->dwarf.loc[UNW_PPC32_R1] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); - c->dwarf.loc[UNW_PPC32_R2] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0); - c->dwarf.loc[UNW_PPC32_R3] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0); - c->dwarf.loc[UNW_PPC32_R4] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0); - c->dwarf.loc[UNW_PPC32_R5] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0); - c->dwarf.loc[UNW_PPC32_R6] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0); - c->dwarf.loc[UNW_PPC32_R7] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0); - c->dwarf.loc[UNW_PPC32_R8] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); - c->dwarf.loc[UNW_PPC32_R9] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); - c->dwarf.loc[UNW_PPC32_R10] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); - c->dwarf.loc[UNW_PPC32_R11] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); - c->dwarf.loc[UNW_PPC32_R12] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); - c->dwarf.loc[UNW_PPC32_R13] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); - c->dwarf.loc[UNW_PPC32_R14] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); - c->dwarf.loc[UNW_PPC32_R15] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); - c->dwarf.loc[UNW_PPC32_R16] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0); - c->dwarf.loc[UNW_PPC32_R17] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0); - c->dwarf.loc[UNW_PPC32_R18] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0); - c->dwarf.loc[UNW_PPC32_R19] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0); - c->dwarf.loc[UNW_PPC32_R20] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0); - c->dwarf.loc[UNW_PPC32_R21] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0); - c->dwarf.loc[UNW_PPC32_R22] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0); - c->dwarf.loc[UNW_PPC32_R23] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0); - c->dwarf.loc[UNW_PPC32_R24] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0); - c->dwarf.loc[UNW_PPC32_R25] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0); - c->dwarf.loc[UNW_PPC32_R26] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0); - c->dwarf.loc[UNW_PPC32_R27] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0); - c->dwarf.loc[UNW_PPC32_R28] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0); - c->dwarf.loc[UNW_PPC32_R29] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0); - c->dwarf.loc[UNW_PPC32_R30] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0); - c->dwarf.loc[UNW_PPC32_R31] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0); - - c->dwarf.loc[UNW_PPC32_LR] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); - c->dwarf.loc[UNW_PPC32_CTR] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0); - - /* This CR0 assignment is probably wrong. There are 8 dwarf columns - assigned to the CR registers, but only one CR register in the - mcontext structure */ - c->dwarf.loc[UNW_PPC32_CCR] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0); - c->dwarf.loc[UNW_PPC32_XER] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0); - - c->dwarf.loc[UNW_PPC32_F0] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0); - c->dwarf.loc[UNW_PPC32_F1] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0); - c->dwarf.loc[UNW_PPC32_F2] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0); - c->dwarf.loc[UNW_PPC32_F3] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0); - c->dwarf.loc[UNW_PPC32_F4] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0); - c->dwarf.loc[UNW_PPC32_F5] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0); - c->dwarf.loc[UNW_PPC32_F6] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0); - c->dwarf.loc[UNW_PPC32_F7] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0); - c->dwarf.loc[UNW_PPC32_F8] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0); - c->dwarf.loc[UNW_PPC32_F9] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0); - c->dwarf.loc[UNW_PPC32_F10] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0); - c->dwarf.loc[UNW_PPC32_F11] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0); - c->dwarf.loc[UNW_PPC32_F12] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0); - c->dwarf.loc[UNW_PPC32_F13] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0); - c->dwarf.loc[UNW_PPC32_F14] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0); - c->dwarf.loc[UNW_PPC32_F15] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0); - c->dwarf.loc[UNW_PPC32_F16] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0); - c->dwarf.loc[UNW_PPC32_F17] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0); - c->dwarf.loc[UNW_PPC32_F18] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0); - c->dwarf.loc[UNW_PPC32_F19] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0); - c->dwarf.loc[UNW_PPC32_F20] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0); - c->dwarf.loc[UNW_PPC32_F21] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0); - c->dwarf.loc[UNW_PPC32_F22] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0); - c->dwarf.loc[UNW_PPC32_F23] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0); - c->dwarf.loc[UNW_PPC32_F24] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0); - c->dwarf.loc[UNW_PPC32_F25] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0); - c->dwarf.loc[UNW_PPC32_F26] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0); - c->dwarf.loc[UNW_PPC32_F27] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0); - c->dwarf.loc[UNW_PPC32_F28] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0); - c->dwarf.loc[UNW_PPC32_F29] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0); - c->dwarf.loc[UNW_PPC32_F30] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0); - c->dwarf.loc[UNW_PPC32_F31] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0); - - ret = 1; - } - } - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lglobal.c deleted file mode 100644 index 6d7b489e14bd9f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lglobal.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Linit.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Make-arch.in b/src/coreclr/src/pal/src/libunwind/src/ppc32/Make-arch.in deleted file mode 100644 index 947dd5fa03d767..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Make-arch.in +++ /dev/null @@ -1,11 +0,0 @@ -# Word size. -ELFW = 64 -# Does use dwarf2 unwind info. -dwarf_target = true - -libunwind_setjmp_OBJS += \ - $(arch)/longjmp.o \ - $(arch)/siglongjmp.o - -libunwind_OBJS_common += \ - $(arch)/is_fpreg.o diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/get_func_addr.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/get_func_addr.c deleted file mode 100644 index 66ff795fe7e163..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/get_func_addr.c +++ /dev/null @@ -1,36 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -tdep_get_func_addr (unw_addr_space_t as, unw_word_t symbol_val_addr, - unw_word_t *real_func_addr) -{ - *real_func_addr = symbol_val_addr; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/init.h b/src/coreclr/src/pal/src/libunwind/src/ppc32/init.h deleted file mode 100644 index 87a69b1450ae19..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/init.h +++ /dev/null @@ -1,72 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -/* Here is the "common" init, for remote and local debuging" */ - -static inline int -common_init_ppc32 (struct cursor *c, unsigned use_prev_instr) -{ - int ret; - int i; - - for (i = UNW_PPC32_R0; i <= UNW_PPC32_R31; i++) { - c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); - } - for (i = UNW_PPC32_F0; i <= UNW_PPC32_F31; i++) { - c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i); - } - - c->dwarf.loc[UNW_PPC32_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CTR); - c->dwarf.loc[UNW_PPC32_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_XER); - c->dwarf.loc[UNW_PPC32_CCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CCR); - c->dwarf.loc[UNW_PPC32_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_LR); - c->dwarf.loc[UNW_PPC32_FPSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_FPSCR); - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC32_LR], &c->dwarf.ip); - if (ret < 0) - return ret; - - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_PPC32_R1), - &c->dwarf.cfa); - if (ret < 0) - return ret; - - c->sigcontext_format = PPC_SCF_NONE; - c->sigcontext_addr = 0; - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/is_fpreg.c deleted file mode 100644 index 646ff2379c4976..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/is_fpreg.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_is_fpreg (int regnum) -{ - return (regnum >= UNW_PPC32_F0 && regnum <= UNW_PPC32_F31); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/regname.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/regname.c deleted file mode 100644 index 459b83a4e559a2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/regname.c +++ /dev/null @@ -1,112 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static const char *regname[] = - { - [UNW_PPC32_R0]="GPR0", - [UNW_PPC32_R1]="GPR1", - [UNW_PPC32_R2]="GPR2", - [UNW_PPC32_R3]="GPR3", - [UNW_PPC32_R4]="GPR4", - [UNW_PPC32_R5]="GPR5", - [UNW_PPC32_R6]="GPR6", - [UNW_PPC32_R7]="GPR7", - [UNW_PPC32_R8]="GPR8", - [UNW_PPC32_R9]="GPR9", - [UNW_PPC32_R10]="GPR10", - [UNW_PPC32_R11]="GPR11", - [UNW_PPC32_R12]="GPR12", - [UNW_PPC32_R13]="GPR13", - [UNW_PPC32_R14]="GPR14", - [UNW_PPC32_R15]="GPR15", - [UNW_PPC32_R16]="GPR16", - [UNW_PPC32_R17]="GPR17", - [UNW_PPC32_R18]="GPR18", - [UNW_PPC32_R19]="GPR19", - [UNW_PPC32_R20]="GPR20", - [UNW_PPC32_R21]="GPR21", - [UNW_PPC32_R22]="GPR22", - [UNW_PPC32_R23]="GPR23", - [UNW_PPC32_R24]="GPR24", - [UNW_PPC32_R25]="GPR25", - [UNW_PPC32_R26]="GPR26", - [UNW_PPC32_R27]="GPR27", - [UNW_PPC32_R28]="GPR28", - [UNW_PPC32_R29]="GPR29", - [UNW_PPC32_R30]="GPR30", - [UNW_PPC32_R31]="GPR31", - - [UNW_PPC32_CTR]="CTR", - [UNW_PPC32_XER]="XER", - [UNW_PPC32_CCR]="CCR", - [UNW_PPC32_LR]="LR", - [UNW_PPC32_FPSCR]="FPSCR", - - [UNW_PPC32_F0]="FPR0", - [UNW_PPC32_F1]="FPR1", - [UNW_PPC32_F2]="FPR2", - [UNW_PPC32_F3]="FPR3", - [UNW_PPC32_F4]="FPR4", - [UNW_PPC32_F5]="FPR5", - [UNW_PPC32_F6]="FPR6", - [UNW_PPC32_F7]="FPR7", - [UNW_PPC32_F8]="FPR8", - [UNW_PPC32_F9]="FPR9", - [UNW_PPC32_F10]="FPR10", - [UNW_PPC32_F11]="FPR11", - [UNW_PPC32_F12]="FPR12", - [UNW_PPC32_F13]="FPR13", - [UNW_PPC32_F14]="FPR14", - [UNW_PPC32_F15]="FPR15", - [UNW_PPC32_F16]="FPR16", - [UNW_PPC32_F17]="FPR17", - [UNW_PPC32_F18]="FPR18", - [UNW_PPC32_F19]="FPR19", - [UNW_PPC32_F20]="FPR20", - [UNW_PPC32_F21]="FPR21", - [UNW_PPC32_F22]="FPR22", - [UNW_PPC32_F23]="FPR23", - [UNW_PPC32_F24]="FPR24", - [UNW_PPC32_F25]="FPR25", - [UNW_PPC32_F26]="FPR26", - [UNW_PPC32_F27]="FPR27", - [UNW_PPC32_F28]="FPR28", - [UNW_PPC32_F29]="FPR29", - [UNW_PPC32_F30]="FPR30", - [UNW_PPC32_F31]="FPR31" -}; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/ppc32/setcontext.S deleted file mode 100644 index b54378a9dc249d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/setcontext.S +++ /dev/null @@ -1,9 +0,0 @@ - .global _UI_setcontext - -_UI_setcontext: - retq - -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/ppc32/ucontext_i.h deleted file mode 100644 index c6ba806a00caa5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/ucontext_i.h +++ /dev/null @@ -1,128 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -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 ucontext_i_h -#define ucontext_i_h - -#include "compiler.h" -#include - -/* These values were derived by reading - /usr/src/linux-2.6.18-1.8/arch/um/include/sysdep-ppc/ptrace.h and - /usr/src/linux-2.6.18-1.8/arch/powerpc/kernel/ppc32.h -*/ - -//#define NIP_IDX 32 -#define CTR_IDX 32 -#define XER_IDX 33 -#define CCR_IDX 34 -#define MSR_IDX 35 -//#define MQ_IDX 36 -#define LINK_IDX 36 - -/* These are dummy structures used only for obtaining the offsets of the - various structure members. */ -static ucontext_t dmy_ctxt UNUSED; - -#define UC_MCONTEXT_GREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[0] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[1] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[2] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[3] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[4] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[5] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[6] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[7] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[8] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[9] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[10] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[11] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[12] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[13] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[14] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[15] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[16] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[17] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[18] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[19] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[20] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[21] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[22] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[23] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[24] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[25] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[26] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[27] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[28] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[29] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[30] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[31] - (void *)&dmy_ctxt) - -#define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[MSR_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CTR_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_LINK ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[LINK_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_XER ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[XER_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_CCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CCR_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_SOFTE ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[SOFTE_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_TRAP ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[TRAP_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_DAR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[DAR_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_DSISR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[DSISR_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_RESULT ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[RESULT_IDX] - (void *)&dmy_ctxt) - -#define UC_MCONTEXT_FREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[0] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[1] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[2] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[3] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[4] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[5] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[6] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[7] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[8] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[9] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[10] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[11] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[12] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[13] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[14] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[15] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[16] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[17] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[18] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[19] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[20] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[21] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[22] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[23] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[24] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[25] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[26] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[27] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[28] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[29] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[30] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[31] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[32] - (void *)&dmy_ctxt) - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/ppc32/unwind_i.h deleted file mode 100644 index ad32d0565441f4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/unwind_i.h +++ /dev/null @@ -1,46 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef unwind_i_h -#define unwind_i_h - -#include - -#include - -#include -#include - -#define ppc32_lock UNW_OBJ(lock) -#define ppc32_local_resume UNW_OBJ(local_resume) -#define ppc32_local_addr_space_init UNW_OBJ(local_addr_space_init) - -extern void ppc32_local_addr_space_init (void); -extern int ppc32_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, - void *arg); - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gcreate_addr_space.c deleted file mode 100644 index bd48555d4e8294..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gcreate_addr_space.c +++ /dev/null @@ -1,71 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* - * We support both big- and little-endian on Linux ppc64. - */ - if (byte_order != 0 - && byte_order != __LITTLE_ENDIAN - && byte_order != __BIG_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - if (byte_order == 0) - /* use host default: */ - as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); - else - as->big_endian = (byte_order == __BIG_ENDIAN); - - /* FIXME! There is no way to specify the ABI. - Default to ELFv1 on big-endian and ELFv2 on little-endian. */ - if (as->big_endian) - as->abi = UNW_PPC64_ABI_ELFv1; - else - as->abi = UNW_PPC64_ABI_ELFv2; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gglobal.c deleted file mode 100644 index 9d0b0f55a6c0d1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gglobal.c +++ /dev/null @@ -1,182 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "dwarf_i.h" - -HIDDEN define_lock (ppc64_lock); -HIDDEN int tdep_init_done; - -/* The API register numbers are exactly the same as the .eh_frame - registers, for now at least. */ -HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] = - { - [UNW_PPC64_R0]=UNW_PPC64_R0, - [UNW_PPC64_R1]=UNW_PPC64_R1, - [UNW_PPC64_R2]=UNW_PPC64_R2, - [UNW_PPC64_R3]=UNW_PPC64_R3, - [UNW_PPC64_R4]=UNW_PPC64_R4, - [UNW_PPC64_R5]=UNW_PPC64_R5, - [UNW_PPC64_R6]=UNW_PPC64_R6, - [UNW_PPC64_R7]=UNW_PPC64_R7, - [UNW_PPC64_R8]=UNW_PPC64_R8, - [UNW_PPC64_R9]=UNW_PPC64_R9, - [UNW_PPC64_R10]=UNW_PPC64_R10, - [UNW_PPC64_R11]=UNW_PPC64_R11, - [UNW_PPC64_R12]=UNW_PPC64_R12, - [UNW_PPC64_R13]=UNW_PPC64_R13, - [UNW_PPC64_R14]=UNW_PPC64_R14, - [UNW_PPC64_R15]=UNW_PPC64_R15, - [UNW_PPC64_R16]=UNW_PPC64_R16, - [UNW_PPC64_R17]=UNW_PPC64_R17, - [UNW_PPC64_R18]=UNW_PPC64_R18, - [UNW_PPC64_R19]=UNW_PPC64_R19, - [UNW_PPC64_R20]=UNW_PPC64_R20, - [UNW_PPC64_R21]=UNW_PPC64_R21, - [UNW_PPC64_R22]=UNW_PPC64_R22, - [UNW_PPC64_R23]=UNW_PPC64_R23, - [UNW_PPC64_R24]=UNW_PPC64_R24, - [UNW_PPC64_R25]=UNW_PPC64_R25, - [UNW_PPC64_R26]=UNW_PPC64_R26, - [UNW_PPC64_R27]=UNW_PPC64_R27, - [UNW_PPC64_R28]=UNW_PPC64_R28, - [UNW_PPC64_R29]=UNW_PPC64_R29, - [UNW_PPC64_R30]=UNW_PPC64_R30, - [UNW_PPC64_R31]=UNW_PPC64_R31, - - [UNW_PPC64_F0]=UNW_PPC64_F0, - [UNW_PPC64_F1]=UNW_PPC64_F1, - [UNW_PPC64_F2]=UNW_PPC64_F2, - [UNW_PPC64_F3]=UNW_PPC64_F3, - [UNW_PPC64_F4]=UNW_PPC64_F4, - [UNW_PPC64_F5]=UNW_PPC64_F5, - [UNW_PPC64_F6]=UNW_PPC64_F6, - [UNW_PPC64_F7]=UNW_PPC64_F7, - [UNW_PPC64_F8]=UNW_PPC64_F8, - [UNW_PPC64_F9]=UNW_PPC64_F9, - [UNW_PPC64_F10]=UNW_PPC64_F10, - [UNW_PPC64_F11]=UNW_PPC64_F11, - [UNW_PPC64_F12]=UNW_PPC64_F12, - [UNW_PPC64_F13]=UNW_PPC64_F13, - [UNW_PPC64_F14]=UNW_PPC64_F14, - [UNW_PPC64_F15]=UNW_PPC64_F15, - [UNW_PPC64_F16]=UNW_PPC64_F16, - [UNW_PPC64_F17]=UNW_PPC64_F17, - [UNW_PPC64_F18]=UNW_PPC64_F18, - [UNW_PPC64_F19]=UNW_PPC64_F19, - [UNW_PPC64_F20]=UNW_PPC64_F20, - [UNW_PPC64_F21]=UNW_PPC64_F21, - [UNW_PPC64_F22]=UNW_PPC64_F22, - [UNW_PPC64_F23]=UNW_PPC64_F23, - [UNW_PPC64_F24]=UNW_PPC64_F24, - [UNW_PPC64_F25]=UNW_PPC64_F25, - [UNW_PPC64_F26]=UNW_PPC64_F26, - [UNW_PPC64_F27]=UNW_PPC64_F27, - [UNW_PPC64_F28]=UNW_PPC64_F28, - [UNW_PPC64_F29]=UNW_PPC64_F29, - [UNW_PPC64_F30]=UNW_PPC64_F30, - [UNW_PPC64_F31]=UNW_PPC64_F31, - - [UNW_PPC64_LR]=UNW_PPC64_LR, - [UNW_PPC64_CTR]=UNW_PPC64_CTR, - [UNW_PPC64_ARG_POINTER]=UNW_PPC64_ARG_POINTER, - - [UNW_PPC64_CR0]=UNW_PPC64_CR0, - [UNW_PPC64_CR1]=UNW_PPC64_CR1, - [UNW_PPC64_CR2]=UNW_PPC64_CR2, - [UNW_PPC64_CR3]=UNW_PPC64_CR3, - [UNW_PPC64_CR4]=UNW_PPC64_CR4, - [UNW_PPC64_CR5]=UNW_PPC64_CR5, - [UNW_PPC64_CR6]=UNW_PPC64_CR6, - [UNW_PPC64_CR7]=UNW_PPC64_CR7, - - [UNW_PPC64_XER]=UNW_PPC64_XER, - - [UNW_PPC64_V0]=UNW_PPC64_V0, - [UNW_PPC64_V1]=UNW_PPC64_V1, - [UNW_PPC64_V2]=UNW_PPC64_V2, - [UNW_PPC64_V3]=UNW_PPC64_V3, - [UNW_PPC64_V4]=UNW_PPC64_V4, - [UNW_PPC64_V5]=UNW_PPC64_V5, - [UNW_PPC64_V6]=UNW_PPC64_V6, - [UNW_PPC64_V7]=UNW_PPC64_V7, - [UNW_PPC64_V8]=UNW_PPC64_V8, - [UNW_PPC64_V9]=UNW_PPC64_V9, - [UNW_PPC64_V10]=UNW_PPC64_V10, - [UNW_PPC64_V11]=UNW_PPC64_V11, - [UNW_PPC64_V12]=UNW_PPC64_V12, - [UNW_PPC64_V13]=UNW_PPC64_V13, - [UNW_PPC64_V14]=UNW_PPC64_V14, - [UNW_PPC64_V15]=UNW_PPC64_V15, - [UNW_PPC64_V16]=UNW_PPC64_V16, - [UNW_PPC64_V17]=UNW_PPC64_V17, - [UNW_PPC64_V18]=UNW_PPC64_V18, - [UNW_PPC64_V19]=UNW_PPC64_V19, - [UNW_PPC64_V20]=UNW_PPC64_V20, - [UNW_PPC64_V21]=UNW_PPC64_V21, - [UNW_PPC64_V22]=UNW_PPC64_V22, - [UNW_PPC64_V23]=UNW_PPC64_V23, - [UNW_PPC64_V24]=UNW_PPC64_V24, - [UNW_PPC64_V25]=UNW_PPC64_V25, - [UNW_PPC64_V26]=UNW_PPC64_V26, - [UNW_PPC64_V27]=UNW_PPC64_V27, - [UNW_PPC64_V28]=UNW_PPC64_V28, - [UNW_PPC64_V29]=UNW_PPC64_V29, - [UNW_PPC64_V30]=UNW_PPC64_V30, - [UNW_PPC64_V31]=UNW_PPC64_V31, - - [UNW_PPC64_VRSAVE]=UNW_PPC64_VRSAVE, - [UNW_PPC64_VSCR]=UNW_PPC64_VSCR, - [UNW_PPC64_SPE_ACC]=UNW_PPC64_SPE_ACC, - [UNW_PPC64_SPEFSCR]=UNW_PPC64_SPEFSCR, - }; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&ppc64_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - dwarf_init (); - -#ifndef UNW_REMOTE_ONLY - ppc64_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&ppc64_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c deleted file mode 100644 index 4c88cd6e77ff0d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c +++ /dev/null @@ -1,229 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include - -#include "ucontext_i.h" -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -static void * -uc_addr (ucontext_t *uc, int reg) -{ - void *addr; - - if ((unsigned) (reg - UNW_PPC64_R0) < 32) - addr = &uc->uc_mcontext.gp_regs[reg - UNW_PPC64_R0]; - - else if ((unsigned) (reg - UNW_PPC64_F0) < 32) - addr = &uc->uc_mcontext.fp_regs[reg - UNW_PPC64_F0]; - - else if ((unsigned) (reg - UNW_PPC64_V0) < 32) - addr = (uc->uc_mcontext.v_regs == 0) ? NULL : &uc->uc_mcontext.v_regs->vrregs[reg - UNW_PPC64_V0][0]; - - else - { - unsigned gregs_idx; - - switch (reg) - { - case UNW_PPC64_NIP: - gregs_idx = NIP_IDX; - break; - case UNW_PPC64_CTR: - gregs_idx = CTR_IDX; - break; - case UNW_PPC64_LR: - gregs_idx = LINK_IDX; - break; - case UNW_PPC64_XER: - gregs_idx = XER_IDX; - break; - case UNW_PPC64_CR0: - gregs_idx = CCR_IDX; - break; - default: - return NULL; - } - addr = &uc->uc_mcontext.gp_regs[gregs_idx]; - } - return addr; -} - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) -{ - return uc_addr (uc, reg); -} - -# endif /* UNW_LOCAL_ONLY */ - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (write) - { - Debug (12, "mem[%lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "mem[%lx] -> %lx\n", addr, *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, - int write, void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = arg; - - if (UNW_PPC64_F0 <= reg && reg <= UNW_PPC64_F31) - goto badreg; - if (UNW_PPC64_V0 <= reg && reg <= UNW_PPC64_V31) - goto badreg; - - addr = uc_addr (uc, reg); - if (!addr) - goto badreg; - - if (write) - { - *(unw_word_t *) addr = *val; - Debug (12, "%s <- %lx\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> %lx\n", unw_regname (reg), *val); - } - return 0; - -badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = arg; - unw_fpreg_t *addr; - - /* Allow only 32 fregs and 32 vregs */ - if (!(((unsigned) (reg - UNW_PPC64_F0) < 32) - ||((unsigned) (reg - UNW_PPC64_V0) < 32))) - goto badreg; - - addr = uc_addr (uc, reg); - if (!addr) - goto badreg; - - if (write) - { - Debug (12, "%s <- %016Lf\n", unw_regname (reg), *val); - *(unw_fpreg_t *) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %016Lf\n", unw_regname (reg), *val); - } - return 0; - -badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -ppc64_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); -#if _CALL_ELF == 2 - local_addr_space.abi = UNW_PPC64_ABI_ELFv2; -#else - local_addr_space.abi = UNW_PPC64_ABI_ELFv1; -#endif - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = ppc64_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gregs.c deleted file mode 100644 index 1cb5d9dc6537d6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gregs.c +++ /dev/null @@ -1,141 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - struct dwarf_loc loc; - - switch (reg) - { - case UNW_PPC64_R0: - case UNW_PPC64_R2: - case UNW_PPC64_R3: - case UNW_PPC64_R4: - case UNW_PPC64_R5: - case UNW_PPC64_R6: - case UNW_PPC64_R7: - case UNW_PPC64_R8: - case UNW_PPC64_R9: - case UNW_PPC64_R10: - case UNW_PPC64_R11: - case UNW_PPC64_R12: - case UNW_PPC64_R13: - case UNW_PPC64_R14: - case UNW_PPC64_R15: - case UNW_PPC64_R16: - case UNW_PPC64_R17: - case UNW_PPC64_R18: - case UNW_PPC64_R19: - case UNW_PPC64_R20: - case UNW_PPC64_R21: - case UNW_PPC64_R22: - case UNW_PPC64_R23: - case UNW_PPC64_R24: - case UNW_PPC64_R25: - case UNW_PPC64_R26: - case UNW_PPC64_R27: - case UNW_PPC64_R28: - case UNW_PPC64_R29: - case UNW_PPC64_R30: - case UNW_PPC64_R31: - case UNW_PPC64_LR: - case UNW_PPC64_CTR: - case UNW_PPC64_CR0: - case UNW_PPC64_CR1: - case UNW_PPC64_CR2: - case UNW_PPC64_CR3: - case UNW_PPC64_CR4: - case UNW_PPC64_CR5: - case UNW_PPC64_CR6: - case UNW_PPC64_CR7: - case UNW_PPC64_VRSAVE: - case UNW_PPC64_VSCR: - case UNW_PPC64_SPE_ACC: - case UNW_PPC64_SPEFSCR: - loc = c->dwarf.loc[reg]; - break; - - case UNW_TDEP_IP: - if (write) - { - c->dwarf.ip = *valp; /* update the IP cache */ - if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip - || *valp >= c->dwarf.pi.end_ip)) - c->dwarf.pi_valid = 0; /* new IP outside of current proc */ - } - else - *valp = c->dwarf.ip; - return 0; - - case UNW_TDEP_SP: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - default: - return -UNW_EBADREG; - break; - } - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - struct dwarf_loc loc; - - if ((unsigned) (reg - UNW_PPC64_F0) < 32) - { - loc = c->dwarf.loc[reg]; - if (write) - return dwarf_putfp (&c->dwarf, loc, *valp); - else - return dwarf_getfp (&c->dwarf, loc, valp); - } - else - if ((unsigned) (reg - UNW_PPC64_V0) < 32) - { - loc = c->dwarf.loc[reg]; - if (write) - return dwarf_putvr (&c->dwarf, loc, *valp); - else - return dwarf_getvr (&c->dwarf, loc, valp); - } - - return -UNW_EBADREG; -} - diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gresume.c deleted file mode 100644 index 0d832d0d97bd34..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gresume.c +++ /dev/null @@ -1,111 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford cjashfor@us.ibm.com - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -#ifndef UNW_REMOTE_ONLY - -#include - -/* sigreturn() is a no-op on x86_64 glibc. */ - -static NORETURN inline long -my_rt_sigreturn (void *new_sp) -{ - /* XXX: empty stub. */ - abort (); -} - -HIDDEN inline int -ppc64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - struct cursor *c = (struct cursor *) cursor; - ucontext_t *uc = (ucontext_t *)c->dwarf.as_arg; - - if (unlikely (c->sigcontext_format != PPC_SCF_NONE)) - { - my_rt_sigreturn(cursor); - abort(); - } - else - { - Debug (8, "resuming at ip=%llx via setcontext()\n", - (unsigned long long) c->dwarf.ip); - setcontext (uc); - } - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ - -/* This routine is responsible for copying the register values in - cursor C and establishing them as the current machine state. */ - -static inline int -establish_machine_state (struct cursor *c) -{ - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_REG_LAST; ++reg) - { - Debug (16, "copying %s %d\n", unw_regname (reg), reg); - if (unw_is_fpreg (reg)) - { - if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) - as->acc.access_fpreg (as, reg, &fpval, 1, arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - as->acc.access_reg (as, reg, &val, 1, arg); - } - } - return 0; -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p)\n", c); - - if ((ret = establish_machine_state (c)) < 0) - return ret; - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gstep.c deleted file mode 100644 index f44e9591054718..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gstep.c +++ /dev/null @@ -1,466 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "ucontext_i.h" -#include "remote.h" -#include - -/* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is - defined there only when __KERNEL__ is defined. We reproduce it here for - our use at the user level in order to locate the ucontext record, which - appears to be at this offset relative to the stack pointer when in the - context of the signal handler return trampoline code - - __kernel_sigtramp_rt64. */ -#define __SIGNAL_FRAMESIZE 128 - -/* This definition comes from the document "64-bit PowerPC ELF Application - Binary Interface Supplement 1.9", section 3.2.2. - http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */ - -typedef struct -{ - long unsigned back_chain; - long unsigned cr_save; - long unsigned lr_save; - /* many more fields here, but they are unused by this code */ -} stack_frame_t; - - -int -unw_step (unw_cursor_t * cursor) -{ - struct cursor *c = (struct cursor *) cursor; - stack_frame_t dummy; - unw_word_t back_chain_offset, lr_save_offset, v_regs_ptr; - struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc, v_regs_loc; - int ret, i; - - Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); - - /* Try DWARF-based unwinding... */ - - ret = dwarf_step (&c->dwarf); - - if (ret < 0 && ret != -UNW_ENOINFO) - { - Debug (2, "returning %d\n", ret); - return ret; - } - - if (unlikely (ret < 0)) - { - if (likely (unw_is_signal_frame (cursor) <= 0)) - { - /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode - produces the mandatory level of traceback record in the code, but - I get the impression that this is transitory, that eventually gcc - will not produce any traceback records at all. So, for now, we - won't bother to try to find and use these records. - - We can, however, attempt to unwind the frame by using the callback - chain. This is very crude, however, and won't be able to unwind - any registers besides the IP, SP, and LR . */ - - back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy); - lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy); - - back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0); - - if ((ret = - dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0) - { - Debug (2, - "Unable to retrieve CFA from back chain in stack frame - %d\n", - ret); - return ret; - } - if (c->dwarf.cfa == 0) - /* Unless the cursor or stack is corrupt or uninitialized we've most - likely hit the top of the stack */ - return 0; - - lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0); - - if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0) - { - Debug (2, - "Unable to retrieve IP from lr save in stack frame - %d\n", - ret); - return ret; - } - - /* Mark all registers unsaved */ - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - ret = 1; - } - else - { - /* Find the sigcontext record by taking the CFA and adjusting by - the dummy signal frame size. - - Note that there isn't any way to determined if SA_SIGINFO was - set in the sa_flags parameter to sigaction when the signal - handler was established. If it was not set, the ucontext - record is not required to be on the stack, in which case the - following code will likely cause a seg fault or other crash - condition. */ - - unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE; - - Debug (1, "signal frame, skip over trampoline\n"); - - c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME; - c->sigcontext_addr = ucontext; - - sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); - ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0); - - ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - - /* Instead of just restoring the non-volatile registers, do all - of the registers for now. This will incur a performance hit, - but it's rare enough not to cause too much of a problem, and - might be useful in some cases. */ - c->dwarf.loc[UNW_PPC64_R0] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0); - c->dwarf.loc[UNW_PPC64_R1] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); - c->dwarf.loc[UNW_PPC64_R2] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0); - c->dwarf.loc[UNW_PPC64_R3] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0); - c->dwarf.loc[UNW_PPC64_R4] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0); - c->dwarf.loc[UNW_PPC64_R5] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0); - c->dwarf.loc[UNW_PPC64_R6] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0); - c->dwarf.loc[UNW_PPC64_R7] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0); - c->dwarf.loc[UNW_PPC64_R8] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); - c->dwarf.loc[UNW_PPC64_R9] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); - c->dwarf.loc[UNW_PPC64_R10] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); - c->dwarf.loc[UNW_PPC64_R11] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); - c->dwarf.loc[UNW_PPC64_R12] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); - c->dwarf.loc[UNW_PPC64_R13] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); - c->dwarf.loc[UNW_PPC64_R14] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); - c->dwarf.loc[UNW_PPC64_R15] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); - c->dwarf.loc[UNW_PPC64_R16] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0); - c->dwarf.loc[UNW_PPC64_R17] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0); - c->dwarf.loc[UNW_PPC64_R18] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0); - c->dwarf.loc[UNW_PPC64_R19] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0); - c->dwarf.loc[UNW_PPC64_R20] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0); - c->dwarf.loc[UNW_PPC64_R21] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0); - c->dwarf.loc[UNW_PPC64_R22] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0); - c->dwarf.loc[UNW_PPC64_R23] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0); - c->dwarf.loc[UNW_PPC64_R24] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0); - c->dwarf.loc[UNW_PPC64_R25] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0); - c->dwarf.loc[UNW_PPC64_R26] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0); - c->dwarf.loc[UNW_PPC64_R27] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0); - c->dwarf.loc[UNW_PPC64_R28] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0); - c->dwarf.loc[UNW_PPC64_R29] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0); - c->dwarf.loc[UNW_PPC64_R30] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0); - c->dwarf.loc[UNW_PPC64_R31] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0); - - c->dwarf.loc[UNW_PPC64_LR] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); - c->dwarf.loc[UNW_PPC64_CTR] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0); - /* This CR0 assignment is probably wrong. There are 8 dwarf columns - assigned to the CR registers, but only one CR register in the - mcontext structure */ - c->dwarf.loc[UNW_PPC64_CR0] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0); - c->dwarf.loc[UNW_PPC64_XER] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0); - c->dwarf.loc[UNW_PPC64_NIP] = - DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0); - - /* TODO: Is there a way of obtaining the value of the - pseudo frame pointer (which is sp + some fixed offset, I - assume), based on the contents of the ucontext record - structure? For now, set this loc to null. */ - c->dwarf.loc[UNW_PPC64_FRAME_POINTER] = DWARF_NULL_LOC; - - c->dwarf.loc[UNW_PPC64_F0] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0); - c->dwarf.loc[UNW_PPC64_F1] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0); - c->dwarf.loc[UNW_PPC64_F2] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0); - c->dwarf.loc[UNW_PPC64_F3] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0); - c->dwarf.loc[UNW_PPC64_F4] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0); - c->dwarf.loc[UNW_PPC64_F5] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0); - c->dwarf.loc[UNW_PPC64_F6] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0); - c->dwarf.loc[UNW_PPC64_F7] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0); - c->dwarf.loc[UNW_PPC64_F8] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0); - c->dwarf.loc[UNW_PPC64_F9] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0); - c->dwarf.loc[UNW_PPC64_F10] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0); - c->dwarf.loc[UNW_PPC64_F11] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0); - c->dwarf.loc[UNW_PPC64_F12] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0); - c->dwarf.loc[UNW_PPC64_F13] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0); - c->dwarf.loc[UNW_PPC64_F14] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0); - c->dwarf.loc[UNW_PPC64_F15] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0); - c->dwarf.loc[UNW_PPC64_F16] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0); - c->dwarf.loc[UNW_PPC64_F17] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0); - c->dwarf.loc[UNW_PPC64_F18] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0); - c->dwarf.loc[UNW_PPC64_F19] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0); - c->dwarf.loc[UNW_PPC64_F20] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0); - c->dwarf.loc[UNW_PPC64_F21] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0); - c->dwarf.loc[UNW_PPC64_F22] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0); - c->dwarf.loc[UNW_PPC64_F23] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0); - c->dwarf.loc[UNW_PPC64_F24] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0); - c->dwarf.loc[UNW_PPC64_F25] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0); - c->dwarf.loc[UNW_PPC64_F26] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0); - c->dwarf.loc[UNW_PPC64_F27] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0); - c->dwarf.loc[UNW_PPC64_F28] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0); - c->dwarf.loc[UNW_PPC64_F29] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0); - c->dwarf.loc[UNW_PPC64_F30] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0); - c->dwarf.loc[UNW_PPC64_F31] = - DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0); - /* Note that there is no .eh_section register column for the - FPSCR register. I don't know why this is. */ - - v_regs_loc = DWARF_LOC (ucontext + UC_MCONTEXT_V_REGS, 0); - ret = dwarf_get (&c->dwarf, v_regs_loc, &v_regs_ptr); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - if (v_regs_ptr != 0) - { - /* The v_regs_ptr is not null. Set all of the AltiVec locs */ - - c->dwarf.loc[UNW_PPC64_V0] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R0, 0); - c->dwarf.loc[UNW_PPC64_V1] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R1, 0); - c->dwarf.loc[UNW_PPC64_V2] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R2, 0); - c->dwarf.loc[UNW_PPC64_V3] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R3, 0); - c->dwarf.loc[UNW_PPC64_V4] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R4, 0); - c->dwarf.loc[UNW_PPC64_V5] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R5, 0); - c->dwarf.loc[UNW_PPC64_V6] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R6, 0); - c->dwarf.loc[UNW_PPC64_V7] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R7, 0); - c->dwarf.loc[UNW_PPC64_V8] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R8, 0); - c->dwarf.loc[UNW_PPC64_V9] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R9, 0); - c->dwarf.loc[UNW_PPC64_V10] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R10, 0); - c->dwarf.loc[UNW_PPC64_V11] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R11, 0); - c->dwarf.loc[UNW_PPC64_V12] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R12, 0); - c->dwarf.loc[UNW_PPC64_V13] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R13, 0); - c->dwarf.loc[UNW_PPC64_V14] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R14, 0); - c->dwarf.loc[UNW_PPC64_V15] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R15, 0); - c->dwarf.loc[UNW_PPC64_V16] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R16, 0); - c->dwarf.loc[UNW_PPC64_V17] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R17, 0); - c->dwarf.loc[UNW_PPC64_V18] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R18, 0); - c->dwarf.loc[UNW_PPC64_V19] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R19, 0); - c->dwarf.loc[UNW_PPC64_V20] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R20, 0); - c->dwarf.loc[UNW_PPC64_V21] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R21, 0); - c->dwarf.loc[UNW_PPC64_V22] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R22, 0); - c->dwarf.loc[UNW_PPC64_V23] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R23, 0); - c->dwarf.loc[UNW_PPC64_V24] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R24, 0); - c->dwarf.loc[UNW_PPC64_V25] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R25, 0); - c->dwarf.loc[UNW_PPC64_V26] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R26, 0); - c->dwarf.loc[UNW_PPC64_V27] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R27, 0); - c->dwarf.loc[UNW_PPC64_V28] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R28, 0); - c->dwarf.loc[UNW_PPC64_V29] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R29, 0); - c->dwarf.loc[UNW_PPC64_V30] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R30, 0); - c->dwarf.loc[UNW_PPC64_V31] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R31, 0); - c->dwarf.loc[UNW_PPC64_VRSAVE] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VRSAVE, 0); - c->dwarf.loc[UNW_PPC64_VSCR] = - DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VSCR, 0); - } - else - { - c->dwarf.loc[UNW_PPC64_V0] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V1] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V2] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V3] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V4] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V5] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V6] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V7] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V8] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V9] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V10] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V11] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V12] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V13] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V14] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V15] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V16] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V17] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V18] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V19] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V20] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V21] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V22] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V23] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V24] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V25] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V26] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V27] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V28] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V29] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V30] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_V31] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_NULL_LOC; - c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_NULL_LOC; - } - ret = 1; - } - } - - if (c->dwarf.ip == 0) - { - /* Unless the cursor or stack is corrupt or uninitialized, - we've most likely hit the top of the stack */ - Debug (2, "returning 0\n"); - return 0; - } - - // on ppc64, R2 register is used as pointer to TOC - // section which is used for symbol lookup in PIC code - // ppc64 linker generates "ld r2, 40(r1)" (ELFv1) or - // "ld r2, 24(r1)" (ELFv2) instruction after each - // @plt call. We need restore R2, but only for @plt calls - { - unw_word_t ip = c->dwarf.ip; - unw_addr_space_t as = c->dwarf.as; - unw_accessors_t *a = unw_get_accessors_int (as); - void *arg = c->dwarf.as_arg; - uint32_t toc_save = (as->abi == UNW_PPC64_ABI_ELFv2)? 24 : 40; - int32_t inst; - - if (fetch32 (as, a, &ip, &inst, arg) >= 0 - && (uint32_t)inst == (0xE8410000U + toc_save)) - { - // @plt call, restoring R2 from CFA+toc_save - c->dwarf.loc[UNW_PPC64_R2] = DWARF_LOC(c->dwarf.cfa + toc_save, 0); - } - } - - Debug (2, "returning %d with last return statement\n", ret); - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lglobal.c deleted file mode 100644 index 6d7b489e14bd9f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lglobal.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Linit.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/get_func_addr.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/get_func_addr.c deleted file mode 100644 index 80a58fa1f80935..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/get_func_addr.c +++ /dev/null @@ -1,51 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, - unw_word_t *entry_point) -{ - if (as->abi == UNW_PPC64_ABI_ELFv1) - { - unw_accessors_t *a; - int ret; - - a = unw_get_accessors_int (as); - /* Entry-point is stored in the 1st word of the function descriptor. - In case that changes in the future, we'd have to update the line - below and read the word at addr + offset: */ - ret = (*a->access_mem) (as, addr, entry_point, 0, NULL); - if (ret < 0) - return ret; - } - else - *entry_point = addr; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/init.h b/src/coreclr/src/pal/src/libunwind/src/ppc64/init.h deleted file mode 100644 index 9b8139343d688a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/init.h +++ /dev/null @@ -1,82 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static inline int -common_init_ppc64 (struct cursor *c, unsigned use_prev_instr) -{ - int ret; - int i; - - for (i = UNW_PPC64_R0; i <= UNW_PPC64_R31; i++) { - c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); - } - for (i = UNW_PPC64_F0; i <= UNW_PPC64_F31; i++) { - c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i); - } - for (i = UNW_PPC64_V0; i <= UNW_PPC64_V31; i++) { - c->dwarf.loc[i] = DWARF_VREG_LOC (&c->dwarf, i); - } - - for (i = UNW_PPC64_CR0; i <= UNW_PPC64_CR7; i++) { - c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); - } - c->dwarf.loc[UNW_PPC64_ARG_POINTER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_ARG_POINTER); - c->dwarf.loc[UNW_PPC64_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_CTR); - c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_VSCR); - - c->dwarf.loc[UNW_PPC64_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_XER); - c->dwarf.loc[UNW_PPC64_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_LR); - c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_VRSAVE); - c->dwarf.loc[UNW_PPC64_SPEFSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_SPEFSCR); - c->dwarf.loc[UNW_PPC64_SPE_ACC] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_SPE_ACC); - - c->dwarf.loc[UNW_PPC64_NIP] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_NIP); - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC64_NIP], &c->dwarf.ip); - if (ret < 0) - return ret; - - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_PPC64_R1), - &c->dwarf.cfa); - if (ret < 0) - return ret; - - c->sigcontext_format = PPC_SCF_NONE; - c->sigcontext_addr = 0; - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/is_fpreg.c deleted file mode 100644 index 653964a7dad25a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/is_fpreg.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_is_fpreg (int regnum) -{ - return (regnum >= UNW_PPC64_F0 && regnum <= UNW_PPC64_F31); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/regname.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/regname.c deleted file mode 100644 index 58c6fa6d87468e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/regname.c +++ /dev/null @@ -1,164 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static const char *regname[] = - { - [UNW_PPC64_R0]="GPR0", - [UNW_PPC64_R1]="GPR1", - [UNW_PPC64_R2]="GPR2", - [UNW_PPC64_R3]="GPR3", - [UNW_PPC64_R4]="GPR4", - [UNW_PPC64_R5]="GPR5", - [UNW_PPC64_R6]="GPR6", - [UNW_PPC64_R7]="GPR7", - [UNW_PPC64_R8]="GPR8", - [UNW_PPC64_R9]="GPR9", - [UNW_PPC64_R10]="GPR10", - [UNW_PPC64_R11]="GPR11", - [UNW_PPC64_R12]="GPR12", - [UNW_PPC64_R13]="GPR13", - [UNW_PPC64_R14]="GPR14", - [UNW_PPC64_R15]="GPR15", - [UNW_PPC64_R16]="GPR16", - [UNW_PPC64_R17]="GPR17", - [UNW_PPC64_R18]="GPR18", - [UNW_PPC64_R19]="GPR19", - [UNW_PPC64_R20]="GPR20", - [UNW_PPC64_R21]="GPR21", - [UNW_PPC64_R22]="GPR22", - [UNW_PPC64_R23]="GPR23", - [UNW_PPC64_R24]="GPR24", - [UNW_PPC64_R25]="GPR25", - [UNW_PPC64_R26]="GPR26", - [UNW_PPC64_R27]="GPR27", - [UNW_PPC64_R28]="GPR28", - [UNW_PPC64_R29]="GPR29", - [UNW_PPC64_R30]="GPR30", - [UNW_PPC64_R31]="GPR31", - - [UNW_PPC64_F0]="FPR0", - [UNW_PPC64_F1]="FPR1", - [UNW_PPC64_F2]="FPR2", - [UNW_PPC64_F3]="FPR3", - [UNW_PPC64_F4]="FPR4", - [UNW_PPC64_F5]="FPR5", - [UNW_PPC64_F6]="FPR6", - [UNW_PPC64_F7]="FPR7", - [UNW_PPC64_F8]="FPR8", - [UNW_PPC64_F9]="FPR9", - [UNW_PPC64_F10]="FPR10", - [UNW_PPC64_F11]="FPR11", - [UNW_PPC64_F12]="FPR12", - [UNW_PPC64_F13]="FPR13", - [UNW_PPC64_F14]="FPR14", - [UNW_PPC64_F15]="FPR15", - [UNW_PPC64_F16]="FPR16", - [UNW_PPC64_F17]="FPR17", - [UNW_PPC64_F18]="FPR18", - [UNW_PPC64_F19]="FPR19", - [UNW_PPC64_F20]="FPR20", - [UNW_PPC64_F21]="FPR21", - [UNW_PPC64_F22]="FPR22", - [UNW_PPC64_F23]="FPR23", - [UNW_PPC64_F24]="FPR24", - [UNW_PPC64_F25]="FPR25", - [UNW_PPC64_F26]="FPR26", - [UNW_PPC64_F27]="FPR27", - [UNW_PPC64_F28]="FPR28", - [UNW_PPC64_F29]="FPR29", - [UNW_PPC64_F30]="FPR30", - [UNW_PPC64_F31]="FPR31", - - [UNW_PPC64_LR]="LR", - [UNW_PPC64_CTR]="CTR", - [UNW_PPC64_ARG_POINTER]="ARG_POINTER", - - [UNW_PPC64_CR0]="CR0", - [UNW_PPC64_CR1]="CR1", - [UNW_PPC64_CR2]="CR2", - [UNW_PPC64_CR3]="CR3", - [UNW_PPC64_CR4]="CR4", - [UNW_PPC64_CR5]="CR5", - [UNW_PPC64_CR6]="CR6", - [UNW_PPC64_CR7]="CR7", - - [UNW_PPC64_XER]="XER", - - [UNW_PPC64_V0]="VR0", - [UNW_PPC64_V1]="VR1", - [UNW_PPC64_V2]="VR2", - [UNW_PPC64_V3]="VR3", - [UNW_PPC64_V4]="VR4", - [UNW_PPC64_V5]="VR5", - [UNW_PPC64_V6]="VR6", - [UNW_PPC64_V7]="VR7", - [UNW_PPC64_V8]="VR8", - [UNW_PPC64_V9]="VR9", - [UNW_PPC64_V10]="VR10", - [UNW_PPC64_V11]="VR11", - [UNW_PPC64_V12]="VR12", - [UNW_PPC64_V13]="VR13", - [UNW_PPC64_V14]="VR14", - [UNW_PPC64_V15]="VR15", - [UNW_PPC64_V16]="VR16", - [UNW_PPC64_V17]="VR17", - [UNW_PPC64_V18]="VR18", - [UNW_PPC64_V19]="VR19", - [UNW_PPC64_V20]="VR20", - [UNW_PPC64_V21]="VR21", - [UNW_PPC64_V22]="VR22", - [UNW_PPC64_V23]="VR23", - [UNW_PPC64_V24]="VR24", - [UNW_PPC64_V25]="VR25", - [UNW_PPC64_V26]="VR26", - [UNW_PPC64_V27]="VR27", - [UNW_PPC64_V28]="VR28", - [UNW_PPC64_V29]="VR29", - [UNW_PPC64_V30]="VR30", - [UNW_PPC64_V31]="VR31", - - [UNW_PPC64_VSCR]="VSCR", - - [UNW_PPC64_VRSAVE]="VRSAVE", - [UNW_PPC64_SPE_ACC]="SPE_ACC", - [UNW_PPC64_SPEFSCR]="SPEFSCR", - - [UNW_PPC64_FRAME_POINTER]="FRAME_POINTER", - [UNW_PPC64_NIP]="NIP", - - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/ppc64/setcontext.S deleted file mode 100644 index ffc2500a517387..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/setcontext.S +++ /dev/null @@ -1,9 +0,0 @@ - .global _UI_setcontext - -_UI_setcontext: - blr - -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/ppc64/ucontext_i.h deleted file mode 100644 index 2ddfdb865a71b0..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/ucontext_i.h +++ /dev/null @@ -1,173 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -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 ucontext_i_h -#define ucontext_i_h - -#include - -/* These values were derived by reading - /usr/src/linux-2.6.18-1.8/arch/um/include/sysdep-ppc/ptrace.h and - /usr/src/linux-2.6.18-1.8/arch/powerpc/kernel/ppc32.h -*/ - -#define NIP_IDX 32 -#define MSR_IDX 33 -#define ORIG_GPR3_IDX 34 -#define CTR_IDX 35 -#define LINK_IDX 36 -#define XER_IDX 37 -#define CCR_IDX 38 -#define SOFTE_IDX 39 -#define TRAP_IDX 40 -#define DAR_IDX 41 -#define DSISR_IDX 42 -#define RESULT_IDX 43 - -#define VSCR_IDX 32 -#define VRSAVE_IDX 33 - -/* These are dummy structures used only for obtaining the offsets of the - various structure members. */ -static ucontext_t dmy_ctxt; -static vrregset_t dmy_vrregset; - -#define UC_MCONTEXT_GREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[0] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[1] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[2] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[3] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[4] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[5] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[6] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[7] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[8] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[9] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[10] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[11] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[12] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[13] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[14] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[15] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[16] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[17] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[18] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[19] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[20] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[21] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[22] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[23] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[24] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[25] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[26] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[27] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[28] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[29] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[30] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[31] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_NIP ((void *)&dmy_ctxt.uc_mcontext.gp_regs[NIP_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[MSR_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[CTR_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_LINK ((void *)&dmy_ctxt.uc_mcontext.gp_regs[LINK_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_XER ((void *)&dmy_ctxt.uc_mcontext.gp_regs[XER_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_CCR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[CCR_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_SOFTE ((void *)&dmy_ctxt.uc_mcontext.gp_regs[SOFTE_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_TRAP ((void *)&dmy_ctxt.uc_mcontext.gp_regs[TRAP_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_DAR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[DAR_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_DSISR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[DSISR_IDX] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_GREGS_RESULT ((void *)&dmy_ctxt.uc_mcontext.gp_regs[RESULT_IDX] - (void *)&dmy_ctxt) - -#define UC_MCONTEXT_FREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[0] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[1] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[2] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[3] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[4] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[5] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[6] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[7] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[8] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[9] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[10] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[11] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[12] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[13] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[14] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[15] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[16] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[17] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[18] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[19] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[20] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[21] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[22] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[23] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[24] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[25] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[26] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[27] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[28] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[29] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[30] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[31] - (void *)&dmy_ctxt) -#define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.fp_regs[32] - (void *)&dmy_ctxt) - -#define UC_MCONTEXT_V_REGS ((void *)&dmy_ctxt.uc_mcontext.v_regs - (void *)&dmy_ctxt) - -#define UC_MCONTEXT_VREGS_R0 ((void *)&dmy_vrregset.vrregs[0] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R1 ((void *)&dmy_vrregset.vrregs[1] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R2 ((void *)&dmy_vrregset.vrregs[2] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R3 ((void *)&dmy_vrregset.vrregs[3] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R4 ((void *)&dmy_vrregset.vrregs[4] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R5 ((void *)&dmy_vrregset.vrregs[5] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R6 ((void *)&dmy_vrregset.vrregs[6] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R7 ((void *)&dmy_vrregset.vrregs[7] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R8 ((void *)&dmy_vrregset.vrregs[8] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R9 ((void *)&dmy_vrregset.vrregs[9] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R10 ((void *)&dmy_vrregset.vrregs[10] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R11 ((void *)&dmy_vrregset.vrregs[11] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R12 ((void *)&dmy_vrregset.vrregs[12] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R13 ((void *)&dmy_vrregset.vrregs[13] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R14 ((void *)&dmy_vrregset.vrregs[14] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R15 ((void *)&dmy_vrregset.vrregs[15] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R16 ((void *)&dmy_vrregset.vrregs[16] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R17 ((void *)&dmy_vrregset.vrregs[17] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R18 ((void *)&dmy_vrregset.vrregs[18] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R19 ((void *)&dmy_vrregset.vrregs[19] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R20 ((void *)&dmy_vrregset.vrregs[20] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R21 ((void *)&dmy_vrregset.vrregs[21] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R22 ((void *)&dmy_vrregset.vrregs[22] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R23 ((void *)&dmy_vrregset.vrregs[23] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R24 ((void *)&dmy_vrregset.vrregs[24] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R25 ((void *)&dmy_vrregset.vrregs[25] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R26 ((void *)&dmy_vrregset.vrregs[26] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R27 ((void *)&dmy_vrregset.vrregs[27] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R28 ((void *)&dmy_vrregset.vrregs[28] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R29 ((void *)&dmy_vrregset.vrregs[29] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R30 ((void *)&dmy_vrregset.vrregs[30] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_R31 ((void *)&dmy_vrregset.vrregs[31] - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_VSCR ((void *)&dmy_vrregset.vscr - (void *)&dmy_vrregset) -#define UC_MCONTEXT_VREGS_VRSAVE ((void *)&dmy_vrregset.vrsave - (void *)&dmy_vrregset) - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/ppc64/unwind_i.h deleted file mode 100644 index 26bbc2df83af7f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/unwind_i.h +++ /dev/null @@ -1,52 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef unwind_i_h -#define unwind_i_h - -#include - -#include - -#include -#include - -#define ppc64_lock UNW_OBJ(lock) -#define ppc64_local_resume UNW_OBJ(local_resume) -#define ppc64_local_addr_space_init UNW_OBJ(local_addr_space_init) -#if 0 -#define ppc64_scratch_loc UNW_OBJ(scratch_loc) -#endif - -extern void ppc64_local_addr_space_init (void); -extern int ppc64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, - void *arg); -#if 0 -extern dwarf_loc_t ppc64_scratch_loc (struct cursor *c, unw_regnum_t reg); -#endif - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c deleted file mode 100644 index 2b92462fa927f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c +++ /dev/null @@ -1,121 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - Copyright (C) 2010 Konstantin Belousov - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UPT_internal.h" - -#if HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE -int -_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - unw_word_t *wp = (unw_word_t *) val; - struct UPT_info *ui = arg; - pid_t pid = ui->pid; - int i; - - if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) - return -UNW_EBADREG; - - errno = 0; - if (write) - for (i = 0; i < (int) (sizeof (*val) / sizeof (wp[i])); ++i) - { -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - ptrace (PTRACE_POKEUSER, pid, _UPT_reg_offset[reg] + i * sizeof(wp[i]), - wp[i]); -#endif - if (errno) - return -UNW_EBADREG; - } - else - for (i = 0; i < (int) (sizeof (*val) / sizeof (wp[i])); ++i) - { -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - wp[i] = ptrace (PTRACE_PEEKUSER, pid, - _UPT_reg_offset[reg] + i * sizeof(wp[i]), 0); -#endif - if (errno) - return -UNW_EBADREG; - } - return 0; -} -#elif HAVE_DECL_PT_GETFPREGS -int -_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - struct UPT_info *ui = arg; - pid_t pid = ui->pid; - fpregset_t fpreg; - -#if defined(__amd64__) - if (1) /* XXXKIB */ - return -UNW_EBADREG; -#elif defined(__i386__) - if ((unsigned) reg < UNW_X86_ST0 || (unsigned) reg > UNW_X86_ST7) - return -UNW_EBADREG; -#elif defined(__arm__) - if ((unsigned) reg < UNW_ARM_F0 || (unsigned) reg > UNW_ARM_F7) - return -UNW_EBADREG; -#else -#error Fix me -#endif - if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) - return -UNW_EBADREG; - - if (ptrace(PT_GETFPREGS, pid, (caddr_t)&fpreg, 0) == -1) - return -UNW_EBADREG; - if (write) { -#if defined(__amd64__) - memcpy(&fpreg.fpr_xacc[reg], val, sizeof(unw_fpreg_t)); -#elif defined(__i386__) - memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t)); -#elif defined(__arm__) - memcpy(&fpreg.fpr[reg], val, sizeof(unw_fpreg_t)); -#else -#error Fix me -#endif - if (ptrace(PT_SETFPREGS, pid, (caddr_t)&fpreg, 0) == -1) - return -UNW_EBADREG; - } else -#if defined(__amd64__) - memcpy(val, &fpreg.fpr_xacc[reg], sizeof(unw_fpreg_t)); -#elif defined(__i386__) - memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t)); -#elif defined(__arm__) - memcpy(val, &fpreg.fpr[reg], sizeof(unw_fpreg_t)); -#else -#error Fix me -#endif - return 0; -} -#else -#error Fix me -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_mem.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_mem.c deleted file mode 100644 index 79bde25dffc056..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_mem.c +++ /dev/null @@ -1,123 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - Copyright (C) 2010 Konstantin Belousov - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UPT_internal.h" - -#if HAVE_DECL_PTRACE_POKEDATA || HAVE_TTRACE -int -_UPT_access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, - int write, void *arg) -{ - struct UPT_info *ui = arg; - int i, end; - unw_word_t tmp_val; - - if (!ui) - return -UNW_EINVAL; - - pid_t pid = ui->pid; - - // Some 32-bit archs have to define a 64-bit unw_word_t. - // Callers of this function therefore expect a 64-bit - // return value, but ptrace only returns a 32-bit value - // in such cases. - if (sizeof(long) == 4 && sizeof(unw_word_t) == 8) - end = 2; - else - end = 1; - - for (i = 0; i < end; i++) - { - unw_word_t tmp_addr = i == 0 ? addr : addr + 4; - - errno = 0; - if (write) - { -#if __BYTE_ORDER == __LITTLE_ENDIAN - tmp_val = i == 0 ? *val : *val >> 32; -#else - tmp_val = i == 0 && end == 2 ? *val >> 32 : *val; -#endif - - Debug (16, "mem[%lx] <- %lx\n", (long) tmp_addr, (long) tmp_val); -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - ptrace (PTRACE_POKEDATA, pid, tmp_addr, tmp_val); - if (errno) - return -UNW_EINVAL; -#endif - } - else - { -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - tmp_val = (unsigned long) ptrace (PTRACE_PEEKDATA, pid, tmp_addr, 0); - - if (i == 0) - *val = 0; - -#if __BYTE_ORDER == __LITTLE_ENDIAN - *val |= tmp_val << (i * 32); -#else - *val |= i == 0 && end == 2 ? tmp_val << 32 : tmp_val; -#endif - - if (errno) - return -UNW_EINVAL; -#endif - Debug (16, "mem[%lx] -> %lx\n", (long) tmp_addr, (long) tmp_val); - } - } - return 0; -} -#elif HAVE_DECL_PT_IO -int -_UPT_access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, - int write, void *arg) -{ - struct UPT_info *ui = arg; - if (!ui) - return -UNW_EINVAL; - pid_t pid = ui->pid; - struct ptrace_io_desc iod; - - iod.piod_offs = (void *)addr; - iod.piod_addr = val; - iod.piod_len = sizeof(*val); - iod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D; - if (write) - Debug (16, "mem[%lx] <- %lx\n", (long) addr, (long) *val); - if (ptrace(PT_IO, pid, (caddr_t)&iod, 0) == -1) - return -UNW_EINVAL; - if (!write) - Debug (16, "mem[%lx] -> %lx\n", (long) addr, (long) *val); - return 0; -} -#else -#error Fix me -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_reg.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_reg.c deleted file mode 100644 index ce25c783b043a3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_reg.c +++ /dev/null @@ -1,352 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - Copyright (C) 2010 Konstantin Belousov - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UPT_internal.h" - -#if UNW_TARGET_IA64 -# include -# ifdef HAVE_ASM_PTRACE_OFFSETS_H -# include -# endif -# include "tdep-ia64/rse.h" -#endif - -#if HAVE_DECL_PTRACE_SETREGSET -#include -int -_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, - int write, void *arg) -{ - struct UPT_info *ui = arg; - pid_t pid = ui->pid; - gregset_t regs; - char *r; - struct iovec loc; - -#if UNW_DEBUG - Debug(16, "using getregset: reg: %s [%u], val: %lx, write: %u\n", - unw_regname(reg), (unsigned) reg, (long) val, write); - - if (write) - Debug (16, "%s [%u] <- %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); -#endif - if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) - { - errno = EINVAL; - goto badreg; - } - - loc.iov_base = ®s; - loc.iov_len = sizeof(regs); - - r = (char *)®s + _UPT_reg_offset[reg]; - if (ptrace (PTRACE_GETREGSET, pid, NT_PRSTATUS, &loc) == -1) - goto badreg; - if (write) { - memcpy(r, val, sizeof(unw_word_t)); - if (ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &loc) == -1) - goto badreg; - } else - memcpy(val, r, sizeof(unw_word_t)); - return 0; - -badreg: - Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); - return -UNW_EBADREG; -} -#elif HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE -int -_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, - int write, void *arg) -{ - struct UPT_info *ui = arg; - pid_t pid = ui->pid; - -#if UNW_DEBUG - Debug(16, "using pokeuser: reg: %s [%u], val: %lx, write: %d\n", unw_regname(reg), (unsigned) reg, (long) val, write); - - if (write) - Debug (16, "%s <- %lx\n", unw_regname (reg), (long) *val); -#endif - -#if UNW_TARGET_IA64 - if ((unsigned) reg - UNW_IA64_NAT < 32) - { - unsigned long nat_bits, mask; - - /* The Linux ptrace represents the statc NaT bits as a single word. */ - mask = ((unw_word_t) 1) << (reg - UNW_IA64_NAT); - errno = 0; -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - nat_bits = ptrace (PTRACE_PEEKUSER, pid, PT_NAT_BITS, 0); - if (errno) - goto badreg; -#endif - - if (write) - { - if (*val) - nat_bits |= mask; - else - nat_bits &= ~mask; -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - errno = 0; - ptrace (PTRACE_POKEUSER, pid, PT_NAT_BITS, nat_bits); - if (errno) - goto badreg; -#endif - } - goto out; - } - else - switch (reg) - { - case UNW_IA64_GR + 0: - if (write) - goto badreg; - *val = 0; - return 0; - - case UNW_REG_IP: - { - unsigned long ip, psr; - - /* distribute bundle-addr. & slot-number across PT_IIP & PT_IPSR. */ -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - errno = 0; - psr = ptrace (PTRACE_PEEKUSER, pid, PT_CR_IPSR, 0); - if (errno) - goto badreg; -#endif - if (write) - { - ip = *val & ~0xfUL; - psr = (psr & ~0x3UL << 41) | (*val & 0x3); -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - errno = 0; - ptrace (PTRACE_POKEUSER, pid, PT_CR_IIP, ip); - ptrace (PTRACE_POKEUSER, pid, PT_CR_IPSR, psr); - if (errno) - goto badreg; -#endif - } - else - { -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - errno = 0; - ip = ptrace (PTRACE_PEEKUSER, pid, PT_CR_IIP, 0); - if (errno) - goto badreg; -#endif - *val = ip + ((psr >> 41) & 0x3); - } - goto out; - } - - case UNW_IA64_AR_BSPSTORE: - reg = UNW_IA64_AR_BSP; - break; - - case UNW_IA64_AR_BSP: - case UNW_IA64_BSP: - { - unsigned long sof, cfm, bsp; - -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - /* Account for the fact that ptrace() expects bsp to point - _after_ the current register frame. */ - errno = 0; - cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0); - if (errno) - goto badreg; -#endif - sof = (cfm & 0x7f); - - if (write) - { - bsp = rse_skip_regs (*val, sof); -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - errno = 0; - ptrace (PTRACE_POKEUSER, pid, PT_AR_BSP, bsp); - if (errno) - goto badreg; -#endif - } - else - { -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - errno = 0; - bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0); - if (errno) - goto badreg; -#endif - *val = rse_skip_regs (bsp, -sof); - } - goto out; - } - - case UNW_IA64_CFM: - /* If we change CFM, we need to adjust ptrace's notion of bsp - accordingly, so that the real bsp remains unchanged. */ - if (write) - { - unsigned long new_sof, old_sof, cfm, bsp; - -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - errno = 0; - bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0); - cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0); -#endif - if (errno) - goto badreg; - old_sof = (cfm & 0x7f); - new_sof = (*val & 0x7f); - if (old_sof != new_sof) - { - bsp = rse_skip_regs (bsp, -old_sof + new_sof); -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - errno = 0; - ptrace (PTRACE_POKEUSER, pid, PT_AR_BSP, 0); - if (errno) - goto badreg; -#endif - } -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - errno = 0; - ptrace (PTRACE_POKEUSER, pid, PT_CFM, *val); - if (errno) - goto badreg; -#endif - goto out; - } - break; - } -#endif /* End of IA64 */ - - if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) - { -#if UNW_DEBUG - Debug(2, "register out of range: >= %zu / %zu\n", sizeof(_UPT_reg_offset), sizeof(_UPT_reg_offset[0])); -#endif - errno = EINVAL; - goto badreg; - } - -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#else - errno = 0; - if (write) - ptrace (PTRACE_POKEUSER, pid, _UPT_reg_offset[reg], *val); - else { -#if UNW_DEBUG - Debug(16, "ptrace PEEKUSER pid: %lu , reg: %lu , offs: %lu\n", (unsigned long)pid, (unsigned long)reg, - (unsigned long)_UPT_reg_offset[reg]); -#endif - *val = ptrace (PTRACE_PEEKUSER, pid, _UPT_reg_offset[reg], 0); - } - if (errno) { -#if UNW_DEBUG - Debug(2, "ptrace failure\n"); -#endif - goto badreg; - } -#endif - -#ifdef UNW_TARGET_IA64 - out: -#endif -#if UNW_DEBUG - if (!write) - Debug (16, "%s[%u] -> %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); -#endif - return 0; - - badreg: - Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); - return -UNW_EBADREG; -} -#elif HAVE_DECL_PT_GETREGS -int -_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, - int write, void *arg) -{ - struct UPT_info *ui = arg; - pid_t pid = ui->pid; - gregset_t regs; - char *r; - -#if UNW_DEBUG - Debug(16, "using getregs: reg: %s [%u], val: %lx, write: %u\n", unw_regname(reg), (unsigned) reg, (long) val, write); - - if (write) - Debug (16, "%s [%u] <- %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); -#endif - if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) - { - errno = EINVAL; - goto badreg; - } - r = (char *)®s + _UPT_reg_offset[reg]; - if (ptrace(PT_GETREGS, pid, (caddr_t)®s, 0) == -1) - goto badreg; - if (write) { - memcpy(r, val, sizeof(unw_word_t)); - if (ptrace(PT_SETREGS, pid, (caddr_t)®s, 0) == -1) - goto badreg; - } else - memcpy(val, r, sizeof(unw_word_t)); - return 0; - - badreg: - Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); - return -UNW_EBADREG; -} -#else -#error Port me -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_accessors.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_accessors.c deleted file mode 100644 index 4724360bb99b9c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_accessors.c +++ /dev/null @@ -1,38 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UPT_internal.h" - -unw_accessors_t _UPT_accessors = - { - .find_proc_info = _UPT_find_proc_info, - .put_unwind_info = _UPT_put_unwind_info, - .get_dyn_info_list_addr = _UPT_get_dyn_info_list_addr, - .access_mem = _UPT_access_mem, - .access_reg = _UPT_access_reg, - .access_fpreg = _UPT_access_fpreg, - .resume = _UPT_resume, - .get_proc_name = _UPT_get_proc_name - }; diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_create.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_create.c deleted file mode 100644 index dd59e974a7eafc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_create.c +++ /dev/null @@ -1,46 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "_UPT_internal.h" - -void * -_UPT_create (pid_t pid) -{ - struct UPT_info *ui = malloc (sizeof (struct UPT_info)); - - if (!ui) - return NULL; - - memset (ui, 0, sizeof (*ui)); - ui->pid = pid; - ui->edi.di_cache.format = -1; - ui->edi.di_debug.format = -1; -#if UNW_TARGET_IA64 - ui->edi.ktab.format = -1; -#endif - return ui; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_destroy.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_destroy.c deleted file mode 100644 index edb664ce1235bb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_destroy.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UPT_internal.h" - -void -_UPT_destroy (void *ptr) -{ - struct UPT_info *ui = (struct UPT_info *) ptr; - invalidate_edi (&ui->edi); - free (ptr); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_elf.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_elf.c deleted file mode 100644 index efc43b578bac0b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_elf.c +++ /dev/null @@ -1,5 +0,0 @@ -/* We need to get a separate copy of the ELF-code into - libunwind-ptrace since it cannot (and must not) have any ELF - dependencies on libunwind. */ -#include "libunwind_i.h" /* get ELFCLASS defined */ -#include "../elfxx.c" diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_find_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_find_proc_info.c deleted file mode 100644 index b3209f451ea9f7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_find_proc_info.c +++ /dev/null @@ -1,145 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include -#include - -#include - -#include "_UPT_internal.h" - -static int -get_unwind_info (struct elf_dyn_info *edi, pid_t pid, unw_addr_space_t as, unw_word_t ip) -{ - unsigned long segbase, mapoff; - char path[PATH_MAX]; - -#if UNW_TARGET_IA64 && defined(__linux) - if (!edi->ktab.start_ip && _Uia64_get_kernel_table (&edi->ktab) < 0) - return -UNW_ENOINFO; - - if (edi->ktab.format != -1 && ip >= edi->ktab.start_ip && ip < edi->ktab.end_ip) - return 0; -#endif - - if ((edi->di_cache.format != -1 - && ip >= edi->di_cache.start_ip && ip < edi->di_cache.end_ip) -#if UNW_TARGET_ARM - || (edi->di_debug.format != -1 - && ip >= edi->di_arm.start_ip && ip < edi->di_arm.end_ip) -#endif - || (edi->di_debug.format != -1 - && ip >= edi->di_debug.start_ip && ip < edi->di_debug.end_ip)) - return 0; - - invalidate_edi(edi); - - if (tdep_get_elf_image (&edi->ei, pid, ip, &segbase, &mapoff, path, - sizeof(path)) < 0) - return -UNW_ENOINFO; - - /* Here, SEGBASE is the starting-address of the (mmap'ped) segment - which covers the IP we're looking for. */ - if (tdep_find_unwind_table (edi, as, path, segbase, mapoff, ip) < 0) - return -UNW_ENOINFO; - - /* This can happen in corner cases where dynamically generated - code falls into the same page that contains the data-segment - and the page-offset of the code is within the first page of - the executable. */ - if (edi->di_cache.format != -1 - && (ip < edi->di_cache.start_ip || ip >= edi->di_cache.end_ip)) - edi->di_cache.format = -1; - - if (edi->di_debug.format != -1 - && (ip < edi->di_debug.start_ip || ip >= edi->di_debug.end_ip)) - edi->di_debug.format = -1; - - if (edi->di_cache.format == -1 -#if UNW_TARGET_ARM - && edi->di_arm.format == -1 -#endif - && edi->di_debug.format == -1) - return -UNW_ENOINFO; - - return 0; -} - -int -_UPT_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, - int need_unwind_info, void *arg) -{ - struct UPT_info *ui = arg; - int ret = -UNW_ENOINFO; - - if (get_unwind_info (&ui->edi, ui->pid, as, ip) < 0) - return -UNW_ENOINFO; - -#if UNW_TARGET_IA64 - if (ui->edi.ktab.format != -1) - { - /* The kernel unwind table resides in local memory, so we have - to use the local address space to search it. Since - _UPT_put_unwind_info() has no easy way of detecting this - case, we simply make a copy of the unwind-info, so - _UPT_put_unwind_info() can always free() the unwind-info - without ill effects. */ - ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi, - need_unwind_info, arg); - if (ret >= 0) - { - if (!need_unwind_info) - pi->unwind_info = NULL; - else - { - void *mem = malloc (pi->unwind_info_size); - - if (!mem) - return -UNW_ENOMEM; - memcpy (mem, pi->unwind_info, pi->unwind_info_size); - pi->unwind_info = mem; - } - } - } -#endif - - if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1) - ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache, - pi, need_unwind_info, arg); - - if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1) - ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi, - need_unwind_info, arg); - -#if UNW_TARGET_ARM - if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1) - ret = tdep_search_unwind_table (as, ip, &ui->edi.di_arm, pi, - need_unwind_info, arg); -#endif - - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c deleted file mode 100644 index cc5ed0441865ea..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c +++ /dev/null @@ -1,105 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UPT_internal.h" - -#if UNW_TARGET_IA64 && defined(__linux) -# include "elf64.h" -# include "os-linux.h" - -static inline int -get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, - int *countp) -{ - unsigned long lo, hi, off; - struct UPT_info *ui = arg; - struct map_iterator mi; - char path[PATH_MAX]; - unw_word_t res; - int count = 0; - - maps_init (&mi, ui->pid); - while (maps_next (&mi, &lo, &hi, &off)) - { - if (off) - continue; - - invalidate_edi(&ui->edi); - - if (elf_map_image (&ui->edi.ei, path) < 0) - /* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */ - continue; - - Debug (16, "checking object %s\n", path); - - if (tdep_find_unwind_table (&ui->edi, as, path, lo, off, 0) > 0) - { - res = _Uia64_find_dyn_list (as, &ui->edi.di_cache, arg); - if (res && count++ == 0) - { - Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res); - *dil_addr = res; - } - } - } - maps_close (&mi); - *countp = count; - return 0; -} - -#else - -static inline int -get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, - int *countp) -{ -# warning Implement get_list_addr(), please. - *countp = 0; - return 0; -} - -#endif - -int -_UPT_get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, - void *arg) -{ - int count, ret; - - Debug (12, "looking for dyn_info list\n"); - - if ((ret = get_list_addr (as, dil_addr, arg, &count)) < 0) - return ret; - - /* If multiple dynamic-info list addresses are found, we would have - to determine which was is the one actually in use (since the - dynamic name resolution algorithm will pick one "winner"). - Perhaps we'd have to track them all until we find one that's - non-empty. Hopefully, this case simply will never arise, since - only libunwind defines the dynamic info list head. */ - assert (count <= 1); - - return (count > 0) ? 0 : -UNW_ENOINFO; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_proc_name.c deleted file mode 100644 index 79c1f38e256ce7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_proc_name.c +++ /dev/null @@ -1,42 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UPT_internal.h" - -int -_UPT_get_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, void *arg) -{ - struct UPT_info *ui = arg; - -#if ELF_CLASS == ELFCLASS64 - return _Uelf64_get_proc_name (as, ui->pid, ip, buf, buf_len, offp); -#elif ELF_CLASS == ELFCLASS32 - return _Uelf32_get_proc_name (as, ui->pid, ip, buf, buf_len, offp); -#else - return -UNW_ENOINFO; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_internal.h b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_internal.h deleted file mode 100644 index 5cef2573ee666b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_internal.h +++ /dev/null @@ -1,59 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 _UPT_internal_h -#define _UPT_internal_h - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_PTRACE_H -#include -#endif -#ifdef HAVE_SYS_PROCFS_H -#include -#endif - -#include -#include -#include -#include -#include - -#include "libunwind_i.h" - -struct UPT_info - { - pid_t pid; /* the process-id of the child we're unwinding */ - struct elf_dyn_info edi; - }; - -extern const int _UPT_reg_offset[UNW_REG_LAST + 1]; - -#endif /* _UPT_internal_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_put_unwind_info.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_put_unwind_info.c deleted file mode 100644 index d4b84631476b6b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_put_unwind_info.c +++ /dev/null @@ -1,35 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UPT_internal.h" - -void -_UPT_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) -{ - if (!pi->unwind_info) - return; - free (pi->unwind_info); - pi->unwind_info = NULL; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c deleted file mode 100644 index c82d1c9887295b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c +++ /dev/null @@ -1,638 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - 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. */ - -#include "_UPT_internal.h" - -#include - -#ifdef HAVE_ASM_PTRACE_OFFSETS_H -# include -#endif - -const int _UPT_reg_offset[UNW_REG_LAST + 1] = - { -#ifdef HAVE_ASM_PTRACE_OFFSETS_H -# ifndef PT_AR_CSD -# define PT_AR_CSD -1 /* this was introduced with rev 2.1 of ia64 */ -# endif - - [UNW_IA64_GR + 0] = -1, [UNW_IA64_GR + 1] = PT_R1, - [UNW_IA64_GR + 2] = PT_R2, [UNW_IA64_GR + 3] = PT_R3, - [UNW_IA64_GR + 4] = PT_R4, [UNW_IA64_GR + 5] = PT_R5, - [UNW_IA64_GR + 6] = PT_R6, [UNW_IA64_GR + 7] = PT_R7, - [UNW_IA64_GR + 8] = PT_R8, [UNW_IA64_GR + 9] = PT_R9, - [UNW_IA64_GR + 10] = PT_R10, [UNW_IA64_GR + 11] = PT_R11, - [UNW_IA64_GR + 12] = PT_R12, [UNW_IA64_GR + 13] = PT_R13, - [UNW_IA64_GR + 14] = PT_R14, [UNW_IA64_GR + 15] = PT_R15, - [UNW_IA64_GR + 16] = PT_R16, [UNW_IA64_GR + 17] = PT_R17, - [UNW_IA64_GR + 18] = PT_R18, [UNW_IA64_GR + 19] = PT_R19, - [UNW_IA64_GR + 20] = PT_R20, [UNW_IA64_GR + 21] = PT_R21, - [UNW_IA64_GR + 22] = PT_R22, [UNW_IA64_GR + 23] = PT_R23, - [UNW_IA64_GR + 24] = PT_R24, [UNW_IA64_GR + 25] = PT_R25, - [UNW_IA64_GR + 26] = PT_R26, [UNW_IA64_GR + 27] = PT_R27, - [UNW_IA64_GR + 28] = PT_R28, [UNW_IA64_GR + 29] = PT_R29, - [UNW_IA64_GR + 30] = PT_R30, [UNW_IA64_GR + 31] = PT_R31, - - [UNW_IA64_NAT+ 0] = -1, [UNW_IA64_NAT+ 1] = PT_NAT_BITS, - [UNW_IA64_NAT+ 2] = PT_NAT_BITS, [UNW_IA64_NAT+ 3] = PT_NAT_BITS, - [UNW_IA64_NAT+ 4] = PT_NAT_BITS, [UNW_IA64_NAT+ 5] = PT_NAT_BITS, - [UNW_IA64_NAT+ 6] = PT_NAT_BITS, [UNW_IA64_NAT+ 7] = PT_NAT_BITS, - [UNW_IA64_NAT+ 8] = PT_NAT_BITS, [UNW_IA64_NAT+ 9] = PT_NAT_BITS, - [UNW_IA64_NAT+ 10] = PT_NAT_BITS, [UNW_IA64_NAT+ 11] = PT_NAT_BITS, - [UNW_IA64_NAT+ 12] = PT_NAT_BITS, [UNW_IA64_NAT+ 13] = PT_NAT_BITS, - [UNW_IA64_NAT+ 14] = PT_NAT_BITS, [UNW_IA64_NAT+ 15] = PT_NAT_BITS, - [UNW_IA64_NAT+ 16] = PT_NAT_BITS, [UNW_IA64_NAT+ 17] = PT_NAT_BITS, - [UNW_IA64_NAT+ 18] = PT_NAT_BITS, [UNW_IA64_NAT+ 19] = PT_NAT_BITS, - [UNW_IA64_NAT+ 20] = PT_NAT_BITS, [UNW_IA64_NAT+ 21] = PT_NAT_BITS, - [UNW_IA64_NAT+ 22] = PT_NAT_BITS, [UNW_IA64_NAT+ 23] = PT_NAT_BITS, - [UNW_IA64_NAT+ 24] = PT_NAT_BITS, [UNW_IA64_NAT+ 25] = PT_NAT_BITS, - [UNW_IA64_NAT+ 26] = PT_NAT_BITS, [UNW_IA64_NAT+ 27] = PT_NAT_BITS, - [UNW_IA64_NAT+ 28] = PT_NAT_BITS, [UNW_IA64_NAT+ 29] = PT_NAT_BITS, - [UNW_IA64_NAT+ 30] = PT_NAT_BITS, [UNW_IA64_NAT+ 31] = PT_NAT_BITS, - - [UNW_IA64_FR + 0] = -1, [UNW_IA64_FR + 1] = -1, - [UNW_IA64_FR + 2] = PT_F2, [UNW_IA64_FR + 3] = PT_F3, - [UNW_IA64_FR + 4] = PT_F4, [UNW_IA64_FR + 5] = PT_F5, - [UNW_IA64_FR + 6] = PT_F6, [UNW_IA64_FR + 7] = PT_F7, - [UNW_IA64_FR + 8] = PT_F8, [UNW_IA64_FR + 9] = PT_F9, - [UNW_IA64_FR + 10] = PT_F10, [UNW_IA64_FR + 11] = PT_F11, - [UNW_IA64_FR + 12] = PT_F12, [UNW_IA64_FR + 13] = PT_F13, - [UNW_IA64_FR + 14] = PT_F14, [UNW_IA64_FR + 15] = PT_F15, - [UNW_IA64_FR + 16] = PT_F16, [UNW_IA64_FR + 17] = PT_F17, - [UNW_IA64_FR + 18] = PT_F18, [UNW_IA64_FR + 19] = PT_F19, - [UNW_IA64_FR + 20] = PT_F20, [UNW_IA64_FR + 21] = PT_F21, - [UNW_IA64_FR + 22] = PT_F22, [UNW_IA64_FR + 23] = PT_F23, - [UNW_IA64_FR + 24] = PT_F24, [UNW_IA64_FR + 25] = PT_F25, - [UNW_IA64_FR + 26] = PT_F26, [UNW_IA64_FR + 27] = PT_F27, - [UNW_IA64_FR + 28] = PT_F28, [UNW_IA64_FR + 29] = PT_F29, - [UNW_IA64_FR + 30] = PT_F30, [UNW_IA64_FR + 31] = PT_F31, - [UNW_IA64_FR + 32] = PT_F32, [UNW_IA64_FR + 33] = PT_F33, - [UNW_IA64_FR + 34] = PT_F34, [UNW_IA64_FR + 35] = PT_F35, - [UNW_IA64_FR + 36] = PT_F36, [UNW_IA64_FR + 37] = PT_F37, - [UNW_IA64_FR + 38] = PT_F38, [UNW_IA64_FR + 39] = PT_F39, - [UNW_IA64_FR + 40] = PT_F40, [UNW_IA64_FR + 41] = PT_F41, - [UNW_IA64_FR + 42] = PT_F42, [UNW_IA64_FR + 43] = PT_F43, - [UNW_IA64_FR + 44] = PT_F44, [UNW_IA64_FR + 45] = PT_F45, - [UNW_IA64_FR + 46] = PT_F46, [UNW_IA64_FR + 47] = PT_F47, - [UNW_IA64_FR + 48] = PT_F48, [UNW_IA64_FR + 49] = PT_F49, - [UNW_IA64_FR + 50] = PT_F50, [UNW_IA64_FR + 51] = PT_F51, - [UNW_IA64_FR + 52] = PT_F52, [UNW_IA64_FR + 53] = PT_F53, - [UNW_IA64_FR + 54] = PT_F54, [UNW_IA64_FR + 55] = PT_F55, - [UNW_IA64_FR + 56] = PT_F56, [UNW_IA64_FR + 57] = PT_F57, - [UNW_IA64_FR + 58] = PT_F58, [UNW_IA64_FR + 59] = PT_F59, - [UNW_IA64_FR + 60] = PT_F60, [UNW_IA64_FR + 61] = PT_F61, - [UNW_IA64_FR + 62] = PT_F62, [UNW_IA64_FR + 63] = PT_F63, - [UNW_IA64_FR + 64] = PT_F64, [UNW_IA64_FR + 65] = PT_F65, - [UNW_IA64_FR + 66] = PT_F66, [UNW_IA64_FR + 67] = PT_F67, - [UNW_IA64_FR + 68] = PT_F68, [UNW_IA64_FR + 69] = PT_F69, - [UNW_IA64_FR + 70] = PT_F70, [UNW_IA64_FR + 71] = PT_F71, - [UNW_IA64_FR + 72] = PT_F72, [UNW_IA64_FR + 73] = PT_F73, - [UNW_IA64_FR + 74] = PT_F74, [UNW_IA64_FR + 75] = PT_F75, - [UNW_IA64_FR + 76] = PT_F76, [UNW_IA64_FR + 77] = PT_F77, - [UNW_IA64_FR + 78] = PT_F78, [UNW_IA64_FR + 79] = PT_F79, - [UNW_IA64_FR + 80] = PT_F80, [UNW_IA64_FR + 81] = PT_F81, - [UNW_IA64_FR + 82] = PT_F82, [UNW_IA64_FR + 83] = PT_F83, - [UNW_IA64_FR + 84] = PT_F84, [UNW_IA64_FR + 85] = PT_F85, - [UNW_IA64_FR + 86] = PT_F86, [UNW_IA64_FR + 87] = PT_F87, - [UNW_IA64_FR + 88] = PT_F88, [UNW_IA64_FR + 89] = PT_F89, - [UNW_IA64_FR + 90] = PT_F90, [UNW_IA64_FR + 91] = PT_F91, - [UNW_IA64_FR + 92] = PT_F92, [UNW_IA64_FR + 93] = PT_F93, - [UNW_IA64_FR + 94] = PT_F94, [UNW_IA64_FR + 95] = PT_F95, - [UNW_IA64_FR + 96] = PT_F96, [UNW_IA64_FR + 97] = PT_F97, - [UNW_IA64_FR + 98] = PT_F98, [UNW_IA64_FR + 99] = PT_F99, - [UNW_IA64_FR +100] = PT_F100, [UNW_IA64_FR +101] = PT_F101, - [UNW_IA64_FR +102] = PT_F102, [UNW_IA64_FR +103] = PT_F103, - [UNW_IA64_FR +104] = PT_F104, [UNW_IA64_FR +105] = PT_F105, - [UNW_IA64_FR +106] = PT_F106, [UNW_IA64_FR +107] = PT_F107, - [UNW_IA64_FR +108] = PT_F108, [UNW_IA64_FR +109] = PT_F109, - [UNW_IA64_FR +110] = PT_F110, [UNW_IA64_FR +111] = PT_F111, - [UNW_IA64_FR +112] = PT_F112, [UNW_IA64_FR +113] = PT_F113, - [UNW_IA64_FR +114] = PT_F114, [UNW_IA64_FR +115] = PT_F115, - [UNW_IA64_FR +116] = PT_F116, [UNW_IA64_FR +117] = PT_F117, - [UNW_IA64_FR +118] = PT_F118, [UNW_IA64_FR +119] = PT_F119, - [UNW_IA64_FR +120] = PT_F120, [UNW_IA64_FR +121] = PT_F121, - [UNW_IA64_FR +122] = PT_F122, [UNW_IA64_FR +123] = PT_F123, - [UNW_IA64_FR +124] = PT_F124, [UNW_IA64_FR +125] = PT_F125, - [UNW_IA64_FR +126] = PT_F126, [UNW_IA64_FR +127] = PT_F127, - - [UNW_IA64_AR + 0] = -1, [UNW_IA64_AR + 1] = -1, - [UNW_IA64_AR + 2] = -1, [UNW_IA64_AR + 3] = -1, - [UNW_IA64_AR + 4] = -1, [UNW_IA64_AR + 5] = -1, - [UNW_IA64_AR + 6] = -1, [UNW_IA64_AR + 7] = -1, - [UNW_IA64_AR + 8] = -1, [UNW_IA64_AR + 9] = -1, - [UNW_IA64_AR + 10] = -1, [UNW_IA64_AR + 11] = -1, - [UNW_IA64_AR + 12] = -1, [UNW_IA64_AR + 13] = -1, - [UNW_IA64_AR + 14] = -1, [UNW_IA64_AR + 15] = -1, - [UNW_IA64_AR + 16] = PT_AR_RSC, [UNW_IA64_AR + 17] = PT_AR_BSP, - [UNW_IA64_AR + 18] = PT_AR_BSPSTORE,[UNW_IA64_AR + 19] = PT_AR_RNAT, - [UNW_IA64_AR + 20] = -1, [UNW_IA64_AR + 21] = -1, - [UNW_IA64_AR + 22] = -1, [UNW_IA64_AR + 23] = -1, - [UNW_IA64_AR + 24] = -1, [UNW_IA64_AR + 25] = PT_AR_CSD, - [UNW_IA64_AR + 26] = -1, [UNW_IA64_AR + 27] = -1, - [UNW_IA64_AR + 28] = -1, [UNW_IA64_AR + 29] = -1, - [UNW_IA64_AR + 30] = -1, [UNW_IA64_AR + 31] = -1, - [UNW_IA64_AR + 32] = PT_AR_CCV, [UNW_IA64_AR + 33] = -1, - [UNW_IA64_AR + 34] = -1, [UNW_IA64_AR + 35] = -1, - [UNW_IA64_AR + 36] = PT_AR_UNAT, [UNW_IA64_AR + 37] = -1, - [UNW_IA64_AR + 38] = -1, [UNW_IA64_AR + 39] = -1, - [UNW_IA64_AR + 40] = PT_AR_FPSR, [UNW_IA64_AR + 41] = -1, - [UNW_IA64_AR + 42] = -1, [UNW_IA64_AR + 43] = -1, - [UNW_IA64_AR + 44] = -1, [UNW_IA64_AR + 45] = -1, - [UNW_IA64_AR + 46] = -1, [UNW_IA64_AR + 47] = -1, - [UNW_IA64_AR + 48] = -1, [UNW_IA64_AR + 49] = -1, - [UNW_IA64_AR + 50] = -1, [UNW_IA64_AR + 51] = -1, - [UNW_IA64_AR + 52] = -1, [UNW_IA64_AR + 53] = -1, - [UNW_IA64_AR + 54] = -1, [UNW_IA64_AR + 55] = -1, - [UNW_IA64_AR + 56] = -1, [UNW_IA64_AR + 57] = -1, - [UNW_IA64_AR + 58] = -1, [UNW_IA64_AR + 59] = -1, - [UNW_IA64_AR + 60] = -1, [UNW_IA64_AR + 61] = -1, - [UNW_IA64_AR + 62] = -1, [UNW_IA64_AR + 63] = -1, - [UNW_IA64_AR + 64] = PT_AR_PFS, [UNW_IA64_AR + 65] = PT_AR_LC, - [UNW_IA64_AR + 66] = PT_AR_EC, [UNW_IA64_AR + 67] = -1, - [UNW_IA64_AR + 68] = -1, [UNW_IA64_AR + 69] = -1, - [UNW_IA64_AR + 70] = -1, [UNW_IA64_AR + 71] = -1, - [UNW_IA64_AR + 72] = -1, [UNW_IA64_AR + 73] = -1, - [UNW_IA64_AR + 74] = -1, [UNW_IA64_AR + 75] = -1, - [UNW_IA64_AR + 76] = -1, [UNW_IA64_AR + 77] = -1, - [UNW_IA64_AR + 78] = -1, [UNW_IA64_AR + 79] = -1, - [UNW_IA64_AR + 80] = -1, [UNW_IA64_AR + 81] = -1, - [UNW_IA64_AR + 82] = -1, [UNW_IA64_AR + 83] = -1, - [UNW_IA64_AR + 84] = -1, [UNW_IA64_AR + 85] = -1, - [UNW_IA64_AR + 86] = -1, [UNW_IA64_AR + 87] = -1, - [UNW_IA64_AR + 88] = -1, [UNW_IA64_AR + 89] = -1, - [UNW_IA64_AR + 90] = -1, [UNW_IA64_AR + 91] = -1, - [UNW_IA64_AR + 92] = -1, [UNW_IA64_AR + 93] = -1, - [UNW_IA64_AR + 94] = -1, [UNW_IA64_AR + 95] = -1, - [UNW_IA64_AR + 96] = -1, [UNW_IA64_AR + 97] = -1, - [UNW_IA64_AR + 98] = -1, [UNW_IA64_AR + 99] = -1, - [UNW_IA64_AR +100] = -1, [UNW_IA64_AR +101] = -1, - [UNW_IA64_AR +102] = -1, [UNW_IA64_AR +103] = -1, - [UNW_IA64_AR +104] = -1, [UNW_IA64_AR +105] = -1, - [UNW_IA64_AR +106] = -1, [UNW_IA64_AR +107] = -1, - [UNW_IA64_AR +108] = -1, [UNW_IA64_AR +109] = -1, - [UNW_IA64_AR +110] = -1, [UNW_IA64_AR +111] = -1, - [UNW_IA64_AR +112] = -1, [UNW_IA64_AR +113] = -1, - [UNW_IA64_AR +114] = -1, [UNW_IA64_AR +115] = -1, - [UNW_IA64_AR +116] = -1, [UNW_IA64_AR +117] = -1, - [UNW_IA64_AR +118] = -1, [UNW_IA64_AR +119] = -1, - [UNW_IA64_AR +120] = -1, [UNW_IA64_AR +121] = -1, - [UNW_IA64_AR +122] = -1, [UNW_IA64_AR +123] = -1, - [UNW_IA64_AR +124] = -1, [UNW_IA64_AR +125] = -1, - [UNW_IA64_AR +126] = -1, [UNW_IA64_AR +127] = -1, - - [UNW_IA64_BR + 0] = PT_B0, [UNW_IA64_BR + 1] = PT_B1, - [UNW_IA64_BR + 2] = PT_B2, [UNW_IA64_BR + 3] = PT_B3, - [UNW_IA64_BR + 4] = PT_B4, [UNW_IA64_BR + 5] = PT_B5, - [UNW_IA64_BR + 6] = PT_B6, [UNW_IA64_BR + 7] = PT_B7, - - [UNW_IA64_PR] = PT_PR, - [UNW_IA64_CFM] = PT_CFM, - [UNW_IA64_IP] = PT_CR_IIP -#elif defined(HAVE_TTRACE) -# warning No support for ttrace() yet. -#elif defined(UNW_TARGET_HPPA) - [UNW_HPPA_GR + 0] = 0x000, [UNW_HPPA_GR + 1] = 0x004, - [UNW_HPPA_GR + 2] = 0x008, [UNW_HPPA_GR + 3] = 0x00c, - [UNW_HPPA_GR + 4] = 0x010, [UNW_HPPA_GR + 5] = 0x014, - [UNW_HPPA_GR + 6] = 0x018, [UNW_HPPA_GR + 7] = 0x01c, - [UNW_HPPA_GR + 8] = 0x020, [UNW_HPPA_GR + 9] = 0x024, - [UNW_HPPA_GR + 10] = 0x028, [UNW_HPPA_GR + 11] = 0x02c, - [UNW_HPPA_GR + 12] = 0x030, [UNW_HPPA_GR + 13] = 0x034, - [UNW_HPPA_GR + 14] = 0x038, [UNW_HPPA_GR + 15] = 0x03c, - [UNW_HPPA_GR + 16] = 0x040, [UNW_HPPA_GR + 17] = 0x044, - [UNW_HPPA_GR + 18] = 0x048, [UNW_HPPA_GR + 19] = 0x04c, - [UNW_HPPA_GR + 20] = 0x050, [UNW_HPPA_GR + 21] = 0x054, - [UNW_HPPA_GR + 22] = 0x058, [UNW_HPPA_GR + 23] = 0x05c, - [UNW_HPPA_GR + 24] = 0x060, [UNW_HPPA_GR + 25] = 0x064, - [UNW_HPPA_GR + 26] = 0x068, [UNW_HPPA_GR + 27] = 0x06c, - [UNW_HPPA_GR + 28] = 0x070, [UNW_HPPA_GR + 29] = 0x074, - [UNW_HPPA_GR + 30] = 0x078, [UNW_HPPA_GR + 31] = 0x07c, - - [UNW_HPPA_FR + 0] = 0x080, [UNW_HPPA_FR + 1] = 0x088, - [UNW_HPPA_FR + 2] = 0x090, [UNW_HPPA_FR + 3] = 0x098, - [UNW_HPPA_FR + 4] = 0x0a0, [UNW_HPPA_FR + 5] = 0x0a8, - [UNW_HPPA_FR + 6] = 0x0b0, [UNW_HPPA_FR + 7] = 0x0b8, - [UNW_HPPA_FR + 8] = 0x0c0, [UNW_HPPA_FR + 9] = 0x0c8, - [UNW_HPPA_FR + 10] = 0x0d0, [UNW_HPPA_FR + 11] = 0x0d8, - [UNW_HPPA_FR + 12] = 0x0e0, [UNW_HPPA_FR + 13] = 0x0e8, - [UNW_HPPA_FR + 14] = 0x0f0, [UNW_HPPA_FR + 15] = 0x0f8, - [UNW_HPPA_FR + 16] = 0x100, [UNW_HPPA_FR + 17] = 0x108, - [UNW_HPPA_FR + 18] = 0x110, [UNW_HPPA_FR + 19] = 0x118, - [UNW_HPPA_FR + 20] = 0x120, [UNW_HPPA_FR + 21] = 0x128, - [UNW_HPPA_FR + 22] = 0x130, [UNW_HPPA_FR + 23] = 0x138, - [UNW_HPPA_FR + 24] = 0x140, [UNW_HPPA_FR + 25] = 0x148, - [UNW_HPPA_FR + 26] = 0x150, [UNW_HPPA_FR + 27] = 0x158, - [UNW_HPPA_FR + 28] = 0x160, [UNW_HPPA_FR + 29] = 0x168, - [UNW_HPPA_FR + 30] = 0x170, [UNW_HPPA_FR + 31] = 0x178, - - [UNW_HPPA_IP] = 0x1a8 /* IAOQ[0] */ -#elif defined(UNW_TARGET_X86) -#if defined __FreeBSD__ -#define UNW_R_OFF(R, r) \ - [UNW_X86_##R] = offsetof(gregset_t, r_##r), - UNW_R_OFF(EAX, eax) - UNW_R_OFF(EDX, edx) - UNW_R_OFF(ECX, ecx) - UNW_R_OFF(EBX, ebx) - UNW_R_OFF(ESI, esi) - UNW_R_OFF(EDI, edi) - UNW_R_OFF(EBP, ebp) - UNW_R_OFF(ESP, esp) - UNW_R_OFF(EIP, eip) -// UNW_R_OFF(CS, cs) -// UNW_R_OFF(EFLAGS, eflags) -// UNW_R_OFF(SS, ss) -#elif defined __linux__ - [UNW_X86_EAX] = 0x18, - [UNW_X86_EBX] = 0x00, - [UNW_X86_ECX] = 0x04, - [UNW_X86_EDX] = 0x08, - [UNW_X86_ESI] = 0x0c, - [UNW_X86_EDI] = 0x10, - [UNW_X86_EBP] = 0x14, - [UNW_X86_EIP] = 0x30, - [UNW_X86_ESP] = 0x3c -/* CS = 0x34, */ -/* DS = 0x1c, */ -/* ES = 0x20, */ -/* FS = 0x24, */ -/* GS = 0x28, */ -/* ORIG_EAX = 0x2c, */ -/* EFLAGS = 0x38, */ -/* SS = 0x40 */ -#else -#error Port me -#endif -#elif defined(UNW_TARGET_X86_64) -#if defined __FreeBSD__ -#define UNW_R_OFF(R, r) \ - [UNW_X86_64_##R] = offsetof(gregset_t, r_##r), - UNW_R_OFF(RAX, rax) - UNW_R_OFF(RDX, rdx) - UNW_R_OFF(RCX, rcx) - UNW_R_OFF(RBX, rbx) - UNW_R_OFF(RSI, rsi) - UNW_R_OFF(RDI, rdi) - UNW_R_OFF(RBP, rbp) - UNW_R_OFF(RSP, rsp) - UNW_R_OFF(R8, r8) - UNW_R_OFF(R9, r9) - UNW_R_OFF(R10, r10) - UNW_R_OFF(R11, r11) - UNW_R_OFF(R12, r12) - UNW_R_OFF(R13, r13) - UNW_R_OFF(R14, r14) - UNW_R_OFF(R15, r15) - UNW_R_OFF(RIP, rip) -// UNW_R_OFF(CS, cs) -// UNW_R_OFF(EFLAGS, rflags) -// UNW_R_OFF(SS, ss) -#undef UNW_R_OFF -#elif defined __linux__ - [UNW_X86_64_RAX] = 0x50, - [UNW_X86_64_RDX] = 0x60, - [UNW_X86_64_RCX] = 0x58, - [UNW_X86_64_RBX] = 0x28, - [UNW_X86_64_RSI] = 0x68, - [UNW_X86_64_RDI] = 0x70, - [UNW_X86_64_RBP] = 0x20, - [UNW_X86_64_RSP] = 0x98, - [UNW_X86_64_R8] = 0x48, - [UNW_X86_64_R9] = 0x40, - [UNW_X86_64_R10] = 0x38, - [UNW_X86_64_R11] = 0x30, - [UNW_X86_64_R12] = 0x18, - [UNW_X86_64_R13] = 0x10, - [UNW_X86_64_R14] = 0x08, - [UNW_X86_64_R15] = 0x00, - [UNW_X86_64_RIP] = 0x80 -// [UNW_X86_64_CS] = 0x88, -// [UNW_X86_64_EFLAGS] = 0x90, -// [UNW_X86_64_RSP] = 0x98, -// [UNW_X86_64_SS] = 0xa0 -#else -#error Port me -#endif -#elif defined(UNW_TARGET_PPC32) || defined(UNW_TARGET_PPC64) - -#define UNW_REG_SLOT_SIZE sizeof(unsigned long) -#define UNW_PPC_R(v) ((v) * UNW_REG_SLOT_SIZE) -#define UNW_PPC_PT(p) UNW_PPC_R(PT_##p) - -#define UNW_FP_OFF(b, i) \ - [UNW_PPC##b##_F##i] = UNW_PPC_R(PT_FPR0 + i * 8/UNW_REG_SLOT_SIZE) - -#define UNW_R_OFF(b, i) \ - [UNW_PPC##b##_R##i] = UNW_PPC_R(PT_R##i) - -#define UNW_PPC_REGS(b) \ - UNW_R_OFF(b, 0), \ - UNW_R_OFF(b, 1), \ - UNW_R_OFF(b, 2), \ - UNW_R_OFF(b, 3), \ - UNW_R_OFF(b, 4), \ - UNW_R_OFF(b, 5), \ - UNW_R_OFF(b, 6), \ - UNW_R_OFF(b, 7), \ - UNW_R_OFF(b, 8), \ - UNW_R_OFF(b, 9), \ - UNW_R_OFF(b, 10), \ - UNW_R_OFF(b, 11), \ - UNW_R_OFF(b, 12), \ - UNW_R_OFF(b, 13), \ - UNW_R_OFF(b, 14), \ - UNW_R_OFF(b, 15), \ - UNW_R_OFF(b, 16), \ - UNW_R_OFF(b, 17), \ - UNW_R_OFF(b, 18), \ - UNW_R_OFF(b, 19), \ - UNW_R_OFF(b, 20), \ - UNW_R_OFF(b, 21), \ - UNW_R_OFF(b, 22), \ - UNW_R_OFF(b, 23), \ - UNW_R_OFF(b, 24), \ - UNW_R_OFF(b, 25), \ - UNW_R_OFF(b, 26), \ - UNW_R_OFF(b, 27), \ - UNW_R_OFF(b, 28), \ - UNW_R_OFF(b, 29), \ - UNW_R_OFF(b, 30), \ - UNW_R_OFF(b, 31), \ - \ - [UNW_PPC##b##_CTR] = UNW_PPC_PT(CTR), \ - [UNW_PPC##b##_XER] = UNW_PPC_PT(XER), \ - [UNW_PPC##b##_LR] = UNW_PPC_PT(LNK), \ - \ - UNW_FP_OFF(b, 0), \ - UNW_FP_OFF(b, 1), \ - UNW_FP_OFF(b, 2), \ - UNW_FP_OFF(b, 3), \ - UNW_FP_OFF(b, 4), \ - UNW_FP_OFF(b, 5), \ - UNW_FP_OFF(b, 6), \ - UNW_FP_OFF(b, 7), \ - UNW_FP_OFF(b, 8), \ - UNW_FP_OFF(b, 9), \ - UNW_FP_OFF(b, 10), \ - UNW_FP_OFF(b, 11), \ - UNW_FP_OFF(b, 12), \ - UNW_FP_OFF(b, 13), \ - UNW_FP_OFF(b, 14), \ - UNW_FP_OFF(b, 15), \ - UNW_FP_OFF(b, 16), \ - UNW_FP_OFF(b, 17), \ - UNW_FP_OFF(b, 18), \ - UNW_FP_OFF(b, 19), \ - UNW_FP_OFF(b, 20), \ - UNW_FP_OFF(b, 21), \ - UNW_FP_OFF(b, 22), \ - UNW_FP_OFF(b, 23), \ - UNW_FP_OFF(b, 24), \ - UNW_FP_OFF(b, 25), \ - UNW_FP_OFF(b, 26), \ - UNW_FP_OFF(b, 27), \ - UNW_FP_OFF(b, 28), \ - UNW_FP_OFF(b, 29), \ - UNW_FP_OFF(b, 30), \ - UNW_FP_OFF(b, 31) - -#define UNW_PPC32_REGS \ - [UNW_PPC32_FPSCR] = UNW_PPC_PT(FPSCR), \ - [UNW_PPC32_CCR] = UNW_PPC_PT(CCR) - -#define UNW_VR_OFF(i) \ - [UNW_PPC64_V##i] = UNW_PPC_R(PT_VR0 + i * 2) - -#define UNW_PPC64_REGS \ - [UNW_PPC64_NIP] = UNW_PPC_PT(NIP), \ - [UNW_PPC64_FRAME_POINTER] = -1, \ - [UNW_PPC64_ARG_POINTER] = -1, \ - [UNW_PPC64_CR0] = -1, \ - [UNW_PPC64_CR1] = -1, \ - [UNW_PPC64_CR2] = -1, \ - [UNW_PPC64_CR3] = -1, \ - [UNW_PPC64_CR4] = -1, \ - [UNW_PPC64_CR5] = -1, \ - [UNW_PPC64_CR6] = -1, \ - [UNW_PPC64_CR7] = -1, \ - [UNW_PPC64_VRSAVE] = UNW_PPC_PT(VRSAVE), \ - [UNW_PPC64_VSCR] = UNW_PPC_PT(VSCR), \ - [UNW_PPC64_SPE_ACC] = -1, \ - [UNW_PPC64_SPEFSCR] = -1, \ - UNW_VR_OFF(0), \ - UNW_VR_OFF(1), \ - UNW_VR_OFF(2), \ - UNW_VR_OFF(3), \ - UNW_VR_OFF(4), \ - UNW_VR_OFF(5), \ - UNW_VR_OFF(6), \ - UNW_VR_OFF(7), \ - UNW_VR_OFF(8), \ - UNW_VR_OFF(9), \ - UNW_VR_OFF(10), \ - UNW_VR_OFF(11), \ - UNW_VR_OFF(12), \ - UNW_VR_OFF(13), \ - UNW_VR_OFF(14), \ - UNW_VR_OFF(15), \ - UNW_VR_OFF(16), \ - UNW_VR_OFF(17), \ - UNW_VR_OFF(18), \ - UNW_VR_OFF(19), \ - UNW_VR_OFF(20), \ - UNW_VR_OFF(21), \ - UNW_VR_OFF(22), \ - UNW_VR_OFF(23), \ - UNW_VR_OFF(24), \ - UNW_VR_OFF(25), \ - UNW_VR_OFF(26), \ - UNW_VR_OFF(27), \ - UNW_VR_OFF(28), \ - UNW_VR_OFF(29), \ - UNW_VR_OFF(30), \ - UNW_VR_OFF(31) - -#if defined(UNW_TARGET_PPC32) - UNW_PPC_REGS(32), - UNW_PPC32_REGS, -#else - UNW_PPC_REGS(64), - UNW_PPC64_REGS, -#endif - -#elif defined(UNW_TARGET_ARM) -#if defined(__linux__) || defined(__FreeBSD__) - [UNW_ARM_R0] = 0x00, - [UNW_ARM_R1] = 0x04, - [UNW_ARM_R2] = 0x08, - [UNW_ARM_R3] = 0x0c, - [UNW_ARM_R4] = 0x10, - [UNW_ARM_R5] = 0x14, - [UNW_ARM_R6] = 0x18, - [UNW_ARM_R7] = 0x1c, - [UNW_ARM_R8] = 0x20, - [UNW_ARM_R9] = 0x24, - [UNW_ARM_R10] = 0x28, - [UNW_ARM_R11] = 0x2c, - [UNW_ARM_R12] = 0x30, - [UNW_ARM_R13] = 0x34, - [UNW_ARM_R14] = 0x38, - [UNW_ARM_R15] = 0x3c, -#else -#error Fix me -#endif -#elif defined(UNW_TARGET_MIPS) - [UNW_MIPS_R0] = 0, - [UNW_MIPS_R1] = 1, - [UNW_MIPS_R2] = 2, - [UNW_MIPS_R3] = 3, - [UNW_MIPS_R4] = 4, - [UNW_MIPS_R5] = 5, - [UNW_MIPS_R6] = 6, - [UNW_MIPS_R7] = 7, - [UNW_MIPS_R8] = 8, - [UNW_MIPS_R9] = 9, - [UNW_MIPS_R10] = 10, - [UNW_MIPS_R11] = 11, - [UNW_MIPS_R12] = 12, - [UNW_MIPS_R13] = 13, - [UNW_MIPS_R14] = 14, - [UNW_MIPS_R15] = 15, - [UNW_MIPS_R16] = 16, - [UNW_MIPS_R17] = 17, - [UNW_MIPS_R18] = 18, - [UNW_MIPS_R19] = 19, - [UNW_MIPS_R20] = 20, - [UNW_MIPS_R21] = 21, - [UNW_MIPS_R22] = 22, - [UNW_MIPS_R23] = 23, - [UNW_MIPS_R24] = 24, - [UNW_MIPS_R25] = 25, - [UNW_MIPS_R26] = 26, - [UNW_MIPS_R27] = 27, - [UNW_MIPS_R28] = 28, - [UNW_MIPS_R29] = 29, - [UNW_MIPS_R30] = 30, - [UNW_MIPS_R31] = 31, - [UNW_MIPS_PC] = 64, -#elif defined(UNW_TARGET_SH) -#elif defined(UNW_TARGET_AARCH64) - [UNW_AARCH64_X0] = 0x00, - [UNW_AARCH64_X1] = 0x08, - [UNW_AARCH64_X2] = 0x10, - [UNW_AARCH64_X3] = 0x18, - [UNW_AARCH64_X4] = 0x20, - [UNW_AARCH64_X5] = 0x28, - [UNW_AARCH64_X6] = 0x30, - [UNW_AARCH64_X7] = 0x38, - [UNW_AARCH64_X8] = 0x40, - [UNW_AARCH64_X9] = 0x48, - [UNW_AARCH64_X10] = 0x50, - [UNW_AARCH64_X11] = 0x58, - [UNW_AARCH64_X12] = 0x60, - [UNW_AARCH64_X13] = 0x68, - [UNW_AARCH64_X14] = 0x70, - [UNW_AARCH64_X15] = 0x78, - [UNW_AARCH64_X16] = 0x80, - [UNW_AARCH64_X17] = 0x88, - [UNW_AARCH64_X18] = 0x90, - [UNW_AARCH64_X19] = 0x98, - [UNW_AARCH64_X20] = 0xa0, - [UNW_AARCH64_X21] = 0xa8, - [UNW_AARCH64_X22] = 0xb0, - [UNW_AARCH64_X23] = 0xb8, - [UNW_AARCH64_X24] = 0xc0, - [UNW_AARCH64_X25] = 0xc8, - [UNW_AARCH64_X26] = 0xd0, - [UNW_AARCH64_X27] = 0xd8, - [UNW_AARCH64_X28] = 0xe0, - [UNW_AARCH64_X29] = 0xe8, - [UNW_AARCH64_X30] = 0xf0, - [UNW_AARCH64_SP] = 0xf8, - [UNW_AARCH64_PC] = 0x100, - [UNW_AARCH64_PSTATE] = 0x108 -#elif defined(UNW_TARGET_TILEGX) - [UNW_TILEGX_R0] = 0x00, - [UNW_TILEGX_R1] = 0x08, - [UNW_TILEGX_R2] = 0x10, - [UNW_TILEGX_R3] = 0x08, - [UNW_TILEGX_R4] = 0x20, - [UNW_TILEGX_R5] = 0x28, - [UNW_TILEGX_R6] = 0x30, - [UNW_TILEGX_R7] = 0x38, - [UNW_TILEGX_R8] = 0x40, - [UNW_TILEGX_R9] = 0x48, - [UNW_TILEGX_R10] = 0x50, - [UNW_TILEGX_R11] = 0x58, - [UNW_TILEGX_R12] = 0x60, - [UNW_TILEGX_R13] = 0x68, - [UNW_TILEGX_R14] = 0x70, - [UNW_TILEGX_R15] = 0x78, - [UNW_TILEGX_R16] = 0x80, - [UNW_TILEGX_R17] = 0x88, - [UNW_TILEGX_R18] = 0x90, - [UNW_TILEGX_R19] = 0x98, - [UNW_TILEGX_R20] = 0xa0, - [UNW_TILEGX_R21] = 0xa8, - [UNW_TILEGX_R22] = 0xb0, - [UNW_TILEGX_R23] = 0xb8, - [UNW_TILEGX_R24] = 0xc0, - [UNW_TILEGX_R25] = 0xc8, - [UNW_TILEGX_R26] = 0xd0, - [UNW_TILEGX_R27] = 0xd8, - [UNW_TILEGX_R28] = 0xe0, - [UNW_TILEGX_R29] = 0xe8, - [UNW_TILEGX_R30] = 0xf0, - [UNW_TILEGX_R31] = 0xf8, - [UNW_TILEGX_R32] = 0x100, - [UNW_TILEGX_R33] = 0x108, - [UNW_TILEGX_R34] = 0x110, - [UNW_TILEGX_R35] = 0x118, - [UNW_TILEGX_R36] = 0x120, - [UNW_TILEGX_R37] = 0x128, - [UNW_TILEGX_R38] = 0x130, - [UNW_TILEGX_R39] = 0x138, - [UNW_TILEGX_R40] = 0x140, - [UNW_TILEGX_R41] = 0x148, - [UNW_TILEGX_R42] = 0x150, - [UNW_TILEGX_R43] = 0x158, - [UNW_TILEGX_R44] = 0x160, - [UNW_TILEGX_R45] = 0x168, - [UNW_TILEGX_R46] = 0x170, - [UNW_TILEGX_R47] = 0x178, - [UNW_TILEGX_R48] = 0x180, - [UNW_TILEGX_R49] = 0x188, - [UNW_TILEGX_R50] = 0x190, - [UNW_TILEGX_R51] = 0x198, - [UNW_TILEGX_R52] = 0x1a0, - [UNW_TILEGX_R53] = 0x1a8, - [UNW_TILEGX_R54] = 0x1b0, - [UNW_TILEGX_R55] = 0x1b8, - [UNW_TILEGX_PC] = 0x1a0 -#else -# error Fix me. -#endif - }; diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_resume.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_resume.c deleted file mode 100644 index d70a0d48218f05..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_resume.c +++ /dev/null @@ -1,40 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "_UPT_internal.h" - -int -_UPT_resume (unw_addr_space_t as, unw_cursor_t *c, void *arg) -{ - struct UPT_info *ui = arg; - -#ifdef HAVE_TTRACE -# warning No support for ttrace() yet. -#elif HAVE_DECL_PTRACE_CONT - return ptrace (PTRACE_CONT, ui->pid, 0, 0); -#elif HAVE_DECL_PT_CONTINUE - return ptrace(PT_CONTINUE, ui->pid, (caddr_t)1, 0); -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/libunwind-ptrace.pc.in b/src/coreclr/src/pal/src/libunwind/src/ptrace/libunwind-ptrace.pc.in deleted file mode 100644 index 673004b69ef0f7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/libunwind-ptrace.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libunwind-ptrace -Description: libunwind ptrace library -Version: @VERSION@ -Requires: libunwind-generic libunwind -Libs: -L${libdir} -lunwind-ptrace -Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/libunwind-setjmp.pc.in b/src/coreclr/src/pal/src/libunwind/src/setjmp/libunwind-setjmp.pc.in deleted file mode 100644 index 7b71126535b0e5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/setjmp/libunwind-setjmp.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libunwind-setjmp -Description: libunwind setjmp library -Version: @VERSION@ -Requires: libunwind -Libs: -L${libdir} -lunwind-setjmp -Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/longjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/longjmp.c deleted file mode 100644 index 8295a9b8ed40de..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/setjmp/longjmp.c +++ /dev/null @@ -1,115 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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_LOCAL_ONLY - -#undef _FORTIFY_SOURCE -#include -#include -#include -#include -#include - -#include "jmpbuf.h" -#include "setjmp_i.h" - -#if defined(__GLIBC__) -#if __GLIBC_PREREQ(2, 4) - -/* Starting with glibc-2.4, {sig,}setjmp in GLIBC obfuscates the - register values in jmp_buf by XORing them with a "random" - canary value. - - This makes it impossible to implement longjmp, as we - can never match wp[JB_SP], unless we decode the canary first. - - Doing so is possible, but doesn't appear to be worth the trouble, - so we simply defer to glibc longjmp here. */ -#define _longjmp __nonworking__longjmp -#define longjmp __nonworking_longjmp -static void _longjmp (jmp_buf env, int val); -static void longjmp (jmp_buf env, int val); -#endif -#endif /* __GLIBC__ */ - -void -_longjmp (jmp_buf env, int val) -{ - extern int _UI_longjmp_cont; - unw_context_t uc; - unw_cursor_t c; - unw_word_t sp; - unw_word_t *wp = (unw_word_t *) env; - - if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0) - abort (); - - do - { - if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) - abort (); -#ifdef __FreeBSD__ - if (sp != wp[JB_SP] + sizeof(unw_word_t)) -#else - if (sp != wp[JB_SP]) -#endif - continue; - - if (!bsp_match (&c, wp)) - continue; - - /* found the right frame: */ - - assert (UNW_NUM_EH_REGS >= 2); - - if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0 - || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0 - || unw_set_reg (&c, UNW_REG_IP, - (unw_word_t) (uintptr_t) &_UI_longjmp_cont)) - abort (); - - unw_resume (&c); - - abort (); - } - while (unw_step (&c) > 0); - - abort (); -} - -#ifdef __GNUC__ -#define STRINGIFY1(x) #x -#define STRINGIFY(x) STRINGIFY1(x) -void longjmp (jmp_buf env, int val) - __attribute__ ((alias (STRINGIFY(_longjmp)))); -#else - -void -longjmp (jmp_buf env, int val) -{ - _longjmp (env, val); -} - -#endif /* __GNUC__ */ diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp.c deleted file mode 100644 index bec9fc7d5bfad9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp.c +++ /dev/null @@ -1,49 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include - -#include "jmpbuf.h" - -/* Why use K&R syntax here? setjmp() is often a macro and that - expands into a call to, say, __setjmp() and we need to define the - libunwind-version of setjmp() with the name of the actual function. - Using K&R syntax lets us keep the setjmp() macro while keeping the - syntax valid... This trick works provided setjmp() doesn't do - anything other than a function call. */ - -int -setjmp (env) - jmp_buf env; -{ - void **wp = (void **) env; - - /* this should work on most platforms, but may not be - performance-optimal; check the code! */ - wp[JB_SP] = __builtin_frame_address (0); - wp[JB_RP] = (void *) __builtin_return_address (0); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp_i.h b/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp_i.h deleted file mode 100644 index 4d9139693ecfb7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp_i.h +++ /dev/null @@ -1,118 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -#if UNW_TARGET_IA64 - -#include "libunwind_i.h" -#include "tdep-ia64/rse.h" - -static inline int -bsp_match (unw_cursor_t *c, unw_word_t *wp) -{ - unw_word_t bsp, pfs, sol; - - if (unw_get_reg (c, UNW_IA64_BSP, &bsp) < 0 - || unw_get_reg (c, UNW_IA64_AR_PFS, &pfs) < 0) - abort (); - - /* simulate the effect of "br.call sigsetjmp" on ar.bsp: */ - sol = (pfs >> 7) & 0x7f; - bsp = rse_skip_regs (bsp, sol); - - if (bsp != wp[JB_BSP]) - return 0; - - if (unlikely (sol == 0)) - { - unw_word_t sp, prev_sp; - unw_cursor_t tmp = *c; - - /* The caller of {sig,}setjmp() cannot have a NULL-frame. If we - see a NULL-frame, we haven't reached the right target yet. - To have a NULL-frame, the number of locals must be zero and - the stack-frame must also be empty. */ - - if (unw_step (&tmp) < 0) - abort (); - - if (unw_get_reg (&tmp, UNW_REG_SP, &sp) < 0 - || unw_get_reg (&tmp, UNW_REG_SP, &prev_sp) < 0) - abort (); - - if (sp == prev_sp) - /* got a NULL-frame; keep looking... */ - return 0; - } - return 1; -} - -/* On ia64 we cannot always call sigprocmask() at - _UI_siglongjmp_cont() because the signal may have switched stacks - and the old stack's register-backing store may have overflown, - leaving us no space to allocate the stacked registers needed to - call sigprocmask(). Fortunately, we can just let unw_resume() (via - sigreturn) take care of restoring the signal-mask. That's faster - anyhow. */ -static inline int -resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp) -{ - unw_word_t sc_addr = ((struct cursor *) c)->sigcontext_addr; - struct sigcontext *sc = (struct sigcontext *) sc_addr; - sigset_t current_mask; - void *mp; - - if (!sc_addr) - return 0; - - /* let unw_resume() install the desired signal mask */ - - if (wp[JB_MASK_SAVED]) - mp = &wp[JB_MASK]; - else - { - if (sigprocmask (SIG_BLOCK, NULL, ¤t_mask) < 0) - abort (); - mp = ¤t_mask; - } - memcpy (&sc->sc_mask, mp, sizeof (sc->sc_mask)); - return 1; -} - -#else /* !UNW_TARGET_IA64 */ - -static inline int -bsp_match (unw_cursor_t *c, unw_word_t *wp) -{ - return 1; -} - -static inline int -resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp) -{ - /* We may want to do this analogously as for ia64... */ - return 0; -} - -#endif /* !UNW_TARGET_IA64 */ diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c deleted file mode 100644 index 0e286f6f0851cc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c +++ /dev/null @@ -1,127 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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_LOCAL_ONLY - -#include - -#include "libunwind_i.h" -#include "jmpbuf.h" -#include "setjmp_i.h" - -#if !defined(_NSIG) && defined(_SIG_MAXSIG) -# define _NSIG (_SIG_MAXSIG - 1) -#endif - -#if defined(__GLIBC__) -#if __GLIBC_PREREQ(2, 4) - -/* Starting with glibc-2.4, {sig,}setjmp in GLIBC obfuscates the - register values in jmp_buf by XORing them with a "random" - canary value. - - This makes it impossible to implement longjmp, as we - can never match wp[JB_SP], unless we decode the canary first. - - Doing so is possible, but doesn't appear to be worth the trouble, - so we simply defer to glibc siglongjmp here. */ - -#define siglongjmp __nonworking_siglongjmp -static void siglongjmp (sigjmp_buf env, int val) UNUSED; -#endif -#endif /* __GLIBC_PREREQ */ - -void -siglongjmp (sigjmp_buf env, int val) -{ - unw_word_t *wp = (unw_word_t *) env; - extern int _UI_siglongjmp_cont; - extern int _UI_longjmp_cont; - unw_context_t uc; - unw_cursor_t c; - unw_word_t sp; - int *cont; - - if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0) - abort (); - - do - { - if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) - abort (); -#ifdef __FreeBSD__ - if (sp != wp[JB_SP] + sizeof(unw_word_t)) -#else - if (sp != wp[JB_SP]) -#endif - continue; - - if (!bsp_match (&c, wp)) - continue; - - /* found the right frame: */ - - /* default to resuming without restoring signal-mask */ - cont = &_UI_longjmp_cont; - - /* Order of evaluation is important here: if unw_resume() - restores signal mask, we must set it up appropriately, even - if wp[JB_MASK_SAVED] is FALSE. */ - if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED]) - { - /* sigmask was saved */ -#if defined(__linux__) - if (UNW_NUM_EH_REGS < 4 || _NSIG > 16 * sizeof (unw_word_t)) - /* signal mask doesn't fit into EH arguments and we can't - put it on the stack without overwriting something - else... */ - abort (); - else - if (unw_set_reg (&c, UNW_REG_EH + 2, wp[JB_MASK]) < 0 - || (_NSIG > 8 * sizeof (unw_word_t) - && unw_set_reg (&c, UNW_REG_EH + 3, wp[JB_MASK + 1]) < 0)) - abort (); -#elif defined(__FreeBSD__) - if (unw_set_reg (&c, UNW_REG_EH + 2, &wp[JB_MASK]) < 0) - abort(); -#else -#error Port me -#endif - cont = &_UI_siglongjmp_cont; - } - - if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0 - || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0 - || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) (uintptr_t) cont)) - abort (); - - unw_resume (&c); - - abort (); - } - while (unw_step (&c) > 0); - - abort (); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/sigsetjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/sigsetjmp.c deleted file mode 100644 index f84935d638ac06..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/setjmp/sigsetjmp.c +++ /dev/null @@ -1,50 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include - -#include "jmpbuf.h" - -int -sigsetjmp (sigjmp_buf env, int savemask) -{ - unw_word_t *wp = (unw_word_t *) env; - - /* This should work on most platforms, but may not be - performance-optimal; check the code! */ - - wp[JB_SP] = (unw_word_t) __builtin_frame_address (0); - wp[JB_RP] = (unw_word_t) __builtin_return_address (0); - wp[JB_MASK_SAVED] = savemask; - - /* Note: we assume here that "wp" has same or better alignment as - sigset_t. */ - if (savemask - && sigprocmask (SIG_BLOCK, NULL, (sigset_t *) (wp + JB_MASK)) < 0) - abort (); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gcreate_addr_space.c deleted file mode 100644 index 6ca3a384da0b7d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gcreate_addr_space.c +++ /dev/null @@ -1,59 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include - -#include "unwind_i.h" - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* SH supports little-endian and big-endian. */ - if (byte_order != 0 && byte_order != __LITTLE_ENDIAN - && byte_order != __BIG_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - /* Default to little-endian for SH. */ - if (byte_order == 0 || byte_order == __LITTLE_ENDIAN) - as->big_endian = 0; - else - as->big_endian = 1; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gget_proc_info.c deleted file mode 100644 index c363d2405d748a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gget_proc_info.c +++ /dev/null @@ -1,39 +0,0 @@ -/* 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. */ - -#include "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - ret = dwarf_make_proc_info (&c->dwarf); - if (ret < 0) - return ret; - - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gget_save_loc.c deleted file mode 100644 index 24d9f63bc329d7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gget_save_loc.c +++ /dev/null @@ -1,83 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - struct cursor *c = (struct cursor *) cursor; - dwarf_loc_t loc; - - switch (reg) - { - case UNW_SH_R0: - case UNW_SH_R1: - case UNW_SH_R2: - case UNW_SH_R3: - case UNW_SH_R4: - case UNW_SH_R5: - case UNW_SH_R6: - case UNW_SH_R7: - case UNW_SH_R8: - case UNW_SH_R9: - case UNW_SH_R10: - case UNW_SH_R11: - case UNW_SH_R12: - case UNW_SH_R13: - case UNW_SH_R14: - case UNW_SH_R15: - case UNW_SH_PC: - case UNW_SH_PR: - loc = c->dwarf.loc[reg]; - break; - - default: - loc = DWARF_NULL_LOC; /* default to "not saved" */ - break; - } - - memset (sloc, 0, sizeof (*sloc)); - - if (DWARF_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (DWARF_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = DWARF_GET_LOC (loc); - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = DWARF_GET_LOC (loc); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gglobal.c deleted file mode 100644 index ed2733397680f9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gglobal.c +++ /dev/null @@ -1,56 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "dwarf_i.h" - -HIDDEN define_lock (sh_lock); -HIDDEN int tdep_init_done; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&sh_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - dwarf_init (); - -#ifndef UNW_REMOTE_ONLY - sh_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&sh_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c deleted file mode 100644 index 52988a721e9d70..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c +++ /dev/null @@ -1,186 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include - -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -static inline void * -uc_addr (ucontext_t *uc, int reg) -{ - if (reg >= UNW_SH_R0 && reg <= UNW_SH_PR) - return &uc->uc_mcontext.gregs[reg]; - else - return NULL; -} - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) -{ - return uc_addr (uc, reg); -} - -# endif /* UNW_LOCAL_ONLY */ - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (write) - { - Debug (16, "mem[%x] <- %x\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - *val = *(unw_word_t *) addr; - Debug (16, "mem[%x] -> %x\n", addr, *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = arg; - - if (unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - *(unw_word_t *) addr = *val; - Debug (12, "%s <- %x\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> %x\n", unw_regname (reg), *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = arg; - unw_fpreg_t *addr; - - if (!unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - *(unw_fpreg_t *) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -sh_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = sh_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c deleted file mode 100644 index 99ddb36fb3e33f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c +++ /dev/null @@ -1,78 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright 2011 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. */ - -#include "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = uc; - - return common_init (c, use_prev_instr); -} - -int -unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_remote.c deleted file mode 100644 index 9b8ba5b89def1a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_remote.c +++ /dev/null @@ -1,45 +0,0 @@ -/* 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. */ - -#include "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - c->dwarf.as_arg = as_arg; - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gis_signal_frame.c deleted file mode 100644 index 4481fe1a498e11..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gis_signal_frame.c +++ /dev/null @@ -1,119 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -/* Disassembly of the Linux VDSO sigreturn functions: - -00000000 <__kernel_sigreturn>: - 0: 05 93 mov.w e <__kernel_sigreturn+0xe>,r3 ! 77 - 2: 10 c3 trapa #16 - 4: 0b 20 or r0,r0 - 6: 0b 20 or r0,r0 - 8: 0b 20 or r0,r0 - a: 0b 20 or r0,r0 - c: 0b 20 or r0,r0 - e: 77 00 .word 0x0077 - 10: 09 00 nop - 12: 09 00 nop - 14: 09 00 nop - 16: 09 00 nop - 18: 09 00 nop - 1a: 09 00 nop - 1c: 09 00 nop - 1e: 09 00 nop - -00000020 <__kernel_rt_sigreturn>: - 20: 05 93 mov.w 2e <__kernel_rt_sigreturn+0xe>,r3 ! ad - 22: 10 c3 trapa #16 - 24: 0b 20 or r0,r0 - 26: 0b 20 or r0,r0 - 28: 0b 20 or r0,r0 - 2a: 0b 20 or r0,r0 - 2c: 0b 20 or r0,r0 - 2e: ad 00 mov.w @(r0,r10),r0 - 30: 09 00 nop - 32: 09 00 nop - 34: 09 00 nop - 36: 09 00 nop - 38: 09 00 nop - 3a: 09 00 nop - 3c: 09 00 nop - 3e: 09 00 nop -*/ - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ -#ifdef __linux__ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - ip = c->dwarf.ip; - - ret = (*a->access_mem) (as, ip, &w0, 0, arg); - if (ret < 0) - return ret; - - if (w0 != 0xc3109305) - return 0; - - ret = (*a->access_mem) (as, ip+4, &w0, 0, arg); - if (ret < 0) - return ret; - - if (w0 != 0x200b200b) - return 0; - - ret = (*a->access_mem) (as, ip+8, &w0, 0, arg); - if (ret < 0) - return ret; - - if (w0 != 0x200b200b) - return 0; - - ret = (*a->access_mem) (as, ip+12, &w0, 0, arg); - if (ret < 0) - return ret; - - if (w0 == 0x0077200b) - return 1; /* non-RT */ - else if (w0 == 0x00ad200b) - return 2; /* RT */ - - /* does not look like a signal frame */ - return 0; - -#else - return -UNW_ENOINFO; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/sh/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gregs.c deleted file mode 100644 index 7d8e8e93da0426..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gregs.c +++ /dev/null @@ -1,81 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - - switch (reg) - { - case UNW_SH_PC: - if (write) - c->dwarf.ip = *valp; /* update the IP cache */ - case UNW_SH_R0: - case UNW_SH_R1: - case UNW_SH_R2: - case UNW_SH_R3: - case UNW_SH_R4: - case UNW_SH_R5: - case UNW_SH_R6: - case UNW_SH_R7: - case UNW_SH_R8: - case UNW_SH_R9: - case UNW_SH_R10: - case UNW_SH_R11: - case UNW_SH_R12: - case UNW_SH_R13: - case UNW_SH_R14: - case UNW_SH_PR: - loc = c->dwarf.loc[reg]; - break; - - case UNW_SH_R15: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c deleted file mode 100644 index a263c92718a0b4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c +++ /dev/null @@ -1,165 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright 2011 Linaro Limited - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" - -#ifndef UNW_REMOTE_ONLY - -HIDDEN inline int -sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ -#ifdef __linux__ - struct cursor *c = (struct cursor *) cursor; - unw_tdep_context_t *uc = c->dwarf.as_arg; - - if (c->sigcontext_format == SH_SCF_NONE) - { - /* Since there are no signals involved here we restore the non scratch - registers only. */ - unsigned long regs[8]; - regs[0] = uc->uc_mcontext.gregs[8]; - regs[1] = uc->uc_mcontext.gregs[9]; - regs[2] = uc->uc_mcontext.gregs[10]; - regs[3] = uc->uc_mcontext.gregs[11]; - regs[4] = uc->uc_mcontext.gregs[12]; - regs[5] = uc->uc_mcontext.gregs[13]; - regs[6] = uc->uc_mcontext.gregs[14]; - regs[7] = uc->uc_mcontext.gregs[15]; - unsigned long pc = uc->uc_mcontext.pr; - - struct regs_overlay { - char x[sizeof(regs)]; - }; - - asm volatile ( - "mov.l @%0+, r8\n" - "mov.l @%0+, r9\n" - "mov.l @%0+, r10\n" - "mov.l @%0+, r11\n" - "mov.l @%0+, r12\n" - "mov.l @%0+, r13\n" - "mov.l @%0+, r14\n" - "mov.l @%0, r15\n" - "lds %1, pr\n" - "rts\n" - "nop\n" - : - : "r" (regs), - "r" (pc), - "m" (*(struct regs_overlay *)regs) - ); - } - else - { - /* In case a signal frame is involved, we're using its trampoline which - calls sigreturn. */ - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - sc->sc_regs[0] = uc->uc_mcontext.gregs[0]; - sc->sc_regs[1] = uc->uc_mcontext.gregs[1]; - sc->sc_regs[2] = uc->uc_mcontext.gregs[2]; - sc->sc_regs[3] = uc->uc_mcontext.gregs[3]; - sc->sc_regs[4] = uc->uc_mcontext.gregs[4]; - sc->sc_regs[5] = uc->uc_mcontext.gregs[5]; - sc->sc_regs[6] = uc->uc_mcontext.gregs[6]; - sc->sc_regs[7] = uc->uc_mcontext.gregs[7]; - sc->sc_regs[8] = uc->uc_mcontext.gregs[8]; - sc->sc_regs[9] = uc->uc_mcontext.gregs[9]; - sc->sc_regs[10] = uc->uc_mcontext.gregs[10]; - sc->sc_regs[11] = uc->uc_mcontext.gregs[11]; - sc->sc_regs[12] = uc->uc_mcontext.gregs[12]; - sc->sc_regs[13] = uc->uc_mcontext.gregs[13]; - sc->sc_regs[14] = uc->uc_mcontext.gregs[14]; - sc->sc_regs[15] = uc->uc_mcontext.gregs[15]; - sc->sc_pc = uc->uc_mcontext.pc; - sc->sc_pr = uc->uc_mcontext.pr; - - /* Set the SP and the PC in order to continue execution at the modified - trampoline which restores the signal mask and the registers. */ - asm __volatile__ ( - "mov %0, r15\n" - "lds %1, pr\n" - "rts\n" - "nop\n" - : - : "r" (c->sigcontext_sp), - "r" (c->sigcontext_pc) - ); - } - unreachable(); -#endif - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ - -static inline void -establish_machine_state (struct cursor *c) -{ - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_REG_LAST; ++reg) - { - Debug (16, "copying %s %d\n", unw_regname (reg), reg); - if (unw_is_fpreg (reg)) - { - if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) - as->acc.access_fpreg (as, reg, &fpval, 1, arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - as->acc.access_reg (as, reg, &val, 1, arg); - } - } -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - - Debug (1, "(cursor=%p)\n", c); - - if (!c->dwarf.ip) - { - /* This can happen easily when the frame-chain gets truncated - due to bad or missing unwind-info. */ - Debug (1, "refusing to resume execution at address 0\n"); - return -UNW_EINVAL; - } - - establish_machine_state (c); - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gstep.c deleted file mode 100644 index 60d7ec2ba9f6e3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gstep.c +++ /dev/null @@ -1,117 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright 2011 Linaro Limited - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" - -static int -sh_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; - struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); - - if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) - return -UNW_EUNSPEC; - - ret = unw_is_signal_frame (cursor); - Debug(1, "unw_is_signal_frame()=%d\n", ret); - - /* Save the SP and PC to be able to return execution at this point - later in time (unw_resume). */ - c->sigcontext_sp = c->dwarf.cfa; - c->sigcontext_pc = c->dwarf.ip; - - if (ret == 1) - { - /* Handle non-RT signal frame. */ - c->sigcontext_format = SH_SCF_LINUX_SIGFRAME; - sc_addr = sp_addr; - } - else if (ret == 2) - { - /* Handle RT signal frame. */ - c->sigcontext_format = SH_SCF_LINUX_RT_SIGFRAME; - sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; - } - else - return -UNW_EUNSPEC; - - c->sigcontext_addr = sc_addr; - - /* Update the dwarf cursor. - Set the location of the registers to the corresponding addresses of the - uc_mcontext / sigcontext structure contents. */ - c->dwarf.loc[UNW_SH_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); - c->dwarf.loc[UNW_SH_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); - c->dwarf.loc[UNW_SH_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); - c->dwarf.loc[UNW_SH_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); - c->dwarf.loc[UNW_SH_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); - c->dwarf.loc[UNW_SH_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); - c->dwarf.loc[UNW_SH_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); - c->dwarf.loc[UNW_SH_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); - c->dwarf.loc[UNW_SH_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); - c->dwarf.loc[UNW_SH_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); - c->dwarf.loc[UNW_SH_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); - c->dwarf.loc[UNW_SH_R11] = DWARF_LOC (sc_addr + LINUX_SC_R11_OFF, 0); - c->dwarf.loc[UNW_SH_R12] = DWARF_LOC (sc_addr + LINUX_SC_R12_OFF, 0); - c->dwarf.loc[UNW_SH_R13] = DWARF_LOC (sc_addr + LINUX_SC_R13_OFF, 0); - c->dwarf.loc[UNW_SH_R14] = DWARF_LOC (sc_addr + LINUX_SC_R14_OFF, 0); - c->dwarf.loc[UNW_SH_R15] = DWARF_LOC (sc_addr + LINUX_SC_R15_OFF, 0); - c->dwarf.loc[UNW_SH_PR] = DWARF_LOC (sc_addr + LINUX_SC_PR_OFF, 0); - c->dwarf.loc[UNW_SH_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); - - /* Set SP/CFA and PC/IP. */ - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_R15], &c->dwarf.cfa); - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_PC], &c->dwarf.ip); - - c->dwarf.pi_valid = 0; - - return 1; -} - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p)\n", c); - - if (unw_is_signal_frame (cursor) > 0) - return sh_handle_signal_frame (cursor); - - ret = dwarf_step (&c->dwarf); - - if (unlikely (ret == -UNW_ESTOPUNWIND)) - return ret; - - if (unlikely (ret < 0)) - return 0; - - return (c->dwarf.ip == 0) ? 0 : 1; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lglobal.c deleted file mode 100644 index 6d7b489e14bd9f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Lglobal.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Linit.c b/src/coreclr/src/pal/src/libunwind/src/sh/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/sh/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/sh/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9fa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/gen-offsets.c b/src/coreclr/src/pal/src/libunwind/src/sh/gen-offsets.c deleted file mode 100644 index 16695a64896fc9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/gen-offsets.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include - -#define UC(N,X) \ - printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) - -#define SC(N,X) \ - printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) - -int -main (void) -{ - printf ( -"/* Linux-specific definitions: */\n\n" - -"/* Define various structure offsets to simplify cross-compilation. */\n\n" - -"/* Offsets for SH Linux \"ucontext_t\": */\n\n"); - - UC ("FLAGS", uc_flags); - UC ("LINK", uc_link); - UC ("STACK", uc_stack); - UC ("MCONTEXT", uc_mcontext); - UC ("SIGMASK", uc_sigmask); - - printf ("\n/* Offsets for SH Linux \"struct sigcontext\": */\n\n"); - - SC ("R0", sc_regs[0]); - SC ("R1", sc_regs[1]); - SC ("R2", sc_regs[2]); - SC ("R3", sc_regs[3]); - SC ("R4", sc_regs[4]); - SC ("R5", sc_regs[5]); - SC ("R6", sc_regs[6]); - SC ("R7", sc_regs[7]); - SC ("R8", sc_regs[8]); - SC ("R9", sc_regs[9]); - SC ("R10", sc_regs[10]); - SC ("R11", sc_regs[11]); - SC ("R12", sc_regs[12]); - SC ("R13", sc_regs[13]); - SC ("R14", sc_regs[14]); - SC ("R15", sc_regs[15]); - - SC ("PC", sc_pc); - SC ("PR", sc_pr); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/init.h b/src/coreclr/src/pal/src/libunwind/src/sh/init.h deleted file mode 100644 index 36713fe89b0c04..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/init.h +++ /dev/null @@ -1,73 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static inline int -common_init (struct cursor *c, unsigned use_prev_instr) -{ - int ret; - - c->dwarf.loc[UNW_SH_R0] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R0); - c->dwarf.loc[UNW_SH_R1] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R1); - c->dwarf.loc[UNW_SH_R2] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R2); - c->dwarf.loc[UNW_SH_R3] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R3); - c->dwarf.loc[UNW_SH_R4] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R4); - c->dwarf.loc[UNW_SH_R5] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R5); - c->dwarf.loc[UNW_SH_R6] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R6); - c->dwarf.loc[UNW_SH_R7] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R7); - c->dwarf.loc[UNW_SH_R8] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R8); - c->dwarf.loc[UNW_SH_R9] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R9); - c->dwarf.loc[UNW_SH_R10] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R10); - c->dwarf.loc[UNW_SH_R11] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R11); - c->dwarf.loc[UNW_SH_R12] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R12); - c->dwarf.loc[UNW_SH_R13] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R13); - c->dwarf.loc[UNW_SH_R14] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R14); - c->dwarf.loc[UNW_SH_R15] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R15); - c->dwarf.loc[UNW_SH_PC] = DWARF_REG_LOC (&c->dwarf, UNW_SH_PC); - c->dwarf.loc[UNW_SH_PR] = DWARF_REG_LOC (&c->dwarf, UNW_SH_PR); - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_PC], &c->dwarf.ip); - if (ret < 0) - return ret; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TDEP_SP], &c->dwarf.cfa); - if (ret < 0) - return ret; - - c->sigcontext_format = SH_SCF_NONE; - c->sigcontext_addr = 0; - c->sigcontext_sp = 0; - c->sigcontext_pc = 0; - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/sh/is_fpreg.c deleted file mode 100644 index de0934019413ec..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/is_fpreg.c +++ /dev/null @@ -1,32 +0,0 @@ -/* 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. */ - -#include "libunwind_i.h" - -int -unw_is_fpreg (int regnum) -{ - /* FIXME: Support FP. */ - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/offsets.h b/src/coreclr/src/pal/src/libunwind/src/sh/offsets.h deleted file mode 100644 index b02d8aee1e0008..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/offsets.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Linux-specific definitions: */ - -/* Define various structure offsets to simplify cross-compilation. */ - -/* Offsets for SH Linux "ucontext_t": */ - -#define LINUX_UC_FLAGS_OFF 0x0 -#define LINUX_UC_LINK_OFF 0x4 -#define LINUX_UC_STACK_OFF 0x8 -#define LINUX_UC_MCONTEXT_OFF 0x14 -#define LINUX_UC_SIGMASK_OFF 0xFC - -/* Offsets for SH Linux "struct sigcontext": */ - -#define LINUX_SC_R0_OFF 0x4 -#define LINUX_SC_R1_OFF 0x8 -#define LINUX_SC_R2_OFF 0xC -#define LINUX_SC_R3_OFF 0x10 -#define LINUX_SC_R4_OFF 0x14 -#define LINUX_SC_R5_OFF 0x18 -#define LINUX_SC_R6_OFF 0x1C -#define LINUX_SC_R7_OFF 0x20 -#define LINUX_SC_R8_OFF 0x24 -#define LINUX_SC_R9_OFF 0x28 -#define LINUX_SC_R10_OFF 0x2C -#define LINUX_SC_R11_OFF 0x30 -#define LINUX_SC_R12_OFF 0x34 -#define LINUX_SC_R13_OFF 0x38 -#define LINUX_SC_R14_OFF 0x3C -#define LINUX_SC_R15_OFF 0x40 -#define LINUX_SC_PC_OFF 0x44 -#define LINUX_SC_PR_OFF 0x48 diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/regname.c b/src/coreclr/src/pal/src/libunwind/src/sh/regname.c deleted file mode 100644 index b52925b4da7ec4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/regname.c +++ /dev/null @@ -1,56 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static const char *const regname[] = - { - [UNW_SH_R0] = "r0", - [UNW_SH_R1] = "r1", - [UNW_SH_R2] = "r2", - [UNW_SH_R3] = "r3", - [UNW_SH_R4] = "r4", - [UNW_SH_R5] = "r5", - [UNW_SH_R6] = "r6", - [UNW_SH_R7] = "r7", - [UNW_SH_R8] = "r8", - [UNW_SH_R9] = "r9", - [UNW_SH_R10] = "r10", - [UNW_SH_R11] = "r11", - [UNW_SH_R12] = "r12", - [UNW_SH_R13] = "r13", - [UNW_SH_R14] = "r14", - [UNW_SH_R15] = "r15", - [UNW_SH_PC] = "pc", - [UNW_SH_PR] = "pr", - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname) && regname[reg] != NULL) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/sh/siglongjmp.S deleted file mode 100644 index 9ca53d124b98d1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/siglongjmp.S +++ /dev/null @@ -1,8 +0,0 @@ - /* Dummy implementation for now. */ - - .globl _UI_siglongjmp_cont - .globl _UI_longjmp_cont - -_UI_siglongjmp_cont: -_UI_longjmp_cont: - rts diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/sh/unwind_i.h deleted file mode 100644 index 3066d84631e96b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/sh/unwind_i.h +++ /dev/null @@ -1,40 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - -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 unwind_i_h -#define unwind_i_h - -#include - -#include "libunwind_i.h" - -#define sh_lock UNW_OBJ(lock) -#define sh_local_resume UNW_OBJ(local_resume) -#define sh_local_addr_space_init UNW_OBJ(local_addr_space_init) - -extern void sh_local_addr_space_init (void); -extern int sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, - void *arg); - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gcreate_addr_space.c deleted file mode 100644 index 39acdc2c3d3abb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gcreate_addr_space.c +++ /dev/null @@ -1,65 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as = malloc (sizeof (*as)); - - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - /* - * Tilegx supports only big or little-endian, not weird stuff like - * PDP_ENDIAN. - */ - if (byte_order != 0 - && byte_order != __LITTLE_ENDIAN - && byte_order != __BIG_ENDIAN) - return NULL; - - if (byte_order == 0) - /* use host default: */ - as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); - else - as->big_endian = (byte_order == __BIG_ENDIAN); - - as->abi = UNW_TILEGX_ABI_N64; - as->addr_size = 8; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_proc_info.c deleted file mode 100644 index 3a158da2df7aa6..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_proc_info.c +++ /dev/null @@ -1,48 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - ret = dwarf_make_proc_info (&c->dwarf); - - if (ret < 0) - { - /* On Tilegx, some routines i.e. _start() etc has no dwarf info. - Just simply mark the end of the frames. */ - memset (pi, 0, sizeof (*pi)); - pi->start_ip = c->dwarf.ip; - pi->end_ip = c->dwarf.ip + 1; - return 0; - } - - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_save_loc.c deleted file mode 100644 index fcf0697892880b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_save_loc.c +++ /dev/null @@ -1,62 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - struct cursor *c = (struct cursor *) cursor; - dwarf_loc_t loc; - - loc = DWARF_NULL_LOC; /* default to "not saved" */ - - if (reg <= UNW_TILEGX_R55) - loc = c->dwarf.loc[reg - UNW_TILEGX_R0]; - else - printf("\nInvalid register!"); - - memset (sloc, 0, sizeof (*sloc)); - - if (DWARF_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (DWARF_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = DWARF_GET_LOC (loc); - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = DWARF_GET_LOC (loc); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gglobal.c deleted file mode 100644 index e18f50a50f3b3e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gglobal.c +++ /dev/null @@ -1,64 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "dwarf_i.h" - -__attribute__((weak)) -pthread_mutex_t tilegx_lock = PTHREAD_MUTEX_INITIALIZER; -HIDDEN int tdep_init_done; - -HIDDEN const uint8_t dwarf_to_unw_regnum_map[] = - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55 - }; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&tilegx_lock, saved_mask); - - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - dwarf_init (); - -#ifndef UNW_REMOTE_ONLY - tilegx_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - - out: - lock_release (&tilegx_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c deleted file mode 100644 index 7564a558be4362..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c +++ /dev/null @@ -1,167 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include - -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -/* Return the address of the 64-bit slot in UC for REG (even for o32, - where registers are 32-bit, the slots are still 64-bit). */ - -static inline void * -uc_addr (ucontext_t *uc, int reg) -{ - if (reg >= UNW_TILEGX_R0 && reg < UNW_TILEGX_R0 + 56) - return &uc->uc_mcontext.gregs[reg - UNW_TILEGX_R0]; - else if (reg == UNW_TILEGX_PC) - return &uc->uc_mcontext.pc; - else - return NULL; -} - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) -{ - char *addr = uc_addr (uc, reg); - return addr; -} - -# endif /* UNW_LOCAL_ONLY */ - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ - *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list; - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if ((long long)addr & (sizeof(unw_word_t) - 1)) - return 0; - - if (write) - { - Debug (16, "mem[%llx] <- %llx\n", (long long) addr, (long long) *val); - *(unw_word_t *) (intptr_t) addr = *val; - } - else - { - *val = *(unw_word_t *) (intptr_t) addr; - Debug (16, "mem[%llx] -> %llx\n", (long long) addr, (long long) *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = arg; - - if (unw_is_fpreg (reg)) - goto badreg; - - Debug (16, "reg = %s\n", unw_regname (reg)); - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - *(unw_word_t *) (intptr_t) addr = (tilegx_reg_t) *val; - Debug (12, "%s <- %llx\n", unw_regname (reg), (long long) *val); - } - else - { - *val = (tilegx_reg_t) *(unw_word_t *) (intptr_t) addr; - Debug (12, "%s -> %llx\n", unw_regname (reg), (long long) *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp); -} - -__attribute__((weak)) void -tilegx_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); - - local_addr_space.abi = UNW_TILEGX_ABI_N64; - local_addr_space.addr_size = sizeof (void *); - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = NULL; - local_addr_space.acc.resume = tilegx_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_local.c deleted file mode 100644 index 31a716df348e3b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_local.c +++ /dev/null @@ -1,80 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - memset(c, 0, sizeof(unw_cursor_t)); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - - c->dwarf.as_arg = uc; - return common_init (c, use_prev_instr); -} - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_remote.c deleted file mode 100644 index 2a31b18aaef78d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_remote.c +++ /dev/null @@ -1,47 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - c->dwarf.as_arg = as_arg; - - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gis_signal_frame.c deleted file mode 100644 index 5452c2cb2aaf1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gis_signal_frame.c +++ /dev/null @@ -1,115 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include -#include "offsets.h" - -#ifdef __linux__ -#include -#include -#else -# error "Only support Linux!" -#endif - -#define MOVELI_R10_RT_SIGRETURN \ - ( 0x000007e051483000ULL | \ - ((unsigned long)__NR_rt_sigreturn << 43) | \ - ((unsigned long)TREG_SYSCALL_NR << 31) ) -#define SWINT1 0x286b180051485000ULL - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor*) cursor; - unw_word_t w0, w1, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - ip = c->dwarf.ip; - - if (!ip || !a->access_mem || (ip & (sizeof(unw_word_t) - 1))) - return 0; - - if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) - return ret; - - if ((ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0) - return ret; - - /* Return 1 if the IP points to a RT sigreturn sequence. */ - if (w0 == MOVELI_R10_RT_SIGRETURN && - w1 == SWINT1) - { - return 1; - } - return 0; -} - - -HIDDEN int -tilegx_handle_signal_frame (unw_cursor_t *cursor) -{ - int i; - struct cursor *c = (struct cursor *) cursor; - unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; - struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); - int ret; - - if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) - return -UNW_EUNSPEC; - - /* Save the SP and PC to be able to return execution at this point - later in time (unw_resume). */ - c->sigcontext_sp = c->dwarf.cfa; - c->sigcontext_pc = c->dwarf.ip; - - c->sigcontext_addr = sp_addr + sizeof (siginfo_t) + - C_ABI_SAVE_AREA_SIZE; - sc_addr = c->sigcontext_addr + LINUX_UC_MCONTEXT_OFF; - - /* Update the dwarf cursor. - Set the location of the registers to the corresponding addresses of the - uc_mcontext / sigcontext structure contents. */ - -#define SC_REG_OFFSET(X) (8 * X) - - for (i = UNW_TILEGX_R0; i <= UNW_TILEGX_R55; i++) - { - c->dwarf.loc[i] = DWARF_LOC (sc_addr + SC_REG_OFFSET(i), 0); - } - - /* Set SP/CFA and PC/IP. */ - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TILEGX_R54], &c->dwarf.cfa); - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TILEGX_R55], &c->dwarf.ip); - - return 1; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gregs.c deleted file mode 100644 index 565c6f4432a28e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gregs.c +++ /dev/null @@ -1,76 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - - if (reg == UNW_TILEGX_R54 && !write) - { - reg = UNW_TILEGX_CFA; - } - - if (reg <= UNW_TILEGX_R55) - loc = c->dwarf.loc[reg - UNW_TILEGX_R0]; - else if (reg == UNW_TILEGX_CFA) - { - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - } - else - { - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - { - if (ci->dwarf.use_prev_instr == 0) { - if (reg == UNW_TILEGX_PC) - c->dwarf.ip = *valp; /* update the IP cache */ - } - else { - if (reg == UNW_TILEGX_R55) - c->dwarf.ip = *valp; /* update the IP cache */ - } - return dwarf_put (&c->dwarf, loc, *valp); - } - else - return dwarf_get (&c->dwarf, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gresume.c deleted file mode 100644 index ece443a5b56fc9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gresume.c +++ /dev/null @@ -1,94 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - - -#include "unwind_i.h" -#include "offsets.h" -#include - -#ifndef UNW_REMOTE_ONLY - -HIDDEN inline int -tilegx_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - int i; - struct cursor *c = (struct cursor *) cursor; - ucontext_t *uc = c->dwarf.as_arg; - - Debug (1, "(cursor=%p\n", c); - - return setcontext(uc); -} - -#endif /* !UNW_REMOTE_ONLY */ - -static inline void -establish_machine_state (struct cursor *c) -{ - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_REG_LAST; ++reg) - { - Debug (16, "copying %s %d\n", unw_regname (reg), reg); - - if (unw_is_fpreg (reg)) - { - Debug (1, "no fp!"); - abort (); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - as->acc.access_reg (as, reg, &val, 1, arg); - } - } -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - - Debug (1, "(cursor=%p) ip=0x%lx\n", c, c->dwarf.ip); - - if (!c->dwarf.ip) - { - /* This can happen easily when the frame-chain gets truncated - due to bad or missing unwind-info. */ - Debug (1, "refusing to resume execution at address 0\n"); - return -UNW_EINVAL; - } - - establish_machine_state (c); - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gstep.c deleted file mode 100644 index c748dbc588a856..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gstep.c +++ /dev/null @@ -1,53 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p, ip=0x%016lx, sp=0x%016lx)\n", - c, c->dwarf.ip, c->dwarf.cfa); - - /* Special handling the singal frame. */ - if (unw_is_signal_frame (cursor) > 0) - return tilegx_handle_signal_frame (cursor); - - /* Try DWARF-based unwinding... */ - ret = dwarf_step (&c->dwarf); - - if (unlikely (ret == -UNW_ESTOPUNWIND)) - return ret; - - /* Dwarf unwinding didn't work, stop. */ - if (unlikely (ret < 0)) - return 0; - - return (c->dwarf.ip == 0) ? 0 : 1; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lglobal.c deleted file mode 100644 index 6d7b489e14bd9f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lglobal.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9fa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/elfxx.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/elfxx.c deleted file mode 100644 index 07d3d12b94fe00..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/elfxx.c +++ /dev/null @@ -1,27 +0,0 @@ -/* 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. */ - -#include "libunwind_i.h" - -#include "../src/elfxx.c" diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/gen-offsets.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/gen-offsets.c deleted file mode 100644 index 8704bb215e3cb7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/gen-offsets.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include - -#define UC(N,X) \ - printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) - -#define SC(N,X) \ - printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) - -int -main (void) -{ - printf ( -"/* Linux-specific definitions: */\n\n" - -"/* Define various structure offsets to simplify cross-compilation. */\n\n" - -"/* Offsets for TILEGX Linux \"ucontext_t\": */\n\n"); - - UC ("FLAGS", uc_flags); - UC ("LINK", uc_link); - UC ("STACK", uc_stack); - UC ("MCONTEXT", uc_mcontext); - UC ("SIGMASK", uc_sigmask); - - UC ("MCONTEXT_GREGS", uc_mcontext.gregs); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/tilegx/getcontext.S deleted file mode 100644 index fbc8654bc7f1f9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/getcontext.S +++ /dev/null @@ -1,36 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "offsets.h" -#include - - .text - # define REG(X) LINUX_UC_MCONTEXT_GREGS + 8 * (X) - .global _Utilegx_getcontext - .type _Utilegx_getcontext, %function - # This is a stub version of getcontext() for TILEGX. -_Utilegx_getcontext: - - diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/init.h b/src/coreclr/src/pal/src/libunwind/src/tilegx/init.h deleted file mode 100644 index 0e0f7fd1da819c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/init.h +++ /dev/null @@ -1,63 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static inline int -common_init (struct cursor *c, unsigned use_prev_instr) -{ - int ret, i; - - for (i = 0; i < 56; i++) - c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R0 + i); - for (i = 56; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - if (use_prev_instr == 0) - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_PC), - &c->dwarf.ip); - else - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R55), - &c->dwarf.ip); - - if (ret < 0) - return ret; - - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R54), - &c->dwarf.cfa); - - if (ret < 0) - return ret; - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/is_fpreg.c deleted file mode 100644 index d6d58969018882..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/is_fpreg.c +++ /dev/null @@ -1,33 +0,0 @@ -/* 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. */ - -#include "libunwind_i.h" - -/* TILEGX has no FP. */ - -int -unw_is_fpreg (int regnum) -{ - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/offsets.h b/src/coreclr/src/pal/src/libunwind/src/tilegx/offsets.h deleted file mode 100644 index 6d30f1edcff1ef..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/offsets.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Linux-specific definitions: */ - -/* Define various structure offsets to simplify cross-compilation. */ - -/* Offsets for TILEGX Linux "ucontext_t": */ - -#define LINUX_UC_FLAGS_OFF 0x0 -#define LINUX_UC_LINK_OFF 0x8 -#define LINUX_UC_STACK_OFF 0x10 -#define LINUX_UC_MCONTEXT_OFF 0x28 -#define LINUX_UC_SIGMASK_OFF 0x228 -#define LINUX_UC_MCONTEXT_GREGS 0x28 diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/regname.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/regname.c deleted file mode 100644 index 0ce47b9d66ed85..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/regname.c +++ /dev/null @@ -1,55 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright (C) 2014 Tilera Corp. - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static const char *regname[] = - { - /* 0. */ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - /* 8. */ - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - /* 16. */ - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - /* 24. */ - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - /* 32. */ - "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", - /* 40. */ - "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", - /* 48. */ - "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", - /* pc, cfa */ - "pc", "cfa" - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/tilegx/siglongjmp.S deleted file mode 100644 index bccb1c77854339..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/siglongjmp.S +++ /dev/null @@ -1,7 +0,0 @@ - /* Dummy implementation for now. */ - .globl _UI_siglongjmp_cont - .globl _UI_longjmp_cont - -_UI_siglongjmp_cont: -_UI_longjmp_cont: - jrp lr diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/tilegx/unwind_i.h deleted file mode 100644 index 9d41c90b4d10bc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/unwind_i.h +++ /dev/null @@ -1,46 +0,0 @@ -/* 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 unwind_i_h -#define unwind_i_h - -#include -#include - -#include - -#include "libunwind_i.h" - -#define tilegx_local_resume UNW_OBJ(local_resume) -#define tilegx_local_addr_space_init UNW_OBJ(local_addr_space_init) - -extern int tilegx_local_resume (unw_addr_space_t as, - unw_cursor_t *cursor, - void *arg); -#define tilegx_handle_signal_frame UNW_OBJ(handle_signal_frame) -extern int tilegx_handle_signal_frame(unw_cursor_t *cursor); - -extern void tilegx_local_addr_space_init (void); - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/Backtrace.c b/src/coreclr/src/pal/src/libunwind/src/unwind/Backtrace.c deleted file mode 100644 index 0b14df4cb9da60..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/Backtrace.c +++ /dev/null @@ -1,56 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -_Unwind_Reason_Code -_Unwind_Backtrace (_Unwind_Trace_Fn trace, void *trace_parameter) -{ - struct _Unwind_Context context; - unw_context_t uc; - int ret; - - if (_Unwind_InitContext (&context, &uc) < 0) - return _URC_FATAL_PHASE1_ERROR; - - /* Phase 1 (search phase) */ - - while (1) - { - if ((ret = unw_step (&context.cursor)) <= 0) - { - if (ret == 0) - return _URC_END_OF_STACK; - else - return _URC_FATAL_PHASE1_ERROR; - } - - if ((*trace) (&context, trace_parameter) != _URC_NO_REASON) - return _URC_FATAL_PHASE1_ERROR; - } -} - -_Unwind_Reason_Code __libunwind_Unwind_Backtrace (_Unwind_Trace_Fn, void *) - ALIAS (_Unwind_Backtrace); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/DeleteException.c b/src/coreclr/src/pal/src/libunwind/src/unwind/DeleteException.c deleted file mode 100644 index ad38eaf651e063..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/DeleteException.c +++ /dev/null @@ -1,38 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -void -_Unwind_DeleteException (struct _Unwind_Exception *exception_object) -{ - _Unwind_Exception_Cleanup_Fn cleanup = exception_object->exception_cleanup; - - if (cleanup) - (*cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exception_object); -} - -void __libunwind_Unwind_DeleteException (struct _Unwind_Exception *) - ALIAS (_Unwind_DeleteException); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/FindEnclosingFunction.c b/src/coreclr/src/pal/src/libunwind/src/unwind/FindEnclosingFunction.c deleted file mode 100644 index 4f106661725f28..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/FindEnclosingFunction.c +++ /dev/null @@ -1,42 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -void * -_Unwind_FindEnclosingFunction (void *ip) -{ - unw_proc_info_t pi; - - if (unw_get_proc_info_by_ip (unw_local_addr_space, - (unw_word_t) (uintptr_t) ip, &pi, 0) - < 0) - return NULL; - - return (void *) (uintptr_t) pi.start_ip; -} - -void *__libunwind_Unwind_FindEnclosingFunction (void *) - ALIAS (_Unwind_FindEnclosingFunction); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/ForcedUnwind.c b/src/coreclr/src/pal/src/libunwind/src/unwind/ForcedUnwind.c deleted file mode 100644 index 905b31cd873508..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/ForcedUnwind.c +++ /dev/null @@ -1,52 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -_Unwind_Reason_Code -_Unwind_ForcedUnwind (struct _Unwind_Exception *exception_object, - _Unwind_Stop_Fn stop, void *stop_parameter) -{ - struct _Unwind_Context context; - unw_context_t uc; - - /* We check "stop" here to tell the compiler's inliner that - exception_object->private_1 isn't NULL when calling - _Unwind_Phase2(). */ - if (!stop) - return _URC_FATAL_PHASE2_ERROR; - - if (_Unwind_InitContext (&context, &uc) < 0) - return _URC_FATAL_PHASE2_ERROR; - - exception_object->private_1 = (unsigned long) stop; - exception_object->private_2 = (unsigned long) stop_parameter; - - return _Unwind_Phase2 (exception_object, &context); -} - -_Unwind_Reason_Code __libunwind_Unwind_ForcedUnwind (struct _Unwind_Exception*, - _Unwind_Stop_Fn, void *) - ALIAS (_Unwind_ForcedUnwind); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetBSP.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetBSP.c deleted file mode 100644 index d1bc84e0d20f84..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/GetBSP.c +++ /dev/null @@ -1,42 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -unsigned long -_Unwind_GetBSP (struct _Unwind_Context *context) -{ -#ifdef UNW_TARGET_IA64 - unw_word_t val; - - unw_get_reg (&context->cursor, UNW_IA64_BSP, &val); - return val; -#else - return 0; -#endif -} - -unsigned long __libunwind_Unwind_GetBSP (struct _Unwind_Context *) - ALIAS (_Unwind_GetBSP); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetCFA.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetCFA.c deleted file mode 100644 index 5ca63903dda0dd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/GetCFA.c +++ /dev/null @@ -1,38 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -unsigned long -_Unwind_GetCFA (struct _Unwind_Context *context) -{ - unw_word_t val; - - unw_get_reg (&context->cursor, UNW_REG_SP, &val); - return val; -} - -unsigned long __libunwind_Unwind_GetCFA (struct _Unwind_Context *) - ALIAS (_Unwind_GetCFA); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetDataRelBase.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetDataRelBase.c deleted file mode 100644 index 8e6914f4f35415..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/GetDataRelBase.c +++ /dev/null @@ -1,39 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -unsigned long -_Unwind_GetDataRelBase (struct _Unwind_Context *context) -{ - unw_proc_info_t pi; - - pi.gp = 0; - unw_get_proc_info (&context->cursor, &pi); - return pi.gp; -} - -unsigned long __libunwind_Unwind_GetDataRelBase (struct _Unwind_Context *) - ALIAS (_Unwind_GetDataRelBase); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetGR.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetGR.c deleted file mode 100644 index fa709434353f62..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/GetGR.c +++ /dev/null @@ -1,43 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -unsigned long -_Unwind_GetGR (struct _Unwind_Context *context, int index) -{ - unw_word_t val; - - if (index == UNW_REG_SP && context->end_of_stack) - /* _Unwind_ForcedUnwind() requires us to return a NULL - stack-pointer after reaching the end of the stack. */ - return 0; - - unw_get_reg (&context->cursor, index, &val); - return val; -} - -unsigned long __libunwind_Unwind_GetGR (struct _Unwind_Context *, int) - ALIAS (_Unwind_GetGR); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetIP.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetIP.c deleted file mode 100644 index e9fc4944025de4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/GetIP.c +++ /dev/null @@ -1,38 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -unsigned long -_Unwind_GetIP (struct _Unwind_Context *context) -{ - unw_word_t val; - - unw_get_reg (&context->cursor, UNW_REG_IP, &val); - return val; -} - -unsigned long __libunwind_Unwind_GetIP (struct _Unwind_Context *) - ALIAS (_Unwind_GetIP); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetIPInfo.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetIPInfo.c deleted file mode 100644 index e8ee7fd7f1b1ca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/GetIPInfo.c +++ /dev/null @@ -1,42 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2009 Red Hat - Contributed by Jan Kratochvil - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -/* gcc/unwind-dw2.c: Retrieve the return address and flag whether that IP is - before or after first not yet fully executed instruction. */ - -unsigned long -_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) -{ - unw_word_t val; - - unw_get_reg (&context->cursor, UNW_REG_IP, &val); - *ip_before_insn = unw_is_signal_frame (&context->cursor); - return val; -} - -unsigned long __libunwind_Unwind_GetIPInfo (struct _Unwind_Context *, int *) - ALIAS (_Unwind_GetIPInfo); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetLanguageSpecificData.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetLanguageSpecificData.c deleted file mode 100644 index e7ca9b453c388b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/GetLanguageSpecificData.c +++ /dev/null @@ -1,40 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -unsigned long -_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context) -{ - unw_proc_info_t pi; - - pi.lsda = 0; - unw_get_proc_info (&context->cursor, &pi); - return pi.lsda; -} - -unsigned long -__libunwind_Unwind_GetLanguageSpecificData (struct _Unwind_Context *) - ALIAS (_Unwind_GetLanguageSpecificData); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetRegionStart.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetRegionStart.c deleted file mode 100644 index f4995813face3d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/GetRegionStart.c +++ /dev/null @@ -1,39 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -unsigned long -_Unwind_GetRegionStart (struct _Unwind_Context *context) -{ - unw_proc_info_t pi; - - pi.start_ip = 0; - unw_get_proc_info (&context->cursor, &pi); - return pi.start_ip; -} - -unsigned long __libunwind_Unwind_GetRegionStart (struct _Unwind_Context *) - ALIAS (_Unwind_GetRegionStart); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetTextRelBase.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetTextRelBase.c deleted file mode 100644 index ce65ae93e77d8f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/GetTextRelBase.c +++ /dev/null @@ -1,35 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -unsigned long -_Unwind_GetTextRelBase (struct _Unwind_Context *context) -{ - return 0; -} - -unsigned long __libunwind_Unwind_GetTextRelBase (struct _Unwind_Context *) - ALIAS (_Unwind_GetTextRelBase); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/RaiseException.c b/src/coreclr/src/pal/src/libunwind/src/unwind/RaiseException.c deleted file mode 100644 index 3c3ca19e989f68..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/RaiseException.c +++ /dev/null @@ -1,103 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -_Unwind_Reason_Code -_Unwind_RaiseException (struct _Unwind_Exception *exception_object) -{ - uint64_t exception_class = exception_object->exception_class; - _Unwind_Personality_Fn personality; - struct _Unwind_Context context; - _Unwind_Reason_Code reason; - unw_proc_info_t pi; - unw_context_t uc; - unw_word_t ip; - int ret; - - Debug (1, "(exception_object=%p)\n", exception_object); - - if (_Unwind_InitContext (&context, &uc) < 0) - return _URC_FATAL_PHASE1_ERROR; - - /* Phase 1 (search phase) */ - - while (1) - { - if ((ret = unw_step (&context.cursor)) <= 0) - { - if (ret == 0) - { - Debug (1, "no handler found\n"); - return _URC_END_OF_STACK; - } - else - return _URC_FATAL_PHASE1_ERROR; - } - - if (unw_get_proc_info (&context.cursor, &pi) < 0) - return _URC_FATAL_PHASE1_ERROR; - - personality = (_Unwind_Personality_Fn) (uintptr_t) pi.handler; - if (personality) - { - reason = (*personality) (_U_VERSION, _UA_SEARCH_PHASE, - exception_class, exception_object, - &context); - if (reason != _URC_CONTINUE_UNWIND) - { - if (reason == _URC_HANDLER_FOUND) - break; - else - { - Debug (1, "personality returned %d\n", reason); - return _URC_FATAL_PHASE1_ERROR; - } - } - } - } - - /* Exceptions are associated with IP-ranges. If a given exception - is handled at a particular IP, it will _always_ be handled at - that IP. If this weren't true, we'd have to track the tuple - (IP,SP,BSP) to uniquely identify the stack frame that's handling - the exception. */ - if (unw_get_reg (&context.cursor, UNW_REG_IP, &ip) < 0) - return _URC_FATAL_PHASE1_ERROR; - exception_object->private_1 = 0; /* clear "stop" pointer */ - exception_object->private_2 = ip; /* save frame marker */ - - Debug (1, "found handler for IP=%lx; entering cleanup phase\n", (long) ip); - - /* Reset the cursor to the first frame: */ - if (unw_init_local (&context.cursor, &uc) < 0) - return _URC_FATAL_PHASE1_ERROR; - - return _Unwind_Phase2 (exception_object, &context); -} - -_Unwind_Reason_Code -__libunwind_Unwind_RaiseException (struct _Unwind_Exception *) - ALIAS (_Unwind_RaiseException); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/Resume.c b/src/coreclr/src/pal/src/libunwind/src/unwind/Resume.c deleted file mode 100644 index e23d6be27cf8da..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/Resume.c +++ /dev/null @@ -1,42 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -void -_Unwind_Resume (struct _Unwind_Exception *exception_object) -{ - struct _Unwind_Context context; - unw_context_t uc; - - if (_Unwind_InitContext (&context, &uc) < 0) - abort (); - - _Unwind_Phase2 (exception_object, &context); - abort (); -} - -void __libunwind_Unwind_Resume (struct _Unwind_Exception *) - ALIAS (_Unwind_Resume); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/Resume_or_Rethrow.c b/src/coreclr/src/pal/src/libunwind/src/unwind/Resume_or_Rethrow.c deleted file mode 100644 index 9c76443b365acc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/Resume_or_Rethrow.c +++ /dev/null @@ -1,47 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -_Unwind_Reason_Code -_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exception_object) -{ - struct _Unwind_Context context; - unw_context_t uc; - - if (exception_object->private_1) - { - if (_Unwind_InitContext (&context, &uc) < 0) - return _URC_FATAL_PHASE2_ERROR; - - return _Unwind_Phase2 (exception_object, &context); - } - else - return _Unwind_RaiseException (exception_object); -} - -_Unwind_Reason_Code -__libunwind_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *) - ALIAS (_Unwind_Resume_or_Rethrow); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/SetGR.c b/src/coreclr/src/pal/src/libunwind/src/unwind/SetGR.c deleted file mode 100644 index ae77a8e8258e84..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/SetGR.c +++ /dev/null @@ -1,47 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" -#ifdef UNW_TARGET_X86 -#include "dwarf_i.h" -#endif - -void -_Unwind_SetGR (struct _Unwind_Context *context, int index, - unsigned long new_value) -{ -#ifdef UNW_TARGET_X86 - index = dwarf_to_unw_regnum(index); -#endif - unw_set_reg (&context->cursor, index, new_value); -#ifdef UNW_TARGET_IA64 - if (index >= UNW_IA64_GR && index <= UNW_IA64_GR + 127) - /* Clear the NaT bit. */ - unw_set_reg (&context->cursor, UNW_IA64_NAT + (index - UNW_IA64_GR), 0); -#endif -} - -void __libunwind_Unwind_SetGR (struct _Unwind_Context *, int, unsigned long) - ALIAS (_Unwind_SetGR); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/SetIP.c b/src/coreclr/src/pal/src/libunwind/src/unwind/SetIP.c deleted file mode 100644 index fccc2f0dd57da8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/SetIP.c +++ /dev/null @@ -1,35 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind-internal.h" - -void -_Unwind_SetIP (struct _Unwind_Context *context, unsigned long new_value) -{ - unw_set_reg (&context->cursor, UNW_REG_IP, new_value); -} - -void __libunwind_Unwind_SetIP (struct _Unwind_Context *, unsigned long) - ALIAS (_Unwind_SetIP); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in b/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in deleted file mode 100644 index 1505c5d6f67d35..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libunwind -Description: libunwind base library -Version: @VERSION@ -Libs: -L${libdir} -lunwind -Libs.private: @LIBLZMA@ -Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/unwind-internal.h b/src/coreclr/src/pal/src/libunwind/src/unwind/unwind-internal.h deleted file mode 100644 index c68fc3c5ed34ad..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/unwind-internal.h +++ /dev/null @@ -1,140 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 unwind_internal_h -#define unwind_internal_h - -#define UNW_LOCAL_ONLY - -#include -#include -#include - -#include "libunwind_i.h" - -/* The version of the _Unwind_*() interface implemented by this code. */ -#define _U_VERSION 1 - -typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) - (int, _Unwind_Action, uint64_t, struct _Unwind_Exception *, - struct _Unwind_Context *); - -struct _Unwind_Context { - unw_cursor_t cursor; - int end_of_stack; /* set to 1 if the end of stack was reached */ -}; - -/* This must be a macro because unw_getcontext() must be invoked from - the callee, even if optimization (and hence inlining) is turned - off. The macro arguments MUST NOT have any side-effects. */ -#define _Unwind_InitContext(context, uc) \ - ((context)->end_of_stack = 0, \ - ((unw_getcontext (uc) < 0 || unw_init_local (&(context)->cursor, uc) < 0) \ - ? -1 : 0)) - -static _Unwind_Reason_Code ALWAYS_INLINE -_Unwind_Phase2 (struct _Unwind_Exception *exception_object, - struct _Unwind_Context *context) -{ - _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) exception_object->private_1; - uint64_t exception_class = exception_object->exception_class; - void *stop_parameter = (void *) exception_object->private_2; - _Unwind_Personality_Fn personality; - _Unwind_Reason_Code reason; - _Unwind_Action actions; - unw_proc_info_t pi; - unw_word_t ip; - int ret; - - actions = _UA_CLEANUP_PHASE; - if (stop) - actions |= _UA_FORCE_UNWIND; - - while (1) - { - ret = unw_step (&context->cursor); - if (ret <= 0) - { - if (ret == 0) - { - actions |= _UA_END_OF_STACK; - context->end_of_stack = 1; - } - else - return _URC_FATAL_PHASE2_ERROR; - } - - if (stop) - { - reason = (*stop) (_U_VERSION, actions, exception_class, - exception_object, context, stop_parameter); - if (reason != _URC_NO_REASON) - /* Stop function may return _URC_FATAL_PHASE2_ERROR if - it's unable to handle end-of-stack condition or - _URC_FATAL_PHASE2_ERROR if something is wrong. Not - that it matters: the resulting state is indeterminate - anyhow so we must return _URC_FATAL_PHASE2_ERROR... */ - return _URC_FATAL_PHASE2_ERROR; - } - - if (context->end_of_stack - || unw_get_proc_info (&context->cursor, &pi) < 0) - return _URC_FATAL_PHASE2_ERROR; - - personality = (_Unwind_Personality_Fn) (uintptr_t) pi.handler; - if (personality) - { - if (!stop) - { - if (unw_get_reg (&context->cursor, UNW_REG_IP, &ip) < 0) - return _URC_FATAL_PHASE2_ERROR; - - if ((unsigned long) stop_parameter == ip) - actions |= _UA_HANDLER_FRAME; - } - - reason = (*personality) (_U_VERSION, actions, exception_class, - exception_object, context); - if (reason != _URC_CONTINUE_UNWIND) - { - if (reason == _URC_INSTALL_CONTEXT) - { - /* we may regain control via _Unwind_Resume() */ - unw_resume (&context->cursor); - abort (); - } - else - return _URC_FATAL_PHASE2_ERROR; - } - if (actions & _UA_HANDLER_FRAME) - /* The personality routine for the handler-frame changed - it's mind; that's a no-no... */ - abort (); - } - } - return _URC_FATAL_PHASE2_ERROR; /* shouldn't be reached */ -} - -#endif /* unwind_internal_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gcreate_addr_space.c deleted file mode 100644 index a7e41a58f48a25..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Gcreate_addr_space.c +++ /dev/null @@ -1,58 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -#if defined(_LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) -#define __LITTLE_ENDIAN _LITTLE_ENDIAN -#endif - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* - * x86 supports only little-endian. - */ - if (byte_order != 0 && byte_order != __LITTLE_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gget_proc_info.c deleted file mode 100644 index 4dc2cff3660794..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Gget_proc_info.c +++ /dev/null @@ -1,45 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - - if (dwarf_make_proc_info (&c->dwarf) < 0) - { - /* On x86, it's relatively common to be missing DWARF unwind - info. We don't want to fail in that case, because the - frame-chain still would let us do a backtrace at least. */ - memset (pi, 0, sizeof (*pi)); - pi->start_ip = c->dwarf.ip; - pi->end_ip = c->dwarf.ip + 1; - return 0; - } - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gget_save_loc.c deleted file mode 100644 index e459382f6d3cfc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Gget_save_loc.c +++ /dev/null @@ -1,133 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - struct cursor *c = (struct cursor *) cursor; - dwarf_loc_t loc; - - loc = DWARF_NULL_LOC; /* default to "not saved" */ - - switch (reg) - { - case UNW_X86_EIP: loc = c->dwarf.loc[EIP]; break; - case UNW_X86_CFA: break; - case UNW_X86_EAX: loc = c->dwarf.loc[EAX]; break; - case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; - case UNW_X86_EDX: loc = c->dwarf.loc[EDX]; break; - case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; - case UNW_X86_ESP: loc = c->dwarf.loc[ESP]; break; - case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; - case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break; - case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break; - case UNW_X86_EFLAGS: loc = c->dwarf.loc[EFLAGS]; break; - case UNW_X86_TRAPNO: loc = c->dwarf.loc[TRAPNO]; break; - case UNW_X86_ST0: loc = c->dwarf.loc[ST0]; break; - - case UNW_X86_FCW: - case UNW_X86_FSW: - case UNW_X86_FTW: - case UNW_X86_FOP: - case UNW_X86_FCS: - case UNW_X86_FIP: - case UNW_X86_FEA: - case UNW_X86_FDS: - case UNW_X86_MXCSR: - case UNW_X86_GS: - case UNW_X86_FS: - case UNW_X86_ES: - case UNW_X86_DS: - case UNW_X86_SS: - case UNW_X86_CS: - case UNW_X86_TSS: - case UNW_X86_LDT: - loc = x86_scratch_loc (c, reg); - break; - - /* stacked fp registers */ - case UNW_X86_ST1: - case UNW_X86_ST2: - case UNW_X86_ST3: - case UNW_X86_ST4: - case UNW_X86_ST5: - case UNW_X86_ST6: - case UNW_X86_ST7: - /* SSE fp registers */ - case UNW_X86_XMM0_lo: - case UNW_X86_XMM0_hi: - case UNW_X86_XMM1_lo: - case UNW_X86_XMM1_hi: - case UNW_X86_XMM2_lo: - case UNW_X86_XMM2_hi: - case UNW_X86_XMM3_lo: - case UNW_X86_XMM3_hi: - case UNW_X86_XMM4_lo: - case UNW_X86_XMM4_hi: - case UNW_X86_XMM5_lo: - case UNW_X86_XMM5_hi: - case UNW_X86_XMM6_lo: - case UNW_X86_XMM6_hi: - case UNW_X86_XMM7_lo: - case UNW_X86_XMM7_hi: - case UNW_X86_XMM0: - case UNW_X86_XMM1: - case UNW_X86_XMM2: - case UNW_X86_XMM3: - case UNW_X86_XMM4: - case UNW_X86_XMM5: - case UNW_X86_XMM6: - case UNW_X86_XMM7: - loc = x86_scratch_loc (c, reg); - break; - - default: - break; - } - - memset (sloc, 0, sizeof (*sloc)); - - if (DWARF_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (DWARF_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = DWARF_GET_LOC (loc); - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = DWARF_GET_LOC (loc); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gglobal.c deleted file mode 100644 index 132b8249944115..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Gglobal.c +++ /dev/null @@ -1,67 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "dwarf_i.h" - -HIDDEN define_lock (x86_lock); -HIDDEN int tdep_init_done; - -/* See comments for svr4_dbx_register_map[] in gcc/config/i386/i386.c. */ - -HIDDEN const uint8_t dwarf_to_unw_regnum_map[19] = - { - UNW_X86_EAX, UNW_X86_ECX, UNW_X86_EDX, UNW_X86_EBX, - UNW_X86_ESP, UNW_X86_EBP, UNW_X86_ESI, UNW_X86_EDI, - UNW_X86_EIP, UNW_X86_EFLAGS, UNW_X86_TRAPNO, - UNW_X86_ST0, UNW_X86_ST1, UNW_X86_ST2, UNW_X86_ST3, - UNW_X86_ST4, UNW_X86_ST5, UNW_X86_ST6, UNW_X86_ST7 - }; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&x86_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - dwarf_init (); - -#ifndef UNW_REMOTE_ONLY - x86_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&x86_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c deleted file mode 100644 index f6b8dc27d49345..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c +++ /dev/null @@ -1,243 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - -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. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) -{ - return x86_r_uc_addr (uc, reg); -} - -# endif /* UNW_LOCAL_ONLY */ - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; - return 0; -} - -#define PAGE_SIZE 4096 -#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) - -/* Cache of already validated addresses */ -#define NLGA 4 -static unw_word_t last_good_addr[NLGA]; -static int lga_victim; - -static int -validate_mem (unw_word_t addr) -{ - int i, victim; -#ifdef HAVE_MINCORE - unsigned char mvec[2]; /* Unaligned access may cross page boundary */ -#endif - size_t len; - - if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) - len = PAGE_SIZE; - else - len = PAGE_SIZE * 2; - - addr = PAGE_START(addr); - - if (addr == 0) - return -1; - - for (i = 0; i < NLGA; i++) - { - if (last_good_addr[i] && (addr == last_good_addr[i])) - return 0; - } - -#ifdef HAVE_MINCORE - if (mincore ((void *) addr, len, mvec) == -1) -#else - if (msync ((void *) addr, len, MS_ASYNC) == -1) -#endif - return -1; - - victim = lga_victim; - for (i = 0; i < NLGA; i++) { - if (!last_good_addr[victim]) { - last_good_addr[victim++] = addr; - return 0; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - last_good_addr[victim] = addr; - victim = (victim + 1) % NLGA; - lga_victim = victim; - - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (write) - { - Debug (16, "mem[%x] <- %x\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - /* validate address */ - const struct cursor *c = (const struct cursor *)arg; - if (c && c->validate && validate_mem(addr)) - return -1; - *val = *(unw_word_t *) addr; - Debug (16, "mem[%x] -> %x\n", addr, *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = ((struct cursor *)arg)->uc; - - if (unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = x86_r_uc_addr (uc, reg))) - goto badreg; - - if (write) - { - *(unw_word_t *) addr = *val; - Debug (12, "%s <- %x\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> %x\n", unw_regname (reg), *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = ((struct cursor *)arg)->uc; - unw_fpreg_t *addr; - - if (!unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = x86_r_uc_addr (uc, reg))) - goto badreg; - - if (write) - { - Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - *(unw_fpreg_t *) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -x86_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = x86_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_local.c deleted file mode 100644 index bff068704def7f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_local.c +++ /dev/null @@ -1,79 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = c; - c->uc = uc; - c->validate = 0; - return common_init (c, use_prev_instr); -} - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_remote.c deleted file mode 100644 index 7c15096e4f7f75..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_remote.c +++ /dev/null @@ -1,56 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - c->dwarf.as_arg = as_arg; - if (as == unw_local_addr_space) - { - c->dwarf.as_arg = c; - c->uc = as_arg; - } - else - { - c->dwarf.as_arg = as_arg; - c->uc = 0; - } - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gos-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gos-freebsd.c deleted file mode 100644 index 7dd0140463859a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Gos-freebsd.c +++ /dev/null @@ -1,374 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010 Konstantin Belousov - -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. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -#include "unwind_i.h" -#include "offsets.h" - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, w1, w2, w3, w4, w5, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - /* Check if EIP points at sigreturn() sequence. It can be: -sigcode+4: from amd64 freebsd32 environment -8d 44 24 20 lea 0x20(%esp),%eax -50 push %eax -b8 a1 01 00 00 mov $0x1a1,%eax -50 push %eax -cd 80 int $0x80 - -sigcode+4: from real i386 -8d 44 24 20 lea 0x20(%esp),%eax -50 push %eax -f7 40 54 00 02 00 testl $0x20000,0x54(%eax) -75 03 jne sigcode+21 -8e 68 14 mov 0x14(%eax),%gs -b8 a1 01 00 00 mov $0x1a1,%eax -50 push %eax -cd 80 int $0x80 - -freebsd4_sigcode+4: -XXX -osigcode: -XXX - */ - ip = c->dwarf.ip; - ret = X86_SCF_NONE; - c->sigcontext_format = ret; - if ((*a->access_mem) (as, ip, &w0, 0, arg) < 0 || - (*a->access_mem) (as, ip + 4, &w1, 0, arg) < 0 || - (*a->access_mem) (as, ip + 8, &w2, 0, arg) < 0 || - (*a->access_mem) (as, ip + 12, &w3, 0, arg) < 0) - return ret; - if (w0 == 0x2024448d && w1 == 0x01a1b850 && w2 == 0xcd500000 && - (w3 & 0xff) == 0x80) - ret = X86_SCF_FREEBSD_SIGFRAME; - else { - if ((*a->access_mem) (as, ip + 16, &w4, 0, arg) < 0 || - (*a->access_mem) (as, ip + 20, &w5, 0, arg) < 0) - return ret; - if (w0 == 0x2024448d && w1 == 0x5440f750 && w2 == 0x75000200 && - w3 == 0x14688e03 && w4 == 0x0001a1b8 && w5 == 0x80cd5000) - ret = X86_SCF_FREEBSD_SIGFRAME; - } - - /* Check for syscall */ - if (ret == X86_SCF_NONE && (*a->access_mem) (as, ip - 2, &w0, 0, arg) >= 0 && - (w0 & 0xffff) == 0x80cd) - ret = X86_SCF_FREEBSD_SYSCALL; - Debug (16, "returning %d\n", ret); - c->sigcontext_format = ret; - return (ret); -} - -HIDDEN int -x86_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) { - struct sigframe *sf; - uintptr_t uc_addr; - struct dwarf_loc esp_loc; - - sf = (struct sigframe *)c->dwarf.cfa; - uc_addr = (uintptr_t)&(sf->sf_uc); - c->sigcontext_addr = c->dwarf.cfa; - - esp_loc = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0); - ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa); - if (ret < 0) - { - Debug (2, "returning 0\n"); - return 0; - } - - c->dwarf.loc[EIP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EIP_OFF, 0); - c->dwarf.loc[ESP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0); - c->dwarf.loc[EAX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EAX_OFF, 0); - c->dwarf.loc[ECX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ECX_OFF, 0); - c->dwarf.loc[EDX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EDX_OFF, 0); - c->dwarf.loc[EBX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBX_OFF, 0); - c->dwarf.loc[EBP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBP_OFF, 0); - c->dwarf.loc[ESI] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESI_OFF, 0); - c->dwarf.loc[EDI] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EDI_OFF, 0); - c->dwarf.loc[EFLAGS] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EFLAGS_OFF, 0); - c->dwarf.loc[TRAPNO] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_TRAPNO_OFF, 0); - c->dwarf.loc[ST0] = DWARF_NULL_LOC; - } else if (c->sigcontext_format == X86_SCF_FREEBSD_SYSCALL) { - c->dwarf.loc[EIP] = DWARF_LOC (c->dwarf.cfa, 0); - c->dwarf.loc[EAX] = DWARF_NULL_LOC; - c->dwarf.cfa += 4; - c->dwarf.use_prev_instr = 1; - } else { - Debug (8, "Gstep: not handling frame format %d\n", c->sigcontext_format); - abort(); - } - return 0; -} - -HIDDEN dwarf_loc_t -x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg) -{ - unw_word_t addr = c->sigcontext_addr, off, xmm_off; - unw_word_t fpstate, fpformat; - int ret, is_fpstate = 0, is_xmmstate = 0; - - switch (c->sigcontext_format) - { - case X86_SCF_NONE: - return DWARF_REG_LOC (&c->dwarf, reg); - - case X86_SCF_FREEBSD_SIGFRAME: - addr += offsetof(struct sigframe, sf_uc) + FREEBSD_UC_MCONTEXT_OFF; - break; - - case X86_SCF_FREEBSD_SIGFRAME4: - abort(); - break; - - case X86_SCF_FREEBSD_OSIGFRAME: - /* XXXKIB */ - abort(); - break; - - case X86_SCF_FREEBSD_SYSCALL: - /* XXXKIB */ - abort(); - break; - - default: - /* XXXKIB */ - abort(); - break; - } - - off = 0; /* shut gcc warning */ - switch (reg) - { - case UNW_X86_GS: off = FREEBSD_UC_MCONTEXT_GS_OFF; break; - case UNW_X86_FS: off = FREEBSD_UC_MCONTEXT_FS_OFF; break; - case UNW_X86_ES: off = FREEBSD_UC_MCONTEXT_ES_OFF; break; - case UNW_X86_DS: off = FREEBSD_UC_MCONTEXT_SS_OFF; break; - case UNW_X86_EDI: off = FREEBSD_UC_MCONTEXT_EDI_OFF; break; - case UNW_X86_ESI: off = FREEBSD_UC_MCONTEXT_ESI_OFF; break; - case UNW_X86_EBP: off = FREEBSD_UC_MCONTEXT_EBP_OFF; break; - case UNW_X86_ESP: off = FREEBSD_UC_MCONTEXT_ESP_OFF; break; - case UNW_X86_EBX: off = FREEBSD_UC_MCONTEXT_EBX_OFF; break; - case UNW_X86_EDX: off = FREEBSD_UC_MCONTEXT_EDX_OFF; break; - case UNW_X86_ECX: off = FREEBSD_UC_MCONTEXT_ECX_OFF; break; - case UNW_X86_EAX: off = FREEBSD_UC_MCONTEXT_EAX_OFF; break; - case UNW_X86_TRAPNO: off = FREEBSD_UC_MCONTEXT_TRAPNO_OFF; break; - case UNW_X86_EIP: off = FREEBSD_UC_MCONTEXT_EIP_OFF; break; - case UNW_X86_CS: off = FREEBSD_UC_MCONTEXT_CS_OFF; break; - case UNW_X86_EFLAGS: off = FREEBSD_UC_MCONTEXT_EFLAGS_OFF; break; - case UNW_X86_SS: off = FREEBSD_UC_MCONTEXT_SS_OFF; break; - - case UNW_X86_FCW: - is_fpstate = 1; - off = FREEBSD_UC_MCONTEXT_CW_OFF; - xmm_off = FREEBSD_UC_MCONTEXT_CW_XMM_OFF; - break; - case UNW_X86_FSW: - is_fpstate = 1; - off = FREEBSD_UC_MCONTEXT_SW_OFF; - xmm_off = FREEBSD_UC_MCONTEXT_SW_XMM_OFF; - break; - case UNW_X86_FTW: - is_fpstate = 1; - xmm_off = FREEBSD_UC_MCONTEXT_TAG_XMM_OFF; - off = FREEBSD_UC_MCONTEXT_TAG_OFF; - break; - case UNW_X86_FCS: - is_fpstate = 1; - off = FREEBSD_UC_MCONTEXT_CSSEL_OFF; - xmm_off = FREEBSD_UC_MCONTEXT_CSSEL_XMM_OFF; - break; - case UNW_X86_FIP: - is_fpstate = 1; - off = FREEBSD_UC_MCONTEXT_IPOFF_OFF; - xmm_off = FREEBSD_UC_MCONTEXT_IPOFF_XMM_OFF; - break; - case UNW_X86_FEA: - is_fpstate = 1; - off = FREEBSD_UC_MCONTEXT_DATAOFF_OFF; - xmm_off = FREEBSD_UC_MCONTEXT_DATAOFF_XMM_OFF; - break; - case UNW_X86_FDS: - is_fpstate = 1; - off = FREEBSD_US_MCONTEXT_DATASEL_OFF; - xmm_off = FREEBSD_US_MCONTEXT_DATASEL_XMM_OFF; - break; - case UNW_X86_MXCSR: - is_fpstate = 1; - is_xmmstate = 1; - xmm_off = FREEBSD_UC_MCONTEXT_MXCSR_XMM_OFF; - break; - - /* stacked fp registers */ - case UNW_X86_ST0: case UNW_X86_ST1: case UNW_X86_ST2: case UNW_X86_ST3: - case UNW_X86_ST4: case UNW_X86_ST5: case UNW_X86_ST6: case UNW_X86_ST7: - is_fpstate = 1; - off = FREEBSD_UC_MCONTEXT_ST0_OFF + 10*(reg - UNW_X86_ST0); - xmm_off = FREEBSD_UC_MCONTEXT_ST0_XMM_OFF + 10*(reg - UNW_X86_ST0); - break; - - /* SSE fp registers */ - case UNW_X86_XMM0_lo: case UNW_X86_XMM0_hi: - case UNW_X86_XMM1_lo: case UNW_X86_XMM1_hi: - case UNW_X86_XMM2_lo: case UNW_X86_XMM2_hi: - case UNW_X86_XMM3_lo: case UNW_X86_XMM3_hi: - case UNW_X86_XMM4_lo: case UNW_X86_XMM4_hi: - case UNW_X86_XMM5_lo: case UNW_X86_XMM5_hi: - case UNW_X86_XMM6_lo: case UNW_X86_XMM6_hi: - case UNW_X86_XMM7_lo: case UNW_X86_XMM7_hi: - is_fpstate = 1; - is_xmmstate = 1; - xmm_off = FREEBSD_UC_MCONTEXT_XMM0_OFF + 8*(reg - UNW_X86_XMM0_lo); - break; - case UNW_X86_XMM0: - case UNW_X86_XMM1: - case UNW_X86_XMM2: - case UNW_X86_XMM3: - case UNW_X86_XMM4: - case UNW_X86_XMM5: - case UNW_X86_XMM6: - case UNW_X86_XMM7: - is_fpstate = 1; - is_xmmstate = 1; - xmm_off = FREEBSD_UC_MCONTEXT_XMM0_OFF + 16*(reg - UNW_X86_XMM0); - break; - - case UNW_X86_FOP: - case UNW_X86_TSS: - case UNW_X86_LDT: - default: - return DWARF_REG_LOC (&c->dwarf, reg); - } - - if (is_fpstate) - { - if ((ret = dwarf_get (&c->dwarf, - DWARF_MEM_LOC (&c->dwarf, addr + FREEBSD_UC_MCONTEXT_FPSTATE_OFF), - &fpstate)) < 0) - return DWARF_NULL_LOC; - if (fpstate == FREEBSD_UC_MCONTEXT_FPOWNED_NONE) - return DWARF_NULL_LOC; - if ((ret = dwarf_get (&c->dwarf, - DWARF_MEM_LOC (&c->dwarf, addr + FREEBSD_UC_MCONTEXT_FPFORMAT_OFF), - &fpformat)) < 0) - return DWARF_NULL_LOC; - if (fpformat == FREEBSD_UC_MCONTEXT_FPFMT_NODEV || - (is_xmmstate && fpformat != FREEBSD_UC_MCONTEXT_FPFMT_XMM)) - return DWARF_NULL_LOC; - if (is_xmmstate) - off = xmm_off; - } - - return DWARF_MEM_LOC (c, addr + off); -} - -#ifndef UNW_REMOTE_ONLY -HIDDEN void * -x86_r_uc_addr (ucontext_t *uc, int reg) -{ - void *addr; - - switch (reg) - { - case UNW_X86_GS: addr = &uc->uc_mcontext.mc_gs; break; - case UNW_X86_FS: addr = &uc->uc_mcontext.mc_fs; break; - case UNW_X86_ES: addr = &uc->uc_mcontext.mc_es; break; - case UNW_X86_DS: addr = &uc->uc_mcontext.mc_ds; break; - case UNW_X86_EAX: addr = &uc->uc_mcontext.mc_eax; break; - case UNW_X86_EBX: addr = &uc->uc_mcontext.mc_ebx; break; - case UNW_X86_ECX: addr = &uc->uc_mcontext.mc_ecx; break; - case UNW_X86_EDX: addr = &uc->uc_mcontext.mc_edx; break; - case UNW_X86_ESI: addr = &uc->uc_mcontext.mc_esi; break; - case UNW_X86_EDI: addr = &uc->uc_mcontext.mc_edi; break; - case UNW_X86_EBP: addr = &uc->uc_mcontext.mc_ebp; break; - case UNW_X86_EIP: addr = &uc->uc_mcontext.mc_eip; break; - case UNW_X86_ESP: addr = &uc->uc_mcontext.mc_esp; break; - case UNW_X86_TRAPNO: addr = &uc->uc_mcontext.mc_trapno; break; - case UNW_X86_CS: addr = &uc->uc_mcontext.mc_cs; break; - case UNW_X86_EFLAGS: addr = &uc->uc_mcontext.mc_eflags; break; - case UNW_X86_SS: addr = &uc->uc_mcontext.mc_ss; break; - - default: - addr = NULL; - } - return addr; -} - -HIDDEN int -x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - struct cursor *c = (struct cursor *) cursor; - ucontext_t *uc = c->uc; - - /* Ensure c->pi is up-to-date. On x86, it's relatively common to be - missing DWARF unwind info. We don't want to fail in that case, - because the frame-chain still would let us do a backtrace at - least. */ - dwarf_make_proc_info (&c->dwarf); - - if (c->sigcontext_format == X86_SCF_NONE) { - Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); - setcontext (uc); - abort(); - } else if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) { - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - - Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); - sigreturn((ucontext_t *)((const char *)sc + FREEBSD_SC_UCONTEXT_OFF)); - abort(); - } else { - Debug (8, "resuming at ip=%x for sigcontext format %d not implemented\n", - c->dwarf.ip, c->sigcontext_format); - abort(); - } - return -UNW_EINVAL; -} - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gos-linux.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gos-linux.c deleted file mode 100644 index fb9a5e346123a4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Gos-linux.c +++ /dev/null @@ -1,331 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" - -#include - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, w1, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - /* Check if EIP points at sigreturn() sequence. On Linux, this is: - - __restore: - 0x58 pop %eax - 0xb8 0x77 0x00 0x00 0x00 movl 0x77,%eax - 0xcd 0x80 int 0x80 - - without SA_SIGINFO, and - - __restore_rt: - 0xb8 0xad 0x00 0x00 0x00 movl 0xad,%eax - 0xcd 0x80 int 0x80 - 0x00 - - if SA_SIGINFO is specified. - */ - ip = c->dwarf.ip; - if ((*a->access_mem) (as, ip, &w0, 0, arg) < 0 - || (*a->access_mem) (as, ip + 4, &w1, 0, arg) < 0) - ret = 0; - else - ret = ((w0 == 0x0077b858 && w1 == 0x80cd0000) - || (w0 == 0x0000adb8 && (w1 & 0xffffff) == 0x80cd00)); - Debug (16, "returning %d\n", ret); - return ret; -} - -HIDDEN int -x86_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - /* c->esp points at the arguments to the handler. Without - SA_SIGINFO, the arguments consist of a signal number - followed by a struct sigcontext. With SA_SIGINFO, the - arguments consist a signal number, a siginfo *, and a - ucontext *. */ - unw_word_t sc_addr; - unw_word_t siginfo_ptr_addr = c->dwarf.cfa + 4; - unw_word_t sigcontext_ptr_addr = c->dwarf.cfa + 8; - unw_word_t siginfo_ptr, sigcontext_ptr; - struct dwarf_loc esp_loc, siginfo_ptr_loc, sigcontext_ptr_loc; - - siginfo_ptr_loc = DWARF_LOC (siginfo_ptr_addr, 0); - sigcontext_ptr_loc = DWARF_LOC (sigcontext_ptr_addr, 0); - ret = (dwarf_get (&c->dwarf, siginfo_ptr_loc, &siginfo_ptr) - | dwarf_get (&c->dwarf, sigcontext_ptr_loc, &sigcontext_ptr)); - if (ret < 0) - { - Debug (2, "returning 0\n"); - return 0; - } - if (siginfo_ptr < c->dwarf.cfa - || siginfo_ptr > c->dwarf.cfa + 256 - || sigcontext_ptr < c->dwarf.cfa - || sigcontext_ptr > c->dwarf.cfa + 256) - { - /* Not plausible for SA_SIGINFO signal */ - c->sigcontext_format = X86_SCF_LINUX_SIGFRAME; - c->sigcontext_addr = sc_addr = c->dwarf.cfa + 4; - } - else - { - /* If SA_SIGINFO were not specified, we actually read - various segment pointers instead. We believe that at - least fs and _fsh are always zero for linux, so it is - not just unlikely, but impossible that we would end - up here. */ - c->sigcontext_format = X86_SCF_LINUX_RT_SIGFRAME; - c->sigcontext_addr = sigcontext_ptr; - sc_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF; - } - esp_loc = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0); - ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa); - if (ret < 0) - { - Debug (2, "returning 0\n"); - return 0; - } - - c->dwarf.loc[EAX] = DWARF_LOC (sc_addr + LINUX_SC_EAX_OFF, 0); - c->dwarf.loc[ECX] = DWARF_LOC (sc_addr + LINUX_SC_ECX_OFF, 0); - c->dwarf.loc[EDX] = DWARF_LOC (sc_addr + LINUX_SC_EDX_OFF, 0); - c->dwarf.loc[EBX] = DWARF_LOC (sc_addr + LINUX_SC_EBX_OFF, 0); - c->dwarf.loc[EBP] = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0); - c->dwarf.loc[ESI] = DWARF_LOC (sc_addr + LINUX_SC_ESI_OFF, 0); - c->dwarf.loc[EDI] = DWARF_LOC (sc_addr + LINUX_SC_EDI_OFF, 0); - c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC; - c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC; - c->dwarf.loc[ST0] = DWARF_NULL_LOC; - c->dwarf.loc[EIP] = DWARF_LOC (sc_addr + LINUX_SC_EIP_OFF, 0); - c->dwarf.loc[ESP] = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0); - - return 0; -} - -HIDDEN dwarf_loc_t -x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg) -{ - unw_word_t addr = c->sigcontext_addr, fpstate_addr, off; - int ret, is_fpstate = 0; - - switch (c->sigcontext_format) - { - case X86_SCF_NONE: - return DWARF_REG_LOC (&c->dwarf, reg); - - case X86_SCF_LINUX_SIGFRAME: - break; - - case X86_SCF_LINUX_RT_SIGFRAME: - addr += LINUX_UC_MCONTEXT_OFF; - break; - - default: - return DWARF_NULL_LOC; - } - - switch (reg) - { - case UNW_X86_GS: off = LINUX_SC_GS_OFF; break; - case UNW_X86_FS: off = LINUX_SC_FS_OFF; break; - case UNW_X86_ES: off = LINUX_SC_ES_OFF; break; - case UNW_X86_DS: off = LINUX_SC_DS_OFF; break; - case UNW_X86_EDI: off = LINUX_SC_EDI_OFF; break; - case UNW_X86_ESI: off = LINUX_SC_ESI_OFF; break; - case UNW_X86_EBP: off = LINUX_SC_EBP_OFF; break; - case UNW_X86_ESP: off = LINUX_SC_ESP_OFF; break; - case UNW_X86_EBX: off = LINUX_SC_EBX_OFF; break; - case UNW_X86_EDX: off = LINUX_SC_EDX_OFF; break; - case UNW_X86_ECX: off = LINUX_SC_ECX_OFF; break; - case UNW_X86_EAX: off = LINUX_SC_EAX_OFF; break; - case UNW_X86_TRAPNO: off = LINUX_SC_TRAPNO_OFF; break; - case UNW_X86_EIP: off = LINUX_SC_EIP_OFF; break; - case UNW_X86_CS: off = LINUX_SC_CS_OFF; break; - case UNW_X86_EFLAGS: off = LINUX_SC_EFLAGS_OFF; break; - case UNW_X86_SS: off = LINUX_SC_SS_OFF; break; - - /* The following is probably not correct for all possible cases. - Somebody who understands this better should review this for - correctness. */ - - case UNW_X86_FCW: is_fpstate = 1; off = LINUX_FPSTATE_CW_OFF; break; - case UNW_X86_FSW: is_fpstate = 1; off = LINUX_FPSTATE_SW_OFF; break; - case UNW_X86_FTW: is_fpstate = 1; off = LINUX_FPSTATE_TAG_OFF; break; - case UNW_X86_FCS: is_fpstate = 1; off = LINUX_FPSTATE_CSSEL_OFF; break; - case UNW_X86_FIP: is_fpstate = 1; off = LINUX_FPSTATE_IPOFF_OFF; break; - case UNW_X86_FEA: is_fpstate = 1; off = LINUX_FPSTATE_DATAOFF_OFF; break; - case UNW_X86_FDS: is_fpstate = 1; off = LINUX_FPSTATE_DATASEL_OFF; break; - case UNW_X86_MXCSR: is_fpstate = 1; off = LINUX_FPSTATE_MXCSR_OFF; break; - - /* stacked fp registers */ - case UNW_X86_ST0: case UNW_X86_ST1: case UNW_X86_ST2: case UNW_X86_ST3: - case UNW_X86_ST4: case UNW_X86_ST5: case UNW_X86_ST6: case UNW_X86_ST7: - is_fpstate = 1; - off = LINUX_FPSTATE_ST0_OFF + 10*(reg - UNW_X86_ST0); - break; - - /* SSE fp registers */ - case UNW_X86_XMM0_lo: case UNW_X86_XMM0_hi: - case UNW_X86_XMM1_lo: case UNW_X86_XMM1_hi: - case UNW_X86_XMM2_lo: case UNW_X86_XMM2_hi: - case UNW_X86_XMM3_lo: case UNW_X86_XMM3_hi: - case UNW_X86_XMM4_lo: case UNW_X86_XMM4_hi: - case UNW_X86_XMM5_lo: case UNW_X86_XMM5_hi: - case UNW_X86_XMM6_lo: case UNW_X86_XMM6_hi: - case UNW_X86_XMM7_lo: case UNW_X86_XMM7_hi: - is_fpstate = 1; - off = LINUX_FPSTATE_XMM0_OFF + 8*(reg - UNW_X86_XMM0_lo); - break; - case UNW_X86_XMM0: - case UNW_X86_XMM1: - case UNW_X86_XMM2: - case UNW_X86_XMM3: - case UNW_X86_XMM4: - case UNW_X86_XMM5: - case UNW_X86_XMM6: - case UNW_X86_XMM7: - is_fpstate = 1; - off = LINUX_FPSTATE_XMM0_OFF + 16*(reg - UNW_X86_XMM0); - break; - - case UNW_X86_FOP: - case UNW_X86_TSS: - case UNW_X86_LDT: - default: - return DWARF_REG_LOC (&c->dwarf, reg); - } - - if (is_fpstate) - { - if ((ret = dwarf_get (&c->dwarf, - DWARF_MEM_LOC (&c->dwarf, - addr + LINUX_SC_FPSTATE_OFF), - &fpstate_addr)) < 0) - return DWARF_NULL_LOC; - - if (!fpstate_addr) - return DWARF_NULL_LOC; - - return DWARF_MEM_LOC (c, fpstate_addr + off); - } - else - return DWARF_MEM_LOC (c, addr + off); -} - -#ifndef UNW_REMOTE_ONLY -HIDDEN void * -x86_r_uc_addr (ucontext_t *uc, int reg) -{ - void *addr; - - switch (reg) - { - case UNW_X86_GS: addr = &uc->uc_mcontext.gregs[REG_GS]; break; - case UNW_X86_FS: addr = &uc->uc_mcontext.gregs[REG_FS]; break; - case UNW_X86_ES: addr = &uc->uc_mcontext.gregs[REG_ES]; break; - case UNW_X86_DS: addr = &uc->uc_mcontext.gregs[REG_DS]; break; - case UNW_X86_EAX: addr = &uc->uc_mcontext.gregs[REG_EAX]; break; - case UNW_X86_EBX: addr = &uc->uc_mcontext.gregs[REG_EBX]; break; - case UNW_X86_ECX: addr = &uc->uc_mcontext.gregs[REG_ECX]; break; - case UNW_X86_EDX: addr = &uc->uc_mcontext.gregs[REG_EDX]; break; - case UNW_X86_ESI: addr = &uc->uc_mcontext.gregs[REG_ESI]; break; - case UNW_X86_EDI: addr = &uc->uc_mcontext.gregs[REG_EDI]; break; - case UNW_X86_EBP: addr = &uc->uc_mcontext.gregs[REG_EBP]; break; - case UNW_X86_EIP: addr = &uc->uc_mcontext.gregs[REG_EIP]; break; - case UNW_X86_ESP: addr = &uc->uc_mcontext.gregs[REG_ESP]; break; - case UNW_X86_TRAPNO: addr = &uc->uc_mcontext.gregs[REG_TRAPNO]; break; - case UNW_X86_CS: addr = &uc->uc_mcontext.gregs[REG_CS]; break; - case UNW_X86_EFLAGS: addr = &uc->uc_mcontext.gregs[REG_EFL]; break; - case UNW_X86_SS: addr = &uc->uc_mcontext.gregs[REG_SS]; break; - - default: - addr = NULL; - } - return addr; -} - -HIDDEN int -x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - struct cursor *c = (struct cursor *) cursor; - ucontext_t *uc = c->uc; - - /* Ensure c->pi is up-to-date. On x86, it's relatively common to be - missing DWARF unwind info. We don't want to fail in that case, - because the frame-chain still would let us do a backtrace at - least. */ - dwarf_make_proc_info (&c->dwarf); - - if (unlikely (c->sigcontext_format != X86_SCF_NONE)) - { - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - - Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); - x86_sigreturn (sc); - } - else - { - Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); - setcontext (uc); - } - return -UNW_EINVAL; -} - -/* sigreturn() is a no-op on x86 glibc. */ -HIDDEN void -x86_sigreturn (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - mcontext_t *sc_mcontext = &((ucontext_t*)sc)->uc_mcontext; - /* Copy in saved uc - all preserved regs are at the start of sigcontext */ - memcpy(sc_mcontext, &c->uc->uc_mcontext, - DWARF_NUM_PRESERVED_REGS * sizeof(unw_word_t)); - - Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", - (unsigned long long) c->dwarf.ip, sc); - __asm__ __volatile__ ("mov %0, %%esp;" - "mov %1, %%eax;" - "syscall" - :: "r"(sc), "i"(SYS_rt_sigreturn) - : "memory"); - abort(); -} -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/x86/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gregs.c deleted file mode 100644 index 4a9592617d0d46..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Gregs.c +++ /dev/null @@ -1,178 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "offsets.h" -#include "unwind_i.h" - -HIDDEN dwarf_loc_t -x86_scratch_loc (struct cursor *c, unw_regnum_t reg) -{ - if (c->sigcontext_addr) - return x86_get_scratch_loc (c, reg); - else - return DWARF_REG_LOC (&c->dwarf, reg); -} - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - unsigned int mask; - int arg_num; - - switch (reg) - { - - case UNW_X86_EIP: - if (write) - c->dwarf.ip = *valp; /* also update the EIP cache */ - loc = c->dwarf.loc[EIP]; - break; - - case UNW_X86_CFA: - case UNW_X86_ESP: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - case UNW_X86_EAX: - case UNW_X86_EDX: - arg_num = reg - UNW_X86_EAX; - mask = (1 << arg_num); - if (write) - { - c->dwarf.eh_args[arg_num] = *valp; - c->dwarf.eh_valid_mask |= mask; - return 0; - } - else if ((c->dwarf.eh_valid_mask & mask) != 0) - { - *valp = c->dwarf.eh_args[arg_num]; - return 0; - } - else - loc = c->dwarf.loc[(reg == UNW_X86_EAX) ? EAX : EDX]; - break; - - case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; - case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; - - case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; - case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break; - case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break; - case UNW_X86_EFLAGS: loc = c->dwarf.loc[EFLAGS]; break; - case UNW_X86_TRAPNO: loc = c->dwarf.loc[TRAPNO]; break; - - case UNW_X86_FCW: - case UNW_X86_FSW: - case UNW_X86_FTW: - case UNW_X86_FOP: - case UNW_X86_FCS: - case UNW_X86_FIP: - case UNW_X86_FEA: - case UNW_X86_FDS: - case UNW_X86_MXCSR: - case UNW_X86_GS: - case UNW_X86_FS: - case UNW_X86_ES: - case UNW_X86_DS: - case UNW_X86_SS: - case UNW_X86_CS: - case UNW_X86_TSS: - case UNW_X86_LDT: - loc = x86_scratch_loc (c, reg); - break; - - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - struct dwarf_loc loc = DWARF_NULL_LOC; - - switch (reg) - { - case UNW_X86_ST0: - loc = c->dwarf.loc[ST0]; - break; - - /* stacked fp registers */ - case UNW_X86_ST1: - case UNW_X86_ST2: - case UNW_X86_ST3: - case UNW_X86_ST4: - case UNW_X86_ST5: - case UNW_X86_ST6: - case UNW_X86_ST7: - /* SSE fp registers */ - case UNW_X86_XMM0: - case UNW_X86_XMM1: - case UNW_X86_XMM2: - case UNW_X86_XMM3: - case UNW_X86_XMM4: - case UNW_X86_XMM5: - case UNW_X86_XMM6: - case UNW_X86_XMM7: - case UNW_X86_XMM0_lo: - case UNW_X86_XMM0_hi: - case UNW_X86_XMM1_lo: - case UNW_X86_XMM1_hi: - case UNW_X86_XMM2_lo: - case UNW_X86_XMM2_hi: - case UNW_X86_XMM3_lo: - case UNW_X86_XMM3_hi: - case UNW_X86_XMM4_lo: - case UNW_X86_XMM4_hi: - case UNW_X86_XMM5_lo: - case UNW_X86_XMM5_hi: - case UNW_X86_XMM6_lo: - case UNW_X86_XMM6_hi: - case UNW_X86_XMM7_lo: - case UNW_X86_XMM7_hi: - loc = x86_scratch_loc (c, reg); - break; - - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_putfp (&c->dwarf, loc, *valp); - else - return dwarf_getfp (&c->dwarf, loc, valp); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gresume.c deleted file mode 100644 index 5072c4ba089991..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Gresume.c +++ /dev/null @@ -1,91 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" -#include "offsets.h" - -/* This routine is responsible for copying the register values in - cursor C and establishing them as the current machine state. */ - -static inline int -establish_machine_state (struct cursor *c) -{ - int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, - int write, void *); - int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, - int write, void *); - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - access_reg = as->acc.access_reg; - access_fpreg = as->acc.access_fpreg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_REG_LAST; ++reg) - { - Debug (16, "copying %s %d\n", unw_regname (reg), reg); - if (unw_is_fpreg (reg)) - { - if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) - (*access_fpreg) (as, reg, &fpval, 1, arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - (*access_reg) (as, reg, &val, 1, arg); - } - } - - if (c->dwarf.args_size) - { - if (tdep_access_reg (c, UNW_X86_ESP, &val, 0) >= 0) - { - val += c->dwarf.args_size; - (*access_reg) (as, UNW_X86_ESP, &val, 1, arg); - } - } - return 0; -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p)\n", c); - - if ((ret = establish_machine_state (c)) < 0) - return ret; - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gstep.c deleted file mode 100644 index 129b739a3e78f2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Gstep.c +++ /dev/null @@ -1,115 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "offsets.h" - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret, i; - - Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip); - - /* Try DWARF-based unwinding... */ - ret = dwarf_step (&c->dwarf); - - if (ret < 0 && ret != -UNW_ENOINFO) - { - Debug (2, "returning %d\n", ret); - return ret; - } - - if (unlikely (ret < 0)) - { - /* DWARF failed, let's see if we can follow the frame-chain - or skip over the signal trampoline. */ - struct dwarf_loc ebp_loc, eip_loc; - - /* We could get here because of missing/bad unwind information. - Validate all addresses before dereferencing. */ - c->validate = 1; - - Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); - - if (unw_is_signal_frame (cursor) > 0) - { - ret = x86_handle_signal_frame(cursor); - if (ret < 0) - { - Debug (2, "returning 0\n"); - return 0; - } - } - else - { - ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - - Debug (13, "[EBP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EBP]), - c->dwarf.cfa); - - ebp_loc = DWARF_LOC (c->dwarf.cfa, 0); - eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0); - c->dwarf.cfa += 8; - - /* Mark all registers unsaved, since we don't know where - they are saved (if at all), except for the EBP and - EIP. */ - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - c->dwarf.loc[EBP] = ebp_loc; - c->dwarf.loc[EIP] = eip_loc; - c->dwarf.use_prev_instr = 1; - } - - if (!DWARF_IS_NULL_LOC (c->dwarf.loc[EBP])) - { - ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip); - if (ret < 0) - { - Debug (13, "dwarf_get([EIP=0x%x]) failed\n", DWARF_GET_LOC (c->dwarf.loc[EIP])); - Debug (2, "returning %d\n", ret); - return ret; - } - else - { - Debug (13, "[EIP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EIP]), - c->dwarf.ip); - } - } - else - c->dwarf.ip = 0; - } - ret = (c->dwarf.ip == 0) ? 0 : 1; - Debug (2, "returning %d\n", ret); - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lglobal.c deleted file mode 100644 index 6d7b489e14bd9f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Lglobal.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Linit.c b/src/coreclr/src/pal/src/libunwind/src/x86/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Los-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/x86/Los-freebsd.c deleted file mode 100644 index a75a205df19c01..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Los-freebsd.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gos-freebsd.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Los-linux.c b/src/coreclr/src/pal/src/libunwind/src/x86/Los-linux.c deleted file mode 100644 index 3cc18aabcc399c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Los-linux.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gos-linux.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-freebsd.S b/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-freebsd.S deleted file mode 100644 index 670eff1ae178e7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-freebsd.S +++ /dev/null @@ -1,112 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010 Konstantin Belousov - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "offsets.h" - - .global _Ux86_getcontext - .type _Ux86_getcontext, @function -_Ux86_getcontext: - .cfi_startproc - pushl %eax - .cfi_adjust_cfa_offset 4 - mov 8(%esp),%eax /* ucontext_t* */ - popl FREEBSD_UC_MCONTEXT_EAX_OFF(%eax) - .cfi_adjust_cfa_offset 4 - movl %ebx, FREEBSD_UC_MCONTEXT_EBX_OFF(%eax) - movl %ecx, FREEBSD_UC_MCONTEXT_ECX_OFF(%eax) - movl %edx, FREEBSD_UC_MCONTEXT_EDX_OFF(%eax) - movl %edi, FREEBSD_UC_MCONTEXT_EDI_OFF(%eax) - movl %esi, FREEBSD_UC_MCONTEXT_ESI_OFF(%eax) - movl %ebp, FREEBSD_UC_MCONTEXT_EBP_OFF(%eax) - - movl (%esp), %ecx - movl %ecx, FREEBSD_UC_MCONTEXT_EIP_OFF(%eax) - - leal 4(%esp), %ecx /* Exclude the return address. */ - movl %ecx, FREEBSD_UC_MCONTEXT_ESP_OFF(%eax) - - xorl %ecx, %ecx - movw %fs, %cx - movl %ecx, FREEBSD_UC_MCONTEXT_FS_OFF(%eax) - movw %gs, %cx - movl %ecx, FREEBSD_UC_MCONTEXT_GS_OFF(%eax) - movw %ds, %cx - movl %ecx, FREEBSD_UC_MCONTEXT_DS_OFF(%eax) - movw %es, %cx - movl %ecx, FREEBSD_UC_MCONTEXT_ES_OFF(%eax) - movw %ss, %cx - movl %ecx, FREEBSD_UC_MCONTEXT_SS_OFF(%eax) - movw %cs, %cx - movl %ecx, FREEBSD_UC_MCONTEXT_CS_OFF(%eax) - - pushfl - .cfi_adjust_cfa_offset 4 - popl FREEBSD_UC_MCONTEXT_EFLAGS_OFF(%eax) - .cfi_adjust_cfa_offset -4 - - movl $0, FREEBSD_UC_MCONTEXT_TRAPNO_OFF(%eax) - - movl $FREEBSD_UC_MCONTEXT_FPOWNED_FPU,\ - FREEBSD_UC_MCONTEXT_OWNEDFP_OFF(%eax) - movl $FREEBSD_UC_MCONTEXT_FPFMT_XMM,\ - FREEBSD_UC_MCONTEXT_FPFORMAT_OFF(%eax) - - /* - * Require CPU with fxsave implemented, and enabled by OS. - * - * If passed ucontext is not aligned to 16-byte boundary, - * save fpu context into temporary aligned location on stack - * and then copy. - */ - leal FREEBSD_UC_MCONTEXT_FPSTATE_OFF(%eax), %edx - testl $0xf, %edx - jne 2f - fxsave (%edx) /* fast path, passed ucontext save area was aligned */ -1: movl $FREEBSD_UC_MCONTEXT_MC_LEN_VAL,\ - FREEBSD_UC_MCONTEXT_MC_LEN_OFF(%eax) - - xorl %eax, %eax - ret - -2: movl %edx, %edi /* not aligned, do the dance */ - subl $512 + 16, %esp /* save area and 16 bytes for alignment */ - .cfi_adjust_cfa_offset 512 + 16 - movl %esp, %edx - orl $0xf, %edx /* align *%edx to 16-byte up */ - incl %edx - fxsave (%edx) - movl %edx, %esi /* copy to the final destination */ - movl $512/4,%ecx - rep; movsl - addl $512 + 16, %esp /* restore the stack */ - .cfi_adjust_cfa_offset -512 - 16 - movl FREEBSD_UC_MCONTEXT_ESI_OFF(%eax), %esi - movl FREEBSD_UC_MCONTEXT_EDI_OFF(%eax), %edi - jmp 1b - - .cfi_endproc - .size _Ux86_getcontext, . - _Ux86_getcontext - - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-linux.S b/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-linux.S deleted file mode 100644 index c469dadbac60eb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-linux.S +++ /dev/null @@ -1,74 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2009 Google, Inc - Contributed by Paul Pluzhnikov - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "offsets.h" - -/* int _Ux86_getcontext (ucontext_t *ucp) - - Saves the machine context in UCP necessary for libunwind. - Unlike the libc implementation, we don't save the signal mask - and hence avoid the cost of a system call per unwind. - -*/ - - .global _Ux86_getcontext - .type _Ux86_getcontext, @function -_Ux86_getcontext: - .cfi_startproc - mov 4(%esp),%eax /* ucontext_t* */ - - /* EAX is not preserved. */ - movl $0, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EAX_OFF)(%eax) - - movl %ebx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EBX_OFF)(%eax) - movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ECX_OFF)(%eax) - movl %edx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EDX_OFF)(%eax) - movl %edi, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EDI_OFF)(%eax) - movl %esi, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ESI_OFF)(%eax) - movl %ebp, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EBP_OFF)(%eax) - - movl (%esp), %ecx - movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EIP_OFF)(%eax) - - leal 4(%esp), %ecx /* Exclude the return address. */ - movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ESP_OFF)(%eax) - - /* glibc getcontext saves FS, but not GS */ - xorl %ecx, %ecx - movw %fs, %cx - movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FS_OFF)(%eax) - - leal LINUX_UC_FPREGS_MEM_OFF(%eax), %ecx - movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FPSTATE_OFF)(%eax) - fnstenv (%ecx) - fldenv (%ecx) - - xor %eax, %eax - ret - .cfi_endproc - .size _Ux86_getcontext, . - _Ux86_getcontext - - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/init.h b/src/coreclr/src/pal/src/libunwind/src/x86/init.h deleted file mode 100644 index b0db8d337dfd36..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/init.h +++ /dev/null @@ -1,69 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static inline int -common_init (struct cursor *c, unsigned use_prev_instr) -{ - int ret, i; - - c->dwarf.loc[EAX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EAX); - c->dwarf.loc[ECX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ECX); - c->dwarf.loc[EDX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EDX); - c->dwarf.loc[EBX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EBX); - c->dwarf.loc[ESP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ESP); - c->dwarf.loc[EBP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EBP); - c->dwarf.loc[ESI] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ESI); - c->dwarf.loc[EDI] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EDI); - c->dwarf.loc[EIP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EIP); - c->dwarf.loc[EFLAGS] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EFLAGS); - c->dwarf.loc[TRAPNO] = DWARF_REG_LOC (&c->dwarf, UNW_X86_TRAPNO); - c->dwarf.loc[ST0] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ST0); - for (i = ST0 + 1; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip); - if (ret < 0) - return ret; - - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_X86_ESP), - &c->dwarf.cfa); - if (ret < 0) - return ret; - - c->sigcontext_format = X86_SCF_NONE; - c->sigcontext_addr = 0; - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/x86/is_fpreg.c deleted file mode 100644 index a3a98ac8d3381c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/is_fpreg.c +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_is_fpreg (int regnum) -{ - return ((regnum >= UNW_X86_ST0 && regnum <= UNW_X86_ST7) - || (regnum >= UNW_X86_XMM0_lo && regnum <= UNW_X86_XMM7_hi) - || (regnum >= UNW_X86_XMM0 && regnum <= UNW_X86_XMM7)); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/longjmp.S b/src/coreclr/src/pal/src/libunwind/src/x86/longjmp.S deleted file mode 100644 index 05173d0c109825..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/longjmp.S +++ /dev/null @@ -1,39 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - - .globl _UI_longjmp_cont - - .type _UI_longjmp_cont, @function -_UI_longjmp_cont: - .cfi_startproc - .cfi_register 8, 0 /* IP saved in EAX */ - push %eax /* push target IP as return address */ - .cfi_restore 8 - mov %edx, %eax /* set up return-value */ - ret - .cfi_endproc - .size _UI_siglongjmp_cont, .-_UI_longjmp_cont - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/offsets.h b/src/coreclr/src/pal/src/libunwind/src/x86/offsets.h deleted file mode 100644 index e5aec7f588849f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/offsets.h +++ /dev/null @@ -1,140 +0,0 @@ -/* Linux-specific definitions: */ - -/* Define various structure offsets to simplify cross-compilation. */ - -/* Offsets for x86 Linux "ucontext_t": */ - -#define LINUX_UC_FLAGS_OFF 0x00 -#define LINUX_UC_LINK_OFF 0x04 -#define LINUX_UC_STACK_OFF 0x08 -#define LINUX_UC_MCONTEXT_OFF 0x14 -#define LINUX_UC_SIGMASK_OFF 0x6c -#define LINUX_UC_FPREGS_MEM_OFF 0xec - -/* The struct sigcontext is located at an offset of 4 - from the stack pointer in the signal frame. */ - -/* Offsets for x86 Linux "struct sigcontext": */ - -#define LINUX_SC_GS_OFF 0x00 -#define LINUX_SC_GSH_OFF 0x02 -#define LINUX_SC_FS_OFF 0x04 -#define LINUX_SC_FSH_OFF 0x06 -#define LINUX_SC_ES_OFF 0x08 -#define LINUX_SC_ESH_OFF 0x0a -#define LINUX_SC_DS_OFF 0x0c -#define LINUX_SC_DSH_OFF 0x0e -#define LINUX_SC_EDI_OFF 0x10 -#define LINUX_SC_ESI_OFF 0x14 -#define LINUX_SC_EBP_OFF 0x18 -#define LINUX_SC_ESP_OFF 0x1c -#define LINUX_SC_EBX_OFF 0x20 -#define LINUX_SC_EDX_OFF 0x24 -#define LINUX_SC_ECX_OFF 0x28 -#define LINUX_SC_EAX_OFF 0x2c -#define LINUX_SC_TRAPNO_OFF 0x30 -#define LINUX_SC_ERR_OFF 0x34 -#define LINUX_SC_EIP_OFF 0x38 -#define LINUX_SC_CS_OFF 0x3c -#define LINUX_SC_CSH_OFF 0x3e -#define LINUX_SC_EFLAGS_OFF 0x40 -#define LINUX_SC_ESP_AT_SIGNAL_OFF 0x44 -#define LINUX_SC_SS_OFF 0x48 -#define LINUX_SC_SSH_OFF 0x4a -#define LINUX_SC_FPSTATE_OFF 0x4c -#define LINUX_SC_OLDMASK_OFF 0x50 -#define LINUX_SC_CR2_OFF 0x54 - -/* Offsets for x86 Linux "struct _fpstate": */ - -#define LINUX_FPSTATE_CW_OFF 0x000 -#define LINUX_FPSTATE_SW_OFF 0x004 -#define LINUX_FPSTATE_TAG_OFF 0x008 -#define LINUX_FPSTATE_IPOFF_OFF 0x00c -#define LINUX_FPSTATE_CSSEL_OFF 0x010 -#define LINUX_FPSTATE_DATAOFF_OFF 0x014 -#define LINUX_FPSTATE_DATASEL_OFF 0x018 -#define LINUX_FPSTATE_ST0_OFF 0x01c -#define LINUX_FPSTATE_ST1_OFF 0x026 -#define LINUX_FPSTATE_ST2_OFF 0x030 -#define LINUX_FPSTATE_ST3_OFF 0x03a -#define LINUX_FPSTATE_ST4_OFF 0x044 -#define LINUX_FPSTATE_ST5_OFF 0x04e -#define LINUX_FPSTATE_ST6_OFF 0x058 -#define LINUX_FPSTATE_ST7_OFF 0x062 -#define LINUX_FPSTATE_STATUS_OFF 0x06c -#define LINUX_FPSTATE_MAGIC_OFF 0x06e -#define LINUX_FPSTATE_FXSR_ENV_OFF 0x070 -#define LINUX_FPSTATE_MXCSR_OFF 0x088 -#define LINUX_FPSTATE_FXSR_ST0_OFF 0x090 -#define LINUX_FPSTATE_FXSR_ST1_OFF 0x0a0 -#define LINUX_FPSTATE_FXSR_ST2_OFF 0x0b0 -#define LINUX_FPSTATE_FXSR_ST3_OFF 0x0c0 -#define LINUX_FPSTATE_FXSR_ST4_OFF 0x0d0 -#define LINUX_FPSTATE_FXSR_ST5_OFF 0x0e0 -#define LINUX_FPSTATE_FXSR_ST6_OFF 0x0f0 -#define LINUX_FPSTATE_FXSR_ST7_OFF 0x100 -#define LINUX_FPSTATE_XMM0_OFF 0x110 -#define LINUX_FPSTATE_XMM1_OFF 0x120 -#define LINUX_FPSTATE_XMM2_OFF 0x130 -#define LINUX_FPSTATE_XMM3_OFF 0x140 -#define LINUX_FPSTATE_XMM4_OFF 0x150 -#define LINUX_FPSTATE_XMM5_OFF 0x160 -#define LINUX_FPSTATE_XMM6_OFF 0x170 -#define LINUX_FPSTATE_XMM7_OFF 0x180 - -/* FreeBSD-specific definitions: */ - -#define FREEBSD_SC_UCONTEXT_OFF 0x20 -#define FREEBSD_UC_MCONTEXT_OFF 0x10 - -#define FREEBSD_UC_MCONTEXT_GS_OFF 0x14 -#define FREEBSD_UC_MCONTEXT_FS_OFF 0x18 -#define FREEBSD_UC_MCONTEXT_ES_OFF 0x1c -#define FREEBSD_UC_MCONTEXT_DS_OFF 0x20 -#define FREEBSD_UC_MCONTEXT_EDI_OFF 0x24 -#define FREEBSD_UC_MCONTEXT_ESI_OFF 0x28 -#define FREEBSD_UC_MCONTEXT_EBP_OFF 0x2c -#define FREEBSD_UC_MCONTEXT_EBX_OFF 0x34 -#define FREEBSD_UC_MCONTEXT_EDX_OFF 0x38 -#define FREEBSD_UC_MCONTEXT_ECX_OFF 0x3c -#define FREEBSD_UC_MCONTEXT_EAX_OFF 0x40 -#define FREEBSD_UC_MCONTEXT_TRAPNO_OFF 0x44 -#define FREEBSD_UC_MCONTEXT_EIP_OFF 0x4c -#define FREEBSD_UC_MCONTEXT_ESP_OFF 0x58 -#define FREEBSD_UC_MCONTEXT_CS_OFF 0x50 -#define FREEBSD_UC_MCONTEXT_EFLAGS_OFF 0x54 -#define FREEBSD_UC_MCONTEXT_SS_OFF 0x5c -#define FREEBSD_UC_MCONTEXT_MC_LEN_OFF 0x60 -#define FREEBSD_UC_MCONTEXT_FPFORMAT_OFF 0x64 -#define FREEBSD_UC_MCONTEXT_OWNEDFP_OFF 0x68 -#define FREEBSD_UC_MCONTEXT_FPSTATE_OFF 0x70 - -#define FREEBSD_UC_MCONTEXT_CW_OFF 0x70 -#define FREEBSD_UC_MCONTEXT_SW_OFF 0x74 -#define FREEBSD_UC_MCONTEXT_TAG_OFF 0x78 -#define FREEBSD_UC_MCONTEXT_IPOFF_OFF 0x7c -#define FREEBSD_UC_MCONTEXT_CSSEL_OFF 0x80 -#define FREEBSD_UC_MCONTEXT_DATAOFF_OFF 0x84 -#define FREEBSD_US_MCONTEXT_DATASEL_OFF 0x88 -#define FREEBSD_UC_MCONTEXT_ST0_OFF 0x8c - -#define FREEBSD_UC_MCONTEXT_CW_XMM_OFF 0x70 -#define FREEBSD_UC_MCONTEXT_SW_XMM_OFF 0x72 -#define FREEBSD_UC_MCONTEXT_TAG_XMM_OFF 0x74 -#define FREEBSD_UC_MCONTEXT_IPOFF_XMM_OFF 0x78 -#define FREEBSD_UC_MCONTEXT_CSSEL_XMM_OFF 0x7c -#define FREEBSD_UC_MCONTEXT_DATAOFF_XMM_OFF 0x80 -#define FREEBSD_US_MCONTEXT_DATASEL_XMM_OFF 0x84 -#define FREEBSD_UC_MCONTEXT_MXCSR_XMM_OFF 0x88 -#define FREEBSD_UC_MCONTEXT_ST0_XMM_OFF 0x90 -#define FREEBSD_UC_MCONTEXT_XMM0_OFF 0x110 - -#define FREEBSD_UC_MCONTEXT_MC_LEN_VAL 0x280 -#define FREEBSD_UC_MCONTEXT_FPFMT_NODEV 0x10000 -#define FREEBSD_UC_MCONTEXT_FPFMT_387 0x10001 -#define FREEBSD_UC_MCONTEXT_FPFMT_XMM 0x10002 -#define FREEBSD_UC_MCONTEXT_FPOWNED_NONE 0x20000 -#define FREEBSD_UC_MCONTEXT_FPOWNED_FPU 0x20001 -#define FREEBSD_UC_MCONTEXT_FPOWNED_PCB 0x20002 - diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/regname.c b/src/coreclr/src/pal/src/libunwind/src/x86/regname.c deleted file mode 100644 index 11f62280413007..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/regname.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "unwind_i.h" - -static const char *regname[] = - { - "eax", "edx", "ecx", "ebx", "esi", "edi", "ebp", "esp", "eip", - "eflags", "trapno", - "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", - "fcw", "fsw", "ftw", "fop", "fcs", "fip", "fea", "fds", - "xmm0_lo", "xmm0_hi", "xmm1_lo", "xmm1_hi", - "xmm2_lo", "xmm2_hi", "xmm3_lo", "xmm3_hi", - "xmm4_lo", "xmm4_hi", "xmm5_lo", "xmm5_hi", - "xmm6_lo", "xmm6_hi", "xmm7_lo", "xmm7_hi", - "mxcsr", - "gs", "fs", "es", "ds", "ss", "cs", - "tss", "ldt", - "cfi", - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/x86/siglongjmp.S deleted file mode 100644 index 32bba3b3b69411..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/siglongjmp.S +++ /dev/null @@ -1,92 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - Copyright (C) 2011 Konstantin Belousov - -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. */ - - .globl _UI_siglongjmp_cont - -#if defined(__linux__) -#define SIG_SETMASK 2 -#elif defined(__FreeBSD__) -#define SIG_SETMASK 3 -#endif - - /* Stack layout at this point: - - +------------+ <- original $esp (at time of setjmp() call) - | sigmask[1] | - +------------+ - | sigmask[0] | - +------------+ - */ - - .type _UI_siglongjmp_cont, @function -_UI_siglongjmp_cont: - .cfi_startproc -#ifdef __linux__ - .cfi_register 8, 0 /* IP saved in EAX */ - .cfi_def_cfa_offset 8 - mov %esp, %ecx /* pass address of signal mask in 3rd sc arg */ - push %eax /* save target IP */ - .cfi_adjust_cfa_offset 4 - .cfi_offset 8, -12 - push %edx /* save return value */ - .cfi_adjust_cfa_offset 4 - push %ebx /* save %ebx (preserved) */ - .cfi_adjust_cfa_offset 4 - .cfi_offset 3, -20 - mov $SIG_SETMASK, %ebx /* 1st syscall arg (how) */ - xor %edx, %edx /* pass NULL as 3rd syscall arg (old maskp) */ - int $0x80 - pop %ebx /* restore %ebx */ - .cfi_adjust_cfa_offset -4 - .cfi_restore 3 - pop %eax /* fetch return value */ - .cfi_adjust_cfa_offset -4 - pop %edx /* pop target IP */ - .cfi_adjust_cfa_offset -4 - .cfi_register 8, 2 /* saved IP is now n EDX */ - lea 8(%esp), %esp /* pop sigmask */ - .cfi_adjust_cfa_offset -4 - jmp *%edx -#elif defined(__FreeBSD__) - pushl %eax - pushl %edx - pushl $0 - pushl %ecx - pushl $SIG_SETMASK - movl $340,%eax - pushl %eax - int $0x80 - addl $16,%esp - popl %eax - popl %edx - jmp *%edx -#else -#error Port me -#endif - .cfi_endproc - .size _UI_siglongjmp_cont, .-_UI_siglongjmp_cont - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/x86/unwind_i.h deleted file mode 100644 index caa7e02dee40e0..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86/unwind_i.h +++ /dev/null @@ -1,68 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 unwind_i_h -#define unwind_i_h - -#include - -#include - -#include "libunwind_i.h" - -/* DWARF column numbers: */ -#define EAX 0 -#define ECX 1 -#define EDX 2 -#define EBX 3 -#define ESP 4 -#define EBP 5 -#define ESI 6 -#define EDI 7 -#define EIP 8 -#define EFLAGS 9 -#define TRAPNO 10 -#define ST0 11 - -#define x86_lock UNW_OBJ(lock) -#define x86_local_resume UNW_OBJ(local_resume) -#define x86_local_addr_space_init UNW_OBJ(local_addr_space_init) -#define x86_scratch_loc UNW_OBJ(scratch_loc) -#define x86_get_scratch_loc UNW_OBJ(get_scratch_loc) -#define x86_r_uc_addr UNW_OBJ(r_uc_addr) -#define x86_sigreturn UNW_OBJ(sigreturn) - -extern void x86_local_addr_space_init (void); -extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, - void *arg); -extern dwarf_loc_t x86_scratch_loc (struct cursor *c, unw_regnum_t reg); -extern dwarf_loc_t x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg); -extern void *x86_r_uc_addr (ucontext_t *uc, int reg); - -extern void x86_sigreturn (unw_cursor_t *cursor); -#define x86_handle_signal_frame UNW_OBJ(handle_signal_frame) -extern int x86_handle_signal_frame(unw_cursor_t *cursor); - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gcreate_addr_space.c deleted file mode 100644 index 9b2db9810abe00..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gcreate_addr_space.c +++ /dev/null @@ -1,61 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Copyright (C) 2012 Tommi Rantala - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -#if defined(_LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) -#define __LITTLE_ENDIAN _LITTLE_ENDIAN -#endif - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* - * x86_64 supports only little-endian. - */ - if (byte_order != 0 && byte_order != __LITTLE_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_proc_info.c deleted file mode 100644 index 50de1e423c2c9e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_proc_info.c +++ /dev/null @@ -1,48 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - - if (dwarf_make_proc_info (&c->dwarf) < 0) - { - /* On x86-64, some key routines such as _start() and _dl_start() - are missing DWARF unwind info. We don't want to fail in that - case, because those frames are uninteresting and just mark - the end of the frame-chain anyhow. */ - memset (pi, 0, sizeof (*pi)); - pi->start_ip = c->dwarf.ip; - pi->end_ip = c->dwarf.ip + 1; - return 0; - } - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c deleted file mode 100644 index 0057c62d648bf3..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c +++ /dev/null @@ -1,73 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - struct cursor *c = (struct cursor *) cursor; - dwarf_loc_t loc; - - loc = DWARF_NULL_LOC; /* default to "not saved" */ - - switch (reg) - { - case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break; - case UNW_X86_64_RSP: loc = c->dwarf.loc[RSP]; break; - case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break; - case UNW_X86_64_R12: loc = c->dwarf.loc[R12]; break; - case UNW_X86_64_R13: loc = c->dwarf.loc[R13]; break; - case UNW_X86_64_R14: loc = c->dwarf.loc[R14]; break; - case UNW_X86_64_R15: loc = c->dwarf.loc[R15]; break; - - default: - break; - } - - memset (sloc, 0, sizeof (*sloc)); - - if (DWARF_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (DWARF_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = DWARF_GET_LOC (loc); - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = DWARF_GET_LOC (loc); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c deleted file mode 100644 index 8d1fbb4b0a9910..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c +++ /dev/null @@ -1,102 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "config.h" -#include "unwind_i.h" -#include "dwarf_i.h" - -HIDDEN define_lock (x86_64_lock); -HIDDEN int tdep_init_done; - -/* See comments for svr4_dbx_register_map[] in gcc/config/i386/i386.c. */ - -HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_NUM_PRESERVED_REGS] = - { - UNW_X86_64_RAX, - UNW_X86_64_RDX, - UNW_X86_64_RCX, - UNW_X86_64_RBX, - UNW_X86_64_RSI, - UNW_X86_64_RDI, - UNW_X86_64_RBP, - UNW_X86_64_RSP, - UNW_X86_64_R8, - UNW_X86_64_R9, - UNW_X86_64_R10, - UNW_X86_64_R11, - UNW_X86_64_R12, - UNW_X86_64_R13, - UNW_X86_64_R14, - UNW_X86_64_R15, - UNW_X86_64_RIP, -#ifdef CONFIG_MSABI_SUPPORT - UNW_X86_64_XMM0, - UNW_X86_64_XMM1, - UNW_X86_64_XMM2, - UNW_X86_64_XMM3, - UNW_X86_64_XMM4, - UNW_X86_64_XMM5, - UNW_X86_64_XMM6, - UNW_X86_64_XMM7, - UNW_X86_64_XMM8, - UNW_X86_64_XMM9, - UNW_X86_64_XMM10, - UNW_X86_64_XMM11, - UNW_X86_64_XMM12, - UNW_X86_64_XMM13, - UNW_X86_64_XMM14, - UNW_X86_64_XMM15 -#endif - }; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&x86_64_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - dwarf_init (); - - tdep_init_mem_validate (); - -#ifndef UNW_REMOTE_ONLY - x86_64_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&x86_64_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c deleted file mode 100644 index 2a84a1eec75e73..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c +++ /dev/null @@ -1,342 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -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. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; - return 0; -} - -#define PAGE_SIZE 4096 -#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) - -static int mem_validate_pipe[2] = {-1, -1}; - -static inline void -open_pipe (void) -{ - /* ignore errors for closing invalid fd's */ - close (mem_validate_pipe[0]); - close (mem_validate_pipe[1]); - - pipe2 (mem_validate_pipe, O_CLOEXEC | O_NONBLOCK); -} - -ALWAYS_INLINE -static int -write_validate (void *addr) -{ - int ret = -1; - ssize_t bytes = 0; - - do - { - char buf; - bytes = read (mem_validate_pipe[0], &buf, 1); - } - while ( errno == EINTR ); - - int valid_read = (bytes > 0 || errno == EAGAIN || errno == EWOULDBLOCK); - if (!valid_read) - { - // re-open closed pipe - open_pipe (); - } - - do - { - /* use syscall insteadof write() so that ASAN does not complain */ - ret = syscall (SYS_write, mem_validate_pipe[1], addr, 1); - } - while ( errno == EINTR ); - - return ret; -} - -static int (*mem_validate_func) (void *addr, size_t len); -static int msync_validate (void *addr, size_t len) -{ - if (msync (addr, len, MS_ASYNC) != 0) - { - return -1; - } - - return write_validate (addr); -} - -#ifdef HAVE_MINCORE -static int mincore_validate (void *addr, size_t len) -{ - unsigned char mvec[2]; /* Unaligned access may cross page boundary */ - size_t i; - - /* mincore could fail with EAGAIN but we conservatively return -1 - instead of looping. */ - if (mincore (addr, len, mvec) != 0) - { - return -1; - } - - for (i = 0; i < (len + PAGE_SIZE - 1) / PAGE_SIZE; i++) - { - if (!(mvec[i] & 1)) return -1; - } - - return write_validate (addr); -} -#endif - -/* Initialise memory validation method. On linux kernels <2.6.21, - mincore() returns incorrect value for MAP_PRIVATE mappings, - such as stacks. If mincore() was available at compile time, - check if we can actually use it. If not, use msync() instead. */ -HIDDEN void -tdep_init_mem_validate (void) -{ - open_pipe (); - -#ifdef HAVE_MINCORE - unsigned char present = 1; - unw_word_t addr = PAGE_START((unw_word_t)&present); - unsigned char mvec[1]; - int ret; - while ((ret = mincore ((void*)addr, PAGE_SIZE, mvec)) == -1 && - errno == EAGAIN) {} - if (ret == 0 && (mvec[0] & 1)) - { - Debug(1, "using mincore to validate memory\n"); - mem_validate_func = mincore_validate; - } - else -#endif - { - Debug(1, "using msync to validate memory\n"); - mem_validate_func = msync_validate; - } -} - -/* Cache of already validated addresses */ -#define NLGA 4 -static unw_word_t last_good_addr[NLGA]; -static int lga_victim; - -static int -validate_mem (unw_word_t addr) -{ - int i, victim; - size_t len; - - if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) - len = PAGE_SIZE; - else - len = PAGE_SIZE * 2; - - addr = PAGE_START(addr); - - if (addr == 0) - return -1; - - for (i = 0; i < NLGA; i++) - { - if (last_good_addr[i] && (addr == last_good_addr[i])) - return 0; - } - - if (mem_validate_func ((void *) addr, len) == -1) - return -1; - - victim = lga_victim; - for (i = 0; i < NLGA; i++) { - if (!last_good_addr[victim]) { - last_good_addr[victim++] = addr; - return 0; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - last_good_addr[victim] = addr; - victim = (victim + 1) % NLGA; - lga_victim = victim; - - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (unlikely (write)) - { - Debug (16, "mem[%016lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - /* validate address */ - const struct cursor *c = (const struct cursor *)arg; - if (likely (c != NULL) && unlikely (c->validate) - && unlikely (validate_mem (addr))) { - Debug (16, "mem[%016lx] -> invalid\n", addr); - return -1; - } - *val = *(unw_word_t *) addr; - Debug (16, "mem[%016lx] -> %lx\n", addr, *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = ((struct cursor *)arg)->uc; - - if (unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = x86_64_r_uc_addr (uc, reg))) - goto badreg; - - if (write) - { - *(unw_word_t *) addr = *val; - Debug (12, "%s <- 0x%016lx\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> 0x%016lx\n", unw_regname (reg), *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = ((struct cursor *)arg)->uc; - unw_fpreg_t *addr; - - if (!unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = x86_64_r_uc_addr (uc, reg))) - goto badreg; - - if (write) - { - Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - *(unw_fpreg_t *) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -x86_64_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = x86_64_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); - - memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); - lga_victim = 0; -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c deleted file mode 100644 index 5eaead0f840bb2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c +++ /dev/null @@ -1,81 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (unlikely (!tdep_init_done)) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = c; - c->uc = uc; - c->validate = 0; - return common_init (c, use_prev_instr); -} - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c deleted file mode 100644 index efd61d64d4b8f2..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c +++ /dev/null @@ -1,57 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - if (as == unw_local_addr_space) - { - c->dwarf.as_arg = c; - c->uc = as_arg; - } - else - { - c->dwarf.as_arg = as_arg; - c->uc = NULL; - } - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-freebsd.c deleted file mode 100644 index 883025c88ddc99..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-freebsd.c +++ /dev/null @@ -1,218 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010 Konstantin Belousov - -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. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include "unwind_i.h" -#include "ucontext_i.h" - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - /* XXXKIB */ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, w1, w2, b0, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors_int (as); - arg = c->dwarf.as_arg; - - /* Check if RIP points at sigreturn sequence. -48 8d 7c 24 10 lea SIGF_UC(%rsp),%rdi -6a 00 pushq $0 -48 c7 c0 a1 01 00 00 movq $SYS_sigreturn,%rax -0f 05 syscall -f4 0: hlt -eb fd jmp 0b - */ - - ip = c->dwarf.ip; - c->sigcontext_format = X86_64_SCF_NONE; - if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 - || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0 - || (ret = (*a->access_mem) (as, ip + 16, &w2, 0, arg)) < 0) - return 0; - w2 &= 0xffffff; - if (w0 == 0x48006a10247c8d48 && - w1 == 0x050f000001a1c0c7 && - w2 == 0x0000000000fdebf4) - { - c->sigcontext_format = X86_64_SCF_FREEBSD_SIGFRAME; - return (c->sigcontext_format); - } - /* Check if RIP points at standard syscall sequence. -49 89 ca mov %rcx,%r10 -0f 05 syscall - */ - if ((ret = (*a->access_mem) (as, ip - 5, &b0, 0, arg)) < 0) - return (0); - Debug (12, "b0 0x%lx\n", b0); - if ((b0 & 0xffffffffffffff) == 0x050fca89490000 || - (b0 & 0xffffffffff) == 0x050fca8949) - { - c->sigcontext_format = X86_64_SCF_FREEBSD_SYSCALL; - return (c->sigcontext_format); - } - return (X86_64_SCF_NONE); -} - -HIDDEN int -x86_64_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t ucontext; - int ret; - - if (c->sigcontext_format == X86_64_SCF_FREEBSD_SIGFRAME) - { - ucontext = c->dwarf.cfa + offsetof(struct sigframe, sf_uc); - c->sigcontext_addr = c->dwarf.cfa; - Debug(1, "signal frame, skip over trampoline\n"); - - struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); - ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - - c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0); - c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0); - c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0); - c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0); - c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0); - c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0); - c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0); - c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); - c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); - c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); - c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); - c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); - c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); - c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); - c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); - c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); - c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0); - - return 0; - } - else if (c->sigcontext_format == X86_64_SCF_FREEBSD_SYSCALL) - { - c->dwarf.loc[RCX] = c->dwarf.loc[R10]; - /* rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0); */ - /* rbp_loc = c->dwarf.loc[RBP]; */ - c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); - ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); - Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", - (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]), - (unsigned long long) c->dwarf.ip); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - c->dwarf.cfa += 8; - c->dwarf.use_prev_instr = 1; - return 1; - } - else - return -UNW_EBADFRAME; - -} - -#ifndef UNW_REMOTE_ONLY -HIDDEN void * -x86_64_r_uc_addr (ucontext_t *uc, int reg) -{ - /* NOTE: common_init() in init.h inlines these for fast path access. */ - void *addr; - - switch (reg) - { - case UNW_X86_64_R8: addr = &uc->uc_mcontext.mc_r8; break; - case UNW_X86_64_R9: addr = &uc->uc_mcontext.mc_r9; break; - case UNW_X86_64_R10: addr = &uc->uc_mcontext.mc_r10; break; - case UNW_X86_64_R11: addr = &uc->uc_mcontext.mc_r11; break; - case UNW_X86_64_R12: addr = &uc->uc_mcontext.mc_r12; break; - case UNW_X86_64_R13: addr = &uc->uc_mcontext.mc_r13; break; - case UNW_X86_64_R14: addr = &uc->uc_mcontext.mc_r14; break; - case UNW_X86_64_R15: addr = &uc->uc_mcontext.mc_r15; break; - case UNW_X86_64_RDI: addr = &uc->uc_mcontext.mc_rdi; break; - case UNW_X86_64_RSI: addr = &uc->uc_mcontext.mc_rsi; break; - case UNW_X86_64_RBP: addr = &uc->uc_mcontext.mc_rbp; break; - case UNW_X86_64_RBX: addr = &uc->uc_mcontext.mc_rbx; break; - case UNW_X86_64_RDX: addr = &uc->uc_mcontext.mc_rdx; break; - case UNW_X86_64_RAX: addr = &uc->uc_mcontext.mc_rax; break; - case UNW_X86_64_RCX: addr = &uc->uc_mcontext.mc_rcx; break; - case UNW_X86_64_RSP: addr = &uc->uc_mcontext.mc_rsp; break; - case UNW_X86_64_RIP: addr = &uc->uc_mcontext.mc_rip; break; - - default: - addr = NULL; - } - return addr; -} - -HIDDEN NORETURN void -x86_64_sigreturn (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - ucontext_t *uc = (ucontext_t *)(c->sigcontext_addr + - offsetof(struct sigframe, sf_uc)); - - uc->uc_mcontext.mc_r8 = c->uc->uc_mcontext.mc_r8; - uc->uc_mcontext.mc_r9 = c->uc->uc_mcontext.mc_r9; - uc->uc_mcontext.mc_r10 = c->uc->uc_mcontext.mc_r10; - uc->uc_mcontext.mc_r11 = c->uc->uc_mcontext.mc_r11; - uc->uc_mcontext.mc_r12 = c->uc->uc_mcontext.mc_r12; - uc->uc_mcontext.mc_r13 = c->uc->uc_mcontext.mc_r13; - uc->uc_mcontext.mc_r14 = c->uc->uc_mcontext.mc_r14; - uc->uc_mcontext.mc_r15 = c->uc->uc_mcontext.mc_r15; - uc->uc_mcontext.mc_rdi = c->uc->uc_mcontext.mc_rdi; - uc->uc_mcontext.mc_rsi = c->uc->uc_mcontext.mc_rsi; - uc->uc_mcontext.mc_rbp = c->uc->uc_mcontext.mc_rbp; - uc->uc_mcontext.mc_rbx = c->uc->uc_mcontext.mc_rbx; - uc->uc_mcontext.mc_rdx = c->uc->uc_mcontext.mc_rdx; - uc->uc_mcontext.mc_rax = c->uc->uc_mcontext.mc_rax; - uc->uc_mcontext.mc_rcx = c->uc->uc_mcontext.mc_rcx; - uc->uc_mcontext.mc_rsp = c->uc->uc_mcontext.mc_rsp; - uc->uc_mcontext.mc_rip = c->uc->uc_mcontext.mc_rip; - - Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", - (unsigned long long) c->dwarf.ip, uc); - sigreturn(uc); - abort(); -} -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-linux.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-linux.c deleted file mode 100644 index bd142345eddd4f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-linux.c +++ /dev/null @@ -1,156 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "ucontext_i.h" - -#include - -HIDDEN void -tdep_fetch_frame (struct dwarf_cursor *dw, unw_word_t ip, int need_unwind_info) -{ - struct cursor *c = (struct cursor *) dw; - assert(! need_unwind_info || dw->pi_valid); - assert(! need_unwind_info || dw->pi.unwind_info); - if (dw->pi_valid - && dw->pi.unwind_info - && ((struct dwarf_cie_info *) dw->pi.unwind_info)->signal_frame) - c->sigcontext_format = X86_64_SCF_LINUX_RT_SIGFRAME; - else - c->sigcontext_format = X86_64_SCF_NONE; - - Debug(5, "fetch frame ip=0x%lx cfa=0x%lx format=%d\n", - dw->ip, dw->cfa, c->sigcontext_format); -} - -HIDDEN int -tdep_cache_frame (struct dwarf_cursor *dw) -{ - struct cursor *c = (struct cursor *) dw; - - Debug(5, "cache frame ip=0x%lx cfa=0x%lx format=%d\n", - dw->ip, dw->cfa, c->sigcontext_format); - return c->sigcontext_format; -} - -HIDDEN void -tdep_reuse_frame (struct dwarf_cursor *dw, int frame) -{ - struct cursor *c = (struct cursor *) dw; - c->sigcontext_format = frame; - if (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME) - { - c->frame_info.frame_type = UNW_X86_64_FRAME_SIGRETURN; - /* Offset from cfa to ucontext_t in signal frame. */ - c->frame_info.cfa_reg_offset = 0; - c->sigcontext_addr = dw->cfa; - } - - Debug(5, "reuse frame ip=0x%lx cfa=0x%lx format=%d addr=0x%lx offset=%+d\n", - dw->ip, dw->cfa, c->sigcontext_format, c->sigcontext_addr, - (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME - ? c->frame_info.cfa_reg_offset : 0)); -} - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - return c->sigcontext_format != X86_64_SCF_NONE; -} - -HIDDEN int -x86_64_handle_signal_frame (unw_cursor_t *cursor) -{ -#if UNW_DEBUG /* To silence compiler warnings */ - /* Should not get here because we now use kernel-provided dwarf - information for the signal trampoline and dwarf_step() works. - Hence unw_step() should never call this function. Maybe - restore old non-dwarf signal handling here, but then the - gating on unw_is_signal_frame() needs to be removed. */ - struct cursor *c = (struct cursor *) cursor; - Debug(1, "old format signal frame? format=%d addr=0x%lx cfa=0x%lx\n", - c->sigcontext_format, c->sigcontext_addr, c->dwarf.cfa); -#endif - return -UNW_EBADFRAME; -} - -#ifndef UNW_REMOTE_ONLY -HIDDEN void * -x86_64_r_uc_addr (ucontext_t *uc, int reg) -{ - /* NOTE: common_init() in init.h inlines these for fast path access. */ - void *addr; - - switch (reg) - { - case UNW_X86_64_R8: addr = &uc->uc_mcontext.gregs[REG_R8]; break; - case UNW_X86_64_R9: addr = &uc->uc_mcontext.gregs[REG_R9]; break; - case UNW_X86_64_R10: addr = &uc->uc_mcontext.gregs[REG_R10]; break; - case UNW_X86_64_R11: addr = &uc->uc_mcontext.gregs[REG_R11]; break; - case UNW_X86_64_R12: addr = &uc->uc_mcontext.gregs[REG_R12]; break; - case UNW_X86_64_R13: addr = &uc->uc_mcontext.gregs[REG_R13]; break; - case UNW_X86_64_R14: addr = &uc->uc_mcontext.gregs[REG_R14]; break; - case UNW_X86_64_R15: addr = &uc->uc_mcontext.gregs[REG_R15]; break; - case UNW_X86_64_RDI: addr = &uc->uc_mcontext.gregs[REG_RDI]; break; - case UNW_X86_64_RSI: addr = &uc->uc_mcontext.gregs[REG_RSI]; break; - case UNW_X86_64_RBP: addr = &uc->uc_mcontext.gregs[REG_RBP]; break; - case UNW_X86_64_RBX: addr = &uc->uc_mcontext.gregs[REG_RBX]; break; - case UNW_X86_64_RDX: addr = &uc->uc_mcontext.gregs[REG_RDX]; break; - case UNW_X86_64_RAX: addr = &uc->uc_mcontext.gregs[REG_RAX]; break; - case UNW_X86_64_RCX: addr = &uc->uc_mcontext.gregs[REG_RCX]; break; - case UNW_X86_64_RSP: addr = &uc->uc_mcontext.gregs[REG_RSP]; break; - case UNW_X86_64_RIP: addr = &uc->uc_mcontext.gregs[REG_RIP]; break; - - default: - addr = NULL; - } - return addr; -} - -/* sigreturn() is a no-op on x86_64 glibc. */ -HIDDEN NORETURN void -x86_64_sigreturn (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; - mcontext_t *sc_mcontext = &((ucontext_t*)sc)->uc_mcontext; - /* Copy in saved uc - all preserved regs are at the start of sigcontext */ - memcpy(sc_mcontext, &c->uc->uc_mcontext, - DWARF_NUM_PRESERVED_REGS * sizeof(unw_word_t)); - - Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", - (unsigned long long) c->dwarf.ip, sc); - __asm__ __volatile__ ("mov %0, %%rsp;" - "mov %1, %%rax;" - "syscall" - :: "r"(sc), "i"(SYS_rt_sigreturn) - : "memory"); - abort(); -} - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gregs.c deleted file mode 100644 index baf8a24f0b9123..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gregs.c +++ /dev/null @@ -1,138 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -#if 0 -static inline dwarf_loc_t -linux_scratch_loc (struct cursor *c, unw_regnum_t reg) -{ - unw_word_t addr = c->sigcontext_addr; - - switch (c->sigcontext_format) - { - case X86_64_SCF_NONE: - return DWARF_REG_LOC (&c->dwarf, reg); - - case X86_64_SCF_LINUX_RT_SIGFRAME: - addr += LINUX_UC_MCONTEXT_OFF; - break; - - case X86_64_SCF_FREEBSD_SIGFRAME: - addr += FREEBSD_UC_MCONTEXT_OFF; - break; - } - - return DWARF_REG_LOC (&c->dwarf, reg); - -} - -HIDDEN dwarf_loc_t -x86_64_scratch_loc (struct cursor *c, unw_regnum_t reg) -{ - if (c->sigcontext_addr) - return linux_scratch_loc (c, reg); - else - return DWARF_REG_LOC (&c->dwarf, reg); -} -#endif - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - unsigned int mask; - int arg_num; - - switch (reg) - { - - case UNW_X86_64_RIP: - if (write) - c->dwarf.ip = *valp; /* also update the RIP cache */ - loc = c->dwarf.loc[RIP]; - break; - - case UNW_X86_64_CFA: - case UNW_X86_64_RSP: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - case UNW_X86_64_RAX: - case UNW_X86_64_RDX: - arg_num = reg - UNW_X86_64_RAX; - mask = (1 << arg_num); - if (write) - { - c->dwarf.eh_args[arg_num] = *valp; - c->dwarf.eh_valid_mask |= mask; - return 0; - } - else if ((c->dwarf.eh_valid_mask & mask) != 0) - { - *valp = c->dwarf.eh_args[arg_num]; - return 0; - } - else - loc = c->dwarf.loc[(reg == UNW_X86_64_RAX) ? RAX : RDX]; - break; - - case UNW_X86_64_RCX: loc = c->dwarf.loc[RCX]; break; - case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break; - - case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break; - case UNW_X86_64_RSI: loc = c->dwarf.loc[RSI]; break; - case UNW_X86_64_RDI: loc = c->dwarf.loc[RDI]; break; - case UNW_X86_64_R8: loc = c->dwarf.loc[R8]; break; - case UNW_X86_64_R9: loc = c->dwarf.loc[R9]; break; - case UNW_X86_64_R10: loc = c->dwarf.loc[R10]; break; - case UNW_X86_64_R11: loc = c->dwarf.loc[R11]; break; - case UNW_X86_64_R12: loc = c->dwarf.loc[R12]; break; - case UNW_X86_64_R13: loc = c->dwarf.loc[R13]; break; - case UNW_X86_64_R14: loc = c->dwarf.loc[R14]; break; - case UNW_X86_64_R15: loc = c->dwarf.loc[R15]; break; - - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - return -UNW_EBADREG; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gresume.c deleted file mode 100644 index 944cdaae192d86..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gresume.c +++ /dev/null @@ -1,123 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "offsets.h" -#include "unwind_i.h" - -#ifndef UNW_REMOTE_ONLY - -HIDDEN inline int -x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - struct cursor *c = (struct cursor *) cursor; - ucontext_t *uc = c->uc; - - /* Ensure c->pi is up-to-date. On x86-64, it's relatively common to - be missing DWARF unwind info. We don't want to fail in that - case, because the frame-chain still would let us do a backtrace - at least. */ - dwarf_make_proc_info (&c->dwarf); - - if (unlikely (c->sigcontext_addr != X86_64_SCF_NONE)) - { - x86_64_sigreturn(cursor); - abort(); - } - else - { - Debug (8, "resuming at ip=%llx via setcontext()\n", - (unsigned long long) c->dwarf.ip); - setcontext (uc); - } - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ - -/* This routine is responsible for copying the register values in - cursor C and establishing them as the current machine state. */ - -static inline int -establish_machine_state (struct cursor *c) -{ - int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, - int write, void *); - int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, - int write, void *); - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - access_reg = as->acc.access_reg; - access_fpreg = as->acc.access_fpreg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_REG_LAST; ++reg) - { - Debug (16, "copying %s %d\n", unw_regname (reg), reg); - if (unw_is_fpreg (reg)) - { - if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) - (*access_fpreg) (as, reg, &fpval, 1, arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - (*access_reg) (as, reg, &val, 1, arg); - } - } - - if (c->dwarf.args_size) - { - if (tdep_access_reg (c, UNW_X86_64_RSP, &val, 0) >= 0) - { - val += c->dwarf.args_size; - (*access_reg) (as, UNW_X86_64_RSP, &val, 1, arg); - } - } - return 0; -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p)\n", c); - - if ((ret = establish_machine_state (c)) < 0) - return ret; - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c deleted file mode 100644 index 2c7bc312e28c06..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c +++ /dev/null @@ -1,119 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "ucontext_i.h" - -HIDDEN void -tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) -{ - struct cursor *c = (struct cursor *) dwarf_to_cursor (d); - unw_tdep_frame_t *f = &c->frame_info; - - Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld" - " ra=0x%lx rbp [where=%d val=%ld @0x%lx] rsp [where=%d val=%ld @0x%lx]\n", - d->ip, d->cfa, f->frame_type, - rs->reg.where[DWARF_CFA_REG_COLUMN], - rs->reg.val[DWARF_CFA_REG_COLUMN], - rs->reg.val[DWARF_CFA_OFF_COLUMN], - DWARF_GET_LOC(d->loc[rs->ret_addr_column]), - rs->reg.where[RBP], rs->reg.val[RBP], DWARF_GET_LOC(d->loc[RBP]), - rs->reg.where[RSP], rs->reg.val[RSP], DWARF_GET_LOC(d->loc[RSP])); - - if (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR && - rs->reg.where[RBP] == DWARF_WHERE_EXPR) { - /* Check for GCC generated alignment frame for rsp. A simple - * def_cfa_expr that loads a constant offset from rbp, where the - * addres of the rip was pushed on the stack */ - unw_word_t cfa_addr = rs->reg.val[DWARF_CFA_REG_COLUMN]; - unw_word_t rbp_addr = rs->reg.val[RBP]; - unw_word_t cfa_offset; - - int ret = dwarf_stack_aligned(d, cfa_addr, rbp_addr, &cfa_offset); - if (ret) { - f->frame_type = UNW_X86_64_FRAME_ALIGNED; - f->cfa_reg_offset = cfa_offset; - f->cfa_reg_rsp = 0; - } - } - - /* A standard frame is defined as: - - CFA is register-relative offset off RBP or RSP; - - Return address is saved at CFA-8; - - RBP is unsaved or saved at CFA+offset, offset != -1; - - RSP is unsaved or saved at CFA+offset, offset != -1. */ - if (f->frame_type == UNW_X86_64_FRAME_OTHER - && (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG) - && (rs->reg.val[DWARF_CFA_REG_COLUMN] == RBP - || rs->reg.val[DWARF_CFA_REG_COLUMN] == RSP) - && labs((long) rs->reg.val[DWARF_CFA_OFF_COLUMN]) < (1 << 28) - && DWARF_GET_LOC(d->loc[rs->ret_addr_column]) == d->cfa-8 - && (rs->reg.where[RBP] == DWARF_WHERE_UNDEF - || rs->reg.where[RBP] == DWARF_WHERE_SAME - || (rs->reg.where[RBP] == DWARF_WHERE_CFAREL - && labs((long) rs->reg.val[RBP]) < (1 << 14) - && rs->reg.val[RBP]+1 != 0)) - && (rs->reg.where[RSP] == DWARF_WHERE_UNDEF - || rs->reg.where[RSP] == DWARF_WHERE_SAME - || (rs->reg.where[RSP] == DWARF_WHERE_CFAREL - && labs((long) rs->reg.val[RSP]) < (1 << 14) - && rs->reg.val[RSP]+1 != 0))) - { - /* Save information for a standard frame. */ - f->frame_type = UNW_X86_64_FRAME_STANDARD; - f->cfa_reg_rsp = (rs->reg.val[DWARF_CFA_REG_COLUMN] == RSP); - f->cfa_reg_offset = rs->reg.val[DWARF_CFA_OFF_COLUMN]; - if (rs->reg.where[RBP] == DWARF_WHERE_CFAREL) - f->rbp_cfa_offset = rs->reg.val[RBP]; - if (rs->reg.where[RSP] == DWARF_WHERE_CFAREL) - f->rsp_cfa_offset = rs->reg.val[RSP]; - Debug (4, " standard frame\n"); - } - - /* Signal frame was detected via augmentation in tdep_fetch_frame() */ - else if (f->frame_type == UNW_X86_64_FRAME_SIGRETURN) - { - /* Later we are going to fish out {RBP,RSP,RIP} from sigcontext via - their ucontext_t offsets. Confirm DWARF info agrees with the - offsets we expect. */ - -#ifndef NDEBUG - const unw_word_t uc = c->sigcontext_addr; - - assert (DWARF_GET_LOC(d->loc[RIP]) - uc == UC_MCONTEXT_GREGS_RIP); - assert (DWARF_GET_LOC(d->loc[RBP]) - uc == UC_MCONTEXT_GREGS_RBP); - assert (DWARF_GET_LOC(d->loc[RSP]) - uc == UC_MCONTEXT_GREGS_RSP); -#endif - - Debug (4, " sigreturn frame\n"); - } - - else if (f->frame_type == UNW_X86_64_FRAME_ALIGNED) { - Debug (4, " aligned frame, offset %li\n", f->cfa_reg_offset); - } - - /* PLT and guessed RBP-walked frames are handled in unw_step(). */ - else - Debug (4, " unusual frame\n"); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c deleted file mode 100644 index 10498170ac76dc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c +++ /dev/null @@ -1,227 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include - -/* Recognise PLT entries such as: - 3bdf0: ff 25 e2 49 13 00 jmpq *0x1349e2(%rip) - 3bdf6: 68 ae 03 00 00 pushq $0x3ae - 3bdfb: e9 00 c5 ff ff jmpq 38300 <_init+0x18> */ -static int -is_plt_entry (struct dwarf_cursor *c) -{ - unw_word_t w0, w1; - unw_accessors_t *a; - int ret; - - a = unw_get_accessors_int (c->as); - if ((ret = (*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg)) < 0 - || (ret = (*a->access_mem) (c->as, c->ip + 8, &w1, 0, c->as_arg)) < 0) - return 0; - - ret = (((w0 & 0xffff) == 0x25ff) - && (((w0 >> 48) & 0xff) == 0x68) - && (((w1 >> 24) & 0xff) == 0xe9)); - - Debug (14, "ip=0x%lx => 0x%016lx 0x%016lx, ret = %d\n", c->ip, w0, w1, ret); - return ret; -} - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret, i; - -#if CONSERVATIVE_CHECKS - int val = c->validate; - c->validate = 1; -#endif - - Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n", - c, c->dwarf.ip, c->dwarf.cfa); - - /* Try DWARF-based unwinding... */ - c->sigcontext_format = X86_64_SCF_NONE; - ret = dwarf_step (&c->dwarf); - -#if CONSERVATIVE_CHECKS - c->validate = val; -#endif - - if (ret < 0 && ret != -UNW_ENOINFO) - { - Debug (2, "returning %d\n", ret); - return ret; - } - - if (likely (ret >= 0)) - { - /* x86_64 ABI specifies that end of call-chain is marked with a - NULL RBP or undefined return address */ - if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) - { - c->dwarf.ip = 0; - ret = 0; - } - } - else - { - /* DWARF failed. There isn't much of a usable frame-chain on x86-64, - but we do need to handle two special-cases: - - (i) signal trampoline: Old kernels and older libcs don't - export the vDSO needed to get proper unwind info for the - trampoline. Recognize that case by looking at the code - and filling in things by hand. - - (ii) PLT (shared-library) call-stubs: PLT stubs are invoked - via CALLQ. Try this for all non-signal trampoline - code. */ - - unw_word_t prev_ip = c->dwarf.ip, prev_cfa = c->dwarf.cfa; - struct dwarf_loc rbp_loc, rsp_loc, rip_loc; - - /* We could get here because of missing/bad unwind information. - Validate all addresses before dereferencing. */ - c->validate = 1; - - Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); - - if (unw_is_signal_frame (cursor) > 0) - { - ret = x86_64_handle_signal_frame(cursor); - if (ret < 0) - { - Debug (2, "returning 0\n"); - return 0; - } - } - else if (is_plt_entry (&c->dwarf)) - { - /* Like regular frame, CFA = RSP+8, RA = [CFA-8], no regs saved. */ - Debug (2, "found plt entry\n"); - c->frame_info.cfa_reg_offset = 8; - c->frame_info.cfa_reg_rsp = -1; - c->frame_info.frame_type = UNW_X86_64_FRAME_STANDARD; - c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); - c->dwarf.cfa += 8; - } - else if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) - { - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - } - else - { - unw_word_t rbp; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[RBP], &rbp); - if (ret < 0) - { - Debug (2, "returning %d [RBP=0x%lx]\n", ret, - DWARF_GET_LOC (c->dwarf.loc[RBP])); - return ret; - } - - if (!rbp) - { - /* Looks like we may have reached the end of the call-chain. */ - rbp_loc = DWARF_NULL_LOC; - rsp_loc = DWARF_NULL_LOC; - rip_loc = DWARF_NULL_LOC; - } - else - { - unw_word_t rbp1 = 0; - rbp_loc = DWARF_LOC(rbp, 0); - rsp_loc = DWARF_NULL_LOC; - rip_loc = DWARF_LOC (rbp + 8, 0); - ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); - Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", - (unsigned long) DWARF_GET_LOC (c->dwarf.loc[RBP]), - rbp, c->dwarf.cfa, rbp1); - - /* Heuristic to determine incorrect guess. For RBP to be a - valid frame it needs to be above current CFA, but don't - let it go more than a little. Note that we can't deduce - anything about new RBP (rbp1) since it may not be a frame - pointer in the frame above. Just check we get the value. */ - if (ret < 0 - || rbp < c->dwarf.cfa - || (rbp - c->dwarf.cfa) > 0x4000) - { - rip_loc = DWARF_NULL_LOC; - rbp_loc = DWARF_NULL_LOC; - } - - c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; - c->frame_info.cfa_reg_rsp = 0; - c->frame_info.cfa_reg_offset = 16; - c->frame_info.rbp_cfa_offset = -16; - c->dwarf.cfa += 16; - } - - /* Mark all registers unsaved */ - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - c->dwarf.loc[RBP] = rbp_loc; - c->dwarf.loc[RSP] = rsp_loc; - c->dwarf.loc[RIP] = rip_loc; - c->dwarf.use_prev_instr = 1; - } - - if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) - { - ret = 0; - Debug (2, "NULL %%rbp loc, returning %d\n", ret); - return ret; - } - if (!DWARF_IS_NULL_LOC (c->dwarf.loc[RIP])) - { - ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); - Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", - (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]), - (unsigned long long) c->dwarf.ip); - if (ret < 0) - { - Debug (2, "returning %d\n", ret); - return ret; - } - ret = 1; - } - else - c->dwarf.ip = 0; - - if (c->dwarf.ip == prev_ip && c->dwarf.cfa == prev_cfa) - return -UNW_EBADFRAME; - } - Debug (2, "returning %d\n", ret); - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c deleted file mode 100644 index 741227105e1843..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c +++ /dev/null @@ -1,551 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "ucontext_i.h" -#include -#include - -#pragma weak pthread_once -#pragma weak pthread_key_create -#pragma weak pthread_getspecific -#pragma weak pthread_setspecific - -/* Initial hash table size. Table expands by 2 bits (times four). */ -#define HASH_MIN_BITS 14 - -typedef struct -{ - unw_tdep_frame_t *frames; - size_t log_size; - size_t used; - size_t dtor_count; /* Counts how many times our destructor has already - been called. */ -} unw_trace_cache_t; - -static const unw_tdep_frame_t empty_frame = { 0, UNW_X86_64_FRAME_OTHER, -1, -1, 0, -1, -1 }; -static define_lock (trace_init_lock); -static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; -static sig_atomic_t trace_cache_once_happen; -static pthread_key_t trace_cache_key; -static struct mempool trace_cache_pool; -static __thread unw_trace_cache_t *tls_cache; -static __thread int tls_cache_destroyed; - -/* Free memory for a thread's trace cache. */ -static void -trace_cache_free (void *arg) -{ - unw_trace_cache_t *cache = arg; - if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS) - { - /* Not yet our turn to get destroyed. Re-install ourselves into the key. */ - pthread_setspecific(trace_cache_key, cache); - Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, - PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); - return; - } - tls_cache_destroyed = 1; - tls_cache = NULL; - munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); - mempool_free (&trace_cache_pool, cache); - Debug(5, "freed cache %p\n", cache); -} - -/* Initialise frame tracing for threaded use. */ -static void -trace_cache_init_once (void) -{ - pthread_key_create (&trace_cache_key, &trace_cache_free); - mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); - trace_cache_once_happen = 1; -} - -static unw_tdep_frame_t * -trace_cache_buckets (size_t n) -{ - unw_tdep_frame_t *frames; - size_t i; - - GET_MEMORY(frames, n * sizeof (unw_tdep_frame_t)); - if (likely(frames != NULL)) - for (i = 0; i < n; ++i) - frames[i] = empty_frame; - - return frames; -} - -/* Allocate and initialise hash table for frame cache lookups. - Returns the cache initialised with (1u << HASH_LOW_BITS) hash - buckets, or NULL if there was a memory allocation problem. */ -static unw_trace_cache_t * -trace_cache_create (void) -{ - unw_trace_cache_t *cache; - - if (tls_cache_destroyed) - { - /* The current thread is in the process of exiting. Don't recreate - cache, as we wouldn't have another chance to free it. */ - Debug(5, "refusing to reallocate cache: " - "thread-locals are being deallocated\n"); - return NULL; - } - - if (! (cache = mempool_alloc(&trace_cache_pool))) - { - Debug(5, "failed to allocate cache\n"); - return NULL; - } - - if (! (cache->frames = trace_cache_buckets(1u << HASH_MIN_BITS))) - { - Debug(5, "failed to allocate buckets\n"); - mempool_free(&trace_cache_pool, cache); - return NULL; - } - - cache->log_size = HASH_MIN_BITS; - cache->used = 0; - cache->dtor_count = 0; - tls_cache_destroyed = 0; /* Paranoia: should already be 0. */ - Debug(5, "allocated cache %p\n", cache); - return cache; -} - -/* Expand the hash table in the frame cache if possible. This always - quadruples the hash size, and clears all previous frame entries. */ -static int -trace_cache_expand (unw_trace_cache_t *cache) -{ - size_t old_size = (1u << cache->log_size); - size_t new_log_size = cache->log_size + 2; - unw_tdep_frame_t *new_frames = trace_cache_buckets (1u << new_log_size); - - if (unlikely(! new_frames)) - { - Debug(5, "failed to expand cache to 2^%lu buckets\n", new_log_size); - return -UNW_ENOMEM; - } - - Debug(5, "expanded cache from 2^%lu to 2^%lu buckets\n", cache->log_size, new_log_size); - munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); - cache->frames = new_frames; - cache->log_size = new_log_size; - cache->used = 0; - return 0; -} - -static unw_trace_cache_t * -trace_cache_get_unthreaded (void) -{ - unw_trace_cache_t *cache; - intrmask_t saved_mask; - static unw_trace_cache_t *global_cache = NULL; - lock_acquire (&trace_init_lock, saved_mask); - if (! global_cache) - { - mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); - global_cache = trace_cache_create (); - } - cache = global_cache; - lock_release (&trace_init_lock, saved_mask); - Debug(5, "using cache %p\n", cache); - return cache; -} - -/* Get the frame cache for the current thread. Create it if there is none. */ -static unw_trace_cache_t * -trace_cache_get (void) -{ - unw_trace_cache_t *cache; - if (likely (pthread_once != NULL)) - { - pthread_once(&trace_cache_once, &trace_cache_init_once); - if (!trace_cache_once_happen) - { - return trace_cache_get_unthreaded(); - } - if (! (cache = tls_cache)) - { - cache = trace_cache_create(); - pthread_setspecific(trace_cache_key, cache); - tls_cache = cache; - } - Debug(5, "using cache %p\n", cache); - return cache; - } - else - { - return trace_cache_get_unthreaded(); - } -} - -/* Initialise frame properties for address cache slot F at address - RIP using current CFA, RBP and RSP values. Modifies CURSOR to - that location, performs one unw_step(), and fills F with what - was discovered about the location. Returns F. - - FIXME: This probably should tell DWARF handling to never evaluate - or use registers other than RBP, RSP and RIP in case there is - highly unusual unwind info which uses these creatively. */ -static unw_tdep_frame_t * -trace_init_addr (unw_tdep_frame_t *f, - unw_cursor_t *cursor, - unw_word_t cfa, - unw_word_t rip, - unw_word_t rbp, - unw_word_t rsp) -{ - struct cursor *c = (struct cursor *) cursor; - struct dwarf_cursor *d = &c->dwarf; - int ret = -UNW_EINVAL; - - /* Initialise frame properties: unknown, not last. */ - f->virtual_address = rip; - f->frame_type = UNW_X86_64_FRAME_OTHER; - f->last_frame = 0; - f->cfa_reg_rsp = -1; - f->cfa_reg_offset = 0; - f->rbp_cfa_offset = -1; - f->rsp_cfa_offset = -1; - - /* Reinitialise cursor to this instruction - but undo next/prev RIP - adjustment because unw_step will redo it - and force RIP, RBP - RSP into register locations (=~ ucontext we keep), then set - their desired values. Then perform the step. */ - d->ip = rip + d->use_prev_instr; - d->cfa = cfa; - d->loc[UNW_X86_64_RIP] = DWARF_REG_LOC (d, UNW_X86_64_RIP); - d->loc[UNW_X86_64_RBP] = DWARF_REG_LOC (d, UNW_X86_64_RBP); - d->loc[UNW_X86_64_RSP] = DWARF_REG_LOC (d, UNW_X86_64_RSP); - c->frame_info = *f; - - if (likely(dwarf_put (d, d->loc[UNW_X86_64_RIP], rip) >= 0) - && likely(dwarf_put (d, d->loc[UNW_X86_64_RBP], rbp) >= 0) - && likely(dwarf_put (d, d->loc[UNW_X86_64_RSP], rsp) >= 0) - && likely((ret = unw_step (cursor)) >= 0)) - *f = c->frame_info; - - /* If unw_step() stopped voluntarily, remember that, even if it - otherwise could not determine anything useful. This avoids - failing trace if we hit frames without unwind info, which is - common for the outermost frame (CRT stuff) on many systems. - This avoids failing trace in very common circumstances; failing - to unw_step() loop wouldn't produce any better result. */ - if (ret == 0) - f->last_frame = -1; - - Debug (3, "frame va %lx type %d last %d cfa %s+%d rbp @ cfa%+d rsp @ cfa%+d\n", - f->virtual_address, f->frame_type, f->last_frame, - f->cfa_reg_rsp ? "rsp" : "rbp", f->cfa_reg_offset, - f->rbp_cfa_offset, f->rsp_cfa_offset); - - return f; -} - -/* Look up and if necessary fill in frame attributes for address RIP - in CACHE using current CFA, RBP and RSP values. Uses CURSOR to - perform any unwind steps necessary to fill the cache. Returns the - frame cache slot which describes RIP. */ -static unw_tdep_frame_t * -trace_lookup (unw_cursor_t *cursor, - unw_trace_cache_t *cache, - unw_word_t cfa, - unw_word_t rip, - unw_word_t rbp, - unw_word_t rsp) -{ - /* First look up for previously cached information using cache as - linear probing hash table with probe step of 1. Majority of - lookups should be completed within few steps, but it is very - important the hash table does not fill up, or performance falls - off the cliff. */ - uint64_t i, addr; - uint64_t cache_size = 1u << cache->log_size; - uint64_t slot = ((rip * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); - unw_tdep_frame_t *frame; - - for (i = 0; i < 16; ++i) - { - frame = &cache->frames[slot]; - addr = frame->virtual_address; - - /* Return if we found the address. */ - if (likely(addr == rip)) - { - Debug (4, "found address after %ld steps\n", i); - return frame; - } - - /* If slot is empty, reuse it. */ - if (likely(! addr)) - break; - - /* Linear probe to next slot candidate, step = 1. */ - if (++slot >= cache_size) - slot -= cache_size; - } - - /* If we collided after 16 steps, or if the hash is more than half - full, force the hash to expand. Fill the selected slot, whether - it's free or collides. Note that hash expansion drops previous - contents; further lookups will refill the hash. */ - Debug (4, "updating slot %lu after %ld steps, replacing 0x%lx\n", slot, i, addr); - if (unlikely(addr || cache->used >= cache_size / 2)) - { - if (unlikely(trace_cache_expand (cache) < 0)) - return NULL; - - cache_size = 1u << cache->log_size; - slot = ((rip * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); - frame = &cache->frames[slot]; - addr = frame->virtual_address; - } - - if (! addr) - ++cache->used; - - return trace_init_addr (frame, cursor, cfa, rip, rbp, rsp); -} - -/* Fast stack backtrace for x86-64. - - This is used by backtrace() implementation to accelerate frequent - queries for current stack, without any desire to unwind. It fills - BUFFER with the call tree from CURSOR upwards for at most SIZE - stack levels. The first frame, backtrace itself, is omitted. When - called, SIZE should give the maximum number of entries that can be - stored into BUFFER. Uses an internal thread-specific cache to - accelerate queries. - - The caller should fall back to a unw_step() loop if this function - fails by returning -UNW_ESTOPUNWIND, meaning the routine hit a - stack frame that is too complex to be traced in the fast path. - - This function is tuned for clients which only need to walk the - stack to get the call tree as fast as possible but without any - other details, for example profilers sampling the stack thousands - to millions of times per second. The routine handles the most - common x86-64 ABI stack layouts: CFA is RBP or RSP plus/minus - constant offset, return address is at CFA-8, and RBP and RSP are - either unchanged or saved on stack at constant offset from the CFA; - the signal return frame; and frames without unwind info provided - they are at the outermost (final) frame or can conservatively be - assumed to be frame-pointer based. - - Any other stack layout will cause the routine to give up. There - are only a handful of relatively rarely used functions which do - not have a stack in the standard form: vfork, longjmp, setcontext - and _dl_runtime_profile on common linux systems for example. - - On success BUFFER and *SIZE reflect the trace progress up to *SIZE - stack levels or the outermost frame, which ever is less. It may - stop short of outermost frame if unw_step() loop would also do so, - e.g. if there is no more unwind information; this is not reported - as an error. - - The function returns a negative value for errors, -UNW_ESTOPUNWIND - if tracing stopped because of an unusual frame unwind info. The - BUFFER and *SIZE reflect tracing progress up to the error frame. - - Callers of this function would normally look like this: - - unw_cursor_t cur; - unw_context_t ctx; - void addrs[128]; - int depth = 128; - int ret; - - unw_getcontext(&ctx); - unw_init_local(&cur, &ctx); - if ((ret = unw_tdep_trace(&cur, addrs, &depth)) < 0) - { - depth = 0; - unw_getcontext(&ctx); - unw_init_local(&cur, &ctx); - while ((ret = unw_step(&cur)) > 0 && depth < 128) - { - unw_word_t ip; - unw_get_reg(&cur, UNW_REG_IP, &ip); - addresses[depth++] = (void *) ip; - } - } -*/ -HIDDEN int -tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) -{ - struct cursor *c = (struct cursor *) cursor; - struct dwarf_cursor *d = &c->dwarf; - unw_trace_cache_t *cache; - unw_word_t rbp, rsp, rip, cfa; - int maxdepth = 0; - int depth = 0; - int ret; - - /* Check input parametres. */ - if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) - return -UNW_EINVAL; - - Debug (1, "begin ip 0x%lx cfa 0x%lx\n", d->ip, d->cfa); - - /* Tell core dwarf routines to call back to us. */ - d->stash_frames = 1; - - /* Determine initial register values. These are direct access safe - because we know they come from the initial machine context. */ - rip = d->ip; - rsp = cfa = d->cfa; - ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_X86_64_RBP]), rbp); - assert(ret == 0); - - /* Get frame cache. */ - if (unlikely(! (cache = trace_cache_get()))) - { - Debug (1, "returning %d, cannot get trace cache\n", -UNW_ENOMEM); - *size = 0; - d->stash_frames = 0; - return -UNW_ENOMEM; - } - - /* Trace the stack upwards, starting from current RIP. Adjust - the RIP address for previous/next instruction as the main - unwinding logic would also do. We undo this before calling - back into unw_step(). */ - while (depth < maxdepth) - { - rip -= d->use_prev_instr; - Debug (2, "depth %d cfa 0x%lx rip 0x%lx rsp 0x%lx rbp 0x%lx\n", - depth, cfa, rip, rsp, rbp); - - /* See if we have this address cached. If not, evaluate enough of - the dwarf unwind information to fill the cache line data, or to - decide this frame cannot be handled in fast trace mode. We - cache negative results too to prevent unnecessary dwarf parsing - for common failures. */ - unw_tdep_frame_t *f = trace_lookup (cursor, cache, cfa, rip, rbp, rsp); - - /* If we don't have information for this frame, give up. */ - if (unlikely(! f)) - { - ret = -UNW_ENOINFO; - break; - } - - Debug (3, "frame va %lx type %d last %d cfa %s+%d rbp @ cfa%+d rsp @ cfa%+d\n", - f->virtual_address, f->frame_type, f->last_frame, - f->cfa_reg_rsp ? "rsp" : "rbp", f->cfa_reg_offset, - f->rbp_cfa_offset, f->rsp_cfa_offset); - - assert (f->virtual_address == rip); - - /* Stop if this was the last frame. In particular don't evaluate - new register values as it may not be safe - we don't normally - run with full validation on, and do not want to - and there's - enough bad unwind info floating around that we need to trust - what unw_step() previously said, in potentially bogus frames. */ - if (f->last_frame) - break; - - /* Evaluate CFA and registers for the next frame. */ - switch (f->frame_type) - { - case UNW_X86_64_FRAME_GUESSED: - /* Fall thru to standard processing after forcing validation. */ - c->validate = 1; - - case UNW_X86_64_FRAME_STANDARD: - /* Advance standard traceable frame. */ - cfa = (f->cfa_reg_rsp ? rsp : rbp) + f->cfa_reg_offset; - ACCESS_MEM_FAST(ret, c->validate, d, cfa - 8, rip); - if (likely(ret >= 0) && likely(f->rbp_cfa_offset != -1)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->rbp_cfa_offset, rbp); - - /* Don't bother reading RSP from DWARF, CFA becomes new RSP. */ - rsp = cfa; - - /* Next frame needs to back up for unwind info lookup. */ - d->use_prev_instr = 1; - break; - - case UNW_X86_64_FRAME_SIGRETURN: - cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ - - ACCESS_MEM_FAST(ret, c->validate, d, cfa + UC_MCONTEXT_GREGS_RIP, rip); - if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + UC_MCONTEXT_GREGS_RBP, rbp); - if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa + UC_MCONTEXT_GREGS_RSP, rsp); - - /* Resume stack at signal restoration point. The stack is not - necessarily continuous here, especially with sigaltstack(). */ - cfa = rsp; - - /* Next frame should not back up. */ - d->use_prev_instr = 0; - break; - - case UNW_X86_64_FRAME_ALIGNED: - /* Address of RIP was pushed on the stack via a simple - * def_cfa_expr - result stack offset stored in cfa_reg_offset */ - cfa = (f->cfa_reg_rsp ? rsp : rbp) + f->cfa_reg_offset; - ACCESS_MEM_FAST(ret, c->validate, d, cfa, cfa); - if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, cfa - 8, rip); - if (likely(ret >= 0)) - ACCESS_MEM_FAST(ret, c->validate, d, rbp, rbp); - - /* Don't bother reading RSP from DWARF, CFA becomes new RSP. */ - rsp = cfa; - - /* Next frame needs to back up for unwind info lookup. */ - d->use_prev_instr = 1; - - break; - - default: - /* We cannot trace through this frame, give up and tell the - caller we had to stop. Data collected so far may still be - useful to the caller, so let it know how far we got. */ - ret = -UNW_ESTOPUNWIND; - break; - } - - Debug (4, "new cfa 0x%lx rip 0x%lx rsp 0x%lx rbp 0x%lx\n", - cfa, rip, rsp, rbp); - - /* If we failed or ended up somewhere bogus, stop. */ - if (unlikely(ret < 0 || rip < 0x4000)) - break; - - /* Record this address in stack trace. We skipped the first address. */ - buffer[depth++] = (void *) (rip - d->use_prev_instr); - } - -#if UNW_DEBUG - Debug (1, "returning %d, depth %d\n", ret, depth); -#endif - *size = depth; - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e5640..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be901453..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd51..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lglobal.c deleted file mode 100644 index 8c43a67c0fff23..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lglobal.c +++ /dev/null @@ -1,6 +0,0 @@ -#define UNW_LOCAL_ONLY -#include "config.h" -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit.c deleted file mode 100644 index e9abfdd46a3e0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_local.c deleted file mode 100644 index 68a1687e85444b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-freebsd.c deleted file mode 100644 index a75a205df19c01..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-freebsd.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gos-freebsd.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-linux.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-linux.c deleted file mode 100644 index 3cc18aabcc399c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-linux.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gos-linux.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcca..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lresume.c deleted file mode 100644 index 41a8cf003de4ac..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstash_frame.c deleted file mode 100644 index 77587803d083d7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstash_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstash_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstep.c deleted file mode 100644 index c1ac3c7547f00d..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ltrace.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ltrace.c deleted file mode 100644 index fcd3f239c9e422..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ltrace.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gtrace.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S deleted file mode 100644 index 7a8b5664bdaebd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S +++ /dev/null @@ -1,134 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 Google, Inc - Contributed by Paul Pluzhnikov - Copyright (C) 2010 Konstantin Belousov - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "ucontext_i.h" - -/* int _Ux86_64_getcontext (ucontext_t *ucp) - - Saves the machine context in UCP necessary for libunwind. - Unlike the libc implementation, we don't save the signal mask - and hence avoid the cost of a system call per unwind. - -*/ - - .global _Ux86_64_getcontext - .type _Ux86_64_getcontext, @function -_Ux86_64_getcontext: - .cfi_startproc - - /* Callee saved: RBX, RBP, R12-R15 */ - movq %r12, UC_MCONTEXT_GREGS_R12(%rdi) - movq %r13, UC_MCONTEXT_GREGS_R13(%rdi) - movq %r14, UC_MCONTEXT_GREGS_R14(%rdi) - movq %r15, UC_MCONTEXT_GREGS_R15(%rdi) - movq %rbp, UC_MCONTEXT_GREGS_RBP(%rdi) - movq %rbx, UC_MCONTEXT_GREGS_RBX(%rdi) - - /* Save argument registers (not strictly needed, but setcontext - restores them, so don't restore garbage). */ - movq %r8, UC_MCONTEXT_GREGS_R8(%rdi) - movq %r9, UC_MCONTEXT_GREGS_R9(%rdi) - movq %rdi, UC_MCONTEXT_GREGS_RDI(%rdi) - movq %rsi, UC_MCONTEXT_GREGS_RSI(%rdi) - movq %rdx, UC_MCONTEXT_GREGS_RDX(%rdi) - movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi) - movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi) - -#if defined __linux__ - /* Save fp state (not needed, except for setcontext not - restoring garbage). */ - leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 - movq %r8, UC_MCONTEXT_FPREGS_PTR(%rdi) - fnstenv (%r8) - stmxcsr FPREGS_OFFSET_MXCSR(%r8) -#elif defined __FreeBSD__ - fxsave UC_MCONTEXT_FPSTATE(%rdi) - movq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi) - movq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi) - /* Save rflags and segment registers, so that sigreturn(2) - does not complain. */ - pushfq - .cfi_adjust_cfa_offset 8 - popq UC_MCONTEXT_RFLAGS(%rdi) - .cfi_adjust_cfa_offset -8 - movl $0, UC_MCONTEXT_FLAGS(%rdi) - movw %cs, UC_MCONTEXT_CS(%rdi) - movw %ss, UC_MCONTEXT_SS(%rdi) -#if 0 - /* Setting the flags to 0 above disables restore of segment - registers from the context */ - movw %ds, UC_MCONTEXT_DS(%rdi) - movw %es, UC_MCONTEXT_ES(%rdi) - movw %fs, UC_MCONTEXT_FS(%rdi) - movw %gs, UC_MCONTEXT_GS(%rdi) -#endif - movq $UC_MCONTEXT_MC_LEN_VAL, UC_MCONTEXT_MC_LEN(%rdi) -#else -#error Port me -#endif - - leaq 8(%rsp), %rax /* exclude this call. */ - movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi) - - movq 0(%rsp), %rax - movq %rax, UC_MCONTEXT_GREGS_RIP(%rdi) - - xorq %rax, %rax - retq - .cfi_endproc - .size _Ux86_64_getcontext, . - _Ux86_64_getcontext - -/* int _Ux86_64_getcontext_trace (ucontext_t *ucp) - - Saves limited machine context in UCP necessary for libunwind. - Unlike _Ux86_64_getcontext, saves only the parts needed for - fast trace. If fast trace fails, caller will have to get the - full context. -*/ - - .global _Ux86_64_getcontext_trace - .hidden _Ux86_64_getcontext_trace - .type _Ux86_64_getcontext_trace, @function -_Ux86_64_getcontext_trace: - .cfi_startproc - - /* Save only RBP, RBX, RSP, RIP - exclude this call. */ - movq %rbp, UC_MCONTEXT_GREGS_RBP(%rdi) - movq %rbx, UC_MCONTEXT_GREGS_RBX(%rdi) - - leaq 8(%rsp), %rax - movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi) - - movq 0(%rsp), %rax - movq %rax, UC_MCONTEXT_GREGS_RIP(%rdi) - - xorq %rax, %rax - retq - .cfi_endproc - .size _Ux86_64_getcontext_trace, . - _Ux86_64_getcontext_trace - - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/init.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/init.h deleted file mode 100644 index a7a996f1272758..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/init.h +++ /dev/null @@ -1,89 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -/* Avoid a trip to x86_64_r_uc_addr() for purely local initialisation. */ -#if defined UNW_LOCAL_ONLY && defined __linux -# define REG_INIT_LOC(c, rlc, ruc) \ - DWARF_LOC ((unw_word_t) &c->uc->uc_mcontext.gregs[REG_ ## ruc], 0) - -#elif defined UNW_LOCAL_ONLY && defined __FreeBSD__ -# define REG_INIT_LOC(c, rlc, ruc) \ - DWARF_LOC ((unw_word_t) &c->uc->uc_mcontext.mc_ ## rlc, 0) - -#else -# define REG_INIT_LOC(c, rlc, ruc) \ - DWARF_REG_LOC (&c->dwarf, UNW_X86_64_ ## ruc) -#endif - -static inline int -common_init (struct cursor *c, unsigned use_prev_instr) -{ - int ret; - - c->dwarf.loc[RAX] = REG_INIT_LOC(c, rax, RAX); - c->dwarf.loc[RDX] = REG_INIT_LOC(c, rdx, RDX); - c->dwarf.loc[RCX] = REG_INIT_LOC(c, rcx, RCX); - c->dwarf.loc[RBX] = REG_INIT_LOC(c, rbx, RBX); - c->dwarf.loc[RSI] = REG_INIT_LOC(c, rsi, RSI); - c->dwarf.loc[RDI] = REG_INIT_LOC(c, rdi, RDI); - c->dwarf.loc[RBP] = REG_INIT_LOC(c, rbp, RBP); - c->dwarf.loc[RSP] = REG_INIT_LOC(c, rsp, RSP); - c->dwarf.loc[R8] = REG_INIT_LOC(c, r8, R8); - c->dwarf.loc[R9] = REG_INIT_LOC(c, r9, R9); - c->dwarf.loc[R10] = REG_INIT_LOC(c, r10, R10); - c->dwarf.loc[R11] = REG_INIT_LOC(c, r11, R11); - c->dwarf.loc[R12] = REG_INIT_LOC(c, r12, R12); - c->dwarf.loc[R13] = REG_INIT_LOC(c, r13, R13); - c->dwarf.loc[R14] = REG_INIT_LOC(c, r14, R14); - c->dwarf.loc[R15] = REG_INIT_LOC(c, r15, R15); - c->dwarf.loc[RIP] = REG_INIT_LOC(c, rip, RIP); - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); - if (ret < 0) - return ret; - - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_X86_64_RSP), - &c->dwarf.cfa); - if (ret < 0) - return ret; - - c->sigcontext_format = X86_64_SCF_NONE; - c->sigcontext_addr = 0; - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - c->dwarf.eh_valid_mask = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/is_fpreg.c deleted file mode 100644 index 5c036137b630fc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/is_fpreg.c +++ /dev/null @@ -1,38 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_is_fpreg (int regnum) -{ -#if 0 - return ((regnum >= UNW_X86_ST0 && regnum <= UNW_X86_ST7) - || (regnum >= UNW_X86_XMM0_lo && regnum <= UNW_X86_XMM7_hi)); -#endif - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/longjmp.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/longjmp.S deleted file mode 100644 index 274778fd80f365..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/longjmp.S +++ /dev/null @@ -1,34 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - - .globl _UI_longjmp_cont - .type _UI_longjmp_cont, @function -_UI_longjmp_cont: - push %rax /* push target IP as return address */ - mov %rdx, %rax /* set up return-value */ - retq - .size _UI_longjmp_cont, .-_UI_longjmp_cont - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/offsets.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/offsets.h deleted file mode 100644 index 0807960f30c0c9..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/offsets.h +++ /dev/null @@ -1,3 +0,0 @@ -/* FreeBSD specific definitions */ - -#define FREEBSD_UC_MCONTEXT_OFF 0x10 diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/regname.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/regname.c deleted file mode 100644 index 77660af4a2edae..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/regname.c +++ /dev/null @@ -1,56 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Contributed by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static const char *regname[] = - { - "RAX", - "RDX", - "RCX", - "RBX", - "RSI", - "RDI", - "RBP", - "RSP", - "R8", - "R9", - "R10", - "R11", - "R12", - "R13", - "R14", - "R15", - "RIP", - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S deleted file mode 100644 index 358217defbaf3b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S +++ /dev/null @@ -1,83 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2007 Google, Inc - Contributed by Arun Sharma - Copyright (C) 2010 Konstantin Belousov - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "ucontext_i.h" - -/* int _Ux86_64_setcontext (const ucontext_t *ucp) - - Restores the machine context provided. - Unlike the libc implementation, doesn't clobber %rax - -*/ - .global _Ux86_64_setcontext - .type _Ux86_64_setcontext, @function - -_Ux86_64_setcontext: - -#if defined __linux__ - /* restore fp state */ - mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8 - fldenv (%r8) - ldmxcsr FPREGS_OFFSET_MXCSR(%r8) -#elif defined __FreeBSD__ - /* restore fp state */ - cmpq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi) - jne 1f - cmpq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi) - jne 1f - fxrstor UC_MCONTEXT_FPSTATE(%rdi) -1: -#else -#error Port me -#endif - - /* restore the rest of the state */ - mov UC_MCONTEXT_GREGS_R8(%rdi),%r8 - mov UC_MCONTEXT_GREGS_R9(%rdi),%r9 - mov UC_MCONTEXT_GREGS_RBX(%rdi),%rbx - mov UC_MCONTEXT_GREGS_RBP(%rdi),%rbp - mov UC_MCONTEXT_GREGS_R12(%rdi),%r12 - mov UC_MCONTEXT_GREGS_R13(%rdi),%r13 - mov UC_MCONTEXT_GREGS_R14(%rdi),%r14 - mov UC_MCONTEXT_GREGS_R15(%rdi),%r15 - mov UC_MCONTEXT_GREGS_RSI(%rdi),%rsi - mov UC_MCONTEXT_GREGS_RDX(%rdi),%rdx - mov UC_MCONTEXT_GREGS_RAX(%rdi),%rax - mov UC_MCONTEXT_GREGS_RCX(%rdi),%rcx - mov UC_MCONTEXT_GREGS_RSP(%rdi),%rsp - - /* push the return address on the stack */ - mov UC_MCONTEXT_GREGS_RIP(%rdi),%rcx - push %rcx - - mov UC_MCONTEXT_GREGS_RCX(%rdi),%rcx - mov UC_MCONTEXT_GREGS_RDI(%rdi),%rdi - retq - - .size _Ux86_64_setcontext, . - _Ux86_64_setcontext - - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/siglongjmp.S deleted file mode 100644 index 32489e53a9f19c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/siglongjmp.S +++ /dev/null @@ -1,32 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - - .globl _UI_siglongjmp_cont - .type _UI_siglongjmp_cont, @function -_UI_siglongjmp_cont: - retq - .size _UI_siglongjmp_cont, . - _UI_siglongjmp_cont - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h deleted file mode 100644 index aded941d053f76..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (C) 2004 Hewlett-Packard Co. - Contributed by David Mosberger-Tang . - -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. */ - -#if defined __linux__ -#define UC_MCONTEXT_GREGS_R8 0x28 -#define UC_MCONTEXT_GREGS_R9 0x30 -#define UC_MCONTEXT_GREGS_R10 0x38 -#define UC_MCONTEXT_GREGS_R11 0x40 -#define UC_MCONTEXT_GREGS_R12 0x48 -#define UC_MCONTEXT_GREGS_R13 0x50 -#define UC_MCONTEXT_GREGS_R14 0x58 -#define UC_MCONTEXT_GREGS_R15 0x60 -#define UC_MCONTEXT_GREGS_RDI 0x68 -#define UC_MCONTEXT_GREGS_RSI 0x70 -#define UC_MCONTEXT_GREGS_RBP 0x78 -#define UC_MCONTEXT_GREGS_RBX 0x80 -#define UC_MCONTEXT_GREGS_RDX 0x88 -#define UC_MCONTEXT_GREGS_RAX 0x90 -#define UC_MCONTEXT_GREGS_RCX 0x98 -#define UC_MCONTEXT_GREGS_RSP 0xa0 -#define UC_MCONTEXT_GREGS_RIP 0xa8 -#define UC_MCONTEXT_FPREGS_PTR 0x1a8 -#define UC_MCONTEXT_FPREGS_MEM 0xe0 -#define UC_SIGMASK 0x128 -#define FPREGS_OFFSET_MXCSR 0x18 -#elif defined __FreeBSD__ -#define UC_SIGMASK 0x0 -#define UC_MCONTEXT_GREGS_RDI 0x18 -#define UC_MCONTEXT_GREGS_RSI 0x20 -#define UC_MCONTEXT_GREGS_RDX 0x28 -#define UC_MCONTEXT_GREGS_RCX 0x30 -#define UC_MCONTEXT_GREGS_R8 0x38 -#define UC_MCONTEXT_GREGS_R9 0x40 -#define UC_MCONTEXT_GREGS_RAX 0x48 -#define UC_MCONTEXT_GREGS_RBX 0x50 -#define UC_MCONTEXT_GREGS_RBP 0x58 -#define UC_MCONTEXT_GREGS_R10 0x60 -#define UC_MCONTEXT_GREGS_R11 0x68 -#define UC_MCONTEXT_GREGS_R12 0x70 -#define UC_MCONTEXT_GREGS_R13 0x78 -#define UC_MCONTEXT_GREGS_R14 0x80 -#define UC_MCONTEXT_GREGS_R15 0x88 -#define UC_MCONTEXT_FS 0x94 -#define UC_MCONTEXT_GS 0x96 -#define UC_MCONTEXT_FLAGS 0xa0 -#define UC_MCONTEXT_ES 0xa4 -#define UC_MCONTEXT_DS 0xa6 -#define UC_MCONTEXT_GREGS_RIP 0xb0 -#define UC_MCONTEXT_CS 0xb8 -#define UC_MCONTEXT_RFLAGS 0xc0 -#define UC_MCONTEXT_GREGS_RSP 0xc8 -#define UC_MCONTEXT_SS 0xd0 -#define UC_MCONTEXT_MC_LEN 0xd8 -#define UC_MCONTEXT_FPFORMAT 0xe0 -#define UC_MCONTEXT_OWNEDFP 0xe8 -#define UC_MCONTEXT_FPSTATE 0xf0 -#define UC_MCONTEXT_FPOWNED_FPU 0x20001 -#define UC_MCONTEXT_FPFMT_XMM 0x10002 -#define UC_MCONTEXT_MC_LEN_VAL 0x320 - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/unwind_i.h deleted file mode 100644 index e95a60ff37676e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/unwind_i.h +++ /dev/null @@ -1,93 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -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 unwind_i_h -#define unwind_i_h - -#include - -#include - -#include "libunwind_i.h" -#include - -/* DWARF column numbers for x86_64: */ -#define RAX 0 -#define RDX 1 -#define RCX 2 -#define RBX 3 -#define RSI 4 -#define RDI 5 -#define RBP 6 -#define RSP 7 -#define R8 8 -#define R9 9 -#define R10 10 -#define R11 11 -#define R12 12 -#define R13 13 -#define R14 14 -#define R15 15 -#define RIP 16 - -#define x86_64_lock UNW_OBJ(lock) -#define x86_64_local_resume UNW_OBJ(local_resume) -#define x86_64_local_addr_space_init UNW_OBJ(local_addr_space_init) -#define setcontext UNW_ARCH_OBJ (setcontext) -#if 0 -#define x86_64_scratch_loc UNW_OBJ(scratch_loc) -#endif -#define x86_64_r_uc_addr UNW_OBJ(r_uc_addr) -#define x86_64_sigreturn UNW_OBJ(sigreturn) - -/* By-pass calls to access_mem() when known to be safe. */ -#ifdef UNW_LOCAL_ONLY -# undef ACCESS_MEM_FAST -# define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ - do { \ - if (unlikely(validate)) \ - (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); \ - else \ - (ret) = 0, (to) = *(unw_word_t *)(addr); \ - } while (0) -#endif - -extern void x86_64_local_addr_space_init (void); -extern int x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, - void *arg); -extern int setcontext (const ucontext_t *ucp); - -#if 0 -extern dwarf_loc_t x86_64_scratch_loc (struct cursor *c, unw_regnum_t reg); -#endif - -extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg); -extern NORETURN void x86_64_sigreturn (unw_cursor_t *cursor); -#define x86_64_handle_signal_frame UNW_OBJ(handle_signal_frame) -extern int x86_64_handle_signal_frame(unw_cursor_t *cursor); - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-nat.c b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-nat.c deleted file mode 100644 index 89df54e0b0ee36..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-nat.c +++ /dev/null @@ -1,626 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 tests corner-cases of NaT-bit handling. */ - -#include -#include -#include -#include - -#include -#include "compiler.h" - -#ifdef HAVE_SYS_UC_ACCESS_H -# include -#endif - -#include "tdep-ia64/rse.h" - -#define NUM_RUNS 1024 -//#define NUM_RUNS 1 -#define MAX_CHECKS 1024 -//#define MAX_CHECKS 2 -#define MAX_VALUES_PER_FUNC 4 - -#define panic(args...) \ - do { printf (args); ++nerrors; } while (0) - -typedef void save_func_t (void *funcs, unsigned long *vals); -typedef unw_word_t *check_func_t (unw_cursor_t *c, unsigned long *vals); - -extern void flushrs (void); - -extern save_func_t save_static_to_stacked; -static check_func_t check_static_to_stacked; - -extern save_func_t save_static_to_fr; -static check_func_t check_static_to_fr; - -extern save_func_t save_static_to_br; -static check_func_t check_static_to_br; - -extern save_func_t save_static_to_mem; -static check_func_t check_static_to_mem; - -extern save_func_t save_static_to_mem2; -static check_func_t check_static_to_mem2; - -extern save_func_t save_static_to_mem3; -static check_func_t check_static_to_mem3; - -extern save_func_t save_static_to_mem4; -static check_func_t check_static_to_mem4; - -extern save_func_t save_static_to_mem5; -static check_func_t check_static_to_mem5; - -extern save_func_t save_static_to_scratch; -static check_func_t check_static_to_scratch; - -extern save_func_t rotate_regs; -static check_func_t check_rotate_regs; - -extern save_func_t save_pr; -static check_func_t check_pr; - -static int verbose; -static int nerrors; - -static int num_checks; -static save_func_t *funcs[MAX_CHECKS + 1]; -static check_func_t *checks[MAX_CHECKS]; -static unw_word_t values[MAX_CHECKS*MAX_VALUES_PER_FUNC]; - -static struct - { - save_func_t *func; - check_func_t *check; - } -all_funcs[] = - { - { save_static_to_stacked, check_static_to_stacked }, - { save_static_to_fr, check_static_to_fr }, - { save_static_to_br, check_static_to_br }, - { save_static_to_mem, check_static_to_mem }, - { save_static_to_mem2, check_static_to_mem2 }, - { save_static_to_mem3, check_static_to_mem3 }, - { save_static_to_mem4, check_static_to_mem4 }, - { save_static_to_mem5, check_static_to_mem5 }, - { save_static_to_scratch, check_static_to_scratch }, - { save_pr, check_pr }, - { rotate_regs, check_rotate_regs }, - }; - -static unw_word_t -random_word (void) -{ - unw_word_t val = random (); - - if (sizeof (unw_word_t) > 4) - val |= ((unw_word_t) random ()) << 32; - - return val; -} - -void -sighandler (int signal, void *siginfo, void *context) -{ - unsigned long *bsp, *arg1; - save_func_t **arg0; - ucontext_t *uc = context; - -#if defined(__linux) - { - long sof; - int sp; - - if (verbose) - printf ("sighandler: signal %d sp=%p nat=%08lx pr=%lx\n", - signal, &sp, uc->uc_mcontext.sc_nat, uc->uc_mcontext.sc_pr); - sof = uc->uc_mcontext.sc_cfm & 0x7f; - bsp = (unsigned long *) rse_skip_regs (uc->uc_mcontext.sc_ar_bsp, -sof); - } -#elif defined(__hpux) - if (__uc_get_ar (uc, UNW_IA64_AR_BSP - UNW_IA64_AR, &bsp) != 0) - { - panic ("%s: reading of ar.bsp failed, errno=%d", __FUNCTION__, errno); - return; - } -#endif - - flushrs (); - arg0 = (save_func_t **) *bsp; - bsp = (unsigned long *) rse_skip_regs ((uint64_t) bsp, 1); - arg1 = (unsigned long *) *bsp; - - (*arg0[0]) (arg0 + 1, arg1); - - /* skip over the instruction which triggered sighandler() */ -#if defined(__linux) - ++uc->uc_mcontext.sc_ip; -#elif defined(HAVE_SYS_UC_ACCESS_H) - { - unsigned long ip; - - if (__uc_get_ip (uc, &ip) != 0) - { - panic ("%s: reading of ip failed, errno=%d", __FUNCTION__, errno); - return; - } - if (__uc_set_ip (uc, ip) != 0) - { - panic ("%s: writing of ip failed, errno=%d", __FUNCTION__, errno); - return; - } - } -#endif -} - -static void -enable_sighandler (void) -{ - struct sigaction act; - - memset (&act, 0, sizeof (act)); - act.sa_handler = (void (*)(int)) sighandler; - act.sa_flags = SA_SIGINFO | SA_NODEFER; - if (sigaction (SIGSEGV, &act, NULL) < 0) - panic ("sigaction: %s\n", strerror (errno)); -} - -static void -disable_sighandler (void) -{ - struct sigaction act; - - memset (&act, 0, sizeof (act)); - act.sa_handler = SIG_DFL; - act.sa_flags = SA_SIGINFO | SA_NODEFER; - if (sigaction (SIGSEGV, &act, NULL) < 0) - panic ("sigaction: %s\n", strerror (errno)); -} - -static unw_word_t * -check_static_to_stacked (unw_cursor_t *c, unw_word_t *vals) -{ - unw_word_t r[4]; - unw_word_t nat[4]; - int i, ret; - - if (verbose) - printf (" %s()\n", __FUNCTION__); - - vals -= 4; - - for (i = 0; i < 4; ++i) - if ((ret = unw_get_reg (c, UNW_IA64_GR + 4 + i, &r[i])) < 0) - panic ("%s: failed to read register r%d, error=%d\n", - __FUNCTION__, 4 + i, ret); - - for (i = 0; i < 4; ++i) - if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4 + i, &nat[i])) < 0) - panic ("%s: failed to read register nat%d, error=%d\n", - __FUNCTION__, 4 + i, ret); - - for (i = 0; i < 4; ++i) - { - if (verbose) - printf (" r%d = %c%016lx (expected %c%016lx)\n", - 4 + i, nat[i] ? '*' : ' ', r[i], - (vals[i] & 1) ? '*' : ' ', vals[i]); - - if (vals[i] & 1) - { - if (!nat[i]) - panic ("%s: r%d not a NaT!\n", __FUNCTION__, 4 + i); - } - else - { - if (nat[i]) - panic ("%s: r%d a NaT!\n", __FUNCTION__, 4 + i); - if (r[i] != vals[i]) - panic ("%s: r%d=%lx instead of %lx!\n", - __FUNCTION__, 4 + i, r[i], vals[i]); - } - } - return vals; -} - -static unw_word_t * -check_static_to_fr (unw_cursor_t *c, unw_word_t *vals) -{ - unw_word_t r4; - unw_word_t nat4; - int ret; - - if (verbose) - printf (" %s()\n", __FUNCTION__); - - vals -= 1; - - if ((ret = unw_get_reg (c, UNW_IA64_GR + 4, &r4)) < 0) - panic ("%s: failed to read register r4, error=%d\n", __FUNCTION__, ret); - - if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4, &nat4)) < 0) - panic ("%s: failed to read register nat4, error=%d\n", __FUNCTION__, ret); - - if (verbose) - printf (" r4 = %c%016lx (expected %c%016lx)\n", - nat4 ? '*' : ' ', r4, (vals[0] & 1) ? '*' : ' ', vals[0]); - - if (vals[0] & 1) - { - if (!nat4) - panic ("%s: r4 not a NaT!\n", __FUNCTION__); - } - else - { - if (nat4) - panic ("%s: r4 a NaT!\n", __FUNCTION__); - if (r4 != vals[0]) - panic ("%s: r4=%lx instead of %lx!\n", __FUNCTION__, r4, vals[0]); - } - return vals; -} - -static unw_word_t * -check_static_to_br (unw_cursor_t *c, unw_word_t *vals) -{ - unw_word_t r4, nat4; - int ret; - - if (verbose) - printf (" %s()\n", __FUNCTION__); - - vals -= 1; - - if ((ret = unw_get_reg (c, UNW_IA64_GR + 4, &r4)) < 0) - panic ("%s: failed to read register r4, error=%d\n", __FUNCTION__, ret); - - if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4, &nat4)) < 0) - panic ("%s: failed to read register nat4, error=%d\n", __FUNCTION__, ret); - - if (verbose) - printf (" r4 = %c%016lx (expected %c%016lx)\n", - nat4 ? '*' : ' ', r4, (vals[0] & 1) ? '*' : ' ', vals[0]); - - if (vals[0] & 1) - { - if (!nat4) - panic ("%s: r4 not a NaT!\n", __FUNCTION__); - } - else - { - if (nat4) - panic ("%s: r4 a NaT!\n", __FUNCTION__); - if (r4 != vals[0]) - panic ("%s: r4=%lx instead of %lx!\n", __FUNCTION__, r4, vals[0]); - } - return vals; -} - -static unw_word_t * -check_static_to_mem (unw_cursor_t *c, unw_word_t *vals) -{ - unw_word_t r5, nat5; - int ret; - - if (verbose) - printf (" %s()\n", __FUNCTION__); - - vals -= 1; - - if ((ret = unw_get_reg (c, UNW_IA64_GR + 5, &r5)) < 0) - panic ("%s: failed to read register r5, error=%d\n", __FUNCTION__, ret); - - if ((ret = unw_get_reg (c, UNW_IA64_NAT + 5, &nat5)) < 0) - panic ("%s: failed to read register nat5, error=%d\n", __FUNCTION__, ret); - - if (verbose) - printf (" r5 = %c%016lx (expected %c%016lx)\n", - nat5 ? '*' : ' ', r5, (vals[0] & 1) ? '*' : ' ', vals[0]); - - if (vals[0] & 1) - { - if (!nat5) - panic ("%s: r5 not a NaT!\n", __FUNCTION__); - } - else - { - if (nat5) - panic ("%s: r5 a NaT!\n", __FUNCTION__); - if (r5 != vals[0]) - panic ("%s: r5=%lx instead of %lx!\n", __FUNCTION__, r5, vals[0]); - } - return vals; -} - -static unw_word_t * -check_static_to_memN (unw_cursor_t *c, unw_word_t *vals, const char *func) -{ - unw_word_t r6, nat6; - int ret; - - if (verbose) - printf (" %s()\n", func); - - vals -= 1; - - if ((ret = unw_get_reg (c, UNW_IA64_GR + 6, &r6)) < 0) - panic ("%s: failed to read register r6, error=%d\n", __FUNCTION__, ret); - - if ((ret = unw_get_reg (c, UNW_IA64_NAT + 6, &nat6)) < 0) - panic ("%s: failed to read register nat6, error=%d\n", __FUNCTION__, ret); - - if (verbose) - printf (" r6 = %c%016lx (expected %c%016lx)\n", - nat6 ? '*' : ' ', r6, (vals[0] & 1) ? '*' : ' ', vals[0]); - - if (vals[0] & 1) - { - if (!nat6) - panic ("%s: r6 not a NaT!\n", __FUNCTION__); - } - else - { - if (nat6) - panic ("%s: r6 a NaT!\n", __FUNCTION__); - if (r6 != vals[0]) - panic ("%s: r6=%lx instead of %lx!\n", __FUNCTION__, r6, vals[0]); - } - return vals; -} - -static unw_word_t * -check_static_to_mem2 (unw_cursor_t *c, unw_word_t *vals) -{ - return check_static_to_memN (c, vals, __FUNCTION__); -} - -static unw_word_t * -check_static_to_mem3 (unw_cursor_t *c, unw_word_t *vals) -{ - return check_static_to_memN (c, vals, __FUNCTION__); -} - -static unw_word_t * -check_static_to_mem4 (unw_cursor_t *c, unw_word_t *vals) -{ - return check_static_to_memN (c, vals, __FUNCTION__); -} - -static unw_word_t * -check_static_to_mem5 (unw_cursor_t *c, unw_word_t *vals) -{ - return check_static_to_memN (c, vals, __FUNCTION__); -} - -static unw_word_t * -check_static_to_scratch (unw_cursor_t *c, unw_word_t *vals) -{ - unw_word_t r[4], nat[4], ec, expected; - unw_fpreg_t f4; - int i, ret; - - if (verbose) - printf (" %s()\n", __FUNCTION__); - - vals -= 4; - - while (!unw_is_signal_frame (c)) - if ((ret = unw_step (c)) < 0) - panic ("%s: unw_step (ret=%d): Failed to skip over signal handler\n", - __FUNCTION__, ret); - if ((ret = unw_step (c)) < 0) - panic ("%s: unw_step (ret=%d): Failed to skip over signal handler\n", - __FUNCTION__, ret); - - for (i = 0; i < 4; ++i) - if ((ret = unw_get_reg (c, UNW_IA64_GR + 4 + i, &r[i])) < 0) - panic ("%s: failed to read register r%d, error=%d\n", - __FUNCTION__, 4 + i, ret); - - for (i = 0; i < 4; ++i) - if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4 + i, &nat[i])) < 0) - panic ("%s: failed to read register nat%d, error=%d\n", - __FUNCTION__, 4 + i, ret); - - for (i = 0; i < 4; ++i) - { - if (verbose) - printf (" r%d = %c%016lx (expected %c%016lx)\n", - 4 + i, nat[i] ? '*' : ' ', r[i], - (vals[i] & 1) ? '*' : ' ', vals[i]); - - if (vals[i] & 1) - { - if (!nat[i]) - panic ("%s: r%d not a NaT!\n", __FUNCTION__, 4 + i); - } - else - { - if (nat[i]) - panic ("%s: r%d a NaT!\n", __FUNCTION__, 4 + i); - if (r[i] != vals[i]) - panic ("%s: r%d=%lx instead of %lx!\n", - __FUNCTION__, 4 + i, r[i], vals[i]); - } - } - if ((ret = unw_get_fpreg (c, UNW_IA64_FR + 4, &f4)) < 0) - panic ("%s: failed to read f4, error=%d\n", __FUNCTION__, ret); - - /* These tests are little-endian specific: */ - if (nat[0]) - { - if (f4.raw.bits[0] != 0 || f4.raw.bits[1] != 0x1fffe) - panic ("%s: f4=%016lx.%016lx instead of NaTVal!\n", - __FUNCTION__, f4.raw.bits[1], f4.raw.bits[0]); - } - else - { - if (f4.raw.bits[0] != r[0] || f4.raw.bits[1] != 0x1003e) - panic ("%s: f4=%016lx.%016lx instead of %lx!\n", - __FUNCTION__, f4.raw.bits[1], f4.raw.bits[0], r[0]); - } - - if ((unw_get_reg (c, UNW_IA64_AR_EC, &ec)) < 0) - panic ("%s: failed to read register ar.ec, error=%d\n", __FUNCTION__, ret); - - expected = vals[0] & 0x3f; - if (ec != expected) - panic ("%s: ar.ec=%016lx instead of %016lx!\n", - __FUNCTION__, ec, expected); - - return vals; -} - -static unw_word_t * -check_pr (unw_cursor_t *c, unw_word_t *vals) -{ - unw_word_t pr, expected; - int ret; -# define BIT(n) ((unw_word_t) 1 << (n)) -# define DONTCARE (BIT( 6) | BIT( 7) | BIT( 8) | BIT( 9) | BIT(10) \ - | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15)) - - if (verbose) - printf (" %s()\n", __FUNCTION__); - - vals -= 1; - - if ((ret = unw_get_reg (c, UNW_IA64_PR, &pr)) < 0) - panic ("%s: failed to read register pr, error=%d\n", __FUNCTION__, ret); - - pr &= ~DONTCARE; - expected = (vals[0] & ~DONTCARE) | 1; - - if (verbose) - printf (" pr = %016lx (expected %016lx)\n", pr, expected); - - if (pr != expected) - panic ("%s: pr=%lx instead of %lx!\n", __FUNCTION__, pr, expected); - - if ((ret = unw_set_reg (c, UNW_IA64_PR, vals[0])) < 0) - panic ("%s: failed to write register pr, error=%d\n", __FUNCTION__, ret); - - if ((ret = unw_get_reg (c, UNW_IA64_PR, &pr)) < 0) - panic ("%s: failed to read register pr, error=%d\n", __FUNCTION__, ret); - - if (pr != vals[0]) - panic ("%s: secondary pr=%lx instead of %lx!\n", - __FUNCTION__, pr, vals[0]); - return vals; -} - -static unw_word_t * -check_rotate_regs (unw_cursor_t *c, unw_word_t *vals) -{ - if (verbose) - printf (" %s()\n", __FUNCTION__); - return check_pr (c, vals - 1); -} - -static void -start_checks (void *funcs, unsigned long *vals) -{ - unw_context_t uc; - unw_cursor_t c; - int i, ret; - - disable_sighandler (); - - unw_getcontext (&uc); - - if ((ret = unw_init_local (&c, &uc)) < 0) - panic ("%s: unw_init_local (ret=%d)\n", __FUNCTION__, ret); - - if ((ret = unw_step (&c)) < 0) - panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret); - - for (i = 0; i < num_checks; ++i) - { - vals = (*checks[num_checks - 1 - i]) (&c, vals); - - if ((ret = unw_step (&c)) < 0) - panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret); - } -} - -static void -run_check (int test) -{ - int index, i; - - if (test == 1) - /* Make first test always go the full depth... */ - num_checks = MAX_CHECKS; - else - num_checks = (random () % MAX_CHECKS) + 1; - - for (i = 0; i < num_checks * MAX_VALUES_PER_FUNC; ++i) - values[i] = random_word (); - - for (i = 0; i < num_checks; ++i) - { - if (test == 1) - /* Make first test once go through each test... */ - index = i % (int) ARRAY_SIZE (all_funcs); - else - index = random () % (int) ARRAY_SIZE (all_funcs); - funcs[i] = all_funcs[index].func; - checks[i] = all_funcs[index].check; - } - - funcs[num_checks] = start_checks; - - enable_sighandler (); - (*funcs[0]) (funcs + 1, values); -} - -int -main (int argc, char **argv) -{ - int i; - - if (argc > 1) - verbose = 1; - - for (i = 0; i < NUM_RUNS; ++i) - { - if (verbose) - printf ("Run %d\n", i + 1); - run_check (i + 1); - } - - if (nerrors > 0) - { - fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); - exit (-1); - } - if (verbose) - printf ("SUCCESS.\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-rbs.c b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-rbs.c deleted file mode 100644 index 2181e70fd306c1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-rbs.c +++ /dev/null @@ -1,193 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 tests corner-cases of unwinding across multiple stacks. - In particular, it verifies that the extreme case with a frame of 96 - stacked registers that are all backed up by separate stacks works - as expected. */ - -#include -#include - -#include -#include "compiler.h" - -#include "ia64-test-rbs.h" - -#define panic(args...) \ - do { fprintf (stderr, args); ++nerrors; return -9999; } while (0) - -/* The loadrs field in ar.rsc is 14 bits wide, which limits all ia64 - implementations to at most 2048 physical stacked registers - (actually, slightly less than that, because loadrs also counts RNaT - slots). Since we can dirty 93 stacked registers per recursion, we - need to recurse RECURSION_DEPTH times to ensure all physical - stacked registers are in use. */ -#define MAX_PHYS_STACKED 2048 -#define RECURSION_DEPTH ((MAX_PHYS_STACKED + 92) / 93) - -typedef int spill_func_t (long iteration, int (*next_func[])()); - -extern int loadup (long iteration, int *values, int (*next_func[])()); -extern char resumption_point_label; - -#define DCL(n) \ - extern int rbs_spill_##n (long iteration, int (*next_func[])()) - DCL(2); DCL(3); DCL(4); DCL(5); DCL(6); DCL(7); - DCL(8); DCL(9); DCL(10); DCL(11); DCL(12); DCL(13); DCL(14); DCL(15); - DCL(16); DCL(17); DCL(18); DCL(19); DCL(20); DCL(21); DCL(22); DCL(23); - DCL(24); DCL(25); DCL(26); DCL(27); DCL(28); DCL(29); DCL(30); DCL(31); - DCL(32); DCL(33); DCL(34); DCL(35); DCL(36); DCL(37); DCL(38); DCL(39); - DCL(40); DCL(41); DCL(42); DCL(43); DCL(44); DCL(45); DCL(46); DCL(47); - DCL(48); DCL(49); DCL(50); DCL(51); DCL(52); DCL(53); DCL(54); DCL(55); - DCL(56); DCL(57); DCL(58); DCL(59); DCL(60); DCL(61); DCL(62); DCL(63); - DCL(64); DCL(65); DCL(66); DCL(67); DCL(68); DCL(69); DCL(70); DCL(71); - DCL(72); DCL(73); DCL(74); DCL(75); DCL(76); DCL(77); DCL(78); DCL(79); - DCL(80); DCL(81); DCL(82); DCL(83); DCL(84); DCL(85); DCL(86); DCL(87); - DCL(88); DCL(89); DCL(90); DCL(91); DCL(92); DCL(93); DCL(94); - -#define SPL(n) rbs_spill_##n -spill_func_t *spill_funcs[] = - { - SPL(2), SPL(3), SPL(4), SPL(5), SPL(6), SPL(7), - SPL(8), SPL(9), SPL(10), SPL(11), SPL(12), SPL(13), SPL(14), SPL(15), - SPL(16), SPL(17), SPL(18), SPL(19), SPL(20), SPL(21), SPL(22), SPL(23), - SPL(24), SPL(25), SPL(26), SPL(27), SPL(28), SPL(29), SPL(30), SPL(31), - SPL(32), SPL(33), SPL(34), SPL(35), SPL(36), SPL(37), SPL(38), SPL(39), - SPL(40), SPL(41), SPL(42), SPL(43), SPL(44), SPL(45), SPL(46), SPL(47), - SPL(48), SPL(49), SPL(50), SPL(51), SPL(52), SPL(53), SPL(54), SPL(55), - SPL(56), SPL(57), SPL(58), SPL(59), SPL(60), SPL(61), SPL(62), SPL(63), - SPL(64), SPL(65), SPL(66), SPL(67), SPL(68), SPL(69), SPL(70), SPL(71), - SPL(72), SPL(73), SPL(74), SPL(75), SPL(76), SPL(77), SPL(78), SPL(79), - SPL(80), SPL(81), SPL(82), SPL(83), SPL(84), SPL(85), SPL(86), SPL(87), - SPL(88), SPL(89), SPL(90), SPL(91), SPL(92), SPL(93), SPL(94) - }; - -static int verbose; -static int nerrors; -static int unwind_count; - -static int -unwind_and_resume (long iteration, int (*next_func[])()) -{ - unw_context_t uc; - unw_cursor_t c; - unw_word_t ip; - int i, ret; - - if (verbose) - printf (" %s(iteration=%ld, next_func=%p)\n", - __FUNCTION__, iteration, next_func); - - unw_getcontext (&uc); - if ((ret = unw_init_local (&c, &uc)) < 0) - panic ("unw_init_local (ret=%d)", ret); - - for (i = 0; i < unwind_count; ++i) - if ((ret = unw_step (&c)) < 0) - panic ("unw_step (ret=%d)", ret); - - if (unw_get_reg (&c, UNW_REG_IP, &ip) < 0 - || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) &resumption_point_label) < 0 - || unw_set_reg (&c, UNW_REG_EH + 0, 0) /* ret val */ - || unw_set_reg (&c, UNW_REG_EH + 1, ip)) - panic ("failed to redirect to resumption_point\n"); - - if (verbose) - { - unw_word_t bsp; - if (unw_get_reg (&c, UNW_IA64_BSP, &bsp) < 0) - panic ("unw_get_reg() failed\n"); - printf (" bsp=%lx, old ip=%lx, new ip=%p\n", bsp, - ip, &resumption_point_label); - } - - ret = unw_resume (&c); - panic ("unw_resume() returned (ret=%d)!!\n", ret); - return 0; -} - -static int -run_check (int test) -{ - int nfuncs, nspills, n, ret, i, reg_values[88]; - spill_func_t *func[NSTACKS + 1]; - - /* First, generate a set of 88 random values which loadup() will load - into loc2-loc89 (r37-r124). */ - for (i = 0; i < (int) ARRAY_SIZE (reg_values); ++i) - { - reg_values[i] = random (); - /* Generate NaTs with a reasonably probability (1/16th): */ - if (reg_values[i] < 0x10000000) - reg_values[i] = 0; - } - - nspills = 0; - nfuncs = 0; - do - { - n = random () % (int) ARRAY_SIZE (spill_funcs); - func[nfuncs++] = spill_funcs[n]; - nspills += 2 + n; - } - while (nspills < 128); - func[nfuncs++] = unwind_and_resume; - - unwind_count = 1 + (random () % (nfuncs + RECURSION_DEPTH - 1)); - - if (verbose) - printf ("test%d: nfuncs=%d, unwind_count=%d\n", - test, nfuncs, unwind_count); - - ret = loadup (RECURSION_DEPTH, reg_values, func); - if (ret < 0) - panic ("test%d: load() returned %d\n", test, ret); - else if (ret != RECURSION_DEPTH + nfuncs - unwind_count) - panic ("test%d: resumed wrong frame: expected %d, got %d\n", - test, RECURSION_DEPTH + nfuncs - unwind_count, ret); - return 0; -} - -int -main (int argc, char **argv) -{ - int i; - - if (argc > 1) - verbose = 1; - - for (i = 0; i < 100000; ++i) - run_check (i + 1); - - if (nerrors > 0) - { - fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); - exit (-1); - } - if (verbose) - printf ("SUCCESS.\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-readonly.c b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-readonly.c deleted file mode 100644 index 25f0506102d43c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-readonly.c +++ /dev/null @@ -1,89 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 verifies that read-only registers cannot be written to. */ - -#include -#include -#include -#include - -#include - -#define panic(args...) \ - do { printf (args); ++nerrors; } while (0) - -static int verbose; -static int nerrors; - -extern void test_func (void (*) (void)); - -void -checker (void) -{ - unw_fpreg_t fpval; - unw_context_t uc; - unw_cursor_t c; - int ret; - - fpval.raw.bits[0] = 100; - fpval.raw.bits[1] = 101; - - unw_getcontext (&uc); - - if ((ret = unw_init_local (&c, &uc)) < 0) - panic ("%s: unw_init_local (ret=%d)\n", __FUNCTION__, ret); - - if ((ret = unw_step (&c)) < 0) - panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret); - - if ((ret = unw_step (&c)) < 0) - panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret); - - if ((ret = unw_set_reg (&c, UNW_IA64_IP, 99)) != -UNW_EREADONLYREG) - panic ("%s: unw_set_reg (ip) returned %d instead of %d\n", - __FUNCTION__, ret, -UNW_EREADONLYREG); - if ((ret = unw_set_reg (&c, UNW_IA64_AR_LC, 99)) != -UNW_EREADONLYREG) - panic ("%s: unw_set_reg (ar.lc) returned %d instead of %d\n", - __FUNCTION__, ret, -UNW_EREADONLYREG); -} - -int -main (int argc, char **argv) -{ - if (argc > 1) - verbose = 1; - - test_func (checker); - - if (nerrors > 0) - { - fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); - exit (-1); - } - if (verbose) - printf ("SUCCESS.\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-stack.c b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-stack.c deleted file mode 100644 index 05874b291f3b3b..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-stack.c +++ /dev/null @@ -1,176 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 tests corner-cases of unwinding across multiple stacks. - In particular, it verifies that the extreme case with a frame of 96 - stacked registers that are all backed up by separate stacks works - as expected. */ - -#include -#include -#include - -#include "ia64-test-stack.h" - -#define panic(args...) \ - { printf (args); ++nerrors; } - -/* The loadrs field in ar.rsc is 14 bits wide, which limits all ia64 - implementations to at most 2048 physical stacked registers - (actually, slightly less than that, because loadrs also counts RNaT - slots). Since we can dirty 95 stacked registers per recursion, we - need to recurse RECURSION_DEPTH times to ensure all physical - stacked registers are in use. */ -#define MAX_PHYS_STACKED 2048 -#define RECURSION_DEPTH ((MAX_PHYS_STACKED + 94) / 95) - -extern void touch_all (unsigned long recursion_depth); -extern void flushrs (void); - -int nerrors; -int verbose; - -void -do_unwind_tests (void) -{ - unw_word_t ip, sp, bsp, v0, v1, v2, v3, n0, n1, n2, n3, cfm, sof, sol, r32; - int ret, reg, i, l; - unw_context_t uc; - unw_cursor_t c; - - if (verbose) - printf ("do_unwind_tests: here we go!\n"); - - /* do a full stack-dump: */ - unw_getcontext (&uc); - unw_init_local (&c, &uc); - i = 0; - do - { - if (verbose) - { - if ((ret = unw_get_reg (&c, UNW_IA64_IP, &ip)) < 0 - || (ret = unw_get_reg (&c, UNW_IA64_SP, &sp)) < 0 - || (ret = unw_get_reg (&c, UNW_IA64_BSP, &bsp)) < 0) - break; - printf ("ip=0x%16lx sp=0x%16lx bsp=0x%16lx\n", ip, sp, bsp); - - for (reg = 32; reg < 128; reg += 4) - { - v0 = v1 = v2 = v3 = 0; - n0 = n1 = n2 = n3 = 0; - (void) - ((ret = unw_get_reg (&c, UNW_IA64_GR + reg, &v0)) < 0 - || (ret = unw_get_reg (&c, UNW_IA64_NAT + reg, &n0)) < 0 - || (ret = unw_get_reg (&c, UNW_IA64_GR + reg + 1, &v1)) < 0 - || (ret = unw_get_reg (&c, UNW_IA64_NAT + reg + 1, &n1)) < 0 - || (ret = unw_get_reg (&c, UNW_IA64_GR + reg + 2, &v2)) < 0 - || (ret = unw_get_reg (&c, UNW_IA64_NAT + reg + 2, &n2)) < 0 - || (ret = unw_get_reg (&c, UNW_IA64_GR + reg + 3, &v3)) < 0 - || (ret = unw_get_reg (&c, UNW_IA64_NAT + reg + 3, &n3)) < 0); - if (reg < 100) - printf (" r%d", reg); - else - printf (" r%d", reg); - printf (" %c%016lx %c%016lx %c%016lx %c%016lx\n", - n0 ? '*' : ' ', v0, n1 ? '*' : ' ', v1, - n2 ? '*' : ' ', v2, n3 ? '*' : ' ', v3); - if (ret < 0) - break; - } - } - - if (i >= 1 && i <= NSTACKS) - { - if ((ret = unw_get_reg (&c, UNW_IA64_CFM, &cfm)) < 0) - break; - sof = cfm & 0x7f; - if (sof != (unw_word_t) (i & 1)) - panic ("\texpected sof=%d, found sof=%lu\n", i - 1, sof); - if (sof == 1) - { - if ((ret = unw_get_reg (&c, UNW_IA64_GR + 32, &r32)) < 0) - break; - if (r32 != (unw_word_t) (i - 1)) - panic ("\texpected r32=%d, found r32=%lu\n", i - 1, r32); - } - } - else if (i > NSTACKS && i <= NSTACKS + RECURSION_DEPTH) - { - if ((ret = unw_get_reg (&c, UNW_IA64_CFM, &cfm)) < 0) - break; - sof = cfm & 0x7f; - sol = (cfm >> 7) & 0x7f; - if (sof != 96) - panic ("\texpected sof=96, found sof=%lu\n", sof); - if (sol != 95) - panic ("\texpected sol=95, found sol=%lu\n", sol); - - for (l = 2; l <= 93; ++l) - { - if ((ret = unw_get_reg (&c, UNW_IA64_GR + 33 + l, &v0)) < 0 - || (ret = unw_get_reg (&c, UNW_IA64_NAT + 33 + l, &n0)) < 0) - break; - switch (l) - { - case 2: case 31: case 73: case 93: - if (!n0) - panic ("\texpected loc%d to be a NaT!\n", l); - break; - - default: - if (n0) - panic ("\tloc%d is unexpectedly a NaT!\n", l); - v1 = ((unw_word_t) (i - NSTACKS) << 32) + l; - if (v0 != v1) - panic ("\tloc%d expected to be %lx, found to be %lx\n", - l, v1, v0); - } - } - } - ++i; - } - while ((ret = unw_step (&c)) > 0); - - if (ret < 0) - panic ("libunwind returned %d\n", ret); -} - -int -main (int argc, char **argv) -{ - if (argc > 1) - ++verbose; - - touch_all (RECURSION_DEPTH); - if (nerrors) - { - printf ("FAILURE: detected %d errors\n", nerrors); - exit (-1); - } - if (verbose) - printf ("SUCCESS\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gperf-simple.c b/src/coreclr/src/pal/src/libunwind/tests/Gperf-simple.c deleted file mode 100644 index e1819182140349..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gperf-simple.c +++ /dev/null @@ -1,264 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include -#include - -#include -#include "compiler.h" - -#include -#include - -#define panic(args...) \ - do { fprintf (stderr, args); exit (-1); } while (0) - -long dummy; - -static long iterations = 10000; -static int maxlevel = 100; - -#define KB 1024 -#define MB (1024*1024) - -static char big[64*MB]; /* should be >> max. cache size */ - -static inline double -gettime (void) -{ - struct timeval tv; - - gettimeofday (&tv, NULL); - return tv.tv_sec + 1e-6*tv.tv_usec; -} - -static int NOINLINE -measure_unwind (int maxlevel, double *step) -{ - double stop, start; - unw_cursor_t cursor; - unw_context_t uc; - int ret, level = 0; - - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - panic ("unw_init_local() failed\n"); - - start = gettime (); - - do - { - ret = unw_step (&cursor); - if (ret < 0) - panic ("unw_step() failed\n"); - ++level; - } - while (ret > 0); - - stop = gettime (); - - if (level <= maxlevel) - panic ("Unwound only %d levels, expected at least %d levels\n", - level, maxlevel); - - *step = (stop - start) / (double) level; - return 0; -} - -static int f1 (int, int, double *); - -static int NOINLINE -g1 (int level, int maxlevel, double *step) -{ - if (level == maxlevel) - return measure_unwind (maxlevel, step); - else - /* defeat last-call/sibcall optimization */ - return f1 (level + 1, maxlevel, step) + level; -} - -static int NOINLINE -f1 (int level, int maxlevel, double *step) -{ - if (level == maxlevel) - return measure_unwind (maxlevel, step); - else - /* defeat last-call/sibcall optimization */ - return g1 (level + 1, maxlevel, step) + level; -} - -static void -doit (const char *label) -{ - double step, min_step, first_step, sum_step; - int i; - - sum_step = first_step = 0.0; - min_step = 1e99; - for (i = 0; i < iterations; ++i) - { - f1 (0, maxlevel, &step); - - sum_step += step; - - if (step < min_step) - min_step = step; - - if (i == 0) - first_step = step; - } - printf ("%s: unw_step : 1st=%9.3f min=%9.3f avg=%9.3f nsec\n", label, - 1e9*first_step, 1e9*min_step, 1e9*sum_step/iterations); -} - -static long -sum (void *buf, size_t size) -{ - long s = 0; - char *cp = buf; - size_t i; - - for (i = 0; i < size; i += 8) - s += cp[i]; - return s; -} - -static void -measure_init (void) -{ -# define N 100 -# define M 10 /* must be at least 2 to get steady-state */ - double stop, start, get_cold, get_warm, init_cold, init_warm, delta; - struct - { - unw_cursor_t c; - char padding[1024]; /* should be > 2 * max. cacheline size */ - } - cursor[N]; - struct - { - unw_context_t uc; - char padding[1024]; /* should be > 2 * max. cacheline size */ - } - uc[N]; - int i, j; - - /* Run each test M times and take the minimum to filter out noise - such dynamic linker resolving overhead, context-switches, - page-in, cache, and TLB effects. */ - - get_cold = 1e99; - for (j = 0; j < M; ++j) - { - dummy += sum (big, sizeof (big)); /* flush the cache */ - for (i = 0; i < N; ++i) - uc[i].padding[511] = i; /* warm up the TLB */ - start = gettime (); - for (i = 0; i < N; ++i) - unw_getcontext (&uc[i].uc); - stop = gettime (); - delta = (stop - start) / N; - if (delta < get_cold) - get_cold = delta; - } - - init_cold = 1e99; - for (j = 0; j < M; ++j) - { - dummy += sum (big, sizeof (big)); /* flush cache */ - for (i = 0; i < N; ++i) - uc[i].padding[511] = i; /* warm up the TLB */ - start = gettime (); - for (i = 0; i < N; ++i) - unw_init_local (&cursor[i].c, &uc[i].uc); - stop = gettime (); - delta = (stop - start) / N; - if (delta < init_cold) - init_cold = delta; - } - - get_warm = 1e99; - for (j = 0; j < M; ++j) - { - start = gettime (); - for (i = 0; i < N; ++i) - unw_getcontext (&uc[0].uc); - stop = gettime (); - delta = (stop - start) / N; - if (delta < get_warm) - get_warm = delta; - } - - init_warm = 1e99; - for (j = 0; j < M; ++j) - { - start = gettime (); - for (i = 0; i < N; ++i) - unw_init_local (&cursor[0].c, &uc[0].uc); - stop = gettime (); - delta = (stop - start) / N; - if (delta < init_warm) - init_warm = delta; - } - - printf ("unw_getcontext : cold avg=%9.3f nsec, warm avg=%9.3f nsec\n", - 1e9 * get_cold, 1e9 * get_warm); - printf ("unw_init_local : cold avg=%9.3f nsec, warm avg=%9.3f nsec\n", - 1e9 * init_cold, 1e9 * init_warm); -} - -int -main (int argc, char **argv) -{ - struct rlimit rlim; - - rlim.rlim_cur = RLIM_INFINITY; - rlim.rlim_max = RLIM_INFINITY; - setrlimit (RLIMIT_STACK, &rlim); - - memset (big, 0xaa, sizeof (big)); - - if (argc > 1) - { - maxlevel = atol (argv[1]); - if (argc > 2) - iterations = atol (argv[2]); - } - - measure_init (); - - doit ("default "); - - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); - doit ("no cache "); - - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); - doit ("global cache "); - - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); - doit ("per-thread cache"); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gperf-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Gperf-trace.c deleted file mode 100644 index 4d24fa5ca86574..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gperf-trace.c +++ /dev/null @@ -1,250 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include -#include - -#include -#include "compiler.h" - -#include -#include - -#define panic(args...) \ - do { fprintf (stderr, args); exit (-1); } while (0) - -long dummy; - -static long iterations = 10000; -static int maxlevel = 100; - -#define KB 1024 -#define MB (1024*1024) - -static char big[64*MB]; /* should be >> max. cache size */ - -static inline double -gettime (void) -{ - struct timeval tv; - - gettimeofday (&tv, NULL); - return tv.tv_sec + 1e-6*tv.tv_usec; -} - -static int NOINLINE -measure_unwind (int maxlevel, double *step) -{ - double stop, start; - int level = 0; - void *buffer[128]; - - start = gettime (); - level = unw_backtrace(buffer, 128); - stop = gettime (); - - if (level <= maxlevel) - panic ("Unwound only %d levels, expected at least %d levels\n", - level, maxlevel); - - *step = (stop - start) / (double) level; - return 0; -} - -static int f1 (int, int, double *); - -static int NOINLINE -g1 (int level, int maxlevel, double *step) -{ - if (level == maxlevel) - return measure_unwind (maxlevel, step); - else - /* defeat last-call/sibcall optimization */ - return f1 (level + 1, maxlevel, step) + level; -} - -static int NOINLINE -f1 (int level, int maxlevel, double *step) -{ - if (level == maxlevel) - return measure_unwind (maxlevel, step); - else - /* defeat last-call/sibcall optimization */ - return g1 (level + 1, maxlevel, step) + level; -} - -static void -doit (const char *label) -{ - double step, min_step, first_step, sum_step; - int i; - - sum_step = first_step = 0.0; - min_step = 1e99; - for (i = 0; i < iterations; ++i) - { - f1 (0, maxlevel, &step); - - sum_step += step; - - if (step < min_step) - min_step = step; - - if (i == 0) - first_step = step; - } - printf ("%s: unw_step : 1st=%9.3f min=%9.3f avg=%9.3f nsec\n", label, - 1e9*first_step, 1e9*min_step, 1e9*sum_step/iterations); -} - -static long -sum (void *buf, size_t size) -{ - long s = 0; - char *cp = buf; - size_t i; - - for (i = 0; i < size; i += 8) - s += cp[i]; - return s; -} - -static void -measure_init (void) -{ -# define N 100 -# define M 10 /* must be at least 2 to get steady-state */ - double stop, start, get_cold, get_warm, init_cold, init_warm, delta; - struct - { - unw_cursor_t c; - char padding[1024]; /* should be > 2 * max. cacheline size */ - } - cursor[N]; - struct - { - unw_context_t uc; - char padding[1024]; /* should be > 2 * max. cacheline size */ - } - uc[N]; - int i, j; - - /* Run each test M times and take the minimum to filter out noise - such dynamic linker resolving overhead, context-switches, - page-in, cache, and TLB effects. */ - - get_cold = 1e99; - for (j = 0; j < M; ++j) - { - dummy += sum (big, sizeof (big)); /* flush the cache */ - for (i = 0; i < N; ++i) - uc[i].padding[511] = i; /* warm up the TLB */ - start = gettime (); - for (i = 0; i < N; ++i) - unw_getcontext (&uc[i].uc); - stop = gettime (); - delta = (stop - start) / N; - if (delta < get_cold) - get_cold = delta; - } - - init_cold = 1e99; - for (j = 0; j < M; ++j) - { - dummy += sum (big, sizeof (big)); /* flush cache */ - for (i = 0; i < N; ++i) - uc[i].padding[511] = i; /* warm up the TLB */ - start = gettime (); - for (i = 0; i < N; ++i) - unw_init_local (&cursor[i].c, &uc[i].uc); - stop = gettime (); - delta = (stop - start) / N; - if (delta < init_cold) - init_cold = delta; - } - - get_warm = 1e99; - for (j = 0; j < M; ++j) - { - start = gettime (); - for (i = 0; i < N; ++i) - unw_getcontext (&uc[0].uc); - stop = gettime (); - delta = (stop - start) / N; - if (delta < get_warm) - get_warm = delta; - } - - init_warm = 1e99; - for (j = 0; j < M; ++j) - { - start = gettime (); - for (i = 0; i < N; ++i) - unw_init_local (&cursor[0].c, &uc[0].uc); - stop = gettime (); - delta = (stop - start) / N; - if (delta < init_warm) - init_warm = delta; - } - - printf ("unw_getcontext : cold avg=%9.3f nsec, warm avg=%9.3f nsec\n", - 1e9 * get_cold, 1e9 * get_warm); - printf ("unw_init_local : cold avg=%9.3f nsec, warm avg=%9.3f nsec\n", - 1e9 * init_cold, 1e9 * init_warm); -} - -int -main (int argc, char **argv) -{ - struct rlimit rlim; - - rlim.rlim_cur = RLIM_INFINITY; - rlim.rlim_max = RLIM_INFINITY; - setrlimit (RLIMIT_STACK, &rlim); - - memset (big, 0xaa, sizeof (big)); - - if (argc > 1) - { - maxlevel = atol (argv[1]); - if (argc > 2) - iterations = atol (argv[2]); - } - - measure_init (); - - doit ("default "); - - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); - doit ("no cache "); - - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); - doit ("global cache "); - - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); - doit ("per-thread cache"); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c deleted file mode 100644 index beae2a3ccd9b94..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c +++ /dev/null @@ -1,263 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "compiler.h" - -#include -#if HAVE_EXECINFO_H -# include -#else - extern int backtrace (void **, int); -#endif -#include -#include -#include -#include -#include -#include -#include - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -#define SIG_STACK_SIZE 0x100000 - -int verbose; -int num_errors; - -/* These variables are global because they - * cause the signal stack to overflow */ -char buf[512], name[256]; -unw_cursor_t cursor; -unw_context_t uc; - -static void -do_backtrace (void) -{ - unw_word_t ip, sp, off; - unw_proc_info_t pi; - int ret; - - if (verbose) - printf ("\texplicit backtrace:\n"); - - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - panic ("unw_init_local failed!\n"); - - do - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - unw_get_reg (&cursor, UNW_REG_SP, &sp); - buf[0] = '\0'; - if (unw_get_proc_name (&cursor, name, sizeof (name), &off) == 0) - { - if (off) - snprintf (buf, sizeof (buf), "<%s+0x%lx>", name, (long) off); - else - snprintf (buf, sizeof (buf), "<%s>", name); - } - if (verbose) - { - printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); - - if (unw_get_proc_info (&cursor, &pi) == 0) - { - printf ("\tproc=0x%lx-0x%lx\n\thandler=0x%lx lsda=0x%lx gp=0x%lx", - (long) pi.start_ip, (long) pi.end_ip, - (long) pi.handler, (long) pi.lsda, (long) pi.gp); - } - -#if UNW_TARGET_IA64 - { - unw_word_t bsp; - - unw_get_reg (&cursor, UNW_IA64_BSP, &bsp); - printf (" bsp=%lx", bsp); - } -#endif - printf ("\n"); - } - - ret = unw_step (&cursor); - if (ret < 0) - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - printf ("FAILURE: unw_step() returned %d for ip=%lx\n", - ret, (long) ip); - ++num_errors; - } - } - while (ret > 0); - - { - void *buffer[20]; - int i, n; - - if (verbose) - printf ("\n\tvia backtrace():\n"); - n = backtrace (buffer, 20); - if (verbose) - for (i = 0; i < n; ++i) - printf ("[%d] ip=%p\n", i, buffer[i]); - } -} - -void -foo (long val UNUSED) -{ - do_backtrace (); -} - -void -bar (long v) -{ - extern long f (long); - int arr[v]; - - /* This is a vain attempt to use up lots of registers to force - the frame-chain info to be saved on the memory stack on ia64. - It happens to work with gcc v3.3.4 and gcc v3.4.1 but perhaps - not with any other compiler. */ - foo (f (arr[0]) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + f (v)) - )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) - ))))))))))))))))))))))))))))))))))))))))))))))))))))))); -} - -void -sighandler (int signal, void *siginfo UNUSED, void *context) -{ - ucontext_t *uc UNUSED; - int sp; - - uc = context; - - if (verbose) - { - printf ("sighandler: got signal %d, sp=%p", signal, &sp); -#if UNW_TARGET_IA64 -# if defined(__linux__) - printf (" @ %lx", uc->uc_mcontext.sc_ip); -# else - { - uint16_t reason; - uint64_t ip; - - __uc_get_reason (uc, &reason); - __uc_get_ip (uc, &ip); - printf (" @ %lx (reason=%d)", ip, reason); - } -# endif -#elif UNW_TARGET_X86 -#if defined __linux__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]); -#elif defined __FreeBSD__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); -#endif -#elif UNW_TARGET_X86_64 -#if defined __linux__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); -#elif defined __FreeBSD__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); -#endif -#endif - printf ("\n"); - } - do_backtrace(); -} - -int -main (int argc, char **argv UNUSED) -{ - struct sigaction act; - stack_t stk; - - verbose = (argc > 1); - - if (verbose) - printf ("Normal backtrace:\n"); - - bar (1); - - memset (&act, 0, sizeof (act)); - act.sa_handler = (void (*)(int)) sighandler; - act.sa_flags = SA_SIGINFO; - if (sigaction (SIGTERM, &act, NULL) < 0) - panic ("sigaction: %s\n", strerror (errno)); - - if (verbose) - printf ("\nBacktrace across signal handler:\n"); - kill (getpid (), SIGTERM); - - if (verbose) - printf ("\nBacktrace across signal handler on alternate stack:\n"); - stk.ss_sp = malloc (SIG_STACK_SIZE); - if (!stk.ss_sp) - panic ("failed to allocate %u bytes\n", SIG_STACK_SIZE); - stk.ss_size = SIG_STACK_SIZE; - stk.ss_flags = 0; - if (sigaltstack (&stk, NULL) < 0) - panic ("sigaltstack: %s\n", strerror (errno)); - - memset (&act, 0, sizeof (act)); - act.sa_handler = (void (*)(int)) sighandler; - act.sa_flags = SA_ONSTACK | SA_SIGINFO; - if (sigaction (SIGTERM, &act, NULL) < 0) - panic ("sigaction: %s\n", strerror (errno)); - kill (getpid (), SIGTERM); - - if (num_errors > 0) - { - fprintf (stderr, "FAILURE: detected %d errors\n", num_errors); - exit (-1); - } - if (verbose) - printf ("SUCCESS.\n"); - - signal (SIGTERM, SIG_DFL); - stk.ss_flags = SS_DISABLE; - sigaltstack (&stk, NULL); - free (stk.ss_sp); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-concurrent.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-concurrent.c deleted file mode 100644 index 6f3447fd844da1..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-concurrent.c +++ /dev/null @@ -1,136 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* Verify that multi-threaded concurrent unwinding works as expected. */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "compiler.h" - -#include -#include -#include -#include -#include -#include -#include - -#define NTHREADS 128 - -#define panic(args...) \ - do { fprintf (stderr, args); ++nerrors; } while (0) - -int verbose; -int nerrors; -int got_usr1, got_usr2; -char *sigusr1_sp; - -void -handler (int sig UNUSED) -{ - unw_word_t ip; - unw_context_t uc; - unw_cursor_t c; - int ret; - - unw_getcontext (&uc); - unw_init_local (&c, &uc); - do - { - unw_get_reg (&c, UNW_REG_IP, &ip); - if (verbose) - printf ("%lx: IP=%lx\n", (long) pthread_self (), (unsigned long) ip); - } - while ((ret = unw_step (&c)) > 0); - - if (ret < 0) - panic ("unw_step() returned %d\n", ret); -} - -void * -worker (void *arg UNUSED) -{ - signal (SIGUSR1, handler); - - if (verbose) - printf ("sending SIGUSR1\n"); - pthread_kill (pthread_self (), SIGUSR1); - return NULL; -} - -static void -doit (void) -{ - pthread_t th[NTHREADS]; - pthread_attr_t attr; - int i; - - pthread_attr_init (&attr); - pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN + 64*1024); - - for (i = 0; i < NTHREADS; ++i) - if (pthread_create (th + i, &attr, worker, NULL)) - { - fprintf (stderr, "FAILURE: Failed to create %u threads " - "(after %u threads)\n", - NTHREADS, i); - exit (-1); - } - - for (i = 0; i < NTHREADS; ++i) - pthread_join (th[i], NULL); -} - -int -main (int argc, char **argv UNUSED) -{ - if (argc > 1) - verbose = 1; - - if (verbose) - printf ("Caching: none\n"); - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); - doit (); - - if (verbose) - printf ("Caching: global\n"); - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); - doit (); - - if (verbose) - printf ("Caching: per-thread\n"); - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); - doit (); - - if (nerrors) - { - fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); - exit (-1); - } - - if (verbose) - printf ("SUCCESS\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-dyn1.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-dyn1.c deleted file mode 100644 index bc7dc9cf7feb93..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-dyn1.c +++ /dev/null @@ -1,223 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 tests dynamic code-generation via function-cloning. */ - -#include "flush-cache.h" - -#include "compiler.h" - -#include -#include -#include -#include -#include -#include -#include - -#if UNW_TARGET_ARM -#define MAX_FUNC_SIZE 96 /* FIXME: arch/compiler dependent */ -#else -#define MAX_FUNC_SIZE 2048 /* max. size of cloned function */ -#endif - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -typedef void (*template_t) (int, void (*)(), - int (*)(const char *, ...), const char *, - const char **); - -int verbose; - -static const char *strarr[] = - { - "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x", NULL - }; - -#ifdef __ia64__ -struct fdesc - { - long code; - long gp; - }; -# define get_fdesc(fdesc,func) (fdesc = *(struct fdesc *) &(func)) -# define get_funcp(fdesc) ((template_t) &(fdesc)) -# define get_gp(fdesc) ((fdesc).gp) -#elif __arm__ -struct fdesc - { - long code; - long is_thumb; - }; -/* Workaround GCC bug: https://bugs.launchpad.net/gcc-linaro/+bug/721531 */ -# define get_fdesc(fdesc,func) ({long tmp = (long) &(func); \ - (fdesc).code = (long) &(func) & ~0x1; \ - (fdesc).is_thumb = tmp & 0x1;}) -/*# define get_fdesc(fdesc,func) ({(fdesc).code = (long) &(func) & ~0x1; \ - (fdesc).is_thumb = (long) &(func) & 0x1;})*/ -# define get_funcp(fdesc) ((template_t) ((fdesc).code | (fdesc).is_thumb)) -# define get_gp(fdesc) (0) -#else -struct fdesc - { - long code; - }; -# define get_fdesc(fdesc,func) (fdesc.code = (long) &(func)) -# define get_funcp(fdesc) ((template_t) (fdesc).code) -# define get_gp(fdesc) (0) -#endif - -void -template (int i, template_t self, - int (*printer)(const char *, ...), const char *fmt, const char **arr) -{ - (*printer) (fmt, arr[11 - i][0], arr[11 - i] + 1); - if (i > 0) - (*self) (i - 1, self, printer, fmt, arr); -} - -static void -sighandler (int signal) -{ - unw_cursor_t cursor; - char name[128], off[32]; - unw_word_t ip, offset; - unw_context_t uc; - int count; - - if (verbose) - printf ("caught signal %d\n", signal); - - unw_getcontext (&uc); - unw_init_local (&cursor, &uc); - - count = 0; - while (!unw_is_signal_frame (&cursor)) - { - if (unw_step (&cursor) < 0) - panic ("failed to find signal frame!\n"); - - if (count++ > 20) - { - panic ("Too many steps to the signal frame (%d)\n", count); - break; - } - } - unw_step (&cursor); - - count = 0; - do - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - name[0] = '\0'; - off[0] = '\0'; - if (unw_get_proc_name (&cursor, name, sizeof (name), &offset) == 0 - && offset > 0) - snprintf (off, sizeof (off), "+0x%lx", (long) offset); - if (verbose) - printf ("ip = %lx <%s%s>\n", (long) ip, name, off); - ++count; - - if (count > 20) - { - panic ("Too many steps (%d)\n", count); - break; - } - - } - while (unw_step (&cursor) > 0); - - if (count != 13) - panic ("FAILURE: expected 13, not %d frames below signal frame\n", count); - - if (verbose) - printf ("SUCCESS\n"); - exit (0); -} - -int -dev_null (const char *format UNUSED, ...) -{ - return 0; -} - -int -main (int argc, char *argv[] UNUSED) -{ - unw_dyn_region_info_t *region; - unw_dyn_info_t di; - struct fdesc fdesc; - template_t funcp; - void *mem; - - if (argc > 1) - ++verbose; - - mem = malloc (getpagesize ()); - - get_fdesc (fdesc, template); - - if (verbose) - printf ("old code @ %p, new code @ %p\n", (void *) fdesc.code, mem); - - memcpy (mem, (void *) fdesc.code, MAX_FUNC_SIZE); - mprotect ((void *) ((long) mem & ~(getpagesize () - 1)), - 2*getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC); - - flush_cache (mem, MAX_FUNC_SIZE); - - signal (SIGSEGV, sighandler); - - /* register the new function: */ - region = alloca (_U_dyn_region_info_size (2)); - region->next = NULL; - region->insn_count = 3 * (MAX_FUNC_SIZE / 16); - region->op_count = 2; - _U_dyn_op_alias (®ion->op[0], 0, -1, fdesc.code); - _U_dyn_op_stop (®ion->op[1]); - - memset (&di, 0, sizeof (di)); - di.start_ip = (long) mem; - di.end_ip = (long) mem + 16*region->insn_count/3; - di.gp = get_gp (fdesc); - di.format = UNW_INFO_FORMAT_DYNAMIC; - di.u.pi.name_ptr = (unw_word_t) "copy_of_template"; - di.u.pi.regions = region; - - _U_dyn_register (&di); - - /* call new function: */ - fdesc.code = (long) mem; - funcp = get_funcp (fdesc); - - if (verbose) - (*funcp) (10, funcp, printf, "iteration %c%s\n", strarr); - else - (*funcp) (10, funcp, dev_null, "iteration %c%s\n", strarr); - - _U_dyn_cancel (&di); - return -1; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-exc.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-exc.c deleted file mode 100644 index 1170bdd03fd981..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-exc.c +++ /dev/null @@ -1,162 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 illustrates the basics of using the unwind interface for - exception handling. */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include - -#include - -#ifdef HAVE_IA64INTRIN_H -# include -#endif - -#define panic(args...) \ - { ++nerrors; fprintf (stderr, args); } - -int nerrors = 0; -int verbose = 0; -int depth = 13; -volatile int got_here = 0; - -extern void b (int); - -void -raise_exception (void) -{ - unw_cursor_t cursor; - unw_context_t uc; - int i; - - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - { - panic ("unw_init_local() failed!\n"); - return; - } - - /* unwind to top-most frame a(), skipping over b() and raise_exception(): */ - for (i = 0; i < depth + 2; ++i) - if (unw_step (&cursor) < 0) - { - panic ("unw_step() failed!\n"); - return; - } - unw_resume (&cursor); /* transfer control to exception handler */ -} - -uintptr_t -get_bsp (void) -{ -#if UNW_TARGET_IA64 -# ifdef __INTEL_COMPILER - return __getReg (_IA64_REG_AR_BSP); -# else - return (uintptr_t) __builtin_ia64_bsp (); -# endif -#else - return 0; -#endif -} - -int -a (int n) -{ - long stack; - int result = 99; - - if (verbose) - printf ("a(n=%d): sp=%p bsp=0x%lx\n", - n, &stack, (unsigned long) get_bsp ()); - - if (n > 0) - a (n - 1); - else - b (16); - - if (verbose) - { - printf ("exception handler: here we go (sp=%p, bsp=0x%lx)...\n", - &stack, (unsigned long) get_bsp ()); - /* This call works around a bug in gcc (up-to pre3.4) which - causes invalid assembly code to be generated when - __builtin_ia64_bsp() gets predicated. */ - getpid (); - } - if (n == depth) - { - result = 0; - got_here = 1; - } - return result; -} - -void -b (int n) -{ - if ((n & 1) == 0) - { - if (verbose) - printf ("b(n=%d) calling raise_exception()\n", n); - raise_exception (); - } - panic ("FAILURE: b() returned from raise_exception()!!\n"); -} - -int -main (int argc, char **argv) -{ - int result; - - if (argc > 1) - { - ++verbose; - depth = atol (argv[1]); - if (depth < 1) - { - fprintf (stderr, "Usage: %s depth\n" - " depth must be >= 1\n", argv[0]); - exit (-1); - } - } - - result = a (depth); - if (result != 0 || !got_here || nerrors > 0) - { - fprintf (stderr, - "FAILURE: test failed: result=%d got_here=%d nerrors=%d\n", - result, got_here, nerrors); - exit (-1); - } - - if (verbose) - printf ("SUCCESS!\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-init.cxx b/src/coreclr/src/pal/src/libunwind/tests/Gtest-init.cxx deleted file mode 100644 index afded019273f53..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-init.cxx +++ /dev/null @@ -1,107 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 tests unwinding from a constructor from within an - atexit() handler. */ - -#include -#include -#include - -#include -#include "compiler.h" - -int verbose, errors; - -#define panic(args...) \ - { ++errors; fprintf (stderr, args); return; } - -class Test_Class { - public: - Test_Class (void); -}; - -static Test_Class t; - -static void -do_backtrace (void) -{ - char name[128], off[32]; - unw_word_t ip, offset; - unw_cursor_t cursor; - unw_context_t uc; - int ret, count = 0; - - unw_getcontext (&uc); - unw_init_local (&cursor, &uc); - - do - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - name[0] = '\0'; - off[0] = '\0'; - if (unw_get_proc_name (&cursor, name, sizeof (name), &offset) == 0 - && offset > 0) - snprintf (off, sizeof (off), "+0x%lx", (long) offset); - if (verbose) - printf (" [%lx] <%s%s>\n", (long) ip, name, off); - if (++count > 32) - panic ("FAILURE: didn't reach beginning of unwind-chain\n"); - } - while ((ret = unw_step (&cursor)) > 0); - - if (ret < 0) - panic ("FAILURE: unw_step() returned %d\n", ret); -} - -static void -b (void) -{ - do_backtrace(); -} - -static void -a (void) -{ - if (verbose) - printf ("do_backtrace() from atexit()-handler:\n"); - b(); - if (errors) - abort (); /* cannot portably call exit() from an atexit() handler */ -} - -Test_Class::Test_Class (void) -{ - if (verbose) - printf ("do_backtrace() from constructor:\n"); - b(); -} - -int -main (int argc, char **argv UNUSED) -{ - verbose = argc > 1; - return atexit (a); -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-nomalloc.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-nomalloc.c deleted file mode 100644 index 5b97fc70918c45..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-nomalloc.c +++ /dev/null @@ -1,110 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2009 Google, Inc - Contributed by Arun Sharma - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include -#include -#include - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -int verbose; -int num_errors; -int in_unwind; - -void * -malloc(size_t s) -{ - static void * (*func)(); - - if(!func) - func = (void *(*)()) dlsym(RTLD_NEXT, "malloc"); - - if (in_unwind) { - num_errors++; - return NULL; - } else { - return func(s); - } -} - -static void -do_backtrace (void) -{ - unw_word_t ip, sp; - unw_cursor_t cursor; - unw_context_t uc; - int ret; - - in_unwind = 1; - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - panic ("unw_init_local failed!\n"); - - do - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - unw_get_reg (&cursor, UNW_REG_SP, &sp); - - ret = unw_step (&cursor); - if (ret < 0) - { - ++num_errors; - } - } - while (ret > 0); - in_unwind = 0; -} - -void -foo3 (void) -{ - do_backtrace (); -} - -void -foo2 (void) -{ - foo3 (); -} - -void -foo1 (void) -{ - foo2 (); -} - -int -main (void) -{ - foo1(); - - if (num_errors > 0) - { - fprintf (stderr, "FAILURE: detected %d errors\n", num_errors); - exit (-1); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig-rt.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig-rt.c deleted file mode 100644 index df515fc1953938..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig-rt.c +++ /dev/null @@ -1,31 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - Copyright (C) 2012 Tommi Rantala - -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. */ - -/* The purpose of this test is to invoke different code paths in libunwind (on - * some architectures), that are executed when the SA_SIGINFO sigaction() flag - * is used. - */ - -#define TEST_WITH_SIGINFO 1 -#include "Gtest-resume-sig.c" diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig.c deleted file mode 100644 index 18ec65da713440..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig.c +++ /dev/null @@ -1,200 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* Verify that unw_resume() restores the signal mask at proper time. */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "compiler.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_IA64INTRIN_H -# include -#endif - -#define panic(args...) \ - do { fprintf (stderr, args); ++nerrors; } while (0) - -int verbose; -int nerrors; -int got_usr1, got_usr2; -char *sigusr1_sp; - -uintptr_t -get_bsp (void) -{ -#if UNW_TARGET_IA64 -# ifdef __INTEL_COMPILER - return __getReg (_IA64_REG_AR_BSP); -# else - return (uintptr_t) __builtin_ia64_bsp (); -# endif -#else - return 0; -#endif -} - -#ifdef TEST_WITH_SIGINFO -void -handler (int sig, - siginfo_t *si UNUSED, - void *ucontext UNUSED) -#else -void -handler (int sig) -#endif -{ - unw_word_t ip; - sigset_t mask; - unw_context_t uc; - unw_cursor_t c; - char foo; - int ret; - // The test rely on SIGUSR2 mask to be cleared when the handler returns. - // For local context from the signal handler, there doesn't seem to be a way - // currently to set it so just clear the whole struct to make sure the signal mask is cleared. - // This should probably be fixed to avoid signal mask being set to random values - // by `unw_resume` if the context was not pre-zeroed., - // Using the signal ucontext direction should also work automatically but currently doesn't - // on ARM/AArch64 (or any other archs that doesn't have a proper sigreturn implementation) - memset(&uc, 0x0, sizeof(uc)); - -#if UNW_TARGET_IA64 - if (verbose) - printf ("bsp = %llx\n", (unsigned long long) get_bsp ()); -#endif - - if (verbose) - printf ("got signal %d\n", sig); - - if (sig == SIGUSR1) - { - ++got_usr1; - sigusr1_sp = &foo; - - sigemptyset (&mask); - sigaddset (&mask, SIGUSR2); - sigprocmask (SIG_BLOCK, &mask, NULL); - kill (getpid (), SIGUSR2); /* pend SIGUSR2 */ - - signal (SIGUSR1, SIG_IGN); - - if ((ret = unw_getcontext (&uc)) < 0) - panic ("unw_getcontext() failed: ret=%d\n", ret); - if ((ret = unw_init_local (&c, &uc)) < 0) - panic ("unw_init_local() failed: ret=%d\n", ret); - - if ((ret = unw_step (&c)) < 0) /* step to signal trampoline */ - panic ("unw_step(1) failed: ret=%d\n", ret); - - if ((ret = unw_step (&c)) < 0) /* step to kill() */ - panic ("unw_step(2) failed: ret=%d\n", ret); - -#if defined(UNW_TARGET_TILEGX) - if ((ret = unw_step (&c)) < 0) /* step to signal trampoline */ - panic ("unw_step(2) failed: ret=%d\n", ret); -#endif - - if ((ret = unw_get_reg (&c, UNW_REG_IP, &ip)) < 0) - panic ("unw_get_reg(IP) failed: ret=%d\n", ret); - if (verbose) - printf ("resuming at 0x%lx, with SIGUSR2 pending\n", - (unsigned long) ip); - unw_resume (&c); - } - else if (sig == SIGUSR2) - { - ++got_usr2; - if (got_usr1) - { - if (verbose) - printf ("OK: stack still at %p\n", &foo); - } - signal (SIGUSR2, SIG_IGN); - } - else - panic ("Got unexpected signal %d\n", sig); -} - -int -main (int argc, char **argv UNUSED) -{ - struct sigaction sa; - float d = 1.0; - int n = 0; - - if (argc > 1) - verbose = 1; - - memset (&sa, 0, sizeof(sa)); -#ifdef TEST_WITH_SIGINFO - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO; -#else - sa.sa_handler = handler; -#endif - - if (sigaction (SIGUSR1, &sa, NULL) != 0 || - sigaction (SIGUSR2, &sa, NULL) != 0) - { - fprintf (stderr, "sigaction() failed: %s\n", strerror (errno)); - return -1; - } - - /* Use the FPU a bit; otherwise we get spurious errors should the - signal handler need to use the FPU for any reason. This seems to - happen on x86-64. */ - while (d > 0.0) - { - d /= 2.0; - ++n; - } - if (n > 9999) - return -1; /* can't happen, but don't tell the compiler... */ - - if (verbose) - printf ("sending SIGUSR1\n"); - kill (getpid (), SIGUSR1); - - if (!got_usr2) - panic ("failed to get SIGUSR2\n"); - - if (nerrors) - { - fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); - exit (-1); - } - - if (verbose) - printf ("SUCCESS\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c deleted file mode 100644 index fc1f646eac6d06..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c +++ /dev/null @@ -1,282 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY - -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. */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "compiler.h" - -#include -#if HAVE_EXECINFO_H -# include -#else - extern int backtrace (void **, int); -#endif -#include -#include -#include -#include -#include -#include -#include - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -#define SIG_STACK_SIZE 0x100000 - -int verbose; -int num_errors; - -/* These variables are global because they - * cause the signal stack to overflow */ -char buf[512], name[256]; -void *addresses[3][128]; -unw_cursor_t cursor; -unw_context_t uc; - -static void -do_backtrace (void) -{ - unw_word_t ip; - int ret = -UNW_ENOINFO; - int depth = 0; - int i, n, m; - - if (verbose) - printf ("\tnormal trace:\n"); - - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - panic ("unw_init_local failed!\n"); - - do - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - addresses[0][depth] = (void *) ip; - } - while ((ret = unw_step (&cursor)) > 0 && ++depth < 128); - - if (ret < 0) - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - printf ("FAILURE: unw_step() returned %d for ip=%lx\n", ret, (long) ip); - ++num_errors; - } - - if (verbose) - for (i = 0; i < depth; ++i) - printf ("\t #%-3d ip=%p\n", i, addresses[0][i]); - - if (verbose) - printf ("\n\tvia backtrace():\n"); - - n = backtrace (addresses[1], 128); - - if (verbose) - for (i = 0; i < n; ++i) - printf ("\t #%-3d ip=%p\n", i, addresses[1][i]); - - if (verbose) - printf ("\n\tvia unw_backtrace():\n"); - - m = unw_backtrace (addresses[2], 128); - - if (verbose) - for (i = 0; i < m; ++i) - printf ("\t #%-3d ip=%p\n", i, addresses[2][i]); - - if (m != depth+1) - { - printf ("FAILURE: unw_step() loop and unw_backtrace() depths differ: %d vs. %d\n", depth, m); - ++num_errors; - } - - if (n != depth+1) - { - printf ("FAILURE: unw_step() loop and backtrace() depths differ: %d vs. %d\n", depth, n); - ++num_errors; - } - - if (n == m) - for (i = 1; i < n; ++i) - /* Allow one in difference in comparison, trace returns adjusted addresses. */ - if (labs((unw_word_t) addresses[1][i] - (unw_word_t) addresses[2][i]) > 1) - { - printf ("FAILURE: backtrace() and unw_backtrace() addresses differ at %d: %p vs. %p\n", - i, addresses[1][i], addresses[2][i]); - ++num_errors; - } - - if (n == depth+1) - for (i = 1; i < depth; ++i) - /* Allow one in difference in comparison, trace returns adjusted addresses. */ - if (labs((unw_word_t) addresses[0][i] - (unw_word_t) addresses[1][i]) > 1) - { - printf ("FAILURE: unw_step() loop and backtrace() addresses differ at %d: %p vs. %p\n", - i, addresses[0][i], addresses[1][i]); - ++num_errors; - } -} - -void -foo (long val UNUSED) -{ - do_backtrace (); -} - -void -bar (long v) -{ - extern long f (long); - int arr[v]; - - /* This is a vain attempt to use up lots of registers to force - the frame-chain info to be saved on the memory stack on ia64. - It happens to work with gcc v3.3.4 and gcc v3.4.1 but perhaps - not with any other compiler. */ - foo (f (arr[0]) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + f (v)) - )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) - ))))))))))))))))))))))))))))))))))))))))))))))))))))))); -} - -void -sighandler (int signal, void *siginfo UNUSED, void *context) -{ - ucontext_t *uc UNUSED; - int sp; - - uc = context; - - if (verbose) - { - printf ("sighandler: got signal %d, sp=%p", signal, &sp); -#if UNW_TARGET_IA64 -# if defined(__linux__) - printf (" @ %lx", uc->uc_mcontext.sc_ip); -# else - { - uint16_t reason; - uint64_t ip; - - __uc_get_reason (uc, &reason); - __uc_get_ip (uc, &ip); - printf (" @ %lx (reason=%d)", ip, reason); - } -# endif -#elif UNW_TARGET_X86 -#if defined __linux__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]); -#elif defined __FreeBSD__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); -#endif -#elif UNW_TARGET_X86_64 -#if defined __linux__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); -#elif defined __FreeBSD__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); -#endif -#elif defined UNW_TARGET_ARM -#if defined __linux__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.arm_pc); -#elif defined __FreeBSD__ - printf (" @ %lx", (unsigned long) uc->uc_mcontext.__gregs[_REG_PC]); -#endif -#endif - printf ("\n"); - } - do_backtrace(); -} - -int -main (int argc, char **argv UNUSED) -{ - struct sigaction act; - stack_t stk; - - verbose = (argc > 1); - - if (verbose) - printf ("Normal backtrace:\n"); - - bar (1); - - memset (&act, 0, sizeof (act)); - act.sa_handler = (void (*)(int)) sighandler; - act.sa_flags = SA_SIGINFO; - if (sigaction (SIGTERM, &act, NULL) < 0) - panic ("sigaction: %s\n", strerror (errno)); - - if (verbose) - printf ("\nBacktrace across signal handler:\n"); - kill (getpid (), SIGTERM); - - if (verbose) - printf ("\nBacktrace across signal handler on alternate stack:\n"); - stk.ss_sp = malloc (SIG_STACK_SIZE); - if (!stk.ss_sp) - panic ("failed to allocate %u bytes\n", SIG_STACK_SIZE); - stk.ss_size = SIG_STACK_SIZE; - stk.ss_flags = 0; - if (sigaltstack (&stk, NULL) < 0) - panic ("sigaltstack: %s\n", strerror (errno)); - - memset (&act, 0, sizeof (act)); - act.sa_handler = (void (*)(int)) sighandler; - act.sa_flags = SA_ONSTACK | SA_SIGINFO; - if (sigaction (SIGTERM, &act, NULL) < 0) - panic ("sigaction: %s\n", strerror (errno)); - kill (getpid (), SIGTERM); - - if (num_errors > 0) - { - fprintf (stderr, "FAILURE: detected %d errors\n", num_errors); - exit (-1); - } - - if (verbose) - printf ("SUCCESS.\n"); - - signal (SIGTERM, SIG_DFL); - stk.ss_flags = SS_DISABLE; - sigaltstack (&stk, NULL); - free (stk.ss_sp); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-nat.c b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-nat.c deleted file mode 100644 index 15ef0caccc0dab..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-nat.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gia64-test-nat.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-rbs.c b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-rbs.c deleted file mode 100644 index b838ebe42f7a1a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-rbs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gia64-test-rbs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-readonly.c b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-readonly.c deleted file mode 100644 index cd23e92613e90a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-readonly.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gia64-test-readonly.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-stack.c b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-stack.c deleted file mode 100644 index 3647629c90bd40..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-stack.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gia64-test-stack.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lperf-simple.c b/src/coreclr/src/pal/src/libunwind/tests/Lperf-simple.c deleted file mode 100644 index cdf38c207a0d5f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Lperf-simple.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gperf-simple.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lperf-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Lperf-trace.c deleted file mode 100644 index 1c3cf21c2137da..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Lperf-trace.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gperf-trace.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lrs-race.c b/src/coreclr/src/pal/src/libunwind/tests/Lrs-race.c deleted file mode 100644 index 6fe4972020d022..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Lrs-race.c +++ /dev/null @@ -1,1514 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by Paul Pluzhnikov - -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. */ - -/* Verify that register state caches work under all caching policies - in a multi-threaded environment with a large number IPs */ - -#define UNW_LOCAL_ONLY -#include -#include "compiler.h" - -#include -#include -#include - -/* ITERS=1000, NTHREAD=10 caught some bugs in the past */ -#ifndef ITERS -#define ITERS 100 -#endif - -#ifndef NTHREAD -#define NTHREAD 2 -#endif - -int verbose; - -void -foo_0 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_1 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_2 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_3 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_4 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_5 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_6 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_7 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_8 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_9 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_10 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_11 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_12 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_13 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_14 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_15 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_16 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_17 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_18 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_19 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_20 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_21 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_22 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_23 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_24 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_25 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_26 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_27 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_28 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_29 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_30 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_31 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_32 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_33 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_34 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_35 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_36 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_37 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_38 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_39 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_40 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_41 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_42 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_43 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_44 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_45 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_46 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_47 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_48 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_49 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_50 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_51 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_52 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_53 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_54 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_55 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_56 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_57 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_58 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_59 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_60 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_61 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_62 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_63 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_64 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_65 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_66 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_67 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_68 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_69 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_70 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_71 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_72 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_73 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_74 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_75 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_76 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_77 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_78 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_79 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_80 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_81 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_82 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_83 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_84 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_85 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_86 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_87 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_88 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_89 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_90 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_91 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_92 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_93 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_94 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_95 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_96 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_97 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_98 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_99 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_100 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_101 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_102 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_103 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_104 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_105 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_106 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_107 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_108 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_109 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_110 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_111 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_112 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_113 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_114 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_115 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_116 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_117 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_118 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_119 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_120 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_121 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_122 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_123 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_124 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_125 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_126 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_127 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void -foo_128 (void) -{ - void *buf[20]; - int n; - - if ((n = unw_backtrace (buf, 20)) < 3) - abort (); -} - -void * -bar(void *p UNUSED) -{ - int i; - for (i = 0; i < ITERS; ++i) { - foo_0 (); - foo_1 (); - foo_2 (); - foo_3 (); - foo_4 (); - foo_5 (); - foo_6 (); - foo_7 (); - foo_8 (); - foo_9 (); - foo_10 (); - foo_11 (); - foo_12 (); - foo_13 (); - foo_14 (); - foo_15 (); - foo_16 (); - foo_17 (); - foo_18 (); - foo_19 (); - foo_20 (); - foo_21 (); - foo_22 (); - foo_23 (); - foo_24 (); - foo_25 (); - foo_26 (); - foo_27 (); - foo_28 (); - foo_29 (); - foo_30 (); - foo_31 (); - foo_32 (); - foo_33 (); - foo_34 (); - foo_35 (); - foo_36 (); - foo_37 (); - foo_38 (); - foo_39 (); - foo_40 (); - foo_41 (); - foo_42 (); - foo_43 (); - foo_44 (); - foo_45 (); - foo_46 (); - foo_47 (); - foo_48 (); - foo_49 (); - foo_50 (); - foo_51 (); - foo_52 (); - foo_53 (); - foo_54 (); - foo_55 (); - foo_56 (); - foo_57 (); - foo_58 (); - foo_59 (); - foo_60 (); - foo_61 (); - foo_62 (); - foo_63 (); - foo_64 (); - foo_65 (); - foo_66 (); - foo_67 (); - foo_68 (); - foo_69 (); - foo_70 (); - foo_71 (); - foo_72 (); - foo_73 (); - foo_74 (); - foo_75 (); - foo_76 (); - foo_77 (); - foo_78 (); - foo_79 (); - foo_80 (); - foo_81 (); - foo_82 (); - foo_83 (); - foo_84 (); - foo_85 (); - foo_86 (); - foo_87 (); - foo_88 (); - foo_89 (); - foo_90 (); - foo_91 (); - foo_92 (); - foo_93 (); - foo_94 (); - foo_95 (); - foo_96 (); - foo_97 (); - foo_98 (); - foo_99 (); - foo_100 (); - foo_101 (); - foo_102 (); - foo_103 (); - foo_104 (); - foo_105 (); - foo_106 (); - foo_107 (); - foo_108 (); - foo_109 (); - foo_110 (); - foo_111 (); - foo_112 (); - foo_113 (); - foo_114 (); - foo_115 (); - foo_116 (); - foo_117 (); - foo_118 (); - foo_119 (); - foo_120 (); - foo_121 (); - foo_122 (); - foo_123 (); - foo_124 (); - foo_125 (); - foo_126 (); - foo_127 (); - foo_128 (); - } - return NULL; -} - -int doit (void) -{ - pthread_t tid[NTHREAD]; - int i; - - for (i = 0; i < NTHREAD; ++i) - if (pthread_create (&tid[i], NULL, bar, NULL)) - return 1; - - for (i = 0; i < NTHREAD; ++i) - if (pthread_join (tid[i], NULL)) - return 1; - - return 0; -} - -int -main (int argc, char **argv UNUSED) -{ - if (argc > 1) - verbose = 1; - - if (verbose) - printf ("Caching: none\n"); - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); - doit (); - - if (verbose) - printf ("Caching: global\n"); - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); - doit (); - - if (verbose) - printf ("Caching: per-thread\n"); - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); - doit (); - - if (verbose) - printf ("SUCCESS\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-bt.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-bt.c deleted file mode 100644 index 3489bf0b51e163..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-bt.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gtest-bt.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-concurrent.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-concurrent.c deleted file mode 100644 index 9462607ec8fb6c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-concurrent.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gtest-concurrent.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-cxx-exceptions.cxx b/src/coreclr/src/pal/src/libunwind/tests/Ltest-cxx-exceptions.cxx deleted file mode 100644 index 24bcd13e3dc219..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-cxx-exceptions.cxx +++ /dev/null @@ -1,80 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2010 stefan.demharter@gmx.net - Copyright (C) 2010 arun.sharma@google.com - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include -#include -#include "compiler.h" - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -static int verbose; - -struct Test -{ - public: // --- ctor/dtor --- - Test() { ++counter_; } - ~Test() { -- counter_; } - Test(const Test&) { ++counter_; } - - public: // --- static members --- - static int counter_; -}; - -int Test::counter_ = 0; - -// Called by foo -extern "C" void bar() -{ - Test t; - try { - Test t; - throw 5; - } catch (...) { - Test t; - if (verbose) - printf("Throwing an int\n"); - throw 6; - } -} - -int main(int argc, char **argv UNUSED) -{ - if (argc > 1) - verbose = 1; - try { - Test t; - bar(); - } catch (int) { - // Dtor of all Test-object has to be called. - if (Test::counter_ != 0) - panic("Counter non-zero\n"); - return Test::counter_; - } catch (...) { - // An int was thrown - we should not get here. - panic("Int was thrown why are we here?\n"); - } - exit(0); -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-dyn1.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-dyn1.c deleted file mode 100644 index c2cab6b9a06a21..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-dyn1.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gtest-dyn1.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-exc.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-exc.c deleted file mode 100644 index 36a234ca82cb25..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-exc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gtest-exc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal-lib.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal-lib.c deleted file mode 100644 index 7474f71f49db85..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal-lib.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -/* To prevent inlining and optimizing away */ -int foo(volatile int* f) { - return *f; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal.c deleted file mode 100644 index 4bde218f3bb2cf..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "libunwind.h" -#include -#include -#include - -#include - -#include -#include -#include - -int stepper(unw_cursor_t* c) { - int steps = 0; - int ret = 1; - while (ret) { - - ret = unw_step(c); - if (!ret) { - break; - } - steps++; - } - return steps; -} - -/* Verify that we can step from both ucontext, and from getcontext() - * roughly the same. This tests that the IP from ucontext is used - * correctly (see impl of unw_init_local2) */ -void handler(int num, siginfo_t* info, void* ucontext) { - unw_cursor_t c; - unw_context_t context; - unw_getcontext(&context); - int ret = unw_init_local2(&c, ucontext, UNW_INIT_SIGNAL_FRAME); - assert(!ret); - int ucontext_steps = stepper(&c); - - ret = unw_init_local(&c, &context); - (void)ret; - assert(!ret); - int getcontext_steps = stepper(&c); - if (ucontext_steps == getcontext_steps - 2) { - exit(0); - } - printf("unw_getcontext steps was %i, ucontext steps was %i, should be %i\n", - getcontext_steps, ucontext_steps, getcontext_steps - 2); - exit(-1); -} - -int foo(volatile int* f); - -int main(){ - struct sigaction a; - memset(&a, 0, sizeof(struct sigaction)); - a.sa_sigaction = &handler; - a.sa_flags = SA_SIGINFO; - sigaction(SIGSEGV, &a, NULL); - - foo(NULL); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-init.cxx b/src/coreclr/src/pal/src/libunwind/tests/Ltest-init.cxx deleted file mode 100644 index 58a6ea42798ffa..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-init.cxx +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gtest-init.cxx" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c deleted file mode 100644 index 1cacb9f028f151..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c +++ /dev/null @@ -1,143 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Copyright (c) 2003 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. */ - -#include "compiler.h" - -#include -#include -#include -#include -#include - -#include -#include - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -void * stack_start; - -#define PAGE_SIZE 4096 - -void do_backtrace (void) -{ - void* buffer[1024]; - int size = 1024; - mprotect((void*)((uintptr_t)stack_start & ~(PAGE_SIZE - 1)), - PAGE_SIZE, PROT_NONE); - - unw_cursor_t cursor; - unw_word_t ip, sp; - unw_context_t uc; - int ret; - int steps = 0; - - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - panic ("unw_init_local failed!\n"); - - do - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - unw_get_reg (&cursor, UNW_REG_SP, &sp); - - ret = unw_step (&cursor); - if (ret < 0) - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - } - steps ++; - } - while (ret > 0); - - if (steps < 5) - { - exit(-1); - } - - mprotect((void*)((uintptr_t)stack_start & ~(PAGE_SIZE - 1)), - PAGE_SIZE, PROT_READ|PROT_WRITE); -} - -void consume_and_run (int depth) -{ - unw_cursor_t cursor; - unw_context_t uc; - char string[1024]; - - sprintf (string, "hello %p %p\n", &cursor, &uc); - if (depth == 0) { - do_backtrace(); - } else { - consume_and_run(depth - 1); - } -} - -int -main (int argc, char **argv UNUSED) -{ - int start; - unw_context_t uc; - unw_cursor_t cursor; - - stack_start = &start; - - // Initialize pipe mem validate check, opens file descriptors - unw_getcontext(&uc); - if (unw_init_local (&cursor, &uc) < 0) - panic ("unw_init_local failed!\n"); - - int i; - for (i = 3; i < 10; i++) - { - - pid_t childpid = fork(); - if (!childpid) - { - /* Close fds and make sure we still work */ - int ret = close(i); - } - - int status; - if (childpid) - { - wait(&status); - if (WIFEXITED(status)) - return WEXITSTATUS(status); - else - return -1; - } - else - { - consume_and_run (10); - - return 0; - } - } - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-nocalloc.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-nocalloc.c deleted file mode 100644 index f5c31b2a3ee259..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-nocalloc.c +++ /dev/null @@ -1,137 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2011 Google, Inc - Contributed by Paul Pluzhnikov - -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_LOCAL_ONLY -#include - -#include -#include -#include -#include -#include - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -int num_mallocs; -int num_callocs; -int in_unwind; - -void * -calloc(size_t n, size_t s) -{ - static void * (*func)(size_t, size_t); - -#ifdef __GLIBC__ - /* In glibc, dlsym() calls calloc. Calling dlsym(RTLD_NEXT, "calloc") here - causes infinite recursion. Instead, we simply use it by its other - name. */ - extern void *__libc_calloc(size_t, size_t); - if (!func) - func = &__libc_calloc; -#else - if(!func) - func = dlsym(RTLD_NEXT, "calloc"); -#endif - - if (in_unwind) { - num_callocs++; - return NULL; - } else { - return func(n, s); - } -} - -void * -malloc(size_t s) -{ - static void * (*func)(size_t); - - if(!func) - func = dlsym(RTLD_NEXT, "malloc"); - - if (in_unwind) { - num_mallocs++; - return NULL; - } else { - return func(s); - } -} - -static void -do_backtrace (void) -{ - const int num_levels = 100; - void *pc[num_levels]; - - in_unwind = 1; - unw_backtrace(pc, num_levels); - in_unwind = 0; -} - -void -foo3 (void) -{ - do_backtrace (); -} - -void -foo2 (void) -{ - foo3 (); -} - -void -foo1 (void) -{ - foo2 (); -} - -int -main (void) -{ - int i, num_errors; - - /* Create (and leak) 100 TSDs, then call backtrace() - and check that it doesn't call malloc()/calloc(). */ - for (i = 0; i < 100; ++i) { - pthread_key_t key; - if (pthread_key_create (&key, NULL)) - panic ("FAILURE: unable to create key %d\n", i); - } - /* Call backtrace right after thread creation, - * where we are sure that we're not inside malloc */ - do_backtrace(); - num_mallocs = num_callocs = 0; - foo1 (); - num_errors = num_mallocs + num_callocs; - if (num_errors > 0) - { - fprintf (stderr, - "FAILURE: detected %d error%s (malloc: %d, calloc: %d)\n", - num_errors, num_errors > 1 ? "s" : "", - num_mallocs, num_callocs); - exit (-1); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-nomalloc.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-nomalloc.c deleted file mode 100644 index 74d6331286c187..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-nomalloc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gtest-nomalloc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig-rt.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig-rt.c deleted file mode 100644 index 01fd6dc7d78aab..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig-rt.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gtest-resume-sig-rt.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig.c deleted file mode 100644 index 0047b524aae7fd..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gtest-resume-sig.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-trace.c deleted file mode 100644 index fb0e9c10bdfc4a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-trace.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gtest-trace.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-varargs.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-varargs.c deleted file mode 100644 index 17ac600be626bc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-varargs.c +++ /dev/null @@ -1,84 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#include "compiler.h" - -#include -#include -#include -#include - -int ok; -int verbose; - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 3) -void a (int, ...) __attribute__((optimize(0))); -void b (void) __attribute__((optimize(0))); -void c (void) __attribute__((optimize(0))); -#endif - -void NOINLINE -b (void) -{ - void *v[20]; - int i, n; - - n = unw_backtrace(v, 20); - - /* Check that the number of addresses given by unw_backtrace() looks - * reasonable. If the compiler inlined everything, then this check will also - * break. */ - if (n >= 7) - ok = 1; - - if (verbose) - for (i = 0; i < n; ++i) - printf ("[%d] %p\n", i, v[i]); -} - -void NOINLINE -c (void) -{ - b (); -} - -void NOINLINE -a (int d, ...) -{ - switch (d) - { - case 5: - a (4, 2,4); - break; - case 4: - a (3, 1,3,5); - break; - case 3: - a (2, 11, 13, 17, 23); - break; - case 2: - a (1); - break; - case 1: - c (); - } -} - -int -main (int argc, char **argv UNUSED) -{ - if (argc > 1) - verbose = 1; - - a (5, 3, 4, 5, 6); - - if (!ok) - { - fprintf (stderr, "FAILURE: expected deeper backtrace.\n"); - return 1; - } - - if (verbose) - printf ("SUCCESS.\n"); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Makefile.am b/src/coreclr/src/pal/src/libunwind/tests/Makefile.am deleted file mode 100644 index 4b0b9db7d16996..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Makefile.am +++ /dev/null @@ -1,234 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include - -EXTRA_DIST = run-ia64-test-dyn1 run-ptrace-mapper run-ptrace-misc \ - run-check-namespace run-coredump-unwind \ - run-coredump-unwind-mdi check-namespace.sh.in \ - Gtest-nomalloc.c - -MAINTAINERCLEANFILES = Makefile.in - -noinst_PROGRAMS_arch = -noinst_PROGRAMS_cdep = -noinst_PROGRAMS_common = -check_PROGRAMS_arch = -check_PROGRAMS_cdep = -check_PROGRAMS_common = test-proc-info test-static-link \ - test-strerror -check_SCRIPTS_arch = -check_SCRIPTS_cdep = -check_SCRIPTS_common = run-check-namespace - -if REMOTE_ONLY - -perf: - -else - LIBUNWIND_local = $(top_builddir)/src/libunwind.la -if ARCH_IA64 - noinst_PROGRAMS_arch += ia64-test-dyn1 - check_SCRIPTS_arch += run-ia64-test-dyn1 - check_PROGRAMS_arch += Gia64-test-stack Lia64-test-stack \ - Gia64-test-nat Lia64-test-nat \ - Gia64-test-rbs Lia64-test-rbs \ - Gia64-test-readonly Lia64-test-readonly \ - ia64-test-setjmp ia64-test-sig -else #!ARCH_IA64 -if ARCH_PPC64 -if USE_ALTIVEC - noinst_PROGRAMS_arch += ppc64-test-altivec -endif #USE_ALTIVEC -endif #ARCH_PPC64 -endif #!ARCH_IA64 - check_PROGRAMS_cdep += Gtest-bt Ltest-bt Gtest-exc Ltest-exc \ - Gtest-init Ltest-init \ - Gtest-concurrent Ltest-concurrent \ - Gtest-resume-sig Ltest-resume-sig \ - Gtest-resume-sig-rt Ltest-resume-sig-rt \ - Gtest-trace Ltest-trace \ - Ltest-init-local-signal \ - Ltest-mem-validate \ - test-async-sig test-flush-cache test-init-remote \ - test-mem test-reg-state Ltest-varargs \ - Ltest-nomalloc Ltest-nocalloc Lrs-race - noinst_PROGRAMS_cdep += forker Gperf-simple Lperf-simple \ - Gperf-trace Lperf-trace - -if BUILD_PTRACE - check_SCRIPTS_cdep += run-ptrace-mapper run-ptrace-misc - check_PROGRAMS_cdep += test-ptrace - noinst_PROGRAMS_cdep += mapper test-ptrace-misc -endif - -if BUILD_SETJMP - check_PROGRAMS_cdep += test-setjmp -endif - -if SUPPORT_CXX_EXCEPTIONS - check_PROGRAMS_cdep += Ltest-cxx-exceptions -endif - -if OS_LINUX -if BUILD_COREDUMP - check_SCRIPTS_cdep += run-coredump-unwind - noinst_PROGRAMS_cdep += crasher test-coredump-unwind - -if HAVE_LZMA - check_SCRIPTS_cdep += run-coredump-unwind-mdi -endif # HAVE_LZMA -endif # BUILD_COREDUMP -endif # OS_LINUX - -perf: perf-startup Gperf-simple Lperf-simple Lperf-trace - @echo "########## Basic performance of generic libunwind:" - @./Gperf-simple - @echo "########## Basic performance of local-only libunwind:" - @./Lperf-simple - @echo "########## Performance of fast unwind:" - @./Lperf-trace - @echo "########## Startup overhead:" - @$(srcdir)/perf-startup @arch@ - -endif - -check_PROGRAMS = $(check_PROGRAMS_common) $(check_PROGRAMS_cdep) \ - $(check_PROGRAMS_arch) -check_SCRIPTS = $(check_SCRIPTS_common) $(check_SCRIPTS_cdep) \ - $(check_SCRIPTS_arch) - - -TESTS = $(check_PROGRAMS) $(check_SCRIPTS) -XFAIL_TESTS = - -if ARCH_IA64 - check_PROGRAMS_cdep += Gtest-dyn1 Ltest-dyn1 -endif - -# Use if arch defines but does not support PTRACE_SINGLESTEP -# ptrace request used in the tests. -XFAIL_TESTS_PTRACE_SINGLESTEP = run-ptrace-mapper run-ptrace-misc - -if ARCH_MIPS -XFAIL_TESTS += $(XFAIL_TESTS_PTRACE_SINGLESTEP) -endif - -if ARCH_ARM -# ARM Linux kernel >=2.6.39 removed PTRACE_SINGLESTEP emulation -XFAIL_TESTS += $(XFAIL_TESTS_PTRACE_SINGLESTEP) -endif - -# This is meant for multilib binaries, -m32. -# ptrace gives EBADREG when testing, -# but generally everything else works. -if NO_PTRACE_TEST - XFAIL_TESTS += run-ptrace-mapper test-ptrace Ltest-init-local-signal -endif - -noinst_PROGRAMS = $(noinst_PROGRAMS_common) $(noinst_PROGRAMS_cdep) \ - $(noinst_PROGRAMS_arch) - -Lia64_test_readonly_SOURCES = Lia64-test-readonly.c ia64-test-readonly-asm.S -Gia64_test_readonly_SOURCES = Gia64-test-readonly.c ia64-test-readonly-asm.S -Lia64_test_stack_SOURCES = Lia64-test-stack.c ia64-test-stack-asm.S \ - ia64-test-stack.h -Gia64_test_stack_SOURCES = Gia64-test-stack.c ia64-test-stack-asm.S \ - ia64-test-stack.h -Lia64_test_rbs_SOURCES = Lia64-test-rbs.c ia64-test-rbs-asm.S ia64-test-rbs.h -Gia64_test_rbs_SOURCES = Gia64-test-rbs.c ia64-test-rbs-asm.S ia64-test-rbs.h -Lia64_test_nat_SOURCES = Lia64-test-nat.c ia64-test-nat-asm.S -Gia64_test_nat_SOURCES = Gia64-test-nat.c ia64-test-nat-asm.S -ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S \ - flush-cache.h -ppc64_test_altivec_SOURCES = ppc64-test-altivec.c ppc64-test-altivec-utils.c -Gtest_init_SOURCES = Gtest-init.cxx -Ltest_init_SOURCES = Ltest-init.cxx -Ltest_cxx_exceptions_SOURCES = Ltest-cxx-exceptions.cxx - -Ltest_init_local_signal_SOURCES = Ltest-init-local-signal.c Ltest-init-local-signal-lib.c - -Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S flush-cache.h -Ltest_dyn1_SOURCES = Ltest-dyn1.c flush-cache.S flush-cache.h -test_static_link_SOURCES = test-static-link-loc.c test-static-link-gen.c -test_static_link_LDFLAGS = -static -forker_LDFLAGS = -static -Gtest_bt_SOURCES = Gtest-bt.c ident.c -Ltest_bt_SOURCES = Ltest-bt.c ident.c -test_ptrace_misc_SOURCES = test-ptrace-misc.c ident.c -Ltest_nomalloc_SOURCES = Ltest-nomalloc.c -Ltest_nocalloc_SOURCES = Ltest-nocalloc.c -Gtest_trace_SOURCES = Gtest-trace.c ident.c -Ltest_trace_SOURCES = Ltest-trace.c ident.c -Ltest_mem_validate_SOURCES = Ltest-mem-validate.c - -LIBUNWIND = $(top_builddir)/src/libunwind-$(arch).la -LIBUNWIND_ptrace = $(top_builddir)/src/libunwind-ptrace.la -LIBUNWIND_coredump = $(top_builddir)/src/libunwind-coredump.la - -if USE_ELF32 -LIBUNWIND_ELF = $(top_builddir)/src/libunwind-elf32.la -endif -if USE_ELF64 -LIBUNWIND_ELF = $(top_builddir)/src/libunwind-elf64.la -endif -if USE_ELFXX -LIBUNWIND_ELF = $(top_builddir)/src/libunwind-elfxx.la -endif - -LIBUNWIND_setjmp = $(top_builddir)/src/libunwind-setjmp.la \ - $(LIBUNWIND_ELF) $(LIBUNWIND) - -test_async_sig_LDADD = $(LIBUNWIND_local) -lpthread -test_flush_cache_LDADD = $(LIBUNWIND_local) -test_init_remote_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -test_mem_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -test_reg_state_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -test_ptrace_LDADD = $(LIBUNWIND_ptrace) $(LIBUNWIND) -test_proc_info_LDADD = $(LIBUNWIND) -test_static_link_LDADD = $(LIBUNWIND) -test_strerror_LDADD = $(LIBUNWIND) -Lrs_race_LDADD = $(LIBUNWIND_local) -lpthread -Ltest_varargs_LDADD = $(LIBUNWIND_local) -Ltest_init_local_signal_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) - -Gtest_bt_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Gtest_concurrent_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -lpthread -Gtest_dyn1_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Gtest_exc_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Gtest_init_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) @BACKTRACELIB@ -Gtest_resume_sig_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Gtest_resume_sig_rt_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Gperf_simple_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Gtest_trace_LDADD=$(LIBUNWIND) $(LIBUNWIND_local) -Gperf_trace_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) - -Ltest_bt_LDADD = $(LIBUNWIND_local) -Ltest_concurrent_LDADD = $(LIBUNWIND_local) -lpthread -Ltest_dyn1_LDADD = $(LIBUNWIND_local) -Ltest_exc_LDADD = $(LIBUNWIND_local) -Ltest_init_LDADD = $(LIBUNWIND_local) -Ltest_nomalloc_LDADD = $(LIBUNWIND_local) @DLLIB@ -Ltest_nocalloc_LDADD = $(LIBUNWIND_local) @DLLIB@ -lpthread -Ltest_resume_sig_LDADD = $(LIBUNWIND_local) -Ltest_resume_sig_rt_LDADD = $(LIBUNWIND_local) -Lperf_simple_LDADD = $(LIBUNWIND_local) -Ltest_trace_LDADD = $(LIBUNWIND_local) -Lperf_trace_LDADD = $(LIBUNWIND_local) -Ltest_mem_validate_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) - -test_setjmp_LDADD = $(LIBUNWIND_setjmp) -ia64_test_setjmp_LDADD = $(LIBUNWIND_setjmp) - -if BUILD_COREDUMP -test_coredump_unwind_LDADD = $(LIBUNWIND_coredump) $(LIBUNWIND) @BACKTRACELIB@ -endif - -Gia64_test_nat_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Gia64_test_stack_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Gia64_test_rbs_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Gia64_test_readonly_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Lia64_test_nat_LDADD = $(LIBUNWIND_local) -Lia64_test_stack_LDADD = $(LIBUNWIND_local) -Lia64_test_rbs_LDADD = $(LIBUNWIND_local) -Lia64_test_readonly_LDADD = $(LIBUNWIND_local) -ia64_test_dyn1_LDADD = $(LIBUNWIND) -ia64_test_sig_LDADD = $(LIBUNWIND) -ppc64_test_altivec_LDADD = $(LIBUNWIND) diff --git a/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in b/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in deleted file mode 100644 index 6d0081732da007..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in +++ /dev/null @@ -1,367 +0,0 @@ -#!/bin/sh -verbose=false -if [ "$1" = "-v" ]; then - verbose=true - shift -fi - -build_plat=@build_arch@ -plat=@arch@ -os=@target_os@ -num_errors=0 - -LIBUNWIND=../src/.libs/libunwind.so -LIBUNWIND_GENERIC=../src/.libs/libunwind-${plat}.so - -fetch_symtab () { - filename=$1 - - if [ ! -r $filename ]; then - return - fi - - if $verbose; then - echo "Checking $filename..." - fi - - # - # Unfortunately, "nm --defined" is a GNU-extension. For portability, - # build the list of defined symbols by hand. - # - symtab=`nm -g $filename` - saved_IFS="$IFS" - IFS="" - undef=`nm -g -u $filename` - for line in $undef; do - symtab=`echo "$symtab" | grep -v "^${line}"\$` - done; - IFS="$saved_IFS" -} - -ignore () { - sym=$1 - symtab=`echo "$symtab" | grep -v " ${sym}\$"` -} - -match () { - sym=$1 - if `echo "$symtab" | grep -q " ${sym}\$"`; then - symtab=`echo "$symtab" | grep -v " ${sym}\$"` - else - echo " ERROR: Symbol \"$sym\" missing." - num_errors=`expr $num_errors + 1` - fi -} - -# -# Filter out miscellaneous symbols that get defined by the -# linker for each shared object. -# -filter_misc () { - ignore _DYNAMIC - ignore _GLOBAL_OFFSET_TABLE_ - ignore __bss_start - ignore _edata - ignore _end - ignore _Uelf32_get_proc_name - ignore _Uelf32_valid_object - ignore _Uelf64_get_proc_name - ignore _Uelf64_valid_object - ignore _U.*debug_level - ignore ICRT.INTERNAL # ICC 8.x defines this - - # Ignore symbols generated by the ARM Linux default linker script. - # For details see the binutils sources (src/ld/emulparams/armelf_linux.sh). - if [ ${plat} = "arm" ]; then - ignore __bss_start__ - ignore __bss_end__ - ignore __end__ - ignore _bss_end__ - fi - - if [ ${plat} = "mips" ]; then - ignore _fbss - ignore _fdata - ignore _ftext - ignore _gp - fi -} - -check_local_unw_abi () { - match _UL${plat}_apply_reg_state - match _UL${plat}_reg_states_iterate - match _UL${plat}_create_addr_space - match _UL${plat}_destroy_addr_space - match _UL${plat}_get_fpreg - match _UL${plat}_get_proc_info - match _UL${plat}_get_proc_info_by_ip - match _UL${plat}_get_proc_name - match _UL${plat}_get_reg - match _UL${plat}_get_save_loc - match _UL${plat}_init_local - match _UL${plat}_init_local2 - match _UL${plat}_init_remote - match _UL${plat}_is_signal_frame - match _UL${plat}_local_addr_space - match _UL${plat}_resume - match _UL${plat}_set_caching_policy - match _UL${plat}_set_cache_size - match _UL${plat}_set_reg - match _UL${plat}_set_fpreg - match _UL${plat}_step - - match _U${plat}_flush_cache - match _U${plat}_get_accessors - match _U${plat}_getcontext - match _U${plat}_regname - match _U${plat}_strerror - - match _U_dyn_cancel - match _U_dyn_info_list_addr - match _U_dyn_register - - match unw_backtrace - match backtrace - - case ${plat} in - arm) - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_is_fpreg - match _UL${plat}_search_unwind_table - match _UL${plat}_dwarf_search_unwind_table - match _UL${plat}_dwarf_find_unwind_table - ;; - hppa) - match _UL${plat}_dwarf_search_unwind_table - match _UL${plat}_dwarf_find_unwind_table - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_setcontext - ;; - ia64) - match _UL${plat}_search_unwind_table - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - ;; - x86) - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_is_fpreg - match _UL${plat}_dwarf_search_unwind_table - match _UL${plat}_dwarf_find_unwind_table - ;; - x86_64) - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_is_fpreg - match _UL${plat}_dwarf_search_unwind_table - match _UL${plat}_dwarf_find_unwind_table - match _U${plat}_setcontext - ;; - ppc*) - match _U${plat}_get_func_addr - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_is_fpreg - match _UL${plat}_dwarf_search_unwind_table - match _UL${plat}_dwarf_find_unwind_table - ;; - tilegx) - match _U${plat}_is_fpreg - match _UL${plat}_dwarf_search_unwind_table - match _UL${plat}_dwarf_find_unwind_table - match _UL${plat}_local_addr_space_init - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match ${plat}_lock - ;; - - *) - match _U${plat}_is_fpreg - match _UL${plat}_dwarf_search_unwind_table - match _UL${plat}_dwarf_find_unwind_table - ;; - esac - - if [ x@enable_debug_frame@ = xyes ]; then - match _UL${plat}_dwarf_find_debug_frame - fi - -} - -check_generic_unw_abi () { - match _U${plat}_apply_reg_state - match _U${plat}_reg_states_iterate - match _U${plat}_create_addr_space - match _U${plat}_destroy_addr_space - match _U${plat}_flush_cache - match _U${plat}_get_accessors - match _U${plat}_get_fpreg - match _U${plat}_get_proc_info - match _U${plat}_get_proc_info_by_ip - match _U${plat}_get_proc_name - match _U${plat}_get_reg - match _U${plat}_get_save_loc - match _U${plat}_init_local - match _U${plat}_init_local2 - match _U${plat}_init_remote - match _U${plat}_is_signal_frame - match _U${plat}_local_addr_space - match _U${plat}_regname - match _U${plat}_resume - match _U${plat}_set_caching_policy - match _U${plat}_set_cache_size - match _U${plat}_set_fpreg - match _U${plat}_set_reg - match _U${plat}_step - match _U${plat}_strerror - - case ${plat} in - arm) - match _U${plat}_is_fpreg - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_search_unwind_table - match _U${plat}_dwarf_search_unwind_table - match _U${plat}_dwarf_find_unwind_table - ;; - hppa) - match _U${plat}_dwarf_search_unwind_table - match _U${plat}_dwarf_find_unwind_table - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - ;; - ia64) - match _U${plat}_search_unwind_table - match _U${plat}_find_dyn_list - if [ $plat = $build_plat ]; then - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - case $os in - linux*) - match _U${plat}_get_kernel_table - ;; - esac - fi - ;; - x86) - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_is_fpreg - match _U${plat}_dwarf_search_unwind_table - match _U${plat}_dwarf_find_unwind_table - ;; - x86_64) - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_is_fpreg - match _U${plat}_dwarf_search_unwind_table - match _U${plat}_dwarf_find_unwind_table - ;; - ppc*) - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_get_func_addr - match _U${plat}_is_fpreg - match _U${plat}_dwarf_search_unwind_table - match _U${plat}_dwarf_find_unwind_table - ;; - tilegx) - match _U${plat}_dwarf_search_unwind_table - match _U${plat}_dwarf_find_unwind_table - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_is_fpreg - match _U${plat}_local_addr_space_init - match ${plat}_lock - ;; - *) - match _U${plat}_is_fpreg - match _U${plat}_dwarf_search_unwind_table - match _U${plat}_dwarf_find_unwind_table - ;; - esac - - if [ x@enable_debug_frame@ = xyes ]; then - match _U${plat}_dwarf_find_debug_frame - fi -} - -check_cxx_abi () { - match _Unwind_Backtrace - match _Unwind_DeleteException - match _Unwind_FindEnclosingFunction - match _Unwind_ForcedUnwind - match _Unwind_GetBSP - match _Unwind_GetCFA - match _Unwind_GetDataRelBase - match _Unwind_GetGR - match _Unwind_GetIP - match _Unwind_GetIPInfo - match _Unwind_GetLanguageSpecificData - match _Unwind_GetRegionStart - match _Unwind_GetTextRelBase - match _Unwind_RaiseException - match _Unwind_Resume - match _Unwind_Resume_or_Rethrow - match _Unwind_SetGR - match _Unwind_SetIP - match __libunwind_Unwind_Backtrace - match __libunwind_Unwind_DeleteException - match __libunwind_Unwind_FindEnclosingFunction - match __libunwind_Unwind_ForcedUnwind - match __libunwind_Unwind_GetBSP - match __libunwind_Unwind_GetCFA - match __libunwind_Unwind_GetDataRelBase - match __libunwind_Unwind_GetGR - match __libunwind_Unwind_GetIP - match __libunwind_Unwind_GetIPInfo - match __libunwind_Unwind_GetLanguageSpecificData - match __libunwind_Unwind_GetRegionStart - match __libunwind_Unwind_GetTextRelBase - match __libunwind_Unwind_RaiseException - match __libunwind_Unwind_Resume - match __libunwind_Unwind_Resume_or_Rethrow - match __libunwind_Unwind_SetGR - match __libunwind_Unwind_SetIP - case $os in - linux*) - # needed only for Intel 8.0 bug-compatibility - match _ReadSLEB - match _ReadULEB - ;; - esac -} - -check_empty () { - if [ -n "$symtab" ]; then - printf " ERROR: Extraneous symbols:\n$symtab\n" - num_errors=`expr $num_errors + 1` - fi -} - -if [ $plat = $build_plat ]; then - fetch_symtab $LIBUNWIND - filter_misc - check_local_unw_abi - if [ x@enable_cxx_exceptions@ = xyes ]; then - check_cxx_abi - fi - check_empty -fi - -fetch_symtab $LIBUNWIND_GENERIC -filter_misc -check_generic_unw_abi -check_empty - -if [ $num_errors -gt 0 ]; then - echo "FAILURE: Detected $num_errors errors" - exit 1 -fi - -if $verbose; then - echo " SUCCESS: all checks passed" -fi -exit 0 diff --git a/src/coreclr/src/pal/src/libunwind/tests/crasher.c b/src/coreclr/src/pal/src/libunwind/tests/crasher.c deleted file mode 100644 index 24c78054c9478a..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/crasher.c +++ /dev/null @@ -1,124 +0,0 @@ -/* This program should crash and produce coredump */ - -#include "compiler.h" - -#include -#include -#include -#include -#ifdef __FreeBSD__ -#include -#include -#include -#endif - -#if defined(__linux__) -void write_maps(char *fname) -{ - char buf[512], path[128]; - char exec; - uintmax_t addr; - FILE *maps = fopen("/proc/self/maps", "r"); - FILE *out = fopen(fname, "w"); - - if (!maps || !out) - exit(EXIT_FAILURE); - - while (fgets(buf, sizeof(buf), maps)) - { - if (sscanf(buf, "%jx-%*x %*c%*c%c%*c %*x %*s %*d /%126[^\n]", &addr, &exec, path+1) != 3) - continue; - - if (exec != 'x') - continue; - - path[0] = '/'; - fprintf(out, "0x%jx:%s ", addr, path); - } - fprintf(out, "\n"); - - fclose(out); - fclose(maps); -} -#elif defined(__FreeBSD__) -void -write_maps(char *fname) -{ - FILE *out; - char *buf, *bp, *eb; - struct kinfo_vmentry *kv; - int mib[4], error; - size_t len; - - out = fopen(fname, "w"); - if (out == NULL) - exit(EXIT_FAILURE); - - len = 0; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_VMMAP; - mib[3] = getpid(); - error = sysctl(mib, 4, NULL, &len, NULL, 0); - if (error == -1) - exit(EXIT_FAILURE); - len = len * 4 / 3; - buf = malloc(len); - if (buf == NULL) - exit(EXIT_FAILURE); - error = sysctl(mib, 4, buf, &len, NULL, 0); - if (error == -1) - exit(EXIT_FAILURE); - - for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) { - kv = (struct kinfo_vmentry *)(uintptr_t)bp; - if (kv->kve_type == KVME_TYPE_VNODE && - (kv->kve_protection & KVME_PROT_EXEC) != 0) { - fprintf(out, "0x%jx:%s ", kv->kve_start, kv->kve_path); - } - } - - fprintf(out, "\n"); - fclose(out); - free(buf); -} -#else -#error Port me -#endif - -#ifdef __GNUC__ -int c(int x) NOINLINE ALIAS(b); -#define compiler_barrier() asm volatile(""); -#else -int c(int x); -#define compiler_barrier() -#endif - -int NOINLINE a(void) -{ - *(volatile int *)32 = 1; - return 1; -} - -int NOINLINE b(int x) -{ - int r; - - compiler_barrier(); - - if (x) - r = a(); - else - r = c(1); - return r + 1; -} - -int -main (int argc, char **argv) -{ - if (argc > 1) - write_maps(argv[1]); - b(0); - return 0; -} - diff --git a/src/coreclr/src/pal/src/libunwind/tests/flush-cache.S b/src/coreclr/src/pal/src/libunwind/tests/flush-cache.S deleted file mode 100644 index 3ee47269e18264..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/flush-cache.S +++ /dev/null @@ -1,104 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifndef HAVE__BUILTIN___CLEAR_CACHE - -#if defined(__ia64__) - - .global flush_cache - - .proc flush_cache -flush_cache: - .prologue - alloc r2=ar.pfs,2,0,0,0 - add r8=31,in1 // round up to 32 byte-boundary - ;; - shr.u r8=r8,5 // we flush 32 bytes per iteration - ;; - add r8=-1,r8 - .save ar.lc, r3 - mov r3=ar.lc // save ar.lc - ;; - .body - - mov ar.lc=r8 - ;; -.loop: fc in0 // issuable on M0 only - add in0=32,in0 - br.cloop.sptk.few .loop - ;; - sync.i - ;; - srlz.i - ;; - mov ar.lc=r3 // restore ar.lc - br.ret.sptk.many rp - .endp flush_cache - -#elif defined(__i386__) || defined (__x86_64__) - - .globl flush_cache -flush_cache: - ret - -#elif defined(__hppa__) - -# warning FIX ME!! - - .globl flush_cache -flush_cache: - .proc - .callinfo - bv %r0(%rp) - .procend -#elif defined(__powerpc64__) -# warning IMPLEMENT ME FOR PPC64!! - .globl flush_cache -flush_cache: - lwz 11, 0(1) ; - lwz 0, 4(11) ; - mtlr 0 ; - lwz 31, -4(11) ; - mr 1, 11 ; - blr -#elif defined(__powerpc__) -# warning IMPLEMENT ME FOR PPC32!! - .globl flush_cache -flush_cache: - lwz 11, 0(1) ; - lwz 0, 4(11) ; - mtlr 0 ; - lwz 31, -4(11) ; - mr 1, 11 ; - blr -#elif defined(__arm__) - .text - .globl flush_cache -flush_cache: - bx lr -#elif defined(__tilegx__) - .text - .globl flush_cache -flush_cache: - - andi r0, r0, -64 -1: { - flush r0 ; - addi r0, r0, 64 - } - { - bgtz r1, 1b ; - addi r1, r1, -64 - } - jrp lr -#else -# error Need flush_cache code for this architecture. -#endif - -#if defined ( __linux__) && !defined (__arm__) - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/flush-cache.h b/src/coreclr/src/pal/src/libunwind/tests/flush-cache.h deleted file mode 100644 index 8227d85b3f42b4..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/flush-cache.h +++ /dev/null @@ -1,38 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - -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 FLUSH_CACHE_H -#define FLUSH_CACHE_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE__BUILTIN___CLEAR_CACHE -#define flush_cache(ADDR, LEN) \ - __builtin___clear_cache((ADDR), (ADDR) + (LEN)) -#else -#include -extern void flush_cache (void *addr, size_t len); -#endif - -#endif /* FLUSH_CACHE_H */ diff --git a/src/coreclr/src/pal/src/libunwind/tests/forker.c b/src/coreclr/src/pal/src/libunwind/tests/forker.c deleted file mode 100644 index b03f86a7f03805..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/forker.c +++ /dev/null @@ -1,76 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include - -#include -#include -#include - -int -main (int argc, char **argv, char **envp) -{ - char *program, **child_argv; - struct timeval start, stop; - double secs; - int status, i; - long count; - pid_t pid; - - count = atol (argv[1]); - program = argv[2]; - - child_argv = alloca ((argc - 1) * sizeof (char *)); - for (i = 0; i < argc - 2; ++i) - child_argv[i] = argv[2 + i]; - child_argv[i] = NULL; - - gettimeofday (&start, NULL); - for (i = 0; i < count; ++i) - { - pid = fork (); - if (pid == 0) - { - execve (program, child_argv, envp); - _exit (-1); - } - else - { - waitpid (pid, &status, 0); - if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) - { - fprintf (stderr, "%s: child failed\n", argv[0]); - exit (-1); - } - } - } - gettimeofday (&stop, NULL); - - secs = ((stop.tv_sec + 1e-6 * stop.tv_usec) - - (start.tv_sec + 1e-6 * start.tv_usec)); - printf ("%lu nsec/execution\n", - (unsigned long) (1e9 * secs / (double) count)); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-dyn-asm.S b/src/coreclr/src/pal/src/libunwind/tests/ia64-dyn-asm.S deleted file mode 100644 index 79582e9e1bb9d8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ia64-dyn-asm.S +++ /dev/null @@ -1,102 +0,0 @@ - .globl func_add1, func_add1_end - .proc func_add1 -func_add1: -{.mib; add r8 = 1, r32 - nop.i 0 - br.ret.sptk.many rp -} -func_add1_end: - .endp func_add1 - - .globl func_add3, func_add3_end - .proc func_add3 -func_add3: -{.mmi; alloc loc0 = ar.pfs, 2, 1, 2, 0 - mov r2 = sp - add sp = -16, sp -} ;; -{.mii; ld8 r8 = [in1], 8 // load the function pointer - mov r3 = rp - mov rp = loc0 // trash rp -} ;; -{.mmi; ld8 r9 = [r8], 8 // load the entry-point - st8 [r2] = r3 - mov out0 = in0 -} ;; -{.mii; ld8 gp = [r8] // load the gp - mov b6 = r9 - mov out1 = in1 -} -{.mib; nop 0 - nop 0 - br.call.sptk rp = b6 -} -{.mmi; add r2 = 16, sp - ;; - ld8 r3 = [r2] // r3 = saved rp - mov ar.pfs = loc0 -} ;; -{.mii; nop 0 - mov rp = r3 - adds sp = 16, sp -} ;; -{.mib; st8 [sp] = in0 // trash rp save location - add r8 = 2, r8 - br.ret.sptk.many rp -} -func_add3_end: - .endp func_add3 - - .globl func_vframe, func_vframe_end - .proc func_vframe -func_vframe: -{.mii; alloc r16 = ar.pfs, 1, 2, 0, 0 // 0 - mov loc0 = rp - mov loc1 = sp -} ;; -{.mmi; sub sp = sp, in0 - st8 [loc1] = r16 - mov r2 = -99 // 0 -} ;; -{.mii; nop 0 - mov rp = r2 - mov ar.pfs = r0 -} -{.mib; mov r16 = r2 - tbit.nz p6, p0 = in0, 4 -(p6) br.cond.sptk.many .exit -} ;; -{.mmi; ld8 r16 = [loc1] - ;; - mov r3 = loc0 // 8 move saved rp to r3 - mov ar.pfs = r16 -} ;; -{.mmi; mov sp = loc1 // 10 - st8 [loc1] = r0 // trash saved pfs - mov loc0 = r2 -} ;; -{.mib; mov r8 = 10 - mov rp = r3 - br.ret.sptk.many rp -} -.exit: -{.mmi; ld8 r16 = [loc1] - ;; - sub sp = 32, sp - mov ar.pfs = r16 -} ;; -{.mmi; mov sp = loc1 - st8 [loc1] = r0 // trash saved pfs - mov rp = loc0 -} -{.mib; nop 0 - mov r8 = 4 - br.ret.sptk.many rp -} -func_vframe_end: - .endp func_vframe - -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-dyn1.c b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-dyn1.c deleted file mode 100644 index 90127dd5b951cc..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-dyn1.c +++ /dev/null @@ -1,223 +0,0 @@ -#include "flush-cache.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -int verbose; - -#ifdef __ia64__ -# define GET_ENTRY(fdesc) (((uintptr_t *) (fdesc))[0]) -# define GET_GP(fdesc) (((uintptr_t *) (fdesc))[0]) -# define EXTRA 16 -#else -# define GET_ENTRY(fdesc) ((uintptr_t ) (fdesc)) -# define GET_GP(fdesc) (0) -# define EXTRA 0 -#endif - -int -make_executable (void *addr, size_t len) -{ - if (mprotect ((void *) (((long) addr) & -getpagesize ()), len, - PROT_READ | PROT_WRITE | PROT_EXEC) < 0) - { - perror ("mprotect"); - return -1; - } - flush_cache (addr, len); - return 0; -} - -void * -create_func (unw_dyn_info_t *di, const char *name, long (*func) (), - void *end, unw_dyn_region_info_t *region) -{ - void *mem, *memend, *addr, *fptr; - unw_word_t gp = 0; - size_t len; - - len = (uintptr_t) end - GET_ENTRY (func) + EXTRA; - mem = malloc (len); - if (verbose) - printf ("%s: cloning %s at %p (%zu bytes)\n", - __FUNCTION__, name, mem, len); - memend = (char *) mem + len; - -#ifdef __ia64__ - addr = (void *) GET_ENTRY (func); - - /* build function descriptor: */ - ((long *) mem)[0] = (long) mem + 16; /* entry point */ - ((long *) mem)[1] = GET_GP (func); /* global-pointer */ - fptr = mem; - mem = (void *) ((long) mem + 16); -#else - fptr = mem; -#endif - - len = (char *) memend - (char *) mem; - memcpy (mem, addr, len); - - if (make_executable (mem, len) < 0) - return NULL; - - if (di) - { - memset (di, 0, sizeof (*di)); - di->start_ip = (unw_word_t) mem; - di->end_ip = (unw_word_t) memend; - di->gp = gp; - di->format = UNW_INFO_FORMAT_DYNAMIC; - di->u.pi.name_ptr = (unw_word_t) name; - di->u.pi.regions = region; - } - return fptr; -} - -int -main (int argc, char **argv) -{ - extern long func_add1 (long); - extern char func_add1_end[]; - extern long func_add3 (long, long (*[])()); - extern char func_add3_end[]; - extern long func_vframe (long); - extern char func_vframe_end[]; - unw_dyn_region_info_t *r_pro, *r_epi, *r, *rtmp; - unw_dyn_info_t di0, di1, di2, di3; - long (*add1) (long); - long (*add3_0) (long); - long (*add3_1) (long, void *[]); - long (*vframe) (long); - void *flist[2]; - long ret; - int i; - - signal (SIGUSR1, SIG_IGN); - signal (SIGUSR2, SIG_IGN); - - if (argc != 1) - verbose = 1; - - add1 = (long (*)(long)) - create_func (&di0, "func_add1", func_add1, func_add1_end, NULL); - - /* Describe the epilogue of func_add3: */ - i = 0; - r_epi = alloca (_U_dyn_region_info_size (5)); - r_epi->op_count = 5; - r_epi->next = NULL; - r_epi->insn_count = -9; - _U_dyn_op_pop_frames (&r_epi->op[i++], - _U_QP_TRUE, /* when=*/ 5, /* num_frames=*/ 1); - _U_dyn_op_stop (&r_epi->op[i++]); - assert ((unsigned) i <= r_epi->op_count); - - /* Describe the prologue of func_add3: */ - i = 0; - r_pro = alloca (_U_dyn_region_info_size (4)); - r_pro->op_count = 4; - r_pro->next = r_epi; - r_pro->insn_count = 8; - _U_dyn_op_save_reg (&r_pro->op[i++], _U_QP_TRUE, /* when=*/ 0, - /* reg=*/ UNW_IA64_AR_PFS, /* dst=*/ UNW_IA64_GR + 34); - _U_dyn_op_add (&r_pro->op[i++], _U_QP_TRUE, /* when=*/ 2, - /* reg= */ UNW_IA64_SP, /* val=*/ -16); - _U_dyn_op_save_reg (&r_pro->op[i++], _U_QP_TRUE, /* when=*/ 4, - /* reg=*/ UNW_IA64_RP, /* dst=*/ UNW_IA64_GR + 3); - _U_dyn_op_spill_sp_rel (&r_pro->op[i++], _U_QP_TRUE, /* when=*/ 7, - /* reg=*/ UNW_IA64_RP, /* off=*/ 16); - assert ((unsigned) i <= r_pro->op_count); - - /* Create regions for func_vframe: */ - i = 0; - r = alloca (_U_dyn_region_info_size (16)); - r->op_count = 16; - r->next = NULL; - r->insn_count = 4; - _U_dyn_op_label_state (&r->op[i++], /* label=*/ 100402); - _U_dyn_op_pop_frames (&r->op[i++], _U_QP_TRUE, /* when=*/ 3, /* frames=*/ 1); - _U_dyn_op_stop (&r->op[i++]); - assert ((unsigned) i <= r->op_count); - - i = 0; - rtmp = r; - r = alloca (_U_dyn_region_info_size (16)); - r->op_count = 16; - r->next = rtmp; - r->insn_count = 16; - _U_dyn_op_save_reg (&r->op[i++], _U_QP_TRUE, /* when=*/ 8, - /* reg=*/ UNW_IA64_RP, /* dst=*/ UNW_IA64_GR + 3); - _U_dyn_op_pop_frames (&r->op[i++], _U_QP_TRUE, /* when=*/ 10, - /* num_frames=*/ 1); - _U_dyn_op_stop (&r->op[i++]); - assert ((unsigned) i <= r->op_count); - - i = 0; - rtmp = r; - r = alloca (_U_dyn_region_info_size (16)); - r->op_count = 16; - r->next = rtmp; - r->insn_count = 5; - _U_dyn_op_save_reg (&r->op[i++], _U_QP_TRUE, /* when=*/ 1, - /* reg=*/ UNW_IA64_RP, /* dst=*/ UNW_IA64_GR + 33); - _U_dyn_op_save_reg (&r->op[i++], _U_QP_TRUE, /* when=*/ 2, - /* reg=*/ UNW_IA64_SP, /* dst=*/ UNW_IA64_GR + 34); - _U_dyn_op_spill_fp_rel (&r->op[i++], _U_QP_TRUE, /* when=*/ 4, - /* reg=*/ UNW_IA64_AR_PFS, /* off=*/ 16); - _U_dyn_op_label_state (&r->op[i++], /* label=*/ 100402); - _U_dyn_op_stop (&r->op[i++]); - assert ((unsigned) i <= r->op_count); - - /* Create two functions which can share the region-list: */ - add3_0 = (long (*) (long)) - create_func (&di1, "func_add3/0", func_add3, func_add3_end, r_pro); - add3_1 = (long (*) (long, void *[])) - create_func (&di2, "func_add3/1", func_add3, func_add3_end, r_pro); - vframe = (long (*) (long)) - create_func (&di3, "func_vframe", func_vframe, func_vframe_end, r); - - _U_dyn_register (&di1); - _U_dyn_register (&di2); - _U_dyn_register (&di3); - _U_dyn_register (&di0); - - flist[0] = add3_0; - flist[1] = add1; - - kill (getpid (), SIGUSR1); /* do something ptmon can latch onto */ - ret = (*add3_1) (13, flist); - if (ret != 18) - { - fprintf (stderr, "FAILURE: (*add3_1)(13) returned %ld\n", ret); - exit (-1); - } - - ret = (*vframe) (48); - if (ret != 4) - { - fprintf (stderr, "FAILURE: (*vframe)(16) returned %ld\n", ret); - exit (-1); - } - ret = (*vframe) (64); - if (ret != 10) - { - fprintf (stderr, "FAILURE: (*vframe)(32) returned %ld\n", ret); - exit (-1); - } - kill (getpid (), SIGUSR2); /* do something ptmon can latch onto */ - - _U_dyn_cancel (&di0); - _U_dyn_cancel (&di1); - _U_dyn_cancel (&di3); - _U_dyn_cancel (&di2); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-nat-asm.S b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-nat-asm.S deleted file mode 100644 index eea5ac27836e88..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-nat-asm.S +++ /dev/null @@ -1,508 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - - .text - -#define CALL_NEXT_PTR(gp_save_reg, arg0, arg1) \ - ld8 r2 = [arg0], 8;; /* read the next function pointer */ \ - ld8 r3 = [r2], 8;; /* read the function's entry-point */ \ - ld8 r2 = [r2];; /* read the function's gp */ \ - mov b6 = r3; \ - mov gp_save_reg = gp; \ - mov out0 = arg0; \ - mov out1 = arg1; \ - mov gp = r2; \ - br.call.sptk.many rp = b6;; \ - mov gp = gp_save_reg - -#define CALL_NEXT(gp_save_reg) CALL_NEXT_PTR(gp_save_reg, in0, in1) - -#define LOAD_VAL(reg) \ - ld8 reg = [in1], 8;; \ - tbit.nz p15, p0 = reg, 0;; \ -(p15) ld8.s reg = [r0] - - - .global flushrs - .proc flushrs -flushrs: - flushrs;; - br.ret.sptk.many rp - .endp flushrs - - /* Save r4-r7 into stacked registers, load them up with the - values passed via the pointer in in1 and then call the - function passed via the pointer in in0. */ - - .global save_static_to_stacked - .proc save_static_to_stacked -save_static_to_stacked: - .prologue - .regstk 2, 7, 2, 0 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 2, 7, 2, 0 - .save rp, loc1 - mov loc1 = rp - .spillreg r4, loc2 - mov loc2 = r4 - .spillreg r5, loc3 - mov loc3 = r5 - .spillreg r6, loc4 - mov loc4 = r6 - .spillreg r7, loc5 - mov loc5 = r7 - .body - LOAD_VAL(r4) - LOAD_VAL(r5) - LOAD_VAL(r6) - LOAD_VAL(r7) - CALL_NEXT(loc6) - - mov r4 = loc2 - mov r5 = loc3 - mov r6 = loc4 - mov r7 = loc5 - - mov ar.pfs = loc0 - mov rp = loc1 - br.ret.sptk.many rp - .endp save_static_to_stacked - - /* Save f2 to the memory stack, save r4 to f2, then load - r4 with the value passed via in1 and call the function - passed via in0. */ - - .global save_static_to_fr - .proc save_static_to_fr -save_static_to_fr: - .prologue - .regstk 2, 3, 2, 0 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 2, 3, 2, 0 - .save rp, loc1 - mov loc1 = rp - .fframe 16 - .spillpsp f2, 0 - stf.spill [sp] = f2, -16 - .spillreg r4, f2 - setf.sig f2 = r4 - - .body - - ld8 r4 = [in1], 8;; - tbit.nz p6, p0 = r4, 0;; -(p6) ld8.s r4 = [r0] - - CALL_NEXT(loc2) - - getf.sig r4 = f2 // restore r4 - .restore sp - add sp = 16, sp;; - ldf.fill f2 = [sp] // restore r2 - - mov ar.pfs = loc0 - mov rp = loc1 - br.ret.sptk.many rp - .endp save_static_to_fr - - /* If r4 is not a NaT, save b3 to a stacked register and - then save r4 in b3. The non-NaTness of r4 is saved in - p1. */ - - .global save_static_to_br - .proc save_static_to_br -save_static_to_br: - .prologue - .regstk 2, 6, 2, 0 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 2, 6, 2, 0 - .save rp, loc1 - mov loc1 = rp - - .save pr, loc2 - mov loc2 = pr // save predicates - - .spillreg b3, loc3 - mov loc3 = b3 - - tnat.z p1, p2 = r4;; - .spillreg.p p1, r4, b3 -(p1) mov b3 = r4 - .spillreg.p p2, r4, loc4 -(p2) mov loc4 = r4 - - .body - - LOAD_VAL(r4) - CALL_NEXT(loc5) - - .pred.rel.mutex p1, p2 -(p1) mov r4 = b3 // restore r4 -(p2) mov r4 = loc4 - - mov ar.pfs = loc0 - mov rp = loc1 - mov pr = loc2, -1 - mov b3 = loc3 // restore b3 - br.ret.sptk.many rp - .endp save_static_to_br - - /* Spill r4 into memory and then save r5 in r4. */ - - .global save_static_to_mem - .proc save_static_to_mem -save_static_to_mem: - .prologue - .regstk 2, 4, 2, 0 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 2, 4, 2, 0 - .save rp, loc1 - mov loc1 = rp - .save ar.unat, loc2 - mov loc2 = ar.unat - - .fframe 16 - .spillpsp r4, 0 - st8.spill [sp] = r4, -16 - - .spillreg r5, r4 - mov r4 = r5 - - .body - - LOAD_VAL(r5) - CALL_NEXT(loc3) - - mov r5 = r4 // restore r5 - .restore sp - add sp = 16, sp;; - ld8.fill r4 = [sp] // restore r4 - - mov ar.pfs = loc0 - mov rp = loc1 - mov ar.unat = loc2 // restore ar.unat - br.ret.sptk.many rp - .endp save_static_to_mem - - /* Spill r6 into memory and save primary ar.unat in a register. */ - - .global save_static_to_mem2 - .proc save_static_to_mem2 -save_static_to_mem2: - .prologue - .regstk 2, 5, 2, 0 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 2, 5, 2, 0 - .save rp, loc1 - mov loc1 = rp - .save ar.unat, loc2 - mov loc2 = ar.unat - - .fframe 16 - .spillpsp r6, 0 - st8.spill [sp] = r6, -16;; - .save @priunat, loc3 - mov loc3 = ar.unat - mov ar.unat = 0 // trash ar.unat - - .body - - LOAD_VAL(r6) - CALL_NEXT(loc4) - - mov ar.unat = loc3 // restore primary UNaT - .restore sp - add sp = 16, sp;; - ld8.fill r6 = [sp] // restore r6 - - mov ar.pfs = loc0 - mov rp = loc1 - mov ar.unat = loc2 // restore ar.unat - br.ret.sptk.many rp - .endp save_static_to_mem2 - - /* Spill r6 into memory and save primary ar.unat in memory. */ - - .global save_static_to_mem3 - .proc save_static_to_mem3 -save_static_to_mem3: - .prologue - .regstk 2, 5, 2, 0 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 2, 5, 2, 0 - .save rp, loc1 - mov loc1 = rp - .save ar.unat, loc2 - mov loc2 = ar.unat - - add r2 = 8, sp - .fframe 16 - .spillpsp r6, 0 - st8.spill [sp] = r6, -16;; - mov r3 = ar.unat;; - .savepsp @priunat, -8 - st8 [r2] = r3 - mov ar.unat = 0 // trash ar.unat - - .body - - LOAD_VAL(r6) - CALL_NEXT(loc4) - - add r2 = 24, sp;; - ld8 r3 = [r2];; - mov ar.unat = r3 // restore primary UNaT - .restore sp - add sp = 16, sp;; - ld8.fill r6 = [sp] // restore r6 - - mov ar.pfs = loc0 - mov rp = loc1 - mov ar.unat = loc2 // restore ar.unat - br.ret.sptk.many rp - .endp save_static_to_mem3 - - /* Spill r6 into memory and save primary ar.unat in register, - then in memory. */ - - .global save_static_to_mem4 - .proc save_static_to_mem4 -save_static_to_mem4: - .prologue - .regstk 2, 5, 2, 0 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 2, 5, 2, 0 - .save rp, loc1 - mov loc1 = rp - .save ar.unat, loc2 - mov loc2 = ar.unat - - add r2 = 8, sp - .fframe 16 - .spillpsp r6, 0 - st8.spill [sp] = r6, -16;; - .save @priunat, r3 - mov r3 = ar.unat;; - mov ar.unat = 0 // trash ar.unat - .savepsp @priunat, -8 - st8 [r2] = r3 - mov r3 = r0 // trash register pri UNaT location - .body - - LOAD_VAL(r6) - CALL_NEXT(loc4) - - add r2 = 24, sp;; - ld8 r3 = [r2];; - mov ar.unat = r3 // restore primary UNaT - .restore sp - add sp = 16, sp;; - ld8.fill r6 = [sp] // restore r6 - - mov ar.pfs = loc0 - mov rp = loc1 - mov ar.unat = loc2 // restore ar.unat - br.ret.sptk.many rp - .endp save_static_to_mem4 - - /* Spill r6 into memory and save primary ar.unat in register, - then in memory. */ - - .global save_static_to_mem5 - .proc save_static_to_mem5 -save_static_to_mem5: - .prologue - .regstk 2, 5, 2, 0 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 2, 5, 2, 0 - .save rp, loc1 - mov loc1 = rp - .save ar.unat, loc2 - mov loc2 = ar.unat - - add r2 = 8, sp - .fframe 16 - .spillpsp r6, 0 - st8.spill [sp] = r6, -16;; - mov r3 = ar.unat;; - mov ar.unat = 0 // trash ar.unat - .savepsp @priunat, -8 - st8 [r2] = r3 - .save @priunat, loc3 - mov loc3 = r3 - st8 [r2] = r0 // trash memory pri UNaT location - .body - - LOAD_VAL(r6) - CALL_NEXT(loc4) - - add r2 = 24, sp;; - ld8 r3 = [r2];; - mov ar.unat = loc3 // restore primary UNaT - .restore sp - add sp = 16, sp;; - ld8.fill r6 = [sp] // restore r6 - - mov ar.pfs = loc0 - mov rp = loc1 - mov ar.unat = loc2 // restore ar.unat - br.ret.sptk.many rp - .endp save_static_to_mem5 - - /* Save r4-r7 to various scratch registers, then trigger - a segfault. */ - - .global save_static_to_scratch - .proc save_static_to_scratch -save_static_to_scratch: - .prologue - - .spillreg r4, r16 - mov r16 = r4 // save r4 in r16 - tnat.nz p6, p7 = r5;; - .spillreg.p p6, r5, f31 -(p6) setf.sig f31 = r5 // save r5 in f31 if it's a NaT - .spillreg.p p7, r5, b6 -(p7) mov b6 = r5 // in b6 if it not - .spillreg r6, f32 - setf.sig f32 = r6 // save r6 in f32 (fph partition) - .spillsp r7, 0 - st8.spill [sp] = r7 // save r7 in the scratch stack space - .spillreg f4, f6 - mov f6 = f4;; - .body - - ld8 r2 = [in1] - ;; - mov ar.ec = r2 - - LOAD_VAL(r4) - LOAD_VAL(r5) - LOAD_VAL(r6) - LOAD_VAL(r7) - setf.sig f4 = r4 - - /* Now force a SIGSEGV. Make sure the ld8 is at the beginning of a - bundle, so the signal-handler can skip over it simply by - incrementing the IP. */ - { - .mmi - ld8 r2 = [r0] - nop.m 0 - nop.i 0 ;; - } - - mov f4 = f6 - mov r4 = r16 - .pred.rel.mutex p6, p7 -(p6) getf.sig r5 = f31 -(p7) mov r5 = b6 - getf.sig r6 = f32 - ld8.fill r7 = [sp] - - br.ret.sptk.many rp - .endp save_static_to_scratch - - /* Rotate registers a bit in a vain attempt to sow some confusion. - Care must be taken not to write any rotating general register - after rotation, because we keep the preserved state - there... */ - - .global rotate_regs - .proc rotate_regs -rotate_regs: - .prologue - .regstk 2, 14, 2, 16 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 2, 14, 2, 16 - .save rp, loc1 - mov loc1 = rp - .save pr, loc2 - mov loc2 = pr - .save ar.lc, loc3 - mov loc3 = ar.lc - .spillreg r4, loc4 - mov loc4 = r4 - - ld8 r2 = [in1], 8;; - mov pr = r2, -1 - - ld8 r2 = [in1], 8;; - mov r8 = in0 - mov r9 = in1 - and r2 = 127, r2;; - mov ar.ec = 0 - mov ar.lc = r2;; - - // use p6 to preserve p63 as it gets rotated into p16: -(p16) cmp.eq.unc p6,p0 = r0,r0;; -1: -(p6) cmp.eq.unc p16,p0 = r0,r0 -(p63) cmp.eq.unc p6,p0 = r0,r0 - br.ctop.dptk.few 1b;; - -(p6) cmp.eq.unc p63,p0 = r0,r0 - - CALL_NEXT_PTR(r4, r8, r9) - - clrrrb - - mov ar.pfs = loc0 - mov rp = loc1 - mov pr = loc2, -1 - mov ar.lc = loc3 - mov r4 = loc4 - br.ret.sptk.many rp - - .endp rotate_regs - - .global save_pr - .proc save_pr -save_pr: - .prologue - .regstk 2, 4, 2, 0 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 2, 4, 2, 0 - .save rp, loc1 - mov loc1 = rp - .save pr, loc2 - mov loc2 = pr - - ld8 r2 = [in1], 8;; - mov pr = r2, -1 - - CALL_NEXT(loc3) - - mov ar.pfs = loc0 - mov rp = loc1 - mov pr = loc2, -1 - br.ret.sptk.many rp - - .endp save_pr - -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs-asm.S b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs-asm.S deleted file mode 100644 index 9a6d33fb1de96c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs-asm.S +++ /dev/null @@ -1,275 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "ia64-test-rbs.h" - - .common stackmem, NSTACKS*STACK_SIZE, 16 - - .text - -#define SAVED_SP_OFF 0 -#define SAVED_RP_OFF 8 -#define SAVED_PFS_OFF 16 -#define SAVED_RNAT_OFF 24 -#define SAVED_BSP_OFF 32 -#define SAVED_BSPSTORE_OFF 40 -#define FRAME_SIZE 48 - -#define SPILL(n) \ - /* int rbs_spill_#n(long iteration, int (*next_func[])()) */ \ - .globl rbs_spill_##n; \ - .proc rbs_spill_##n; \ -rbs_spill_##n: \ - .prologue; \ - alloc r18 = ar.pfs, 2, (n)-2, 2, 0;/* read ar.pfs */ \ - /* first, calculate address of new stack: */ \ - addl r2 = @ltoff(stackmem), gp; \ - add r8 = 1, in0; \ - ;; \ - ld8 r2 = [r2]; /* r2 = &stackmem */ \ - shl r3 = in0, STACK_SIZE_SHIFT; \ - shladd r8 = r8, 3, in1; /* r8 = &next_func[iteration+1] */ \ - ;; \ - ld8 r8 = [r8]; /* r8 = next_func[iteration+1] */ \ - add r2 = r2, r3; /* r2 = stackmem[iteration] */ \ - ;; \ - ld8 r9 = [r8], 8;; /* r9 = target's entry-point */ \ - ld8 gp = [r8]; /* r22 = target's gp */ \ - addl r3 = STACK_SIZE-FRAME_SIZE, r2; /* r3 = &stackframe */ \ - ;; \ - mov b6 = r9; \ - st8 [r3] = sp; \ - .vframesp SAVED_SP_OFF+16; \ - adds sp = -16, r3; /* switch the memory stack */ \ - ;; \ - adds r3 = (SAVED_RP_OFF - SAVED_SP_OFF), r3; \ - mov r16 = rp; \ - ;; \ - .savesp rp, SAVED_RP_OFF+16; \ - st8 [r3] = r16, (SAVED_PFS_OFF - SAVED_RP_OFF); \ - ;; \ - .savesp ar.pfs, SAVED_PFS_OFF+16; \ - st8 [r3] = r18, (SAVED_BSP_OFF - SAVED_PFS_OFF); \ - mov r16 = ar.bsp; \ - mov r17 = ar.bspstore; \ - mov r18 = ar.rnat; \ - ;; \ - .savesp ar.bsp, SAVED_BSP_OFF+16; \ - st8 [r3] = r16, (SAVED_BSPSTORE_OFF - SAVED_BSP_OFF); \ - ;; \ - .savesp ar.bspstore, SAVED_BSPSTORE_OFF+16; \ - st8 [r3] = r17, (SAVED_RNAT_OFF - SAVED_BSPSTORE_OFF); \ - mov out1 = in1; \ - ;; \ - .savesp ar.rnat, SAVED_RNAT_OFF+16; \ - st8 [r3] = r18; \ - .body; \ - mov ar.bspstore = r2; /* switch the backing store */ \ - adds out0 = 1, in0; \ - ;; \ - br.call.sptk.many rp = b6; \ -1: /* switch back to stack: */ \ - adds r3 = SAVED_SP_OFF+16, sp; \ - cmp.ge p8, p0 = r8, r0; \ - ;; \ -(p8) add r8 = 1, r8; \ - ld8 r16 = [r3], (SAVED_RP_OFF-SAVED_SP_OFF);; /* saved sp */ \ - ld8 r17 = [r3], (SAVED_PFS_OFF-SAVED_RP_OFF);; /* saved rp */ \ - ld8 r18 = [r3], (SAVED_RNAT_OFF-SAVED_PFS_OFF);;/* saved pfs */ \ - ld8 r19 = [r3], (SAVED_BSP_OFF-SAVED_RNAT_OFF);;/* saved rnat */ \ - ld8 r20 = [r3], (SAVED_BSPSTORE_OFF-SAVED_BSP_OFF);;/* saved bsp */ \ - ld8 r21 = [r3];; /* saved bspstore */ \ - mov rp = r17; \ - mov ar.pfs = r18; \ - shl r3 = in0, STACK_SIZE_SHIFT; \ - addl r2 = @ltoff(stackmem), gp;; \ - ld8 r2 = [r2];; /* r2 = &stackmem */ \ - add r2 = r2, r3; /* r2 = stackmem[iteration] */ \ - mov r3 = ar.bsp;; \ - sub r2 = r3, r2;; /* r2 = dirty_size */ \ - shl r2 = r2, 16;; \ - mov ar.rsc = r2;; \ - alloc r3 = ar.pfs, 0, 0, 0, 0;; \ - loadrs;; \ - mov ar.bspstore = r21;; /* this also restores ar.bsp */ \ - mov ar.rnat = r19; \ - .restore sp; \ - mov sp = r16; \ - br.ret.sptk.many rp; \ - .endp rbs_spill_##n - - SPILL(2); SPILL(3) - SPILL(4); SPILL(5); SPILL(6); SPILL(7) - SPILL(8); SPILL(9); SPILL(10); SPILL(11) - SPILL(12); SPILL(13); SPILL(14); SPILL(15) - SPILL(16); SPILL(17); SPILL(18); SPILL(19) - SPILL(20); SPILL(21); SPILL(22); SPILL(23) - SPILL(24); SPILL(25); SPILL(26); SPILL(27) - SPILL(28); SPILL(29); SPILL(30); SPILL(31) - SPILL(32); SPILL(33); SPILL(34); SPILL(35) - SPILL(36); SPILL(37); SPILL(38); SPILL(39) - SPILL(40); SPILL(41); SPILL(42); SPILL(43) - SPILL(44); SPILL(45); SPILL(46); SPILL(47) - SPILL(48); SPILL(49); SPILL(50); SPILL(51) - SPILL(52); SPILL(53); SPILL(54); SPILL(55) - SPILL(56); SPILL(57); SPILL(58); SPILL(59) - SPILL(60); SPILL(61); SPILL(62); SPILL(63) - SPILL(64); SPILL(65); SPILL(66); SPILL(67) - SPILL(68); SPILL(69); SPILL(70); SPILL(71) - SPILL(72); SPILL(73); SPILL(74); SPILL(75) - SPILL(76); SPILL(77); SPILL(78); SPILL(79) - SPILL(80); SPILL(81); SPILL(82); SPILL(83) - SPILL(84); SPILL(85); SPILL(86); SPILL(87) - SPILL(88); SPILL(89); SPILL(90); SPILL(91) - SPILL(92); SPILL(93); SPILL(94) - -#define LD_LOC(n) \ - ld4 loc##n = [in1], 4;; \ - cmp.eq p8, p9 = r0, loc##n;; \ -(p9) or loc##n = loc##n, r8; \ -(p8) ld4.s loc##n = [r0] - -#define CK_LOC(n) \ - ld4 r16 = [in1], 4;; \ - cmp.eq p8, p9 = r0, r16; \ - or r16 = r16, r9;; \ -(p8) tnat.z p10, p0 = loc##n; \ -(p9) cmp.ne p10, p0 = r16, loc##n; \ - ;; \ -(p10) mov r8 = -n; \ -(p10) br.cond.spnt.many .fail - - /* int loadup(long iteration, int *values, next_func[]) */ - - .global loadup - .proc loadup -loadup: - .prologue - .save ar.pfs, r36 - alloc loc1 = ar.pfs, 3, 90, 3, 0 - .save rp, loc0 - mov loc0 = rp - .body - cmp.eq p6, p7 = 1, in0 - ;; - mov ar.rsc = 0 // put RSE into enforced lazy mode -(p6) mov out1 = in2 -(p7) mov out2 = in2 - -(p6) ld8 r17 = [in2] // get address of function descriptor -(p7) add out0 = -1, in0 -(p7) mov out1 = in1 - - ;; -(p6) ld8 r16 = [r17], 8 // load entry point - shl r8 = in0, 32 // store iteration # in top 32 bits - mov r18 = in1 - ;; -(p6) ld8 r1 = [r17] // load gp -(p6) mov b6 = r16 - -(p6) mov out0 = 0 - ;; - LD_LOC( 2); LD_LOC( 3) - LD_LOC( 4); LD_LOC( 5); LD_LOC( 6); LD_LOC( 7) - LD_LOC( 8); LD_LOC( 9); LD_LOC(10); LD_LOC(11) - LD_LOC(12); LD_LOC(13); LD_LOC(14); LD_LOC(15) - LD_LOC(16); LD_LOC(17); LD_LOC(18); LD_LOC(19) - LD_LOC(20); LD_LOC(21); LD_LOC(22); LD_LOC(23) - LD_LOC(24); LD_LOC(25); LD_LOC(26); LD_LOC(27) - LD_LOC(28); LD_LOC(29); LD_LOC(30); LD_LOC(31) - LD_LOC(32); LD_LOC(33); LD_LOC(34); LD_LOC(35) - LD_LOC(36); LD_LOC(37); LD_LOC(38); LD_LOC(39) - LD_LOC(40); LD_LOC(41); LD_LOC(42); LD_LOC(43) - LD_LOC(44); LD_LOC(45); LD_LOC(46); LD_LOC(47) - LD_LOC(48); LD_LOC(49); LD_LOC(50); LD_LOC(51) - LD_LOC(52); LD_LOC(53); LD_LOC(54); LD_LOC(55) - LD_LOC(56); LD_LOC(57); LD_LOC(58); LD_LOC(59) - LD_LOC(60); LD_LOC(61); LD_LOC(62); LD_LOC(63) - LD_LOC(64); LD_LOC(65); LD_LOC(66); LD_LOC(67) - LD_LOC(68); LD_LOC(69); LD_LOC(70); LD_LOC(71) - LD_LOC(72); LD_LOC(73); LD_LOC(74); LD_LOC(75) - LD_LOC(76); LD_LOC(77); LD_LOC(78); LD_LOC(79) - LD_LOC(80); LD_LOC(81); LD_LOC(82); LD_LOC(83) - LD_LOC(84); LD_LOC(85); LD_LOC(86); LD_LOC(87) - LD_LOC(88); LD_LOC(89) - ;; -{ .mbb - mov in1 = r18 -(p6) br.call.sptk.many rp = b6 -(p7) br.call.sptk.many rp = loadup -} - cmp.lt p8, p9 = r8, r0 - shl r9 = in0, 32 // store iteration # in top 32 bits -(p8) br.cond.spnt.few .fail - ;; - add r8 = 1, r8 - CK_LOC( 2); CK_LOC( 3) - CK_LOC( 4); CK_LOC( 5); CK_LOC( 6); CK_LOC( 7) - CK_LOC( 8); CK_LOC( 9); CK_LOC(10); CK_LOC(11) - CK_LOC(12); CK_LOC(13); CK_LOC(14); CK_LOC(15) - CK_LOC(16); CK_LOC(17); CK_LOC(18); CK_LOC(19) - CK_LOC(20); CK_LOC(21); CK_LOC(22); CK_LOC(23) - CK_LOC(24); CK_LOC(25); CK_LOC(26); CK_LOC(27) - CK_LOC(28); CK_LOC(29); CK_LOC(30); CK_LOC(31) - CK_LOC(32); CK_LOC(33); CK_LOC(34); CK_LOC(35) - CK_LOC(36); CK_LOC(37); CK_LOC(38); CK_LOC(39) - CK_LOC(40); CK_LOC(41); CK_LOC(42); CK_LOC(43) - CK_LOC(44); CK_LOC(45); CK_LOC(46); CK_LOC(47) - CK_LOC(48); CK_LOC(49); CK_LOC(50); CK_LOC(51) - CK_LOC(52); CK_LOC(53); CK_LOC(54); CK_LOC(55) - CK_LOC(56); CK_LOC(57); CK_LOC(58); CK_LOC(59) - CK_LOC(60); CK_LOC(61); CK_LOC(62); CK_LOC(63) - CK_LOC(64); CK_LOC(65); CK_LOC(66); CK_LOC(67) - CK_LOC(68); CK_LOC(69); CK_LOC(70); CK_LOC(71) - CK_LOC(72); CK_LOC(73); CK_LOC(74); CK_LOC(75) - CK_LOC(76); CK_LOC(77); CK_LOC(78); CK_LOC(79) - CK_LOC(80); CK_LOC(81); CK_LOC(82); CK_LOC(83) - CK_LOC(84); CK_LOC(85); CK_LOC(86); CK_LOC(87) - CK_LOC(88); CK_LOC(89) -.fail: - mov rp = loc0 - mov ar.pfs = loc1 - br.ret.sptk.many rp - .endp loadup - - .global resumption_point_label - .proc resumption_point -resumption_point: -resumption_point_label: - .prologue - .save rp, r16 - .save ar.pfs, r0 - .body - mov r8 = r15 - mov b6 = r16 - ;; - br.cond.sptk.many b6 - .endp resumption_point - -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs.h b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs.h deleted file mode 100644 index 3315ad638006ea..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs.h +++ /dev/null @@ -1,3 +0,0 @@ -#define NSTACKS 128 -#define STACK_SIZE_SHIFT 17 -#define STACK_SIZE (1 << STACK_SIZE_SHIFT) diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-readonly-asm.S b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-readonly-asm.S deleted file mode 100644 index acd3ada2c6497c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-readonly-asm.S +++ /dev/null @@ -1,55 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - - .text - - .global test_func - .proc test_func -test_func: - .prologue - .regstk 1, 3, 0, 0 - .save ar.pfs, loc0 - alloc loc0 = ar.pfs, 1, 3, 0, 0 - mov loc1 = rp - .save rp, r0 - .save ar.lc, r0 - .body - mov loc2 = gp - ld8 r2 = [in0], 8;; - ld8 r1 = [in0];; - mov b6 = r2 - br.call.sptk.many rp = b6 - - mov gp = loc2 - mov rp = loc1 - mov ar.pfs = loc0 - br.ret.sptk.many rp - - .endp test_func - -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-setjmp.c b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-setjmp.c deleted file mode 100644 index 50eaa01bc30feb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-setjmp.c +++ /dev/null @@ -1,155 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* Test to verify that we can siglongjmp() into a frame whose register - window is not backed by valid memory. */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_IA64INTRIN_H -# include -#endif - -static sigjmp_buf env; -static int return_level; -static uintptr_t return_bsp; -static int verbose; - -uintptr_t -get_bsp (void) -{ -#ifdef __INTEL_COMPILER - return __getReg (_IA64_REG_AR_BSP); -#else - return (uintptr_t) __builtin_ia64_bsp (); -#endif -} - -static void -sighandler (int signal, void *siginfo, void *sigcontext) -{ - ucontext_t *uc = sigcontext; - int local = 0; - - if (verbose) - printf ("got signal, stack at %p, saved bsp=0x%lx\n", - &local, uc->uc_mcontext.sc_ar_bsp); - siglongjmp (env, 1); -} - -/* Direct call of doit () at the end of doit () would get optimized by GCC to - a branch. */ -static void doit (int n); -typedef void (*doit_type) (int); -static volatile doit_type doit_pointer = doit; - -static void -doit (int n) -{ - uintptr_t guard_page_addr, bsp = get_bsp (); - void *ret; - - if (n == 0) - { - size_t page_size = getpagesize (); - - guard_page_addr = (bsp + page_size - 1) & -page_size; - if (verbose) - printf ("guard_page_addr = 0x%lx\n", (unsigned long) guard_page_addr); - ret = mmap ((void *) guard_page_addr, page_size, PROT_NONE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (ret != (void *) guard_page_addr) - { - if (ret == MAP_FAILED) - perror ("mmap"); - else - fprintf (stderr, "mmap() returned %p, expected 0x%lx\n", - ret, guard_page_addr); - exit (EXIT_FAILURE); - } - } - - if (sigsetjmp (env, 1)) - { - return_level = n; - return_bsp = bsp; - } - else - (*doit_pointer) (n + 1); -} - -int -main (int argc, char **argv) -{ - struct sigaction sa; - stack_t ss; - - if (argc > 1) - verbose = 1; - - ss.ss_sp = malloc (2 * SIGSTKSZ); - if (ss.ss_sp == NULL) - { - puts ("failed to allocate alternate stack"); - return EXIT_FAILURE; - } - ss.ss_flags = 0; - ss.ss_size = 2 * SIGSTKSZ; - if (sigaltstack (&ss, NULL) < 0) - { - printf ("sigaltstack failed: %s\n", strerror (errno)); - return EXIT_FAILURE; - } - - sa.sa_handler = (void (*) (int)) sighandler; - sigemptyset (&sa.sa_mask); - sa.sa_flags = SA_SIGINFO | SA_ONSTACK; - if (sigaction (SIGSEGV, &sa, NULL) < 0) - { - printf ("sigaction failed: %s\n", strerror (errno)); - exit (1); - } - - doit (0); - - if (verbose) - { - printf ("sigsetjmp returned at level %d bsp=0x%lx\n", - return_level, return_bsp); - puts ("Test succeeded!"); - } - return EXIT_SUCCESS; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-sig.c b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-sig.c deleted file mode 100644 index 473efe91d758be..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-sig.c +++ /dev/null @@ -1,102 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2001-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 test uses the unwind interface to modify the IP in an ancestor - frame while still returning to the parent frame. */ - -#include -#include -#include - -#include - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -int verbose; - -static void -sighandler (int signal) -{ - unw_cursor_t cursor, cursor2; - unw_word_t ip; - unw_context_t uc; - - if (verbose) - printf ("caught signal %d\n", signal); - - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - panic ("unw_init() failed!\n"); - - /* get cursor for caller of sighandler: */ - if (unw_step (&cursor) < 0) - panic ("unw_step() failed!\n"); - - cursor2 = cursor; - while (!unw_is_signal_frame (&cursor2)) - if (unw_step (&cursor2) < 0) - panic ("failed to find signal frame!\n"); - - if (unw_step (&cursor2) < 0) - panic ("unw_step() failed!\n"); - - if (unw_get_reg (&cursor2, UNW_REG_IP, &ip) < 0) - panic ("failed to get IP!\n"); - - /* skip faulting instruction (doesn't handle MLX template) */ - ++ip; - if ((ip & 0x3) == 0x3) - ip += 13; - - if (unw_set_reg (&cursor2, UNW_REG_IP, ip) < 0) - panic ("failed to set IP!\n"); - - unw_resume (&cursor); /* update context & return to caller of sighandler() */ - - panic ("unexpected return from unw_resume()!\n"); -} - -static void -doit (volatile char *p) -{ - int ch; - - ch = *p; /* trigger SIGSEGV */ - - if (verbose) - printf ("doit: finishing execution!\n"); -} - -int -main (int argc, char **argv) -{ - if (argc > 1) - verbose = 1; - - signal (SIGSEGV, sighandler); - doit (0); - if (verbose) - printf ("SUCCESS\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack-asm.S b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack-asm.S deleted file mode 100644 index 0aea33a441345f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack-asm.S +++ /dev/null @@ -1,183 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "ia64-test-stack.h" - - .common stackmem, NSTACKS*STACK_SIZE, 16 - - .global do_unwind_tests - - .text - -#define SAVED_SP_OFF 0 -#define SAVED_RP_OFF 8 -#define SAVED_PFS_OFF 16 -#define SAVED_RNAT_OFF 24 -#define SAVED_BSP_OFF 32 -#define SAVED_BSPSTORE_OFF 40 -#define FRAME_SIZE 48 - - .proc stack_it -stack_it: - .prologue - alloc r18 = ar.pfs, 0, 0, 0, 0 // read ar.pfs - // first, calculate address of new stack: - addl r2 = @ltoff(stackmem), gp - shl r3 = r8, STACK_SIZE_SHIFT - ;; - ld8 r2 = [r2] // r2 = &stackmem - ;; - add r2 = r2, r3 // r2 = stackmem[iteration] - ;; - addl r3 = STACK_SIZE-FRAME_SIZE, r2 // r3 = &stackframe - ;; - st8 [r3] = sp - .vframesp SAVED_SP_OFF+16 - adds sp = -16, r3 // switch the memory stack - ;; - adds r3 = (SAVED_RP_OFF - SAVED_SP_OFF), r3 - mov r16 = rp - ;; - .savesp rp, SAVED_RP_OFF+16 - st8 [r3] = r16, (SAVED_PFS_OFF - SAVED_RP_OFF) - ;; - .savesp ar.pfs, SAVED_PFS_OFF+16 - st8 [r3] = r18, (SAVED_BSP_OFF - SAVED_PFS_OFF) - - mov r16 = ar.bsp - mov r17 = ar.bspstore - mov r18 = ar.rnat - ;; - .savesp ar.bsp, SAVED_BSP_OFF+16 - st8 [r3] = r16, (SAVED_BSPSTORE_OFF - SAVED_BSP_OFF) - ;; - .savesp ar.bspstore, SAVED_BSPSTORE_OFF+16 - st8 [r3] = r17, (SAVED_RNAT_OFF - SAVED_BSPSTORE_OFF) - ;; - .savesp ar.rnat, SAVED_RNAT_OFF+16 - st8 [r3] = r18 - ;; - mov ar.bspstore = r2 // switch the backing store - - .body - - // for even iterations, allocate a local variable: - tbit.nz p6, p0 = r8, 0 -(p6) br.cond.sptk.few .skip - ;; - alloc r2 = ar.pfs, 0, 1, 0, 0 - mov loc0 = r8 - ;; -.skip: cmp.ne p6, p7 = 0, r8 - ;; -{ .mbb -(p6) adds r8 = -1, r8 -(p6) br.call.sptk.many rp = stack_it // next iteration -(p7) br.call.sptk.many rp = do_unwind_tests // time for introspection... -} - // switch back to stack: - - adds r3 = SAVED_SP_OFF+16, sp - ;; - ld8 r16 = [r3], (SAVED_RP_OFF-SAVED_SP_OFF);; // saved sp - ld8 r17 = [r3], (SAVED_PFS_OFF-SAVED_RP_OFF);; // saved rp - ld8 r18 = [r3], (SAVED_RNAT_OFF-SAVED_PFS_OFF);; // saved pfs - ld8 r19 = [r3], (SAVED_BSP_OFF-SAVED_RNAT_OFF);; // saved rnat - ld8 r20 = [r3], (SAVED_BSPSTORE_OFF-SAVED_BSP_OFF);; // saved bsp - ld8 r21 = [r3];; // saved bspstore - - mov rp = r17 - mov ar.pfs = r18 - mov ar.bspstore = r21 // this also restores ar.bsp - ;; - mov ar.rnat = r19 - - .restore sp - mov sp = r16 - br.ret.sptk.many rp - .endp stack_it - - -#define SET_LOC(n) add loc##n = n, r8 -#define SET_NAT(n) ld8.s loc##n = [r0] - - .global touch_all - .proc touch_all -touch_all: - .prologue - .save ar.pfs, r34 - alloc loc1 = ar.pfs, 1, 94, 1, 0 - .save rp, loc0 - mov loc0 = rp - .body - - mov ar.rsc = 0 // put RSE into enforced lazy mode - shl r8 = in0, 32 // store iteration # in top 32 bits - add out0 = -1, in0 - cmp.eq p6, p7 = 1, in0 - ;; - SET_LOC( 2); SET_LOC( 3) - SET_LOC( 4); SET_LOC( 5); SET_LOC( 6); SET_LOC( 7) - SET_LOC( 8); SET_LOC( 9); SET_LOC(10); SET_LOC(11) - SET_LOC(12); SET_LOC(13); SET_LOC(14); SET_LOC(15) - SET_LOC(16); SET_LOC(17); SET_LOC(18); SET_LOC(19) - SET_LOC(20); SET_LOC(21); SET_LOC(22); SET_LOC(23) - SET_LOC(24); SET_LOC(25); SET_LOC(26); SET_LOC(27) - SET_LOC(28); SET_LOC(29); SET_LOC(30); SET_LOC(31) - SET_LOC(32); SET_LOC(33); SET_LOC(34); SET_LOC(35) - SET_LOC(36); SET_LOC(37); SET_LOC(38); SET_LOC(39) - SET_LOC(40); SET_LOC(41); SET_LOC(42); SET_LOC(43) - SET_LOC(44); SET_LOC(45); SET_LOC(46); SET_LOC(47) - SET_LOC(48); SET_LOC(49); SET_LOC(50); SET_LOC(51) - SET_LOC(52); SET_LOC(53); SET_LOC(54); SET_LOC(55) - SET_LOC(56); SET_LOC(57); SET_LOC(58); SET_LOC(59) - SET_LOC(60); SET_LOC(61); SET_LOC(62); SET_LOC(63) - SET_LOC(64); SET_LOC(65); SET_LOC(66); SET_LOC(67) - SET_LOC(68); SET_LOC(69); SET_LOC(70); SET_LOC(71) - SET_LOC(72); SET_LOC(73); SET_LOC(74); SET_LOC(75) - SET_LOC(76); SET_LOC(77); SET_LOC(78); SET_LOC(79) - SET_LOC(80); SET_LOC(81); SET_LOC(82); SET_LOC(83) - SET_LOC(84); SET_LOC(85); SET_LOC(86); SET_LOC(87) - SET_LOC(88); SET_LOC(89); SET_LOC(90); SET_LOC(91) - SET_LOC(92); SET_LOC(93) - ;; - SET_NAT(2); SET_NAT(31); SET_NAT(73); SET_NAT(93) - ;; -{ .mbb - mov r8=NSTACKS-1 -(p6) br.call.sptk.many rp = stack_it -(p7) br.call.sptk.many rp = touch_all -} - ;; - - mov rp = loc0 - mov ar.pfs = loc1 - br.ret.sptk.many rp - .endp touch_all - -#ifdef __linux__ - /* We do not need executable stack. */ - .section .note.GNU-stack,"",@progbits -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack.h b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack.h deleted file mode 100644 index 5665a79d9564ba..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack.h +++ /dev/null @@ -1,3 +0,0 @@ -#define NSTACKS 1024 -#define STACK_SIZE_SHIFT 17 -#define STACK_SIZE (1 << STACK_SIZE_SHIFT) diff --git a/src/coreclr/src/pal/src/libunwind/tests/ident.c b/src/coreclr/src/pal/src/libunwind/tests/ident.c deleted file mode 100644 index 9024e292f5a542..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ident.c +++ /dev/null @@ -1,5 +0,0 @@ -long -f (long val) -{ - return val; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/mapper.c b/src/coreclr/src/pal/src/libunwind/tests/mapper.c deleted file mode 100644 index b47ae780f8ede8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/mapper.c +++ /dev/null @@ -1,78 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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 program creates lots of mappings such that on Linux the - reading of /proc/PID/maps gets very slow. With proper caching, - test-ptrace should still run at acceptable speed once - /proc/PID/maps has been scanned. If the program dies with a - SIGALRM, it means it was running unexpectedly slow. */ - -#include -#include -#include -#include - -#include - -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -# define MAP_ANONYMOUS MAP_ANON -#endif -#if !defined(MAP_NORESERVE) -# define MAP_NORESERVE 0 -#endif - -int -main (void) -{ - long n = 0; - - signal (SIGUSR1, SIG_IGN); - signal (SIGUSR2, SIG_IGN); - - printf ("Starting mmap test...\n"); - for (n = 0; n < 30000; ++n) - { - if (mmap (NULL, 1, (n & 1) ? PROT_READ : PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS -#ifdef MAP_NORESERVE - | MAP_NORESERVE -#endif - , - -1, 0) == MAP_FAILED) - { - printf ("Failed after %ld successful maps\n", n - 1); - exit (0); - } - } - - alarm (80); /* die if we don't finish in 80 seconds */ - - printf ("Turning on single-stepping...\n"); - kill (getpid (), SIGUSR1); /* tell test-ptrace to start single-stepping */ - printf ("Va bene?\n"); - kill (getpid (), SIGUSR2); /* tell test-ptrace to stop single-stepping */ - printf ("Turned single-stepping off...\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/perf-startup b/src/coreclr/src/pal/src/libunwind/tests/perf-startup deleted file mode 100755 index 1c24e9a9bc3b54..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/perf-startup +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -platform=$1 -LIBUNWIND=../src/.libs/libunwind.so -LIBUNWIND_PLAT=../src/.libs/libunwind-$platform.so -warmup=$(./forker 2000 /bin/true | cut -f1 -d' ') - -nsec1=$(./forker 2000 /bin/true | cut -f1 -d' ') -printf "\"/bin/true\"\t\t\t\t\t\t: $nsec1 nsec/execution\n" - -nsec2=$(LD_PRELOAD=$LIBUNWIND ./forker 2000 /bin/true | cut -f1 -d' ') -printf "\"LD_PRELOAD=$LIBUNWIND /bin/true\"\t: $nsec2 nsec/execution\n" - -nsec3=$(LD_PRELOAD=$LIBUNWIND_PLAT ./forker 2000 /bin/true | cut -f1 -d' ') -printf "\"LD_PRELOAD=$LIBUNWIND_PLAT /bin/true\"\t: $nsec3 nsec/execution\n" - -echo - -printf "Overhead of preloading $LIBUNWIND\t: $(($nsec2 - $nsec1)) nsec\n" -printf "Overhead of preloading $LIBUNWIND_PLAT\t: $(($nsec3 - $nsec1)) nsec\n" diff --git a/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec-utils.c b/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec-utils.c deleted file mode 100644 index bd67ff7d6e0265..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec-utils.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -union si_overlay -{ - vector signed int v; - int ints[4]; -}; - -vector signed int -vec_init () -{ - vector signed int v; - static int count = 1; - - ((union si_overlay *) &v)->ints[0] = count++; - ((union si_overlay *) &v)->ints[1] = count++; - ((union si_overlay *) &v)->ints[2] = count++; - ((union si_overlay *) &v)->ints[3] = count++; - return v; -} - -void -vec_print (vector signed int v) -{ - printf ("%08x %08x %08x %08x", - ((union si_overlay *) &v)->ints[0], - ((union si_overlay *) &v)->ints[1], - ((union si_overlay *) &v)->ints[2], - ((union si_overlay *) &v)->ints[3]); -} - diff --git a/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec.c b/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec.c deleted file mode 100644 index a3e95eefbbc129..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec.c +++ /dev/null @@ -1,177 +0,0 @@ - - -#include -#include -#include -#include -#include -#include - -#include - -#define panic(args...) { fprintf (stderr, args); abort(); } - -extern vector signed int vec_init (); -extern void vec_print (vector signed int v); - -vector signed int vec_stack (int count); - -int -main () -{ - printf ("&vec_stack = %016lx\n", (unsigned long) vec_stack); - vec_stack (3); - return 0; -} - - -vector signed int -vec_stack (int count) -{ - register vector signed int v1; - register vector signed int v2; - register vector signed int v3; - register vector signed int v4; - register vector signed int v5; - register vector signed int v6; - register vector signed int v7; - register vector signed int v8; - register vector signed int v9; - - unw_fpreg_t vr; - - unw_cursor_t cursor; - unw_word_t ip, sp; - unw_context_t uc; - int ret; - int verbose = 1; - - /* if (count == 0) return vec_init(); */ - - if (count == 0) - { - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - { - panic ("unw_init_local failed!\n"); - } - else - { - do - { - if ((ret = unw_get_reg (&cursor, UNW_REG_IP, &ip)) < 0) - { - panic ("FAILURE: unw_get_reg returned %d for UNW_REG_IP\n", - ret); - } - if ((ret = unw_get_reg (&cursor, UNW_REG_SP, &sp)) < 0) - { - panic ("FAILURE: unw_get_reg returned %d for UNW_REG_SP\n", - ret); - } - if ((ret = unw_get_fpreg (&cursor, UNW_PPC64_V30, &vr)) < 0) - { - panic - ("FAILURE: unw_get_vreg returned %d for UNW_PPC64_V30\n", - ret); - } - - - if (verbose) - { - const char *regname = unw_regname (UNW_PPC64_V30); - char proc_name_buffer[256]; - unw_word_t offset; - unsigned int * vec_half1, * vec_half2; - vec_half1 = (unsigned int *)&vr; - vec_half2 = vec_half1 + 1; - printf ("ip = %016lx, sp=%016lx\n", (long) ip, (long) sp); - printf ("vr30 = %08x %08x %08x %08x\n", - (unsigned int) (*vec_half1 >> 16), - (unsigned int) (*vec_half1 & 0xffffffff), - (unsigned int) (*vec_half2 >> 16), - (unsigned int) (*vec_half2 & 0xffffffff)); - ret = - unw_get_proc_name (&cursor, proc_name_buffer, - sizeof (proc_name_buffer), &offset); - if (ret == 0) - { - printf ("proc name = %s, offset = %lx\n", - proc_name_buffer, offset); - } - else - { - panic ("unw_get_proc_name returned %d\n", ret); - } - printf ("unw_regname(UNW_PPC_V30) = %s\n\n", regname); - } - - ret = unw_step (&cursor); - if (ret < 0) - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - panic ("FAILURE: unw_step() returned %d for ip=%lx\n", ret, - (long) ip); - } - } - while (ret > 0); - } - } - - v1 = vec_init (); - v2 = vec_init (); - v3 = vec_init (); - v4 = vec_init (); - v5 = vec_init (); - v6 = vec_init (); - - /* make use of all of the registers in some calculation */ - v7 = - vec_nor (v1, vec_add (v2, vec_sub (v3, vec_and (v4, vec_or (v5, v6))))); - - /* - * "force" the registers to be non-volatile by making a call and also - * using the registers after the call. - */ - v8 = vec_stack (count - 1); - - /* - * Use the result from the previous call, plus all of the non-volatile - * registers in another calculation. - */ - v9 = - vec_nor (v1, - vec_add (v2, - vec_sub (v3, - vec_and (v4, vec_or (v5, vec_xor (v6, v8)))))); - - printf ("v1 - "); - vec_print (v1); - printf ("\n"); - printf ("v2 - "); - vec_print (v2); - printf ("\n"); - printf ("v3 - "); - vec_print (v3); - printf ("\n"); - printf ("v4 - "); - vec_print (v4); - printf ("\n"); - printf ("v5 - "); - vec_print (v5); - printf ("\n"); - printf ("v6 - "); - vec_print (v6); - printf ("\n"); - printf ("v7 - "); - vec_print (v7); - printf ("\n"); - printf ("v8 - "); - vec_print (v8); - printf ("\n"); - printf ("v9 - "); - vec_print (v9); - printf ("\n"); - - return v9; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-check-namespace b/src/coreclr/src/pal/src/libunwind/tests/run-check-namespace deleted file mode 100755 index d57c8642a270e7..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/run-check-namespace +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -chmod +x ./check-namespace.sh -./check-namespace.sh $* diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind b/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind deleted file mode 100755 index 8d077425746023..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh - -# this function is slight modification of the one used in RPM -# found at https://bugzilla.redhat.com/show_bug.cgi?id=834073 -# written by Alexander Larsson -add_minidebug() -{ - debuginfo="$1" ## we don't have separate debuginfo file - binary="$1" - - dynsyms=`mktemp` - funcsyms=`mktemp` - keep_symbols=`mktemp` - mini_debuginfo=`mktemp` - - # Extract the dynamic symbols from the main binary, there is no need to also have these - # in the normal symbol table - nm -D "$binary" --format=posix --defined-only | awk '{ print $1 }' | sort > "$dynsyms" - # Extract all the text (i.e. function) symbols from the debuginfo - nm "$debuginfo" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t") print $1 }' | sort > "$funcsyms" - # Keep all the function symbols not already in the dynamic symbol table - comm -13 "$dynsyms" "$funcsyms" > "$keep_symbols" - # Copy the full debuginfo, keeping only a minumal set of symbols and removing some unnecessary sections - objcopy -S --remove-section .gdb_index --remove-section .comment --keep-symbols="$keep_symbols" "$debuginfo" "$mini_debuginfo" &> /dev/null - #Inject the compressed data into the .gnu_debugdata section of the original binary - xz "$mini_debuginfo" - mini_debuginfo="${mini_debuginfo}.xz" - objcopy --add-section .gnu_debugdata="$mini_debuginfo" "$binary" - rm -f "$dynsyms" "$funcsyms" "$keep_symbols" "$mini_debuginfo" - - strip "$binary" ## throw away the symbol table -} - - -TESTDIR=`pwd` -TEMPDIR=`mktemp --tmpdir -d libunwind-test-XXXXXXXXXX` -trap "rm -r -- $TEMPDIR" EXIT - -cp crasher $TEMPDIR/crasher -if [ "$1" = "-minidebuginfo" ]; then - add_minidebug $TEMPDIR/crasher -fi - -# create core dump -( - cd $TEMPDIR - ulimit -c 10000 - ./crasher backing_files -) 2>/dev/null -COREFILE=$TEMPDIR/core* - -# magic option -testcase enables checking for the specific contents of the stack -./test-coredump-unwind $COREFILE -testcase `cat $TEMPDIR/backing_files` diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind-mdi b/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind-mdi deleted file mode 100755 index d0a315b8e32c67..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind-mdi +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# This test intends to test the unw_get_proc_name function on binaries without -# the symbol table but with so called MiniDebuginfo available. In particular, -# it is tested using the coredump accessors. For more info about MiniDebugInfo -# see e.g. http://fedoraproject.org/wiki/Features/MiniDebugInfo - -${0%/*}/run-coredump-unwind -minidebuginfo diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-ia64-test-dyn1 b/src/coreclr/src/pal/src/libunwind/tests/run-ia64-test-dyn1 deleted file mode 100755 index acce944ca15b6e..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/run-ia64-test-dyn1 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -./test-ptrace -t ./ia64-test-dyn1 diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-mapper b/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-mapper deleted file mode 100755 index dc3010d4b33fe8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-mapper +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -./test-ptrace -c -n -t ./mapper $* diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-misc b/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-misc deleted file mode 100755 index c3a6552f1de935..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-misc +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -./test-ptrace -c -t ./test-ptrace-misc diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-async-sig.c b/src/coreclr/src/pal/src/libunwind/tests/test-async-sig.c deleted file mode 100644 index 2ce8b4bb711d03..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-async-sig.c +++ /dev/null @@ -1,193 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* Check whether basic unwinding truly is async-signal safe. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "compiler.h" - -#include -#include -#include -#include -#include - -#include - -#define UNW_LOCAL_ONLY -#include - -static const int nerrors_max = 100; - -struct itimerval interval = - { - .it_interval = { .tv_sec = 0, .tv_usec = 0 }, - .it_value = { .tv_sec = 0, .tv_usec = 1000 } - }; - -int verbose; -int nerrors; -int sigcount; - -#ifndef CONFIG_BLOCK_SIGNALS -/* When libunwind is configured with --enable-block-signals=no, the caller - is responsible for preventing recursion via signal handlers. - We use a simple global here. In a multithreaded program, one would use - a thread-local variable. */ -int recurcount; -#endif - -#define panic(args...) \ - { ++nerrors; fprintf (stderr, args); return; } - -static void -do_backtrace (int may_print, int get_proc_name) -{ - char buf[512], name[256]; - unw_cursor_t cursor; - unw_word_t ip, sp, off; - unw_context_t uc; - int ret; - int depth = 0; - -#ifndef CONFIG_BLOCK_SIGNALS - if (recurcount > 0) - return; - recurcount += 1; -#endif - - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - panic ("unw_init_local failed!\n"); - - do - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - unw_get_reg (&cursor, UNW_REG_SP, &sp); - - buf[0] = '\0'; - if (get_proc_name || (may_print && verbose)) - { - ret = unw_get_proc_name (&cursor, name, sizeof (name), &off); - if (ret == 0 && (may_print && verbose)) - { - if (off) - snprintf (buf, sizeof (buf), "<%s+0x%lx>", name, (long) off); - else - { - size_t len = strlen (name); - buf[0] = '<'; - memcpy (buf + 1, name, len); - buf[len + 1] = '>'; - buf[len + 2] = '\0'; - } - } - } - - if (may_print && verbose) - printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); - - ret = unw_step (&cursor); - if (ret < 0) - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - panic ("FAILURE: unw_step() returned %d for ip=%lx\n", - ret, (long) ip); - } - if (depth++ > 100) - { - panic ("FAILURE: unw_step() looping over %d iterations\n", depth); - break; - } - } - while (ret > 0); - -#ifndef CONFIG_BLOCK_SIGNALS - recurcount -= 1; -#endif -} - -void -sighandler (int signal) -{ - if (verbose) - printf ("sighandler(signal=%d, count=%d)\n", signal, sigcount); - - do_backtrace (1, 1); - - ++sigcount; - - if (sigcount == 100) - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); - else if (sigcount == 200) - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); - else if (sigcount == 300 || nerrors > nerrors_max) - { - if (nerrors > nerrors_max) - panic ("Too many errors (%d)\n", nerrors); - if (nerrors) - { - fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); - exit (-1); - } - if (verbose) - printf ("SUCCESS.\n"); - exit (0); - } - setitimer (ITIMER_VIRTUAL, &interval, NULL); -} - -int -main (int argc, char **argv UNUSED) -{ - struct sigaction act; - long i = 0; - - if (argc > 1) - verbose = 1; - - unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); - - memset (&act, 0, sizeof (act)); - act.sa_handler = sighandler; - act.sa_flags = SA_SIGINFO; - sigaction (SIGVTALRM, &act, NULL); - - setitimer (ITIMER_VIRTUAL, &interval, NULL); - - while (1) - { - if (0 && verbose) - printf ("%s: starting backtrace\n", __FUNCTION__); - do_backtrace (0, (i++ % 100) == 0); - if (nerrors > nerrors_max) - { - fprintf (stderr, "Too many errors (%d)\n", nerrors); - exit (-1); - } - } - return (0); -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c b/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c deleted file mode 100644 index 53498237c2fd0f..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Example program for unwinding core dumps. - * - * Compile a-la: - * gcc -Os -Wall \ - * -Wl,--start-group \ - * -lunwind -lunwind-x86 -lunwind-coredump \ - * example-core-unwind.c \ - * -Wl,--end-group \ - * -oexample-core-unwind - * - * Run: - * eu-unstrip -n --core COREDUMP - * figure out which virtual addresses in COREDUMP correspond to which mapped executable files - * (binary and libraries), then supply them like this: - * ./example-core-unwind COREDUMP 0x400000:/bin/crashed_program 0x3458600000:/lib/libc.so.6 [...] - * - * Note: Program eu-unstrip is part of elfutils, virtual addresses of shared - * libraries can be determined by ldd (at least on linux). - */ - -#include "compiler.h" - -#undef _GNU_SOURCE -#define _GNU_SOURCE 1 -#undef __USE_GNU -#define __USE_GNU 1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* For SIGSEGV handler code */ -#include -#include - -#include - - -/* Utility logging functions */ - -enum { - LOGMODE_NONE = 0, - LOGMODE_STDIO = (1 << 0), - LOGMODE_SYSLOG = (1 << 1), - LOGMODE_BOTH = LOGMODE_SYSLOG + LOGMODE_STDIO, -}; -const char *msg_prefix = ""; -const char *msg_eol = "\n"; -int logmode = LOGMODE_STDIO; -int xfunc_error_retval = EXIT_FAILURE; - -void xfunc_die(void) -{ - exit(xfunc_error_retval); -} - -static void verror_msg_helper(const char *s, - va_list p, - const char* strerr, - int flags) -{ - char *msg; - int prefix_len, strerr_len, msgeol_len, used; - - if (!logmode) - return; - - used = vasprintf(&msg, s, p); - if (used < 0) - return; - - /* This is ugly and costs +60 bytes compared to multiple - * fprintf's, but is guaranteed to do a single write. - * This is needed for e.g. when multiple children - * can produce log messages simultaneously. */ - - prefix_len = msg_prefix[0] ? strlen(msg_prefix) + 2 : 0; - strerr_len = strerr ? strlen(strerr) : 0; - msgeol_len = strlen(msg_eol); - /* +3 is for ": " before strerr and for terminating NUL */ - char *msg1 = (char*) realloc(msg, prefix_len + used + strerr_len + msgeol_len + 3); - if (!msg1) - { - free(msg); - return; - } - msg = msg1; - /* TODO: maybe use writev instead of memmoving? Need full_writev? */ - if (prefix_len) - { - char *p; - memmove(msg + prefix_len, msg, used); - used += prefix_len; - p = stpcpy(msg, msg_prefix); - p[0] = ':'; - p[1] = ' '; - } - if (strerr) - { - if (s[0]) - { - msg[used++] = ':'; - msg[used++] = ' '; - } - strcpy(&msg[used], strerr); - used += strerr_len; - } - strcpy(&msg[used], msg_eol); - - if (flags & LOGMODE_STDIO) - { - fflush(stdout); - write(STDERR_FILENO, msg, used + msgeol_len); - } - msg[used] = '\0'; /* remove msg_eol (usually "\n") */ - if (flags & LOGMODE_SYSLOG) - { - syslog(LOG_ERR, "%s", msg + prefix_len); - } - free(msg); -} - -void log_msg(const char *s, ...) -{ - va_list p; - va_start(p, s); - verror_msg_helper(s, p, NULL, logmode); - va_end(p); -} -/* It's a macro, not function, since it collides with log() from math.h */ -#undef log -#define log(...) log_msg(__VA_ARGS__) - -void error_msg(const char *s, ...) -{ - va_list p; - va_start(p, s); - verror_msg_helper(s, p, NULL, logmode); - va_end(p); -} - -void error_msg_and_die(const char *s, ...) -{ - va_list p; - va_start(p, s); - verror_msg_helper(s, p, NULL, logmode); - va_end(p); - xfunc_die(); -} - -void perror_msg(const char *s, ...) -{ - va_list p; - va_start(p, s); - /* Guard against ": Success" */ - verror_msg_helper(s, p, errno ? strerror(errno) : NULL, logmode); - va_end(p); -} - -void perror_msg_and_die(const char *s, ...) -{ - va_list p; - va_start(p, s); - /* Guard against ": Success" */ - verror_msg_helper(s, p, errno ? strerror(errno) : NULL, logmode); - va_end(p); - xfunc_die(); -} - -void die_out_of_memory(void) -{ - error_msg_and_die("Out of memory, exiting"); -} - -/* End of utility logging functions */ - - - -static -void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) -{ - long ip = 0; - ucontext_t *uc UNUSED; - - uc = ucontext; -#if defined(__linux__) -#ifdef UNW_TARGET_X86 - ip = uc->uc_mcontext.gregs[REG_EIP]; -#elif defined(UNW_TARGET_X86_64) - ip = uc->uc_mcontext.gregs[REG_RIP]; -#elif defined(UNW_TARGET_ARM) - ip = uc->uc_mcontext.arm_pc; -#endif -#elif defined(__FreeBSD__) -#ifdef __i386__ - ip = uc->uc_mcontext.mc_eip; -#elif defined(__amd64__) - ip = uc->uc_mcontext.mc_rip; -#else -#error Port me -#endif -#else -#error Port me -#endif - dprintf(2, "signal:%d address:0x%lx ip:0x%lx\n", - sig, - /* this is void*, but using %p would print "(null)" - * even for ptrs which are not exactly 0, but, say, 0x123: - */ - (long)info->si_addr, - ip); - - { - /* glibc extension */ - void *array[50]; - int size; - size = backtrace(array, 50); -#ifdef __linux__ - backtrace_symbols_fd(array, size, 2); -#endif - } - - _exit(1); -} - -static void install_sigsegv_handler(void) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handle_sigsegv; - sa.sa_flags = SA_SIGINFO; - sigaction(SIGSEGV, &sa, NULL); - sigaction(SIGILL, &sa, NULL); - sigaction(SIGFPE, &sa, NULL); - sigaction(SIGBUS, &sa, NULL); -} - -int -main(int argc UNUSED, char **argv) -{ - unw_addr_space_t as; - struct UCD_info *ui; - unw_cursor_t c; - int ret; - -#define TEST_FRAMES 4 -#define TEST_NAME_LEN 32 - int testcase = 0; - int test_cur = 0; - long test_start_ips[TEST_FRAMES]; - char test_names[TEST_FRAMES][TEST_NAME_LEN]; - - install_sigsegv_handler(); - - const char *progname = strrchr(argv[0], '/'); - if (progname) - progname++; - else - progname = argv[0]; - - if (!argv[1]) - error_msg_and_die("Usage: %s COREDUMP [VADDR:BINARY_FILE]...", progname); - - msg_prefix = progname; - - as = unw_create_addr_space(&_UCD_accessors, 0); - if (!as) - error_msg_and_die("unw_create_addr_space() failed"); - - ui = _UCD_create(argv[1]); - if (!ui) - error_msg_and_die("_UCD_create('%s') failed", argv[1]); - ret = unw_init_remote(&c, as, ui); - if (ret < 0) - error_msg_and_die("unw_init_remote() failed: ret=%d\n", ret); - - argv += 2; - - /* Enable checks for the crasher test program? */ - if (*argv && !strcmp(*argv, "-testcase")) - { - testcase = 1; - logmode = LOGMODE_NONE; - argv++; - } - - while (*argv) - { - char *colon; - unsigned long vaddr = strtoul(*argv, &colon, 16); - if (*colon != ':') - error_msg_and_die("Bad format: '%s'", *argv); - if (_UCD_add_backing_file_at_vaddr(ui, vaddr, colon + 1) < 0) - error_msg_and_die("Can't add backing file '%s'", colon + 1); - argv++; - } - - for (;;) - { - unw_word_t ip; - ret = unw_get_reg(&c, UNW_REG_IP, &ip); - if (ret < 0) - error_msg_and_die("unw_get_reg(UNW_REG_IP) failed: ret=%d\n", ret); - - unw_proc_info_t pi; - ret = unw_get_proc_info(&c, &pi); - if (ret < 0) - error_msg_and_die("unw_get_proc_info(ip=0x%lx) failed: ret=%d\n", (long) ip, ret); - - if (!testcase) - printf("\tip=0x%08lx proc=%08lx-%08lx handler=0x%08lx lsda=0x%08lx\n", - (long) ip, - (long) pi.start_ip, (long) pi.end_ip, - (long) pi.handler, (long) pi.lsda); - - if (testcase && test_cur < TEST_FRAMES) - { - unw_word_t off; - - test_start_ips[test_cur] = (long) pi.start_ip; - if (unw_get_proc_name(&c, test_names[test_cur], sizeof(test_names[0]), &off) != 0) - { - test_names[test_cur][0] = '\0'; - } - test_cur++; - } - - log("step"); - ret = unw_step(&c); - log("step done:%d", ret); - if (ret < 0) - error_msg_and_die("FAILURE: unw_step() returned %d", ret); - if (ret == 0) - break; - } - log("stepping ended"); - - /* Check that the second and third frames are equal, but distinct of the - * others */ - if (testcase && - (test_cur != 4 - || test_start_ips[1] != test_start_ips[2] - || test_start_ips[0] == test_start_ips[1] - || test_start_ips[2] == test_start_ips[3] - ) - ) - { - fprintf(stderr, "FAILURE: start IPs incorrect\n"); - return -1; - } - - if (testcase && - ( strcmp(test_names[0], "a") - || strcmp(test_names[1], "b") - || strcmp(test_names[2], "b") - || strcmp(test_names[3], "main") - ) - ) - { - fprintf(stderr, "FAILURE: procedure names are missing/incorrect\n"); - return -1; - } - - _UCD_destroy(ui); - unw_destroy_addr_space(as); - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-flush-cache.c b/src/coreclr/src/pal/src/libunwind/tests/test-flush-cache.c deleted file mode 100644 index 1611cf48efda69..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-flush-cache.c +++ /dev/null @@ -1,143 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Copyright (c) 2003 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. */ - -#include -#include - -#define UNW_LOCAL_ONLY /* must define this for consistency with backtrace() */ -#include - -int verbose; - -int -f257 (void) -{ - void *buffer[300]; - int i, n; - - if (verbose) - printf ("First backtrace:\n"); - n = unw_backtrace (buffer, 300); - if (verbose) - for (i = 0; i < n; ++i) - printf ("[%d] ip=%p\n", i, buffer[i]); - - unw_set_cache_size (unw_local_addr_space, 1023, 0); - unw_flush_cache (unw_local_addr_space, 0, 0); - - if (verbose) - printf ("\nSecond backtrace:\n"); - n = unw_backtrace (buffer, 300); - if (verbose) - for (i = 0; i < n; ++i) - printf ("[%d] ip=%p\n", i, buffer[i]); - return 0; -} - -#define F(n,m) \ -int \ -f##n (void) \ -{ \ - return f##m (); \ -} - -/* Here, we rely on the fact that the script-cache's hash-table is 256 - entries big. With 257 functions, we're guaranteed to get at least - one hash-collision. */ -F(256,257) F(255,256) F(254,255) F(253,254) -F(252,253) F(251,252) F(250,251) F(249,250) -F(248,249) F(247,248) F(246,247) F(245,246) -F(244,245) F(243,244) F(242,243) F(241,242) -F(240,241) F(239,240) F(238,239) F(237,238) -F(236,237) F(235,236) F(234,235) F(233,234) -F(232,233) F(231,232) F(230,231) F(229,230) -F(228,229) F(227,228) F(226,227) F(225,226) -F(224,225) F(223,224) F(222,223) F(221,222) -F(220,221) F(219,220) F(218,219) F(217,218) -F(216,217) F(215,216) F(214,215) F(213,214) -F(212,213) F(211,212) F(210,211) F(209,210) -F(208,209) F(207,208) F(206,207) F(205,206) -F(204,205) F(203,204) F(202,203) F(201,202) -F(200,201) F(199,200) F(198,199) F(197,198) -F(196,197) F(195,196) F(194,195) F(193,194) -F(192,193) F(191,192) F(190,191) F(189,190) -F(188,189) F(187,188) F(186,187) F(185,186) -F(184,185) F(183,184) F(182,183) F(181,182) -F(180,181) F(179,180) F(178,179) F(177,178) -F(176,177) F(175,176) F(174,175) F(173,174) -F(172,173) F(171,172) F(170,171) F(169,170) -F(168,169) F(167,168) F(166,167) F(165,166) -F(164,165) F(163,164) F(162,163) F(161,162) -F(160,161) F(159,160) F(158,159) F(157,158) -F(156,157) F(155,156) F(154,155) F(153,154) -F(152,153) F(151,152) F(150,151) F(149,150) -F(148,149) F(147,148) F(146,147) F(145,146) -F(144,145) F(143,144) F(142,143) F(141,142) -F(140,141) F(139,140) F(138,139) F(137,138) -F(136,137) F(135,136) F(134,135) F(133,134) -F(132,133) F(131,132) F(130,131) F(129,130) -F(128,129) F(127,128) F(126,127) F(125,126) -F(124,125) F(123,124) F(122,123) F(121,122) -F(120,121) F(119,120) F(118,119) F(117,118) -F(116,117) F(115,116) F(114,115) F(113,114) -F(112,113) F(111,112) F(110,111) F(109,110) -F(108,109) F(107,108) F(106,107) F(105,106) -F(104,105) F(103,104) F(102,103) F(101,102) -F(100,101) F(99,100) F(98,99) F(97,98) -F(96,97) F(95,96) F(94,95) F(93,94) -F(92,93) F(91,92) F(90,91) F(89,90) -F(88,89) F(87,88) F(86,87) F(85,86) -F(84,85) F(83,84) F(82,83) F(81,82) -F(80,81) F(79,80) F(78,79) F(77,78) -F(76,77) F(75,76) F(74,75) F(73,74) -F(72,73) F(71,72) F(70,71) F(69,70) -F(68,69) F(67,68) F(66,67) F(65,66) -F(64,65) F(63,64) F(62,63) F(61,62) -F(60,61) F(59,60) F(58,59) F(57,58) -F(56,57) F(55,56) F(54,55) F(53,54) -F(52,53) F(51,52) F(50,51) F(49,50) -F(48,49) F(47,48) F(46,47) F(45,46) -F(44,45) F(43,44) F(42,43) F(41,42) -F(40,41) F(39,40) F(38,39) F(37,38) -F(36,37) F(35,36) F(34,35) F(33,34) -F(32,33) F(31,32) F(30,31) F(29,30) -F(28,29) F(27,28) F(26,27) F(25,26) -F(24,25) F(23,24) F(22,23) F(21,22) -F(20,21) F(19,20) F(18,19) F(17,18) -F(16,17) F(15,16) F(14,15) F(13,14) -F(12,13) F(11,12) F(10,11) F(9,10) -F(8,9) F(7,8) F(6,7) F(5,6) -F(4,5) F(3,4) F(2,3) F(1,2) - -int -main (int argc, char **argv) -{ - if (argc > 1 && strcmp (argv[1], "-v") == 0) - verbose = 1; - - return f1 (); -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-init-remote.c b/src/coreclr/src/pal/src/libunwind/tests/test-init-remote.c deleted file mode 100644 index 66f2d6a1e0c2bf..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-init-remote.c +++ /dev/null @@ -1,103 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -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. */ - -/* This test simply verifies that unw_init_remote() can be used in - lieu of unw_init_local(). This was broken for a while on ia64. */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "compiler.h" - -#include -#include -#include -#include - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -int verbose; - -static int -do_backtrace (void) -{ - char buf[512], name[256]; - unw_word_t ip, sp, off; - unw_cursor_t cursor; - unw_context_t uc; - int ret; - - unw_getcontext (&uc); - if (unw_init_remote (&cursor, unw_local_addr_space, &uc) < 0) - panic ("unw_init_remote failed!\n"); - - do - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - unw_get_reg (&cursor, UNW_REG_SP, &sp); - buf[0] = '\0'; - if (unw_get_proc_name (&cursor, name, sizeof (name), &off) == 0) - { - if (off) - snprintf (buf, sizeof (buf), "<%s+0x%lx>", name, (long) off); - else - snprintf (buf, sizeof (buf), "<%s>", name); - } - if (verbose) - printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); - - ret = unw_step (&cursor); - if (ret < 0) - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - printf ("FAILURE: unw_step() returned %d for ip=%lx\n", - ret, (long) ip); - return -1; - } - } - while (ret > 0); - - return 0; -} - -static int -foo (void) -{ - return do_backtrace (); -} - -int -main (int argc, char **argv UNUSED) -{ - verbose = (argc > 1); - - if (verbose) - printf ("Normal backtrace:\n"); - return foo (); -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-mem.c b/src/coreclr/src/pal/src/libunwind/tests/test-mem.c deleted file mode 100644 index 52c977488ac324..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-mem.c +++ /dev/null @@ -1,103 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Copyright (c) 2003 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. */ - -#include "compiler.h" - -#include -#include -#include -#include -#include - -#include - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -int verbose; - -static void -do_backtrace (void) -{ - unw_cursor_t cursor; - unw_word_t ip, sp; - unw_context_t uc; - int ret; - - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - panic ("unw_init_local failed!\n"); - - do - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - unw_get_reg (&cursor, UNW_REG_SP, &sp); - - if (verbose) - printf ("%016lx (sp=%016lx)\n", (long) ip, (long) sp); - - ret = unw_step (&cursor); - if (ret < 0) - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - panic ("FAILURE: unw_step() returned %d for ip=%lx\n", - ret, (long) ip); - } - } - while (ret > 0); -} - -int -consume_some_stack_space (void) -{ - unw_cursor_t cursor; - unw_context_t uc; - char string[1024]; - - memset (&cursor, 0, sizeof (cursor)); - memset (&uc, 0, sizeof (uc)); - return sprintf (string, "hello %p %p\n", &cursor, &uc); -} - -int -main (int argc, char **argv UNUSED) -{ - struct rlimit rlim; - - verbose = argc > 1; - - if (consume_some_stack_space () > 9999) - exit (-1); /* can't happen, but don't let the compiler know... */ - - rlim.rlim_cur = 0; - rlim.rlim_max = RLIM_INFINITY; - setrlimit (RLIMIT_DATA, &rlim); - setrlimit (RLIMIT_AS, &rlim); - - do_backtrace (); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-proc-info.c b/src/coreclr/src/pal/src/libunwind/tests/test-proc-info.c deleted file mode 100644 index c4145bc374ec38..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-proc-info.c +++ /dev/null @@ -1,171 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Copyright (c) 2003 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. */ - -/* This test program checks whether proc_info lookup failures are - cached. They must NOT be cached because it could otherwise turn - temporary failures into permanent ones. Furthermore, we allow apps - to return -UNW_ESTOPUNWIND to terminate unwinding (though this - feature is deprecated and dynamic unwind info should be used - instead). */ - -#include -#include - -#include -#include "compiler.h" - -int errors; - -#define panic(args...) \ - { ++errors; fprintf (stderr, args); return -1; } - -static int -find_proc_info (unw_addr_space_t as UNUSED, - unw_word_t ip UNUSED, - unw_proc_info_t *pip UNUSED, - int need_unwind_info UNUSED, - void *arg UNUSED) -{ - return -UNW_ESTOPUNWIND; -} - -static int -access_mem (unw_addr_space_t as UNUSED, - unw_word_t addr UNUSED, - unw_word_t *valp, int write, - void *arg UNUSED) -{ - if (!write) - *valp = 0; - return 0; -} - -static int -access_reg (unw_addr_space_t as UNUSED, - unw_regnum_t regnum UNUSED, - unw_word_t *valp, int write, - void *arg UNUSED) -{ - if (!write) - *valp = 32; - return 0; -} - -static int -access_fpreg (unw_addr_space_t as UNUSED, - unw_regnum_t regnum UNUSED, - unw_fpreg_t *valp, int write, - void *arg UNUSED) -{ - if (!write) - memset (valp, 0, sizeof (*valp)); - return 0; -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as UNUSED, - unw_word_t *dilap UNUSED, - void *arg UNUSED) -{ - return -UNW_ENOINFO; -} - -static void -put_unwind_info (unw_addr_space_t as UNUSED, - unw_proc_info_t *pi UNUSED, - void *arg UNUSED) -{ - ++errors; - fprintf (stderr, "%s() got called!\n", __FUNCTION__); -} - -static int -resume (unw_addr_space_t as UNUSED, - unw_cursor_t *reg UNUSED, - void *arg UNUSED) -{ - panic ("%s() got called!\n", __FUNCTION__); -} - -static int -get_proc_name (unw_addr_space_t as UNUSED, - unw_word_t ip UNUSED, - char *buf UNUSED, - size_t buf_len UNUSED, - unw_word_t *offp UNUSED, - void *arg UNUSED) -{ - panic ("%s() got called!\n", __FUNCTION__); -} - -int -main (int argc, char **argv) -{ - unw_accessors_t acc; - unw_addr_space_t as; - int ret, verbose = 0; - unw_cursor_t c; - - if (argc > 1 && strcmp (argv[1], "-v") == 0) - verbose = 1; - - memset (&acc, 0, sizeof (acc)); - acc.find_proc_info = find_proc_info; - acc.put_unwind_info = put_unwind_info; - acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - acc.access_mem = access_mem; - acc.access_reg = access_reg; - acc.access_fpreg = access_fpreg; - acc.resume = resume; - acc.get_proc_name = get_proc_name; - - as = unw_create_addr_space (&acc, 0); - if (!as) - panic ("unw_create_addr_space() failed\n"); - - unw_set_caching_policy (as, UNW_CACHE_GLOBAL); - - ret = unw_init_remote (&c, as, NULL); - if (ret < 0) - panic ("unw_init_remote() returned %d instead of 0\n", ret); - - ret = unw_step (&c); - if (ret != -UNW_ESTOPUNWIND) - panic ("First call to unw_step() returned %d instead of %d\n", - ret, -UNW_ESTOPUNWIND); - - ret = unw_step (&c); - if (ret != -UNW_ESTOPUNWIND) - panic ("Second call to unw_step() returned %d instead of %d\n", - ret, -UNW_ESTOPUNWIND); - - unw_destroy_addr_space (as); - - if (verbose) - printf ("SUCCESS\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-ptrace-misc.c b/src/coreclr/src/pal/src/libunwind/tests/test-ptrace-misc.c deleted file mode 100644 index 374059dc44a972..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-ptrace-misc.c +++ /dev/null @@ -1,120 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "compiler.h" - -#include -#include -#include -#include -#include - -#include - -pid_t self; -int global[64]; - -int -func (int arg) -{ - int sum = 0, i, max, arr[1024]; - - if (arg == 0) - { - sum = global[2]; - sum += sum + sum * getppid (); - return sum; - } - else - { - max = arg; - if (max >= 64) - max = 64; - - for (i = 0; i < max; ++i) - arr[i] = func (arg - 1); - - for (i = 0; i < max; ++i) - if (arr[i] > 16) - sum += arr[i]; - else - sum -= arr[i]; - } - return sum; -} - -int -bar (int v) -{ - extern long f (long); - int arr[1] = { v }; - uintptr_t r; - - /* This is a vain attempt to use up lots of registers to force - the frame-chain info to be saved on the memory stack on ia64. - It happens to work with gcc v3.3.4 and gcc v3.4.1 but perhaps - not with any other compiler. */ - r = (uintptr_t) malloc(f (arr[0]) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) - + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + f (v)) - )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) - ))))))))))))))))))))))))))))))))))))))))))))))))))))))); - if (r < 2) - v = r; - - kill (self, SIGUSR1); /* tell test-ptrace to start single-stepping */ - v = func (v); - kill (self, SIGUSR2); /* tell test-ptrace to stop single-stepping */ - return v; -} - -int -main (int argc, char **argv UNUSED) -{ - int val = argc; - - signal (SIGUSR1, SIG_IGN); - signal (SIGUSR2, SIG_IGN); - - self = getpid (); - - printf ("sum = %d\n", bar (val)); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-ptrace.c b/src/coreclr/src/pal/src/libunwind/tests/test-ptrace.c deleted file mode 100644 index e7c7883f38f9eb..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-ptrace.c +++ /dev/null @@ -1,370 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#ifdef HAVE_TTRACE - -int -main (void) -{ - printf ("FAILURE: ttrace() not supported yet\n"); - return -1; -} - -#else /* !HAVE_TTRACE */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -extern char **environ; - -static const int nerrors_max = 100; - -int nerrors; -int verbose; -int print_names = 1; - -enum - { - INSTRUCTION, - SYSCALL, - TRIGGER - } -trace_mode = SYSCALL; - -#define panic(args...) \ - do { fprintf (stderr, args); ++nerrors; } while (0) - -static unw_addr_space_t as; -static struct UPT_info *ui; - -static int killed; - -void -do_backtrace (void) -{ - unw_word_t ip, sp, start_ip = 0, off; - int n = 0, ret; - unw_proc_info_t pi; - unw_cursor_t c; - char buf[512]; - size_t len; - - ret = unw_init_remote (&c, as, ui); - if (ret < 0) - panic ("unw_init_remote() failed: ret=%d\n", ret); - - do - { - if ((ret = unw_get_reg (&c, UNW_REG_IP, &ip)) < 0 - || (ret = unw_get_reg (&c, UNW_REG_SP, &sp)) < 0) - panic ("unw_get_reg/unw_get_proc_name() failed: ret=%d\n", ret); - - if (n == 0) - start_ip = ip; - - buf[0] = '\0'; - if (print_names) - unw_get_proc_name (&c, buf, sizeof (buf), &off); - - if (verbose) - { - if (off) - { - len = strlen (buf); - if (len >= sizeof (buf) - 32) - len = sizeof (buf) - 32; - sprintf (buf + len, "+0x%lx", (unsigned long) off); - } - printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); - } - - if ((ret = unw_get_proc_info (&c, &pi)) < 0) - panic ("unw_get_proc_info(ip=0x%lx) failed: ret=%d\n", (long) ip, ret); - else if (verbose) - printf ("\tproc=%016lx-%016lx\n\thandler=%lx lsda=%lx", - (long) pi.start_ip, (long) pi.end_ip, - (long) pi.handler, (long) pi.lsda); - -#if UNW_TARGET_IA64 - { - unw_word_t bsp; - - if ((ret = unw_get_reg (&c, UNW_IA64_BSP, &bsp)) < 0) - panic ("unw_get_reg() failed: ret=%d\n", ret); - else if (verbose) - printf (" bsp=%lx", bsp); - } -#endif - if (verbose) - printf ("\n"); - - ret = unw_step (&c); - if (ret < 0) - { - unw_get_reg (&c, UNW_REG_IP, &ip); - panic ("FAILURE: unw_step() returned %d for ip=%lx (start ip=%lx)\n", - ret, (long) ip, (long) start_ip); - } - - if (++n > 64) - { - /* guard against bad unwind info in old libraries... */ - panic ("too deeply nested---assuming bogus unwind (start ip=%lx)\n", - (long) start_ip); - break; - } - if (nerrors > nerrors_max) - { - panic ("Too many errors (%d)!\n", nerrors); - break; - } - } - while (ret > 0); - - if (ret < 0) - panic ("unwind failed with ret=%d\n", ret); - - if (verbose) - printf ("================\n\n"); -} - -static pid_t target_pid; -static void target_pid_kill (void) -{ - kill (target_pid, SIGKILL); -} - -int -main (int argc, char **argv) -{ - int status, pid, pending_sig, optind = 1, state = 1; - - as = unw_create_addr_space (&_UPT_accessors, 0); - if (!as) - panic ("unw_create_addr_space() failed"); - - if (argc == 1) - { - static char *args[] = { "self", "/bin/ls", "/usr", NULL }; - - /* automated test case */ - argv = args; - - /* Unless the args array is 'walked' the child - process is unable to access it and dies with a segfault */ - fprintf(stderr, "Automated test (%s,%s,%s,%s)\n", - args[0],args[1],args[2],args[3]); - } - else if (argc > 1) - while (argv[optind][0] == '-') - { - if (strcmp (argv[optind], "-v") == 0) - ++optind, verbose = 1; - else if (strcmp (argv[optind], "-i") == 0) - ++optind, trace_mode = INSTRUCTION; /* backtrace at each insn */ - else if (strcmp (argv[optind], "-s") == 0) - ++optind, trace_mode = SYSCALL; /* backtrace at each syscall */ - else if (strcmp (argv[optind], "-t") == 0) - /* Execute until raise(SIGUSR1), then backtrace at each insn - until raise(SIGUSR2). */ - ++optind, trace_mode = TRIGGER; - else if (strcmp (argv[optind], "-c") == 0) - /* Enable caching of unwind-info. */ - ++optind, unw_set_caching_policy (as, UNW_CACHE_GLOBAL); - else if (strcmp (argv[optind], "-n") == 0) - /* Don't look-up and print symbol names. */ - ++optind, print_names = 0; - else - fprintf(stderr, "unrecognized option: %s\n", argv[optind++]); - if (optind >= argc) - break; - } - - target_pid = fork (); - if (!target_pid) - { - /* child */ - - if (!verbose) - dup2 (open ("/dev/null", O_WRONLY), 1); - -#if HAVE_DECL_PTRACE_TRACEME - ptrace (PTRACE_TRACEME, 0, 0, 0); -#elif HAVE_DECL_PT_TRACE_ME - ptrace (PT_TRACE_ME, 0, 0, 0); -#else -#error Trace me -#endif - - if ((argc > 1) && (optind == argc)) { - fprintf(stderr, "Need to specify a command line for the child\n"); - exit (-1); - } - execve (argv[optind], argv + optind, environ); - _exit (-1); - } - atexit (target_pid_kill); - - ui = _UPT_create (target_pid); - - while (nerrors <= nerrors_max) - { - pid = wait4 (-1, &status, 0, NULL); - if (pid == -1) - { - if (errno == EINTR) - continue; - - panic ("wait4() failed (errno=%d)\n", errno); - } - pending_sig = 0; - if (WIFSIGNALED (status) || WIFEXITED (status) - || (WIFSTOPPED (status) && WSTOPSIG (status) != SIGTRAP)) - { - if (WIFEXITED (status)) - { - if (WEXITSTATUS (status) != 0) - panic ("child's exit status %d\n", WEXITSTATUS (status)); - break; - } - else if (WIFSIGNALED (status)) - { - if (!killed) - panic ("child terminated by signal %d\n", WTERMSIG (status)); - break; - } - else - { - pending_sig = WSTOPSIG (status); - /* Avoid deadlock: */ - if (WSTOPSIG (status) == SIGKILL) - break; - if (trace_mode == TRIGGER) - { - if (WSTOPSIG (status) == SIGUSR1) - state = 0; - else if (WSTOPSIG (status) == SIGUSR2) - state = 1; - } - if (WSTOPSIG (status) != SIGUSR1 && WSTOPSIG (status) != SIGUSR2) - { - static int count = 0; - - if (count++ > 100) - { - panic ("Too many child unexpected signals (now %d)\n", - WSTOPSIG (status)); - killed = 1; - } - } - } - } - - switch (trace_mode) - { - case TRIGGER: - if (state) -#if HAVE_DECL_PTRACE_CONT - ptrace (PTRACE_CONT, target_pid, 0, 0); -#elif HAVE_DECL_PT_CONTINUE - ptrace (PT_CONTINUE, target_pid, (caddr_t)1, 0); -#else -#error Port me -#endif - else - { - do_backtrace (); -#if HAVE_DECL_PTRACE_SINGLESTEP - if (ptrace (PTRACE_SINGLESTEP, target_pid, 0, pending_sig) < 0) - { - panic ("ptrace(PTRACE_SINGLESTEP) failed (errno=%d)\n", errno); - killed = 1; - } -#elif HAVE_DECL_PT_STEP - if (ptrace (PT_STEP, target_pid, (caddr_t)1, pending_sig) < 0) - { - panic ("ptrace(PT_STEP) failed (errno=%d)\n", errno); - killed = 1; - } -#else -#error Singlestep me -#endif - } - break; - - case SYSCALL: - if (!state) - do_backtrace (); - state ^= 1; -#if HAVE_DECL_PTRACE_SYSCALL - ptrace (PTRACE_SYSCALL, target_pid, 0, pending_sig); -#elif HAVE_DECL_PT_SYSCALL - ptrace (PT_SYSCALL, target_pid, (caddr_t)1, pending_sig); -#else -#error Syscall me -#endif - break; - - case INSTRUCTION: - do_backtrace (); -#if HAVE_DECL_PTRACE_SINGLESTEP - ptrace (PTRACE_SINGLESTEP, target_pid, 0, pending_sig); -#elif HAVE_DECL_PT_STEP - ptrace (PT_STEP, target_pid, (caddr_t)1, pending_sig); -#else -#error Singlestep me -#endif - break; - } - if (killed) - kill (target_pid, SIGKILL); - } - - _UPT_destroy (ui); - unw_destroy_addr_space (as); - - if (nerrors) - { - printf ("FAILURE: detected %d errors\n", nerrors); - exit (-1); - } - if (verbose) - printf ("SUCCESS\n"); - - return 0; -} - -#endif /* !HAVE_TTRACE */ diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-reg-state.c b/src/coreclr/src/pal/src/libunwind/tests/test-reg-state.c deleted file mode 100644 index ac713ea68ad721..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-reg-state.c +++ /dev/null @@ -1,133 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Copyright (c) 2003 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. */ - -#include "compiler.h" - -#include -#include -#include -#include -#include - -#include -#include - -#define panic(args...) \ - { fprintf (stderr, args); exit (-1); } - -int verbose; - -struct cb_data -{ - unw_word_t ip; - void* reg_state; - size_t len; -}; - -static int -dwarf_reg_states_callback(void *token, - void *rs, - size_t size, - unw_word_t start_ip, unw_word_t end_ip) -{ - struct cb_data *data = token; - if (start_ip <= data->ip && data->ip < end_ip) - { - data->reg_state = mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - memcpy(data->reg_state, rs, size); - data->len = size; - } - return 0; -} - -static void -do_backtrace (void) -{ - unw_cursor_t cursor; - unw_word_t ip, sp; - unw_context_t uc; - int ret; - - unw_getcontext (&uc); - if (unw_init_local (&cursor, &uc) < 0) - panic ("unw_init_local failed!\n"); - - do - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - unw_get_reg (&cursor, UNW_REG_SP, &sp); - - if (verbose) - printf ("%016lx (sp=%016lx)\n", (long) ip, (long) sp); - - struct cb_data data = {.ip = ip, .reg_state = NULL}; - ret = unw_reg_states_iterate(&cursor, dwarf_reg_states_callback, &data); - if (ret > 0) - { - ret = unw_apply_reg_state (&cursor, data.reg_state); - munmap(data.reg_state, data.len); - } - if (ret < 0) - { - unw_get_reg (&cursor, UNW_REG_IP, &ip); - panic ("FAILURE: unw_step() returned %d for ip=%lx\n", - ret, (long) ip); - } - } - while (ret > 0); -} - -int -consume_some_stack_space (void) -{ - unw_cursor_t cursor; - unw_context_t uc; - char string[1024]; - - memset (&cursor, 0, sizeof (cursor)); - memset (&uc, 0, sizeof (uc)); - return sprintf (string, "hello %p %p\n", &cursor, &uc); -} - -int -main (int argc, char **argv UNUSED) -{ - struct rlimit rlim; - - verbose = argc > 1; - - if (consume_some_stack_space () > 9999) - exit (-1); /* can't happen, but don't let the compiler know... */ - - rlim.rlim_cur = 0; - rlim.rlim_max = RLIM_INFINITY; - setrlimit (RLIMIT_DATA, &rlim); - - do_backtrace (); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-setjmp.c b/src/coreclr/src/pal/src/libunwind/tests/test-setjmp.c deleted file mode 100644 index 769b71b2228c6c..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-setjmp.c +++ /dev/null @@ -1,285 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -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. */ - -/* The setjmp()/longjmp(), sigsetjmp()/siglongjmp(). */ - -#include "compiler.h" - -#include -#include -#include -#include -#include -#include - -int nerrors; -int verbose; - -static jmp_buf jbuf; -static sigjmp_buf sigjbuf; -static sigset_t sigset4; - -void -raise_longjmp (jmp_buf jbuf, int i, int n) -{ - while (i < n) - raise_longjmp (jbuf, i + 1, n); - - longjmp (jbuf, n); -} - -void -test_setjmp (void) -{ - volatile int i; - jmp_buf jbuf; - int ret; - - for (i = 0; i < 10; ++i) - { - if ((ret = setjmp (jbuf))) - { - if (verbose) - printf ("%s: secondary setjmp () return, ret=%d\n", - __FUNCTION__, ret); - if (ret != i + 1) - { - fprintf (stderr, "%s: setjmp() returned %d, expected %d\n", - __FUNCTION__, ret, i + 1); - ++nerrors; - } - continue; - } - if (verbose) - printf ("%s.%d: done with setjmp(); calling children\n", - __FUNCTION__, i + 1); - - raise_longjmp (jbuf, 0, i + 1); - - fprintf (stderr, "%s: raise_longjmp() returned unexpectedly\n", - __FUNCTION__); - ++nerrors; - } -} - - -void -raise_siglongjmp (sigjmp_buf jbuf, int i, int n) -{ - while (i < n) - raise_siglongjmp (jbuf, i + 1, n); - - siglongjmp (jbuf, n); -} - -void -test_sigsetjmp (void) -{ - sigjmp_buf jbuf; - volatile int i; - int ret; - - for (i = 0; i < 10; ++i) - { - if ((ret = sigsetjmp (jbuf, 1))) - { - if (verbose) - printf ("%s: secondary sigsetjmp () return, ret=%d\n", - __FUNCTION__, ret); - if (ret != i + 1) - { - fprintf (stderr, "%s: sigsetjmp() returned %d, expected %d\n", - __FUNCTION__, ret, i + 1); - ++nerrors; - } - continue; - } - if (verbose) - printf ("%s.%d: done with sigsetjmp(); calling children\n", - __FUNCTION__, i + 1); - - raise_siglongjmp (jbuf, 0, i + 1); - - fprintf (stderr, "%s: raise_siglongjmp() returned unexpectedly\n", - __FUNCTION__); - ++nerrors; - } -} - -void -sighandler (int signal) -{ - if (verbose) - printf ("%s: got signal %d\n", __FUNCTION__, signal); - - sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset4); - if (verbose) - printf ("%s: back from sigprocmask\n", __FUNCTION__); - - siglongjmp (sigjbuf, 1); - printf ("%s: siglongjmp() returned unexpectedly!\n", __FUNCTION__); -} - -int -main (int argc, char **argv UNUSED) -{ - volatile sigset_t sigset1, sigset2, sigset3; - volatile struct sigaction act; - - if (argc > 1) - verbose = 1; - - sigemptyset ((sigset_t *) &sigset1); - sigaddset ((sigset_t *) &sigset1, SIGUSR1); - sigemptyset ((sigset_t *) &sigset2); - sigaddset ((sigset_t *) &sigset2, SIGUSR2); - - memset ((void *) &act, 0, sizeof (act)); - act.sa_handler = sighandler; - sigaction (SIGTERM, (struct sigaction *) &act, NULL); - - test_setjmp (); - test_sigsetjmp (); - - /* _setjmp() MUST NOT change signal mask: */ - sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL); - if (_setjmp (jbuf)) - { - sigemptyset ((sigset_t *) &sigset3); - sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); - if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset2, - sizeof (sigset_t)) != 0) - { - fprintf (stderr, "FAILURE: _longjmp() manipulated signal mask!\n"); - ++nerrors; - } - else if (verbose) - printf ("OK: _longjmp() seems not to change signal mask\n"); - } - else - { - sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL); - _longjmp (jbuf, 1); - } - - /* sigsetjmp(jbuf, 1) MUST preserve signal mask: */ - sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL); - if (sigsetjmp (sigjbuf, 1)) - { - sigemptyset ((sigset_t *) &sigset3); - sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); - if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset1, - sizeof (sigset_t)) != 0) - { - fprintf (stderr, - "FAILURE: siglongjmp() didn't restore signal mask!\n"); - ++nerrors; - } - else if (verbose) - printf ("OK: siglongjmp() restores signal mask when asked to\n"); - } - else - { - sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL); - siglongjmp (sigjbuf, 1); - } - - /* sigsetjmp(jbuf, 0) MUST NOT preserve signal mask: */ - sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL); - if (sigsetjmp (sigjbuf, 0)) - { - sigemptyset ((sigset_t *) &sigset3); - sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); - if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset2, - sizeof (sigset_t)) != 0) - { - fprintf (stderr, - "FAILURE: siglongjmp() changed signal mask!\n"); - ++nerrors; - } - else if (verbose) - printf ("OK: siglongjmp() leaves signal mask alone when asked to\n"); - } - else - { - sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL); - siglongjmp (sigjbuf, 1); - } - - /* sigsetjmp(jbuf, 1) MUST preserve signal mask: */ - sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL); - if (sigsetjmp (sigjbuf, 1)) - { - sigemptyset ((sigset_t *) &sigset3); - sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); - if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset1, - sizeof (sigset_t)) != 0) - { - fprintf (stderr, - "FAILURE: siglongjmp() didn't restore signal mask!\n"); - ++nerrors; - } - else if (verbose) - printf ("OK: siglongjmp() restores signal mask when asked to\n"); - } - else - { - sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL); - kill (getpid (), SIGTERM); - fprintf (stderr, "FAILURE: unexpected return from kill()\n"); - ++nerrors; - } - - /* sigsetjmp(jbuf, 0) MUST NOT preserve signal mask: */ - sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL); - if (sigsetjmp (sigjbuf, 0)) - { - sigemptyset ((sigset_t *) &sigset3); - sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); - if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset4, - sizeof (sigset_t)) != 0) - { - fprintf (stderr, - "FAILURE: siglongjmp() changed signal mask!\n"); - ++nerrors; - } - else if (verbose) - printf ("OK: siglongjmp() leaves signal mask alone when asked to\n"); - } - else - { - sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL); - kill (getpid (), SIGTERM); - fprintf (stderr, "FAILURE: unexpected return from kill()\n"); - ++nerrors; - } - - if (nerrors > 0) - { - fprintf (stderr, "FAILURE: detected %d failures\n", nerrors); - exit (-1); - } - if (verbose) - printf ("SUCCESS\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-static-link-gen.c b/src/coreclr/src/pal/src/libunwind/tests/test-static-link-gen.c deleted file mode 100644 index d61e7a51c66c06..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-static-link-gen.c +++ /dev/null @@ -1,74 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Copyright (c) 2003 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. */ - -#include - -#include - -extern int verbose; - -static void *funcs[] = - { - (void *) &unw_get_reg, - (void *) &unw_get_fpreg, - (void *) &unw_set_reg, - (void *) &unw_set_fpreg, - (void *) &unw_resume, - (void *) &unw_create_addr_space, - (void *) &unw_destroy_addr_space, - (void *) &unw_get_accessors, - (void *) &unw_flush_cache, - (void *) &unw_set_caching_policy, - (void *) &unw_set_cache_size, - (void *) &unw_regname, - (void *) &unw_get_proc_info, - (void *) &unw_get_save_loc, - (void *) &unw_is_signal_frame, - (void *) &unw_get_proc_name - }; - -int -test_generic (void) -{ - if (verbose) - printf (__FILE__": funcs[0]=%p\n", funcs[0]); - -#ifndef UNW_REMOTE_ONLY - { - unw_context_t uc; - unw_cursor_t c; - - unw_getcontext (&uc); - unw_init_local (&c, &uc); - unw_init_remote (&c, unw_local_addr_space, &uc); - - return unw_step (&c); - } -#else - return 0; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-static-link-loc.c b/src/coreclr/src/pal/src/libunwind/tests/test-static-link-loc.c deleted file mode 100644 index 1c7aa0378c8df5..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-static-link-loc.c +++ /dev/null @@ -1,102 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Copyright (c) 2003 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. */ - -/* The purpose of this program is simply to link in all libunwind-API - functions both in their local-only and generic variants and to make - sure that the final result can be linked statically. */ - -#include - -#define UNW_LOCAL_ONLY -#include -#include "compiler.h" - -extern int test_generic (void); - -int verbose; - -#ifdef UNW_REMOTE_ONLY - -int -test_local (void) -{ - return 0; -} - -#else /* !UNW_REMOTE_ONLY */ - -static void *funcs[] = - { - (void *) &unw_get_reg, - (void *) &unw_get_fpreg, - (void *) &unw_set_reg, - (void *) &unw_set_fpreg, - (void *) &unw_resume, - (void *) &unw_create_addr_space, - (void *) &unw_destroy_addr_space, - (void *) &unw_get_accessors, - (void *) &unw_flush_cache, - (void *) &unw_set_caching_policy, - (void *) &unw_set_cache_size, - (void *) &unw_regname, - (void *) &unw_get_proc_info, - (void *) &unw_get_save_loc, - (void *) &unw_is_signal_frame, - (void *) &unw_get_proc_name, - (void *) &_U_dyn_register, - (void *) &_U_dyn_cancel - }; - -int -test_local (void) -{ - unw_context_t uc; - unw_cursor_t c; - - if (verbose) - printf (__FILE__": funcs[0]=%p\n", funcs[0]); - - unw_getcontext (&uc); - unw_init_local (&c, &uc); - unw_init_remote (&c, unw_local_addr_space, &uc); - return unw_step (&c); -} - -#endif /* !UNW_REMOTE_ONLY */ - -int -main (int argc, char **argv UNUSED) -{ - if (argc > 1) - verbose = 1; - - if (test_local () < 0) - return -1; - if (test_generic () < 0) - return -1; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-strerror.c b/src/coreclr/src/pal/src/libunwind/tests/test-strerror.c deleted file mode 100644 index f7ae61ed17bdf8..00000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/test-strerror.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "compiler.h" -#include -#include - -int -main (int argc, char **argv UNUSED) -{ - int i, verbose = argc > 1; - const char *msg; - - for (i = 0; i < 16; ++i) - { - msg = unw_strerror (-i); - if (verbose) - printf ("%6d -> %s\n", -i, msg); - } - return 0; -} From 162d0c94f96b73f21ed25e27a2409f9f2c618185 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 7 May 2020 15:44:19 -0400 Subject: [PATCH 02/12] Add libunwind 1.5rc2 source Rename unused autoconfig dir aux -> aux_ consistenet with original checkin --- src/coreclr/src/pal/src/libunwind/.gitignore | 81 + src/coreclr/src/pal/src/libunwind/.travis.yml | 34 + src/coreclr/src/pal/src/libunwind/AUTHORS | 1 + src/coreclr/src/pal/src/libunwind/COPYING | 20 + src/coreclr/src/pal/src/libunwind/ChangeLog | 55 + src/coreclr/src/pal/src/libunwind/LICENSE | 18 + src/coreclr/src/pal/src/libunwind/Makefile.am | 111 + src/coreclr/src/pal/src/libunwind/NEWS | 247 + src/coreclr/src/pal/src/libunwind/README | 239 + src/coreclr/src/pal/src/libunwind/TODO | 97 + .../src/pal/src/libunwind/acinclude.m4 | 32 + src/coreclr/src/pal/src/libunwind/autogen.sh | 9 + .../src/pal/src/libunwind/aux_/config.guess | 1321 +++++ .../src/pal/src/libunwind/aux_/config.sub | 1443 +++++ .../src/pal/src/libunwind/aux_/ltmain.sh | 5107 +++++++++++++++++ .../src/pal/src/libunwind/configure.ac | 481 ++ .../src/pal/src/libunwind/doc/Makefile.am | 80 + src/coreclr/src/pal/src/libunwind/doc/NOTES | 127 + .../pal/src/libunwind/doc/_U_dyn_cancel.man | 66 + .../pal/src/libunwind/doc/_U_dyn_cancel.tex | 46 + .../pal/src/libunwind/doc/_U_dyn_register.man | 68 + .../pal/src/libunwind/doc/_U_dyn_register.tex | 47 + .../src/pal/src/libunwind/doc/common.tex.in | 11 + .../src/libunwind/doc/libunwind-dynamic.man | 538 ++ .../src/libunwind/doc/libunwind-dynamic.tex | 401 ++ .../pal/src/libunwind/doc/libunwind-ia64.man | 314 + .../pal/src/libunwind/doc/libunwind-ia64.tex | 216 + .../src/libunwind/doc/libunwind-ptrace.man | 220 + .../src/libunwind/doc/libunwind-ptrace.tex | 134 + .../src/libunwind/doc/libunwind-setjmp.man | 132 + .../src/libunwind/doc/libunwind-setjmp.tex | 87 + .../src/pal/src/libunwind/doc/libunwind.man | 508 ++ .../src/pal/src/libunwind/doc/libunwind.tex | 359 ++ .../src/pal/src/libunwind/doc/libunwind.trans | 34 + .../src/libunwind/doc/unw_apply_reg_state.man | 90 + .../src/libunwind/doc/unw_apply_reg_state.tex | 63 + .../pal/src/libunwind/doc/unw_backtrace.man | 86 + .../pal/src/libunwind/doc/unw_backtrace.tex | 54 + .../libunwind/doc/unw_create_addr_space.man | 457 ++ .../libunwind/doc/unw_create_addr_space.tex | 265 + .../libunwind/doc/unw_destroy_addr_space.man | 57 + .../libunwind/doc/unw_destroy_addr_space.tex | 40 + .../pal/src/libunwind/doc/unw_flush_cache.man | 93 + .../pal/src/libunwind/doc/unw_flush_cache.tex | 58 + .../src/libunwind/doc/unw_get_accessors.man | 79 + .../src/libunwind/doc/unw_get_accessors.tex | 55 + .../pal/src/libunwind/doc/unw_get_fpreg.man | 111 + .../pal/src/libunwind/doc/unw_get_fpreg.tex | 77 + .../src/libunwind/doc/unw_get_proc_info.man | 203 + .../src/libunwind/doc/unw_get_proc_info.tex | 123 + .../libunwind/doc/unw_get_proc_info_by_ip.man | 134 + .../libunwind/doc/unw_get_proc_info_by_ip.tex | 91 + .../src/libunwind/doc/unw_get_proc_name.man | 123 + .../src/libunwind/doc/unw_get_proc_name.tex | 82 + .../src/pal/src/libunwind/doc/unw_get_reg.man | 112 + .../src/pal/src/libunwind/doc/unw_get_reg.tex | 77 + .../pal/src/libunwind/doc/unw_getcontext.man | 93 + .../pal/src/libunwind/doc/unw_getcontext.tex | 63 + .../pal/src/libunwind/doc/unw_init_local.man | 124 + .../pal/src/libunwind/doc/unw_init_local.tex | 80 + .../pal/src/libunwind/doc/unw_init_local2.man | 1 + .../pal/src/libunwind/doc/unw_init_remote.man | 123 + .../pal/src/libunwind/doc/unw_init_remote.tex | 79 + .../pal/src/libunwind/doc/unw_is_fpreg.man | 73 + .../pal/src/libunwind/doc/unw_is_fpreg.tex | 52 + .../src/libunwind/doc/unw_is_signal_frame.man | 88 + .../src/libunwind/doc/unw_is_signal_frame.tex | 67 + .../libunwind/doc/unw_reg_states_iterate.man | 137 + .../libunwind/doc/unw_reg_states_iterate.tex | 83 + .../src/pal/src/libunwind/doc/unw_regname.man | 68 + .../src/pal/src/libunwind/doc/unw_regname.tex | 47 + .../src/pal/src/libunwind/doc/unw_resume.man | 146 + .../src/pal/src/libunwind/doc/unw_resume.tex | 99 + .../src/libunwind/doc/unw_set_cache_size.man | 88 + .../src/libunwind/doc/unw_set_cache_size.tex | 59 + .../libunwind/doc/unw_set_caching_policy.man | 119 + .../libunwind/doc/unw_set_caching_policy.tex | 81 + .../pal/src/libunwind/doc/unw_set_fpreg.man | 117 + .../pal/src/libunwind/doc/unw_set_fpreg.tex | 79 + .../src/pal/src/libunwind/doc/unw_set_reg.man | 117 + .../src/pal/src/libunwind/doc/unw_set_reg.tex | 79 + .../src/pal/src/libunwind/doc/unw_step.man | 106 + .../src/pal/src/libunwind/doc/unw_step.tex | 68 + .../pal/src/libunwind/doc/unw_strerror.man | 63 + .../pal/src/libunwind/doc/unw_strerror.tex | 42 + .../src/pal/src/libunwind/include/compiler.h | 72 + .../src/pal/src/libunwind/include/dwarf-eh.h | 129 + .../src/pal/src/libunwind/include/dwarf.h | 450 ++ .../src/pal/src/libunwind/include/dwarf_i.h | 490 ++ .../src/libunwind/include/libunwind-aarch64.h | 245 + .../pal/src/libunwind/include/libunwind-arm.h | 303 + .../libunwind/include/libunwind-common.h.in | 292 + .../libunwind/include/libunwind-coredump.h | 73 + .../src/libunwind/include/libunwind-dynamic.h | 214 + .../src/libunwind/include/libunwind-hppa.h | 125 + .../src/libunwind/include/libunwind-ia64.h | 194 + .../src/libunwind/include/libunwind-mips.h | 160 + .../src/libunwind/include/libunwind-ppc32.h | 207 + .../src/libunwind/include/libunwind-ppc64.h | 271 + .../src/libunwind/include/libunwind-ptrace.h | 63 + .../src/libunwind/include/libunwind-s390x.h | 144 + .../pal/src/libunwind/include/libunwind-sh.h | 114 + .../src/libunwind/include/libunwind-tilegx.h | 161 + .../pal/src/libunwind/include/libunwind-x86.h | 187 + .../src/libunwind/include/libunwind-x86_64.h | 141 + .../pal/src/libunwind/include/libunwind.h.in | 38 + .../pal/src/libunwind/include/libunwind_i.h | 370 ++ .../src/pal/src/libunwind/include/mempool.h | 89 + .../src/pal/src/libunwind/include/remote.h | 129 + .../include/tdep-aarch64/dwarf-config.h | 52 + .../libunwind/include/tdep-aarch64/jmpbuf.h | 33 + .../include/tdep-aarch64/libunwind_i.h | 320 ++ .../libunwind/include/tdep-arm/dwarf-config.h | 51 + .../libunwind/include/tdep-arm/ex_tables.h | 55 + .../src/libunwind/include/tdep-arm/jmpbuf.h | 32 + .../libunwind/include/tdep-arm/libunwind_i.h | 326 ++ .../include/tdep-hppa/dwarf-config.h | 54 + .../src/libunwind/include/tdep-hppa/jmpbuf.h | 33 + .../libunwind/include/tdep-hppa/libunwind_i.h | 279 + .../src/libunwind/include/tdep-ia64/jmpbuf.h | 32 + .../libunwind/include/tdep-ia64/libunwind_i.h | 281 + .../pal/src/libunwind/include/tdep-ia64/rse.h | 67 + .../src/libunwind/include/tdep-ia64/script.h | 85 + .../include/tdep-mips/dwarf-config.h | 51 + .../src/libunwind/include/tdep-mips/jmpbuf.h | 32 + .../libunwind/include/tdep-mips/libunwind_i.h | 339 ++ .../include/tdep-ppc32/dwarf-config.h | 56 + .../src/libunwind/include/tdep-ppc32/jmpbuf.h | 37 + .../include/tdep-ppc32/libunwind_i.h | 314 + .../include/tdep-ppc64/dwarf-config.h | 56 + .../src/libunwind/include/tdep-ppc64/jmpbuf.h | 37 + .../include/tdep-ppc64/libunwind_i.h | 369 ++ .../include/tdep-s390x/dwarf-config.h | 52 + .../src/libunwind/include/tdep-s390x/jmpbuf.h | 35 + .../include/tdep-s390x/libunwind_i.h | 262 + .../libunwind/include/tdep-sh/dwarf-config.h | 49 + .../src/libunwind/include/tdep-sh/jmpbuf.h | 48 + .../libunwind/include/tdep-sh/libunwind_i.h | 280 + .../include/tdep-tilegx/dwarf-config.h | 50 + .../libunwind/include/tdep-tilegx/jmpbuf.h | 33 + .../include/tdep-tilegx/libunwind_i.h | 263 + .../libunwind/include/tdep-x86/dwarf-config.h | 52 + .../src/libunwind/include/tdep-x86/jmpbuf.h | 42 + .../libunwind/include/tdep-x86/libunwind_i.h | 293 + .../include/tdep-x86_64/dwarf-config.h | 57 + .../libunwind/include/tdep-x86_64/jmpbuf.h | 44 + .../include/tdep-x86_64/libunwind_i.h | 269 + .../src/libunwind/include/tdep/dwarf-config.h | 28 + .../pal/src/libunwind/include/tdep/jmpbuf.h | 30 + .../libunwind/include/tdep/libunwind_i.h.in | 39 + .../src/pal/src/libunwind/include/unwind.h | 154 + .../pal/src/libunwind/include/x86/jmpbuf.h | 31 + .../pal/src/libunwind/scripts/kernel-diff.sh | 10 + .../src/libunwind/scripts/kernel-files.txt | 19 + .../pal/src/libunwind/scripts/make-L-files | 30 + .../src/pal/src/libunwind/src/Makefile.am | 795 +++ .../libunwind/src/aarch64/Gapply_reg_state.c | 37 + .../src/aarch64/Gcreate_addr_space.c | 60 + .../libunwind/src/aarch64/Gget_proc_info.c | 39 + .../src/libunwind/src/aarch64/Gget_save_loc.c | 100 + .../pal/src/libunwind/src/aarch64/Gglobal.c | 57 + .../src/pal/src/libunwind/src/aarch64/Ginit.c | 189 + .../src/libunwind/src/aarch64/Ginit_local.c | 78 + .../src/libunwind/src/aarch64/Ginit_remote.c | 45 + .../libunwind/src/aarch64/Gis_signal_frame.c | 64 + .../src/aarch64/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/aarch64/Gregs.c | 118 + .../pal/src/libunwind/src/aarch64/Gresume.c | 198 + .../src/libunwind/src/aarch64/Gstash_frame.c | 89 + .../src/pal/src/libunwind/src/aarch64/Gstep.c | 189 + .../pal/src/libunwind/src/aarch64/Gtrace.c | 548 ++ .../libunwind/src/aarch64/Lapply_reg_state.c | 5 + .../src/aarch64/Lcreate_addr_space.c | 5 + .../libunwind/src/aarch64/Lget_proc_info.c | 5 + .../src/libunwind/src/aarch64/Lget_save_loc.c | 5 + .../pal/src/libunwind/src/aarch64/Lglobal.c | 5 + .../src/pal/src/libunwind/src/aarch64/Linit.c | 5 + .../src/libunwind/src/aarch64/Linit_local.c | 5 + .../src/libunwind/src/aarch64/Linit_remote.c | 5 + .../libunwind/src/aarch64/Lis_signal_frame.c | 5 + .../src/aarch64/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/aarch64/Lregs.c | 5 + .../pal/src/libunwind/src/aarch64/Lresume.c | 5 + .../src/libunwind/src/aarch64/Lstash_frame.c | 5 + .../src/pal/src/libunwind/src/aarch64/Lstep.c | 5 + .../pal/src/libunwind/src/aarch64/Ltrace.c | 5 + .../src/libunwind/src/aarch64/gen-offsets.c | 68 + .../src/libunwind/src/aarch64/getcontext.S | 52 + .../src/pal/src/libunwind/src/aarch64/init.h | 126 + .../pal/src/libunwind/src/aarch64/is_fpreg.c | 32 + .../pal/src/libunwind/src/aarch64/offsets.h | 49 + .../pal/src/libunwind/src/aarch64/regname.c | 106 + .../src/libunwind/src/aarch64/siglongjmp.S | 12 + .../pal/src/libunwind/src/aarch64/unwind_i.h | 64 + .../src/libunwind/src/arm/Gapply_reg_state.c | 37 + .../libunwind/src/arm/Gcreate_addr_space.c | 60 + .../pal/src/libunwind/src/arm/Gex_tables.c | 549 ++ .../src/libunwind/src/arm/Gget_proc_info.c | 41 + .../pal/src/libunwind/src/arm/Gget_save_loc.c | 81 + .../src/pal/src/libunwind/src/arm/Gglobal.c | 65 + .../src/pal/src/libunwind/src/arm/Ginit.c | 234 + .../pal/src/libunwind/src/arm/Ginit_local.c | 78 + .../pal/src/libunwind/src/arm/Ginit_remote.c | 45 + .../pal/src/libunwind/src/arm/Gos-freebsd.c | 129 + .../src/pal/src/libunwind/src/arm/Gos-linux.c | 182 + .../src/pal/src/libunwind/src/arm/Gos-other.c | 48 + .../libunwind/src/arm/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/arm/Gregs.c | 83 + .../src/pal/src/libunwind/src/arm/Gresume.c | 154 + .../pal/src/libunwind/src/arm/Gstash_frame.c | 90 + .../src/pal/src/libunwind/src/arm/Gstep.c | 201 + .../src/pal/src/libunwind/src/arm/Gtrace.c | 557 ++ .../src/libunwind/src/arm/Lapply_reg_state.c | 5 + .../libunwind/src/arm/Lcreate_addr_space.c | 5 + .../pal/src/libunwind/src/arm/Lex_tables.c | 5 + .../src/libunwind/src/arm/Lget_proc_info.c | 5 + .../pal/src/libunwind/src/arm/Lget_save_loc.c | 5 + .../src/pal/src/libunwind/src/arm/Lglobal.c | 5 + .../src/pal/src/libunwind/src/arm/Linit.c | 5 + .../pal/src/libunwind/src/arm/Linit_local.c | 5 + .../pal/src/libunwind/src/arm/Linit_remote.c | 5 + .../src/libunwind/src/arm/Lis_signal_frame.c | 5 + .../pal/src/libunwind/src/arm/Los-freebsd.c | 5 + .../src/pal/src/libunwind/src/arm/Los-linux.c | 5 + .../src/pal/src/libunwind/src/arm/Los-other.c | 5 + .../libunwind/src/arm/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/arm/Lregs.c | 5 + .../src/pal/src/libunwind/src/arm/Lresume.c | 5 + .../pal/src/libunwind/src/arm/Lstash_frame.c | 5 + .../src/pal/src/libunwind/src/arm/Lstep.c | 5 + .../src/pal/src/libunwind/src/arm/Ltrace.c | 6 + .../pal/src/libunwind/src/arm/gen-offsets.c | 54 + .../pal/src/libunwind/src/arm/getcontext.S | 63 + .../src/pal/src/libunwind/src/arm/init.h | 77 + .../src/pal/src/libunwind/src/arm/is_fpreg.c | 39 + .../src/pal/src/libunwind/src/arm/offsets.h | 42 + .../src/pal/src/libunwind/src/arm/regname.c | 90 + .../pal/src/libunwind/src/arm/siglongjmp.S | 12 + .../src/pal/src/libunwind/src/arm/unwind_i.h | 62 + .../src/pal/src/libunwind/src/coredump/README | 8 + .../libunwind/src/coredump/_UCD_access_mem.c | 98 + .../src/coredump/_UCD_access_reg_freebsd.c | 157 + .../src/coredump/_UCD_access_reg_linux.c | 149 + .../libunwind/src/coredump/_UCD_accessors.c | 36 + .../src/libunwind/src/coredump/_UCD_create.c | 424 ++ .../src/libunwind/src/coredump/_UCD_destroy.c | 52 + .../src/coredump/_UCD_elf_map_image.c | 98 + .../src/coredump/_UCD_find_proc_info.c | 163 + .../src/coredump/_UCD_get_proc_name.c | 74 + .../libunwind/src/coredump/_UCD_internal.h | 105 + .../pal/src/libunwind/src/coredump/_UCD_lib.h | 57 + .../src/coredump/_UPT_access_fpreg.c | 34 + .../pal/src/libunwind/src/coredump/_UPT_elf.c | 5 + .../coredump/_UPT_get_dyn_info_list_addr.c | 113 + .../src/coredump/_UPT_put_unwind_info.c | 36 + .../src/libunwind/src/coredump/_UPT_resume.c | 35 + .../src/coredump/libunwind-coredump.pc.in | 11 + .../src/pal/src/libunwind/src/dwarf/Gexpr.c | 702 +++ .../src/pal/src/libunwind/src/dwarf/Gfde.c | 359 ++ .../libunwind/src/dwarf/Gfind_proc_info-lsb.c | 990 ++++ .../libunwind/src/dwarf/Gfind_unwind_table.c | 233 + .../src/pal/src/libunwind/src/dwarf/Gparser.c | 1081 ++++ .../src/pal/src/libunwind/src/dwarf/Gpe.c | 39 + .../src/pal/src/libunwind/src/dwarf/Lexpr.c | 5 + .../src/pal/src/libunwind/src/dwarf/Lfde.c | 5 + .../libunwind/src/dwarf/Lfind_proc_info-lsb.c | 5 + .../libunwind/src/dwarf/Lfind_unwind_table.c | 5 + .../src/pal/src/libunwind/src/dwarf/Lparser.c | 5 + .../src/pal/src/libunwind/src/dwarf/Lpe.c | 5 + .../src/pal/src/libunwind/src/dwarf/global.c | 37 + src/coreclr/src/pal/src/libunwind/src/elf32.c | 4 + src/coreclr/src/pal/src/libunwind/src/elf32.h | 9 + src/coreclr/src/pal/src/libunwind/src/elf64.c | 4 + src/coreclr/src/pal/src/libunwind/src/elf64.h | 9 + src/coreclr/src/pal/src/libunwind/src/elfxx.c | 482 ++ src/coreclr/src/pal/src/libunwind/src/elfxx.h | 101 + .../src/libunwind/src/hppa/Gapply_reg_state.c | 37 + .../libunwind/src/hppa/Gcreate_addr_space.c | 54 + .../src/libunwind/src/hppa/Gget_proc_info.c | 46 + .../src/libunwind/src/hppa/Gget_save_loc.c | 59 + .../src/pal/src/libunwind/src/hppa/Gglobal.c | 55 + .../src/pal/src/libunwind/src/hppa/Ginit.c | 193 + .../pal/src/libunwind/src/hppa/Ginit_local.c | 77 + .../pal/src/libunwind/src/hppa/Ginit_remote.c | 46 + .../src/libunwind/src/hppa/Gis_signal_frame.c | 74 + .../libunwind/src/hppa/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/hppa/Gregs.c | 87 + .../src/pal/src/libunwind/src/hppa/Gresume.c | 145 + .../src/pal/src/libunwind/src/hppa/Gstep.c | 95 + .../src/libunwind/src/hppa/Lapply_reg_state.c | 5 + .../libunwind/src/hppa/Lcreate_addr_space.c | 5 + .../src/libunwind/src/hppa/Lget_proc_info.c | 5 + .../src/libunwind/src/hppa/Lget_save_loc.c | 5 + .../src/pal/src/libunwind/src/hppa/Lglobal.c | 5 + .../src/pal/src/libunwind/src/hppa/Linit.c | 5 + .../pal/src/libunwind/src/hppa/Linit_local.c | 5 + .../pal/src/libunwind/src/hppa/Linit_remote.c | 5 + .../src/libunwind/src/hppa/Lis_signal_frame.c | 5 + .../libunwind/src/hppa/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/hppa/Lregs.c | 5 + .../src/pal/src/libunwind/src/hppa/Lresume.c | 5 + .../src/pal/src/libunwind/src/hppa/Lstep.c | 5 + .../src/libunwind/src/hppa/get_accessors.c | 38 + .../pal/src/libunwind/src/hppa/getcontext.S | 74 + .../src/pal/src/libunwind/src/hppa/init.h | 47 + .../src/pal/src/libunwind/src/hppa/offsets.h | 17 + .../src/pal/src/libunwind/src/hppa/regname.c | 50 + .../pal/src/libunwind/src/hppa/setcontext.S | 77 + .../pal/src/libunwind/src/hppa/siglongjmp.S | 16 + .../src/pal/src/libunwind/src/hppa/tables.c | 43 + .../src/pal/src/libunwind/src/hppa/unwind_i.h | 47 + .../src/libunwind/src/ia64/Gapply_reg_state.c | 39 + .../libunwind/src/ia64/Gcreate_addr_space.c | 63 + .../libunwind/src/ia64/Gfind_unwind_table.c | 143 + .../src/libunwind/src/ia64/Gget_proc_info.c | 38 + .../src/libunwind/src/ia64/Gget_save_loc.c | 168 + .../src/pal/src/libunwind/src/ia64/Gglobal.c | 122 + .../src/pal/src/libunwind/src/ia64/Ginit.c | 506 ++ .../pal/src/libunwind/src/ia64/Ginit_local.c | 110 + .../pal/src/libunwind/src/ia64/Ginit_remote.c | 61 + .../src/libunwind/src/ia64/Ginstall_cursor.S | 348 ++ .../src/libunwind/src/ia64/Gis_signal_frame.c | 54 + .../src/pal/src/libunwind/src/ia64/Gparser.c | 1131 ++++ .../src/pal/src/libunwind/src/ia64/Grbs.c | 319 + .../libunwind/src/ia64/Greg_states_iterate.c | 39 + .../src/pal/src/libunwind/src/ia64/Gregs.c | 612 ++ .../src/pal/src/libunwind/src/ia64/Gresume.c | 274 + .../src/pal/src/libunwind/src/ia64/Gscript.c | 765 +++ .../src/pal/src/libunwind/src/ia64/Gstep.c | 359 ++ .../src/pal/src/libunwind/src/ia64/Gtables.c | 731 +++ .../src/libunwind/src/ia64/Lapply_reg_state.c | 5 + .../libunwind/src/ia64/Lcreate_addr_space.c | 5 + .../libunwind/src/ia64/Lfind_unwind_table.c | 5 + .../src/libunwind/src/ia64/Lget_proc_info.c | 5 + .../src/libunwind/src/ia64/Lget_save_loc.c | 5 + .../src/pal/src/libunwind/src/ia64/Lglobal.c | 5 + .../src/pal/src/libunwind/src/ia64/Linit.c | 5 + .../pal/src/libunwind/src/ia64/Linit_local.c | 5 + .../pal/src/libunwind/src/ia64/Linit_remote.c | 5 + .../src/libunwind/src/ia64/Linstall_cursor.S | 6 + .../src/libunwind/src/ia64/Lis_signal_frame.c | 5 + .../src/pal/src/libunwind/src/ia64/Lparser.c | 5 + .../src/pal/src/libunwind/src/ia64/Lrbs.c | 5 + .../libunwind/src/ia64/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/ia64/Lregs.c | 5 + .../src/pal/src/libunwind/src/ia64/Lresume.c | 5 + .../src/pal/src/libunwind/src/ia64/Lscript.c | 5 + .../src/pal/src/libunwind/src/ia64/Lstep.c | 5 + .../src/pal/src/libunwind/src/ia64/Ltables.c | 5 + .../src/pal/src/libunwind/src/ia64/NOTES | 65 + .../src/libunwind/src/ia64/dyn_info_list.S | 26 + .../pal/src/libunwind/src/ia64/getcontext.S | 177 + .../src/pal/src/libunwind/src/ia64/init.h | 132 + .../src/pal/src/libunwind/src/ia64/longjmp.S | 42 + .../pal/src/libunwind/src/ia64/mk_cursor_i | 7 + .../src/pal/src/libunwind/src/ia64/offsets.h | 137 + .../src/pal/src/libunwind/src/ia64/regname.c | 189 + .../src/pal/src/libunwind/src/ia64/regs.h | 73 + .../src/pal/src/libunwind/src/ia64/setjmp.S | 51 + .../pal/src/libunwind/src/ia64/siglongjmp.S | 69 + .../pal/src/libunwind/src/ia64/sigsetjmp.S | 69 + .../pal/src/libunwind/src/ia64/ucontext_i.h | 68 + .../src/libunwind/src/ia64/unwind_decoder.h | 477 ++ .../src/pal/src/libunwind/src/ia64/unwind_i.h | 633 ++ .../src/libunwind/src/libunwind-generic.pc.in | 11 + .../libunwind/src/mi/Gdestroy_addr_space.c | 37 + .../pal/src/libunwind/src/mi/Gdyn-extract.c | 64 + .../pal/src/libunwind/src/mi/Gdyn-remote.c | 326 ++ .../src/mi/Gfind_dynamic_proc_info.c | 92 + .../pal/src/libunwind/src/mi/Gget_accessors.c | 37 + .../src/pal/src/libunwind/src/mi/Gget_fpreg.c | 34 + .../libunwind/src/mi/Gget_proc_info_by_ip.c | 39 + .../pal/src/libunwind/src/mi/Gget_proc_name.c | 126 + .../src/pal/src/libunwind/src/mi/Gget_reg.c | 41 + .../src/mi/Gput_dynamic_unwind_info.c | 55 + .../src/libunwind/src/mi/Gset_cache_size.c | 72 + .../libunwind/src/mi/Gset_caching_policy.c | 46 + .../src/pal/src/libunwind/src/mi/Gset_fpreg.c | 34 + .../src/pal/src/libunwind/src/mi/Gset_reg.c | 34 + .../libunwind/src/mi/Ldestroy_addr_space.c | 5 + .../pal/src/libunwind/src/mi/Ldyn-extract.c | 5 + .../pal/src/libunwind/src/mi/Ldyn-remote.c | 5 + .../src/mi/Lfind_dynamic_proc_info.c | 5 + .../pal/src/libunwind/src/mi/Lget_accessors.c | 5 + .../src/pal/src/libunwind/src/mi/Lget_fpreg.c | 5 + .../libunwind/src/mi/Lget_proc_info_by_ip.c | 5 + .../pal/src/libunwind/src/mi/Lget_proc_name.c | 5 + .../src/pal/src/libunwind/src/mi/Lget_reg.c | 5 + .../src/mi/Lput_dynamic_unwind_info.c | 5 + .../src/libunwind/src/mi/Lset_cache_size.c | 5 + .../libunwind/src/mi/Lset_caching_policy.c | 5 + .../src/pal/src/libunwind/src/mi/Lset_fpreg.c | 5 + .../src/pal/src/libunwind/src/mi/Lset_reg.c | 5 + .../src/pal/src/libunwind/src/mi/_ReadSLEB.c | 25 + .../src/pal/src/libunwind/src/mi/_ReadULEB.c | 20 + .../src/pal/src/libunwind/src/mi/backtrace.c | 83 + .../src/pal/src/libunwind/src/mi/dyn-cancel.c | 46 + .../pal/src/libunwind/src/mi/dyn-info-list.c | 34 + .../pal/src/libunwind/src/mi/dyn-register.c | 44 + .../pal/src/libunwind/src/mi/flush_cache.c | 62 + .../src/pal/src/libunwind/src/mi/init.c | 60 + .../src/pal/src/libunwind/src/mi/mempool.c | 184 + .../src/pal/src/libunwind/src/mi/strerror.c | 51 + .../src/libunwind/src/mips/Gapply_reg_state.c | 37 + .../libunwind/src/mips/Gcreate_addr_space.c | 73 + .../src/libunwind/src/mips/Gget_proc_info.c | 44 + .../src/libunwind/src/mips/Gget_save_loc.c | 100 + .../src/pal/src/libunwind/src/mips/Gglobal.c | 55 + .../src/pal/src/libunwind/src/mips/Ginit.c | 209 + .../pal/src/libunwind/src/mips/Ginit_local.c | 76 + .../pal/src/libunwind/src/mips/Ginit_remote.c | 45 + .../src/libunwind/src/mips/Gis_signal_frame.c | 78 + .../libunwind/src/mips/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/mips/Gregs.c | 106 + .../src/pal/src/libunwind/src/mips/Gresume.c | 45 + .../src/pal/src/libunwind/src/mips/Gstep.c | 224 + .../src/libunwind/src/mips/Lapply_reg_state.c | 5 + .../libunwind/src/mips/Lcreate_addr_space.c | 5 + .../src/libunwind/src/mips/Lget_proc_info.c | 5 + .../src/libunwind/src/mips/Lget_save_loc.c | 5 + .../src/pal/src/libunwind/src/mips/Lglobal.c | 5 + .../src/pal/src/libunwind/src/mips/Linit.c | 5 + .../pal/src/libunwind/src/mips/Linit_local.c | 5 + .../pal/src/libunwind/src/mips/Linit_remote.c | 5 + .../src/libunwind/src/mips/Lis_signal_frame.c | 5 + .../libunwind/src/mips/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/mips/Lregs.c | 5 + .../src/pal/src/libunwind/src/mips/Lresume.c | 5 + .../src/pal/src/libunwind/src/mips/Lstep.c | 5 + .../src/pal/src/libunwind/src/mips/elfxx.c | 27 + .../pal/src/libunwind/src/mips/gen-offsets.c | 30 + .../pal/src/libunwind/src/mips/getcontext.S | 93 + .../src/pal/src/libunwind/src/mips/init.h | 59 + .../src/pal/src/libunwind/src/mips/is_fpreg.c | 35 + .../src/pal/src/libunwind/src/mips/offsets.h | 86 + .../src/pal/src/libunwind/src/mips/regname.c | 48 + .../pal/src/libunwind/src/mips/siglongjmp.S | 8 + .../src/pal/src/libunwind/src/mips/unwind_i.h | 43 + .../src/pal/src/libunwind/src/os-freebsd.c | 166 + .../src/pal/src/libunwind/src/os-hpux.c | 78 + .../src/pal/src/libunwind/src/os-linux.c | 73 + .../src/pal/src/libunwind/src/os-linux.h | 297 + .../src/pal/src/libunwind/src/os-qnx.c | 117 + .../src/pal/src/libunwind/src/os-solaris.c | 73 + .../src/libunwind/src/ppc/Gapply_reg_state.c | 37 + .../src/libunwind/src/ppc/Gget_proc_info.c | 41 + .../pal/src/libunwind/src/ppc/Gget_save_loc.c | 34 + .../pal/src/libunwind/src/ppc/Ginit_local.c | 88 + .../pal/src/libunwind/src/ppc/Ginit_remote.c | 60 + .../src/libunwind/src/ppc/Gis_signal_frame.c | 78 + .../libunwind/src/ppc/Greg_states_iterate.c | 37 + .../src/libunwind/src/ppc/Lapply_reg_state.c | 5 + .../src/libunwind/src/ppc/Lget_proc_info.c | 5 + .../pal/src/libunwind/src/ppc/Lget_save_loc.c | 5 + .../pal/src/libunwind/src/ppc/Linit_local.c | 5 + .../pal/src/libunwind/src/ppc/Linit_remote.c | 5 + .../src/libunwind/src/ppc/Lis_signal_frame.c | 5 + .../libunwind/src/ppc/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/ppc/longjmp.S | 36 + .../pal/src/libunwind/src/ppc/siglongjmp.S | 31 + .../libunwind/src/ppc32/Gapply_reg_state.c | 37 + .../libunwind/src/ppc32/Gcreate_addr_space.c | 56 + .../src/pal/src/libunwind/src/ppc32/Gglobal.c | 135 + .../src/pal/src/libunwind/src/ppc32/Ginit.c | 219 + .../libunwind/src/ppc32/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/ppc32/Gregs.c | 90 + .../src/pal/src/libunwind/src/ppc32/Gresume.c | 77 + .../src/pal/src/libunwind/src/ppc32/Gstep.c | 309 + .../libunwind/src/ppc32/Lapply_reg_state.c | 5 + .../libunwind/src/ppc32/Lcreate_addr_space.c | 5 + .../src/pal/src/libunwind/src/ppc32/Lglobal.c | 5 + .../src/pal/src/libunwind/src/ppc32/Linit.c | 5 + .../libunwind/src/ppc32/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/ppc32/Lregs.c | 5 + .../src/pal/src/libunwind/src/ppc32/Lresume.c | 5 + .../src/pal/src/libunwind/src/ppc32/Lstep.c | 5 + .../pal/src/libunwind/src/ppc32/Make-arch.in | 11 + .../src/libunwind/src/ppc32/get_func_addr.c | 36 + .../src/pal/src/libunwind/src/ppc32/init.h | 72 + .../pal/src/libunwind/src/ppc32/is_fpreg.c | 34 + .../src/pal/src/libunwind/src/ppc32/regname.c | 112 + .../pal/src/libunwind/src/ppc32/setcontext.S | 9 + .../pal/src/libunwind/src/ppc32/ucontext_i.h | 128 + .../pal/src/libunwind/src/ppc32/unwind_i.h | 46 + .../libunwind/src/ppc64/Gapply_reg_state.c | 37 + .../libunwind/src/ppc64/Gcreate_addr_space.c | 71 + .../src/pal/src/libunwind/src/ppc64/Gglobal.c | 182 + .../src/pal/src/libunwind/src/ppc64/Ginit.c | 232 + .../libunwind/src/ppc64/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/ppc64/Gregs.c | 141 + .../src/pal/src/libunwind/src/ppc64/Gresume.c | 111 + .../src/pal/src/libunwind/src/ppc64/Gstep.c | 466 ++ .../libunwind/src/ppc64/Lapply_reg_state.c | 5 + .../libunwind/src/ppc64/Lcreate_addr_space.c | 5 + .../src/pal/src/libunwind/src/ppc64/Lglobal.c | 5 + .../src/pal/src/libunwind/src/ppc64/Linit.c | 5 + .../libunwind/src/ppc64/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/ppc64/Lregs.c | 5 + .../src/pal/src/libunwind/src/ppc64/Lresume.c | 5 + .../src/pal/src/libunwind/src/ppc64/Lstep.c | 5 + .../src/libunwind/src/ppc64/get_func_addr.c | 51 + .../src/pal/src/libunwind/src/ppc64/init.h | 82 + .../pal/src/libunwind/src/ppc64/is_fpreg.c | 34 + .../src/pal/src/libunwind/src/ppc64/regname.c | 164 + .../pal/src/libunwind/src/ppc64/setcontext.S | 9 + .../pal/src/libunwind/src/ppc64/ucontext_i.h | 173 + .../pal/src/libunwind/src/ppc64/unwind_i.h | 52 + .../libunwind/src/ptrace/_UPT_access_fpreg.c | 128 + .../libunwind/src/ptrace/_UPT_access_mem.c | 123 + .../libunwind/src/ptrace/_UPT_access_reg.c | 352 ++ .../src/libunwind/src/ptrace/_UPT_accessors.c | 38 + .../src/libunwind/src/ptrace/_UPT_create.c | 46 + .../src/libunwind/src/ptrace/_UPT_destroy.c | 34 + .../pal/src/libunwind/src/ptrace/_UPT_elf.c | 5 + .../src/ptrace/_UPT_find_proc_info.c | 145 + .../src/ptrace/_UPT_get_dyn_info_list_addr.c | 110 + .../libunwind/src/ptrace/_UPT_get_proc_name.c | 42 + .../src/libunwind/src/ptrace/_UPT_internal.h | 59 + .../src/ptrace/_UPT_put_unwind_info.c | 35 + .../libunwind/src/ptrace/_UPT_reg_offset.c | 672 +++ .../src/libunwind/src/ptrace/_UPT_resume.c | 40 + .../src/ptrace/libunwind-ptrace.pc.in | 11 + .../libunwind/src/s390x/Gapply_reg_state.c | 37 + .../libunwind/src/s390x/Gcreate_addr_space.c | 62 + .../src/libunwind/src/s390x/Gget_proc_info.c | 48 + .../src/libunwind/src/s390x/Gget_save_loc.c | 86 + .../src/pal/src/libunwind/src/s390x/Gglobal.c | 101 + .../src/pal/src/libunwind/src/s390x/Ginit.c | 365 ++ .../pal/src/libunwind/src/s390x/Ginit_local.c | 81 + .../src/libunwind/src/s390x/Ginit_remote.c | 57 + .../libunwind/src/s390x/Gis_signal_frame.c | 77 + .../libunwind/src/s390x/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/s390x/Gregs.c | 116 + .../src/pal/src/libunwind/src/s390x/Gresume.c | 160 + .../src/pal/src/libunwind/src/s390x/Gstep.c | 146 + .../libunwind/src/s390x/Lapply_reg_state.c | 5 + .../libunwind/src/s390x/Lcreate_addr_space.c | 5 + .../src/libunwind/src/s390x/Lget_proc_info.c | 5 + .../src/libunwind/src/s390x/Lget_save_loc.c | 5 + .../src/pal/src/libunwind/src/s390x/Lglobal.c | 6 + .../src/pal/src/libunwind/src/s390x/Linit.c | 5 + .../pal/src/libunwind/src/s390x/Linit_local.c | 5 + .../src/libunwind/src/s390x/Linit_remote.c | 5 + .../libunwind/src/s390x/Lis_signal_frame.c | 5 + .../libunwind/src/s390x/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/s390x/Lregs.c | 5 + .../src/pal/src/libunwind/src/s390x/Lresume.c | 5 + .../src/pal/src/libunwind/src/s390x/Lstep.c | 5 + .../pal/src/libunwind/src/s390x/getcontext.S | 74 + .../src/pal/src/libunwind/src/s390x/init.h | 71 + .../pal/src/libunwind/src/s390x/is_fpreg.c | 36 + .../src/pal/src/libunwind/src/s390x/regname.c | 57 + .../pal/src/libunwind/src/s390x/setcontext.S | 76 + .../pal/src/libunwind/src/s390x/unwind_i.h | 48 + .../src/setjmp/libunwind-setjmp.pc.in | 11 + .../pal/src/libunwind/src/setjmp/longjmp.c | 115 + .../src/pal/src/libunwind/src/setjmp/setjmp.c | 49 + .../pal/src/libunwind/src/setjmp/setjmp_i.h | 118 + .../pal/src/libunwind/src/setjmp/siglongjmp.c | 131 + .../pal/src/libunwind/src/setjmp/sigsetjmp.c | 50 + .../src/libunwind/src/sh/Gapply_reg_state.c | 37 + .../src/libunwind/src/sh/Gcreate_addr_space.c | 59 + .../pal/src/libunwind/src/sh/Gget_proc_info.c | 39 + .../pal/src/libunwind/src/sh/Gget_save_loc.c | 83 + .../src/pal/src/libunwind/src/sh/Gglobal.c | 56 + .../src/pal/src/libunwind/src/sh/Ginit.c | 185 + .../pal/src/libunwind/src/sh/Ginit_local.c | 78 + .../pal/src/libunwind/src/sh/Ginit_remote.c | 45 + .../src/libunwind/src/sh/Gis_signal_frame.c | 119 + .../libunwind/src/sh/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/sh/Gregs.c | 81 + .../src/pal/src/libunwind/src/sh/Gresume.c | 165 + .../src/pal/src/libunwind/src/sh/Gstep.c | 117 + .../src/libunwind/src/sh/Lapply_reg_state.c | 5 + .../src/libunwind/src/sh/Lcreate_addr_space.c | 5 + .../pal/src/libunwind/src/sh/Lget_proc_info.c | 5 + .../pal/src/libunwind/src/sh/Lget_save_loc.c | 5 + .../src/pal/src/libunwind/src/sh/Lglobal.c | 5 + .../src/pal/src/libunwind/src/sh/Linit.c | 5 + .../pal/src/libunwind/src/sh/Linit_local.c | 5 + .../pal/src/libunwind/src/sh/Linit_remote.c | 5 + .../src/libunwind/src/sh/Lis_signal_frame.c | 5 + .../libunwind/src/sh/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/sh/Lregs.c | 5 + .../src/pal/src/libunwind/src/sh/Lresume.c | 5 + .../src/pal/src/libunwind/src/sh/Lstep.c | 5 + .../pal/src/libunwind/src/sh/gen-offsets.c | 51 + .../src/pal/src/libunwind/src/sh/init.h | 73 + .../src/pal/src/libunwind/src/sh/is_fpreg.c | 32 + .../src/pal/src/libunwind/src/sh/offsets.h | 32 + .../src/pal/src/libunwind/src/sh/regname.c | 56 + .../src/pal/src/libunwind/src/sh/siglongjmp.S | 8 + .../src/pal/src/libunwind/src/sh/unwind_i.h | 40 + .../libunwind/src/tilegx/Gapply_reg_state.c | 37 + .../libunwind/src/tilegx/Gcreate_addr_space.c | 65 + .../src/libunwind/src/tilegx/Gget_proc_info.c | 48 + .../src/libunwind/src/tilegx/Gget_save_loc.c | 62 + .../pal/src/libunwind/src/tilegx/Gglobal.c | 64 + .../src/pal/src/libunwind/src/tilegx/Ginit.c | 166 + .../src/libunwind/src/tilegx/Ginit_local.c | 80 + .../src/libunwind/src/tilegx/Ginit_remote.c | 47 + .../libunwind/src/tilegx/Gis_signal_frame.c | 115 + .../src/tilegx/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/tilegx/Gregs.c | 76 + .../pal/src/libunwind/src/tilegx/Gresume.c | 94 + .../src/pal/src/libunwind/src/tilegx/Gstep.c | 53 + .../libunwind/src/tilegx/Lapply_reg_state.c | 5 + .../libunwind/src/tilegx/Lcreate_addr_space.c | 5 + .../src/libunwind/src/tilegx/Lget_proc_info.c | 5 + .../src/libunwind/src/tilegx/Lget_save_loc.c | 5 + .../pal/src/libunwind/src/tilegx/Lglobal.c | 5 + .../src/pal/src/libunwind/src/tilegx/Linit.c | 5 + .../src/libunwind/src/tilegx/Linit_local.c | 5 + .../src/libunwind/src/tilegx/Linit_remote.c | 5 + .../libunwind/src/tilegx/Lis_signal_frame.c | 5 + .../src/tilegx/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/tilegx/Lregs.c | 5 + .../pal/src/libunwind/src/tilegx/Lresume.c | 5 + .../src/pal/src/libunwind/src/tilegx/Lstep.c | 5 + .../src/pal/src/libunwind/src/tilegx/elfxx.c | 27 + .../src/libunwind/src/tilegx/gen-offsets.c | 30 + .../pal/src/libunwind/src/tilegx/getcontext.S | 36 + .../src/pal/src/libunwind/src/tilegx/init.h | 63 + .../pal/src/libunwind/src/tilegx/is_fpreg.c | 33 + .../pal/src/libunwind/src/tilegx/offsets.h | 12 + .../pal/src/libunwind/src/tilegx/regname.c | 55 + .../pal/src/libunwind/src/tilegx/siglongjmp.S | 7 + .../pal/src/libunwind/src/tilegx/unwind_i.h | 46 + .../pal/src/libunwind/src/unwind/Backtrace.c | 56 + .../libunwind/src/unwind/DeleteException.c | 38 + .../src/unwind/FindEnclosingFunction.c | 42 + .../src/libunwind/src/unwind/ForcedUnwind.c | 52 + .../src/pal/src/libunwind/src/unwind/GetBSP.c | 42 + .../src/pal/src/libunwind/src/unwind/GetCFA.c | 38 + .../src/libunwind/src/unwind/GetDataRelBase.c | 39 + .../src/pal/src/libunwind/src/unwind/GetGR.c | 43 + .../src/pal/src/libunwind/src/unwind/GetIP.c | 38 + .../pal/src/libunwind/src/unwind/GetIPInfo.c | 42 + .../src/unwind/GetLanguageSpecificData.c | 40 + .../src/libunwind/src/unwind/GetRegionStart.c | 39 + .../src/libunwind/src/unwind/GetTextRelBase.c | 35 + .../src/libunwind/src/unwind/RaiseException.c | 103 + .../src/pal/src/libunwind/src/unwind/Resume.c | 42 + .../libunwind/src/unwind/Resume_or_Rethrow.c | 47 + .../src/pal/src/libunwind/src/unwind/SetGR.c | 47 + .../src/pal/src/libunwind/src/unwind/SetIP.c | 35 + .../src/libunwind/src/unwind/libunwind.pc.in | 11 + .../libunwind/src/unwind/unwind-internal.h | 140 + .../src/libunwind/src/x86/Gapply_reg_state.c | 37 + .../libunwind/src/x86/Gcreate_addr_space.c | 58 + .../src/libunwind/src/x86/Gget_proc_info.c | 45 + .../pal/src/libunwind/src/x86/Gget_save_loc.c | 133 + .../src/pal/src/libunwind/src/x86/Gglobal.c | 67 + .../src/pal/src/libunwind/src/x86/Ginit.c | 242 + .../pal/src/libunwind/src/x86/Ginit_local.c | 79 + .../pal/src/libunwind/src/x86/Ginit_remote.c | 56 + .../pal/src/libunwind/src/x86/Gos-freebsd.c | 374 ++ .../src/pal/src/libunwind/src/x86/Gos-linux.c | 331 ++ .../libunwind/src/x86/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/x86/Gregs.c | 178 + .../src/pal/src/libunwind/src/x86/Gresume.c | 91 + .../src/pal/src/libunwind/src/x86/Gstep.c | 115 + .../src/libunwind/src/x86/Lapply_reg_state.c | 5 + .../libunwind/src/x86/Lcreate_addr_space.c | 5 + .../src/libunwind/src/x86/Lget_proc_info.c | 5 + .../pal/src/libunwind/src/x86/Lget_save_loc.c | 5 + .../src/pal/src/libunwind/src/x86/Lglobal.c | 5 + .../src/pal/src/libunwind/src/x86/Linit.c | 5 + .../pal/src/libunwind/src/x86/Linit_local.c | 5 + .../pal/src/libunwind/src/x86/Linit_remote.c | 5 + .../pal/src/libunwind/src/x86/Los-freebsd.c | 5 + .../src/pal/src/libunwind/src/x86/Los-linux.c | 5 + .../libunwind/src/x86/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/x86/Lregs.c | 5 + .../src/pal/src/libunwind/src/x86/Lresume.c | 5 + .../src/pal/src/libunwind/src/x86/Lstep.c | 5 + .../libunwind/src/x86/getcontext-freebsd.S | 112 + .../src/libunwind/src/x86/getcontext-linux.S | 74 + .../src/pal/src/libunwind/src/x86/init.h | 69 + .../src/pal/src/libunwind/src/x86/is_fpreg.c | 34 + .../src/pal/src/libunwind/src/x86/longjmp.S | 39 + .../src/pal/src/libunwind/src/x86/offsets.h | 140 + .../src/pal/src/libunwind/src/x86/regname.c | 27 + .../pal/src/libunwind/src/x86/siglongjmp.S | 92 + .../src/pal/src/libunwind/src/x86/unwind_i.h | 68 + .../libunwind/src/x86_64/Gapply_reg_state.c | 37 + .../libunwind/src/x86_64/Gcreate_addr_space.c | 61 + .../src/libunwind/src/x86_64/Gget_proc_info.c | 48 + .../src/libunwind/src/x86_64/Gget_save_loc.c | 74 + .../pal/src/libunwind/src/x86_64/Gglobal.c | 109 + .../src/pal/src/libunwind/src/x86_64/Ginit.c | 427 ++ .../src/libunwind/src/x86_64/Ginit_local.c | 81 + .../src/libunwind/src/x86_64/Ginit_remote.c | 57 + .../src/libunwind/src/x86_64/Gos-freebsd.c | 218 + .../pal/src/libunwind/src/x86_64/Gos-linux.c | 156 + .../src/libunwind/src/x86_64/Gos-solaris.c | 133 + .../src/x86_64/Greg_states_iterate.c | 37 + .../src/pal/src/libunwind/src/x86_64/Gregs.c | 138 + .../pal/src/libunwind/src/x86_64/Gresume.c | 123 + .../src/libunwind/src/x86_64/Gstash_frame.c | 119 + .../src/pal/src/libunwind/src/x86_64/Gstep.c | 290 + .../src/pal/src/libunwind/src/x86_64/Gtrace.c | 551 ++ .../libunwind/src/x86_64/Lapply_reg_state.c | 5 + .../libunwind/src/x86_64/Lcreate_addr_space.c | 5 + .../src/libunwind/src/x86_64/Lget_proc_info.c | 5 + .../src/libunwind/src/x86_64/Lget_save_loc.c | 5 + .../pal/src/libunwind/src/x86_64/Lglobal.c | 6 + .../src/pal/src/libunwind/src/x86_64/Linit.c | 5 + .../src/libunwind/src/x86_64/Linit_local.c | 5 + .../src/libunwind/src/x86_64/Linit_remote.c | 5 + .../src/libunwind/src/x86_64/Los-freebsd.c | 5 + .../pal/src/libunwind/src/x86_64/Los-linux.c | 5 + .../src/libunwind/src/x86_64/Los-solaris.c | 5 + .../src/x86_64/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/x86_64/Lregs.c | 5 + .../pal/src/libunwind/src/x86_64/Lresume.c | 5 + .../src/libunwind/src/x86_64/Lstash_frame.c | 5 + .../src/pal/src/libunwind/src/x86_64/Lstep.c | 5 + .../src/pal/src/libunwind/src/x86_64/Ltrace.c | 5 + .../pal/src/libunwind/src/x86_64/getcontext.S | 136 + .../src/pal/src/libunwind/src/x86_64/init.h | 89 + .../pal/src/libunwind/src/x86_64/is_fpreg.c | 38 + .../pal/src/libunwind/src/x86_64/longjmp.S | 34 + .../pal/src/libunwind/src/x86_64/offsets.h | 3 + .../pal/src/libunwind/src/x86_64/regname.c | 56 + .../pal/src/libunwind/src/x86_64/setcontext.S | 87 + .../pal/src/libunwind/src/x86_64/siglongjmp.S | 32 + .../pal/src/libunwind/src/x86_64/ucontext_i.h | 102 + .../pal/src/libunwind/src/x86_64/unwind_i.h | 93 + .../pal/src/libunwind/tests/Gia64-test-nat.c | 626 ++ .../pal/src/libunwind/tests/Gia64-test-rbs.c | 193 + .../src/libunwind/tests/Gia64-test-readonly.c | 89 + .../src/libunwind/tests/Gia64-test-stack.c | 176 + .../pal/src/libunwind/tests/Gperf-simple.c | 264 + .../src/pal/src/libunwind/tests/Gperf-trace.c | 250 + .../src/pal/src/libunwind/tests/Gtest-bt.c | 263 + .../src/libunwind/tests/Gtest-concurrent.c | 136 + .../src/pal/src/libunwind/tests/Gtest-dyn1.c | 223 + .../src/pal/src/libunwind/tests/Gtest-exc.c | 162 + .../pal/src/libunwind/tests/Gtest-init.cxx | 107 + .../pal/src/libunwind/tests/Gtest-nomalloc.c | 110 + .../src/libunwind/tests/Gtest-resume-sig-rt.c | 31 + .../src/libunwind/tests/Gtest-resume-sig.c | 200 + .../src/pal/src/libunwind/tests/Gtest-trace.c | 282 + .../tests/Gx64-test-dwarf-expressions.c | 68 + .../pal/src/libunwind/tests/Lia64-test-nat.c | 5 + .../pal/src/libunwind/tests/Lia64-test-rbs.c | 5 + .../src/libunwind/tests/Lia64-test-readonly.c | 5 + .../src/libunwind/tests/Lia64-test-stack.c | 5 + .../pal/src/libunwind/tests/Lperf-simple.c | 5 + .../src/pal/src/libunwind/tests/Lperf-trace.c | 5 + .../src/pal/src/libunwind/tests/Lrs-race.c | 1514 +++++ .../src/pal/src/libunwind/tests/Ltest-bt.c | 5 + .../src/libunwind/tests/Ltest-concurrent.c | 5 + .../libunwind/tests/Ltest-cxx-exceptions.cxx | 80 + .../src/pal/src/libunwind/tests/Ltest-dyn1.c | 5 + .../src/pal/src/libunwind/tests/Ltest-exc.c | 5 + .../tests/Ltest-init-local-signal-lib.c | 6 + .../libunwind/tests/Ltest-init-local-signal.c | 60 + .../pal/src/libunwind/tests/Ltest-init.cxx | 5 + .../src/libunwind/tests/Ltest-mem-validate.c | 145 + .../pal/src/libunwind/tests/Ltest-nocalloc.c | 137 + .../pal/src/libunwind/tests/Ltest-nomalloc.c | 5 + .../src/libunwind/tests/Ltest-resume-sig-rt.c | 5 + .../src/libunwind/tests/Ltest-resume-sig.c | 5 + .../src/pal/src/libunwind/tests/Ltest-trace.c | 5 + .../pal/src/libunwind/tests/Ltest-varargs.c | 84 + .../tests/Lx64-test-dwarf-expressions.c | 5 + .../src/pal/src/libunwind/tests/Makefile.am | 251 + .../src/libunwind/tests/check-namespace.sh.in | 387 ++ .../src/pal/src/libunwind/tests/crasher.c | 129 + .../src/pal/src/libunwind/tests/flush-cache.S | 104 + .../src/pal/src/libunwind/tests/flush-cache.h | 38 + .../src/pal/src/libunwind/tests/forker.c | 76 + .../pal/src/libunwind/tests/ia64-dyn-asm.S | 102 + .../pal/src/libunwind/tests/ia64-test-dyn1.c | 223 + .../src/libunwind/tests/ia64-test-nat-asm.S | 508 ++ .../src/libunwind/tests/ia64-test-rbs-asm.S | 275 + .../pal/src/libunwind/tests/ia64-test-rbs.h | 3 + .../libunwind/tests/ia64-test-readonly-asm.S | 55 + .../src/libunwind/tests/ia64-test-setjmp.c | 155 + .../pal/src/libunwind/tests/ia64-test-sig.c | 102 + .../src/libunwind/tests/ia64-test-stack-asm.S | 183 + .../pal/src/libunwind/tests/ia64-test-stack.h | 3 + .../src/pal/src/libunwind/tests/ident.c | 5 + .../src/pal/src/libunwind/tests/mapper.c | 78 + .../src/pal/src/libunwind/tests/perf-startup | 19 + .../tests/ppc64-test-altivec-utils.c | 32 + .../src/libunwind/tests/ppc64-test-altivec.c | 177 + .../src/libunwind/tests/run-check-namespace | 3 + .../src/libunwind/tests/run-coredump-unwind | 53 + .../libunwind/tests/run-coredump-unwind-mdi | 8 + .../src/libunwind/tests/run-ia64-test-dyn1 | 2 + .../pal/src/libunwind/tests/run-ptrace-mapper | 2 + .../pal/src/libunwind/tests/run-ptrace-misc | 2 + .../pal/src/libunwind/tests/test-async-sig.c | 193 + .../libunwind/tests/test-coredump-unwind.c | 399 ++ .../src/libunwind/tests/test-flush-cache.c | 143 + .../src/libunwind/tests/test-init-remote.c | 103 + .../src/pal/src/libunwind/tests/test-mem.c | 103 + .../pal/src/libunwind/tests/test-proc-info.c | 171 + .../src/libunwind/tests/test-ptrace-misc.c | 120 + .../src/pal/src/libunwind/tests/test-ptrace.c | 370 ++ .../pal/src/libunwind/tests/test-reg-state.c | 133 + .../src/pal/src/libunwind/tests/test-setjmp.c | 285 + .../libunwind/tests/test-static-link-gen.c | 74 + .../libunwind/tests/test-static-link-loc.c | 102 + .../pal/src/libunwind/tests/test-strerror.c | 18 + .../tests/x64-test-dwarf-expressions.S | 78 + .../tests/x64-unwind-badjmp-signal-frame.c | 124 + 810 files changed, 81798 insertions(+) create mode 100644 src/coreclr/src/pal/src/libunwind/.gitignore create mode 100644 src/coreclr/src/pal/src/libunwind/.travis.yml create mode 100644 src/coreclr/src/pal/src/libunwind/AUTHORS create mode 100644 src/coreclr/src/pal/src/libunwind/COPYING create mode 100644 src/coreclr/src/pal/src/libunwind/ChangeLog create mode 100644 src/coreclr/src/pal/src/libunwind/LICENSE create mode 100644 src/coreclr/src/pal/src/libunwind/Makefile.am create mode 100644 src/coreclr/src/pal/src/libunwind/NEWS create mode 100644 src/coreclr/src/pal/src/libunwind/README create mode 100644 src/coreclr/src/pal/src/libunwind/TODO create mode 100644 src/coreclr/src/pal/src/libunwind/acinclude.m4 create mode 100755 src/coreclr/src/pal/src/libunwind/autogen.sh create mode 100644 src/coreclr/src/pal/src/libunwind/aux_/config.guess create mode 100644 src/coreclr/src/pal/src/libunwind/aux_/config.sub create mode 100644 src/coreclr/src/pal/src/libunwind/aux_/ltmain.sh create mode 100644 src/coreclr/src/pal/src/libunwind/configure.ac create mode 100644 src/coreclr/src/pal/src/libunwind/doc/Makefile.am create mode 100644 src/coreclr/src/pal/src/libunwind/doc/NOTES create mode 100644 src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/common.tex.in create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/libunwind.trans create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_init_local.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_init_local.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_init_local2.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_regname.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_regname.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_resume.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_resume.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_step.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_step.tex create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_strerror.man create mode 100644 src/coreclr/src/pal/src/libunwind/doc/unw_strerror.tex create mode 100644 src/coreclr/src/pal/src/libunwind/include/compiler.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/dwarf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/dwarf_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-arm.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-coredump.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-dynamic.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-hppa.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-ia64.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-ppc32.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-ppc64.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-ptrace.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-sh.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-tilegx.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-x86.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-x86_64.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind.h.in create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/mempool.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/remote.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-arm/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-arm/ex_tables.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-arm/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-hppa/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-hppa/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-hppa/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ia64/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ia64/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ia64/rse.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ia64/script.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-mips/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-sh/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-sh/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-sh/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in create mode 100644 src/coreclr/src/pal/src/libunwind/include/unwind.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/x86/jmpbuf.h create mode 100755 src/coreclr/src/pal/src/libunwind/scripts/kernel-diff.sh create mode 100644 src/coreclr/src/pal/src/libunwind/scripts/kernel-files.txt create mode 100755 src/coreclr/src/pal/src/libunwind/scripts/make-L-files create mode 100644 src/coreclr/src/pal/src/libunwind/src/Makefile.am create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gstash_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Gtrace.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lstash_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/Ltrace.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/gen-offsets.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/getcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/offsets.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/siglongjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gos-freebsd.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gos-linux.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gos-other.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gstash_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Gtrace.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lex_tables.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Los-freebsd.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Los-linux.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Los-other.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lstash_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/Ltrace.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/gen-offsets.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/getcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/offsets.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/siglongjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/arm/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/README create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_mem.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_accessors.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_destroy.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_elf_map_image.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_find_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_internal.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_lib.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_access_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_elf.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_put_unwind_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_resume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/coredump/libunwind-coredump.pc.in create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gfde.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Gpe.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lexpr.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lfde.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_proc_info-lsb.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_unwind_table.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lparser.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/Lpe.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/dwarf/global.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/elf32.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/elf32.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/elf64.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/elf64.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/elfxx.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/elfxx.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/get_accessors.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/getcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/offsets.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/setcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/siglongjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/tables.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/hppa/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gfind_unwind_table.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Ginstall_cursor.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gparser.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Grbs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gscript.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Gtables.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lfind_unwind_table.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Linstall_cursor.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lparser.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lrbs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lscript.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/Ltables.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/NOTES create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/dyn_info_list.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/getcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/longjmp.S create mode 100755 src/coreclr/src/pal/src/libunwind/src/ia64/mk_cursor_i create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/offsets.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/regs.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/setjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/siglongjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/sigsetjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/ucontext_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/unwind_decoder.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ia64/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/libunwind-generic.pc.in create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gdestroy_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-extract.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gget_accessors.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gget_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_info_by_ip.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gget_reg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gput_dynamic_unwind_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gset_cache_size.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gset_caching_policy.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gset_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Gset_reg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Ldestroy_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-extract.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lfind_dynamic_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lget_accessors.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lget_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_info_by_ip.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_name.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lget_reg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lput_dynamic_unwind_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lset_cache_size.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lset_caching_policy.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lset_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/Lset_reg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/_ReadSLEB.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/_ReadULEB.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/dyn-cancel.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/dyn-info-list.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/dyn-register.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/init.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/mempool.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mi/strerror.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/elfxx.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/gen-offsets.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/getcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/offsets.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/siglongjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/mips/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/os-freebsd.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/os-hpux.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/os-linux.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/os-linux.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/os-qnx.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/os-solaris.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Gis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Lis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/longjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc/siglongjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/Make-arch.in create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/get_func_addr.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/setcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/ucontext_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc32/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/get_func_addr.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/setcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/ucontext_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ppc64/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_mem.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_reg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_accessors.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_create.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_destroy.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_elf.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_find_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_proc_name.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_internal.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_put_unwind_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_resume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/ptrace/libunwind-ptrace.pc.in create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/libunwind-setjmp.pc.in create mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/longjmp.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/setjmp/sigsetjmp.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/gen-offsets.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/offsets.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/siglongjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/sh/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/elfxx.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/gen-offsets.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/getcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/offsets.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/siglongjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/tilegx/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/Backtrace.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/DeleteException.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/FindEnclosingFunction.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/ForcedUnwind.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetBSP.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetCFA.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetDataRelBase.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetGR.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetIP.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetIPInfo.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetLanguageSpecificData.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetRegionStart.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/GetTextRelBase.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/RaiseException.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/Resume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/Resume_or_Rethrow.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/SetGR.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/SetIP.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in create mode 100644 src/coreclr/src/pal/src/libunwind/src/unwind/unwind-internal.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gos-freebsd.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gos-linux.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Los-freebsd.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Los-linux.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/getcontext-freebsd.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/getcontext-linux.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/longjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/offsets.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/siglongjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-freebsd.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-linux.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Los-freebsd.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Los-linux.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lstash_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Ltrace.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/longjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/offsets.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/siglongjmp.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gia64-test-nat.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gia64-test-rbs.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gia64-test-readonly.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gia64-test-stack.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gperf-simple.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gperf-trace.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-concurrent.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-dyn1.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-exc.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-init.cxx create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-nomalloc.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig-rt.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lia64-test-nat.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lia64-test-rbs.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lia64-test-readonly.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lia64-test-stack.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lperf-simple.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lperf-trace.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lrs-race.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-bt.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-concurrent.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-cxx-exceptions.cxx create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-dyn1.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-exc.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal-lib.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-init.cxx create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-nocalloc.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-nomalloc.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig-rt.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-trace.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Ltest-varargs.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Makefile.am create mode 100644 src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in create mode 100644 src/coreclr/src/pal/src/libunwind/tests/crasher.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/flush-cache.S create mode 100644 src/coreclr/src/pal/src/libunwind/tests/flush-cache.h create mode 100644 src/coreclr/src/pal/src/libunwind/tests/forker.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-dyn-asm.S create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-dyn1.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-nat-asm.S create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs-asm.S create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs.h create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-readonly-asm.S create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-setjmp.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-sig.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack-asm.S create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack.h create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ident.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/mapper.c create mode 100755 src/coreclr/src/pal/src/libunwind/tests/perf-startup create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec-utils.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec.c create mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-check-namespace create mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind create mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind-mdi create mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-ia64-test-dyn1 create mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-ptrace-mapper create mode 100755 src/coreclr/src/pal/src/libunwind/tests/run-ptrace-misc create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-async-sig.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-flush-cache.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-init-remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-mem.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-proc-info.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-ptrace-misc.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-ptrace.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-reg-state.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-setjmp.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-static-link-gen.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-static-link-loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/test-strerror.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S create mode 100644 src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c diff --git a/src/coreclr/src/pal/src/libunwind/.gitignore b/src/coreclr/src/pal/src/libunwind/.gitignore new file mode 100644 index 00000000000000..724a1f4882e2cc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/.gitignore @@ -0,0 +1,81 @@ +*.la +*.a +*.o +*.lo +*~ +*.pc + +.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 +include/libunwind.h +include/tdep/libunwind_i.h + +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/Lrs-race +tests/Ltest-varargs +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-reg-state +tests/test-varargs +tests/test-static-link +tests/[GL]test-trace +tests/[GL]perf-trace +tests/Ltest-cxx-exceptions +tests/Ltest-init-local-signal +tests/Ltest-mem-validate +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 +tests/[GL]x64-test-dwarf-expressions +tests/x64-unwind-badjmp-signal-frame +tests/*.log +tests/*.trs diff --git a/src/coreclr/src/pal/src/libunwind/.travis.yml b/src/coreclr/src/pal/src/libunwind/.travis.yml new file mode 100644 index 00000000000000..7bf0f8d0638efa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/.travis.yml @@ -0,0 +1,34 @@ +sudo: required +language: c +compiler: gcc +env: +- TARGET=x86_64-linux-gnu +- TARGET=x86-linux-gnu +- TARGET=arm-linux-gnueabihf +- TARGET=aarch64-linux-gnu +- TARGET=mipsel-unknown-linux-gnu +# Currently experiencing build failures here +#- TARGET=powerpc64-linux-gnu + +linux-s390x: &linux-s390x + os: linux + arch: s390x + env: TARGET=s390x-linux-gnu + script: + - ./autogen.sh + - ./configure + - make -j32 + - ulimit -c unlimited + - make check -j32 + +script: +- ./autogen.sh +- ./configure --target=$TARGET --host=$HOST +- make -j32 +- sudo bash -c 'echo core.%p.%p > /proc/sys/kernel/core_pattern' +- ulimit -c unlimited +- if [ $TARGET == 'x86_64-linux-gnu' ]; then make check -j32; fi + +jobs: + include: + - <<: *linux-s390x diff --git a/src/coreclr/src/pal/src/libunwind/AUTHORS b/src/coreclr/src/pal/src/libunwind/AUTHORS new file mode 100644 index 00000000000000..719eee5c85a2f7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/AUTHORS @@ -0,0 +1 @@ +David Mosberger diff --git a/src/coreclr/src/pal/src/libunwind/COPYING b/src/coreclr/src/pal/src/libunwind/COPYING new file mode 100644 index 00000000000000..41e7d8a6fdb536 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/COPYING @@ -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. diff --git a/src/coreclr/src/pal/src/libunwind/ChangeLog b/src/coreclr/src/pal/src/libunwind/ChangeLog new file mode 100644 index 00000000000000..dfa24b957cb223 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/ChangeLog @@ -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 + + * 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 + + * 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 + + * include/unwind-ia64.h: Include via "unwind.h" to ensure + the file is picked up from same directory. + +2002-01-16 David Mosberger-Tang + + * 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 + + * Version 0.0 released. + +2002-01-11 David Mosberger-Tang + + * ChangeLog created. diff --git a/src/coreclr/src/pal/src/libunwind/LICENSE b/src/coreclr/src/pal/src/libunwind/LICENSE new file mode 100644 index 00000000000000..c9b44cb8aaebb1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/LICENSE @@ -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. diff --git a/src/coreclr/src/pal/src/libunwind/Makefile.am b/src/coreclr/src/pal/src/libunwind/Makefile.am new file mode 100644 index 00000000000000..8132fa4cb952aa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/Makefile.am @@ -0,0 +1,111 @@ +include_HEADERS = include/libunwind-dynamic.h + +if BUILD_PTRACE +include_HEADERS += include/libunwind-ptrace.h +endif BUILD_PTRACE + +if BUILD_COREDUMP +include_HEADERS += include/libunwind-coredump.h +endif BUILD_COREDUMP + +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_TILEGX +include_HEADERS += include/libunwind-tilegx.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 ARCH_S390X +include_HEADERS += include/libunwind-s390x.h +endif + +if !REMOTE_ONLY +include_HEADERS += include/libunwind.h include/unwind.h +endif + +nodist_include_HEADERS = include/libunwind-common.h + +SUBDIRS = src + +if CONFIG_TESTS +SUBDIRS += tests +endif + +if CONFIG_DOCS +SUBDIRS += doc +endif + +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-tilegx/libunwind_i.h \ + include/tdep-tilegx/jmpbuf.h include/tdep-tilegx/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-s390x/dwarf-config.h \ + include/tdep-s390x/jmpbuf.h include/tdep-s390x/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~ + diff --git a/src/coreclr/src/pal/src/libunwind/NEWS b/src/coreclr/src/pal/src/libunwind/NEWS new file mode 100644 index 00000000000000..ae6cbcfb0b57d5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/NEWS @@ -0,0 +1,247 @@ +-*-Mode: outline-*- + +* News for v1.3: + +** Iteration of unwind register states support + Doug Moore +** Freebsd/Armv6 support + Konstantin Belousov +** Many, many dwarf bugfixes +** Mips remote unwind support +** aarch64 ptrace support + +* News for v1.2: + +** aarch64 port +** dwarf parsing improvements +** Fast stacktraces for aarch64 & arm +** tilegx port +** powerpc64 port + +* 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 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 + 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. diff --git a/src/coreclr/src/pal/src/libunwind/README b/src/coreclr/src/pal/src/libunwind/README new file mode 100644 index 00000000000000..b6d93ae4a68551 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/README @@ -0,0 +1,239 @@ +# libunwind + +[![Build Status](https://travis-ci.org/libunwind/libunwind.svg?branch=master)](https://travis-ci.org/libunwind/libunwind) + +This is version 1.5 of the unwind library. This library supports +several architecture/operating-system combinations: + +| System | Architecture | Status | +| :------ | :----------- | :----- | +| Linux | x86-64 | ✓ | +| Linux | x86 | ✓ | +| Linux | ARM | ✓ | +| Linux | AArch64 | ✓ | +| Linux | PPC64 | ✓ | +| Linux | SuperH | ✓ | +| Linux | IA-64 | ✓ | +| Linux | PARISC | Works well, but C library missing unwind-info | +| Linux | Tilegx | 64-bit mode only | +| Linux | MIPS | Newly added | +| HP-UX | IA-64 | Mostly works, but known to have serious limitations | +| FreeBSD | x86-64 | ✓ | +| FreeBSD | x86 | ✓ | +| FreeBSD | AArch64 | ✓ | +| Solaris | x86-64 | ✓ | + +## Libc Requirements + +libunwind depends on getcontext(), setcontext() functions which are missing +from C libraries like musl-libc because they are considered to be "obsolescent" +API by POSIX document. The following table tries to track current status of +such dependencies + + - r, requires + - p, provides its own implementation + - empty, no requirement + +| Archtecture | getcontext | setcontext | +|--------------|------------|------------| +| aarch64 | p | | +| arm | p | | +| hppa | p | p | +| ia64 | p | r | +| mips | p | | +| ppc32 | r | | +| ppc64 | r | r | +| s390x | p | p | +| sh | r | | +| tilegx | r | r | +| x86 | p | r | +| x86_64 | p | p | + +## General Build Instructions + +In general, this library can be built and installed with the following +commands: + + $ ./autogen.sh # 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 +on older versions of FreeBSD, you need libexecinfo library available in +ports as devel/libexecinfo. This port has been removed as of 2017 and is +indeed no longer needed. + +## 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: + +* `test-ptrace` + +### Expected results on x86-64 Linux + +The following tests are expected to fail on x86-64 Linux: + +* `run-ptrace-misc` (see + and ) + +### 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. + +### Expected results on Solaris x86-64 + +`make check` is passing 27 out of 33 tests. The following six tests are consistently +failing: + +* `Gtest-concurrent` +* `Ltest-concurrent` +* `Ltest-init-local-signal` +* `Lrs-race` +* `test-setjmp` +* `x64-unwind-badjmp-signal-frame` + +## 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 . + +You can do this by sending an email to with +a body of "subscribe libunwind-devel", or you can subscribe and manage your +subscription via the web-interface at . + +You can also interact on our GitHub page: . diff --git a/src/coreclr/src/pal/src/libunwind/TODO b/src/coreclr/src/pal/src/libunwind/TODO new file mode 100644 index 00000000000000..8b2e0262b00103 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/TODO @@ -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 , 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 diff --git a/src/coreclr/src/pal/src/libunwind/acinclude.m4 b/src/coreclr/src/pal/src/libunwind/acinclude.m4 new file mode 100644 index 00000000000000..497f7c2f215253 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/acinclude.m4 @@ -0,0 +1,32 @@ +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) +]) diff --git a/src/coreclr/src/pal/src/libunwind/autogen.sh b/src/coreclr/src/pal/src/libunwind/autogen.sh new file mode 100755 index 00000000000000..b08bc831f6447f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/autogen.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +test -n "$srcdir" || srcdir=`dirname "$0"` +test -n "$srcdir" || srcdir=. +( + cd "$srcdir" && + autoreconf --force -v --install +) || exit +test -n "$NOCONFIGURE" || "$srcdir/configure" "$@" diff --git a/src/coreclr/src/pal/src/libunwind/aux_/config.guess b/src/coreclr/src/pal/src/libunwind/aux_/config.guess new file mode 100644 index 00000000000000..ed2e03b7f2b96b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/aux_/config.guess @@ -0,0 +1,1321 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-20' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c ; + for c in cc gcc c89 c99 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $dummy.c $dummy.o $dummy.rel ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/coreclr/src/pal/src/libunwind/aux_/config.sub b/src/coreclr/src/pal/src/libunwind/aux_/config.sub new file mode 100644 index 00000000000000..f3657978c7401e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/aux_/config.sub @@ -0,0 +1,1443 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-07' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dsp16xx \ + | fr30 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el | mips64vr4300 \ + | mips64vr4300el | mips64vr5000 | mips64vr5000el \ + | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ + | mipsisa32 | mipsisa64 \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ + | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ + | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/coreclr/src/pal/src/libunwind/aux_/ltmain.sh b/src/coreclr/src/pal/src/libunwind/aux_/ltmain.sh new file mode 100644 index 00000000000000..6fc690018edbbb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/aux_/ltmain.sh @@ -0,0 +1,5107 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + exit 0 + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 + exit 0 + ;; + + --debug) + echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case $nonopt in + *cc | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + prev= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + case $prev in + "") ;; + xcompiler) + # Aesthetically quote the previous argument. + prev= + lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + + case $arg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + # Accept any command-line options. + case $arg in + -o) + if test "$user_target" != "no"; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + user_target=next + ;; + + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + case $user_target in + next) + # The next one is the -o target name + user_target=yes + continue + ;; + yes) + # We got the output file + user_target=set + libobj="$arg" + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $lastarg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + case $user_target in + set) + ;; + no) + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + *) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSfmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $libobj" + else + removelist="$libobj" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + else + # Don't build PIC code + command="$base_compile $srcfile" + fi + if test "$build_old_libs" = yes; then + lo_libobj="$libobj" + dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$libobj"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + + if test -d "$dir"; then + $show "$rm $libobj" + $run $rm $libobj + else + $show "$mkdir $dir" + $run $mkdir $dir + status=$? + if test $status -ne 0 && test ! -d $dir; then + exit $status + fi + fi + fi + if test "$compiler_o_lo" = yes; then + output_obj="$libobj" + command="$command -o $output_obj" + elif test "$compiler_c_o" = yes; then + output_obj="$obj" + command="$command -o $output_obj" + fi + + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test x"$output_obj" != x"$libobj"; then + $show "$mv $output_obj $libobj" + if $run $mv $output_obj $libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # If we have no pic_flag, then copy the object into place and finish. + if (test -z "$pic_flag" || test "$pic_mode" != default) && + test "$build_old_libs" = yes; then + # Rename the .lo from within objdir to obj + if test -f $obj; then + $show $rm $obj + $run $rm $obj + fi + + $show "$mv $libobj $obj" + if $run $mv $libobj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` + libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + # Now arrange that obj and lo_libobj become the same file + $show "(cd $xdir && $LN_S $baseobj $libobj)" + if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + exit 0 + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $srcfile" + else + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + output_obj="$obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test x"$output_obj" != x"$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + else + # Move the .lo from within objdir + $show "$mv $libobj $lo_libobj" + if $run $mv $libobj $lo_libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + fi + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + + exit 0 + ;; + + # libtool link mode + link | relink) + modename="$modename: link" + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invokation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args="$nonopt" + compile_command="$nonopt" + finalize_command="$nonopt" + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -all-static | -static) + if test "X$arg" = "X-all-static"; then + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test $# -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n $prev + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | no/*-*-nonstopux*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.lo | *.$objext) + # A library or standard object. + if test "$prev" = dlfiles; then + # This file was specified with -dlopen. + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $arg" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` + prev= + else + case $arg in + *.lo) libobjs="$libobjs $arg" ;; + *) objs="$objs $arg" ;; + esac + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit 1 + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test $linkmode = prog; then + # Determine which files to process + case $pass in + dlopen) + libs="$dlfiles" + save_deplibs="$deplibs" # Collect dlpreopened libraries + deplibs= + ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -l*) + if test $linkmode = oldlib && test $linkmode = obj; then + $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 + continue + fi + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + # Search the libtool library + lib="$searchdir/lib${name}.la" + if test -f "$lib"; then + found=yes + break + fi + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test $pass = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test $pass = scan; then + deplibs="$deplib $deplibs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test $pass = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + if test "$deplibs_check_method" != pass_all; then + echo + echo "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not used here." + else + echo + echo "*** Warning: Linking the shared library $output against the" + echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test $pass != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test $found = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit 1 + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test $linkmode = oldlib && test $linkmode = obj; }; then + # Add dl[pre]opened files of deplib + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test $pass = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test $linkmode != prog && test $linkmode != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit 1 + fi + continue + fi # $pass = conv + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + + # This library was specified with -dlopen. + if test $pass = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. + dlprefiles="$dlprefiles $lib" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test $pass = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test $linkmode = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" + fi + continue + fi + + if test $linkmode = prog && test $pass != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test $linkalldeplibs = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # Link against this shared library + + if test "$linkmode,$pass" = "prog,link" || + { test $linkmode = lib && test $hardcode_into_libs = yes; }; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + if test $linkmode = prog; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + fi + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$extract_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$old_archive_from_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n $old_archive_from_expsyms_cmds + + if test $linkmode = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\/]*) + add_dir="-L$inst_prefix_dir$libdir $add_dir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test $linkmode = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test $linkmode = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\/]*) + add_dir="-L$inst_prefix_dir$libdir $add_dir" + ;; + esac + fi + add="-l$name" + fi + + if test $linkmode = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test $linkmode = prog; then + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + # Try to link the static library + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + echo "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test $linkmode = lib; then + if test -n "$dependency_libs" && + { test $hardcode_into_libs != yes || test $build_old_libs = yes || + test $link_static = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test $link_all_deplibs != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="-L$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="-L$absdir" + fi + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test $pass = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test $pass != dlopen; then + test $pass != scan && dependency_libs="$newdependency_libs" + if test $pass != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + *) + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + if test "$pass" = "conv" && + { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then + libs="$deplibs" # reset libs + deplibs= + fi + done # for pass + if test $linkmode = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit 1 + else + echo + echo "*** Warning: Linking the shared library $output against the non-libtool" + echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + libext=al + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + current="$2" + revision="$3" + age="$4" + + # Check that each of the things are valid numbers. + case $current in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $revision in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $age in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test $loop != 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + verstring="0.0" + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring="" + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs. + $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" + $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test $hardcode_into_libs != yes || test $build_old_libs = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test $build_libtool_need_lc = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behaviour. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | egrep "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for file magic test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check below in file_magic test + if eval echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | egrep "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | + grep . >/dev/null; then + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + echo "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test $allow_undefined = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test $hardcode_into_libs = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + test -z "$dlname" && dlname=$soname + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Ensure that we have .o objects for linkers which dislike .lo + # (e.g. aix) in case we are running --disable-static + for obj in $libobjs; do + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + if test ! -f $xdir/$oldobj; then + $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" + $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? + fi + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + save_deplibs="$deplibs" + for conv in $convenience; do + tmp_deplibs= + for test_deplib in $deplibs; do + if test "$test_deplib" != "$conv"; then + tmp_deplibs="$tmp_deplibs $test_deplib" + fi + done + deplibs="$tmp_deplibs" + done + eval cmds=\"$archive_cmds\" + deplibs="$save_deplibs" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit 0 + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show $rm $libobj + $run $rm $libobj + xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$libobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + $show "(cd $xdir && $LN_S $oldobj $baseobj)" + $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + prog) + case $host in + *cygwin*) output=`echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval 'echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test $need_relink = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit 0 + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case $0 in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) exeext=.exe ;; + *) exeext= ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 ${SED} + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # win32 systems need to use the prog path for dll + # lookup to work + *-*-cygwin* | *-*-pw32*) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + # Ensure that we have .o objects in place in case we decided + # not to build a shared library, and have fallen back to building + # static libs even though --disable-static was passed! + for oldobj in $oldobjs; do + if test ! -f $oldobj; then + xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$oldobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` + obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + $show "(cd $xdir && ${LN_S} $obj $baseobj)" + $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? + fi + done + + eval cmds=\"$old_archive_cmds\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test $need_relink = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | sed "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit 1 + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%%"` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit 1 + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test $# -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + /usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $0 --finish$current_libdirs' + else + exit 0 + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = ":" && exit 0 + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved enviroment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + rmdirs= + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$objdir" + else + objdir="$dir/$objdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test $mode = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test $mode = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test $mode = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` + rmfiles="$rmfiles $dir/$oldobj" + fi + ;; + + *) + # Do a test to see if this is a libtool program. + if test $mode = clean && + (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$file + + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit 1 +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/src/coreclr/src/pal/src/libunwind/configure.ac b/src/coreclr/src/pal/src/libunwind/configure.ac new file mode 100644 index 00000000000000..226a10fb35047a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/configure.ac @@ -0,0 +1,481 @@ +define(pkg_major, 1) +define(pkg_minor, 5) +define(pkg_extra, -rc1) +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 +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +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 + +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 ]) +AC_CHECK_TYPES([struct elf_prstatus, struct prstatus], [], [], +[$ac_includes_default +#if HAVE_SYS_PROCFS_H +# include +#endif +]) + +AC_CHECK_DECLS([PTRACE_POKEUSER, PTRACE_POKEDATA, PTRACE_SETREGSET, +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 +#endif +#include +]) + +dnl Checks for library functions. +AC_CHECK_FUNCS(dl_iterate_phdr dl_phdr_removals_counter dlmodinfo getunwind \ + ttrace mincore pipe2) + +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], + [aarch64*],[$2=aarch64], + [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], + [tile*],[$2=tilegx], + [$2=$1]) +]) dnl SET_ARCH + +SET_ARCH([$build_cpu],[build_arch]) +SET_ARCH([$host_cpu],[host_arch]) +SET_ARCH([$target_cpu],[target_arch]) + +# Check for Android +AC_MSG_CHECKING([for Android]) +android="no" +case "$host_os" in + *android*) + android="yes" + AC_MSG_RESULT([yes]) + ;; + *) + AC_MSG_RESULT([no]) + ;; +esac + +AC_ARG_ENABLE(coredump, + AS_HELP_STRING([--enable-coredump],[building libunwind-coredump library]),, + [AS_CASE([$host_arch], [aarch64*|arm*|mips*|sh*|x86*|tile*], [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_ARG_ENABLE(documentation, + AS_HELP_STRING([--disable-documentation],[Disable generating the man pages]),, + [enable_documentation=yes]) + +AC_ARG_ENABLE(tests, + AS_HELP_STRING([--disable-tests],[Disable tests build]),, + [enable_tests=yes]) + +AC_ARG_ENABLE(weak-backtrace, + AS_HELP_STRING([--disable-weak-backtrace],[Do not provide the weak 'backtrace' symbol.]),, + [enable_weak_backtrace=yes]) + +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(NO_PTRACE_TEST, test x$build_arch != x$host_arch) +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(ARCH_TILEGX, test x$target_arch = xtilegx) +AM_CONDITIONAL(ARCH_S390X, test x$target_arch = xs390x) +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) +AM_CONDITIONAL(OS_SOLARIS, expr x$target_os : xsolaris >/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|s390x|tilegx) 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;; + tile*) 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;; + (aarch64) 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) + +LIBZ= +AC_MSG_CHECKING([whether to support ZLIB-compressed symbol tables]) +AC_ARG_ENABLE(zlibdebuginfo, +AS_HELP_STRING([--enable-zlibdebuginfo], [Enables support for ZLIB-compressed symbol tables]),, [enable_zlibdebuginfo=auto]) +AC_MSG_RESULT([$enable_zlibdebuginfo]) +if test x$enable_zlibdebuginfo != xno; then + AC_CHECK_LIB([z], [uncompress], + [LIBZ=-lz + AC_DEFINE([HAVE_ZLIB], [1], [Define if you have libz]) + enable_zlibdebuginfo=yes], + [if test x$enable_zlibdebuginfo = xyes; then + AC_MSG_FAILURE([libz not found]) + fi]) +fi +AC_SUBST([LIBZ]) +AM_CONDITIONAL(HAVE_ZLIB, test x$enable_zlibdebuginfo = xyes) + +AC_MSG_CHECKING([whether to support UNW_CACHE_PER_THREAD]) +AC_ARG_ENABLE([per-thread-cache], +AS_HELP_STRING([--enable-per-thread-cache], [build with support for UNW_CACHE_PER_THREAD (which imposes a hight TLS memory usage) (default: disabled)])) +AC_MSG_RESULT([$enable_per_thread_cache]) +AS_IF([test x$enable_per_thread_cache = xyes], [ + LIBUNWIND___THREAD + AS_IF([test x$libc_cv_gcc___thread = xno], [ + AC_MSG_FAILURE([UNW_CACHE_PER_THREAD requires __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([if building on Solaris then define __EXTENSIONS__ macro]) +if $OS_SOLARIS; then + CFLAGS="${CFLAGS} -D__EXTENSIONS__" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +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 -a x$android != xyes; then + LIBCRTS="-lgcc_s" +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" +case "$ac_cv_search_backtrace" in + -l*) BACKTRACELIB=$ac_cv_search_backtrace;; + *) BACKTRACELIB="";; +esac + + +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_SUBST(BACKTRACELIB) + +AC_PATH_PROG([LATEX2MAN],[latex2man]) +if test "x$LATEX2MAN" = "x"; then + AC_MSG_WARN([latex2man not found. Install latex2man. Disabling docs.]) + enable_documentation="no"; +fi + +AM_CONDITIONAL([CONFIG_DOCS], [test x$enable_documentation = xyes]) +if test "x$enable_documentation" = "xyes"; then + AC_CONFIG_FILES(doc/Makefile doc/common.tex) +fi + +AM_CONDITIONAL([CONFIG_TESTS], [test x$enable_tests = xyes]) +if test "x$enable_tests" = "xyes"; then + AC_CONFIG_FILES(tests/Makefile tests/check-namespace.sh) +fi + +AM_CONDITIONAL([CONFIG_WEAK_BACKTRACE], [test "x$enable_weak_backtrace" = xyes]) +AM_COND_IF([CONFIG_WEAK_BACKTRACE], [ + AC_DEFINE([CONFIG_WEAK_BACKTRACE], [1], [Define if the weak 'backtrace' symbol is provided.]) +]) + +AC_CONFIG_FILES(Makefile src/Makefile + 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 diff --git a/src/coreclr/src/pal/src/libunwind/doc/Makefile.am b/src/coreclr/src/pal/src/libunwind/doc/Makefile.am new file mode 100644 index 00000000000000..bfe46691245e1f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/Makefile.am @@ -0,0 +1,80 @@ +# man pages that go into section 3: +man3_MANS = libunwind.man libunwind-dynamic.man libunwind-ia64.man \ + libunwind-ptrace.man libunwind-setjmp.man \ + unw_apply_reg_state.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_init_local2.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_reg_states_iterate.man \ + unw_set_caching_policy.man \ + unw_set_cache_size.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_apply_reg_state.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_reg_states_iterate.tex \ + unw_set_cache_size.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 diff --git a/src/coreclr/src/pal/src/libunwind/doc/NOTES b/src/coreclr/src/pal/src/libunwind/doc/NOTES new file mode 100644 index 00000000000000..3f3caa95bb5d6a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/NOTES @@ -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 . For example, to get the IA-64-specific register +names, an application would do: + + #include + +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 , 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 , 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 + and bar.c might include 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 + diff --git a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.man b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.man new file mode 100644 index 00000000000000..a420a6deaf3e09 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.tex b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.tex new file mode 100644 index 00000000000000..ca5a12a76eede5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_cancel.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.man b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.man new file mode 100644 index 00000000000000..107e5fd0e18d8c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.tex b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.tex new file mode 100644 index 00000000000000..ab23b5c6213634 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/_U_dyn_register.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/common.tex.in b/src/coreclr/src/pal/src/libunwind/doc/common.tex.in new file mode 100644 index 00000000000000..91c96a9df48d60 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/common.tex.in @@ -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 diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.man b/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.man new file mode 100644 index 00000000000000..7c7507cb1089da --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.man @@ -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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.tex b/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.tex new file mode 100644 index 00000000000000..21e895a34f30ca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind-dynamic.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.man b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.man new file mode 100644 index 00000000000000..06b141eb3e2b70 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.man @@ -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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.tex b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.tex new file mode 100644 index 00000000000000..c08946dc4b327d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ia64.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.man b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.man new file mode 100644 index 00000000000000..985fcae275333c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.tex b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.tex new file mode 100644 index 00000000000000..fe074d8619174a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind-ptrace.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.man b/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.man new file mode 100644 index 00000000000000..1faa38e475ddba --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.tex b/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.tex new file mode 100644 index 00000000000000..17ce073186a6c3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind-setjmp.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind.man b/src/coreclr/src/pal/src/libunwind/doc/libunwind.man new file mode 100644 index 00000000000000..02ab6b89374818 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind.man @@ -0,0 +1,508 @@ +'\" t +.\" Manual page created with latex2man on Thu Jan 12 06:50:29 PST 2017 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "LIBUNWIND" "3" "12 January 2017" "Programming Library " "Programming Library " +.SH NAME +libunwind +\-\- a (mostly) platform\-independent unwind API +.PP +.SH SYNOPSIS + +.PP +#include +.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 +int +unw_set_cache_size(unw_addr_space_t, +size_t, +int); +.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 +\&. +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 + +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 +and uses the linker switch +\fB\-l\fPunwind\&. +For cross\-platform unwinding, a program +includes +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. The cache size can be dynamically changed with +unw_set_cache_size(), +which also fluches the current cache. +.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_cache_size(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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind.tex b/src/coreclr/src/pal/src/libunwind/doc/libunwind.tex new file mode 100644 index 00000000000000..6cbb4766336dd1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind.tex @@ -0,0 +1,359 @@ +\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{int} \Func{unw\_set\_cache\_size}(\Type{unw\_addr\_space\_t}, \Type{size\_t}, \Type{int});\\ + +\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 + +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. The cache size can be dynamically changed with +\Func{unw\_set\_cache\_size}(), which also fluches the current cache. + + +\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\_cache\_size(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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/libunwind.trans b/src/coreclr/src/pal/src/libunwind/doc/libunwind.trans new file mode 100644 index 00000000000000..a514e5a081d73f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/libunwind.trans @@ -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'} = "$htmlMacro1a{File}"; + $htmlMacro2c{'SeeAlso'} = "$htmlMacro1b{File}"; +$texiMacro1a{'SeeAlso'} = $texiMacro1a{File}; + $texiMacro1b{'SeeAlso'} = $texiMacro1b{File}; + diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.man b/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.man new file mode 100644 index 00000000000000..457f0c4dd17a47 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.man @@ -0,0 +1,90 @@ +'\" t +.\" Manual page created with latex2man on Wed Aug 16 11:09:44 PDT 2017 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "UNW\\_APPLY\\_REG\\_STATE" "3" "16 August 2017" "Programming Library " "Programming Library " +.SH NAME +unw_apply_reg_state +\-\- apply a register state update to a cursor +.PP +.SH SYNOPSIS + +.PP +#include +.br +.PP +int +unw_apply_reg_state(unw_cursor_t *cp, +void *reg_states_data); +.br +.PP +.SH DESCRIPTION + +.PP +The unw_apply_reg_state() +routine updates the register values +of a cursor according to the instructions in reg_states_data, +which have been obtained by calling unw_reg_states_iterate\&. +.PP +.SH RETURN VALUE + +.PP +On successful completion, unw_apply_reg_state() +returns 0. +Otherwise the negative value of one of the error\-codes below is +returned. +.PP +.SH THREAD AND SIGNAL SAFETY + +.PP +unw_apply_reg_state() +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_apply_reg_state() +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_reg_states_iterate(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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.tex new file mode 100644 index 00000000000000..c67cc3ebfafdeb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_apply_reg_state.tex @@ -0,0 +1,63 @@ +\documentclass{article} +\usepackage[fancyhdr,pdf]{latex2man} + +\input{common.tex} + +\begin{document} + +\begin{Name}{3}{unw\_apply\_reg\_state}{David Mosberger-Tang}{Programming Library}{unw\_apply\_reg\_state}unw\_apply\_reg\_state -- apply a register state update to a cursor +\end{Name} + +\section{Synopsis} + +\File{\#include $<$libunwind.h$>$}\\ + +\Type{int} +\Func{unw\_apply\_reg\_state}(\Type{unw\_cursor\_t~*}\Var{cp}, +\Type{void~*}\Var{reg\_states\_data});\\ + +\section{Description} + +The \Func{unw\_apply\_reg\_state}() routine updates the register values +of a cursor according to the instructions in \Var{reg\_states\_data}, +which have been obtained by calling \Var{unw\_reg\_states\_iterate}. + +\section{Return Value} + +On successful completion, \Func{unw\_apply\_reg\_state}() returns 0. +Otherwise the negative value of one of the error-codes below is +returned. + +\section{Thread and Signal Safety} + +\Func{unw\_apply\_reg\_state}() 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\_apply\_reg\_state}() 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\_reg\_states\_iterate(3)} + +\section{Author} + +\noindent +David Mosberger-Tang\\ +Email: \Email{dmosberger@gmail.com}\\ +WWW: \URL{http://www.nongnu.org/libunwind/}. +\LatexManEnd + +\end{document} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.man b/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.man new file mode 100644 index 00000000000000..5699bbfe2881d2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.man @@ -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 +.br +.PP +int +unw_backtrace(void **buffer, +int size); +.br +.PP +#include +.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 +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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.tex new file mode 100644 index 00000000000000..c383eeb37a166f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_backtrace.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.man b/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.man new file mode 100644 index 00000000000000..4aca13ecd8297e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.man @@ -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 +.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 +\&. +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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.tex new file mode 100644 index 00000000000000..8de0691f3a9206 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_create_addr_space.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.man b/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.man new file mode 100644 index 00000000000000..90c9777efbadd9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.tex new file mode 100644 index 00000000000000..a66b10b4b0bb4e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_destroy_addr_space.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.man b/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.man new file mode 100644 index 00000000000000..627449effe2ad9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.man @@ -0,0 +1,93 @@ +'\" t +.\" Manual page created with latex2man on Fri Dec 2 16:09:33 PST 2016 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "UNW\\_FLUSH\\_CACHE" "3" "02 December 2016" "Programming Library " "Programming Library " +.SH NAME +unw_flush_cache +\-\- flush cached info +.PP +.SH SYNOPSIS + +.PP +#include +.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) +unw_set_cache_size(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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.tex new file mode 100644 index 00000000000000..32319db5d15872 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_flush_cache.tex @@ -0,0 +1,58 @@ +\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)} +\SeeAlso{unw\_set\_cache\_size(3)} + +\section{Author} + +\noindent +David Mosberger-Tang\\ +Email: \Email{dmosberger@gmail.com}\\ +WWW: \URL{http://www.nongnu.org/libunwind/}. +\LatexManEnd + +\end{document} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.man new file mode 100644 index 00000000000000..83fe4fcea6d673 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.tex new file mode 100644 index 00000000000000..bf344a32de2e61 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_accessors.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.man new file mode 100644 index 00000000000000..5e54ca13d3bb52 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.tex new file mode 100644 index 00000000000000..dd679adc06ab75 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_fpreg.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.man new file mode 100644 index 00000000000000..09eadee27ad1a1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.tex new file mode 100644 index 00000000000000..72621f1a6510f7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.man new file mode 100644 index 00000000000000..a347a1d0089119 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.tex new file mode 100644 index 00000000000000..5e1d5d247ebf29 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_info_by_ip.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.man new file mode 100644 index 00000000000000..8b2bd06eaf084a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.tex new file mode 100644 index 00000000000000..c413990880dcd6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_proc_name.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.man b/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.man new file mode 100644 index 00000000000000..83e8bb43b64f4b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.tex new file mode 100644 index 00000000000000..b66e8c0dbb4265 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_get_reg.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.man b/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.man new file mode 100644 index 00000000000000..13725df9570cfa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.tex new file mode 100644 index 00000000000000..fa3eb814b3f650 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_getcontext.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.man b/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.man new file mode 100644 index 00000000000000..301dd6f93bdf00 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.man @@ -0,0 +1,124 @@ +'\" t +.\" Manual page created with latex2man on Wed Aug 16 12:11:05 PDT 2017 +.\" 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 2017" "Programming Library " "Programming Library " +.SH NAME +unw_init_local +\-\- initialize cursor for local unwinding +.PP +.SH SYNOPSIS + +.PP +#include +.br +.PP +int +unw_init_local(unw_cursor_t *c, +unw_context_t *ctxt); +.br +int +unw_init_local2(unw_cursor_t *c, +unw_context_t *ctxt, +int +flag); +.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 is expected to be one provided by a call to +unw_getcontext; as such, the instruction pointer may point to the +instruction after the last instruction of a function, and libunwind +will back\-up the instruction pointer before beginning a walk up the +call stack. 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. +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 , +whereas unw_init_remote() +is not. +.PP +If the unw_context_t is known to be a signal frame (i.e., from the +third argument in a sigaction handler on linux), +unw_init_local2() +should be used for correct initialization +on some platforms, passing the UNW_INIT_SIGNAL_FRAME flag. +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.tex new file mode 100644 index 00000000000000..ff0d03bc77db0e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_init_local.tex @@ -0,0 +1,80 @@ +\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});\\ +\Type{int} \Func{unw\_init\_local2}(\Type{unw\_cursor\_t~*}\Var{c}, \Type{unw\_context\_t~*}\Var{ctxt}, \Type{int} \Var{flag});\\ + +\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 is expected to be one provided by a call to +unw_getcontext; as such, the instruction pointer may point to the +instruction after the last instruction of a function, and libunwind +will back-up the instruction pointer before beginning a walk up the +call stack. 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. +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. + +If the unw_context_t is known to be a signal frame (i.e., from the +third argument in a sigaction handler on linux), +\Func{unw\_init\_local2}() should be used for correct initialization +on some platforms, passing the UNW_INIT_SIGNAL_FRAME flag. + +\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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_init_local2.man b/src/coreclr/src/pal/src/libunwind/doc/unw_init_local2.man new file mode 100644 index 00000000000000..6cbbf008ab6a84 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_init_local2.man @@ -0,0 +1 @@ +.so man3/unw_init_local.3 diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.man b/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.man new file mode 100644 index 00000000000000..0acdac9617b75d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.man @@ -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 +.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 +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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.tex new file mode 100644 index 00000000000000..9b4dc7997ae61f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_init_remote.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.man b/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.man new file mode 100644 index 00000000000000..0c26ec1bc740a2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.tex new file mode 100644 index 00000000000000..c28cdc9be4fd23 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_is_fpreg.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.man b/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.man new file mode 100644 index 00000000000000..d9a7cda7b5fe1c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.tex new file mode 100644 index 00000000000000..f262e5600c1df7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_is_signal_frame.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.man b/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.man new file mode 100644 index 00000000000000..e328ad2e38cdff --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.man @@ -0,0 +1,137 @@ +'\" t +.\" Manual page created with latex2man on Wed Aug 16 11:09:44 PDT 2017 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "UNW\\_REG\\_STATES\\_ITERATE" "3" "16 August 2017" "Programming Library " "Programming Library " +.SH NAME +unw_reg_states_iterate +\-\- get register state info on current procedure +.PP +.SH SYNOPSIS + +.PP +#include +.br +.PP +int +unw_reg_states_iterate(unw_cursor_t *cp, +unw_reg_states_callbackcb, +void *token); +.br +.PP +.SH DESCRIPTION + +.PP +The unw_reg_states_iterate() +routine provides +information about the procedure that created the stack frame +identified by argument cp\&. +The cb +argument is a pointer +to a function of type unw_reg_states_callback +which is used to +return the information. The function unw_reg_states_callback +has the +following definition: +.PP +int +( *unw_reg_states_callback)(void *token, +void *reg_states_data, +size_t +reg_states_data_size, +unw_word_t +start_ip, +unw_word_t +end_ip); +.PP +The callback function may be invoked several times for each call of unw_reg_states_iterate\&. +Each call is associcated with a instruction address range and a set of instructions on how to update register values when returning from the procedure in that address range. For each invocation, the arguments to the callback function are: +.TP +void * token + The token value passed to unw_reg_states_callback\&. +.br +.TP +void * reg_states_data + A pointer to data about +updating register values. This data, or a copy of it, can be passed +to unw_apply_reg_state\&. +.br +.TP +int reg_states_data_size + The size of the register update data. +.br +.TP +unw_word_t start_ip + The address of the first +instruction of the address range. +.br +.TP +unw_word_t end_ip + The address of the first +instruction \fIbeyond\fP +the end of the address range. +.br +.PP +.SH RETURN VALUE + +.PP +On successful completion, unw_reg_states_iterate() +returns +0. If the callback function returns a nonzero value, that indicates +failure and the function returns immediately. Otherwise the negative +value of one of the error\-codes below is returned. +.PP +.SH THREAD AND SIGNAL SAFETY + +.PP +unw_reg_states_iterate() +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_reg_states_iterate() +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_apply_reg_state(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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.tex new file mode 100644 index 00000000000000..36c9b548a25d74 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_reg_states_iterate.tex @@ -0,0 +1,83 @@ +\documentclass{article} +\usepackage[fancyhdr,pdf]{latex2man} + +\input{common.tex} + +\begin{document} + +\begin{Name}{3}{unw\_reg\_states\_iterate}{David Mosberger-Tang}{Programming Library}{unw\_reg\_states\_iterate}unw\_reg\_states\_iterate -- get register state info on current procedure +\end{Name} + +\section{Synopsis} + +\File{\#include $<$libunwind.h$>$}\\ + +\Type{int} \Func{unw\_reg\_states\_iterate}(\Type{unw\_cursor\_t~*}\Var{cp}, \Type{unw\_reg\_states\_callback}\Var{cb}, \Type{void~*}\Var{token});\\ + +\section{Description} + +The \Func{unw\_reg\_states\_iterate}() routine provides +information about the procedure that created the stack frame +identified by argument \Var{cp}. The \Var{cb} argument is a pointer +to a function of type \Type{unw\_reg\_states\_callback} which is used to +return the information. The function \Type{unw\_reg\_states\_callback} has the +following definition: + +\Type{int} (~*\Var{unw\_reg\_states\_callback})(\Type{void~*}\Var{token}, + \Type{void~*}\Var{reg\_states\_data}, + \Type{size\_t} \Var{reg\_states\_data\_size}, + \Type{unw\_word\_t} \Var{start\_ip}, \Type{unw\_word\_t} \Var{end\_ip}); + +The callback function may be invoked several times for each call of \Func{unw\_reg\_states\_iterate}. Each call is associcated with a instruction address range and a set of instructions on how to update register values when returning from the procedure in that address range. For each invocation, the arguments to the callback function are: +\begin{description} +\item[\Type{void~*} \Var{token}] The token value passed to \Var{unw\_reg\_states\_callback}. \\ +\item[\Type{void~*} \Var{reg\_states\_data}] A pointer to data about + updating register values. This data, or a copy of it, can be passed + to \Var{unw\_apply\_reg\_state}.\\ +\item[\Type{int} \Var{reg\_states\_data\_size}] The size of the register update data. \\ +\item[\Type{unw\_word\_t} \Var{start\_ip}] The address of the first + instruction of the address range. \\ +\item[\Type{unw\_word\_t} \Var{end\_ip}] The address of the first + instruction \emph{beyond} the end of the address range. \\ +\end{description} + +\section{Return Value} + +On successful completion, \Func{unw\_reg\_states\_iterate}() returns +0. If the callback function returns a nonzero value, that indicates +failure and the function returns immediately. Otherwise the negative +value of one of the error-codes below is returned. + +\section{Thread and Signal Safety} + +\Func{unw\_reg\_states\_iterate}() 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\_reg\_states\_iterate}() 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\_apply\_reg\_state(3)} + +\section{Author} + +\noindent +David Mosberger-Tang\\ +Email: \Email{dmosberger@gmail.com}\\ +WWW: \URL{http://www.nongnu.org/libunwind/}. +\LatexManEnd + +\end{document} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_regname.man b/src/coreclr/src/pal/src/libunwind/doc/unw_regname.man new file mode 100644 index 00000000000000..1e3e2dbc6ea1fe --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_regname.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_regname.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_regname.tex new file mode 100644 index 00000000000000..94b6434194d6f2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_regname.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_resume.man b/src/coreclr/src/pal/src/libunwind/doc/unw_resume.man new file mode 100644 index 00000000000000..1bf38327bf00ed --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_resume.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_resume.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_resume.tex new file mode 100644 index 00000000000000..38b18248ab66f2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_resume.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.man b/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.man new file mode 100644 index 00000000000000..34bbc53961450c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.man @@ -0,0 +1,88 @@ +'\" t +.\" Manual page created with latex2man on Fri Jan 13 08:33:21 PST 2017 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "UNW\\_SET\\_CACHE\\_SIZE" "3" "13 January 2017" "Programming Library " "Programming Library " +.SH NAME +unw_set_cache_size +\-\- set unwind cache size +.PP +.SH SYNOPSIS + +.PP +#include +.br +.PP +int +unw_set_cache_size(unw_addr_space_t +as, +size_t +size, +int +flag); +.br +.PP +.SH DESCRIPTION + +.PP +The unw_set_cache_size() +routine sets the cache size of +address space as +to hold at least as many items as given by +argument size\&. +It may hold more items as determined by the +implementation. To disable caching, call +unw_set_caching_policy) +with a policy of +UNW_CACHE_NONE\&. +Flag is currently unused and must be 0. +.PP +.SH RETURN VALUE + +.PP +On successful completion, unw_set_cache_size() +returns 0. +Otherwise the negative value of one of the error\-codes below is +returned. +.PP +.SH THREAD AND SIGNAL SAFETY + +.PP +unw_set_cache_size() +is thread\-safe but \fInot\fP +safe +to use from a signal handler. +.PP +.SH ERRORS + +.PP +.TP +UNW_ENOMEM + The desired cache size could not be +established because the application is out of memory. +.PP +.SH SEE ALSO + +.PP +libunwind(3), +unw_create_addr_space(3), +unw_set_caching_policy(3), +unw_flush_cache(3) +.PP +.SH AUTHOR + +.PP +Dave Watson +.br +Email: \fBdade.watson@gmail.com\fP +.br +WWW: \fBhttp://www.nongnu.org/libunwind/\fP\&. +.\" NOTE: This file is generated, DO NOT EDIT. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.tex new file mode 100644 index 00000000000000..1bd7e00df7c231 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_set_cache_size.tex @@ -0,0 +1,59 @@ +\documentclass{article} +\usepackage[fancyhdr,pdf]{latex2man} + +\input{common.tex} + +\begin{document} + +\begin{Name}{3}{unw\_set\_cache\_size}{Dave Watson}{Programming Library}{unw\_set\_cache\_size}unw\_set\_cache\_size -- set unwind cache size +\end{Name} + +\section{Synopsis} + +\File{\#include $<$libunwind.h$>$}\\ + +\Type{int} \Func{unw\_set\_cache\_size}(\Type{unw\_addr\_space\_t} \Var{as}, \Type{size\_t} \Var{size}, \Type{int} \Var{flag});\\ + +\section{Description} + +The \Func{unw\_set\_cache\_size}() routine sets the cache size of +address space \Var{as} to hold at least as many items as given by +argument \Var{size}. It may hold more items as determined by the +implementation. To disable caching, call +\Func{unw\_set\_caching\_policy}) with a policy of +\Const{UNW\_CACHE\_NONE}. Flag is currently unused and must be 0. + +\section{Return Value} + +On successful completion, \Func{unw\_set\_cache\_size}() returns 0. +Otherwise the negative value of one of the error-codes below is +returned. + +\section{Thread and Signal Safety} + +\Func{unw\_set\_cache\_size}() is thread-safe but \emph{not} safe +to use from a signal handler. + +\section{Errors} + +\begin{Description} +\item[\Const{UNW\_ENOMEM}] The desired cache size 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\_set\_caching\_policy(3)}, +\SeeAlso{unw\_flush\_cache(3)} + +\section{Author} + +\noindent +Dave Watson\\ +Email: \Email{dade.watson@gmail.com}\\ +WWW: \URL{http://www.nongnu.org/libunwind/}. +\LatexManEnd + +\end{document} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.man b/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.man new file mode 100644 index 00000000000000..4862ea545e5d45 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.man @@ -0,0 +1,119 @@ +'\" t +.\" Manual page created with latex2man on Fri Dec 2 16:09:33 PST 2016 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "UNW\\_SET\\_CACHING\\_POLICY" "3" "02 December 2016" "Programming Library " "Programming Library " +.SH NAME +unw_set_caching_policy +\-\- set unwind caching policy +.PP +.SH SYNOPSIS + +.PP +#include +.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_set_cache_size(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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.tex new file mode 100644 index 00000000000000..3a4b07e84af0f3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_set_caching_policy.tex @@ -0,0 +1,81 @@ +\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\_set\_cache\_size(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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.man b/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.man new file mode 100644 index 00000000000000..6cefa54623ca2f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.tex new file mode 100644 index 00000000000000..aaf7fb25a761eb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_set_fpreg.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.man b/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.man new file mode 100644 index 00000000000000..5d57045f747515 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.tex new file mode 100644 index 00000000000000..2421846be59e78 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_set_reg.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_step.man b/src/coreclr/src/pal/src/libunwind/doc/unw_step.man new file mode 100644 index 00000000000000..54da1b2f3d62a1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_step.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_step.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_step.tex new file mode 100644 index 00000000000000..106bd9ba99c0c7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_step.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.man b/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.man new file mode 100644 index 00000000000000..467c44d26204c3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.man @@ -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 +.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. diff --git a/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.tex b/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.tex new file mode 100644 index 00000000000000..7cad011768d73d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/doc/unw_strerror.tex @@ -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} diff --git a/src/coreclr/src/pal/src/libunwind/include/compiler.h b/src/coreclr/src/pal/src/libunwind/include/compiler.h new file mode 100644 index 00000000000000..2fa59eff7fbd86 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/compiler.h @@ -0,0 +1,72 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +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 ALIAS2(name) #name +# define ALIAS(name) __attribute__((alias (ALIAS2(name)))) +# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) +# define ALWAYS_INLINE inline __attribute__((always_inline)) +# define HIDDEN __attribute__((visibility ("hidden"))) +# else +# define ALWAYS_INLINE +# define HIDDEN +# 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 WEAK +# define likely(x) (x) +# define unlikely(x) (x) +#endif + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +#endif /* COMPILER_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h b/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h new file mode 100644 index 00000000000000..96002a1b9d2d23 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h @@ -0,0 +1,129 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +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" +#include "libunwind_i.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 __attribute__((packed)) dwarf_eh_frame_hdr + { + unsigned char version; + unsigned char eh_frame_ptr_enc; + unsigned char fde_count_enc; + unsigned char table_enc; + Elf_W (Addr) eh_frame; + /* The rest of the header is variable-length and consists of the + following members: + + 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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf.h b/src/coreclr/src/pal/src/libunwind/include/dwarf.h new file mode 100644 index 00000000000000..764f6f20ac22ba --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/dwarf.h @@ -0,0 +1,450 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +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 + +struct dwarf_cursor; /* forward-declaration */ +struct elf_dyn_info; + +#include "dwarf-config.h" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef UNW_REMOTE_ONLY + #if defined(HAVE_LINK_H) + #include + #elif defined(HAVE_SYS_LINK_H) + #include + #else + #error Could not find + #endif +#endif + +#include + +/* 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 +#define DWARF_CIE_VERSION_MAX 4 + +#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_val_expression = 0x16, + 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_VAL_EXPR, /* register has computed value */ + } +dwarf_where_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_only_state + { + char where[DWARF_NUM_PRESERVED_REGS + 2]; /* how is the register saved? */ + unw_word_t val[DWARF_NUM_PRESERVED_REGS + 2]; /* where it's saved */ + } +dwarf_reg_only_state_t; + +typedef struct dwarf_reg_state + { + unw_word_t ret_addr_column; /* which column in rule table represents return address */ + dwarf_reg_only_state_t reg; + } +dwarf_reg_state_t; + +typedef struct dwarf_stackable_reg_state + { + struct dwarf_stackable_reg_state *next; /* for rs_stack */ + dwarf_reg_state_t state; + } +dwarf_stackable_reg_state_t; + +typedef struct dwarf_reg_cache_entry + { + unw_word_t ip; /* ip this rs is for */ + 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_cache_entry_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 eh_args[UNW_TDEP_NUM_EH_REGS]; + unsigned int eh_valid_mask; + + 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_DEFAULT_LOG_UNW_CACHE_SIZE 7 +#define DWARF_DEFAULT_UNW_CACHE_SIZE (1 << DWARF_DEFAULT_LOG_UNW_CACHE_SIZE) + +#define DWARF_DEFAULT_LOG_UNW_HASH_SIZE (DWARF_DEFAULT_LOG_UNW_CACHE_SIZE + 1) +#define DWARF_DEFAULT_UNW_HASH_SIZE (1 << DWARF_DEFAULT_LOG_UNW_HASH_SIZE) + +typedef unsigned char unw_hash_index_t; + +struct dwarf_rs_cache + { + pthread_mutex_t lock; + unsigned short rr_head; /* index of least-recently allocated rs */ + + unsigned short log_size; + unsigned short prev_log_size; + + /* hash table that maps instruction pointer to rs index: */ + unsigned short *hash; + + uint32_t generation; /* generation number */ + + /* rs cache: */ + dwarf_reg_state_t *buckets; + dwarf_reg_cache_entry_t *links; + + /* default memory, loaded in BSS segment */ + unsigned short default_hash[DWARF_DEFAULT_UNW_HASH_SIZE]; + dwarf_reg_state_t default_buckets[DWARF_DEFAULT_UNW_CACHE_SIZE]; + dwarf_reg_cache_entry_t default_links[DWARF_DEFAULT_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; + /* Index (for binary search). */ + struct table_entry *index; + size_t index_size; + /* Pointer to next descriptor. */ + struct unw_debug_frame_list *next; + }; + +/* 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_stack_aligned UNW_OBJ (dwarf_stack_aligned) +#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_make_proc_info UNW_OBJ (dwarf_make_proc_info) +#define dwarf_apply_reg_state UNW_OBJ (dwarf_apply_reg_state) +#define dwarf_reg_states_iterate UNW_OBJ (dwarf_reg_states_iterate) +#define dwarf_read_encoded_pointer UNW_OBJ (dwarf_read_encoded_pointer) +#define dwarf_step UNW_OBJ (dwarf_step) +#define dwarf_flush_rs_cache UNW_OBJ (dwarf_flush_rs_cache) + +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); + +extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip); +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 stack_val, unw_word_t *addr, + unw_word_t len, unw_word_t *valp, + int *is_register); +extern int +dwarf_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr, + unw_word_t rbp_addr, unw_word_t *offset); + +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, + unw_word_t base, + int need_unwind_info, + int is_debug_frame, + void *arg); +extern int dwarf_find_save_locs (struct dwarf_cursor *c); +extern int dwarf_make_proc_info (struct dwarf_cursor *c); +extern int dwarf_apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs); +extern int dwarf_reg_states_iterate (struct dwarf_cursor *c, unw_reg_states_callback cb, void *token); +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); +extern int dwarf_flush_rs_cache (struct dwarf_rs_cache *cache); + +#endif /* dwarf_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf_i.h b/src/coreclr/src/pal/src/libunwind/include/dwarf_i.h new file mode 100644 index 00000000000000..983b9f5c2afbc7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/dwarf_i.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 = 0; + int32_t sval32 = 0; + int64_t sval64 = 0; + 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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h new file mode 100644 index 00000000000000..778b43626b9256 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h @@ -0,0 +1,245 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + 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 +#include +#include + +#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. + + Calculation is regs used (64 + 34) * 2 + 40 (bytes of rest of + cursor) + padding +*/ + +#define UNW_TDEP_CURSOR_LEN 250 + +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 */ + } +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. */ + } +unw_tdep_save_loc_t; + + +/* On AArch64, we can directly use ucontext_t as the unwind context, + * however, the __reserved struct is quite large: tune it down to only + * the necessary used fields. */ + +struct unw_sigcontext + { + uint64_t fault_address; + uint64_t regs[31]; + uint64_t sp; + uint64_t pc; + uint64_t pstate; + uint8_t __reserved[(34 * 8)] __attribute__((__aligned__(16))); +}; + +typedef struct + { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + __sigset_t uc_sigmask; + struct unw_sigcontext uc_mcontext; + } unw_tdep_context_t; + +typedef struct + { + uint32_t _ctx_magic; + uint32_t _ctx_size; + uint32_t fpsr; + uint32_t fpcr; + uint64_t vregs[64]; + } unw_fpsimd_context_t; + + + +#include "libunwind-common.h" +#include "libunwind-dynamic.h" + +#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__ ( \ + "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, x13, [%[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" \ + "stp x1, x30, [%[base], #248]\n" \ + : [base] "+r" (unw_base) : : "x1", "memory"); \ + }), 0) +#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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-arm.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-arm.h new file mode 100644 index 00000000000000..6709b7abaeefa4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-arm.h @@ -0,0 +1,303 @@ +/* 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 +#include + +#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. */ + } +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]\n" \ + ".code 16\n" \ + : [base] "+r" (unw_base) : : "memory", "cc"); \ + }), 0) +#endif + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no arm-specific auxiliary proc-info */ + } +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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in b/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in new file mode 100644 index 00000000000000..9dbb415f50441e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in @@ -0,0 +1,292 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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) + +#ifdef __sun +// On SmartOS, gcc fails with the following error: +// +// ../include/libunwind-common.h:43:41: error: expected identifier or '(' before numeric constant +// # define UNW_PREFIX UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_) +// ^ +// +// workaround is to undefine _U explicitly. +// see https://github.com/libunwind/libunwind/issues/118 for more details. +// +#undef _U +#endif + +#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 enum + { + UNW_INIT_SIGNAL_FRAME = 1, /* We know this is a signal frame */ + } +unw_init_local2_flags_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 */ +#if defined(NEED_LAST_IP) + unw_word_t last_ip; /* first IP that could begin another procedure */ +#endif + 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; + +typedef int (*unw_reg_states_callback)(void *token, + void *reg_states_data, + size_t reg_states_data_size, + unw_word_t start_ip, unw_word_t end_ip); + +/* 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_get_accessors_int UNW_ARCH_OBJ(get_accessors_int) +#define unw_init_local UNW_OBJ(init_local) +#define unw_init_local2 UNW_OBJ(init_local2) +#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_reg_states_iterate UNW_OBJ(reg_states_iterate) +#define unw_apply_reg_state UNW_OBJ(apply_reg_state) +#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_get_proc_name UNW_OBJ(get_proc_name) +#define unw_set_caching_policy UNW_OBJ(set_caching_policy) +#define unw_set_cache_size UNW_OBJ(set_cache_size) +#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 unw_accessors_t *unw_get_accessors_int (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 int unw_set_cache_size (unw_addr_space_t, size_t, int); +extern const char *unw_regname (unw_regnum_t); + +extern int unw_init_local (unw_cursor_t *, unw_context_t *); +extern int unw_init_local2 (unw_cursor_t *, unw_context_t *, int); +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_reg_states_iterate (unw_cursor_t *, unw_reg_states_callback, void *); +extern int unw_apply_reg_state (unw_cursor_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_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; diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-coredump.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-coredump.h new file mode 100644 index 00000000000000..3c7814140f940d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-coredump.h @@ -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 + +#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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-dynamic.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-dynamic.h new file mode 100644 index 00000000000000..edb0bbd343db7f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-dynamic.h @@ -0,0 +1,214 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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_INFO_FORMAT_IP_OFFSET, /* Like UNW_INFO_FORMAT_REMOTE_TABLE, but + table entries are considered + relative to di->start_ip, rather + than di->segbase */ + } +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 diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-hppa.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-hppa.h new file mode 100644 index 00000000000000..7013aa772682db --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-hppa.h @@ -0,0 +1,125 @@ +/* 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 +#include + +#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. */ + } +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 */ + } +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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-ia64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-ia64.h new file mode 100644 index 00000000000000..0cc4f39eaab1e4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-ia64.h @@ -0,0 +1,194 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 +#include + +#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 */ + } +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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h new file mode 100644 index 00000000000000..ced34b2027af66 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h @@ -0,0 +1,160 @@ +/* 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 +#include + +#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, which are 32-bit wide for O32 and N32 + ABIs, and 64-bit wide for N64 ABI. */ +#if _MIPS_SIM == _ABI64 +typedef uint64_t unw_word_t; +#else +typedef uint32_t unw_word_t; +#endif +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 = 64, + + /* 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_PC, + + 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. */ + } +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 */ + } +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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc32.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc32.h new file mode 100644 index 00000000000000..47ebfde5a3cf3a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc32.h @@ -0,0 +1,207 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + 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 +#include + +#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. */ + } +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 */ + } +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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc64.h new file mode 100644 index 00000000000000..9944628da02f72 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-ppc64.h @@ -0,0 +1,271 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + 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 +#include + +#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; + +typedef enum + { + UNW_PPC64_ABI_ELFv1, + UNW_PPC64_ABI_ELFv2 + } +ppc64_abi_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. */ + } +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 */ + } +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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-ptrace.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-ptrace.h new file mode 100644 index 00000000000000..801325c4d4d00c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-ptrace.h @@ -0,0 +1,63 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 + +#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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h new file mode 100644 index 00000000000000..ebda40d57af9b6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h @@ -0,0 +1,144 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for s390x by Michael Munday + +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 +#include +#include + +#define UNW_TARGET s390x +#define UNW_TARGET_S390X 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 384 + +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; + +typedef double unw_tdep_fpreg_t; + +typedef enum + { + /* general purpose registers */ + UNW_S390X_R0, + UNW_S390X_R1, + UNW_S390X_R2, + UNW_S390X_R3, + UNW_S390X_R4, + UNW_S390X_R5, + UNW_S390X_R6, + UNW_S390X_R7, + UNW_S390X_R8, + UNW_S390X_R9, + UNW_S390X_R10, + UNW_S390X_R11, + UNW_S390X_R12, + UNW_S390X_R13, + UNW_S390X_R14, + UNW_S390X_R15, + + /* floating point registers */ + UNW_S390X_F0, + UNW_S390X_F1, + UNW_S390X_F2, + UNW_S390X_F3, + UNW_S390X_F4, + UNW_S390X_F5, + UNW_S390X_F6, + UNW_S390X_F7, + UNW_S390X_F8, + UNW_S390X_F9, + UNW_S390X_F10, + UNW_S390X_F11, + UNW_S390X_F12, + UNW_S390X_F13, + UNW_S390X_F14, + UNW_S390X_F15, + + /* PSW */ + UNW_S390X_IP, + + UNW_TDEP_LAST_REG = UNW_S390X_IP, + + /* TODO: access, vector registers */ + + /* frame info (read-only) */ + UNW_S390X_CFA, + + UNW_TDEP_IP = UNW_S390X_IP, + UNW_TDEP_SP = UNW_S390X_R15, + + /* TODO: placeholders */ + UNW_TDEP_EH = UNW_S390X_R0, + } +s390x_regnum_t; + +#define UNW_TDEP_NUM_EH_REGS 2 /* XXX Not sure what this means */ + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + char unused; + } +unw_tdep_save_loc_t; + +/* On s390x, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +typedef struct + { + /* no s390x-specific auxiliary proc-info */ + char unused; + } +unw_tdep_proc_info_t; + +#include "libunwind-dynamic.h" +#include "libunwind-common.h" + +#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) + +extern int unw_tdep_getcontext (unw_tdep_context_t *); +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-sh.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-sh.h new file mode 100644 index 00000000000000..927f61ff42bdad --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-sh.h @@ -0,0 +1,114 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +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 +#include +#include + +#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. */ + } +unw_tdep_save_loc_t; + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no sh-specific auxiliary proc-info */ + } +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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-tilegx.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-tilegx.h new file mode 100644 index 00000000000000..0f84ea65ee3657 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-tilegx.h @@ -0,0 +1,161 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +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 +#include + +#define UNW_TARGET tilegx +#define UNW_TARGET_TILEGX 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 + +/* The size of a "word" varies on TILEGX. This type is used for memory + addresses and register values. */ +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; + +typedef long double unw_tdep_fpreg_t; + +typedef enum +{ + UNW_TILEGX_R0, + UNW_TILEGX_R1, + UNW_TILEGX_R2, + UNW_TILEGX_R3, + UNW_TILEGX_R4, + UNW_TILEGX_R5, + UNW_TILEGX_R6, + UNW_TILEGX_R7, + UNW_TILEGX_R8, + UNW_TILEGX_R9, + UNW_TILEGX_R10, + UNW_TILEGX_R11, + UNW_TILEGX_R12, + UNW_TILEGX_R13, + UNW_TILEGX_R14, + UNW_TILEGX_R15, + UNW_TILEGX_R16, + UNW_TILEGX_R17, + UNW_TILEGX_R18, + UNW_TILEGX_R19, + UNW_TILEGX_R20, + UNW_TILEGX_R21, + UNW_TILEGX_R22, + UNW_TILEGX_R23, + UNW_TILEGX_R24, + UNW_TILEGX_R25, + UNW_TILEGX_R26, + UNW_TILEGX_R27, + UNW_TILEGX_R28, + UNW_TILEGX_R29, + UNW_TILEGX_R30, + UNW_TILEGX_R31, + UNW_TILEGX_R32, + UNW_TILEGX_R33, + UNW_TILEGX_R34, + UNW_TILEGX_R35, + UNW_TILEGX_R36, + UNW_TILEGX_R37, + UNW_TILEGX_R38, + UNW_TILEGX_R39, + UNW_TILEGX_R40, + UNW_TILEGX_R41, + UNW_TILEGX_R42, + UNW_TILEGX_R43, + UNW_TILEGX_R44, + UNW_TILEGX_R45, + UNW_TILEGX_R46, + UNW_TILEGX_R47, + UNW_TILEGX_R48, + UNW_TILEGX_R49, + UNW_TILEGX_R50, + UNW_TILEGX_R51, + UNW_TILEGX_R52, + UNW_TILEGX_R53, + UNW_TILEGX_R54, + UNW_TILEGX_R55, + + /* FIXME: Other registers! */ + + UNW_TILEGX_PC, + /* For TILEGX, the CFA is the value of SP (r54) at the call site in the + previous frame. */ + UNW_TILEGX_CFA, + + UNW_TDEP_LAST_REG = UNW_TILEGX_PC, + + UNW_TDEP_IP = UNW_TILEGX_R55, /* R55 is link register for Tilegx */ + UNW_TDEP_SP = UNW_TILEGX_R54, + UNW_TDEP_EH = UNW_TILEGX_R0 /* FIXME. */ +} tilegx_regnum_t; + +typedef enum +{ + UNW_TILEGX_ABI_N64 = 2 +} tilegx_abi_t; + +#define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for TILEGX. */ + +typedef struct unw_tdep_save_loc +{ + /* Additional target-dependent info on a save location. */ +} unw_tdep_save_loc_t; + +typedef ucontext_t unw_tdep_context_t; + +#include "libunwind-dynamic.h" + +typedef struct +{ + /* no tilegx-specific auxiliary proc-info */ +} unw_tdep_proc_info_t; + +#include "libunwind-common.h" + +#define unw_tdep_getcontext getcontext + +#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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-x86.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-x86.h new file mode 100644 index 00000000000000..40fe0464f2f6c2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-x86.h @@ -0,0 +1,187 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 +#include +#include + +#define UNW_TARGET x86 +#define UNW_TARGET_X86 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 127 + +typedef uint32_t unw_word_t; +typedef int32_t unw_sword_t; + +typedef union { + struct { uint8_t b[4]; } val32; + struct { uint8_t b[10]; } val80; + struct { uint8_t b[16]; } val128; +} 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. + + The described register usage convention is based on "System V + Application Binary Interface, Intel386 Architecture Processor + Supplement, Fourth Edition" at + + http://www.linuxbase.org/spec/refspecs/elf/abi386-4.pdf + + It would have been nice to use the same register numbering as + DWARF, but that doesn't work because the libunwind requires + that the exception argument registers be consecutive, which the + wouldn't be with the DWARF numbering. */ + UNW_X86_EAX, /* scratch (exception argument 1) */ + UNW_X86_EDX, /* scratch (exception argument 2) */ + UNW_X86_ECX, /* scratch */ + UNW_X86_EBX, /* preserved */ + UNW_X86_ESI, /* preserved */ + UNW_X86_EDI, /* preserved */ + UNW_X86_EBP, /* (optional) frame-register */ + UNW_X86_ESP, /* (optional) frame-register */ + UNW_X86_EIP, /* frame-register */ + UNW_X86_EFLAGS, /* scratch (except for "direction", which is fixed */ + UNW_X86_TRAPNO, /* scratch */ + + /* MMX/stacked-fp registers */ + UNW_X86_ST0, /* fp return value */ + UNW_X86_ST1, /* scratch */ + UNW_X86_ST2, /* scratch */ + UNW_X86_ST3, /* scratch */ + UNW_X86_ST4, /* scratch */ + UNW_X86_ST5, /* scratch */ + UNW_X86_ST6, /* scratch */ + UNW_X86_ST7, /* scratch */ + + UNW_X86_FCW, /* scratch */ + UNW_X86_FSW, /* scratch */ + UNW_X86_FTW, /* scratch */ + UNW_X86_FOP, /* scratch */ + UNW_X86_FCS, /* scratch */ + UNW_X86_FIP, /* scratch */ + UNW_X86_FEA, /* scratch */ + UNW_X86_FDS, /* scratch */ + + /* SSE registers */ + UNW_X86_XMM0_lo, /* scratch */ + UNW_X86_XMM0_hi, /* scratch */ + UNW_X86_XMM1_lo, /* scratch */ + UNW_X86_XMM1_hi, /* scratch */ + UNW_X86_XMM2_lo, /* scratch */ + UNW_X86_XMM2_hi, /* scratch */ + UNW_X86_XMM3_lo, /* scratch */ + UNW_X86_XMM3_hi, /* scratch */ + UNW_X86_XMM4_lo, /* scratch */ + UNW_X86_XMM4_hi, /* scratch */ + UNW_X86_XMM5_lo, /* scratch */ + UNW_X86_XMM5_hi, /* scratch */ + UNW_X86_XMM6_lo, /* scratch */ + UNW_X86_XMM6_hi, /* scratch */ + UNW_X86_XMM7_lo, /* scratch */ + UNW_X86_XMM7_hi, /* scratch */ + + UNW_X86_MXCSR, /* scratch */ + + /* segment registers */ + UNW_X86_GS, /* special */ + UNW_X86_FS, /* special */ + UNW_X86_ES, /* special */ + UNW_X86_DS, /* special */ + UNW_X86_SS, /* special */ + UNW_X86_CS, /* special */ + UNW_X86_TSS, /* special */ + UNW_X86_LDT, /* special */ + + /* frame info (read-only) */ + UNW_X86_CFA, + + UNW_X86_XMM0, /* scratch */ + UNW_X86_XMM1, /* scratch */ + UNW_X86_XMM2, /* scratch */ + UNW_X86_XMM3, /* scratch */ + UNW_X86_XMM4, /* scratch */ + UNW_X86_XMM5, /* scratch */ + UNW_X86_XMM6, /* scratch */ + UNW_X86_XMM7, /* scratch */ + + UNW_TDEP_LAST_REG = UNW_X86_XMM7, + + UNW_TDEP_IP = UNW_X86_EIP, + UNW_TDEP_SP = UNW_X86_ESP, + UNW_TDEP_EH = UNW_X86_EAX + } +x86_regnum_t; + +#define UNW_TDEP_NUM_EH_REGS 2 /* eax and edx are exception args */ + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + } +unw_tdep_save_loc_t; + +/* On x86, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +#include "libunwind-dynamic.h" + +typedef struct + { + /* no x86-specific auxiliary proc-info */ + } +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 *); + +#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 */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-x86_64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-x86_64.h new file mode 100644 index 00000000000000..78eb541afb303c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-x86_64.h @@ -0,0 +1,141 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +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 +#include +#include + +#define UNW_TARGET x86_64 +#define UNW_TARGET_X86_64 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 127 + +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; + +typedef long double unw_tdep_fpreg_t; + +typedef enum + { + UNW_X86_64_RAX, + UNW_X86_64_RDX, + UNW_X86_64_RCX, + UNW_X86_64_RBX, + UNW_X86_64_RSI, + UNW_X86_64_RDI, + UNW_X86_64_RBP, + UNW_X86_64_RSP, + UNW_X86_64_R8, + UNW_X86_64_R9, + UNW_X86_64_R10, + UNW_X86_64_R11, + UNW_X86_64_R12, + UNW_X86_64_R13, + UNW_X86_64_R14, + UNW_X86_64_R15, + UNW_X86_64_RIP, +#ifdef CONFIG_MSABI_SUPPORT + UNW_X86_64_XMM0, + UNW_X86_64_XMM1, + UNW_X86_64_XMM2, + UNW_X86_64_XMM3, + UNW_X86_64_XMM4, + UNW_X86_64_XMM5, + UNW_X86_64_XMM6, + UNW_X86_64_XMM7, + UNW_X86_64_XMM8, + UNW_X86_64_XMM9, + UNW_X86_64_XMM10, + UNW_X86_64_XMM11, + UNW_X86_64_XMM12, + UNW_X86_64_XMM13, + UNW_X86_64_XMM14, + UNW_X86_64_XMM15, + UNW_TDEP_LAST_REG = UNW_X86_64_XMM15, +#else + UNW_TDEP_LAST_REG = UNW_X86_64_RIP, +#endif + + /* XXX Add other regs here */ + + /* frame info (read-only) */ + UNW_X86_64_CFA, + + UNW_TDEP_IP = UNW_X86_64_RIP, + UNW_TDEP_SP = UNW_X86_64_RSP, + UNW_TDEP_BP = UNW_X86_64_RBP, + UNW_TDEP_EH = UNW_X86_64_RAX + } +x86_64_regnum_t; + +#define UNW_TDEP_NUM_EH_REGS 2 /* XXX Not sure what this means */ + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + char unused; + } +unw_tdep_save_loc_t; + +/* On x86_64, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +typedef struct + { + /* no x86-64-specific auxiliary proc-info */ + char unused; + } +unw_tdep_proc_info_t; + +#include "libunwind-dynamic.h" +#include "libunwind-common.h" + +#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) + +extern int unw_tdep_getcontext (unw_tdep_context_t *); +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in b/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in new file mode 100644 index 00000000000000..a13e7767325df1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in @@ -0,0 +1,38 @@ +/* Provide a real file - not a symlink - as it would cause multiarch conflicts + when multiple different arch releases are installed simultaneously. */ + +#ifndef UNW_REMOTE_ONLY + +#if defined __aarch64__ +#include "libunwind-aarch64.h" +#elif defined __arm__ +# include "libunwind-arm.h" +#elif defined __hppa__ +# include "libunwind-hppa.h" +#elif defined __ia64__ +# include "libunwind-ia64.h" +#elif defined __mips__ +# include "libunwind-mips.h" +#elif defined __powerpc__ && !defined __powerpc64__ +# include "libunwind-ppc32.h" +#elif defined __powerpc64__ +# include "libunwind-ppc64.h" +#elif defined __sh__ +# include "libunwind-sh.h" +#elif defined __i386__ +# include "libunwind-x86.h" +#elif defined __x86_64__ +# include "libunwind-x86_64.h" +#elif defined __tilegx__ +# include "libunwind-tilegx.h" +#elif defined __s390x__ +# include "libunwind-s390x.h" +#else +# error "Unsupported arch" +#endif + +#else /* UNW_REMOTE_ONLY */ + +# include "libunwind-@arch@.h" + +#endif /* UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h new file mode 100644 index 00000000000000..e0f4540144230e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h @@ -0,0 +1,370 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +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 files contains libunwind-internal definitions which are + subject to frequent change and are not to be exposed to + libunwind-users. */ + +#ifndef libunwind_i_h +#define libunwind_i_h + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "compiler.h" + +#if defined(HAVE___THREAD) && HAVE___THREAD +#define UNWI_DEFAULT_CACHING_POLICY UNW_CACHE_PER_THREAD +#else +#define UNWI_DEFAULT_CACHING_POLICY UNW_CACHE_GLOBAL +#endif + +/* Platform-independent libunwind-internal declarations. */ + +#include /* HP-UX needs this before include of pthread.h */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(HAVE_ELF_H) +# include +#elif defined(HAVE_SYS_ELF_H) +# include +#else +# error Could not locate +#endif + +#if defined(HAVE_ENDIAN_H) +# include +#elif defined(HAVE_SYS_ENDIAN_H) +# include +# if defined(_LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) +# define __LITTLE_ENDIAN _LITTLE_ENDIAN +# endif +# if defined(_BIG_ENDIAN) && !defined(__BIG_ENDIAN) +# define __BIG_ENDIAN _BIG_ENDIAN +# endif +# if defined(_BYTE_ORDER) && !defined(__BYTE_ORDER) +# define __BYTE_ORDER _BYTE_ORDER +# endif +#else +# define __LITTLE_ENDIAN 1234 +# define __BIG_ENDIAN 4321 +# if defined(__hpux) +# define __BYTE_ORDER __BIG_ENDIAN +# elif defined(__QNX__) +# if defined(__BIGENDIAN__) +# define __BYTE_ORDER __BIG_ENDIAN +# elif defined(__LITTLEENDIAN__) +# define __BYTE_ORDER __LITTLE_ENDIAN +# else +# error Host has unknown byte-order. +# endif +# else +# error Host has unknown byte-order. +# endif +#endif + +#if defined(HAVE__BUILTIN_UNREACHABLE) +# define unreachable() __builtin_unreachable() +#else +# define unreachable() do { } while (1) +#endif + +#ifdef DEBUG +# define UNW_DEBUG 1 +#else +# define UNW_DEBUG 0 +#endif + +/* Make it easy to write thread-safe code which may or may not be + linked against libpthread. The macros below can be used + unconditionally and if -lpthread is around, they'll call the + corresponding routines otherwise, they do nothing. */ + +#pragma weak pthread_mutex_init +#pragma weak pthread_mutex_lock +#pragma weak pthread_mutex_unlock + +#define mutex_init(l) \ + (pthread_mutex_init != NULL ? pthread_mutex_init ((l), NULL) : 0) +#define mutex_lock(l) \ + (pthread_mutex_lock != NULL ? pthread_mutex_lock (l) : 0) +#define mutex_unlock(l) \ + (pthread_mutex_unlock != NULL ? pthread_mutex_unlock (l) : 0) + +#ifdef HAVE_ATOMIC_OPS_H +# include +static inline int +cmpxchg_ptr (void *addr, void *old, void *new) +{ + union + { + void *vp; + AO_t *aop; + } + u; + + u.vp = addr; + return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new); +} +# define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr) +# define fetch_and_add(_ptr, value) AO_fetch_and_add(_ptr, value) +# define atomic_read(ptr) (AO_load(ptr)) + /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */ +# if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2) +# define HAVE_CMPXCHG +# endif +# define HAVE_FETCH_AND_ADD +#elif defined(HAVE_SYNC_ATOMICS) || defined(HAVE_IA64INTRIN_H) +# ifdef HAVE_IA64INTRIN_H +# include +# endif +static inline int +cmpxchg_ptr (void *addr, void *old, void *new) +{ + union + { + void *vp; + long *vlp; + } + u; + + u.vp = addr; + return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new); +} +# define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1) +# define fetch_and_add(_ptr, value) __sync_fetch_and_add(_ptr, value) +# define atomic_read(ptr) (__atomic_load_n(ptr,__ATOMIC_RELAXED)) +# define HAVE_CMPXCHG +# define HAVE_FETCH_AND_ADD +#endif + +#ifndef atomic_read +#define atomic_read(ptr) (*(ptr)) +#endif + +#define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn)) +#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn) + +#define unwi_full_mask UNWI_ARCH_OBJ(full_mask) + +/* Type of a mask that can be used to inhibit preemption. At the + userlevel, preemption is caused by signals and hence sigset_t is + appropriate. In constrast, the Linux kernel uses "unsigned long" + to hold the processor "flags" instead. */ +typedef sigset_t intrmask_t; + +extern intrmask_t unwi_full_mask; + +/* Silence compiler warnings about variables which are used only if libunwind + is configured in a certain way */ +static inline void mark_as_used(void *v UNUSED) { +} + +#if defined(CONFIG_BLOCK_SIGNALS) +# define SIGPROCMASK(how, new_mask, old_mask) \ + sigprocmask((how), (new_mask), (old_mask)) +#else +# define SIGPROCMASK(how, new_mask, old_mask) mark_as_used(old_mask) +#endif + +/* Prefer adaptive mutexes if available */ +#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +#define UNW_PTHREAD_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +#else +#define UNW_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#endif + +#define define_lock(name) \ + pthread_mutex_t name = UNW_PTHREAD_MUTEX_INITIALIZER +#define lock_init(l) mutex_init (l) +#define lock_acquire(l,m) \ +do { \ + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m)); \ + mutex_lock (l); \ +} while (0) +#define lock_release(l,m) \ +do { \ + mutex_unlock (l); \ + SIGPROCMASK (SIG_SETMASK, &(m), NULL); \ +} while (0) + +#define SOS_MEMORY_SIZE 16384 /* see src/mi/mempool.c */ + +#ifndef MAP_ANONYMOUS +# define MAP_ANONYMOUS MAP_ANON +#endif +#define GET_MEMORY(mem, size) \ +do { \ + /* Hopefully, mmap() goes straight through to a system call stub... */ \ + mem = mmap (NULL, size, PROT_READ | PROT_WRITE, \ + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ + if (mem == MAP_FAILED) \ + mem = NULL; \ +} while (0) + +#define unwi_find_dynamic_proc_info UNWI_OBJ(find_dynamic_proc_info) +#define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info) +#define unwi_put_dynamic_unwind_info UNWI_OBJ(put_dynamic_unwind_info) +#define unwi_dyn_remote_find_proc_info UNWI_OBJ(dyn_remote_find_proc_info) +#define unwi_dyn_remote_put_unwind_info UNWI_OBJ(dyn_remote_put_unwind_info) +#define unwi_dyn_validate_cache UNWI_OBJ(dyn_validate_cache) + +extern int unwi_find_dynamic_proc_info (unw_addr_space_t as, + unw_word_t ip, + unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern int unwi_extract_dynamic_proc_info (unw_addr_space_t as, + unw_word_t ip, + unw_proc_info_t *pi, + unw_dyn_info_t *di, + int need_unwind_info, + void *arg); +extern void unwi_put_dynamic_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pi, void *arg); + +/* These handle the remote (cross-address-space) case of accessing + dynamic unwind info. */ + +extern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as, + unw_word_t ip, + unw_proc_info_t *pi, + int need_unwind_info, + void *arg); +extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pi, + void *arg); +extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg); + +extern unw_dyn_info_list_t _U_dyn_info_list; +extern pthread_mutex_t _U_dyn_info_list_lock; + +#if UNW_DEBUG +#define unwi_debug_level UNWI_ARCH_OBJ(debug_level) +extern long unwi_debug_level; + +# include +# define Debug(level,format...) \ +do { \ + if (unwi_debug_level >= level) \ + { \ + int _n = level; \ + if (_n > 16) \ + _n = 16; \ + fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \ + fprintf (stderr, format); \ + } \ +} while (0) +# define Dprintf(format...) fprintf (stderr, format) +#else +# define Debug(level,format...) +# define Dprintf(format...) +#endif + +static ALWAYS_INLINE int +print_error (const char *string) +{ + return write (2, string, strlen (string)); +} + +#define mi_init UNWI_ARCH_OBJ(mi_init) + +extern void mi_init (void); /* machine-independent initializations */ +extern unw_word_t _U_dyn_info_list_addr (void); + +/* This is needed/used by ELF targets only. */ + +struct elf_image + { + void *image; /* pointer to mmap'd image */ + size_t size; /* (file-) size of the image */ + }; + +struct elf_dyn_info + { + struct elf_image ei; + unw_dyn_info_t di_cache; + unw_dyn_info_t di_debug; /* additional table info for .debug_frame */ +#if UNW_TARGET_IA64 + unw_dyn_info_t ktab; +#endif +#if UNW_TARGET_ARM + unw_dyn_info_t di_arm; /* additional table info for .ARM.exidx */ +#endif + }; + +static inline void invalidate_edi (struct elf_dyn_info *edi) +{ + if (edi->ei.image) + munmap (edi->ei.image, edi->ei.size); + memset (edi, 0, sizeof (*edi)); + edi->di_cache.format = -1; + edi->di_debug.format = -1; +#if UNW_TARGET_ARM + edi->di_arm.format = -1; +#endif +} + + +/* Provide a place holder for architecture to override for fast access + to memory when known not to need to validate and know the access + will be local to the process. A suitable override will improve + unw_tdep_trace() performance in particular. */ +#define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ + do { (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); } \ + while (0) + +/* Define GNU and processor specific values for the Phdr p_type field in case + they aren't defined by . */ +#ifndef PT_GNU_EH_FRAME +# define PT_GNU_EH_FRAME 0x6474e550 +#endif /* !PT_GNU_EH_FRAME */ +#ifndef PT_ARM_EXIDX +# define PT_ARM_EXIDX 0x70000001 /* ARM unwind segment */ +#endif /* !PT_ARM_EXIDX */ + +#include "tdep/libunwind_i.h" + +#ifndef tdep_get_func_addr +# define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0) +#endif + +#ifndef DWARF_VAL_LOC +# define DWARF_IS_VAL_LOC(l) 0 +# define DWARF_VAL_LOC(c,v) DWARF_NULL_LOC +#endif + +#define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) + +#endif /* libunwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/mempool.h b/src/coreclr/src/pal/src/libunwind/include/mempool.h new file mode 100644 index 00000000000000..1f1c77009933f2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/mempool.h @@ -0,0 +1,89 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 mempool_h +#define mempool_h + +/* Memory pools provide simple memory management of fixed-size + objects. Memory pools are used for two purposes: + + o To ensure a stack can be unwound even when a process + is out of memory. + + o To ensure a stack can be unwound at any time in a + multi-threaded process (e.g., even at a time when the normal + malloc-lock is taken, possibly by the very thread that is + being unwind). + + + To achieve the second objective, memory pools allocate memory + directly via mmap() system call (or an equivalent facility). + + The first objective is accomplished by reserving memory ahead of + time. Since the memory requirements of stack unwinding generally + depends on the complexity of the procedures being unwind, there is + no absolute guarantee that unwinding will always work, but in + practice, this should not be a serious problem. */ + +#include + +#include "libunwind_i.h" + +#define sos_alloc(s) UNWI_ARCH_OBJ(_sos_alloc)(s) +#define mempool_init(p,s,r) UNWI_ARCH_OBJ(_mempool_init)(p,s,r) +#define mempool_alloc(p) UNWI_ARCH_OBJ(_mempool_alloc)(p) +#define mempool_free(p,o) UNWI_ARCH_OBJ(_mempool_free)(p,o) + +/* The mempool structure should be treated as an opaque object. It's + declared here only to enable static allocation of mempools. */ +struct mempool + { + pthread_mutex_t lock; + size_t obj_size; /* object size (rounded up for alignment) */ + size_t chunk_size; /* allocation granularity */ + unsigned int reserve; /* minimum (desired) size of the free-list */ + unsigned int num_free; /* number of objects on the free-list */ + struct object + { + struct object *next; + } + *free_list; + }; + +/* Emergency allocation for one-time stuff that doesn't fit the memory + pool model. A limited amount of memory is available in this + fashion and once allocated, there is no way to free it. */ +extern void *sos_alloc (size_t size); + +/* Initialize POOL for an object size of OBJECT_SIZE bytes. RESERVE + is the number of objects that should be reserved for use under + tight memory situations. If it is zero, mempool attempts to pick a + reasonable default value. */ +extern void mempool_init (struct mempool *pool, + size_t obj_size, size_t reserve); +extern void *mempool_alloc (struct mempool *pool); +extern void mempool_free (struct mempool *pool, void *object); + +#endif /* mempool_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/remote.h b/src/coreclr/src/pal/src/libunwind/include/remote.h new file mode 100644 index 00000000000000..064d6309adb7ec --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/remote.h @@ -0,0 +1,129 @@ +#ifndef REMOTE_H +#define REMOTE_H + +/* Helper functions for accessing (remote) memory. These functions + assume that all addresses are naturally aligned (e.g., 32-bit + quantity is stored at a 32-bit-aligned address. */ + +#ifdef UNW_LOCAL_ONLY + +static inline int +fetch8 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int8_t *valp, void *arg) +{ + *valp = *(int8_t *) (uintptr_t) *addr; + *addr += 1; + return 0; +} + +static inline int +fetch16 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int16_t *valp, void *arg) +{ + *valp = *(int16_t *) (uintptr_t) *addr; + *addr += 2; + return 0; +} + +static inline int +fetch32 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int32_t *valp, void *arg) +{ + *valp = *(int32_t *) (uintptr_t) *addr; + *addr += 4; + return 0; +} + +static inline int +fetchw (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_word_t *valp, void *arg) +{ + *valp = *(unw_word_t *) (uintptr_t) *addr; + *addr += sizeof (unw_word_t); + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +#define WSIZE (sizeof (unw_word_t)) + +static inline int +fetch8 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int8_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -WSIZE, 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*(WSIZE - 1 - off); +#endif + *valp = val & 0xff; + return ret; +} + +static inline int +fetch16 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int16_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; + int ret; + + if ((off & 0x1) != 0) + return -UNW_EINVAL; + + *addr += 2; + + ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + val >>= 8*off; +#else + val >>= 8*(WSIZE - 2 - off); +#endif + *valp = val & 0xffff; + return ret; +} + +static inline int +fetch32 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int32_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; + int ret; + + if ((off & 0x3) != 0) + return -UNW_EINVAL; + + *addr += 4; + + ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + val >>= 8*off; +#else + val >>= 8*(WSIZE - 4 - off); +#endif + *valp = val & 0xffffffff; + return ret; +} + +static inline int +fetchw (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_word_t *valp, void *arg) +{ + int ret; + + ret = (*a->access_mem) (as, *addr, valp, 0, arg); + *addr += WSIZE; + return ret; +} + +#endif /* !UNW_LOCAL_ONLY */ + +#endif /* REMOTE_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/dwarf-config.h new file mode 100644 index 00000000000000..f65db17ee65888 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/dwarf-config.h @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + 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 dwarf_config_h +#define dwarf_config_h + +/* This matches the value udes by GCC (see + gcc/config/aarch64/aarch64.h:DWARF_FRAME_REGISTERS. */ +#define DWARF_NUM_PRESERVED_REGS 97 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 0 + +#define dwarf_to_unw_regnum(reg) (((reg) <= UNW_AARCH64_V31) ? (reg) : 0) + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/jmpbuf.h new file mode 100644 index 00000000000000..3f01a442baf909 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/jmpbuf.h @@ -0,0 +1,33 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + 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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +/* FIXME for AArch64 */ + +#define JB_SP 13 +#define JB_RP 14 +#define JB_MASK_SAVED 15 +#define JB_MASK 16 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/libunwind_i.h new file mode 100644 index 00000000000000..b91273fa1c5525 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-aarch64/libunwind_i.h @@ -0,0 +1,320 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + 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 AARCH64_LIBUNWIND_I_H +#define AARCH64_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf64.h" +#include "mempool.h" +#include "dwarf.h" + +typedef enum + { + UNW_AARCH64_FRAME_STANDARD = -2, /* regular fp, sp +/- offset */ + UNW_AARCH64_FRAME_SIGRETURN = -1, /* special sigreturn frame */ + UNW_AARCH64_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */ + UNW_AARCH64_FRAME_GUESSED = 1 /* guessed it was regular, but not known */ + } +unw_tdep_frame_type_t; + +typedef struct + { + uint64_t virtual_address; + int64_t frame_type : 2; /* unw_tdep_frame_type_t classification */ + int64_t last_frame : 1; /* non-zero if last frame in chain */ + int64_t cfa_reg_sp : 1; /* cfa dwarf base register is sp vs. fp */ + int64_t cfa_reg_offset : 30; /* cfa is at this offset from base register value */ + int64_t fp_cfa_offset : 30; /* fp saved at this offset from cfa (-1 = not saved) */ + int64_t lr_cfa_offset : 30; /* lr saved at this offset from cfa (-1 = not saved) */ + int64_t sp_cfa_offset : 30; /* sp saved at this offset from cfa (-1 = not saved) */ + } +unw_tdep_frame_t; + +#ifdef UNW_LOCAL_ONLY + +typedef unw_word_t aarch64_loc_t; + +#else /* !UNW_LOCAL_ONLY */ + +typedef struct aarch64_loc + { + unw_word_t w0, w1; + } +aarch64_loc_t; + +#endif /* !UNW_LOCAL_ONLY */ + +struct unw_addr_space + { + struct unw_accessors acc; + int big_endian; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + unw_tdep_frame_t frame_info; /* quick tracing assist info */ + + enum + { + AARCH64_SCF_NONE, + AARCH64_SCF_LINUX_RT_SIGFRAME, + } + sigcontext_format; + unw_word_t sigcontext_addr; + unw_word_t sigcontext_sp; + unw_word_t sigcontext_pc; + int validate; + }; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_word_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_word_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + + + +#define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace) +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,frame) do {} while(0) +#define tdep_stash_frame UNW_OBJ(tdep_stash_frame) +#define tdep_trace UNW_OBJ(tdep_trace) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) ((as)->big_endian) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_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); +extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); +extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); +extern void tdep_stash_frame (struct dwarf_cursor *c, + struct dwarf_reg_state *rs); +extern int tdep_getcontext_trace (unw_tdep_context_t *); + +#endif /* AARCH64_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/dwarf-config.h new file mode 100644 index 00000000000000..f50228975ecbb6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/dwarf-config.h @@ -0,0 +1,51 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +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_config_h +#define dwarf_config_h + +/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not + explicitly defined. */ +#define DWARF_NUM_PRESERVED_REGS 128 + +#define dwarf_to_unw_regnum(reg) (((reg) < 16) ? (reg) : 0) + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 0 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/ex_tables.h b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/ex_tables.h new file mode 100644 index 00000000000000..9df5e0a9fa4b9b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/ex_tables.h @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright 2011 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 ARM_EX_TABLES_H +#define ARM_EX_TABLES_H + +typedef enum arm_exbuf_cmd { + ARM_EXIDX_CMD_FINISH, + ARM_EXIDX_CMD_DATA_PUSH, + ARM_EXIDX_CMD_DATA_POP, + ARM_EXIDX_CMD_REG_POP, + ARM_EXIDX_CMD_REG_TO_SP, + ARM_EXIDX_CMD_VFP_POP, + ARM_EXIDX_CMD_WREG_POP, + ARM_EXIDX_CMD_WCGR_POP, + ARM_EXIDX_CMD_RESERVED, + ARM_EXIDX_CMD_REFUSED, +} arm_exbuf_cmd_t; + +struct arm_exbuf_data +{ + arm_exbuf_cmd_t cmd; + uint32_t data; +}; + +#define arm_exidx_extract UNW_OBJ(arm_exidx_extract) +#define arm_exidx_decode UNW_OBJ(arm_exidx_decode) +#define arm_exidx_apply_cmd UNW_OBJ(arm_exidx_apply_cmd) + +int arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf); +int arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c); +int arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c); + +#endif // ARM_EX_TABLES_H diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/jmpbuf.h new file mode 100644 index 00000000000000..008e77f79600b7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/jmpbuf.h @@ -0,0 +1,32 @@ +/* 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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +/* FIXME for ARM! */ + +#define JB_SP 4 +#define JB_RP 5 +#define JB_MASK_SAVED 6 +#define JB_MASK 7 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h new file mode 100644 index 00000000000000..2602f41c4f79fc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-arm/libunwind_i.h @@ -0,0 +1,326 @@ +/* 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 ARM_LIBUNWIND_I_H +#define ARM_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" +#include "ex_tables.h" + +typedef enum + { + UNW_ARM_FRAME_SYSCALL = -3, /* r7 saved in r12, sp offset zero */ + UNW_ARM_FRAME_STANDARD = -2, /* regular r7, sp +/- offset */ + UNW_ARM_FRAME_SIGRETURN = -1, /* special sigreturn frame */ + UNW_ARM_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */ + UNW_ARM_FRAME_GUESSED = 1 /* guessed it was regular, but not known */ + } +unw_tdep_frame_type_t; + +typedef struct + { + uint32_t virtual_address; + int32_t frame_type : 3; /* unw_tdep_frame_type_t classification */ + int32_t last_frame : 1; /* non-zero if last frame in chain */ + int32_t cfa_reg_sp : 1; /* cfa dwarf base register is sp vs. r7 */ + int32_t cfa_reg_offset : 30; /* cfa is at this offset from base register value */ + int32_t r7_cfa_offset : 30; /* r7 saved at this offset from cfa (-1 = not saved) */ + int32_t lr_cfa_offset : 30; /* lr saved at this offset from cfa (-1 = not saved) */ + int32_t sp_cfa_offset : 30; /* sp saved at this offset from cfa (-1 = not saved) */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + int big_endian; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + unw_tdep_frame_t frame_info; /* quick tracing assist info */ + + enum + { + ARM_SCF_NONE, /* no signal frame */ + ARM_SCF_LINUX_SIGFRAME, /* non-RT signal frame, kernel >=2.6.18 */ + ARM_SCF_LINUX_RT_SIGFRAME, /* RT signal frame, kernel >=2.6.18 */ + ARM_SCF_LINUX_OLD_SIGFRAME, /* non-RT signal frame, kernel < 2.6.18 */ + ARM_SCF_LINUX_OLD_RT_SIGFRAME, /* RT signal frame, kernel < 2.6.18 */ + ARM_SCF_FREEBSD_SIGFRAME, /* FreeBSD sigframe */ + ARM_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall stub */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + unw_word_t sigcontext_sp; + unw_word_t sigcontext_pc; + int validate; + }; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_word_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_word_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +#define arm_find_proc_info UNW_OBJ(find_proc_info) +#define arm_put_unwind_info UNW_OBJ(put_unwind_info) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table UNW_OBJ(search_unwind_table) +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,frame) do {} while(0) +#define tdep_stash_frame UNW_OBJ(tdep_stash_frame) +#define tdep_trace UNW_OBJ(tdep_trace) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + arm_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + arm_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) ((as)->big_endian) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int arm_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, + void *arg); +extern void arm_put_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pi, void *arg); +extern int tdep_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); +extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); +extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); +extern void tdep_stash_frame (struct dwarf_cursor *c, + struct dwarf_reg_state *rs); + +/* unwinding method selection support */ +#define UNW_ARM_METHOD_ALL 0xFF +#define UNW_ARM_METHOD_DWARF 0x01 +#define UNW_ARM_METHOD_FRAME 0x02 +#define UNW_ARM_METHOD_EXIDX 0x04 + +#define unwi_unwind_method UNW_OBJ(unwind_method) +extern int unwi_unwind_method; + +#define UNW_TRY_METHOD(x) (unwi_unwind_method & x) + +#endif /* ARM_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/dwarf-config.h new file mode 100644 index 00000000000000..fb963c7d30778a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/dwarf-config.h @@ -0,0 +1,54 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +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_config_h +#define dwarf_config_h + +/* See DWARF_FRAME_REGNUM() macro in gcc/config/pa/pa32-regs.h: */ +#define dwarf_to_unw_regnum(reg) \ + (((reg) < DWARF_NUM_PRESERVED_REGS) ? (reg) : 0) + +/* This matches the value used by GCC (see + gcc/config/pa/pa32-regs.h:FIRST_PSEUDO_REGISTER), which leaves + plenty of room for expansion. */ +#define DWARF_NUM_PRESERVED_REGS 89 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 1 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/jmpbuf.h new file mode 100644 index 00000000000000..91f062ff7dffb6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/jmpbuf.h @@ -0,0 +1,33 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#ifndef JB_SP +# define JB_SP 19 +#endif +#define JB_RP 20 +#define JB_MASK_SAVED 21 +#define JB_MASK 22 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/libunwind_i.h new file mode 100644 index 00000000000000..72649aa3ecc559 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-hppa/libunwind_i.h @@ -0,0 +1,279 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 HPPA_LIBUNWIND_I_H +#define HPPA_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no hppa-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + HPPA_SCF_NONE, /* no signal frame encountered */ + HPPA_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + }; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_word_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_word_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,frame) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 1 + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_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); +extern void *tdep_uc_addr (ucontext_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +#endif /* HPPA_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/jmpbuf.h new file mode 100644 index 00000000000000..d642af2075a165 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/jmpbuf.h @@ -0,0 +1,32 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP and BSP: */ + +#define JB_SP 0 +#define JB_RP 8 +#define JB_BSP 17 +#define JB_MASK_SAVED 70 +#define JB_MASK 71 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/libunwind_i.h new file mode 100644 index 00000000000000..1d9770bab8564f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/libunwind_i.h @@ -0,0 +1,281 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 IA64_LIBUNWIND_I_H +#define IA64_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include "elf64.h" +#include "mempool.h" + +typedef struct + { + /* no ia64-specific fast trace */ + } +unw_tdep_frame_t; + +enum ia64_pregnum + { + /* primary unat: */ + IA64_REG_PRI_UNAT_GR, + IA64_REG_PRI_UNAT_MEM, + + /* memory stack (order matters: see build_script() */ + IA64_REG_PSP, /* previous memory stack pointer */ + /* register stack */ + IA64_REG_BSP, /* register stack pointer */ + IA64_REG_BSPSTORE, + IA64_REG_PFS, /* previous function state */ + IA64_REG_RNAT, + /* instruction pointer: */ + IA64_REG_IP, + + /* preserved registers: */ + IA64_REG_R4, IA64_REG_R5, IA64_REG_R6, IA64_REG_R7, + IA64_REG_NAT4, IA64_REG_NAT5, IA64_REG_NAT6, IA64_REG_NAT7, + IA64_REG_UNAT, IA64_REG_PR, IA64_REG_LC, IA64_REG_FPSR, + IA64_REG_B1, IA64_REG_B2, IA64_REG_B3, IA64_REG_B4, IA64_REG_B5, + IA64_REG_F2, IA64_REG_F3, IA64_REG_F4, IA64_REG_F5, + IA64_REG_F16, IA64_REG_F17, IA64_REG_F18, IA64_REG_F19, + IA64_REG_F20, IA64_REG_F21, IA64_REG_F22, IA64_REG_F23, + IA64_REG_F24, IA64_REG_F25, IA64_REG_F26, IA64_REG_F27, + IA64_REG_F28, IA64_REG_F29, IA64_REG_F30, IA64_REG_F31, + IA64_NUM_PREGS + }; + +#ifdef UNW_LOCAL_ONLY + +typedef unw_word_t ia64_loc_t; + +#else /* !UNW_LOCAL_ONLY */ + +typedef struct ia64_loc + { + unw_word_t w0, w1; + } +ia64_loc_t; + +#endif /* !UNW_LOCAL_ONLY */ + +#include "script.h" + +#define ABI_UNKNOWN 0 +#define ABI_LINUX 1 +#define ABI_HPUX 2 +#define ABI_FREEBSD 3 +#define ABI_OPENVMS 4 +#define ABI_NSK 5 /* Tandem/HP Non-Stop Kernel */ +#define ABI_WINDOWS 6 + +struct unw_addr_space + { + struct unw_accessors acc; + int big_endian; + int abi; /* abi < 0 => unknown, 0 => SysV, 1 => HP-UX, 2 => Windows */ + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ +#ifndef UNW_REMOTE_ONLY + unsigned long long shared_object_removals; +#endif + + struct ia64_script_cache global_cache; + }; + +/* Note: The ABI numbers in the ABI-markers (.unwabi directive) are + not the same as the above ABI numbers. */ +#define ABI_MARKER_OLD_LINUX_SIGTRAMP ((0 << 8) | 's') +#define ABI_MARKER_OLD_LINUX_INTERRUPT ((0 << 8) | 'i') +#define ABI_MARKER_HP_UX_SIGTRAMP ((1 << 8) | 1) +#define ABI_MARKER_LINUX_SIGTRAMP ((3 << 8) | 's') +#define ABI_MARKER_LINUX_INTERRUPT ((3 << 8) | 'i') + +struct cursor + { + void *as_arg; /* argument to address-space callbacks */ + unw_addr_space_t as; /* reference to per-address-space info */ + + /* IP, CFM, and predicate cache (these are always equal to the + values stored in ip_loc, cfm_loc, and pr_loc, + respectively). */ + unw_word_t ip; /* instruction pointer value */ + unw_word_t cfm; /* current frame mask */ + unw_word_t pr; /* current predicate values */ + + /* current frame info: */ + unw_word_t bsp; /* backing store pointer value */ + unw_word_t sp; /* stack pointer value */ + unw_word_t psp; /* previous sp value */ + ia64_loc_t cfm_loc; /* cfm save location (or NULL) */ + ia64_loc_t ec_loc; /* ar.ec save location (usually cfm_loc) */ + ia64_loc_t loc[IA64_NUM_PREGS]; + + unw_word_t eh_args[4]; /* exception handler arguments */ + unw_word_t sigcontext_addr; /* address of sigcontext or 0 */ + unw_word_t sigcontext_off; /* sigcontext-offset relative to signal sp */ + + short hint; + short prev_script; + + uint8_t nat_bitnr[4]; /* NaT bit numbers for r4-r7 */ + uint16_t abi_marker; /* abi_marker for current frame (if any) */ + uint16_t last_abi_marker; /* last abi_marker encountered so far */ + uint8_t eh_valid_mask; + + 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 */ + + /* In case of stack-discontiguities, such as those introduced by + signal-delivery on an alternate signal-stack (see + sigaltstack(2)), we use the following data-structure to keep + track of the register-backing-store areas across on which the + current frame may be backed up. Since there are at most 96 + stacked registers and since we only have to track the current + frame and only areas that are not empty, this puts an upper + limit on the # of backing-store areas we have to track. + + Note that the rbs-area indexed by rbs_curr identifies the + rbs-area that was in effect at the time AR.BSP had the value + c->bsp. However, this rbs area may not actually contain the + value in the register that c->bsp corresponds to because that + register may not have gotten spilled until much later, when a + possibly different rbs-area might have been in effect + already. */ + uint8_t rbs_curr; /* index of curr. rbs-area (contains c->bsp) */ + uint8_t rbs_left_edge; /* index of inner-most valid rbs-area */ + struct rbs_area + { + unw_word_t end; + unw_word_t size; + ia64_loc_t rnat_loc; + } + rbs_area[96 + 2]; /* 96 stacked regs + 1 extra stack on each side... */ +}; + +struct ia64_global_unwind_state + { + pthread_mutex_t lock; /* global data lock */ + + volatile char init_done; + + /* Table of registers that prologues can save (and order in which + they're saved). */ + const unsigned char save_order[8]; + + /* + * uc_addr() may return pointers to these variables. We need to + * make sure they don't get written via ia64_put() or + * ia64_putfp(). To make it possible to test for these variables + * quickly, we collect them in a single sub-structure. + */ + struct + { + unw_word_t r0; /* r0 is byte-order neutral */ + unw_fpreg_t f0; /* f0 is byte-order neutral */ + unw_fpreg_t f1_le, f1_be; /* f1 is byte-order dependent */ + } + read_only; + unw_fpreg_t nat_val_le, nat_val_be; + unw_fpreg_t int_val_le, int_val_be; + + struct mempool reg_state_pool; + struct mempool labeled_state_pool; + +# if UNW_DEBUG + const char *preg_name[IA64_NUM_PREGS]; +# endif + }; + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done unw.init_done +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table unw_search_ia64_unwind_table +#define tdep_find_unwind_table ia64_find_unwind_table +#define tdep_find_proc_info UNW_OBJ(find_proc_info) +#define tdep_uc_addr UNW_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,frame) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) +#define tdep_get_as(c) ((c)->as) +#define tdep_get_as_arg(c) ((c)->as_arg) +#define tdep_get_ip(c) ((c)->ip) +#define tdep_big_endian(as) ((c)->as->big_endian != 0) + +#ifndef UNW_LOCAL_ONLY +# define tdep_put_unwind_info UNW_OBJ(put_unwind_info) +#endif + +/* This can't be an UNW_ARCH_OBJ() because we need separate + unw.initialized flags for the local-only and generic versions of + the library. Also, if we wanted to have a single, shared global + data structure, we couldn't declare "unw" as HIDDEN. */ +#define unw UNW_OBJ(data) + +extern void tdep_init (void); +extern int tdep_find_unwind_table (struct elf_dyn_info *edi, + unw_addr_space_t as, char *path, + unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip); +extern int tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, + void *arg); +extern void tdep_put_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pi, void *arg); +extern void *tdep_uc_addr (ucontext_t *uc, unw_regnum_t regnum, + uint8_t *nat_bitnr); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +extern struct ia64_global_unwind_state unw; + +/* In user-level, we have no reasonable way of determining the base of + an arbitrary backing-store. We default to half the + address-space. */ +#define rbs_get_base(c,bspstore,rbs_basep) \ + (*(rbs_basep) = (bspstore) - (((unw_word_t) 1) << 63), 0) + +#endif /* IA64_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/rse.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/rse.h new file mode 100644 index 00000000000000..ee521a5917abf8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/rse.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 1998, 1999, 2002, 2003, 2005 Hewlett-Packard Co + * David Mosberger-Tang + * + * Register stack engine related helper functions. This file may be + * used in applications, so be careful about the name-space and give + * some consideration to non-GNU C compilers (though __inline__ is + * fine). + */ +#ifndef RSE_H +#define RSE_H + +#include + +static inline uint64_t +rse_slot_num (uint64_t addr) +{ + return (addr >> 3) & 0x3f; +} + +/* + * Return TRUE if ADDR is the address of an RNAT slot. + */ +static inline uint64_t +rse_is_rnat_slot (uint64_t addr) +{ + return rse_slot_num (addr) == 0x3f; +} + +/* + * Returns the address of the RNAT slot that covers the slot at + * address SLOT_ADDR. + */ +static inline uint64_t +rse_rnat_addr (uint64_t slot_addr) +{ + return slot_addr | (0x3f << 3); +} + +/* + * Calculate the number of registers in the dirty partition starting at + * BSPSTORE and ending at BSP. This isn't simply (BSP-BSPSTORE)/8 + * because every 64th slot stores ar.rnat. + */ +static inline uint64_t +rse_num_regs (uint64_t bspstore, uint64_t bsp) +{ + uint64_t slots = (bsp - bspstore) >> 3; + + return slots - (rse_slot_num(bspstore) + slots)/0x40; +} + +/* + * The inverse of the above: given bspstore and the number of + * registers, calculate ar.bsp. + */ +static inline uint64_t +rse_skip_regs (uint64_t addr, long num_regs) +{ + long delta = rse_slot_num(addr) + num_regs; + + if (num_regs < 0) + delta -= 0x3e; + return addr + ((num_regs + delta/0x3f) << 3); +} + +#endif /* RSE_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/script.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/script.h new file mode 100644 index 00000000000000..fe3360bf5829d3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-ia64/script.h @@ -0,0 +1,85 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 IA64_LOG_UNW_CACHE_SIZE 7 +#define IA64_UNW_CACHE_SIZE (1 << IA64_LOG_UNW_CACHE_SIZE) + +#define IA64_LOG_UNW_HASH_SIZE (IA64_LOG_UNW_CACHE_SIZE + 1) +#define IA64_UNW_HASH_SIZE (1 << IA64_LOG_UNW_HASH_SIZE) + +typedef unsigned char unw_hash_index_t; + +struct ia64_script_insn + { + unsigned int opc; /* see enum ia64_script_insn_opcode */ + unsigned int dst; + unw_word_t val; + }; + +/* Updating each preserved register may result in one script + instruction each. At the end of the script, psp gets popped, + accounting for one more instruction. */ +#define IA64_MAX_SCRIPT_LEN (IA64_NUM_PREGS + 1) + +struct ia64_script + { + unw_word_t ip; /* ip this script is for */ + unw_word_t pr_mask; /* mask of predicates script depends on */ + unw_word_t pr_val; /* predicate values this script is for */ + unw_proc_info_t pi; /* info about underlying procedure */ + unsigned short lru_chain; /* used for least-recently-used chain */ + unsigned short coll_chain; /* used for hash collisions */ + unsigned short hint; /* hint for next script to try (or -1) */ + unsigned short count; /* number of instructions in script */ + unsigned short abi_marker; + struct ia64_script_insn insn[IA64_MAX_SCRIPT_LEN]; + }; + +struct ia64_script_cache + { +#ifdef HAVE_ATOMIC_OPS_H + AO_TS_t busy; /* is the script-cache busy? */ +#else + pthread_mutex_t lock; +#endif + unsigned short lru_head; /* index of lead-recently used script */ + unsigned short lru_tail; /* index of most-recently used script */ + + /* hash table that maps instruction pointer to script index: */ + unsigned short hash[IA64_UNW_HASH_SIZE]; + + uint32_t generation; /* generation number */ + + /* script cache: */ + struct ia64_script buckets[IA64_UNW_CACHE_SIZE]; + }; + +#define ia64_cache_proc_info UNW_OBJ(cache_proc_info) +#define ia64_get_cached_proc_info UNW_OBJ(get_cached_proc_info) + +struct cursor; /* forward declaration */ + +extern int ia64_cache_proc_info (struct cursor *c); +extern int ia64_get_cached_proc_info (struct cursor *c); diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h new file mode 100644 index 00000000000000..74b821f5c0d70a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h @@ -0,0 +1,51 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +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_config_h +#define dwarf_config_h + +/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not + explicitly defined. */ +#define DWARF_NUM_PRESERVED_REGS 188 + +#define dwarf_to_unw_regnum(reg) (((reg) < 32) ? (reg) : 0) + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/jmpbuf.h new file mode 100644 index 00000000000000..c099f9267e204b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/jmpbuf.h @@ -0,0 +1,32 @@ +/* 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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +/* FIXME for MIPS! */ + +#define JB_SP 4 +#define JB_RP 5 +#define JB_MASK_SAVED 6 +#define JB_MASK 7 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h new file mode 100644 index 00000000000000..0c0fd3cf47eb3b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h @@ -0,0 +1,339 @@ +/* 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 MIPS_LIBUNWIND_I_H +#define MIPS_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#if !defined(UNW_REMOTE_ONLY) && _MIPS_SIM == _ABI64 +# include "elf64.h" +#else +# include "elf32.h" +#endif +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no mips-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + + int big_endian; + mips_abi_t abi; + unsigned int addr_size; + + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; +}; + +#define tdep_big_endian(as) ((as)->big_endian) + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + unw_word_t sigcontext_addr; + }; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifndef UNW_REMOTE_ONLY +# if _MIPS_SIM == _ABIN32 +typedef long long mips_reg_t; +# else +typedef long mips_reg_t; +# endif +#endif + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +/* FIXME: Implement these for the MIPS FPU. */ +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) (intptr_t) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) (intptr_t) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(mips_reg_t *) (intptr_t) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(mips_reg_t *) (intptr_t) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +read_s32 (struct dwarf_cursor *c, unw_word_t addr, unw_word_t *val) +{ + int offset = addr & 4; + int ret; + unw_word_t memval; + + ret = (*c->as->acc.access_mem) (c->as, addr - offset, &memval, 0, c->as_arg); + if (ret < 0) + return ret; + + if ((offset != 0) == tdep_big_endian (c->as)) + *val = (int32_t) memval; + else + *val = (int32_t) (memval >> 32); + + return 0; +} + +static inline int +write_s32 (struct dwarf_cursor *c, unw_word_t addr, const unw_word_t *val) +{ + int offset = addr & 4; + int ret; + unw_word_t memval; + + ret = (*c->as->acc.access_mem) (c->as, addr - offset, &memval, 0, c->as_arg); + if (ret < 0) + return ret; + + if ((offset != 0) == tdep_big_endian (c->as)) + memval = (memval & ~0xffffffffLL) | (uint32_t) *val; + else + memval = (memval & 0xffffffffLL) | (uint32_t) (*val << 32); + + return (*c->as->acc.access_mem) (c->as, addr - offset, &memval, 1, c->as_arg); +} + +/* FIXME: Implement these for the MIPS FPU. */ +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else if (c->as->abi == UNW_MIPS_ABI_O32) + return read_s32 (c, DWARF_GET_LOC (loc), val); + else if (c->as->abi == UNW_MIPS_ABI_N32) { + if (tdep_big_endian(c->as)) + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc) + 4, val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + } + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else if (c->as->abi == UNW_MIPS_ABI_O32) + return write_s32 (c, DWARF_GET_LOC (loc), &val); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,frame) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_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); +extern void *tdep_uc_addr (ucontext_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +#endif /* MIPS_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/dwarf-config.h new file mode 100644 index 00000000000000..bf6886b066b135 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/dwarf-config.h @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + 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 dwarf_config_h +#define dwarf_config_h + +/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */ +#define DWARF_NUM_PRESERVED_REGS 115 + +#define DWARF_REGNUM_MAP_LENGTH 115 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 1 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/jmpbuf.h new file mode 100644 index 00000000000000..861e94d9712fea --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/jmpbuf.h @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + 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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#define JB_SP 6 +#define JB_RP 7 +#define JB_MASK_SAVED 8 +#define JB_MASK 9 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/libunwind_i.h new file mode 100644 index 00000000000000..4cf6d135f63ff6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc32/libunwind_i.h @@ -0,0 +1,314 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + 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 PPC32_LIBUNWIND_I_H +#define PPC32_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no ppc32-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space +{ + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + int validate; +}; + +struct cursor +{ + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + PPC_SCF_NONE, /* no signal frame encountered */ + PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ + } + sigcontext_format; + unw_word_t sigcontext_addr; +}; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_IS_FP_LOC(l) 0 +# define DWARF_IS_V_LOC(l) 0 +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +#else /* !UNW_LOCAL_ONLY */ + +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_LOC_TYPE_V (1 << 2) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) +# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_V)) + +#endif /* !UNW_LOCAL_ONLY */ + +static inline int +dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + unw_word_t *valp = (unw_word_t *) val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_V_LOC (loc)); + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg); +} + +static inline int +dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + unw_word_t *valp = (unw_word_t *) & val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_V_LOC (loc)); + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg); +} + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + unw_word_t *valp = (unw_word_t *) val; + unw_word_t addr; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg); + +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + unw_word_t *valp = (unw_word_t *) & val; + unw_word_t addr; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + + return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,frame) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) +#define tdep_get_func_addr UNW_OBJ(get_func_addr) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip, + int need_unwind_info); + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 1 + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_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); +extern void *tdep_uc_addr (ucontext_t * uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t * valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t * valp, int write); +extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, + unw_word_t *entry_point); + +#endif /* PPC64_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/dwarf-config.h new file mode 100644 index 00000000000000..6d8ef0a9404749 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/dwarf-config.h @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + 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 dwarf_config_h +#define dwarf_config_h + +/* For PPC64, 48 GPRs + 33 FPRs + 33 AltiVec + 1 SPE */ +#define DWARF_NUM_PRESERVED_REGS 115 + +#define DWARF_REGNUM_MAP_LENGTH 115 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/jmpbuf.h new file mode 100644 index 00000000000000..861e94d9712fea --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/jmpbuf.h @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + 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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#define JB_SP 6 +#define JB_RP 7 +#define JB_MASK_SAVED 8 +#define JB_MASK 9 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/libunwind_i.h new file mode 100644 index 00000000000000..975f3bb3662add --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-ppc64/libunwind_i.h @@ -0,0 +1,369 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + + Copied from libunwind-x86_64.h, modified slightly for building + frysk successfully on ppc64, by Wu Zhou + 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 PPC64_LIBUNWIND_I_H +#define PPC64_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf64.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no ppc64-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space +{ + struct unw_accessors acc; + int big_endian; + ppc64_abi_t abi; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + int validate; +}; + +struct cursor +{ + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + PPC_SCF_NONE, /* no signal frame encountered */ + PPC_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */ + } + sigcontext_format; + unw_word_t sigcontext_addr; +}; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_VREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +static inline int +dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_word_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_word_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_LOC_TYPE_V (1 << 2) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_IS_V_LOC(l) (((l).type & DWARF_LOC_TYPE_V) != 0) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) +# define DWARF_VREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_V)) + +static inline int +dwarf_getvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + unw_word_t *valp = (unw_word_t *) val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_V_LOC (loc)); + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 0, c->as_arg); +} + +static inline int +dwarf_putvr (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + unw_word_t *valp = (unw_word_t *) & val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_V_LOC (loc)); + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, valp + 1, 1, c->as_arg); +} + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t * val) +{ + unw_word_t *valp = (unw_word_t *) val; + unw_word_t addr; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 0, c->as_arg); + +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + unw_word_t *valp = (unw_word_t *) & val; + unw_word_t addr; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + assert (DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + + return (*c->as->acc.access_mem) (c->as, addr + 0, valp, 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t * val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + assert (!DWARF_IS_V_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,frame) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) +#define tdep_get_func_addr UNW_OBJ(get_func_addr) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +extern int tdep_fetch_proc_info_post (struct dwarf_cursor *c, unw_word_t ip, + int need_unwind_info); + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) ((as)->big_endian) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_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); +extern void *tdep_uc_addr (ucontext_t * uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t * valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t * valp, int write); +extern int tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, + unw_word_t *entry_point); + +#endif /* PPC64_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h new file mode 100644 index 00000000000000..ca419bd52acdd3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +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. */ + +/* copy of include/tdep-x86/dwarf-config.h, modified slightly for x86-64 + some consolidation is possible here */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* derived from DWARF register mappings in Z ELF ABI */ +#define DWARF_NUM_PRESERVED_REGS 66 +#define DWARF_REGNUM_MAP_LENGTH DWARF_NUM_PRESERVED_REGS + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 1 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; + unw_word_t type; /* see S390X_LOC_TYPE_* macros. */ + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h new file mode 100644 index 00000000000000..509237525553a1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +#if defined __linux__ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#define JB_SP 9 // __gregs[9] +#define JB_RP 8 // __gregs[8] +#define JB_MASK_SAVED 18 // __mask_was_saved +#define JB_MASK 19 // __saved_mask + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h new file mode 100644 index 00000000000000..137a0b8a4f9282 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h @@ -0,0 +1,262 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +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 S390X_LIBUNWIND_I_H +#define S390X_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf64.h" +#include "mempool.h" +#include "dwarf.h" + +struct unw_addr_space + { + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + S390X_SCF_NONE = 0, /* no signal frame encountered */ + S390X_SCF_LINUX_SIGFRAME = 1, /* Linux struct sigcontext */ + S390X_SCF_LINUX_RT_SIGFRAME = 2, /* Linux ucontext_t */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + unw_word_t sigcontext_sp; + unw_word_t sigcontext_pc; + int validate; + ucontext_t *uc; + }; + +static inline ucontext_t * +dwarf_get_uc(const struct dwarf_cursor *cursor) +{ + const struct cursor *c = (struct cursor *) cursor->as_arg; + return c->uc; +} + +#define DWARF_GET_LOC(l) ((l).val) +# define DWARF_LOC_TYPE_MEM (0 << 0) +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_LOC_TYPE_VAL (1 << 2) + +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_IS_MEM_LOC(l) ((l).type == DWARF_LOC_TYPE_MEM) +# define DWARF_IS_VAL_LOC(l) (((l).type & DWARF_LOC_TYPE_VAL) != 0) + +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_VAL_LOC(c,v) DWARF_LOC ((v), DWARF_LOC_TYPE_VAL) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), DWARF_LOC_TYPE_MEM) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) + +#else /* !UNW_LOCAL_ONLY */ + +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +#endif /* !UNW_LOCAL_ONLY */ + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_FP_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + /* FPRs may be saved in GPRs */ + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), (unw_word_t*)val, + 0, c->as_arg); + if (DWARF_IS_MEM_LOC (loc)) + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), (unw_word_t*)val, + 0, c->as_arg); + assert(DWARF_IS_VAL_LOC (loc)); + *val = *(unw_fpreg_t*) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); + assert(!DWARF_IS_VAL_LOC (loc)); + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_FP_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + /* FPRs may be saved in GPRs */ + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), (unw_word_t*) &val, + 1, c->as_arg); + + assert(DWARF_IS_MEM_LOC (loc)); + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), (unw_word_t*) &val, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + if (DWARF_IS_MEM_LOC (loc)) + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + /* GPRs may be saved in FPRs */ + if (DWARF_IS_FP_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), (unw_fpreg_t*)val, + 0, c->as_arg); + assert(DWARF_IS_VAL_LOC (loc)); + *val = DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); + assert(!DWARF_IS_VAL_LOC (loc)); + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + /* GPRs may be saved in FPRs */ + if (DWARF_IS_FP_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), (unw_fpreg_t*) &val, + 1, c->as_arg); + + assert(DWARF_IS_MEM_LOC (loc)); + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame(cs,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) +#define tdep_uc_addr UNW_OBJ(uc_addr) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 1 + +extern int tdep_init_done; + +extern void tdep_init (void); +extern void tdep_init_mem_validate (void); +extern int tdep_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); +extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +#endif /* S390X_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-sh/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-sh/dwarf-config.h new file mode 100644 index 00000000000000..2f76f5be7f4c3b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-sh/dwarf-config.h @@ -0,0 +1,49 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +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_config_h +#define dwarf_config_h + +#define DWARF_NUM_PRESERVED_REGS 18 + +#define dwarf_to_unw_regnum(reg) (((reg) <= UNW_SH_PR) ? (reg) : 0) + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-sh/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-sh/jmpbuf.h new file mode 100644 index 00000000000000..8b44b5b219a289 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-sh/jmpbuf.h @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +/* SH4 glibc jump buffer contents: + * 0. r8 + * 1. r9 + * 2. r10 + * 3. r11 + * 4. r12 + * 5. r13 + * 6. r14 + * 7. r15 + * 8. pr/pc + * 9. gbr + * 10. fpscr + * 11. fr12 + * 12. fr13 + * 13. fr14 + * 14. fr15 + */ + +#define JB_SP 7 +#define JB_RP 8 +#define JB_MASK_SAVED 15 +#define JB_MASK 16 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-sh/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-sh/libunwind_i.h new file mode 100644 index 00000000000000..8ced49104b5c82 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-sh/libunwind_i.h @@ -0,0 +1,280 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +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 SH_LIBUNWIND_I_H +#define SH_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no sh-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + int big_endian; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + enum + { + SH_SCF_NONE, /* no signal frame */ + SH_SCF_LINUX_SIGFRAME, /* non-RT signal frame */ + SH_SCF_LINUX_RT_SIGFRAME, /* RT signal frame */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + unw_word_t sigcontext_sp; + unw_word_t sigcontext_pc; + }; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_word_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_word_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,frame) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) ((as)->big_endian) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_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); +extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +#endif /* SH_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/dwarf-config.h new file mode 100644 index 00000000000000..93bc6aaecced65 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/dwarf-config.h @@ -0,0 +1,50 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +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_config_h +#define dwarf_config_h + +/* This is FIRST_PSEUDO_REGISTER in GCC, since DWARF_FRAME_REGISTERS is not + explicitly defined. */ +#define DWARF_NUM_PRESERVED_REGS 188 + +#define DWARF_REGNUM_MAP_LENGTH (56 + 2) + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc +{ + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see DWARF_LOC_TYPE_* macros. */ +#endif +} dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/jmpbuf.h new file mode 100644 index 00000000000000..3afe9e46cc499a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/jmpbuf.h @@ -0,0 +1,33 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +/* FIXME for Tilegx! */ + +#define JB_SP 4 +#define JB_RP 5 +#define JB_MASK_SAVED 6 +#define JB_MASK 7 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/libunwind_i.h new file mode 100644 index 00000000000000..2cfed456a70fdd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-tilegx/libunwind_i.h @@ -0,0 +1,263 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +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 TILEGX_LIBUNWIND_I_H +#define TILEGX_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +# include "elf64.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct +{ + /* no Tilegx-specific fast trace */ +} unw_tdep_frame_t; + +struct unw_addr_space +{ + struct unw_accessors acc; + + int big_endian; + tilegx_abi_t abi; + unsigned int addr_size; + + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; +}; + +#define tdep_big_endian(as) ((as)->big_endian) + +struct cursor +{ + struct dwarf_cursor dwarf; /* must be first */ + unw_word_t sigcontext_addr; + unw_word_t sigcontext_sp; + unw_word_t sigcontext_pc; +}; + +#define DWARF_GET_LOC(l) ((l).val) + +#ifndef UNW_REMOTE_ONLY +typedef long tilegx_reg_t; +#endif + +#ifdef UNW_LOCAL_ONLY +#define DWARF_NULL_LOC DWARF_LOC (0, 0) +#define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +#define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +#define DWARF_IS_REG_LOC(l) 0 +#define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) +#define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +#define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) (intptr_t) \ + tdep_uc_addr((c)->as_arg, (r)), 0)) + +/* Tilegx has no FP. */ +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + Debug (1, "Tielgx has no fp!\n"); + abort(); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + Debug (1, "Tielgx has no fp!\n"); + abort(); + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + + *val = *(tilegx_reg_t *) (intptr_t) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + + *(tilegx_reg_t *) (intptr_t) DWARF_GET_LOC (loc) = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ +#define DWARF_LOC_TYPE_FP (1 << 0) +#define DWARF_LOC_TYPE_REG (1 << 1) +#define DWARF_NULL_LOC DWARF_LOC (0, 0) +#define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +#define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +#define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +#define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +#define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +#define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +#define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +/* TILEGX has no fp. */ +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + Debug (1, "Tielgx has no fp!\n"); + abort(); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + Debug (1, "Tielgx has no fp!\n"); + abort(); + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_needs_initialization UNW_OBJ(needs_initialization) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,frame) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) + +#ifdef UNW_LOCAL_ONLY +#define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +#define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +#define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +#define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_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); +extern void *tdep_uc_addr (ucontext_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, + pid_t pid, unw_word_t ip, + unsigned long *segbase, + unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, + unw_regnum_t reg, + unw_word_t *valp, + int write); +extern int tdep_access_fpreg (struct cursor *c, + unw_regnum_t reg, + unw_fpreg_t *valp, + int write); + +#endif /* TILEGX_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86/dwarf-config.h new file mode 100644 index 00000000000000..f76f9c1c4eb2fe --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86/dwarf-config.h @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +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_config_h +#define dwarf_config_h + +/* This matches the value used by GCC (see + gcc/config/i386.h:DWARF_FRAME_REGISTERS), which leaves plenty of + room for expansion. */ +#define DWARF_NUM_PRESERVED_REGS 17 + +#define DWARF_REGNUM_MAP_LENGTH 19 + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 0 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; +#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ +#endif + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86/jmpbuf.h new file mode 100644 index 00000000000000..521dfa6992b36e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86/jmpbuf.h @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#if defined __linux__ + +#define JB_SP 4 +#define JB_RP 5 +#define JB_MASK_SAVED 6 +#define JB_MASK 7 + +#elif defined __FreeBSD__ + +#define JB_SP 2 +#define JB_RP 0 +#define JB_MASK_SAVED 11 +#define JB_MASK 7 + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86/libunwind_i.h new file mode 100644 index 00000000000000..5231189a499c16 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86/libunwind_i.h @@ -0,0 +1,293 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 X86_LIBUNWIND_I_H +#define X86_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf32.h" +#include "mempool.h" +#include "dwarf.h" + +typedef struct + { + /* no x86-specific fast trace */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + X86_SCF_NONE, /* no signal frame encountered */ + X86_SCF_LINUX_SIGFRAME, /* Linux x86 sigcontext */ + X86_SCF_LINUX_RT_SIGFRAME, /* POSIX ucontext_t */ + X86_SCF_FREEBSD_SIGFRAME, /* FreeBSD x86 sigcontext */ + X86_SCF_FREEBSD_SIGFRAME4, /* FreeBSD 4.x x86 sigcontext */ + X86_SCF_FREEBSD_OSIGFRAME, /* FreeBSD pre-4.x x86 sigcontext */ + X86_SCF_FREEBSD_SYSCALL, /* FreeBSD x86 syscall */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + int validate; + ucontext_t *uc; + }; + +static inline ucontext_t * +dwarf_get_uc(const struct dwarf_cursor *cursor) +{ + const struct cursor *c = (struct cursor *) cursor->as_arg; + return c->uc; +} + +#define DWARF_GET_LOC(l) ((l).val) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +# define DWARF_IS_REG_LOC(l) 0 +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val; + return 0; +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (!DWARF_GET_LOC (loc)) + return -1; + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#else /* !UNW_LOCAL_ONLY */ +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + val, 0, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 0, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0, + c->as_arg); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + char *valp = (char *) &val; + unw_word_t addr; + int ret; + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), + &val, 1, c->as_arg); + + addr = DWARF_GET_LOC (loc); + if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp, + 1, c->as_arg)) < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + /* If a code-generator were to save a value of type unw_word_t in a + floating-point register, we would have to support this case. I + suppose it could happen with MMX registers, but does it really + happen? */ + assert (!DWARF_IS_FP_LOC (loc)); + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr) +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,frame) do {} while(0) +#define tdep_stash_frame(c,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 0 + +extern int tdep_init_done; + +extern void tdep_init (void); +extern int tdep_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); +extern void *tdep_uc_addr (ucontext_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +#endif /* X86_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/dwarf-config.h new file mode 100644 index 00000000000000..ff77808e069464 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/dwarf-config.h @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +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. */ + +/* copy of include/tdep-x86/dwarf-config.h, modified slightly for x86-64 + some consolidation is possible here */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* XXX need to verify if this value is correct */ +#ifdef CONFIG_MSABI_SUPPORT +#define DWARF_NUM_PRESERVED_REGS 33 +#else +#define DWARF_NUM_PRESERVED_REGS 17 +#endif + +#define DWARF_REGNUM_MAP_LENGTH DWARF_NUM_PRESERVED_REGS + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 0 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h new file mode 100644 index 00000000000000..b2e5332b059661 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h @@ -0,0 +1,44 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +#if defined __linux__ || defined __sun + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: + https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=sysdeps/x86_64/jmpbuf-offsets.h;h=ea94a1f90554deecceaf995ca5ee485ae8bffab7;hb=HEAD */ + +#define JB_SP 6 +#define JB_RP 7 +#define JB_MASK_SAVED 8 +#define JB_MASK 9 + +#elif defined __FreeBSD__ + +#define JB_SP 2 +#define JB_RP 0 +/* Pretend the ip cannot be 0 and mask is always saved */ +#define JB_MASK_SAVED 0 +#define JB_MASK 9 + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h new file mode 100644 index 00000000000000..6b798c7115f3c9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h @@ -0,0 +1,269 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +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 X86_64_LIBUNWIND_I_H +#define X86_64_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf64.h" +#include "mempool.h" +#include "dwarf.h" + +typedef enum + { + UNW_X86_64_FRAME_ALIGNED = -3, /* frame stack pointer aligned */ + UNW_X86_64_FRAME_STANDARD = -2, /* regular rbp, rsp +/- offset */ + UNW_X86_64_FRAME_SIGRETURN = -1, /* special sigreturn frame */ + UNW_X86_64_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */ + UNW_X86_64_FRAME_GUESSED = 1 /* guessed it was regular, but not known */ + } +unw_tdep_frame_type_t; + +typedef struct + { + uint64_t virtual_address; + int64_t frame_type : 3; /* unw_tdep_frame_type_t classification */ + int64_t last_frame : 1; /* non-zero if last frame in chain */ + int64_t cfa_reg_rsp : 1; /* cfa dwarf base register is rsp vs. rbp */ + int64_t cfa_reg_offset : 29; /* cfa is at this offset from base register value */ + int64_t rbp_cfa_offset : 15; /* rbp saved at this offset from cfa (-1 = not saved) */ + int64_t rsp_cfa_offset : 15; /* rsp saved at this offset from cfa (-1 = not saved) */ + } +unw_tdep_frame_t; + +struct unw_addr_space + { + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + unw_tdep_frame_t frame_info; /* quick tracing assist info */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + X86_64_SCF_NONE, /* no signal frame encountered */ + X86_64_SCF_LINUX_RT_SIGFRAME, /* Linux ucontext_t */ + X86_64_SCF_FREEBSD_SIGFRAME, /* FreeBSD signal frame */ + X86_64_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall */ + X86_64_SCF_SOLARIS_SIGFRAME, /* illumos/Solaris signal frame */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + int validate; + ucontext_t *uc; + }; + +static inline ucontext_t * +dwarf_get_uc(const struct dwarf_cursor *cursor) +{ + const struct cursor *c = (struct cursor *) cursor->as_arg; + return c->uc; +} + +#define DWARF_GET_LOC(l) ((l).val) +# define DWARF_LOC_TYPE_MEM (0 << 0) +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_LOC_TYPE_VAL (1 << 2) + +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_IS_MEM_LOC(l) ((l).type == DWARF_LOC_TYPE_MEM) +# define DWARF_IS_VAL_LOC(l) (((l).type & DWARF_LOC_TYPE_VAL) != 0) + +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_VAL_LOC(c,v) DWARF_LOC ((v), DWARF_LOC_TYPE_VAL) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), DWARF_LOC_TYPE_MEM) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0)) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + x86_64_r_uc_addr(dwarf_get_uc(c), (r)), 0)) + +#else /* !UNW_LOCAL_ONLY */ + +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +#endif /* !UNW_LOCAL_ONLY */ + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + abort (); +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + abort (); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + if (DWARF_IS_MEM_LOC (loc)) + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + assert(DWARF_IS_VAL_LOC (loc)); + *val = DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + assert(!DWARF_IS_VAL_LOC (loc)); + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace) +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#if __linux__ +# define tdep_fetch_frame UNW_OBJ(fetch_frame) +# define tdep_cache_frame UNW_OBJ(cache_frame) +# define tdep_reuse_frame UNW_OBJ(reuse_frame) +#else +# define tdep_fetch_frame(c,ip,n) do {} while(0) +# define tdep_cache_frame(c) 0 +# define tdep_reuse_frame(c,frame) do {} while(0) +#endif +#define tdep_stash_frame UNW_OBJ(stash_frame) +#define tdep_trace UNW_OBJ(tdep_trace) +#define x86_64_r_uc_addr UNW_OBJ(r_uc_addr) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 0 + +#ifdef HAVE_ATOMIC_OPS_H +extern AO_t tdep_init_done; +#else +extern int tdep_init_done; +#endif + +extern void tdep_init (void); +extern void tdep_init_mem_validate (void); +extern int tdep_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); +extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); +#if __linux__ +extern void tdep_fetch_frame (struct dwarf_cursor *c, unw_word_t ip, + int need_unwind_info); +extern int tdep_cache_frame (struct dwarf_cursor *c); +extern void tdep_reuse_frame (struct dwarf_cursor *c, + int frame); +extern void tdep_stash_frame (struct dwarf_cursor *c, + struct dwarf_reg_state *rs); +#endif + +extern int tdep_getcontext_trace (unw_tdep_context_t *); +extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n); + +#endif /* X86_64_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep/dwarf-config.h new file mode 100644 index 00000000000000..c759a46c63b9da --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep/dwarf-config.h @@ -0,0 +1,28 @@ +/* Provide a real file - not a symlink - as it would cause multiarch conflicts + when multiple different arch releases are installed simultaneously. */ + +#if defined __aarch64__ +# include "tdep-aarch64/dwarf-config.h" +#elif defined __arm__ +# include "tdep-arm/dwarf-config.h" +#elif defined __hppa__ +# include "tdep-hppa/dwarf-config.h" +#elif defined __ia64__ +# include "tdep-ia64/dwarf-config.h" +#elif defined __mips__ +# include "tdep-mips/dwarf-config.h" +#elif defined __powerpc__ && !defined __powerpc64__ +# include "tdep-ppc32/dwarf-config.h" +#elif defined __powerpc64__ +# include "tdep-ppc64/dwarf-config.h" +#elif defined __sh__ +# include "tdep-sh/dwarf-config.h" +#elif defined __i386__ +# include "tdep-x86/dwarf-config.h" +#elif defined __x86_64__ || defined __amd64__ +# include "tdep-x86_64/dwarf-config.h" +#elif defined __tilegx__ +# include "tdep-tilegx/dwarf-config.h" +#else +# error "Unsupported arch" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep/jmpbuf.h new file mode 100644 index 00000000000000..13093a0cdc3fa0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep/jmpbuf.h @@ -0,0 +1,30 @@ +/* Provide a real file - not a symlink - as it would cause multiarch conflicts + when multiple different arch releases are installed simultaneously. */ + +#ifndef UNW_REMOTE_ONLY + +#if defined __aarch64__ +# include "tdep-aarch64/jmpbuf.h" +#elif defined __arm__ +# include "tdep-arm/jmpbuf.h" +#elif defined __hppa__ +# include "tdep-hppa/jmpbuf.h" +#elif defined __ia64__ +# include "tdep-ia64/jmpbuf.h" +#elif defined __mips__ +# include "tdep-mips/jmpbuf.h" +#elif defined __powerpc__ && !defined __powerpc64__ +# include "tdep-ppc32/jmpbuf.h" +#elif defined __powerpc64__ +# include "tdep-ppc64/jmpbuf.h" +#elif defined __i386__ +# include "tdep-x86/jmpbuf.h" +#elif defined __x86_64__ +# include "tdep-x86_64/jmpbuf.h" +#elif defined __tilegx__ +# include "tdep-tilegx/jmpbuf.h" +#else +# error "Unsupported arch" +#endif + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in b/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in new file mode 100644 index 00000000000000..c47299640e8e66 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in @@ -0,0 +1,39 @@ +/* Provide a real file - not a symlink - as it would cause multiarch conflicts + when multiple different arch releases are installed simultaneously. */ + +#ifndef UNW_REMOTE_ONLY + +#if defined __aarch64__ +# include "tdep-aarch64/libunwind_i.h" +#elif defined __arm__ +# include "tdep-arm/libunwind_i.h" +#elif defined __hppa__ +# include "tdep-hppa/libunwind_i.h" +#elif defined __ia64__ +# include "tdep-ia64/libunwind_i.h" +#elif defined __mips__ +# include "tdep-mips/libunwind_i.h" +#elif defined __powerpc__ && !defined __powerpc64__ +# include "tdep-ppc32/libunwind_i.h" +#elif defined __powerpc64__ +# include "tdep-ppc64/libunwind_i.h" +#elif defined __sh__ +# include "tdep-sh/libunwind_i.h" +#elif defined __i386__ +# include "tdep-x86/libunwind_i.h" +#elif defined __x86_64__ +# include "tdep-x86_64/libunwind_i.h" +#elif defined __tilegx__ +# include "tdep-tilegx/libunwind_i.h" +#elif defined __s390x__ +# include "tdep-s390x/libunwind_i.h" +#else +# error "Unsupported arch" +#endif + + +#else /* UNW_REMOTE_ONLY */ + +# include "tdep-@arch@/libunwind_i.h" + +#endif /* UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/include/unwind.h b/src/coreclr/src/pal/src/libunwind/include/unwind.h new file mode 100644 index 00000000000000..7cf128deca3079 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/unwind.h @@ -0,0 +1,154 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 _UNWIND_H +#define _UNWIND_H + +/* For uint64_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Minimal interface as per C++ ABI draft standard: + + http://www.codesourcery.com/cxx-abi/abi-eh.html */ + +typedef enum + { + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8 + } +_Unwind_Reason_Code; + +typedef int _Unwind_Action; + +#define _UA_SEARCH_PHASE 1 +#define _UA_CLEANUP_PHASE 2 +#define _UA_HANDLER_FRAME 4 +#define _UA_FORCE_UNWIND 8 + +struct _Unwind_Context; /* opaque data-structure */ +struct _Unwind_Exception; /* forward-declaration */ + +typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, + struct _Unwind_Exception *); + +typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int, _Unwind_Action, + uint64_t, + struct _Unwind_Exception *, + struct _Unwind_Context *, + void *); + +/* The C++ ABI requires exception_class, private_1, and private_2 to + be of type uint64 and the entire structure to be + double-word-aligned. Please note that exception_class stays 64-bit + even on 32-bit machines for gcc compatibility. */ +struct _Unwind_Exception + { + uint64_t exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + unsigned long private_1; + unsigned long private_2; + } __attribute__((__aligned__)); + +extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, + _Unwind_Stop_Fn, void *); +extern void _Unwind_Resume (struct _Unwind_Exception *); +extern void _Unwind_DeleteException (struct _Unwind_Exception *); +extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int); +extern void _Unwind_SetGR (struct _Unwind_Context *, int, unsigned long); +extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); +extern unsigned long _Unwind_GetIPInfo (struct _Unwind_Context *, int *); +extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned long); +extern unsigned long _Unwind_GetLanguageSpecificData (struct _Unwind_Context*); +extern unsigned long _Unwind_GetRegionStart (struct _Unwind_Context *); + +#ifdef _GNU_SOURCE + +/* Callback for _Unwind_Backtrace(). The backtrace stops immediately + if the callback returns any value other than _URC_NO_REASON. */ +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *, + void *); + +/* See http://gcc.gnu.org/ml/gcc-patches/2001-09/msg00082.html for why + _UA_END_OF_STACK exists. */ +# define _UA_END_OF_STACK 16 + +/* If the unwind was initiated due to a forced unwind, resume that + operation, else re-raise the exception. This is used by + __cxa_rethrow(). */ +extern _Unwind_Reason_Code + _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); + +/* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why + _Unwind_GetBSP() exists. */ +extern unsigned long _Unwind_GetBSP (struct _Unwind_Context *); + +/* Return the "canonical frame address" for the given context. + This is used by NPTL... */ +extern unsigned long _Unwind_GetCFA (struct _Unwind_Context *); + +/* Return the base-address for data references. */ +extern unsigned long _Unwind_GetDataRelBase (struct _Unwind_Context *); + +/* Return the base-address for text references. */ +extern unsigned long _Unwind_GetTextRelBase (struct _Unwind_Context *); + +/* Call _Unwind_Trace_Fn once for each stack-frame, without doing any + cleanup. The first frame for which the callback is invoked is the + one for the caller of _Unwind_Backtrace(). _Unwind_Backtrace() + returns _URC_END_OF_STACK when the backtrace stopped due to + reaching the end of the call-chain or _URC_FATAL_PHASE1_ERROR if it + stops for any other reason. */ +extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); + +/* Find the start-address of the procedure containing the specified IP + or NULL if it cannot be found (e.g., because the function has no + unwind info). Note: there is not necessarily a one-to-one + correspondence between source-level functions and procedures: some + functions don't have unwind-info and others are split into multiple + procedures. */ +extern void *_Unwind_FindEnclosingFunction (void *); + +/* See also Linux Standard Base Spec: + http://www.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/libgcc-s.html */ + +#endif /* _GNU_SOURCE */ + +#ifdef __cplusplus +}; +#endif + +#endif /* _UNWIND_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/x86/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/x86/jmpbuf.h new file mode 100644 index 00000000000000..94d5984f08c496 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/x86/jmpbuf.h @@ -0,0 +1,31 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#define JB_SP 4 +#define JB_RP 5 +#define JB_MASK_SAVED 6 +#define JB_MASK 7 diff --git a/src/coreclr/src/pal/src/libunwind/scripts/kernel-diff.sh b/src/coreclr/src/pal/src/libunwind/scripts/kernel-diff.sh new file mode 100755 index 00000000000000..459194e15a31c7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/scripts/kernel-diff.sh @@ -0,0 +1,10 @@ +kdir=${1:-../kernel} +scriptdir=$(dirname $0) +udir=$(dirname $scriptdir) +cat $scriptdir/kernel-files.txt | \ +(while read l r; do + left=$(eval echo $l) + right=$(eval echo $r) +# echo $left $right + diff -up $left $right +done) diff --git a/src/coreclr/src/pal/src/libunwind/scripts/kernel-files.txt b/src/coreclr/src/pal/src/libunwind/scripts/kernel-files.txt new file mode 100644 index 00000000000000..d79e453a33ac7a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/scripts/kernel-files.txt @@ -0,0 +1,19 @@ +$udir/include/tdep-ia64/rse.h $kdir/arch/ia64/unwind/rse.h +$udir/src/ia64/Ginit_local.c $kdir/arch/ia64/unwind/init_local.c +$udir/src/ia64/Gis_signal_frame.c $kdir/arch/ia64/unwind/is_signal_frame.c +$udir/src/ia64/Gparser.c $kdir/arch/ia64/unwind/parser.c +$udir/src/ia64/Grbs.c $kdir/arch/ia64/unwind/rbs.c +$udir/src/ia64/Gregs.c $kdir/arch/ia64/unwind/regs.c +$udir/src/ia64/Gscript.c $kdir/arch/ia64/unwind/script.c +$udir/src/ia64/Gstep.c $kdir/arch/ia64/unwind/step.c +$udir/src/ia64/init.h $kdir/arch/ia64/unwind/init.h +$udir/src/ia64/offsets.h $kdir/arch/ia64/unwind/offsets.h +$udir/src/ia64/regname.c $kdir/arch/ia64/unwind/regname.c +$udir/src/ia64/regs.h $kdir/arch/ia64/unwind/regs.h +$udir/src/ia64/unwind_decoder.h $kdir/arch/ia64/unwind/unwind_decoder.h +$udir/src/mi/Gget_fpreg.c $kdir/unwind/get_fpreg.c +$udir/src/mi/Gget_reg.c $kdir/unwind/get_reg.c +$udir/src/mi/Gset_fpreg.c $kdir/unwind/set_fpreg.c +$udir/src/mi/Gset_reg.c $kdir/unwind/set_reg.c +$udir/src/mi/flush_cache.c $kdir/unwind/flush_cache.c +$udir/src/mi/mempool.c $kdir/unwind/mempool.c diff --git a/src/coreclr/src/pal/src/libunwind/scripts/make-L-files b/src/coreclr/src/pal/src/libunwind/scripts/make-L-files new file mode 100755 index 00000000000000..8280e3d76ae1a1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/scripts/make-L-files @@ -0,0 +1,30 @@ +#!/bin/sh +cwd=`pwd` +dir=`basename ${cwd}` +# +# When compiling a file that goes into libunwind, we only +# need to compile it when we really do support UNW_LOCAL_ONLY. +# In contrast, libunwind-tests should always get compiled. +# +if test $dir = "tests"; then + local_only_test="" +else + local_only_test="defined(UNW_LOCAL_ONLY) && " +fi +for gname in `ls G*.c G*.cxx G*.S 2>/dev/null`; do + lname="L$(expr $gname : '.\(.*\)')" + bk edit $lname >/dev/null 2>&1 + ext=$(expr $gname : '[^.]*[.]\(.*\)') + if [ "$ext" = "S" ]; then + include="" + else + include="#include " + fi + echo -e "\ +#define UNW_LOCAL_ONLY\n\ +$include\n\ +#if ${local_only_test}!defined(UNW_REMOTE_ONLY)\n\ +#include \"$gname\"\n\ +#endif" > $lname + echo created $lname +done diff --git a/src/coreclr/src/pal/src/libunwind/src/Makefile.am b/src/coreclr/src/pal/src/libunwind/src/Makefile.am new file mode 100644 index 00000000000000..ff977446a7c2b8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/Makefile.am @@ -0,0 +1,795 @@ +SOVERSION=8:1:0 # See comments at end of file. +SETJMP_SO_VERSION=0:0:0 +COREDUMP_SO_VERSION=0:0:0 +# +# Don't link with start-files since we don't use any constructors/destructors: +# +COMMON_SO_LDFLAGS = $(LDFLAGS_NOSTARTFILES) + +lib_LIBRARIES = +lib_LTLIBRARIES = +if !REMOTE_ONLY +lib_LTLIBRARIES += libunwind.la +if BUILD_PTRACE +lib_LTLIBRARIES += libunwind-ptrace.la +endif +if BUILD_COREDUMP +lib_LTLIBRARIES += libunwind-coredump.la +endif +endif + +noinst_HEADERS = +noinst_LTLIBRARIES = + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libunwind-generic.pc + +if !REMOTE_ONLY +pkgconfig_DATA += unwind/libunwind.pc +endif + +if BUILD_PTRACE +pkgconfig_DATA += ptrace/libunwind-ptrace.pc +endif + +if BUILD_SETJMP +pkgconfig_DATA += setjmp/libunwind-setjmp.pc +endif + +if BUILD_COREDUMP +pkgconfig_DATA += coredump/libunwind-coredump.pc +endif + +### libunwind-ptrace: +libunwind_ptrace_la_SOURCES = \ + ptrace/_UPT_elf.c \ + ptrace/_UPT_accessors.c ptrace/_UPT_access_fpreg.c \ + ptrace/_UPT_access_mem.c ptrace/_UPT_access_reg.c \ + ptrace/_UPT_create.c ptrace/_UPT_destroy.c \ + ptrace/_UPT_find_proc_info.c ptrace/_UPT_get_dyn_info_list_addr.c \ + ptrace/_UPT_put_unwind_info.c ptrace/_UPT_get_proc_name.c \ + ptrace/_UPT_reg_offset.c ptrace/_UPT_resume.c +noinst_HEADERS += ptrace/_UPT_internal.h + +### libunwind-coredump: +libunwind_coredump_la_SOURCES = \ + coredump/_UCD_accessors.c \ + coredump/_UCD_create.c \ + coredump/_UCD_destroy.c \ + coredump/_UCD_access_mem.c \ + coredump/_UCD_elf_map_image.c \ + coredump/_UCD_find_proc_info.c \ + coredump/_UCD_get_proc_name.c \ + \ + coredump/_UPT_elf.c \ + coredump/_UPT_access_fpreg.c \ + coredump/_UPT_get_dyn_info_list_addr.c \ + coredump/_UPT_put_unwind_info.c \ + coredump/_UPT_resume.c +libunwind_coredump_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ + -version-info $(COREDUMP_SO_VERSION) +libunwind_coredump_la_LIBADD = $(LIBLZMA) $(LIBZ) +noinst_HEADERS += coredump/_UCD_internal.h coredump/_UCD_lib.h + +### libunwind-setjmp: +libunwind_setjmp_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ + -version-info $(SETJMP_SO_VERSION) + +if USE_ELF32 +LIBUNWIND_ELF = libunwind-elf32.la +endif +if USE_ELF64 +LIBUNWIND_ELF = libunwind-elf64.la +endif +if USE_ELFXX +LIBUNWIND_ELF = libunwind-elfxx.la +endif + +libunwind_setjmp_la_LIBADD = $(LIBUNWIND_ELF) \ + libunwind-$(arch).la \ + libunwind.la -lc +libunwind_setjmp_la_SOURCES = setjmp/longjmp.c \ + setjmp/siglongjmp.c +noinst_HEADERS += setjmp/setjmp_i.h + +### libunwind: +libunwind_la_LIBADD = + +# List of arch-independent files needed by both local-only and generic +# libraries: +libunwind_la_SOURCES_common = \ + $(libunwind_la_SOURCES_os) \ + mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c + +# List of arch-independent files needed by generic library (libunwind-$ARCH): +libunwind_la_SOURCES_generic = \ + mi/Gdyn-extract.c mi/Gdyn-remote.c mi/Gfind_dynamic_proc_info.c \ + mi/Gget_accessors.c \ + mi/Gget_proc_info_by_ip.c mi/Gget_proc_name.c \ + mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \ + mi/Gget_reg.c mi/Gset_reg.c \ + mi/Gget_fpreg.c mi/Gset_fpreg.c \ + mi/Gset_caching_policy.c \ + mi/Gset_cache_size.c + +if SUPPORT_CXX_EXCEPTIONS +libunwind_la_SOURCES_local_unwind = \ + unwind/Backtrace.c unwind/DeleteException.c \ + unwind/FindEnclosingFunction.c unwind/ForcedUnwind.c \ + unwind/GetBSP.c unwind/GetCFA.c unwind/GetDataRelBase.c \ + unwind/GetGR.c unwind/GetIP.c unwind/GetLanguageSpecificData.c \ + unwind/GetRegionStart.c unwind/GetTextRelBase.c \ + unwind/RaiseException.c unwind/Resume.c \ + unwind/Resume_or_Rethrow.c unwind/SetGR.c unwind/SetIP.c \ + unwind/GetIPInfo.c + +# _ReadULEB()/_ReadSLEB() are needed for Intel C++ 8.0 compatibility +libunwind_la_SOURCES_os_linux_local = mi/_ReadULEB.c mi/_ReadSLEB.c +endif + +# List of arch-independent files needed by local-only library (libunwind): +libunwind_la_SOURCES_local_nounwind = \ + $(libunwind_la_SOURCES_os_local) \ + mi/backtrace.c \ + mi/dyn-cancel.c mi/dyn-info-list.c mi/dyn-register.c \ + mi/Ldyn-extract.c mi/Lfind_dynamic_proc_info.c \ + mi/Lget_accessors.c \ + mi/Lget_proc_info_by_ip.c mi/Lget_proc_name.c \ + mi/Lput_dynamic_unwind_info.c mi/Ldestroy_addr_space.c \ + mi/Lget_reg.c mi/Lset_reg.c \ + mi/Lget_fpreg.c mi/Lset_fpreg.c \ + mi/Lset_caching_policy.c \ + mi/Lset_cache_size.c + +libunwind_la_SOURCES_local = \ + $(libunwind_la_SOURCES_local_nounwind) \ + $(libunwind_la_SOURCES_local_unwind) + +noinst_HEADERS += os-linux.h +libunwind_la_SOURCES_os_linux = os-linux.c + +libunwind_la_SOURCES_os_hpux = os-hpux.c + +libunwind_la_SOURCES_os_freebsd = os-freebsd.c + +libunwind_la_SOURCES_os_qnx = os-qnx.c + +libunwind_la_SOURCES_os_solaris = os-solaris.c + +libunwind_dwarf_common_la_SOURCES = dwarf/global.c + +libunwind_dwarf_local_la_SOURCES = \ + dwarf/Lexpr.c dwarf/Lfde.c dwarf/Lparser.c dwarf/Lpe.c \ + dwarf/Lfind_proc_info-lsb.c \ + dwarf/Lfind_unwind_table.c +libunwind_dwarf_local_la_LIBADD = libunwind-dwarf-common.la + +libunwind_dwarf_generic_la_SOURCES = \ + dwarf/Gexpr.c dwarf/Gfde.c dwarf/Gparser.c dwarf/Gpe.c \ + dwarf/Gfind_proc_info-lsb.c \ + dwarf/Gfind_unwind_table.c +libunwind_dwarf_generic_la_LIBADD = libunwind-dwarf-common.la + +if USE_DWARF + noinst_LTLIBRARIES += libunwind-dwarf-common.la libunwind-dwarf-generic.la +if !REMOTE_ONLY + noinst_LTLIBRARIES += libunwind-dwarf-local.la +endif + libunwind_la_LIBADD += libunwind-dwarf-local.la +endif + +noinst_HEADERS += elf32.h elf64.h elfxx.h + +libunwind_elf32_la_SOURCES = elf32.c +libunwind_elf64_la_SOURCES = elf64.c +libunwind_elfxx_la_SOURCES = elfxx.c +libunwind_elf32_la_LIBADD = $(LIBLZMA) $(LIBZ) +libunwind_elf64_la_LIBADD = $(LIBLZMA) $(LIBZ) +libunwind_elfxx_la_LIBADD = $(LIBLZMA) $(LIBZ) + +noinst_LTLIBRARIES += $(LIBUNWIND_ELF) +libunwind_la_LIBADD += $(LIBUNWIND_ELF) + +# The list of files that go into libunwind and libunwind-aarch64: +noinst_HEADERS += aarch64/init.h aarch64/offsets.h aarch64/unwind_i.h +libunwind_la_SOURCES_aarch64_common = $(libunwind_la_SOURCES_common) \ + aarch64/is_fpreg.c aarch64/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \ + $(libunwind_la_SOURCES_local) \ + aarch64/Lapply_reg_state.c aarch64/Lreg_states_iterate.c \ + aarch64/Lcreate_addr_space.c aarch64/Lget_proc_info.c \ + aarch64/Lget_save_loc.c aarch64/Lglobal.c aarch64/Linit.c \ + aarch64/Linit_local.c aarch64/Linit_remote.c \ + aarch64/Lis_signal_frame.c aarch64/Lregs.c aarch64/Lresume.c \ + aarch64/Lstash_frame.c aarch64/Lstep.c aarch64/Ltrace.c \ + aarch64/getcontext.S + +libunwind_aarch64_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \ + $(libunwind_la_SOURCES_generic) \ + aarch64/Gapply_reg_state.c aarch64/Greg_states_iterate.c \ + aarch64/Gcreate_addr_space.c aarch64/Gget_proc_info.c \ + aarch64/Gget_save_loc.c aarch64/Gglobal.c aarch64/Ginit.c \ + aarch64/Ginit_local.c aarch64/Ginit_remote.c \ + aarch64/Gis_signal_frame.c aarch64/Gregs.c aarch64/Gresume.c \ + aarch64/Gstash_frame.c aarch64/Gstep.c aarch64/Gtrace.c + +# The list of files that go into libunwind and libunwind-arm: +noinst_HEADERS += arm/init.h arm/offsets.h arm/unwind_i.h +libunwind_la_SOURCES_arm_common = $(libunwind_la_SOURCES_common) \ + arm/is_fpreg.c arm/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_arm = $(libunwind_la_SOURCES_arm_common) \ + $(libunwind_la_SOURCES_arm_os_local) \ + $(libunwind_la_SOURCES_local) \ + arm/getcontext.S \ + arm/Lapply_reg_state.c arm/Lreg_states_iterate.c \ + arm/Lcreate_addr_space.c arm/Lget_proc_info.c arm/Lget_save_loc.c \ + arm/Lglobal.c arm/Linit.c arm/Linit_local.c arm/Linit_remote.c \ + arm/Lregs.c arm/Lresume.c arm/Lstep.c \ + arm/Lex_tables.c arm/Lstash_frame.c arm/Ltrace.c + +# The list of files that go into libunwind-arm: +libunwind_arm_la_SOURCES_arm = $(libunwind_la_SOURCES_arm_common) \ + $(libunwind_la_SOURCES_arm_os) \ + $(libunwind_la_SOURCES_generic) \ + arm/Gapply_reg_state.c arm/Greg_states_iterate.c \ + arm/Gcreate_addr_space.c arm/Gget_proc_info.c arm/Gget_save_loc.c \ + arm/Gglobal.c arm/Ginit.c arm/Ginit_local.c arm/Ginit_remote.c \ + arm/Gregs.c arm/Gresume.c arm/Gstep.c \ + arm/Gex_tables.c arm/Gstash_frame.c arm/Gtrace.c + +# The list of files that go both into libunwind and libunwind-ia64: +noinst_HEADERS += ia64/init.h ia64/offsets.h ia64/regs.h \ + ia64/ucontext_i.h ia64/unwind_decoder.h ia64/unwind_i.h +libunwind_la_SOURCES_ia64_common = $(libunwind_la_SOURCES_common) \ + ia64/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \ + $(libunwind_la_SOURCES_local) \ + \ + ia64/dyn_info_list.S ia64/getcontext.S \ + \ + ia64/Lapply_reg_state.c ia64/Lreg_states_iterate.c \ + ia64/Lcreate_addr_space.c ia64/Lget_proc_info.c ia64/Lget_save_loc.c \ + ia64/Lglobal.c ia64/Linit.c ia64/Linit_local.c ia64/Linit_remote.c \ + ia64/Linstall_cursor.S ia64/Lis_signal_frame.c ia64/Lparser.c \ + ia64/Lrbs.c ia64/Lregs.c ia64/Lresume.c ia64/Lscript.c ia64/Lstep.c \ + ia64/Ltables.c ia64/Lfind_unwind_table.c + +# The list of files that go into libunwind-ia64: +libunwind_ia64_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \ + $(libunwind_la_SOURCES_generic) \ + ia64/Gapply_reg_state.c ia64/Greg_states_iterate.c \ + ia64/Gcreate_addr_space.c ia64/Gget_proc_info.c ia64/Gget_save_loc.c \ + ia64/Gglobal.c ia64/Ginit.c ia64/Ginit_local.c ia64/Ginit_remote.c \ + ia64/Ginstall_cursor.S ia64/Gis_signal_frame.c ia64/Gparser.c \ + ia64/Grbs.c ia64/Gregs.c ia64/Gresume.c ia64/Gscript.c ia64/Gstep.c \ + ia64/Gtables.c ia64/Gfind_unwind_table.c + +# The list of files that go both into libunwind and libunwind-hppa: +noinst_HEADERS += hppa/init.h hppa/offsets.h hppa/unwind_i.h +libunwind_la_SOURCES_hppa_common = $(libunwind_la_SOURCES_common) \ + hppa/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \ + $(libunwind_la_SOURCES_local) \ + hppa/getcontext.S hppa/setcontext.S \ + hppa/Lapply_reg_state.c hppa/Lreg_states_iterate.c \ + hppa/Lcreate_addr_space.c hppa/Lget_save_loc.c hppa/Lglobal.c \ + hppa/Linit.c hppa/Linit_local.c hppa/Linit_remote.c \ + hppa/Lis_signal_frame.c hppa/Lget_proc_info.c hppa/Lregs.c \ + hppa/Lresume.c hppa/Lstep.c + +# The list of files that go into libunwind-hppa: +libunwind_hppa_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \ + $(libunwind_la_SOURCES_generic) \ + hppa/Gapply_reg_state.c hppa/Greg_states_iterate.c \ + hppa/Gcreate_addr_space.c hppa/Gget_save_loc.c hppa/Gglobal.c \ + hppa/Ginit.c hppa/Ginit_local.c hppa/Ginit_remote.c \ + hppa/Gis_signal_frame.c hppa/Gget_proc_info.c hppa/Gregs.c \ + hppa/Gresume.c hppa/Gstep.c + +# The list of files that go info libunwind and libunwind-mips: +noinst_HEADERS += mips/init.h mips/offsets.h mips/unwind_i.h +libunwind_la_SOURCES_mips_common = $(libunwind_la_SOURCES_common) \ + mips/is_fpreg.c mips/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \ + $(libunwind_la_SOURCES_local) \ + mips/getcontext.S \ + mips/Lapply_reg_state.c mips/Lreg_states_iterate.c \ + mips/Lcreate_addr_space.c mips/Lget_proc_info.c mips/Lget_save_loc.c \ + mips/Lglobal.c mips/Linit.c mips/Linit_local.c mips/Linit_remote.c \ + mips/Lis_signal_frame.c mips/Lregs.c mips/Lresume.c mips/Lstep.c + +libunwind_mips_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \ + $(libunwind_la_SOURCES_generic) \ + mips/Gapply_reg_state.c mips/Greg_states_iterate.c \ + mips/Gcreate_addr_space.c mips/Gget_proc_info.c mips/Gget_save_loc.c \ + mips/Gglobal.c mips/Ginit.c mips/Ginit_local.c mips/Ginit_remote.c \ + mips/Gis_signal_frame.c mips/Gregs.c mips/Gresume.c mips/Gstep.c + +# The list of files that go info libunwind and libunwind-tilegx: +noinst_HEADERS += tilegx/init.h tilegx/offsets.h tilegx/unwind_i.h +libunwind_la_SOURCES_tilegx_common = $(libunwind_la_SOURCES_common) \ + tilegx/is_fpreg.c tilegx/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \ + $(libunwind_la_SOURCES_local) \ + tilegx/getcontext.S \ + tilegx/Lapply_reg_state.c tilegx/Lreg_states_iterate.c \ + tilegx/Lcreate_addr_space.c tilegx/Lget_proc_info.c tilegx/Lget_save_loc.c \ + tilegx/Lglobal.c tilegx/Linit.c tilegx/Linit_local.c tilegx/Linit_remote.c \ + tilegx/Lis_signal_frame.c tilegx/Lregs.c tilegx/Lresume.c tilegx/Lstep.c + +libunwind_tilegx_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \ + $(libunwind_la_SOURCES_generic) \ + tilegx/Gapply_reg_state.c tilegx/Greg_states_iterate.c \ + tilegx/Gcreate_addr_space.c tilegx/Gget_proc_info.c tilegx/Gget_save_loc.c \ + tilegx/Gglobal.c tilegx/Ginit.c tilegx/Ginit_local.c tilegx/Ginit_remote.c \ + tilegx/Gis_signal_frame.c tilegx/Gregs.c tilegx/Gresume.c tilegx/Gstep.c + + +# The list of files that go both into libunwind and libunwind-x86: +noinst_HEADERS += x86/init.h x86/offsets.h x86/unwind_i.h +libunwind_la_SOURCES_x86_common = $(libunwind_la_SOURCES_common) \ + x86/is_fpreg.c x86/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ + $(libunwind_la_SOURCES_x86_os_local) \ + $(libunwind_la_SOURCES_local) \ + x86/Lapply_reg_state.c x86/Lreg_states_iterate.c \ + x86/Lcreate_addr_space.c x86/Lget_save_loc.c x86/Lglobal.c \ + x86/Linit.c x86/Linit_local.c x86/Linit_remote.c \ + x86/Lget_proc_info.c x86/Lregs.c \ + x86/Lresume.c x86/Lstep.c + +# The list of files that go into libunwind-x86: +libunwind_x86_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ + $(libunwind_la_SOURCES_x86_os) \ + $(libunwind_la_SOURCES_generic) \ + x86/Gapply_reg_state.c x86/Greg_states_iterate.c \ + x86/Gcreate_addr_space.c x86/Gget_save_loc.c x86/Gglobal.c \ + x86/Ginit.c x86/Ginit_local.c x86/Ginit_remote.c \ + x86/Gget_proc_info.c x86/Gregs.c \ + x86/Gresume.c x86/Gstep.c + +# The list of files that go both into libunwind and libunwind-x86_64: +noinst_HEADERS += x86_64/offsets.h \ + x86_64/init.h x86_64/unwind_i.h x86_64/ucontext_i.h +libunwind_la_SOURCES_x86_64_common = $(libunwind_la_SOURCES_common) \ + x86_64/is_fpreg.c x86_64/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \ + $(libunwind_la_SOURCES_x86_64_os_local) \ + $(libunwind_la_SOURCES_local) \ + x86_64/setcontext.S \ + x86_64/Lapply_reg_state.c x86_64/Lreg_states_iterate.c \ + x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \ + x86_64/Linit.c x86_64/Linit_local.c x86_64/Linit_remote.c \ + x86_64/Lget_proc_info.c x86_64/Lregs.c x86_64/Lresume.c \ + x86_64/Lstash_frame.c x86_64/Lstep.c x86_64/Ltrace.c x86_64/getcontext.S + +# The list of files that go into libunwind-x86_64: +libunwind_x86_64_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \ + $(libunwind_la_SOURCES_x86_64_os) \ + $(libunwind_la_SOURCES_generic) \ + x86_64/Gapply_reg_state.c x86_64/Greg_states_iterate.c \ + x86_64/Gcreate_addr_space.c x86_64/Gget_save_loc.c x86_64/Gglobal.c \ + x86_64/Ginit.c x86_64/Ginit_local.c x86_64/Ginit_remote.c \ + x86_64/Gget_proc_info.c x86_64/Gregs.c x86_64/Gresume.c \ + x86_64/Gstash_frame.c x86_64/Gstep.c x86_64/Gtrace.c + +# The list of local files that go to Power 64 and 32: +libunwind_la_SOURCES_ppc = \ + ppc/Lget_proc_info.c ppc/Lget_save_loc.c ppc/Linit_local.c \ + ppc/Linit_remote.c ppc/Lis_signal_frame.c + +# The list of generic files that go to Power 64 and 32: +libunwind_ppc_la_SOURCES_ppc_generic = \ + ppc/Gget_proc_info.c ppc/Gget_save_loc.c ppc/Ginit_local.c \ + ppc/Ginit_remote.c ppc/Gis_signal_frame.c + +# The list of files that go both into libunwind and libunwind-ppc32: +noinst_HEADERS += ppc32/init.h ppc32/unwind_i.h ppc32/ucontext_i.h +libunwind_la_SOURCES_ppc32_common = $(libunwind_la_SOURCES_common) \ + ppc32/is_fpreg.c ppc32/regname.c ppc32/get_func_addr.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_ppc) \ + ppc32/Lapply_reg_state.c ppc32/Lreg_states_iterate.c \ + ppc32/Lcreate_addr_space.c \ + ppc32/Lglobal.c ppc32/Linit.c \ + ppc32/Lregs.c ppc32/Lresume.c ppc32/Lstep.c + +# The list of files that go into libunwind-ppc32: +libunwind_ppc32_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_ppc_la_SOURCES_ppc_generic) \ + ppc32/Gapply_reg_state.c ppc32/Greg_states_iterate.c \ + ppc32/Gcreate_addr_space.c \ + ppc32/Gglobal.c ppc32/Ginit.c \ + ppc32/Gregs.c ppc32/Gresume.c ppc32/Gstep.c + +# The list of files that go both into libunwind and libunwind-ppc64: +noinst_HEADERS += ppc64/init.h ppc64/unwind_i.h ppc64/ucontext_i.h +libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \ + ppc64/is_fpreg.c ppc64/regname.c ppc64/get_func_addr.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_ppc) \ + ppc64/Lapply_reg_state.c ppc64/Lreg_states_iterate.c \ + ppc64/Lcreate_addr_space.c \ + ppc64/Lglobal.c ppc64/Linit.c \ + ppc64/Lregs.c ppc64/Lresume.c ppc64/Lstep.c + +# The list of files that go into libunwind-ppc64: +libunwind_ppc64_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_ppc_la_SOURCES_ppc_generic) \ + ppc64/Gapply_reg_state.c ppc64/Greg_states_iterate.c \ + ppc64/Gcreate_addr_space.c \ + ppc64/Gglobal.c ppc64/Ginit.c \ + ppc64/Gregs.c ppc64/Gresume.c ppc64/Gstep.c + +# The list of files that go into libunwind and libunwind-sh: +noinst_HEADERS += sh/init.h sh/offsets.h sh/unwind_i.h +libunwind_la_SOURCES_sh_common = $(libunwind_la_SOURCES_common) \ + sh/is_fpreg.c sh/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ + $(libunwind_la_SOURCES_local) \ + sh/Lapply_reg_state.c sh/Lreg_states_iterate.c \ + sh/Lcreate_addr_space.c sh/Lget_proc_info.c sh/Lget_save_loc.c \ + sh/Lglobal.c sh/Linit.c sh/Linit_local.c sh/Linit_remote.c \ + sh/Lis_signal_frame.c sh/Lregs.c sh/Lresume.c sh/Lstep.c + +libunwind_sh_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ + $(libunwind_la_SOURCES_generic) \ + sh/Gapply_reg_state.c sh/Greg_states_iterate.c \ + sh/Gcreate_addr_space.c sh/Gget_proc_info.c sh/Gget_save_loc.c \ + sh/Gglobal.c sh/Ginit.c sh/Ginit_local.c sh/Ginit_remote.c \ + sh/Gis_signal_frame.c sh/Gregs.c sh/Gresume.c sh/Gstep.c + +# The list of files that go both into libunwind and libunwind-s390x: +noinst_HEADERS += s390x/init.h s390x/unwind_i.h +libunwind_la_SOURCES_s390x_common = $(libunwind_la_SOURCES_common) \ + s390x/is_fpreg.c s390x/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_s390x = $(libunwind_la_SOURCES_s390x_common) \ + $(libunwind_la_SOURCES_local) \ + s390x/Lapply_reg_state.c s390x/Lreg_states_iterate.c \ + s390x/Lcreate_addr_space.c s390x/Lget_save_loc.c s390x/Lglobal.c \ + s390x/Linit.c s390x/Linit_local.c s390x/Linit_remote.c \ + s390x/Lget_proc_info.c s390x/Lregs.c s390x/Lresume.c \ + s390x/Lis_signal_frame.c s390x/Lstep.c \ + s390x/getcontext.S s390x/setcontext.S + +# The list of files that go into libunwind-s390x: +libunwind_s390x_la_SOURCES_s390x = $(libunwind_la_SOURCES_s390x_common) \ + $(libunwind_la_SOURCES_generic) \ + s390x/Gapply_reg_state.c s390x/Greg_states_iterate.c \ + s390x/Gcreate_addr_space.c s390x/Gget_save_loc.c s390x/Gglobal.c \ + s390x/Ginit.c s390x/Ginit_local.c s390x/Ginit_remote.c \ + s390x/Gget_proc_info.c s390x/Gregs.c s390x/Gresume.c \ + s390x/Gis_signal_frame.c s390x/Gstep.c + +if REMOTE_ONLY +install-exec-hook: +# Nothing to do here.... +else +# +# This is not ideal, but I know of no other way to install an +# alias for a library. For the shared version, we have to do +# a file check before creating the link, because it isn't going +# to be there if the user configured with --disable-shared. +# +install-exec-hook: + if test -f $(DESTDIR)$(libdir)/libunwind-$(arch).a; then \ + cd $(DESTDIR)$(libdir) && $(LN_S) -f libunwind-$(arch).a libunwind-generic.a; \ + fi + if test -f $(DESTDIR)$(libdir)/libunwind-$(arch).so; then \ + cd $(DESTDIR)$(libdir) && $(LN_S) -f libunwind-$(arch).so \ + libunwind-generic.so; \ + fi +endif + +if OS_LINUX + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_linux) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_linux_local) + libunwind_la_SOURCES_x86_os = x86/Gos-linux.c + libunwind_x86_la_SOURCES_os = x86/getcontext-linux.S + libunwind_la_SOURCES_x86_os_local = x86/Los-linux.c + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-linux.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-linux.c + libunwind_la_SOURCES_arm_os = arm/Gos-linux.c + libunwind_la_SOURCES_arm_os_local = arm/Los-linux.c + libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_linux.c +endif + +if OS_HPUX + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_hpux) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_hpux_local) +endif + +if OS_FREEBSD + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_freebsd) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_freebsd_local) + libunwind_la_SOURCES_x86_os = x86/Gos-freebsd.c + libunwind_x86_la_SOURCES_os = x86/getcontext-freebsd.S + libunwind_la_SOURCES_x86_os_local = x86/Los-freebsd.c + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-freebsd.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-freebsd.c + libunwind_la_SOURCES_arm_os = arm/Gos-freebsd.c + libunwind_la_SOURCES_arm_os_local = arm/Los-freebsd.c + libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c +endif + +if OS_SOLARIS + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_solaris) + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-solaris.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-solaris.c +endif + +if OS_QNX + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_qnx) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_qnx_local) + libunwind_la_SOURCES_arm_os = arm/Gos-other.c + libunwind_la_SOURCES_arm_os_local = arm/Los-other.c +endif + +if ARCH_AARCH64 + lib_LTLIBRARIES += libunwind-aarch64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_aarch64) + libunwind_aarch64_la_SOURCES = $(libunwind_aarch64_la_SOURCES_aarch64) + libunwind_aarch64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_aarch64_la_LIBADD = libunwind-dwarf-generic.la + libunwind_aarch64_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_aarch64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += aarch64/siglongjmp.S +else +if ARCH_ARM + lib_LTLIBRARIES += libunwind-arm.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_arm) + libunwind_arm_la_SOURCES = $(libunwind_arm_la_SOURCES_arm) + libunwind_arm_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_arm_la_LIBADD = libunwind-dwarf-generic.la + libunwind_arm_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_arm_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += arm/siglongjmp.S +else +if ARCH_IA64 + BUILT_SOURCES = Gcursor_i.h Lcursor_i.h +mk_Gcursor_i.s: $(srcdir)/ia64/mk_Gcursor_i.c + $(COMPILE) -S "$(srcdir)/ia64/mk_Gcursor_i.c" -o mk_Gcursor_i.s +mk_Lcursor_i.s: $(srcdir)/ia64/mk_Lcursor_i.c + $(COMPILE) -S "$(srcdir)/ia64/mk_Lcursor_i.c" -o mk_Lcursor_i.s +Gcursor_i.h: mk_Gcursor_i.s + "$(srcdir)/ia64/mk_cursor_i" mk_Gcursor_i.s > Gcursor_i.h +Lcursor_i.h: mk_Lcursor_i.s + "$(srcdir)/ia64/mk_cursor_i" mk_Lcursor_i.s > Lcursor_i.h + + lib_LTLIBRARIES += libunwind-ia64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_ia64) + libunwind_ia64_la_SOURCES = $(libunwind_ia64_la_SOURCES_ia64) + libunwind_ia64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_ia64_la_LIBADD = libunwind-elf64.la +if !REMOTE_ONLY + libunwind_ia64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += ia64/setjmp.S ia64/sigsetjmp.S \ + ia64/longjmp.S ia64/siglongjmp.S +else +if ARCH_HPPA + lib_LTLIBRARIES += libunwind-hppa.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_hppa) + libunwind_hppa_la_SOURCES = $(libunwind_hppa_la_SOURCES_hppa) + libunwind_hppa_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_hppa_la_LIBADD = libunwind-dwarf-generic.la + libunwind_hppa_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_hppa_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += hppa/siglongjmp.S +else +if ARCH_MIPS + lib_LTLIBRARIES += libunwind-mips.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_mips) + libunwind_mips_la_SOURCES = $(libunwind_mips_la_SOURCES_mips) + libunwind_mips_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_mips_la_LIBADD = libunwind-dwarf-generic.la + libunwind_mips_la_LIBADD += libunwind-elfxx.la +if !REMOTE_ONLY + libunwind_mips_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += mips/siglongjmp.S +else +if ARCH_TILEGX + lib_LTLIBRARIES += libunwind-tilegx.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_tilegx) + libunwind_tilegx_la_SOURCES = $(libunwind_tilegx_la_SOURCES_tilegx) + libunwind_tilegx_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_tilegx_la_LIBADD = libunwind-dwarf-generic.la + libunwind_tilegx_la_LIBADD += libunwind-elfxx.la +if !REMOTE_ONLY + libunwind_tilegx_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += tilegx/siglongjmp.S +else +if ARCH_X86 + lib_LTLIBRARIES += libunwind-x86.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86) $(libunwind_x86_la_SOURCES_os) + libunwind_x86_la_SOURCES = $(libunwind_x86_la_SOURCES_x86) + libunwind_x86_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_x86_la_LIBADD = libunwind-dwarf-generic.la + libunwind_x86_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_x86_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += x86/longjmp.S x86/siglongjmp.S +else +if ARCH_X86_64 + lib_LTLIBRARIES += libunwind-x86_64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86_64) + libunwind_x86_64_la_SOURCES = $(libunwind_x86_64_la_SOURCES_x86_64) + libunwind_x86_64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_x86_64_la_LIBADD = libunwind-dwarf-generic.la + libunwind_x86_64_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_x86_64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += x86_64/longjmp.S x86_64/siglongjmp.S +else +if ARCH_PPC32 + lib_LTLIBRARIES += libunwind-ppc32.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc32) + libunwind_ppc32_la_SOURCES = $(libunwind_ppc32_la_SOURCES_ppc32) + libunwind_ppc32_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_ppc32_la_LIBADD = libunwind-dwarf-generic.la + libunwind_ppc32_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_ppc32_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S +else +if ARCH_PPC64 + lib_LTLIBRARIES += libunwind-ppc64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc64) + libunwind_ppc64_la_SOURCES = $(libunwind_ppc64_la_SOURCES_ppc64) + libunwind_ppc64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_ppc64_la_LIBADD = libunwind-dwarf-generic.la + libunwind_ppc64_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_ppc64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S +else +if ARCH_SH + lib_LTLIBRARIES += libunwind-sh.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_sh) + libunwind_sh_la_SOURCES = $(libunwind_sh_la_SOURCES_sh) + libunwind_sh_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_sh_la_LIBADD = libunwind-dwarf-generic.la + libunwind_sh_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_sh_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += sh/siglongjmp.S +else +if ARCH_S390X + lib_LTLIBRARIES += libunwind-s390x.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_s390x) + libunwind_s390x_la_SOURCES = $(libunwind_s390x_la_SOURCES_s390x) + libunwind_s390x_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_s390x_la_LIBADD = libunwind-dwarf-generic.la + libunwind_s390x_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_s390x_la_LIBADD += libunwind.la -lc +endif + +endif # ARCH_S390X +endif # ARCH_SH +endif # ARCH_PPC64 +endif # ARCH_PPC32 +endif # ARCH_X86_64 +endif # ARCH_X86 +endif # ARCH_TILEGX +endif # ARCH_MIPS +endif # ARCH_HPPA +endif # ARCH_IA64 +endif # ARCH_ARM +endif # ARCH_AARCH64 + +# libunwind-setjmp depends on libunwind-$(arch). Therefore must be added +# at the end. +if BUILD_SETJMP +lib_LTLIBRARIES += libunwind-setjmp.la +endif + +# +# Don't link with standard libraries, because those may mention +# libunwind already. +# +libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -XCClinker -nostdlib \ + $(LDFLAGS_STATIC_LIBCXA) -version-info $(SOVERSION) +libunwind_la_LIBADD += -lc $(LIBCRTS) +libunwind_la_LIBADD += $(LIBLZMA) $(LIBZ) + +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I. +AM_CCASFLAGS = $(AM_CPPFLAGS) +noinst_HEADERS += unwind/unwind-internal.h + +EXTRA_DIST = $(libunwind_la_SOURCES_aarch64) \ + $(libunwind_la_SOURCES_arm) \ + $(libunwind_la_SOURCES_hppa) \ + $(libunwind_la_SOURCES_ia64) \ + $(libunwind_la_SOURCES_mips) \ + $(libunwind_la_SOURCES_sh) \ + $(libunwind_la_SOURCES_x86) \ + $(libunwind_la_SOURCES_os_freebsd) \ + $(libunwind_la_SOURCES_os_linux) \ + $(libunwind_la_SOURCES_os_hpux) \ + $(libunwind_la_SOURCES_os_qnx) \ + $(libunwind_la_SOURCES_os_solaris) \ + $(libunwind_la_SOURCES_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_aarch64_la_SOURCES_aarch64) \ + $(libunwind_arm_la_SOURCES_arm) \ + $(libunwind_hppa_la_SOURCES_hppa) \ + $(libunwind_ia64_la_SOURCES_ia64) \ + $(libunwind_mips_la_SOURCES_mips) \ + $(libunwind_sh_la_SOURCES_sh) \ + $(libunwind_x86_la_SOURCES_x86) \ + $(libunwind_x86_64_la_SOURCES_x86_64) + +MAINTAINERCLEANFILES = Makefile.in + +# The -version-info flag accepts an argument of the form +# `current[:revision[:age]]'. So, passing `-version-info 3:12:1' sets +# current to 3, revision to 12, and age to 1. + +# If either revision or age are omitted, they default to 0. Also note +# that age must be less than or equal to the current interface number. + +# Here are a set of rules to help you update your library version +# information: + +# 1. Start with version information of `0:0:0' for each libtool +# library. + +# 2. Update the version information only immediately before a public +# release of your software. More frequent updates are unnecessary, +# and only guarantee that the current interface number gets larger +# faster. + +# 3. If the library source code has changed at all since the last +# update, then increment revision (`c:r:a' becomes `c:r+1:a'). + +# 4. If any interfaces have been added, removed, or changed since the +# last update, increment current, and set revision to 0. + +# 5. If any interfaces have been added since the last public release, +# then increment age. + +# 6. If any interfaces have been removed since the last public +# release, then set age to 0. diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gcreate_addr_space.c new file mode 100644 index 00000000000000..f217adc745540b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gcreate_addr_space.c @@ -0,0 +1,60 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + 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. */ + +#include +#include + +#include "unwind_i.h" + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* AArch64 supports little-endian and big-endian. */ + if (byte_order != 0 && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + /* Default to little-endian for AArch64. */ + if (byte_order == 0 || byte_order == __LITTLE_ENDIAN) + as->big_endian = 0; + else + as->big_endian = 1; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_proc_info.c new file mode 100644 index 00000000000000..c363d2405d748a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_proc_info.c @@ -0,0 +1,39 @@ +/* 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. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = dwarf_make_proc_info (&c->dwarf); + if (ret < 0) + return ret; + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_save_loc.c new file mode 100644 index 00000000000000..86bbbd03d11b3b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gget_save_loc.c @@ -0,0 +1,100 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + 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. */ + +#include "unwind_i.h" + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + switch (reg) + { + case UNW_AARCH64_X0: + case UNW_AARCH64_X1: + case UNW_AARCH64_X2: + case UNW_AARCH64_X3: + case UNW_AARCH64_X4: + case UNW_AARCH64_X5: + case UNW_AARCH64_X6: + case UNW_AARCH64_X7: + case UNW_AARCH64_X8: + case UNW_AARCH64_X9: + case UNW_AARCH64_X10: + case UNW_AARCH64_X11: + case UNW_AARCH64_X12: + case UNW_AARCH64_X13: + case UNW_AARCH64_X14: + case UNW_AARCH64_X15: + case UNW_AARCH64_X16: + case UNW_AARCH64_X17: + case UNW_AARCH64_X18: + case UNW_AARCH64_X19: + case UNW_AARCH64_X20: + case UNW_AARCH64_X21: + case UNW_AARCH64_X22: + case UNW_AARCH64_X23: + case UNW_AARCH64_X24: + case UNW_AARCH64_X25: + case UNW_AARCH64_X26: + case UNW_AARCH64_X27: + case UNW_AARCH64_X28: + case UNW_AARCH64_X29: + case UNW_AARCH64_X30: + case UNW_AARCH64_SP: + case UNW_AARCH64_PC: + case UNW_AARCH64_PSTATE: + loc = c->dwarf.loc[reg]; + break; + + default: + loc = DWARF_NULL_LOC; /* default to "not saved" */ + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gglobal.c new file mode 100644 index 00000000000000..72e36b2d4d67a8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gglobal.c @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + 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. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (aarch64_lock); +HIDDEN int tdep_init_done; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&aarch64_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + aarch64_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&aarch64_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c new file mode 100644 index 00000000000000..35389762f27ed4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c @@ -0,0 +1,189 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + 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. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static inline void * +uc_addr (unw_tdep_context_t *uc, int reg) +{ + if (reg >= UNW_AARCH64_X0 && reg < UNW_AARCH64_V0) + return &uc->uc_mcontext.regs[reg]; + else if (reg >= UNW_AARCH64_V0 && reg <= UNW_AARCH64_V31) + return &GET_FPCTX(uc)->vregs[reg - UNW_AARCH64_V0]; + else + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (unw_tdep_context_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (16, "mem[%lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (16, "mem[%lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + unw_tdep_context_t *uc = arg; + + if (unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + unw_tdep_context_t *uc = arg; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +aarch64_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = aarch64_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c new file mode 100644 index 00000000000000..69d4ed3861db9b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c @@ -0,0 +1,78 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2011-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. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + + return common_init (c, use_prev_instr); +} + +int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, unw_tdep_context_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_remote.c new file mode 100644 index 00000000000000..9b8ba5b89def1a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_remote.c @@ -0,0 +1,45 @@ +/* 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. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gis_signal_frame.c new file mode 100644 index 00000000000000..67159d83961431 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gis_signal_frame.c @@ -0,0 +1,64 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + 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. */ + +#include "unwind_i.h" + +/* The restorer stub will always have the form: + + d2801168 movz x8, #0x8b + d4000001 svc #0x0 +*/ + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + ret = (*a->access_mem) (as, ip, &w0, 0, arg); + if (ret < 0) + return ret; + + /* FIXME: distinguish 32bit insn vs 64bit registers. */ + if (w0 != 0xd4000001d2801168) + return 0; + + return 1; + +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gregs.c new file mode 100644 index 00000000000000..a8843734459b57 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gregs.c @@ -0,0 +1,118 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + 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. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + unsigned int mask; + + switch (reg) + { + case UNW_AARCH64_X0: + case UNW_AARCH64_X1: + case UNW_AARCH64_X2: + case UNW_AARCH64_X3: + mask = 1 << reg; + if (write) + { + c->dwarf.eh_args[reg] = *valp; + c->dwarf.eh_valid_mask |= mask; + return 0; + } + else if ((c->dwarf.eh_valid_mask & mask) != 0) + { + *valp = c->dwarf.eh_args[reg]; + return 0; + } + else + loc = c->dwarf.loc[reg]; + break; + + case UNW_AARCH64_X30: + if (write) + c->dwarf.ip = *valp; /* update the IP cache */ + case UNW_AARCH64_X4: + case UNW_AARCH64_X5: + case UNW_AARCH64_X6: + case UNW_AARCH64_X7: + case UNW_AARCH64_X8: + case UNW_AARCH64_X9: + case UNW_AARCH64_X10: + case UNW_AARCH64_X11: + case UNW_AARCH64_X12: + case UNW_AARCH64_X13: + case UNW_AARCH64_X14: + case UNW_AARCH64_X15: + case UNW_AARCH64_X16: + case UNW_AARCH64_X17: + case UNW_AARCH64_X18: + case UNW_AARCH64_X19: + case UNW_AARCH64_X20: + case UNW_AARCH64_X21: + case UNW_AARCH64_X22: + case UNW_AARCH64_X23: + case UNW_AARCH64_X24: + case UNW_AARCH64_X25: + case UNW_AARCH64_X26: + case UNW_AARCH64_X27: + case UNW_AARCH64_X28: + case UNW_AARCH64_X29: + case UNW_AARCH64_PC: + case UNW_AARCH64_PSTATE: + loc = c->dwarf.loc[reg]; + break; + + case UNW_AARCH64_SP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + dwarf_loc_t loc = c->dwarf.loc[reg]; + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c new file mode 100644 index 00000000000000..2cc161360ef537 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c @@ -0,0 +1,198 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2011-2013 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_tdep_context_t *uc = c->dwarf.as_arg; + + if (c->sigcontext_format == AARCH64_SCF_NONE) + { + /* Since there are no signals involved here we restore EH and non scratch + registers only. */ + unsigned long regs[24]; + regs[0] = uc->uc_mcontext.regs[0]; + regs[1] = uc->uc_mcontext.regs[1]; + regs[2] = uc->uc_mcontext.regs[2]; + regs[3] = uc->uc_mcontext.regs[3]; + regs[4] = uc->uc_mcontext.regs[19]; + regs[5] = uc->uc_mcontext.regs[20]; + regs[6] = uc->uc_mcontext.regs[21]; + regs[7] = uc->uc_mcontext.regs[22]; + regs[8] = uc->uc_mcontext.regs[23]; + regs[9] = uc->uc_mcontext.regs[24]; + regs[10] = uc->uc_mcontext.regs[25]; + regs[11] = uc->uc_mcontext.regs[26]; + regs[12] = uc->uc_mcontext.regs[27]; + regs[13] = uc->uc_mcontext.regs[28]; + regs[14] = uc->uc_mcontext.regs[29]; /* FP */ + regs[15] = uc->uc_mcontext.regs[30]; /* LR */ + regs[16] = GET_FPCTX(uc)->vregs[8]; + regs[17] = GET_FPCTX(uc)->vregs[9]; + regs[18] = GET_FPCTX(uc)->vregs[10]; + regs[19] = GET_FPCTX(uc)->vregs[11]; + regs[20] = GET_FPCTX(uc)->vregs[12]; + regs[21] = GET_FPCTX(uc)->vregs[13]; + regs[22] = GET_FPCTX(uc)->vregs[14]; + regs[23] = GET_FPCTX(uc)->vregs[15]; + unsigned long sp = uc->uc_mcontext.sp; + + struct regs_overlay { + char x[sizeof(regs)]; + }; + + __asm__ __volatile__ ( + "mov x4, %0\n" + "mov x5, %1\n" + "ldp x0, x1, [x4]\n" + "ldp x2, x3, [x4,16]\n" + "ldp x19, x20, [x4,32]\n" + "ldp x21, x22, [x4,48]\n" + "ldp x23, x24, [x4,64]\n" + "ldp x25, x26, [x4,80]\n" + "ldp x27, x28, [x4,96]\n" + "ldp x29, x30, [x4,112]\n" + "ldp d8, d9, [x4,128]\n" + "ldp d10, d11, [x4,144]\n" + "ldp d12, d13, [x4,160]\n" + "ldp d14, d15, [x4,176]\n" + "mov sp, x5\n" + "ret \n" + : + : "r" (regs), + "r" (sp), + "m" (*(struct regs_overlay *)regs) + ); + } + else + { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + if (c->dwarf.eh_valid_mask & 0x1) sc->regs[0] = c->dwarf.eh_args[0]; + if (c->dwarf.eh_valid_mask & 0x2) sc->regs[1] = c->dwarf.eh_args[1]; + if (c->dwarf.eh_valid_mask & 0x4) sc->regs[2] = c->dwarf.eh_args[2]; + if (c->dwarf.eh_valid_mask & 0x8) sc->regs[3] = c->dwarf.eh_args[3]; + + sc->regs[4] = uc->uc_mcontext.regs[4]; + sc->regs[5] = uc->uc_mcontext.regs[5]; + sc->regs[6] = uc->uc_mcontext.regs[6]; + sc->regs[7] = uc->uc_mcontext.regs[7]; + sc->regs[8] = uc->uc_mcontext.regs[8]; + sc->regs[9] = uc->uc_mcontext.regs[9]; + sc->regs[10] = uc->uc_mcontext.regs[10]; + sc->regs[11] = uc->uc_mcontext.regs[11]; + sc->regs[12] = uc->uc_mcontext.regs[12]; + sc->regs[13] = uc->uc_mcontext.regs[13]; + sc->regs[14] = uc->uc_mcontext.regs[14]; + sc->regs[15] = uc->uc_mcontext.regs[15]; + sc->regs[16] = uc->uc_mcontext.regs[16]; + sc->regs[17] = uc->uc_mcontext.regs[17]; + sc->regs[18] = uc->uc_mcontext.regs[18]; + sc->regs[19] = uc->uc_mcontext.regs[19]; + sc->regs[20] = uc->uc_mcontext.regs[20]; + sc->regs[21] = uc->uc_mcontext.regs[21]; + sc->regs[22] = uc->uc_mcontext.regs[22]; + sc->regs[23] = uc->uc_mcontext.regs[23]; + sc->regs[24] = uc->uc_mcontext.regs[24]; + sc->regs[25] = uc->uc_mcontext.regs[25]; + sc->regs[26] = uc->uc_mcontext.regs[26]; + sc->regs[27] = uc->uc_mcontext.regs[27]; + sc->regs[28] = uc->uc_mcontext.regs[28]; + sc->regs[29] = uc->uc_mcontext.regs[29]; + sc->regs[30] = uc->uc_mcontext.regs[30]; + sc->sp = uc->uc_mcontext.sp; + sc->pc = uc->uc_mcontext.pc; + sc->pstate = uc->uc_mcontext.pstate; + + __asm__ __volatile__ ( + "mov sp, %0\n" + "ret %1\n" + : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) + ); + } + unreachable(); +#else + printf ("%s: implement me\n", __FUNCTION__); +#endif + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +static inline void +establish_machine_state (struct cursor *c) +{ + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_AARCH64_V31; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + as->acc.access_fpreg (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + } +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + Debug (1, "(cursor=%p)\n", c); + + if (!c->dwarf.ip) + { + /* This can happen easily when the frame-chain gets truncated + due to bad or missing unwind-info. */ + Debug (1, "refusing to resume execution at address 0\n"); + return -UNW_EINVAL; + } + + establish_machine_state (c); + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstash_frame.c new file mode 100644 index 00000000000000..6689af1a61d565 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstash_frame.c @@ -0,0 +1,89 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + Copyright (C) 2014 CERN and Aalto University + Contributed by Filip Nyback + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN void +tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) +{ + struct cursor *c = (struct cursor *) dwarf_to_cursor (d); + unw_tdep_frame_t *f = &c->frame_info; + + Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld" + " ra=0x%lx fp [where=%d val=%ld @0x%lx] lr [where=%d val=%ld @0x%lx] " + "sp [where=%d val=%ld @0x%lx]\n", + d->ip, d->cfa, f->frame_type, + rs->reg.where[DWARF_CFA_REG_COLUMN], + rs->reg.val[DWARF_CFA_REG_COLUMN], + rs->reg.val[DWARF_CFA_OFF_COLUMN], + DWARF_GET_LOC(d->loc[rs->ret_addr_column]), + rs->reg.where[FP], rs->reg.val[FP], DWARF_GET_LOC(d->loc[FP]), + rs->reg.where[LR], rs->reg.val[LR], DWARF_GET_LOC(d->loc[LR]), + rs->reg.where[SP], rs->reg.val[SP], DWARF_GET_LOC(d->loc[SP])); + + /* A standard frame is defined as: + - CFA is register-relative offset off FP or SP; + - Return address is saved in LR; + - FP is unsaved or saved at CFA+offset, offset != -1; + - LR is unsaved or saved at CFA+offset, offset != -1; + - SP is unsaved or saved at CFA+offset, offset != -1. */ + if (f->frame_type == UNW_AARCH64_FRAME_OTHER + && (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG) + && (rs->reg.val[DWARF_CFA_REG_COLUMN] == FP + || rs->reg.val[DWARF_CFA_REG_COLUMN] == SP) + && labs(rs->reg.val[DWARF_CFA_OFF_COLUMN]) < (1 << 29) + && rs->ret_addr_column == LR + && (rs->reg.where[FP] == DWARF_WHERE_UNDEF + || rs->reg.where[FP] == DWARF_WHERE_SAME + || (rs->reg.where[FP] == DWARF_WHERE_CFAREL + && labs(rs->reg.val[FP]) < (1 << 29) + && rs->reg.val[FP]+1 != 0)) + && (rs->reg.where[LR] == DWARF_WHERE_UNDEF + || rs->reg.where[LR] == DWARF_WHERE_SAME + || (rs->reg.where[LR] == DWARF_WHERE_CFAREL + && labs(rs->reg.val[LR]) < (1 << 29) + && rs->reg.val[LR]+1 != 0)) + && (rs->reg.where[SP] == DWARF_WHERE_UNDEF + || rs->reg.where[SP] == DWARF_WHERE_SAME + || (rs->reg.where[SP] == DWARF_WHERE_CFAREL + && labs(rs->reg.val[SP]) < (1 << 29) + && rs->reg.val[SP]+1 != 0))) + { + /* Save information for a standard frame. */ + f->frame_type = UNW_AARCH64_FRAME_STANDARD; + f->cfa_reg_sp = (rs->reg.val[DWARF_CFA_REG_COLUMN] == SP); + f->cfa_reg_offset = rs->reg.val[DWARF_CFA_OFF_COLUMN]; + if (rs->reg.where[FP] == DWARF_WHERE_CFAREL) + f->fp_cfa_offset = rs->reg.val[FP]; + if (rs->reg.where[LR] == DWARF_WHERE_CFAREL) + f->lr_cfa_offset = rs->reg.val[LR]; + if (rs->reg.where[SP] == DWARF_WHERE_CFAREL) + f->sp_cfa_offset = rs->reg.val[SP]; + Debug (4, " standard frame\n"); + } + else + Debug (4, " unusual frame\n"); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstep.c new file mode 100644 index 00000000000000..fdf64a73f3304a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gstep.c @@ -0,0 +1,189 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2011-2013 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +/* Recognise PLT entries such as: + 40ddf0: b0000570 adrp x16, 4ba000 <_GLOBAL_OFFSET_TABLE_+0x2a8> + 40ddf4: f9433611 ldr x17, [x16,#1640] + 40ddf8: 9119a210 add x16, x16, #0x668 + 40ddfc: d61f0220 br x17 */ +static int +is_plt_entry (struct dwarf_cursor *c) +{ + unw_word_t w0, w1; + unw_accessors_t *a; + int ret; + + a = unw_get_accessors_int (c->as); + if ((ret = (*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg)) < 0 + || (ret = (*a->access_mem) (c->as, c->ip + 8, &w1, 0, c->as_arg)) < 0) + return 0; + + ret = (((w0 & 0xff0000009f000000) == 0xf900000090000000) + && ((w1 & 0xffffffffff000000) == 0xd61f022091000000)); + + Debug (14, "ip=0x%lx => 0x%016lx 0x%016lx, ret = %d\n", c->ip, w0, w1, ret); + return ret; +} + +static int +aarch64_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + + ret = unw_is_signal_frame (cursor); + Debug(1, "unw_is_signal_frame()=%d\n", ret); + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + if (ret) + { + c->sigcontext_format = AARCH64_SCF_LINUX_RT_SIGFRAME; + sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + } + else + return -UNW_EUNSPEC; + + c->sigcontext_addr = sc_addr; + c->frame_info.frame_type = UNW_AARCH64_FRAME_SIGRETURN; + c->frame_info.cfa_reg_offset = sc_addr - sp_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + c->dwarf.loc[UNW_AARCH64_X0] = DWARF_LOC (sc_addr + LINUX_SC_X0_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X1] = DWARF_LOC (sc_addr + LINUX_SC_X1_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X2] = DWARF_LOC (sc_addr + LINUX_SC_X2_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X3] = DWARF_LOC (sc_addr + LINUX_SC_X3_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X4] = DWARF_LOC (sc_addr + LINUX_SC_X4_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X5] = DWARF_LOC (sc_addr + LINUX_SC_X5_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X6] = DWARF_LOC (sc_addr + LINUX_SC_X6_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X7] = DWARF_LOC (sc_addr + LINUX_SC_X7_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X8] = DWARF_LOC (sc_addr + LINUX_SC_X8_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X9] = DWARF_LOC (sc_addr + LINUX_SC_X9_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X10] = DWARF_LOC (sc_addr + LINUX_SC_X10_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X11] = DWARF_LOC (sc_addr + LINUX_SC_X11_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X12] = DWARF_LOC (sc_addr + LINUX_SC_X12_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X13] = DWARF_LOC (sc_addr + LINUX_SC_X13_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X14] = DWARF_LOC (sc_addr + LINUX_SC_X14_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X15] = DWARF_LOC (sc_addr + LINUX_SC_X15_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X16] = DWARF_LOC (sc_addr + LINUX_SC_X16_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X17] = DWARF_LOC (sc_addr + LINUX_SC_X17_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X18] = DWARF_LOC (sc_addr + LINUX_SC_X18_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X19] = DWARF_LOC (sc_addr + LINUX_SC_X19_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X20] = DWARF_LOC (sc_addr + LINUX_SC_X20_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X21] = DWARF_LOC (sc_addr + LINUX_SC_X21_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X22] = DWARF_LOC (sc_addr + LINUX_SC_X22_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X23] = DWARF_LOC (sc_addr + LINUX_SC_X23_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X24] = DWARF_LOC (sc_addr + LINUX_SC_X24_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X25] = DWARF_LOC (sc_addr + LINUX_SC_X25_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X26] = DWARF_LOC (sc_addr + LINUX_SC_X26_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X27] = DWARF_LOC (sc_addr + LINUX_SC_X27_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X28] = DWARF_LOC (sc_addr + LINUX_SC_X28_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X29] = DWARF_LOC (sc_addr + LINUX_SC_X29_OFF, 0); + c->dwarf.loc[UNW_AARCH64_X30] = DWARF_LOC (sc_addr + LINUX_SC_X30_OFF, 0); + c->dwarf.loc[UNW_AARCH64_SP] = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0); + c->dwarf.loc[UNW_AARCH64_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); + c->dwarf.loc[UNW_AARCH64_PSTATE] = DWARF_LOC (sc_addr + LINUX_SC_PSTATE_OFF, 0); + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_SP], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); + + c->dwarf.pi_valid = 0; + c->dwarf.use_prev_instr = 0; + + return 1; +} + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx))\n", + c, c->dwarf.ip, c->dwarf.cfa); + + /* Check if this is a signal frame. */ + if (unw_is_signal_frame (cursor) > 0) + return aarch64_handle_signal_frame (cursor); + + ret = dwarf_step (&c->dwarf); + Debug(1, "dwarf_step()=%d\n", ret); + + if (unlikely (ret == -UNW_ESTOPUNWIND)) + return ret; + + if (unlikely (ret < 0)) + { + /* DWARF failed. */ + if (is_plt_entry (&c->dwarf)) + { + Debug (2, "found plt entry\n"); + c->frame_info.frame_type = UNW_AARCH64_FRAME_STANDARD; + } + else + { + Debug (2, "fallback\n"); + c->frame_info.frame_type = UNW_AARCH64_FRAME_GUESSED; + } + /* Use link register (X30). */ + c->frame_info.cfa_reg_offset = 0; + c->frame_info.cfa_reg_sp = 0; + c->frame_info.fp_cfa_offset = -1; + c->frame_info.lr_cfa_offset = -1; + c->frame_info.sp_cfa_offset = -1; + c->dwarf.loc[UNW_AARCH64_PC] = c->dwarf.loc[UNW_AARCH64_X30]; + c->dwarf.loc[UNW_AARCH64_X30] = DWARF_NULL_LOC; + if (!DWARF_IS_NULL_LOC (c->dwarf.loc[UNW_AARCH64_PC])) + { + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); + if (ret < 0) + { + Debug (2, "failed to get pc from link register: %d\n", ret); + return ret; + } + Debug (2, "link register (x30) = 0x%016lx\n", c->dwarf.ip); + ret = 1; + } + else + c->dwarf.ip = 0; + } + + return (c->dwarf.ip == 0) ? 0 : 1; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gtrace.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gtrace.c new file mode 100644 index 00000000000000..c67faf0e357938 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gtrace.c @@ -0,0 +1,548 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + Copyright (C) 2014 CERN and Aalto University + Contributed by Filip Nyback + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" +#include +#include + +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific + +/* Initial hash table size. Table expands by 2 bits (times four). */ +#define HASH_MIN_BITS 14 + +typedef struct +{ + unw_tdep_frame_t *frames; + size_t log_size; + size_t used; + size_t dtor_count; /* Counts how many times our destructor has already + been called. */ +} unw_trace_cache_t; + +static const unw_tdep_frame_t empty_frame = { 0, UNW_AARCH64_FRAME_OTHER, -1, -1, 0, -1, -1, -1 }; +static define_lock (trace_init_lock); +static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; +static sig_atomic_t trace_cache_once_happen; +static pthread_key_t trace_cache_key; +static struct mempool trace_cache_pool; +static __thread unw_trace_cache_t *tls_cache; +static __thread int tls_cache_destroyed; + +/* Free memory for a thread's trace cache. */ +static void +trace_cache_free (void *arg) +{ + unw_trace_cache_t *cache = arg; + if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS) + { + /* Not yet our turn to get destroyed. Re-install ourselves into the key. */ + pthread_setspecific(trace_cache_key, cache); + Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, + PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); + return; + } + tls_cache_destroyed = 1; + tls_cache = NULL; + munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); + mempool_free (&trace_cache_pool, cache); + Debug(5, "freed cache %p\n", cache); +} + +/* Initialise frame tracing for threaded use. */ +static void +trace_cache_init_once (void) +{ + pthread_key_create (&trace_cache_key, &trace_cache_free); + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + trace_cache_once_happen = 1; +} + +static unw_tdep_frame_t * +trace_cache_buckets (size_t n) +{ + unw_tdep_frame_t *frames; + size_t i; + + GET_MEMORY(frames, n * sizeof (unw_tdep_frame_t)); + if (likely(frames != NULL)) + for (i = 0; i < n; ++i) + frames[i] = empty_frame; + + return frames; +} + +/* Allocate and initialise hash table for frame cache lookups. + Returns the cache initialised with (1u << HASH_LOW_BITS) hash + buckets, or NULL if there was a memory allocation problem. */ +static unw_trace_cache_t * +trace_cache_create (void) +{ + unw_trace_cache_t *cache; + + if (tls_cache_destroyed) + { + /* The current thread is in the process of exiting. Don't recreate + cache, as we wouldn't have another chance to free it. */ + Debug(5, "refusing to reallocate cache: " + "thread-locals are being deallocated\n"); + return NULL; + } + + if (! (cache = mempool_alloc(&trace_cache_pool))) + { + Debug(5, "failed to allocate cache\n"); + return NULL; + } + + if (! (cache->frames = trace_cache_buckets(1u << HASH_MIN_BITS))) + { + Debug(5, "failed to allocate buckets\n"); + mempool_free(&trace_cache_pool, cache); + return NULL; + } + + cache->log_size = HASH_MIN_BITS; + cache->used = 0; + cache->dtor_count = 0; + tls_cache_destroyed = 0; /* Paranoia: should already be 0. */ + Debug(5, "allocated cache %p\n", cache); + return cache; +} + +/* Expand the hash table in the frame cache if possible. This always + quadruples the hash size, and clears all previous frame entries. */ +static int +trace_cache_expand (unw_trace_cache_t *cache) +{ + size_t old_size = (1u << cache->log_size); + size_t new_log_size = cache->log_size + 2; + unw_tdep_frame_t *new_frames = trace_cache_buckets (1u << new_log_size); + + if (unlikely(! new_frames)) + { + Debug(5, "failed to expand cache to 2^%lu buckets\n", new_log_size); + return -UNW_ENOMEM; + } + + Debug(5, "expanded cache from 2^%lu to 2^%lu buckets\n", cache->log_size, new_log_size); + munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); + cache->frames = new_frames; + cache->log_size = new_log_size; + cache->used = 0; + return 0; +} + +static unw_trace_cache_t * +trace_cache_get_unthreaded (void) +{ + unw_trace_cache_t *cache; + intrmask_t saved_mask; + static unw_trace_cache_t *global_cache = NULL; + lock_acquire (&trace_init_lock, saved_mask); + if (! global_cache) + { + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + global_cache = trace_cache_create (); + } + cache = global_cache; + lock_release (&trace_init_lock, saved_mask); + Debug(5, "using cache %p\n", cache); + return cache; +} + +/* Get the frame cache for the current thread. Create it if there is none. */ +static unw_trace_cache_t * +trace_cache_get (void) +{ + unw_trace_cache_t *cache; + if (likely (pthread_once != NULL)) + { + pthread_once(&trace_cache_once, &trace_cache_init_once); + if (!trace_cache_once_happen) + { + return trace_cache_get_unthreaded(); + } + if (! (cache = tls_cache)) + { + cache = trace_cache_create(); + pthread_setspecific(trace_cache_key, cache); + tls_cache = cache; + } + Debug(5, "using cache %p\n", cache); + return cache; + } + else + { + return trace_cache_get_unthreaded(); + } +} + +/* Initialise frame properties for address cache slot F at address + PC using current CFA, FP and SP values. Modifies CURSOR to + that location, performs one unw_step(), and fills F with what + was discovered about the location. Returns F. + + FIXME: This probably should tell DWARF handling to never evaluate + or use registers other than FP, SP and PC in case there is + highly unusual unwind info which uses these creatively. */ +static unw_tdep_frame_t * +trace_init_addr (unw_tdep_frame_t *f, + unw_cursor_t *cursor, + unw_word_t cfa, + unw_word_t pc, + unw_word_t fp, + unw_word_t sp) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + int ret = -UNW_EINVAL; + + /* Initialise frame properties: unknown, not last. */ + f->virtual_address = pc; + f->frame_type = UNW_AARCH64_FRAME_OTHER; + f->last_frame = 0; + f->cfa_reg_sp = -1; + f->cfa_reg_offset = 0; + f->fp_cfa_offset = -1; + f->lr_cfa_offset = -1; + f->sp_cfa_offset = -1; + + /* Reinitialise cursor to this instruction - but undo next/prev PC + adjustment because unw_step will redo it - and force PC, FP and + SP into register locations (=~ ucontext we keep), then set + their desired values. Then perform the step. */ + d->ip = pc + d->use_prev_instr; + d->cfa = cfa; + d->loc[UNW_AARCH64_X29] = DWARF_REG_LOC (d, UNW_AARCH64_X29); + d->loc[UNW_AARCH64_SP] = DWARF_REG_LOC (d, UNW_AARCH64_SP); + d->loc[UNW_AARCH64_PC] = DWARF_REG_LOC (d, UNW_AARCH64_PC); + c->frame_info = *f; + + if (likely(dwarf_put (d, d->loc[UNW_AARCH64_X29], fp) >= 0) + && likely(dwarf_put (d, d->loc[UNW_AARCH64_SP], sp) >= 0) + && likely(dwarf_put (d, d->loc[UNW_AARCH64_PC], pc) >= 0) + && likely((ret = unw_step (cursor)) >= 0)) + *f = c->frame_info; + + /* If unw_step() stopped voluntarily, remember that, even if it + otherwise could not determine anything useful. This avoids + failing trace if we hit frames without unwind info, which is + common for the outermost frame (CRT stuff) on many systems. + This avoids failing trace in very common circumstances; failing + to unw_step() loop wouldn't produce any better result. */ + if (ret == 0) + f->last_frame = -1; + + Debug (3, "frame va %lx type %d last %d cfa %s+%d fp @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_sp ? "sp" : "fp", f->cfa_reg_offset, + f->fp_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); + + return f; +} + +/* Look up and if necessary fill in frame attributes for address PC + in CACHE using current CFA, FP and SP values. Uses CURSOR to + perform any unwind steps necessary to fill the cache. Returns the + frame cache slot which describes RIP. */ +static unw_tdep_frame_t * +trace_lookup (unw_cursor_t *cursor, + unw_trace_cache_t *cache, + unw_word_t cfa, + unw_word_t pc, + unw_word_t fp, + unw_word_t sp) +{ + /* First look up for previously cached information using cache as + linear probing hash table with probe step of 1. Majority of + lookups should be completed within few steps, but it is very + important the hash table does not fill up, or performance falls + off the cliff. */ + uint64_t i, addr; + uint64_t cache_size = 1u << cache->log_size; + uint64_t slot = ((pc * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); + unw_tdep_frame_t *frame; + + for (i = 0; i < 16; ++i) + { + frame = &cache->frames[slot]; + addr = frame->virtual_address; + + /* Return if we found the address. */ + if (likely(addr == pc)) + { + Debug (4, "found address after %ld steps\n", i); + return frame; + } + + /* If slot is empty, reuse it. */ + if (likely(! addr)) + break; + + /* Linear probe to next slot candidate, step = 1. */ + if (++slot >= cache_size) + slot -= cache_size; + } + + /* If we collided after 16 steps, or if the hash is more than half + full, force the hash to expand. Fill the selected slot, whether + it's free or collides. Note that hash expansion drops previous + contents; further lookups will refill the hash. */ + Debug (4, "updating slot %lu after %ld steps, replacing 0x%lx\n", slot, i, addr); + if (unlikely(addr || cache->used >= cache_size / 2)) + { + if (unlikely(trace_cache_expand (cache) < 0)) + return NULL; + + cache_size = 1u << cache->log_size; + slot = ((pc * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); + frame = &cache->frames[slot]; + addr = frame->virtual_address; + } + + if (! addr) + ++cache->used; + + return trace_init_addr (frame, cursor, cfa, pc, fp, sp); +} + +/* Fast stack backtrace for AArch64. + + This is used by backtrace() implementation to accelerate frequent + queries for current stack, without any desire to unwind. It fills + BUFFER with the call tree from CURSOR upwards for at most SIZE + stack levels. The first frame, backtrace itself, is omitted. When + called, SIZE should give the maximum number of entries that can be + stored into BUFFER. Uses an internal thread-specific cache to + accelerate queries. + + The caller should fall back to a unw_step() loop if this function + fails by returning -UNW_ESTOPUNWIND, meaning the routine hit a + stack frame that is too complex to be traced in the fast path. + + This function is tuned for clients which only need to walk the + stack to get the call tree as fast as possible but without any + other details, for example profilers sampling the stack thousands + to millions of times per second. The routine handles the most + common AArch64 ABI stack layouts: CFA is FP or SP plus/minus + constant offset, return address is in LR, and FP, LR and SP are + either unchanged or saved on stack at constant offset from the CFA; + the signal return frame; and frames without unwind info provided + they are at the outermost (final) frame or can conservatively be + assumed to be frame-pointer based. + + Any other stack layout will cause the routine to give up. There + are only a handful of relatively rarely used functions which do + not have a stack in the standard form: vfork, longjmp, setcontext + and _dl_runtime_profile on common linux systems for example. + + On success BUFFER and *SIZE reflect the trace progress up to *SIZE + stack levels or the outermost frame, which ever is less. It may + stop short of outermost frame if unw_step() loop would also do so, + e.g. if there is no more unwind information; this is not reported + as an error. + + The function returns a negative value for errors, -UNW_ESTOPUNWIND + if tracing stopped because of an unusual frame unwind info. The + BUFFER and *SIZE reflect tracing progress up to the error frame. + + Callers of this function would normally look like this: + + unw_cursor_t cur; + unw_context_t ctx; + void addrs[128]; + int depth = 128; + int ret; + + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + if ((ret = unw_tdep_trace(&cur, addrs, &depth)) < 0) + { + depth = 0; + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + while ((ret = unw_step(&cur)) > 0 && depth < 128) + { + unw_word_t ip; + unw_get_reg(&cur, UNW_REG_IP, &ip); + addresses[depth++] = (void *) ip; + } + } +*/ +HIDDEN int +tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + unw_trace_cache_t *cache; + unw_word_t fp, sp, pc, cfa, lr; + int maxdepth = 0; + int depth = 0; + int ret; + + /* Check input parametres. */ + if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) + return -UNW_EINVAL; + + Debug (1, "begin ip 0x%lx cfa 0x%lx\n", d->ip, d->cfa); + + /* Tell core dwarf routines to call back to us. */ + d->stash_frames = 1; + + /* Determine initial register values. These are direct access safe + because we know they come from the initial machine context. */ + pc = d->ip; + sp = cfa = d->cfa; + ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_AARCH64_X29]), fp); + assert(ret == 0); + lr = 0; + + /* Get frame cache. */ + if (unlikely(! (cache = trace_cache_get()))) + { + Debug (1, "returning %d, cannot get trace cache\n", -UNW_ENOMEM); + *size = 0; + d->stash_frames = 0; + return -UNW_ENOMEM; + } + + /* Trace the stack upwards, starting from current RIP. Adjust + the RIP address for previous/next instruction as the main + unwinding logic would also do. We undo this before calling + back into unw_step(). */ + while (depth < maxdepth) + { + pc -= d->use_prev_instr; + Debug (2, "depth %d cfa 0x%lx pc 0x%lx sp 0x%lx fp 0x%lx\n", + depth, cfa, pc, sp, fp); + + /* See if we have this address cached. If not, evaluate enough of + the dwarf unwind information to fill the cache line data, or to + decide this frame cannot be handled in fast trace mode. We + cache negative results too to prevent unnecessary dwarf parsing + for common failures. */ + unw_tdep_frame_t *f = trace_lookup (cursor, cache, cfa, pc, fp, sp); + + /* If we don't have information for this frame, give up. */ + if (unlikely(! f)) + { + ret = -UNW_ENOINFO; + break; + } + + Debug (3, "frame va %lx type %d last %d cfa %s+%d fp @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_sp ? "sp" : "fp", f->cfa_reg_offset, + f->fp_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); + + assert (f->virtual_address == pc); + + /* Stop if this was the last frame. In particular don't evaluate + new register values as it may not be safe - we don't normally + run with full validation on, and do not want to - and there's + enough bad unwind info floating around that we need to trust + what unw_step() previously said, in potentially bogus frames. */ + if (f->last_frame) + break; + + /* Evaluate CFA and registers for the next frame. */ + switch (f->frame_type) + { + case UNW_AARCH64_FRAME_GUESSED: + /* Fall thru to standard processing after forcing validation. */ + c->validate = 1; + + case UNW_AARCH64_FRAME_STANDARD: + /* Advance standard traceable frame. */ + cfa = (f->cfa_reg_sp ? sp : fp) + f->cfa_reg_offset; + if (likely(f->lr_cfa_offset != -1)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc); + else if (lr != 0) + { + /* Use the saved link register as the new pc. */ + pc = lr; + lr = 0; + } + if (likely(ret >= 0) && likely(f->fp_cfa_offset != -1)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->fp_cfa_offset, fp); + + /* Don't bother reading SP from DWARF, CFA becomes new SP. */ + sp = cfa; + + /* Next frame needs to back up for unwind info lookup. */ + d->use_prev_instr = 1; + break; + + case UNW_AARCH64_FRAME_SIGRETURN: + cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ + + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_PC_OFF, pc); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_X29_OFF, fp); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_SP_OFF, sp); + /* Save the link register here in case we end up in a function that + doesn't save the link register in the prologue, e.g. kill. */ + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_X30_OFF, lr); + + /* Resume stack at signal restoration point. The stack is not + necessarily continuous here, especially with sigaltstack(). */ + cfa = sp; + + /* Next frame should not back up. */ + d->use_prev_instr = 0; + break; + + default: + /* We cannot trace through this frame, give up and tell the + caller we had to stop. Data collected so far may still be + useful to the caller, so let it know how far we got. */ + ret = -UNW_ESTOPUNWIND; + break; + } + + Debug (4, "new cfa 0x%lx pc 0x%lx sp 0x%lx fp 0x%lx\n", + cfa, pc, sp, fp); + + /* If we failed or ended up somewhere bogus, stop. */ + if (unlikely(ret < 0 || pc < 0x4000)) + break; + + /* Record this address in stack trace. We skipped the first address. */ + buffer[depth++] = (void *) (pc - d->use_prev_instr); + } + +#if UNW_DEBUG + Debug (1, "returning %d, depth %d\n", ret, depth); +#endif + *size = depth; + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lglobal.c new file mode 100644 index 00000000000000..6d7b489e14bd9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lis_signal_frame.c new file mode 100644 index 00000000000000..b9a7c4f51ad9fa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstash_frame.c new file mode 100644 index 00000000000000..77587803d083d7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstash_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstash_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ltrace.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ltrace.c new file mode 100644 index 00000000000000..fcd3f239c9e422 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ltrace.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gtrace.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/gen-offsets.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/gen-offsets.c new file mode 100644 index 00000000000000..eadc2377d8f7a7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/gen-offsets.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +#define UC(N,X) \ + printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) + +#define SC(N,X) \ + printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) + +int +main (void) +{ + printf ( +"/* Linux-specific definitions: */\n\n" + +"/* Define various structure offsets to simplify cross-compilation. */\n\n" + +"/* Offsets for AArch64 Linux \"ucontext_t\": */\n\n"); + + UC ("FLAGS", uc_flags); + UC ("LINK", uc_link); + UC ("STACK", uc_stack); + UC ("MCONTEXT", uc_mcontext); + UC ("SIGMASK", uc_sigmask); + + printf ("\n/* Offsets for AArch64 Linux \"struct sigcontext\": */\n\n"); + + SC ("R0", regs[0]); + SC ("R1", regs[1]); + SC ("R2", regs[2]); + SC ("R3", regs[3]); + SC ("R4", regs[4]); + SC ("R5", regs[5]); + SC ("R6", regs[6]); + SC ("R7", regs[7]); + SC ("R8", regs[8]); + SC ("R9", regs[9]); + SC ("R10", regs[10]); + SC ("R11", regs[11]); + SC ("R12", regs[12]); + SC ("R13", regs[13]); + SC ("R14", regs[14]); + SC ("R15", regs[15]); + SC ("R16", regs[16]); + SC ("R17", regs[17]); + SC ("R18", regs[18]); + SC ("R19", regs[19]); + SC ("R20", regs[20]); + SC ("R21", regs[21]); + SC ("R22", regs[22]); + SC ("R23", regs[23]); + SC ("R24", regs[24]); + SC ("R25", regs[25]); + SC ("R26", regs[26]); + SC ("R27", regs[27]); + SC ("R28", regs[28]); + SC ("R29", regs[29]); + SC ("R30", regs[30]); + SC ("R31", regs[31]); + + SC ("PC", pc); + SC ("SP", sp); + SC ("Fault", fault_address); + SC ("state", pstate); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/aarch64/getcontext.S new file mode 100644 index 00000000000000..25ed5b66be73ea --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/getcontext.S @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 Google, Inc + Contributed by Paul Pluzhnikov + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" + +/* int _Uaarch64_getcontext_trace (unw_tdep_context_t *ucp) + + Saves limited machine context in UCP necessary for fast trace. If fast trace + fails, caller will have to get the full context. +*/ + + .global _Uaarch64_getcontext_trace + .hidden _Uaarch64_getcontext_trace + .type _Uaarch64_getcontext_trace, @function +_Uaarch64_getcontext_trace: + .cfi_startproc + + /* Save only FP, SP, PC - exclude this call. */ + str x29, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_X29_OFF)] + mov x9, sp + str x9, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_SP_OFF)] + str x30, [x0, #(LINUX_UC_MCONTEXT_OFF + LINUX_SC_PC_OFF)] + + ret + .cfi_endproc + .size _Uaarch64_getcontext_trace, . - _Uaarch64_getcontext_trace + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/init.h b/src/coreclr/src/pal/src/libunwind/src/aarch64/init.h new file mode 100644 index 00000000000000..5dab60bb64ed71 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/init.h @@ -0,0 +1,126 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + 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. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret, i; + + c->dwarf.loc[UNW_AARCH64_X0] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X0); + c->dwarf.loc[UNW_AARCH64_X1] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X1); + c->dwarf.loc[UNW_AARCH64_X2] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X2); + c->dwarf.loc[UNW_AARCH64_X3] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X3); + c->dwarf.loc[UNW_AARCH64_X4] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X4); + c->dwarf.loc[UNW_AARCH64_X5] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X5); + c->dwarf.loc[UNW_AARCH64_X6] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X6); + c->dwarf.loc[UNW_AARCH64_X7] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X7); + c->dwarf.loc[UNW_AARCH64_X8] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X8); + c->dwarf.loc[UNW_AARCH64_X9] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X9); + c->dwarf.loc[UNW_AARCH64_X10] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X10); + c->dwarf.loc[UNW_AARCH64_X11] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X11); + c->dwarf.loc[UNW_AARCH64_X12] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X12); + c->dwarf.loc[UNW_AARCH64_X13] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X13); + c->dwarf.loc[UNW_AARCH64_X14] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X14); + c->dwarf.loc[UNW_AARCH64_X15] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X15); + c->dwarf.loc[UNW_AARCH64_X16] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X16); + c->dwarf.loc[UNW_AARCH64_X17] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X17); + c->dwarf.loc[UNW_AARCH64_X18] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X18); + c->dwarf.loc[UNW_AARCH64_X19] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X19); + c->dwarf.loc[UNW_AARCH64_X20] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X20); + c->dwarf.loc[UNW_AARCH64_X21] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X21); + c->dwarf.loc[UNW_AARCH64_X22] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X22); + c->dwarf.loc[UNW_AARCH64_X23] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X23); + c->dwarf.loc[UNW_AARCH64_X24] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X24); + c->dwarf.loc[UNW_AARCH64_X25] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X25); + c->dwarf.loc[UNW_AARCH64_X26] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X26); + c->dwarf.loc[UNW_AARCH64_X27] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X27); + c->dwarf.loc[UNW_AARCH64_X28] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X28); + c->dwarf.loc[UNW_AARCH64_X29] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X29); + c->dwarf.loc[UNW_AARCH64_X30] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_X30); + c->dwarf.loc[UNW_AARCH64_SP] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_SP); + c->dwarf.loc[UNW_AARCH64_PC] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_PC); + c->dwarf.loc[UNW_AARCH64_PSTATE] = DWARF_REG_LOC (&c->dwarf, + UNW_AARCH64_PSTATE); + c->dwarf.loc[UNW_AARCH64_V0] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V0); + c->dwarf.loc[UNW_AARCH64_V1] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V1); + c->dwarf.loc[UNW_AARCH64_V2] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V2); + c->dwarf.loc[UNW_AARCH64_V3] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V3); + c->dwarf.loc[UNW_AARCH64_V4] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V4); + c->dwarf.loc[UNW_AARCH64_V5] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V5); + c->dwarf.loc[UNW_AARCH64_V6] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V6); + c->dwarf.loc[UNW_AARCH64_V7] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V7); + c->dwarf.loc[UNW_AARCH64_V8] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V8); + c->dwarf.loc[UNW_AARCH64_V9] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V9); + c->dwarf.loc[UNW_AARCH64_V10] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V10); + c->dwarf.loc[UNW_AARCH64_V11] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V11); + c->dwarf.loc[UNW_AARCH64_V12] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V12); + c->dwarf.loc[UNW_AARCH64_V13] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V13); + c->dwarf.loc[UNW_AARCH64_V14] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V14); + c->dwarf.loc[UNW_AARCH64_V15] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V15); + c->dwarf.loc[UNW_AARCH64_V16] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V16); + c->dwarf.loc[UNW_AARCH64_V17] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V17); + c->dwarf.loc[UNW_AARCH64_V18] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V18); + c->dwarf.loc[UNW_AARCH64_V19] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V19); + c->dwarf.loc[UNW_AARCH64_V20] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V20); + c->dwarf.loc[UNW_AARCH64_V21] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V21); + c->dwarf.loc[UNW_AARCH64_V22] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V22); + c->dwarf.loc[UNW_AARCH64_V23] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V23); + c->dwarf.loc[UNW_AARCH64_V24] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V24); + c->dwarf.loc[UNW_AARCH64_V25] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V25); + c->dwarf.loc[UNW_AARCH64_V26] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V26); + c->dwarf.loc[UNW_AARCH64_V27] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V27); + c->dwarf.loc[UNW_AARCH64_V28] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V28); + c->dwarf.loc[UNW_AARCH64_V29] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V29); + c->dwarf.loc[UNW_AARCH64_V30] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V30); + c->dwarf.loc[UNW_AARCH64_V31] = DWARF_REG_LOC (&c->dwarf, UNW_AARCH64_V31); + + for (i = UNW_AARCH64_PSTATE + 1; i < UNW_AARCH64_V0; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_SP], &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = AARCH64_SCF_NONE; + c->sigcontext_addr = 0; + c->sigcontext_sp = 0; + c->sigcontext_pc = 0; + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/is_fpreg.c new file mode 100644 index 00000000000000..2981d27520bb9b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/is_fpreg.c @@ -0,0 +1,32 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + 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. */ + +#include "libunwind_i.h" + +int +unw_is_fpreg (int regnum) +{ + return (regnum >= UNW_AARCH64_V0 && regnum <= UNW_AARCH64_V31); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/offsets.h b/src/coreclr/src/pal/src/libunwind/src/aarch64/offsets.h new file mode 100644 index 00000000000000..e78251d0a8f82c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/offsets.h @@ -0,0 +1,49 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* Offsets for AArch64 Linux "ucontext_t": */ + +#define LINUX_UC_FLAGS_OFF 0x0 +#define LINUX_UC_LINK_OFF 0x8 +#define LINUX_UC_STACK_OFF 0x10 +#define LINUX_UC_SIGMASK_OFF 0x28 +#define LINUX_UC_MCONTEXT_OFF 0xb0 + +/* Offsets for AArch64 Linux "struct sigcontext": */ + +#define LINUX_SC_FAULTADDRESS_OFF 0x00 +#define LINUX_SC_X0_OFF 0x008 +#define LINUX_SC_X1_OFF 0x010 +#define LINUX_SC_X2_OFF 0x018 +#define LINUX_SC_X3_OFF 0x020 +#define LINUX_SC_X4_OFF 0x028 +#define LINUX_SC_X5_OFF 0x030 +#define LINUX_SC_X6_OFF 0x038 +#define LINUX_SC_X7_OFF 0x040 +#define LINUX_SC_X8_OFF 0x048 +#define LINUX_SC_X9_OFF 0x050 +#define LINUX_SC_X10_OFF 0x058 +#define LINUX_SC_X11_OFF 0x060 +#define LINUX_SC_X12_OFF 0x068 +#define LINUX_SC_X13_OFF 0x070 +#define LINUX_SC_X14_OFF 0x078 +#define LINUX_SC_X15_OFF 0x080 +#define LINUX_SC_X16_OFF 0x088 +#define LINUX_SC_X17_OFF 0x090 +#define LINUX_SC_X18_OFF 0x098 +#define LINUX_SC_X19_OFF 0x0a0 +#define LINUX_SC_X20_OFF 0x0a8 +#define LINUX_SC_X21_OFF 0x0b0 +#define LINUX_SC_X22_OFF 0x0b8 +#define LINUX_SC_X23_OFF 0x0c0 +#define LINUX_SC_X24_OFF 0x0c8 +#define LINUX_SC_X25_OFF 0x0d0 +#define LINUX_SC_X26_OFF 0x0d8 +#define LINUX_SC_X27_OFF 0x0e0 +#define LINUX_SC_X28_OFF 0x0e8 +#define LINUX_SC_X29_OFF 0x0f0 +#define LINUX_SC_X30_OFF 0x0f8 +#define LINUX_SC_SP_OFF 0x100 +#define LINUX_SC_PC_OFF 0x108 +#define LINUX_SC_PSTATE_OFF 0x110 diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/regname.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/regname.c new file mode 100644 index 00000000000000..0f7a8bdcfbf559 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/regname.c @@ -0,0 +1,106 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + 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. */ + +#include "unwind_i.h" + +static const char *const regname[] = + { + [UNW_AARCH64_X0] = "x0", + [UNW_AARCH64_X1] = "x1", + [UNW_AARCH64_X2] = "x2", + [UNW_AARCH64_X3] = "x3", + [UNW_AARCH64_X4] = "x4", + [UNW_AARCH64_X5] = "x5", + [UNW_AARCH64_X6] = "x6", + [UNW_AARCH64_X7] = "x7", + [UNW_AARCH64_X8] = "x8", + [UNW_AARCH64_X9] = "x9", + [UNW_AARCH64_X10] = "x10", + [UNW_AARCH64_X11] = "x11", + [UNW_AARCH64_X12] = "x12", + [UNW_AARCH64_X13] = "x13", + [UNW_AARCH64_X14] = "x14", + [UNW_AARCH64_X15] = "x15", + [UNW_AARCH64_X16] = "ip0", + [UNW_AARCH64_X17] = "ip1", + [UNW_AARCH64_X18] = "x18", + [UNW_AARCH64_X19] = "x19", + [UNW_AARCH64_X20] = "x20", + [UNW_AARCH64_X21] = "x21", + [UNW_AARCH64_X22] = "x22", + [UNW_AARCH64_X23] = "x23", + [UNW_AARCH64_X24] = "x24", + [UNW_AARCH64_X25] = "x25", + [UNW_AARCH64_X26] = "x26", + [UNW_AARCH64_X27] = "x27", + [UNW_AARCH64_X28] = "x28", + [UNW_AARCH64_X29] = "fp", + [UNW_AARCH64_X30] = "lr", + [UNW_AARCH64_SP] = "sp", + [UNW_AARCH64_PC] = "pc", + [UNW_AARCH64_V0] = "v0", + [UNW_AARCH64_V1] = "v1", + [UNW_AARCH64_V2] = "v2", + [UNW_AARCH64_V3] = "v3", + [UNW_AARCH64_V4] = "v4", + [UNW_AARCH64_V5] = "v5", + [UNW_AARCH64_V6] = "v6", + [UNW_AARCH64_V7] = "v7", + [UNW_AARCH64_V8] = "v8", + [UNW_AARCH64_V9] = "v9", + [UNW_AARCH64_V10] = "v10", + [UNW_AARCH64_V11] = "v11", + [UNW_AARCH64_V12] = "v12", + [UNW_AARCH64_V13] = "v13", + [UNW_AARCH64_V14] = "v14", + [UNW_AARCH64_V15] = "v15", + [UNW_AARCH64_V16] = "v16", + [UNW_AARCH64_V17] = "v17", + [UNW_AARCH64_V18] = "v18", + [UNW_AARCH64_V19] = "v19", + [UNW_AARCH64_V20] = "v20", + [UNW_AARCH64_V21] = "v21", + [UNW_AARCH64_V22] = "v22", + [UNW_AARCH64_V23] = "v23", + [UNW_AARCH64_V24] = "v24", + [UNW_AARCH64_V25] = "v25", + [UNW_AARCH64_V26] = "v26", + [UNW_AARCH64_V27] = "v27", + [UNW_AARCH64_V28] = "v28", + [UNW_AARCH64_V29] = "v29", + [UNW_AARCH64_V30] = "v30", + [UNW_AARCH64_V31] = "v31", + [UNW_AARCH64_FPSR] = "fpsr", + [UNW_AARCH64_FPCR] = "fpcr", + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname) && regname[reg] != NULL) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/aarch64/siglongjmp.S new file mode 100644 index 00000000000000..9985c4b4aab378 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/siglongjmp.S @@ -0,0 +1,12 @@ + /* Dummy implementation for now. */ + + .global _UI_siglongjmp_cont + .global _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + ret +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",%progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h new file mode 100644 index 00000000000000..db7e29dd722e91 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h @@ -0,0 +1,64 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + 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 unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" + +/* DWARF column numbers for AArch64: */ +#define X29 29 +#define FP 29 +#define X30 30 +#define LR 30 +#define SP 31 + +#define aarch64_lock UNW_OBJ(lock) +#define aarch64_local_resume UNW_OBJ(local_resume) +#define aarch64_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern void aarch64_local_addr_space_init (void); +extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); + +/* By-pass calls to access_mem() when known to be safe. */ +#ifdef UNW_LOCAL_ONLY +# undef ACCESS_MEM_FAST +# define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ + do { \ + if (unlikely(validate)) \ + (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); \ + else \ + (ret) = 0, (to) = *(unw_word_t *)(addr); \ + } while (0) +#endif + +#define GET_FPCTX(uc) ((unw_fpsimd_context_t *)(&uc->uc_mcontext.__reserved)) + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gcreate_addr_space.c new file mode 100644 index 00000000000000..7b2d6bacfdcd7d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gcreate_addr_space.c @@ -0,0 +1,60 @@ +/* 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. */ + +#include + +#include "unwind_i.h" + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * ARM supports little-endian and big-endian. + */ + if (byte_order != 0 && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + /* Default to little-endian for ARM. */ + if (byte_order == 0 || byte_order == __LITTLE_ENDIAN) + as->big_endian = 0; + else + as->big_endian = 1; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c new file mode 100644 index 00000000000000..d6573a65e0c7d9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c @@ -0,0 +1,549 @@ +/* libunwind - a platform-independent unwind library + Copyright 2011 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. */ + +/* This file contains functionality for parsing and interpreting the ARM +specific unwind information. Documentation about the exception handling +ABI for the ARM architecture can be found at: +http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf +*/ + +#include "libunwind_i.h" + +#define ARM_EXBUF_START(x) (((x) >> 4) & 0x0f) +#define ARM_EXBUF_COUNT(x) ((x) & 0x0f) +#define ARM_EXBUF_END(x) (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x)) + +#define ARM_EXIDX_CANT_UNWIND 0x00000001 +#define ARM_EXIDX_COMPACT 0x80000000 + +#define ARM_EXTBL_OP_FINISH 0xb0 + +enum arm_exbuf_cmd_flags { + ARM_EXIDX_VFP_SHIFT_16 = 1 << 16, + ARM_EXIDX_VFP_DOUBLE = 1 << 17, +}; + +struct arm_cb_data + { + /* in: */ + unw_word_t ip; /* instruction-pointer we're looking for */ + unw_proc_info_t *pi; /* proc-info pointer */ + /* out: */ + unw_dyn_info_t di; /* info about the ARM exidx segment */ + }; + +static inline uint32_t CONST_ATTR +prel31_read (uint32_t prel31) +{ + return ((int32_t)prel31 << 1) >> 1; +} + +static inline int +prel31_to_addr (unw_addr_space_t as, void *arg, unw_word_t prel31, + unw_word_t *val) +{ + unw_word_t offset; + + if ((*as->acc.access_mem)(as, prel31, &offset, 0, arg) < 0) + return -UNW_EINVAL; + + offset = ((long)offset << 1) >> 1; + *val = prel31 + offset; + + return 0; +} + +/** + * Applies the given command onto the new state to the given dwarf_cursor. + */ +HIDDEN int +arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c) +{ + int ret = 0; + unsigned i; + + switch (edata->cmd) + { + case ARM_EXIDX_CMD_FINISH: + /* Set LR to PC if not set already. */ + if (DWARF_IS_NULL_LOC (c->loc[UNW_ARM_R15])) + c->loc[UNW_ARM_R15] = c->loc[UNW_ARM_R14]; + /* Set IP. */ + dwarf_get (c, c->loc[UNW_ARM_R15], &c->ip); + break; + case ARM_EXIDX_CMD_DATA_PUSH: + Debug (2, "vsp = vsp - %d\n", edata->data); + c->cfa -= edata->data; + break; + case ARM_EXIDX_CMD_DATA_POP: + Debug (2, "vsp = vsp + %d\n", edata->data); + c->cfa += edata->data; + break; + case ARM_EXIDX_CMD_REG_POP: + for (i = 0; i < 16; i++) + if (edata->data & (1 << i)) + { + Debug (2, "pop {r%d}\n", i); + c->loc[UNW_ARM_R0 + i] = DWARF_LOC (c->cfa, 0); + c->cfa += 4; + } + /* Set cfa in case the SP got popped. */ + if (edata->data & (1 << 13)) + dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa); + break; + case ARM_EXIDX_CMD_REG_TO_SP: + assert (edata->data < 16); + Debug (2, "vsp = r%d\n", edata->data); + c->loc[UNW_ARM_R13] = c->loc[UNW_ARM_R0 + edata->data]; + dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa); + break; + case ARM_EXIDX_CMD_VFP_POP: + /* Skip VFP registers, but be sure to adjust stack */ + for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data); + i++) + c->cfa += 8; + if (!(edata->data & ARM_EXIDX_VFP_DOUBLE)) + c->cfa += 4; + break; + case ARM_EXIDX_CMD_WREG_POP: + for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data); + i++) + c->cfa += 8; + break; + case ARM_EXIDX_CMD_WCGR_POP: + for (i = 0; i < 4; i++) + if (edata->data & (1 << i)) + c->cfa += 4; + break; + case ARM_EXIDX_CMD_REFUSED: + case ARM_EXIDX_CMD_RESERVED: + ret = -1; + break; + } + return ret; +} + +/** + * Decodes the given unwind instructions into arm_exbuf_data and calls + * arm_exidx_apply_cmd that applies the command onto the dwarf_cursor. + */ +HIDDEN int +arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c) +{ +#define READ_OP() *buf++ + const uint8_t *end = buf + len; + int ret; + struct arm_exbuf_data edata; + + assert(buf != NULL); + assert(len > 0); + + while (buf < end) + { + uint8_t op = READ_OP (); + if ((op & 0xc0) == 0x00) + { + edata.cmd = ARM_EXIDX_CMD_DATA_POP; + edata.data = (((int)op & 0x3f) << 2) + 4; + } + else if ((op & 0xc0) == 0x40) + { + edata.cmd = ARM_EXIDX_CMD_DATA_PUSH; + edata.data = (((int)op & 0x3f) << 2) + 4; + } + else if ((op & 0xf0) == 0x80) + { + uint8_t op2 = READ_OP (); + if (op == 0x80 && op2 == 0x00) + edata.cmd = ARM_EXIDX_CMD_REFUSED; + else + { + edata.cmd = ARM_EXIDX_CMD_REG_POP; + edata.data = ((op & 0xf) << 8) | op2; + edata.data = edata.data << 4; + } + } + else if ((op & 0xf0) == 0x90) + { + if (op == 0x9d || op == 0x9f) + edata.cmd = ARM_EXIDX_CMD_RESERVED; + else + { + edata.cmd = ARM_EXIDX_CMD_REG_TO_SP; + edata.data = op & 0x0f; + } + } + else if ((op & 0xf0) == 0xa0) + { + unsigned end = (op & 0x07); + edata.data = (1 << (end + 1)) - 1; + edata.data = edata.data << 4; + if (op & 0x08) + edata.data |= 1 << 14; + edata.cmd = ARM_EXIDX_CMD_REG_POP; + } + else if (op == ARM_EXTBL_OP_FINISH) + { + edata.cmd = ARM_EXIDX_CMD_FINISH; + buf = end; + } + else if (op == 0xb1) + { + uint8_t op2 = READ_OP (); + if (op2 == 0 || (op2 & 0xf0)) + edata.cmd = ARM_EXIDX_CMD_RESERVED; + else + { + edata.cmd = ARM_EXIDX_CMD_REG_POP; + edata.data = op2 & 0x0f; + } + } + else if (op == 0xb2) + { + uint32_t offset = 0; + uint8_t byte, shift = 0; + do + { + byte = READ_OP (); + offset |= (byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + edata.data = offset * 4 + 0x204; + edata.cmd = ARM_EXIDX_CMD_DATA_POP; + } + else if (op == 0xb3 || op == 0xc8 || op == 0xc9) + { + edata.cmd = ARM_EXIDX_CMD_VFP_POP; + edata.data = READ_OP (); + if (op == 0xc8) + edata.data |= ARM_EXIDX_VFP_SHIFT_16; + if (op != 0xb3) + edata.data |= ARM_EXIDX_VFP_DOUBLE; + } + else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0) + { + edata.cmd = ARM_EXIDX_CMD_VFP_POP; + edata.data = 0x80 | (op & 0x07); + if ((op & 0xf8) == 0xd0) + edata.data |= ARM_EXIDX_VFP_DOUBLE; + } + else if (op >= 0xc0 && op <= 0xc5) + { + edata.cmd = ARM_EXIDX_CMD_WREG_POP; + edata.data = 0xa0 | (op & 0x07); + } + else if (op == 0xc6) + { + edata.cmd = ARM_EXIDX_CMD_WREG_POP; + edata.data = READ_OP (); + } + else if (op == 0xc7) + { + uint8_t op2 = READ_OP (); + if (op2 == 0 || (op2 & 0xf0)) + edata.cmd = ARM_EXIDX_CMD_RESERVED; + else + { + edata.cmd = ARM_EXIDX_CMD_WCGR_POP; + edata.data = op2 & 0x0f; + } + } + else + edata.cmd = ARM_EXIDX_CMD_RESERVED; + + ret = arm_exidx_apply_cmd (&edata, c); + if (ret < 0) + return ret; + } + return 0; +} + +/** + * Reads the entry from the given cursor and extracts the unwind instructions + * into buf. Returns the number of the extracted unwind insns or + * -UNW_ESTOPUNWIND if the special bit pattern ARM_EXIDX_CANT_UNWIND (0x1) was + * found. + */ +HIDDEN int +arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf) +{ + int nbuf = 0; + unw_word_t entry = (unw_word_t) c->pi.unwind_info; + unw_word_t addr; + uint32_t data; + + /* An ARM unwind entry consists of a prel31 offset to the start of a + function followed by 31bits of data: + * if set to 0x1: the function cannot be unwound (EXIDX_CANTUNWIND) + * if bit 31 is one: this is a table entry itself (ARM_EXIDX_COMPACT) + * if bit 31 is zero: this is a prel31 offset of the start of the + table entry for this function */ + if (prel31_to_addr(c->as, c->as_arg, entry, &addr) < 0) + return -UNW_EINVAL; + + if ((*c->as->acc.access_mem)(c->as, entry + 4, &data, 0, c->as_arg) < 0) + return -UNW_EINVAL; + + if (data == ARM_EXIDX_CANT_UNWIND) + { + Debug (2, "0x1 [can't unwind]\n"); + nbuf = -UNW_ESTOPUNWIND; + } + else if (data & ARM_EXIDX_COMPACT) + { + Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, + (data >> 24) & 0x7f, data); + buf[nbuf++] = data >> 16; + buf[nbuf++] = data >> 8; + buf[nbuf++] = data; + } + else + { + unw_word_t extbl_data; + unsigned int n_table_words = 0; + + if (prel31_to_addr(c->as, c->as_arg, entry + 4, &extbl_data) < 0) + return -UNW_EINVAL; + + if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0, c->as_arg) < 0) + return -UNW_EINVAL; + + if (data & ARM_EXIDX_COMPACT) + { + int pers = (data >> 24) & 0x0f; + Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, pers, data); + if (pers == 1 || pers == 2) + { + n_table_words = (data >> 16) & 0xff; + extbl_data += 4; + } + else + buf[nbuf++] = data >> 16; + buf[nbuf++] = data >> 8; + buf[nbuf++] = data; + } + else + { + unw_word_t pers; + if (prel31_to_addr (c->as, c->as_arg, extbl_data, &pers) < 0) + return -UNW_EINVAL; + Debug (2, "%p Personality routine: %8p\n", (void *)addr, + (void *)pers); + if ((*c->as->acc.access_mem)(c->as, extbl_data + 4, &data, 0, + c->as_arg) < 0) + return -UNW_EINVAL; + n_table_words = data >> 24; + buf[nbuf++] = data >> 16; + buf[nbuf++] = data >> 8; + buf[nbuf++] = data; + extbl_data += 8; + } + assert (n_table_words <= 5); + unsigned j; + for (j = 0; j < n_table_words; j++) + { + if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0, + c->as_arg) < 0) + return -UNW_EINVAL; + extbl_data += 4; + buf[nbuf++] = data >> 24; + buf[nbuf++] = data >> 16; + buf[nbuf++] = data >> 8; + buf[nbuf++] = data >> 0; + } + } + + if (nbuf > 0 && buf[nbuf - 1] != ARM_EXTBL_OP_FINISH) + buf[nbuf++] = ARM_EXTBL_OP_FINISH; + + return nbuf; +} + +int +arm_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) +{ + /* The .ARM.exidx section contains a sorted list of key-value pairs - + the unwind entries. The 'key' is a prel31 offset to the start of a + function. We binary search this section in order to find the + appropriate unwind entry. */ + unw_word_t first = di->u.rti.table_data; + unw_word_t last = di->u.rti.table_data + di->u.rti.table_len - 8; + unw_word_t entry, val; + + if (prel31_to_addr (as, arg, first, &val) < 0 || ip < val) + return -UNW_ENOINFO; + + if (prel31_to_addr (as, arg, last, &val) < 0) + return -UNW_EINVAL; + + if (ip >= val) + { + entry = last; + + if (prel31_to_addr (as, arg, last, &pi->start_ip) < 0) + return -UNW_EINVAL; + + pi->end_ip = di->end_ip -1; + } + else + { + while (first < last - 8) + { + entry = first + (((last - first) / 8 + 1) >> 1) * 8; + + if (prel31_to_addr (as, arg, entry, &val) < 0) + return -UNW_EINVAL; + + if (ip < val) + last = entry; + else + first = entry; + } + + entry = first; + + if (prel31_to_addr (as, arg, entry, &pi->start_ip) < 0) + return -UNW_EINVAL; + + if (prel31_to_addr (as, arg, entry + 8, &pi->end_ip) < 0) + return -UNW_EINVAL; + + pi->end_ip--; + } + + if (need_unwind_info) + { + pi->unwind_info_size = 8; + pi->unwind_info = (void *) entry; + pi->format = UNW_INFO_FORMAT_ARM_EXIDX; + } + return 0; +} + +int +tdep_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) +{ + if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX) + && di->format == UNW_INFO_FORMAT_ARM_EXIDX) + return arm_search_unwind_table (as, ip, di, pi, need_unwind_info, arg); + else if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) + && di->format != UNW_INFO_FORMAT_ARM_EXIDX) + return dwarf_search_unwind_table (as, ip, di, pi, need_unwind_info, arg); + + return -UNW_ENOINFO; +} + +#ifndef UNW_REMOTE_ONLY +/** + * Callback to dl_iterate_phdr to find infos about the ARM exidx segment. + */ +static int +arm_phdr_cb (struct dl_phdr_info *info, size_t size, void *data) +{ + struct arm_cb_data *cb_data = data; + const Elf_W(Phdr) *p_text = NULL; + const Elf_W(Phdr) *p_arm_exidx = NULL; + const Elf_W(Phdr) *phdr = info->dlpi_phdr; + long n; + + for (n = info->dlpi_phnum; --n >= 0; phdr++) + { + switch (phdr->p_type) + { + case PT_LOAD: + if (cb_data->ip >= phdr->p_vaddr + info->dlpi_addr && + cb_data->ip < phdr->p_vaddr + info->dlpi_addr + phdr->p_memsz) + p_text = phdr; + break; + + case PT_ARM_EXIDX: + p_arm_exidx = phdr; + break; + + default: + break; + } + } + + if (p_text && p_arm_exidx) + { + cb_data->di.format = UNW_INFO_FORMAT_ARM_EXIDX; + cb_data->di.start_ip = p_text->p_vaddr + info->dlpi_addr; + cb_data->di.end_ip = cb_data->di.start_ip + p_text->p_memsz; + cb_data->di.u.rti.name_ptr = (unw_word_t) info->dlpi_name; + cb_data->di.u.rti.table_data = p_arm_exidx->p_vaddr + info->dlpi_addr; + cb_data->di.u.rti.table_len = p_arm_exidx->p_memsz; + return 1; + } + + return 0; +} + +HIDDEN int +arm_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, void *arg) +{ + int ret = -1; + intrmask_t saved_mask; + + Debug (14, "looking for IP=0x%lx\n", (long) ip); + + if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)) + ret = dwarf_find_proc_info (as, ip, pi, need_unwind_info, arg); + + if (ret < 0 && UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) + { + struct arm_cb_data cb_data; + + memset (&cb_data, 0, sizeof (cb_data)); + cb_data.ip = ip; + cb_data.pi = pi; + cb_data.di.format = -1; + + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); + ret = dl_iterate_phdr (arm_phdr_cb, &cb_data); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + + if (cb_data.di.format != -1) + ret = arm_search_unwind_table (as, ip, &cb_data.di, pi, + need_unwind_info, arg); + else + ret = -UNW_ENOINFO; + } + + return ret; +} + +HIDDEN void +arm_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} +#endif /* !UNW_REMOTE_ONLY */ + diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gget_proc_info.c new file mode 100644 index 00000000000000..4051a10766e474 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gget_proc_info.c @@ -0,0 +1,41 @@ +/* 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. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + /* We can only unwind using Dwarf into on ARM: return failure code + if it's not present. */ + ret = dwarf_make_proc_info (&c->dwarf); + if (ret < 0) + return ret; + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gget_save_loc.c new file mode 100644 index 00000000000000..9fb070489cd52b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gget_save_loc.c @@ -0,0 +1,81 @@ +/* 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. */ + +#include "unwind_i.h" + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_ARM_R0: + case UNW_ARM_R1: + case UNW_ARM_R2: + case UNW_ARM_R3: + case UNW_ARM_R4: + case UNW_ARM_R5: + case UNW_ARM_R6: + case UNW_ARM_R7: + case UNW_ARM_R8: + case UNW_ARM_R9: + case UNW_ARM_R10: + case UNW_ARM_R11: + case UNW_ARM_R12: + case UNW_ARM_R13: + case UNW_ARM_R14: + case UNW_ARM_R15: + loc = c->dwarf.loc[reg - UNW_ARM_R0]; + break; + + default: + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gglobal.c new file mode 100644 index 00000000000000..7b93fbd89a1850 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gglobal.c @@ -0,0 +1,65 @@ +/* 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. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (arm_lock); +HIDDEN int tdep_init_done; + +/* Unwinding methods to use. See UNW_METHOD_ enums */ +HIDDEN int unwi_unwind_method = UNW_ARM_METHOD_ALL; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&arm_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + /* read ARM unwind method setting */ + const char* str = getenv ("UNW_ARM_UNWIND_METHOD"); + if (str) + { + unwi_unwind_method = atoi (str); + } + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + arm_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&arm_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c new file mode 100644 index 00000000000000..0bac0d72da6fe6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c @@ -0,0 +1,234 @@ +/* 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. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static inline void * +uc_addr (unw_tdep_context_t *uc, int reg) +{ + if (reg >= UNW_ARM_R0 && reg < UNW_ARM_R0 + 16) + return &uc->regs[reg - UNW_ARM_R0]; + else + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (unw_tdep_context_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +#define PAGE_SIZE 4096 +#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) + +/* Cache of already validated addresses */ +#define NLGA 4 +static unw_word_t last_good_addr[NLGA]; +static int lga_victim; + +static int +validate_mem (unw_word_t addr) +{ + int i, victim; + size_t len; + + if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) + len = PAGE_SIZE; + else + len = PAGE_SIZE * 2; + + addr = PAGE_START(addr); + + if (addr == 0) + return -1; + + for (i = 0; i < NLGA; i++) + { + if (last_good_addr[i] && (addr == last_good_addr[i])) + return 0; + } + + if (msync ((void *) addr, len, MS_ASYNC) == -1) + return -1; + + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (!last_good_addr[victim]) { + last_good_addr[victim++] = addr; + return 0; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; + + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + /* validate address */ + const struct cursor *c = (const struct cursor *) arg; + if (c && validate_mem(addr)) + return -1; + + if (write) + { + Debug (16, "mem[%x] <- %x\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (16, "mem[%x] -> %x\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + unw_tdep_context_t *uc = arg; + + if (unw_is_fpreg (reg)) + goto badreg; + +Debug (16, "reg = %s\n", unw_regname (reg)); + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %x\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %x\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + unw_tdep_context_t *uc = arg; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +arm_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = arm_find_proc_info; + local_addr_space.acc.put_unwind_info = arm_put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = arm_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_local.c new file mode 100644 index 00000000000000..e13519b79a9e6e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_local.c @@ -0,0 +1,78 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 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. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + + return common_init (c, use_prev_instr); +} + +int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, unw_context_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_remote.c new file mode 100644 index 00000000000000..9b8ba5b89def1a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit_remote.c @@ -0,0 +1,45 @@ +/* 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. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gos-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gos-freebsd.c new file mode 100644 index 00000000000000..a1069223a507dc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gos-freebsd.c @@ -0,0 +1,129 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + Copyright 2015 The FreeBSD Foundation + + Portions of this software were developed by Konstantin Belousov + under sponsorship from the FreeBSD Foundation. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include "unwind_i.h" +#include "offsets.h" +#include "ex_tables.h" + +HIDDEN int +arm_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret, fmt; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + fmt = unw_is_signal_frame(cursor); + + c->dwarf.pi_valid = 0; + + if (fmt == UNW_ARM_FRAME_SYSCALL) + { + c->sigcontext_format = ARM_SCF_FREEBSD_SYSCALL; + c->frame_info.frame_type = UNW_ARM_FRAME_SYSCALL; + c->frame_info.cfa_reg_offset = 0; + c->dwarf.loc[UNW_ARM_R7] = c->dwarf.loc[UNW_ARM_R12]; + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R14], &c->dwarf.ip); + return 1; + } + + c->sigcontext_format = ARM_SCF_FREEBSD_SIGFRAME; + sc_addr = sp_addr; + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + c->sigcontext_addr = sc_addr; + c->frame_info.frame_type = UNW_ARM_FRAME_SIGRETURN; + c->frame_info.cfa_reg_offset = sc_addr - sp_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ +#define ROFF(n) (FREEBSD_SC_UCONTEXT_OFF + FREEBSD_UC_MCONTEXT_OFF + \ + FREEBSD_MC_R0_OFF + (n) * 4) +#define SL(n) \ + c->dwarf.loc[UNW_ARM_R ## n] = DWARF_LOC (sc_addr + ROFF(n), 0); + SL(0); SL(1); SL(2); SL(3); SL(4); SL(5); SL(6); SL(7); + SL(8); SL(9); SL(10); SL(11); SL(12); SL(13); SL(14); SL(15); +#undef SL +#undef ROFF + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R13], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); + + return 1; +} + +/* Returns 1 in case of a non-RT signal frame and 2 in case of a RT signal + frame. */ +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, w2, w3, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) + return ret; + if ((ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0) + return ret; + if ((ret = (*a->access_mem) (as, ip + 8, &w2, 0, arg)) < 0) + return ret; + if ((ret = (*a->access_mem) (as, ip + 12, &w3, 0, arg)) < 0) + return ret; + + if (w0 == 0xe1a0000d && w1 == 0xe2800040 && w2 == 0xe59f700c && + w3 == 0xef0001a1) + return UNW_ARM_FRAME_SIGRETURN; + + if ((ret = (*a->access_mem) (as, ip - 4, &w0, 0, arg)) < 0) + return ret; + if (w0 == 0xef000000) + return UNW_ARM_FRAME_SYSCALL; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gos-linux.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gos-linux.c new file mode 100644 index 00000000000000..260e086f6953ea --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gos-linux.c @@ -0,0 +1,182 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include "unwind_i.h" +#include "offsets.h" + +HIDDEN int +arm_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + + /* Obtain signal frame type (non-RT or RT). */ + ret = unw_is_signal_frame (cursor); + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + /* Since kernel version 2.6.18 the non-RT signal frame starts with a + ucontext while the RT signal frame starts with a siginfo, followed + by a sigframe whose first element is an ucontext. + Prior 2.6.18 the non-RT signal frame starts with a sigcontext while + the RT signal frame starts with two pointers followed by a siginfo + and an ucontext. The first pointer points to the start of the siginfo + structure and the second one to the ucontext structure. */ + + if (ret == 1) + { + /* Handle non-RT signal frames. Check if the first word on the stack + is the magic number. */ + if (sp == 0x5ac3c35a) + { + c->sigcontext_format = ARM_SCF_LINUX_SIGFRAME; + sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF; + } + else + { + c->sigcontext_format = ARM_SCF_LINUX_OLD_SIGFRAME; + sc_addr = sp_addr; + } + } + else if (ret == 2) + { + /* Handle RT signal frames. Check if the first word on the stack is a + pointer to the siginfo structure. */ + if (sp == sp_addr + 8) + { + c->sigcontext_format = ARM_SCF_LINUX_OLD_RT_SIGFRAME; + sc_addr = sp_addr + 8 + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + } + else + { + c->sigcontext_format = ARM_SCF_LINUX_RT_SIGFRAME; + sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + } + } + else + return -UNW_EUNSPEC; + + c->sigcontext_addr = sc_addr; + c->frame_info.frame_type = UNW_ARM_FRAME_SIGRETURN; + c->frame_info.cfa_reg_offset = sc_addr - sp_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + c->dwarf.loc[UNW_ARM_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); + c->dwarf.loc[UNW_ARM_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); + c->dwarf.loc[UNW_ARM_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); + c->dwarf.loc[UNW_ARM_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); + c->dwarf.loc[UNW_ARM_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); + c->dwarf.loc[UNW_ARM_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); + c->dwarf.loc[UNW_ARM_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); + c->dwarf.loc[UNW_ARM_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); + c->dwarf.loc[UNW_ARM_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); + c->dwarf.loc[UNW_ARM_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); + c->dwarf.loc[UNW_ARM_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); + c->dwarf.loc[UNW_ARM_R11] = DWARF_LOC (sc_addr + LINUX_SC_FP_OFF, 0); + c->dwarf.loc[UNW_ARM_R12] = DWARF_LOC (sc_addr + LINUX_SC_IP_OFF, 0); + c->dwarf.loc[UNW_ARM_R13] = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0); + c->dwarf.loc[UNW_ARM_R14] = DWARF_LOC (sc_addr + LINUX_SC_LR_OFF, 0); + c->dwarf.loc[UNW_ARM_R15] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R13], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); + + c->dwarf.pi_valid = 0; + + return 1; +} + +#define ARM_NR_sigreturn 119 +#define ARM_NR_rt_sigreturn 173 +#define ARM_NR_OABI_SYSCALL_BASE 0x900000 + +/* ARM EABI sigreturn (the syscall number is loaded into r7) */ +#define MOV_R7_SIGRETURN (0xe3a07000UL | ARM_NR_sigreturn) +#define MOV_R7_RT_SIGRETURN (0xe3a07000UL | ARM_NR_rt_sigreturn) + +/* ARM OABI sigreturn (using SWI) */ +#define ARM_SIGRETURN \ + (0xef000000UL | ARM_NR_sigreturn | ARM_NR_OABI_SYSCALL_BASE) +#define ARM_RT_SIGRETURN \ + (0xef000000UL | ARM_NR_rt_sigreturn | ARM_NR_OABI_SYSCALL_BASE) + +/* Thumb sigreturn (two insns, syscall number is loaded into r7) */ +#define THUMB_SIGRETURN (0xdf00UL << 16 | 0x2700 | ARM_NR_sigreturn) +#define THUMB_RT_SIGRETURN (0xdf00UL << 16 | 0x2700 | ARM_NR_rt_sigreturn) + +/* Thumb2 sigreturn (mov.w r7, $SYS_ify(rt_sigreturn/sigreturn)) */ +#define THUMB2_SIGRETURN (((0x0700 | ARM_NR_sigreturn) << 16) | \ + 0xf04f) +#define THUMB2_RT_SIGRETURN (((0x0700 | ARM_NR_rt_sigreturn) << 16) | \ + 0xf04f) +/* TODO: with different toolchains, there are a lot more possibilities */ + +/* Returns 1 in case of a non-RT signal frame and 2 in case of a RT signal + frame. */ +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + /* The least bit denotes thumb/arm mode. Do not read there. */ + ip = c->dwarf.ip & ~0x1; + + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) + return ret; + + /* Return 1 if the IP points to a non-RT sigreturn sequence. */ + if (w0 == MOV_R7_SIGRETURN || w0 == ARM_SIGRETURN || w0 == THUMB_SIGRETURN + || w0 == THUMB2_SIGRETURN) + return 1; + /* Return 2 if the IP points to a RT sigreturn sequence. */ + else if (w0 == MOV_R7_RT_SIGRETURN || w0 == ARM_RT_SIGRETURN + || w0 == THUMB_RT_SIGRETURN || w0 == THUMB2_RT_SIGRETURN) + return 2; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gos-other.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gos-other.c new file mode 100644 index 00000000000000..73c102c3d26f03 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gos-other.c @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include "unwind_i.h" +#include "offsets.h" + +HIDDEN int +arm_handle_signal_frame (unw_cursor_t *cursor) +{ + return -UNW_EUNSPEC; +} + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#if defined(__QNX__) + /* Not supported yet */ + return 0; +#else + printf ("%s: implement me\n", __FUNCTION__); + return -UNW_ENOINFO; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/arm/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gregs.c new file mode 100644 index 00000000000000..0d52f0b2225225 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gregs.c @@ -0,0 +1,83 @@ +/* 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. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_ARM_R15: + if (write) + c->dwarf.ip = *valp; /* update the IP cache */ + case UNW_ARM_R0: + case UNW_ARM_R1: + case UNW_ARM_R2: + case UNW_ARM_R3: + case UNW_ARM_R4: + case UNW_ARM_R5: + case UNW_ARM_R6: + case UNW_ARM_R7: + case UNW_ARM_R8: + case UNW_ARM_R9: + case UNW_ARM_R10: + case UNW_ARM_R11: + case UNW_ARM_R12: + case UNW_ARM_R14: + loc = c->dwarf.loc[reg - UNW_ARM_R0]; + break; + + case UNW_ARM_R13: + case UNW_ARM_CFA: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + /* FIXME: Initialise coprocessor & shadow registers? */ + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +/* FIXME for ARM. */ + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c new file mode 100644 index 00000000000000..3b9dfb33e60a7b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c @@ -0,0 +1,154 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_tdep_context_t *uc = c->dwarf.as_arg; + + if (c->sigcontext_format == ARM_SCF_NONE) + { + /* Since there are no signals involved here we restore the non scratch + registers only. */ + unsigned long regs[10]; + regs[0] = uc->regs[4]; + regs[1] = uc->regs[5]; + regs[2] = uc->regs[6]; + regs[3] = uc->regs[7]; + regs[4] = uc->regs[8]; + regs[5] = uc->regs[9]; + regs[6] = uc->regs[10]; + regs[7] = uc->regs[11]; /* FP */ + regs[8] = uc->regs[13]; /* SP */ + regs[9] = uc->regs[14]; /* LR */ + + struct regs_overlay { + char x[sizeof(regs)]; + }; + + __asm__ __volatile__ ( + "ldmia %0, {r4-r12, lr}\n" + "mov sp, r12\n" + "bx lr\n" + : : "r" (regs), + "m" (*(struct regs_overlay *)regs) + ); + } + else + { + /* In case a signal frame is involved, we're using its trampoline which + calls sigreturn. */ + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + sc->arm_r0 = uc->regs[0]; + sc->arm_r1 = uc->regs[1]; + sc->arm_r2 = uc->regs[2]; + sc->arm_r3 = uc->regs[3]; + sc->arm_r4 = uc->regs[4]; + sc->arm_r5 = uc->regs[5]; + sc->arm_r6 = uc->regs[6]; + sc->arm_r7 = uc->regs[7]; + sc->arm_r8 = uc->regs[8]; + sc->arm_r9 = uc->regs[9]; + sc->arm_r10 = uc->regs[10]; + sc->arm_fp = uc->regs[11]; /* FP */ + sc->arm_ip = uc->regs[12]; /* IP */ + sc->arm_sp = uc->regs[13]; /* SP */ + sc->arm_lr = uc->regs[14]; /* LR */ + sc->arm_pc = uc->regs[15]; /* PC */ + /* clear the ITSTATE bits. */ + sc->arm_cpsr &= 0xf9ff03ffUL; + + /* Set the SP and the PC in order to continue execution at the modified + trampoline which restores the signal mask and the registers. */ + __asm__ __volatile__ ( + "mov sp, %0\n" + "bx %1\n" + : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) + ); + } + unreachable(); +#else + printf ("%s: implement me\n", __FUNCTION__); +#endif + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +static inline void +establish_machine_state (struct cursor *c) +{ + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + as->acc.access_fpreg (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + } +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + Debug (1, "(cursor=%p)\n", c); + + if (!c->dwarf.ip) + { + /* This can happen easily when the frame-chain gets truncated + due to bad or missing unwind-info. */ + Debug (1, "refusing to resume execution at address 0\n"); + return -UNW_EINVAL; + } + + establish_machine_state (c); + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gstash_frame.c new file mode 100644 index 00000000000000..c5a76b86d0a96a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gstash_frame.c @@ -0,0 +1,90 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + Copyright (C) 2014 CERN and Aalto University + Contributed by Filip Nyback + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN void +tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) +{ + struct cursor *c = (struct cursor *) dwarf_to_cursor (d); + unw_tdep_frame_t *f = &c->frame_info; + + Debug (4, "ip=0x%x cfa=0x%x type %d cfa [where=%d val=%d] cfaoff=%d" + " ra=0x%x r7 [where=%d val=%d @0x%x] lr [where=%d val=%d @0x%x] " + "sp [where=%d val=%d @0x%x]\n", + d->ip, d->cfa, f->frame_type, + rs->reg.where[DWARF_CFA_REG_COLUMN], + rs->reg.val[DWARF_CFA_REG_COLUMN], + rs->reg.val[DWARF_CFA_OFF_COLUMN], + DWARF_GET_LOC(d->loc[rs->ret_addr_column]), + rs->reg.where[R7], rs->reg.val[R7], DWARF_GET_LOC(d->loc[R7]), + rs->reg.where[LR], rs->reg.val[LR], DWARF_GET_LOC(d->loc[LR]), + rs->reg.where[SP], rs->reg.val[SP], DWARF_GET_LOC(d->loc[SP])); + + /* A standard frame is defined as: + - CFA is register-relative offset off R7 or SP; + - Return address is saved in LR; + - R7 is unsaved or saved at CFA+offset, offset != -1; + - LR is unsaved or saved at CFA+offset, offset != -1; + - SP is unsaved or saved at CFA+offset, offset != -1. */ + if (f->frame_type == UNW_ARM_FRAME_OTHER + && (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG) + && (rs->reg.val[DWARF_CFA_REG_COLUMN] == R7 + || rs->reg.val[DWARF_CFA_REG_COLUMN] == SP) + && labs(rs->reg.val[DWARF_CFA_OFF_COLUMN]) < (1 << 29) + && rs->ret_addr_column == LR + && (rs->reg.where[R7] == DWARF_WHERE_UNDEF + || rs->reg.where[R7] == DWARF_WHERE_SAME + || (rs->reg.where[R7] == DWARF_WHERE_CFAREL + && labs(rs->reg.val[R7]) < (1 << 29) + && rs->reg.val[R7]+1 != 0)) + && (rs->reg.where[LR] == DWARF_WHERE_UNDEF + || rs->reg.where[LR] == DWARF_WHERE_SAME + || (rs->reg.where[LR] == DWARF_WHERE_CFAREL + && labs(rs->reg.val[LR]) < (1 << 29) + && rs->reg.val[LR]+1 != 0)) + && (rs->reg.where[SP] == DWARF_WHERE_UNDEF + || rs->reg.where[SP] == DWARF_WHERE_SAME + || (rs->reg.where[SP] == DWARF_WHERE_CFAREL + && labs(rs->reg.val[SP]) < (1 << 29) + && rs->reg.val[SP]+1 != 0))) + { + /* Save information for a standard frame. */ + f->frame_type = UNW_ARM_FRAME_STANDARD; + f->cfa_reg_sp = (rs->reg.val[DWARF_CFA_REG_COLUMN] == SP); + f->cfa_reg_offset = rs->reg.val[DWARF_CFA_OFF_COLUMN]; + if (rs->reg.where[R7] == DWARF_WHERE_CFAREL) + f->r7_cfa_offset = rs->reg.val[R7]; + if (rs->reg.where[LR] == DWARF_WHERE_CFAREL) + f->lr_cfa_offset = rs->reg.val[LR]; + if (rs->reg.where[SP] == DWARF_WHERE_CFAREL) + f->sp_cfa_offset = rs->reg.val[SP]; + Debug (4, " standard frame\n"); + } + else + Debug (4, " unusual frame\n"); +} + diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c new file mode 100644 index 00000000000000..895e8a892afce0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c @@ -0,0 +1,201 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" +#include "ex_tables.h" + +#include + +#define arm_exidx_step UNW_OBJ(arm_exidx_step) + +static inline int +arm_exidx_step (struct cursor *c) +{ + unw_word_t old_ip, old_cfa; + uint8_t buf[32]; + int ret; + + old_ip = c->dwarf.ip; + old_cfa = c->dwarf.cfa; + + /* mark PC unsaved */ + c->dwarf.loc[UNW_ARM_R15] = DWARF_NULL_LOC; + unw_word_t ip = c->dwarf.ip; + if (c->dwarf.use_prev_instr) + /* The least bit denotes thumb/arm mode, clear it. */ + ip = (ip & ~(unw_word_t)0x1) - 1; + + /* check dynamic info first --- it overrides everything else */ + ret = unwi_find_dynamic_proc_info (c->dwarf.as, ip, &c->dwarf.pi, 1, + c->dwarf.as_arg); + if (ret == -UNW_ENOINFO) + { + if ((ret = tdep_find_proc_info (&c->dwarf, ip, 1)) < 0) + return ret; + } + + if (c->dwarf.pi.format != UNW_INFO_FORMAT_ARM_EXIDX) + return -UNW_ENOINFO; + + ret = arm_exidx_extract (&c->dwarf, buf); + if (ret == -UNW_ESTOPUNWIND) + return 0; + else if (ret < 0) + return ret; + + ret = arm_exidx_decode (buf, ret, &c->dwarf); + if (ret < 0) + return ret; + + if (c->dwarf.ip == old_ip && c->dwarf.cfa == old_cfa) + { + Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n", + __FUNCTION__, (long) c->dwarf.ip); + return -UNW_EBADFRAME; + } + + c->dwarf.pi_valid = 0; + + return (c->dwarf.ip == 0) ? 0 : 1; +} + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret = -UNW_EUNSPEC; + + Debug (1, "(cursor=%p)\n", c); + + /* Check if this is a signal frame. */ + if (unw_is_signal_frame (cursor) > 0) + return arm_handle_signal_frame (cursor); + +#ifdef CONFIG_DEBUG_FRAME + /* First, try DWARF-based unwinding. */ + if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)) + { + ret = dwarf_step (&c->dwarf); + Debug(1, "dwarf_step()=%d\n", ret); + + if (likely (ret > 0)) + return 1; + else if (unlikely (ret == -UNW_ESTOPUNWIND)) + return ret; + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + } +#endif /* CONFIG_DEBUG_FRAME */ + + /* Next, try extbl-based unwinding. */ + if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) + { + Debug (13, "%s(ret=%d), trying extbl\n", + UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() failed " : "", + ret); + ret = arm_exidx_step (c); + if (ret > 0) + return 1; + if (ret == -UNW_ESTOPUNWIND || ret == 0) + return ret; + } + + /* Fall back on APCS frame parsing. + Note: This won't work in case the ARM EABI is used. */ +#ifdef __FreeBSD__ + if (0) +#else + if (unlikely (ret < 0)) +#endif + { + if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME)) + { + Debug (13, "%s%s%s%s(ret=%d), trying frame-chain\n", + UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() " : "", + (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) && UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX)) ? "and " : "", + UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX) ? "arm_exidx_step() " : "", + (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) || UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX)) ? "failed " : "", + ret); + ret = UNW_ESUCCESS; + /* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */ + unw_word_t instr, i; + dwarf_loc_t ip_loc, fp_loc; + unw_word_t frame; + /* Mark all registers unsaved, since we don't know where + they are saved (if at all), except for the EBP and + EIP. */ + if (dwarf_get(&c->dwarf, c->dwarf.loc[UNW_ARM_R11], &frame) < 0) + { + return 0; + } + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) { + c->dwarf.loc[i] = DWARF_NULL_LOC; + } + if (frame) + { + if (dwarf_get(&c->dwarf, DWARF_LOC(frame, 0), &instr) < 0) + { + return 0; + } + instr -= 8; + if (dwarf_get(&c->dwarf, DWARF_LOC(instr, 0), &instr) < 0) + { + return 0; + } + if ((instr & 0xFFFFD800) == 0xE92DD800) + { + /* Standard APCS frame. */ + ip_loc = DWARF_LOC(frame - 4, 0); + fp_loc = DWARF_LOC(frame - 12, 0); + } + else + { + /* Codesourcery optimized normal frame. */ + ip_loc = DWARF_LOC(frame, 0); + fp_loc = DWARF_LOC(frame - 4, 0); + } + if (dwarf_get(&c->dwarf, ip_loc, &c->dwarf.ip) < 0) + { + return 0; + } + c->dwarf.loc[UNW_ARM_R12] = ip_loc; + c->dwarf.loc[UNW_ARM_R11] = fp_loc; + c->dwarf.pi_valid = 0; + Debug(15, "ip=%x\n", c->dwarf.ip); + } + else + { + ret = -UNW_ENOINFO; + } + } + } + return ret == -UNW_ENOINFO ? 0 : ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gtrace.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gtrace.c new file mode 100644 index 00000000000000..2f277520b36348 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gtrace.c @@ -0,0 +1,557 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + Copyright (C) 2014 CERN and Aalto University + Contributed by Filip Nyback + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" +#include +#include + +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific + +/* Initial hash table size. Table expands by 2 bits (times four). */ +#define HASH_MIN_BITS 14 + +typedef struct +{ + unw_tdep_frame_t *frames; + size_t log_size; + size_t used; + size_t dtor_count; /* Counts how many times our destructor has already + been called. */ +} unw_trace_cache_t; + +static const unw_tdep_frame_t empty_frame = { 0, UNW_ARM_FRAME_OTHER, -1, -1, 0, -1, -1, -1 }; +static define_lock (trace_init_lock); +static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; +static sig_atomic_t trace_cache_once_happen; +static pthread_key_t trace_cache_key; +static struct mempool trace_cache_pool; +static __thread unw_trace_cache_t *tls_cache; +static __thread int tls_cache_destroyed; + +/* Free memory for a thread's trace cache. */ +static void +trace_cache_free (void *arg) +{ + unw_trace_cache_t *cache = arg; + if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS) + { + /* Not yet our turn to get destroyed. Re-install ourselves into the key. */ + pthread_setspecific(trace_cache_key, cache); + Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, + PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); + return; + } + tls_cache_destroyed = 1; + tls_cache = NULL; + munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); + mempool_free (&trace_cache_pool, cache); + Debug(5, "freed cache %p\n", cache); +} + +/* Initialise frame tracing for threaded use. */ +static void +trace_cache_init_once (void) +{ + pthread_key_create (&trace_cache_key, &trace_cache_free); + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + trace_cache_once_happen = 1; +} + +static unw_tdep_frame_t * +trace_cache_buckets (size_t n) +{ + unw_tdep_frame_t *frames; + size_t i; + + GET_MEMORY(frames, n * sizeof (unw_tdep_frame_t)); + if (likely(frames != NULL)) + for (i = 0; i < n; ++i) + frames[i] = empty_frame; + + return frames; +} + +/* Allocate and initialise hash table for frame cache lookups. + Returns the cache initialised with (1u << HASH_LOW_BITS) hash + buckets, or NULL if there was a memory allocation problem. */ +static unw_trace_cache_t * +trace_cache_create (void) +{ + unw_trace_cache_t *cache; + + if (tls_cache_destroyed) + { + /* The current thread is in the process of exiting. Don't recreate + cache, as we wouldn't have another chance to free it. */ + Debug(5, "refusing to reallocate cache: " + "thread-locals are being deallocated\n"); + return NULL; + } + + if (! (cache = mempool_alloc(&trace_cache_pool))) + { + Debug(5, "failed to allocate cache\n"); + return NULL; + } + + if (! (cache->frames = trace_cache_buckets(1u << HASH_MIN_BITS))) + { + Debug(5, "failed to allocate buckets\n"); + mempool_free(&trace_cache_pool, cache); + return NULL; + } + + cache->log_size = HASH_MIN_BITS; + cache->used = 0; + cache->dtor_count = 0; + tls_cache_destroyed = 0; /* Paranoia: should already be 0. */ + Debug(5, "allocated cache %p\n", cache); + return cache; +} + +/* Expand the hash table in the frame cache if possible. This always + quadruples the hash size, and clears all previous frame entries. */ +static int +trace_cache_expand (unw_trace_cache_t *cache) +{ + size_t old_size = (1u << cache->log_size); + size_t new_log_size = cache->log_size + 2; + unw_tdep_frame_t *new_frames = trace_cache_buckets (1u << new_log_size); + + if (unlikely(! new_frames)) + { + Debug(5, "failed to expand cache to 2^%u buckets\n", new_log_size); + return -UNW_ENOMEM; + } + + Debug(5, "expanded cache from 2^%u to 2^%u buckets\n", cache->log_size, + new_log_size); + munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); + cache->frames = new_frames; + cache->log_size = new_log_size; + cache->used = 0; + return 0; +} + +static unw_trace_cache_t * +trace_cache_get_unthreaded (void) +{ + unw_trace_cache_t *cache; + intrmask_t saved_mask; + static unw_trace_cache_t *global_cache = NULL; + lock_acquire (&trace_init_lock, saved_mask); + if (! global_cache) + { + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + global_cache = trace_cache_create (); + } + cache = global_cache; + lock_release (&trace_init_lock, saved_mask); + Debug(5, "using cache %p\n", cache); + return cache; +} + +/* Get the frame cache for the current thread. Create it if there is none. */ +static unw_trace_cache_t * +trace_cache_get (void) +{ + unw_trace_cache_t *cache; + if (likely (pthread_once != NULL)) + { + pthread_once(&trace_cache_once, &trace_cache_init_once); + if (!trace_cache_once_happen) + { + return trace_cache_get_unthreaded(); + } + if (! (cache = tls_cache)) + { + cache = trace_cache_create(); + pthread_setspecific(trace_cache_key, cache); + tls_cache = cache; + } + Debug(5, "using cache %p\n", cache); + return cache; + } + else + { + return trace_cache_get_unthreaded(); + } +} + +/* Initialise frame properties for address cache slot F at address + PC using current CFA, R7 and SP values. Modifies CURSOR to + that location, performs one unw_step(), and fills F with what + was discovered about the location. Returns F. + + FIXME: This probably should tell DWARF handling to never evaluate + or use registers other than R7, SP and PC in case there is + highly unusual unwind info which uses these creatively. */ +static unw_tdep_frame_t * +trace_init_addr (unw_tdep_frame_t *f, + unw_cursor_t *cursor, + unw_word_t cfa, + unw_word_t pc, + unw_word_t r7, + unw_word_t sp) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + int ret = -UNW_EINVAL; + + /* Initialise frame properties: unknown, not last. */ + f->virtual_address = pc; + f->frame_type = UNW_ARM_FRAME_OTHER; + f->last_frame = 0; + f->cfa_reg_sp = -1; + f->cfa_reg_offset = 0; + f->r7_cfa_offset = -1; + f->lr_cfa_offset = -1; + f->sp_cfa_offset = -1; + + /* Reinitialise cursor to this instruction - but undo next/prev RIP + adjustment because unw_step will redo it - and force PC, R7 and + SP into register locations (=~ ucontext we keep), then set + their desired values. Then perform the step. */ + d->ip = pc + d->use_prev_instr; + d->cfa = cfa; + d->loc[UNW_ARM_R7] = DWARF_REG_LOC (d, UNW_ARM_R7); + d->loc[UNW_ARM_R13] = DWARF_REG_LOC (d, UNW_ARM_R13); + d->loc[UNW_ARM_R15] = DWARF_REG_LOC (d, UNW_ARM_R15); + c->frame_info = *f; + + if (likely(dwarf_put (d, d->loc[UNW_ARM_R7], r7) >= 0) + && likely(dwarf_put (d, d->loc[UNW_ARM_R13], sp) >= 0) + && likely(dwarf_put (d, d->loc[UNW_ARM_R15], pc) >= 0) + && likely((ret = unw_step (cursor)) >= 0)) + *f = c->frame_info; + + /* If unw_step() stopped voluntarily, remember that, even if it + otherwise could not determine anything useful. This avoids + failing trace if we hit frames without unwind info, which is + common for the outermost frame (CRT stuff) on many systems. + This avoids failing trace in very common circumstances; failing + to unw_step() loop wouldn't produce any better result. */ + if (ret == 0) + f->last_frame = -1; + + Debug (3, "frame va %x type %d last %d cfa %s+%d r7 @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_sp ? "sp" : "r7", f->cfa_reg_offset, + f->r7_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); + + return f; +} + +/* Look up and if necessary fill in frame attributes for address PC + in CACHE using current CFA, R7 and SP values. Uses CURSOR to + perform any unwind steps necessary to fill the cache. Returns the + frame cache slot which describes RIP. */ +static unw_tdep_frame_t * +trace_lookup (unw_cursor_t *cursor, + unw_trace_cache_t *cache, + unw_word_t cfa, + unw_word_t pc, + unw_word_t r7, + unw_word_t sp) +{ + /* First look up for previously cached information using cache as + linear probing hash table with probe step of 1. Majority of + lookups should be completed within few steps, but it is very + important the hash table does not fill up, or performance falls + off the cliff. */ + uint32_t i, addr; + uint32_t cache_size = 1u << cache->log_size; + uint32_t slot = ((pc * 0x9e3779b9) >> 11) & (cache_size-1); + unw_tdep_frame_t *frame; + + for (i = 0; i < 16; ++i) + { + frame = &cache->frames[slot]; + addr = frame->virtual_address; + + /* Return if we found the address. */ + if (likely(addr == pc)) + { + Debug (4, "found address after %d steps\n", i); + return frame; + } + + /* If slot is empty, reuse it. */ + if (likely(! addr)) + break; + + /* Linear probe to next slot candidate, step = 1. */ + if (++slot >= cache_size) + slot -= cache_size; + } + + /* If we collided after 16 steps, or if the hash is more than half + full, force the hash to expand. Fill the selected slot, whether + it's free or collides. Note that hash expansion drops previous + contents; further lookups will refill the hash. */ + Debug (4, "updating slot %u after %d steps, replacing 0x%x\n", slot, i, addr); + if (unlikely(addr || cache->used >= cache_size / 2)) + { + if (unlikely(trace_cache_expand (cache) < 0)) + return NULL; + + cache_size = 1u << cache->log_size; + slot = ((pc * 0x9e3779b9) >> 11) & (cache_size-1); + frame = &cache->frames[slot]; + addr = frame->virtual_address; + } + + if (! addr) + ++cache->used; + + return trace_init_addr (frame, cursor, cfa, pc, r7, sp); +} + +/* Fast stack backtrace for ARM. + + This is used by backtrace() implementation to accelerate frequent + queries for current stack, without any desire to unwind. It fills + BUFFER with the call tree from CURSOR upwards for at most SIZE + stack levels. The first frame, backtrace itself, is omitted. When + called, SIZE should give the maximum number of entries that can be + stored into BUFFER. Uses an internal thread-specific cache to + accelerate queries. + + The caller should fall back to a unw_step() loop if this function + fails by returning -UNW_ESTOPUNWIND, meaning the routine hit a + stack frame that is too complex to be traced in the fast path. + + This function is tuned for clients which only need to walk the + stack to get the call tree as fast as possible but without any + other details, for example profilers sampling the stack thousands + to millions of times per second. The routine handles the most + common ARM ABI stack layouts: CFA is R7 or SP plus/minus + constant offset, return address is in LR, and R7, LR and SP are + either unchanged or saved on stack at constant offset from the CFA; + the signal return frame; and frames without unwind info provided + they are at the outermost (final) frame or can conservatively be + assumed to be frame-pointer based. + + Any other stack layout will cause the routine to give up. There + are only a handful of relatively rarely used functions which do + not have a stack in the standard form: vfork, longjmp, setcontext + and _dl_runtime_profile on common linux systems for example. + + On success BUFFER and *SIZE reflect the trace progress up to *SIZE + stack levels or the outermost frame, which ever is less. It may + stop short of outermost frame if unw_step() loop would also do so, + e.g. if there is no more unwind information; this is not reported + as an error. + + The function returns a negative value for errors, -UNW_ESTOPUNWIND + if tracing stopped because of an unusual frame unwind info. The + BUFFER and *SIZE reflect tracing progress up to the error frame. + + Callers of this function would normally look like this: + + unw_cursor_t cur; + unw_context_t ctx; + void addrs[128]; + int depth = 128; + int ret; + + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + if ((ret = unw_tdep_trace(&cur, addrs, &depth)) < 0) + { + depth = 0; + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + while ((ret = unw_step(&cur)) > 0 && depth < 128) + { + unw_word_t ip; + unw_get_reg(&cur, UNW_REG_IP, &ip); + addresses[depth++] = (void *) ip; + } + } +*/ +HIDDEN int +tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + unw_trace_cache_t *cache; + unw_word_t sp, pc, cfa, r7, lr; + int maxdepth = 0; + int depth = 0; + int ret; + + /* Check input parametres. */ + if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) + return -UNW_EINVAL; + + Debug (1, "begin ip 0x%x cfa 0x%x\n", d->ip, d->cfa); + + /* Tell core dwarf routines to call back to us. */ + d->stash_frames = 1; + + /* Determine initial register values. These are direct access safe + because we know they come from the initial machine context. */ + pc = d->ip; + sp = cfa = d->cfa; + ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_ARM_R7]), r7); + assert(ret == 0); + lr = 0; + + /* Get frame cache. */ + if (unlikely(! (cache = trace_cache_get()))) + { + Debug (1, "returning %d, cannot get trace cache\n", -UNW_ENOMEM); + *size = 0; + d->stash_frames = 0; + return -UNW_ENOMEM; + } + + /* Trace the stack upwards, starting from current PC. Adjust + the PC address for previous/next instruction as the main + unwinding logic would also do. We undo this before calling + back into unw_step(). */ + while (depth < maxdepth) + { + pc -= d->use_prev_instr; + Debug (2, "depth %d cfa 0x%x pc 0x%x sp 0x%x r7 0x%x\n", + depth, cfa, pc, sp, r7); + + /* See if we have this address cached. If not, evaluate enough of + the dwarf unwind information to fill the cache line data, or to + decide this frame cannot be handled in fast trace mode. We + cache negative results too to prevent unnecessary dwarf parsing + for common failures. */ + unw_tdep_frame_t *f = trace_lookup (cursor, cache, cfa, pc, r7, sp); + + /* If we don't have information for this frame, give up. */ + if (unlikely(! f)) + { + ret = -UNW_ENOINFO; + break; + } + + Debug (3, "frame va %x type %d last %d cfa %s+%d r7 @ cfa%+d lr @ cfa%+d sp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_sp ? "sp" : "r7", f->cfa_reg_offset, + f->r7_cfa_offset, f->lr_cfa_offset, f->sp_cfa_offset); + + assert (f->virtual_address == pc); + + /* Stop if this was the last frame. In particular don't evaluate + new register values as it may not be safe - we don't normally + run with full validation on, and do not want to - and there's + enough bad unwind info floating around that we need to trust + what unw_step() previously said, in potentially bogus frames. */ + if (f->last_frame) + break; + + /* Evaluate CFA and registers for the next frame. */ + switch (f->frame_type) + { + case UNW_ARM_FRAME_GUESSED: + /* Fall thru to standard processing after forcing validation. */ + c->validate = 1; + + case UNW_ARM_FRAME_STANDARD: + /* Advance standard traceable frame. */ + cfa = (f->cfa_reg_sp ? sp : r7) + f->cfa_reg_offset; + if (likely(f->lr_cfa_offset != -1)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc); + else if (lr != 0) + { + /* Use the saved link register as the new pc. */ + pc = lr; + lr = 0; + } + if (likely(ret >= 0) && likely(f->r7_cfa_offset != -1)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->r7_cfa_offset, r7); + + /* Don't bother reading SP from DWARF, CFA becomes new SP. */ + sp = cfa; + + /* Next frame needs to back up for unwind info lookup. */ + d->use_prev_instr = 1; + break; + + case UNW_ARM_FRAME_SIGRETURN: + cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ +#if defined(__linux__) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_PC_OFF, pc); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_R7_OFF, r7); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_SP_OFF, sp); + /* Save the link register here in case we end up in a function that + doesn't save the link register in the prologue, e.g. kill. */ + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_LR_OFF, lr); +#elif defined(__FreeBSD__) + printf("XXX\n"); +#endif + + /* Resume stack at signal restoration point. The stack is not + necessarily continuous here, especially with sigaltstack(). */ + cfa = sp; + + /* Next frame should not back up. */ + d->use_prev_instr = 0; + break; + + case UNW_ARM_FRAME_SYSCALL: + printf("XXX1\n"); + break; + + default: + /* We cannot trace through this frame, give up and tell the + caller we had to stop. Data collected so far may still be + useful to the caller, so let it know how far we got. */ + ret = -UNW_ESTOPUNWIND; + break; + } + + Debug (4, "new cfa 0x%x pc 0x%x sp 0x%x r7 0x%x\n", + cfa, pc, sp, r7); + + /* If we failed or ended up somewhere bogus, stop. */ + if (unlikely(ret < 0 || pc < 0x4000)) + break; + + /* Record this address in stack trace. We skipped the first address. */ + buffer[depth++] = (void *) (pc - d->use_prev_instr); + } + +#if UNW_DEBUG + Debug (1, "returning %d, depth %d\n", ret, depth); +#endif + *size = depth; + return ret; +} + diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lex_tables.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lex_tables.c new file mode 100644 index 00000000000000..4a4f925c9c3256 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lex_tables.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gex_tables.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lglobal.c new file mode 100644 index 00000000000000..6d7b489e14bd9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Linit.c b/src/coreclr/src/pal/src/libunwind/src/arm/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/arm/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/arm/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lis_signal_frame.c new file mode 100644 index 00000000000000..b9a7c4f51ad9fa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Los-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/arm/Los-freebsd.c new file mode 100644 index 00000000000000..a75a205df19c01 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Los-freebsd.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-freebsd.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Los-linux.c b/src/coreclr/src/pal/src/libunwind/src/arm/Los-linux.c new file mode 100644 index 00000000000000..3cc18aabcc399c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Los-linux.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-linux.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Los-other.c b/src/coreclr/src/pal/src/libunwind/src/arm/Los-other.c new file mode 100644 index 00000000000000..a75a205df19c01 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Los-other.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-freebsd.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lstash_frame.c new file mode 100644 index 00000000000000..77587803d083d7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lstash_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstash_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/arm/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ltrace.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ltrace.c new file mode 100644 index 00000000000000..24b7b3cfa62df4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Ltrace.c @@ -0,0 +1,6 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gtrace.c" +#endif + diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/gen-offsets.c b/src/coreclr/src/pal/src/libunwind/src/arm/gen-offsets.c new file mode 100644 index 00000000000000..7d6bf2f1c57043 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/gen-offsets.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +#define UC(N,X) \ + printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) + +#define SC(N,X) \ + printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) + +int +main (void) +{ + printf ( +"/* Linux-specific definitions: */\n\n" + +"/* Define various structure offsets to simplify cross-compilation. */\n\n" + +"/* Offsets for ARM Linux \"ucontext_t\": */\n\n"); + + UC ("FLAGS", uc_flags); + UC ("LINK", uc_link); + UC ("STACK", uc_stack); + UC ("MCONTEXT", uc_mcontext); + UC ("SIGMASK", uc_sigmask); + UC ("REGSPACE", uc_regspace); + + printf ("\n/* Offsets for ARM Linux \"struct sigcontext\": */\n\n"); + + SC ("TRAPNO", trap_no); + SC ("ERRORCODE", error_code); + SC ("OLDMASK", oldmask); + SC ("R0", arm_r0); + SC ("R1", arm_r1); + SC ("R2", arm_r2); + SC ("R3", arm_r3); + SC ("R4", arm_r4); + SC ("R5", arm_r5); + SC ("R6", arm_r6); + SC ("R7", arm_r7); + SC ("R8", arm_r8); + SC ("R9", arm_r9); + SC ("R10", arm_r10); + SC ("FP", arm_fp); + SC ("IP", arm_ip); + SC ("SP", arm_sp); + SC ("LR", arm_lr); + SC ("PC", arm_pc); + SC ("CPSR", arm_cpsr); + SC ("FAULTADDR", fault_address); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/arm/getcontext.S new file mode 100644 index 00000000000000..7e18784477d8f3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/getcontext.S @@ -0,0 +1,63 @@ +/* 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. */ + +#include "offsets.h" + + .text + .arm + + .global _Uarm_getcontext + .type _Uarm_getcontext, %function + @ This is a stub version of getcontext() for ARM which only stores core + @ registers. It must be called in a special way, not as a regular + @ function -- see also the libunwind-arm.h:unw_tdep_getcontext macro. +_Uarm_getcontext: + stmfd sp!, {r0, r1} + @ store r0 +#if defined(__linux__) + str r0, [r0, #LINUX_UC_MCONTEXT_OFF + LINUX_SC_R0_OFF] + add r0, r0, #LINUX_UC_MCONTEXT_OFF + LINUX_SC_R0_OFF +#elif defined(__FreeBSD__) + str r0, [r0, #FREEBSD_UC_MCONTEXT_OFF + FREEBSD_MC_R0_OFF] + add r0, r0, #FREEBSD_UC_MCONTEXT_OFF + FREEBSD_MC_R0_OFF +#else +#error Fix me +#endif + @ store r1 to r12 + stmib r0, {r1-r12} + @ reconstruct r13 at call site, then store + add r1, sp, #12 + str r1, [r0, #13 * 4] + @ retrieve r14 from call site, then store + ldr r1, [sp, #8] + str r1, [r0, #14 * 4] + @ point lr to instruction after call site's stack adjustment + add r1, lr, #4 + str r1, [r0, #15 * 4] + ldmfd sp!, {r0, r1} + bx lr +#if defined(__linux__) || defined(__FreeBSD__) + /* We do not need executable stack. */ + .section .note.GNU-stack,"",%progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/init.h b/src/coreclr/src/pal/src/libunwind/src/arm/init.h new file mode 100644 index 00000000000000..7d765ecf097f6f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/init.h @@ -0,0 +1,77 @@ +/* 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. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret, i; + + c->dwarf.loc[UNW_ARM_R0] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R0); + c->dwarf.loc[UNW_ARM_R1] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R1); + c->dwarf.loc[UNW_ARM_R2] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R2); + c->dwarf.loc[UNW_ARM_R3] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R3); + c->dwarf.loc[UNW_ARM_R4] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R4); + c->dwarf.loc[UNW_ARM_R5] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R5); + c->dwarf.loc[UNW_ARM_R6] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R6); + c->dwarf.loc[UNW_ARM_R7] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R7); + c->dwarf.loc[UNW_ARM_R8] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R8); + c->dwarf.loc[UNW_ARM_R9] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R9); + c->dwarf.loc[UNW_ARM_R10] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R10); + c->dwarf.loc[UNW_ARM_R11] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R11); + c->dwarf.loc[UNW_ARM_R12] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R12); + c->dwarf.loc[UNW_ARM_R13] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13); + c->dwarf.loc[UNW_ARM_R14] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R14); + c->dwarf.loc[UNW_ARM_R15] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R15); + for (i = UNW_ARM_R15 + 1; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); + if (ret < 0) + return ret; + + /* FIXME: correct for ARM? */ + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = ARM_SCF_NONE; + c->sigcontext_addr = 0; + c->sigcontext_sp = 0; + c->sigcontext_pc = 0; + + /* FIXME: Initialisation for other registers. */ + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/arm/is_fpreg.c new file mode 100644 index 00000000000000..e55bcff03edaac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/is_fpreg.c @@ -0,0 +1,39 @@ +/* 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. */ + +#include "libunwind_i.h" + +/* FIXME: I'm not sure if libunwind's GP/FP register distinction is very useful + on ARM. Count all the FP or coprocessor registers we know about for now. */ + +int +unw_is_fpreg (int regnum) +{ + return ((regnum >= UNW_ARM_S0 && regnum <= UNW_ARM_S31) + || (regnum >= UNW_ARM_F0 && regnum <= UNW_ARM_F7) + || (regnum >= UNW_ARM_wCGR0 && regnum <= UNW_ARM_wCGR7) + || (regnum >= UNW_ARM_wR0 && regnum <= UNW_ARM_wR15) + || (regnum >= UNW_ARM_wC0 && regnum <= UNW_ARM_wC7) + || (regnum >= UNW_ARM_D0 && regnum <= UNW_ARM_D31)); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/offsets.h b/src/coreclr/src/pal/src/libunwind/src/arm/offsets.h new file mode 100644 index 00000000000000..621701106c4e59 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/offsets.h @@ -0,0 +1,42 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* Offsets for ARM Linux "ucontext_t": */ + +#define LINUX_UC_FLAGS_OFF 0x00 +#define LINUX_UC_LINK_OFF 0x04 +#define LINUX_UC_STACK_OFF 0x08 +#define LINUX_UC_MCONTEXT_OFF 0x14 +#define LINUX_UC_SIGMASK_OFF 0x68 +#define LINUX_UC_REGSPACE_OFF 0xE8 + +/* Offsets for ARM Linux "struct sigcontext": */ + +#define LINUX_SC_TRAPNO_OFF 0x00 +#define LINUX_SC_ERRORCODE_OFF 0x04 +#define LINUX_SC_OLDMASK_OFF 0x08 +#define LINUX_SC_R0_OFF 0x0C +#define LINUX_SC_R1_OFF 0x10 +#define LINUX_SC_R2_OFF 0x14 +#define LINUX_SC_R3_OFF 0x18 +#define LINUX_SC_R4_OFF 0x1C +#define LINUX_SC_R5_OFF 0x20 +#define LINUX_SC_R6_OFF 0x24 +#define LINUX_SC_R7_OFF 0x28 +#define LINUX_SC_R8_OFF 0x2C +#define LINUX_SC_R9_OFF 0x30 +#define LINUX_SC_R10_OFF 0x34 +#define LINUX_SC_FP_OFF 0x38 +#define LINUX_SC_IP_OFF 0x3C +#define LINUX_SC_SP_OFF 0x40 +#define LINUX_SC_LR_OFF 0x44 +#define LINUX_SC_PC_OFF 0x48 +#define LINUX_SC_CPSR_OFF 0x4C +#define LINUX_SC_FAULTADDR_OFF 0x50 + +/* FreeBSD-specific definitions: */ + +#define FREEBSD_SC_UCONTEXT_OFF 0x40 +#define FREEBSD_UC_MCONTEXT_OFF 0x10 +#define FREEBSD_MC_R0_OFF 0 diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/regname.c b/src/coreclr/src/pal/src/libunwind/src/arm/regname.c new file mode 100644 index 00000000000000..7cac630c177113 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/regname.c @@ -0,0 +1,90 @@ +#include "unwind_i.h" + +static const char *regname[] = + { + /* 0. */ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + /* 8. */ + "r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc", + /* 16. Obsolete FPA names. */ + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + /* 24. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 32. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 40. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 48. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 56. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 64. */ + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + /* 72. */ + "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", + /* 80. */ + "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", + /* 88. */ + "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", + /* 96. */ + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + /* 104. */ + "wCGR0", "wCGR1", "wCGR2", "wCGR3", "wCGR4", "wCGR5", "wCGR6", "wCGR7", + /* 112. */ + "wR0", "wR1", "wR2", "wR3", "wR4", "wR5", "wR6", "wR7", + /* 128. */ + "spsr", "spsr_fiq", "spsr_irq", "spsr_abt", "spsr_und", "spsr_svc", 0, 0, + /* 136. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 144. */ + "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "r13_usr", "r14_usr", + /* 151. */ + "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "r14_fiq", + /* 158. */ + "r13_irq", "r14_irq", + /* 160. */ + "r13_abt", "r14_abt", + /* 162. */ + "r13_und", "r14_und", + /* 164. */ + "r13_svc", "r14_svc", 0, 0, + /* 168. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 176. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 184. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 192. */ + "wC0", "wC1", "wC2", "wC3", "wC4", "wC5", "wC6", "wC7", + /* 200. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 208. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 216. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 224. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 232. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 240. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 248. */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 256. */ + "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", + /* 264. */ + "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", + /* 272. */ + "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", + /* 280. */ + "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/arm/siglongjmp.S new file mode 100644 index 00000000000000..4df07366831914 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/siglongjmp.S @@ -0,0 +1,12 @@ + /* Dummy implementation for now. */ + + .globl _UI_siglongjmp_cont + .globl _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + bx lr +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",%progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/arm/unwind_i.h new file mode 100644 index 00000000000000..fe0bca005b1637 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/arm/unwind_i.h @@ -0,0 +1,62 @@ +/* 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 unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" + +/* DWARF column numbers for ARM: */ +#define R7 7 +#define SP 13 +#define LR 14 +#define PC 15 + +#define arm_lock UNW_OBJ(lock) +#define arm_local_resume UNW_OBJ(local_resume) +#define arm_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern void arm_local_addr_space_init (void); +extern int arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +#define arm_handle_signal_frame UNW_OBJ(handle_signal_frame) +extern int arm_handle_signal_frame(unw_cursor_t *cursor); + +/* By-pass calls to access_mem() when known to be safe. */ +#ifdef UNW_LOCAL_ONLY +# undef ACCESS_MEM_FAST +# define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ + do { \ + if (unlikely(validate)) \ + (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); \ + else \ + (ret) = 0, (to) = *(unw_word_t *)(addr); \ + } while (0) +#endif + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/README b/src/coreclr/src/pal/src/libunwind/src/coredump/README new file mode 100644 index 00000000000000..204493c93e91a2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/README @@ -0,0 +1,8 @@ +This code is based on "unwinding via ptrace" code from ptrace/ +directory. + +Files with names starting with _UCD_ are substantially changed +from their ptrace/_UPT_... progenitors. + +Files which still have _UPT_... names are either verbiatim copies +from ptrace/, or unimplemented stubs. diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_mem.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_mem.c new file mode 100644 index 00000000000000..1fdbd128ffc1e4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_mem.c @@ -0,0 +1,98 @@ +/* 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. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +int +_UCD_access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *val, + int write, void *arg) +{ + if (write) + { + Debug(0, "write is not supported\n"); + return -UNW_EINVAL; + } + + struct UCD_info *ui = arg; + + unw_word_t addr_last = addr + sizeof(*val)-1; + coredump_phdr_t *phdr; + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + phdr = &ui->phdrs[i]; + if (phdr->p_vaddr <= addr && addr_last < phdr->p_vaddr + phdr->p_memsz) + { + goto found; + } + } + Debug(1, "addr 0x%llx is unmapped\n", (unsigned long long)addr); + return -UNW_EINVAL; + + found: ; + + const char *filename UNUSED; + off_t fileofs; + int fd; + if (addr_last >= phdr->p_vaddr + phdr->p_filesz) + { + /* This part of mapped address space is not present in coredump file */ + /* Do we have it in the backup file? */ + if (phdr->backing_fd < 0) + { + Debug(1, "access to not-present data in phdr[%d]: addr:0x%llx\n", + i, (unsigned long long)addr + ); + return -UNW_EINVAL; + } + filename = phdr->backing_filename; + fileofs = addr - phdr->p_vaddr; + fd = phdr->backing_fd; + goto read; + } + + filename = ui->coredump_filename; + fileofs = phdr->p_offset + (addr - phdr->p_vaddr); + fd = ui->coredump_fd; + read: + if (lseek(fd, fileofs, SEEK_SET) != fileofs) + goto read_error; + if (read(fd, val, sizeof(*val)) != sizeof(*val)) + goto read_error; + + Debug(1, "0x%llx <- [addr:0x%llx fileofs:0x%llx]\n", + (unsigned long long)(*val), + (unsigned long long)addr, + (unsigned long long)fileofs + ); + return 0; + + read_error: + Debug(1, "access out of file: addr:0x%llx fileofs:%llx file:'%s'\n", + (unsigned long long)addr, + (unsigned long long)fileofs, + filename + ); + return -UNW_EINVAL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c new file mode 100644 index 00000000000000..930a1148e4f442 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c @@ -0,0 +1,157 @@ +/* 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. */ + +#include "_UCD_lib.h" + +#include "_UCD_internal.h" + +int +_UCD_access_reg (unw_addr_space_t as, + unw_regnum_t regnum, unw_word_t *valp, + int write, void *arg) +{ + if (write) + { + Debug(0, "write is not supported\n"); + return -UNW_EINVAL; + } + + struct UCD_info *ui = arg; + +#if defined(UNW_TARGET_X86) + switch (regnum) { + case UNW_X86_EAX: + *valp = ui->prstatus->pr_reg.r_eax; + break; + case UNW_X86_EDX: + *valp = ui->prstatus->pr_reg.r_edx; + break; + case UNW_X86_ECX: + *valp = ui->prstatus->pr_reg.r_ecx; + break; + case UNW_X86_EBX: + *valp = ui->prstatus->pr_reg.r_ebx; + break; + case UNW_X86_ESI: + *valp = ui->prstatus->pr_reg.r_esi; + break; + case UNW_X86_EDI: + *valp = ui->prstatus->pr_reg.r_edi; + break; + case UNW_X86_EBP: + *valp = ui->prstatus->pr_reg.r_ebp; + break; + case UNW_X86_ESP: + *valp = ui->prstatus->pr_reg.r_esp; + break; + case UNW_X86_EIP: + *valp = ui->prstatus->pr_reg.r_eip; + break; + case UNW_X86_EFLAGS: + *valp = ui->prstatus->pr_reg.r_eflags; + break; + case UNW_X86_TRAPNO: + *valp = ui->prstatus->pr_reg.r_trapno; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + } +#elif defined(UNW_TARGET_X86_64) + switch (regnum) { + case UNW_X86_64_RAX: + *valp = ui->prstatus->pr_reg.r_rax; + break; + case UNW_X86_64_RDX: + *valp = ui->prstatus->pr_reg.r_rdx; + break; + case UNW_X86_64_RCX: + *valp = ui->prstatus->pr_reg.r_rcx; + break; + case UNW_X86_64_RBX: + *valp = ui->prstatus->pr_reg.r_rbx; + break; + case UNW_X86_64_RSI: + *valp = ui->prstatus->pr_reg.r_rsi; + break; + case UNW_X86_64_RDI: + *valp = ui->prstatus->pr_reg.r_rdi; + break; + case UNW_X86_64_RBP: + *valp = ui->prstatus->pr_reg.r_rbp; + break; + case UNW_X86_64_RSP: + *valp = ui->prstatus->pr_reg.r_rsp; + break; + case UNW_X86_64_RIP: + *valp = ui->prstatus->pr_reg.r_rip; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + } +#elif defined(UNW_TARGET_ARM) + if (regnum >= UNW_ARM_R0 && regnum <= UNW_ARM_R12) { + *valp = ui->prstatus->pr_reg.r[regnum]; + } else { + switch (regnum) { + case UNW_ARM_R13: + *valp = ui->prstatus->pr_reg.r_sp; + break; + case UNW_ARM_R14: + *valp = ui->prstatus->pr_reg.r_lr; + break; + case UNW_ARM_R15: + *valp = ui->prstatus->pr_reg.r_pc; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + } + } +#elif defined(UNW_TARGET_AARCH64) + if (regnum >= UNW_AARCH64_X0 && regnum < UNW_AARCH64_X30) { + *valp = ui->prstatus->pr_reg.x[regnum]; + } else { + switch (regnum) { + case UNW_AARCH64_SP: + *valp = ui->prstatus->pr_reg.sp; + break; + case UNW_AARCH64_X30: + *valp = ui->prstatus->pr_reg.lr; + break; + case UNW_AARCH64_PC: + *valp = ui->prstatus->pr_reg.elr; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + } + } + +#else +#error Port me +#endif + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c new file mode 100644 index 00000000000000..43792f849b3d7a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c @@ -0,0 +1,149 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" + +#include "_UCD_internal.h" + +int +_UCD_access_reg (unw_addr_space_t as, + unw_regnum_t regnum, unw_word_t *valp, + int write, void *arg) +{ + struct UCD_info *ui = arg; + + if (write) + { + Debug(0, "write is not supported\n"); + return -UNW_EINVAL; + } + + if (regnum < 0) + goto badreg; + +#if defined(UNW_TARGET_AARCH64) + if (regnum >= UNW_AARCH64_FPCR) + goto badreg; +#elif defined(UNW_TARGET_ARM) + if (regnum >= 16) + goto badreg; +#elif defined(UNW_TARGET_SH) + if (regnum > UNW_SH_PR) + goto badreg; +#elif defined(UNW_TARGET_TILEGX) + if (regnum > UNW_TILEGX_CFA) + goto badreg; +#elif defined(UNW_TARGET_S390X) + if (regnum > UNW_S390X_R15) + goto badreg; +#else +#if defined(UNW_TARGET_MIPS) + static const uint8_t remap_regs[] = + { + [UNW_MIPS_R0] = EF_REG0, + [UNW_MIPS_R1] = EF_REG1, + [UNW_MIPS_R2] = EF_REG2, + [UNW_MIPS_R3] = EF_REG3, + [UNW_MIPS_R4] = EF_REG4, + [UNW_MIPS_R5] = EF_REG5, + [UNW_MIPS_R6] = EF_REG6, + [UNW_MIPS_R7] = EF_REG7, + [UNW_MIPS_R8] = EF_REG8, + [UNW_MIPS_R9] = EF_REG9, + [UNW_MIPS_R10] = EF_REG10, + [UNW_MIPS_R11] = EF_REG11, + [UNW_MIPS_R12] = EF_REG12, + [UNW_MIPS_R13] = EF_REG13, + [UNW_MIPS_R14] = EF_REG14, + [UNW_MIPS_R15] = EF_REG15, + [UNW_MIPS_R16] = EF_REG16, + [UNW_MIPS_R17] = EF_REG17, + [UNW_MIPS_R18] = EF_REG18, + [UNW_MIPS_R19] = EF_REG19, + [UNW_MIPS_R20] = EF_REG20, + [UNW_MIPS_R21] = EF_REG21, + [UNW_MIPS_R22] = EF_REG22, + [UNW_MIPS_R23] = EF_REG23, + [UNW_MIPS_R24] = EF_REG24, + [UNW_MIPS_R25] = EF_REG25, + [UNW_MIPS_R28] = EF_REG28, + [UNW_MIPS_R29] = EF_REG29, + [UNW_MIPS_R30] = EF_REG30, + [UNW_MIPS_R31] = EF_REG31, + [UNW_MIPS_PC] = EF_CP0_EPC, + }; +#elif defined(UNW_TARGET_X86) + static const uint8_t remap_regs[] = + { + /* names from libunwind-x86.h */ + [UNW_X86_EAX] = offsetof(struct user_regs_struct, eax) / sizeof(long), + [UNW_X86_EDX] = offsetof(struct user_regs_struct, edx) / sizeof(long), + [UNW_X86_ECX] = offsetof(struct user_regs_struct, ecx) / sizeof(long), + [UNW_X86_EBX] = offsetof(struct user_regs_struct, ebx) / sizeof(long), + [UNW_X86_ESI] = offsetof(struct user_regs_struct, esi) / sizeof(long), + [UNW_X86_EDI] = offsetof(struct user_regs_struct, edi) / sizeof(long), + [UNW_X86_EBP] = offsetof(struct user_regs_struct, ebp) / sizeof(long), + [UNW_X86_ESP] = offsetof(struct user_regs_struct, esp) / sizeof(long), + [UNW_X86_EIP] = offsetof(struct user_regs_struct, eip) / sizeof(long), + [UNW_X86_EFLAGS] = offsetof(struct user_regs_struct, eflags) / sizeof(long), + [UNW_X86_TRAPNO] = offsetof(struct user_regs_struct, orig_eax) / sizeof(long), + }; +#elif defined(UNW_TARGET_X86_64) + static const int8_t remap_regs[] = + { + [UNW_X86_64_RAX] = offsetof(struct user_regs_struct, rax) / sizeof(long), + [UNW_X86_64_RDX] = offsetof(struct user_regs_struct, rdx) / sizeof(long), + [UNW_X86_64_RCX] = offsetof(struct user_regs_struct, rcx) / sizeof(long), + [UNW_X86_64_RBX] = offsetof(struct user_regs_struct, rbx) / sizeof(long), + [UNW_X86_64_RSI] = offsetof(struct user_regs_struct, rsi) / sizeof(long), + [UNW_X86_64_RDI] = offsetof(struct user_regs_struct, rdi) / sizeof(long), + [UNW_X86_64_RBP] = offsetof(struct user_regs_struct, rbp) / sizeof(long), + [UNW_X86_64_RSP] = offsetof(struct user_regs_struct, rsp) / sizeof(long), + [UNW_X86_64_RIP] = offsetof(struct user_regs_struct, rip) / sizeof(long), + }; +#else +#error Port me +#endif + + if (regnum >= (unw_regnum_t)ARRAY_SIZE(remap_regs)) + goto badreg; + + regnum = remap_regs[regnum]; +#endif + + /* pr_reg is a long[] array, but it contains struct user_regs_struct's + * image. + */ + Debug(1, "pr_reg[%d]:%ld (0x%lx)\n", regnum, + (long)ui->prstatus->pr_reg[regnum], + (long)ui->prstatus->pr_reg[regnum] + ); + *valp = ui->prstatus->pr_reg[regnum]; + + return 0; + +badreg: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_accessors.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_accessors.c new file mode 100644 index 00000000000000..ae5c23d21940b9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_accessors.c @@ -0,0 +1,36 @@ +/* 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. */ + +#include "_UCD_internal.h" + +unw_accessors_t _UCD_accessors = + { + .find_proc_info = _UCD_find_proc_info, + .put_unwind_info = _UCD_put_unwind_info, + .get_dyn_info_list_addr = _UCD_get_dyn_info_list_addr, + .access_mem = _UCD_access_mem, + .access_reg = _UCD_access_reg, + .access_fpreg = _UCD_access_fpreg, + .resume = _UCD_resume, + .get_proc_name = _UCD_get_proc_name + }; diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c new file mode 100644 index 00000000000000..4c430efb27b53c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c @@ -0,0 +1,424 @@ +/* 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. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* Endian detection */ +#include +#if defined(HAVE_BYTESWAP_H) +#include +#endif +#if defined(HAVE_ENDIAN_H) +# include +#elif defined(HAVE_SYS_ENDIAN_H) +# include +#endif +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN +# define WE_ARE_BIG_ENDIAN 1 +# define WE_ARE_LITTLE_ENDIAN 0 +#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#elif defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN +# define WE_ARE_BIG_ENDIAN 1 +# define WE_ARE_LITTLE_ENDIAN 0 +#elif defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#elif defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN +# define WE_ARE_BIG_ENDIAN 1 +# define WE_ARE_LITTLE_ENDIAN 0 +#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#elif defined(__386__) +# define WE_ARE_BIG_ENDIAN 0 +# define WE_ARE_LITTLE_ENDIAN 1 +#else +# error "Can't determine endianness" +#endif + +#include +#include /* struct elf_prstatus */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +#define NOTE_DATA(_hdr) STRUCT_MEMBER_P((_hdr), sizeof (Elf32_Nhdr) + UNW_ALIGN((_hdr)->n_namesz, 4)) +#define NOTE_SIZE(_hdr) (sizeof (Elf32_Nhdr) + UNW_ALIGN((_hdr)->n_namesz, 4) + UNW_ALIGN((_hdr)->n_descsz, 4)) +#define NOTE_NEXT(_hdr) STRUCT_MEMBER_P((_hdr), NOTE_SIZE(_hdr)) +#define NOTE_FITS_IN(_hdr, _size) ((_size) >= sizeof (Elf32_Nhdr) && (_size) >= NOTE_SIZE (_hdr)) +#define NOTE_FITS(_hdr, _end) NOTE_FITS_IN((_hdr), (unsigned long)((char *)(_end) - (char *)(_hdr))) + +struct UCD_info * +_UCD_create(const char *filename) +{ + union + { + Elf32_Ehdr h32; + Elf64_Ehdr h64; + } elf_header; +#define elf_header32 elf_header.h32 +#define elf_header64 elf_header.h64 + bool _64bits; + + struct UCD_info *ui = memset(malloc(sizeof(*ui)), 0, sizeof(*ui)); + ui->edi.di_cache.format = -1; + ui->edi.di_debug.format = -1; +#if UNW_TARGET_IA64 + ui->edi.ktab.format = -1; +#endif + + int fd = ui->coredump_fd = open(filename, O_RDONLY); + if (fd < 0) + goto err; + ui->coredump_filename = strdup(filename); + + /* No sane ELF32 file is going to be smaller then ELF64 _header_, + * so let's just read 64-bit sized one. + */ + if (read(fd, &elf_header64, sizeof(elf_header64)) != sizeof(elf_header64)) + { + Debug(0, "'%s' is not an ELF file\n", filename); + goto err; + } + + if (memcmp(&elf_header32, ELFMAG, SELFMAG) != 0) + { + Debug(0, "'%s' is not an ELF file\n", filename); + goto err; + } + + if (elf_header32.e_ident[EI_CLASS] != ELFCLASS32 + && elf_header32.e_ident[EI_CLASS] != ELFCLASS64) + { + Debug(0, "'%s' is not a 32/64 bit ELF file\n", filename); + goto err; + } + + if (WE_ARE_LITTLE_ENDIAN != (elf_header32.e_ident[EI_DATA] == ELFDATA2LSB)) + { + Debug(0, "'%s' is endian-incompatible\n", filename); + goto err; + } + + _64bits = (elf_header32.e_ident[EI_CLASS] == ELFCLASS64); + if (_64bits && sizeof(elf_header64.e_entry) > sizeof(off_t)) + { + Debug(0, "Can't process '%s': 64-bit file " + "while only %ld bits are supported", + filename, 8L * sizeof(off_t)); + goto err; + } + + /* paranoia check */ + if (_64bits + ? 0 /* todo: (elf_header64.e_ehsize != NN || elf_header64.e_phentsize != NN) */ + : (elf_header32.e_ehsize != 52 || elf_header32.e_phentsize != 32) + ) + { + Debug(0, "'%s' has wrong e_ehsize or e_phentsize\n", filename); + goto err; + } + + off_t ofs = (_64bits ? elf_header64.e_phoff : elf_header32.e_phoff); + if (lseek(fd, ofs, SEEK_SET) != ofs) + { + Debug(0, "Can't read phdrs from '%s'\n", filename); + goto err; + } + unsigned size = ui->phdrs_count = (_64bits ? elf_header64.e_phnum : elf_header32.e_phnum); + coredump_phdr_t *phdrs = ui->phdrs = memset(malloc(size * sizeof(phdrs[0])), 0, size * sizeof(phdrs[0])); + if (_64bits) + { + coredump_phdr_t *cur = phdrs; + unsigned i = 0; + while (i < size) + { + Elf64_Phdr hdr64; + if (read(fd, &hdr64, sizeof(hdr64)) != sizeof(hdr64)) + { + Debug(0, "Can't read phdrs from '%s'\n", filename); + goto err; + } + cur->p_type = hdr64.p_type ; + cur->p_flags = hdr64.p_flags ; + cur->p_offset = hdr64.p_offset; + cur->p_vaddr = hdr64.p_vaddr ; + /*cur->p_paddr = hdr32.p_paddr ; always 0 */ +//TODO: check that and abort if it isn't? + cur->p_filesz = hdr64.p_filesz; + cur->p_memsz = hdr64.p_memsz ; + cur->p_align = hdr64.p_align ; + /* cur->backing_filename = NULL; - done by memset */ + cur->backing_fd = -1; + cur->backing_filesize = hdr64.p_filesz; + i++; + cur++; + } + } else { + coredump_phdr_t *cur = phdrs; + unsigned i = 0; + while (i < size) + { + Elf32_Phdr hdr32; + if (read(fd, &hdr32, sizeof(hdr32)) != sizeof(hdr32)) + { + Debug(0, "Can't read phdrs from '%s'\n", filename); + goto err; + } + cur->p_type = hdr32.p_type ; + cur->p_flags = hdr32.p_flags ; + cur->p_offset = hdr32.p_offset; + cur->p_vaddr = hdr32.p_vaddr ; + /*cur->p_paddr = hdr32.p_paddr ; always 0 */ + cur->p_filesz = hdr32.p_filesz; + cur->p_memsz = hdr32.p_memsz ; + cur->p_align = hdr32.p_align ; + /* cur->backing_filename = NULL; - done by memset */ + cur->backing_fd = -1; + cur->backing_filesize = hdr32.p_memsz; + i++; + cur++; + } + } + + unsigned i = 0; + coredump_phdr_t *cur = phdrs; + while (i < size) + { + Debug(2, "phdr[%03d]: type:%d", i, cur->p_type); + if (cur->p_type == PT_NOTE) + { + Elf32_Nhdr *note_hdr, *note_end; + unsigned n_threads; + + ui->note_phdr = malloc(cur->p_filesz); + if (lseek(fd, cur->p_offset, SEEK_SET) != (off_t)cur->p_offset + || (uoff_t)read(fd, ui->note_phdr, cur->p_filesz) != cur->p_filesz) + { + Debug(0, "Can't read PT_NOTE from '%s'\n", filename); + goto err; + } + + note_end = STRUCT_MEMBER_P (ui->note_phdr, cur->p_filesz); + + /* Count number of threads */ + n_threads = 0; + note_hdr = (Elf32_Nhdr *)ui->note_phdr; + while (NOTE_FITS (note_hdr, note_end)) + { + if (note_hdr->n_type == NT_PRSTATUS) + n_threads++; + + note_hdr = NOTE_NEXT (note_hdr); + } + + ui->n_threads = n_threads; + ui->threads = malloc(sizeof (void *) * n_threads); + + n_threads = 0; + note_hdr = (Elf32_Nhdr *)ui->note_phdr; + while (NOTE_FITS (note_hdr, note_end)) + { + if (note_hdr->n_type == NT_PRSTATUS) + ui->threads[n_threads++] = NOTE_DATA (note_hdr); + + note_hdr = NOTE_NEXT (note_hdr); + } + } + if (cur->p_type == PT_LOAD) + { + Debug(2, " ofs:%08llx va:%08llx filesize:%08llx memsize:%08llx flg:%x", + (unsigned long long) cur->p_offset, + (unsigned long long) cur->p_vaddr, + (unsigned long long) cur->p_filesz, + (unsigned long long) cur->p_memsz, + cur->p_flags + ); + if (cur->p_filesz < cur->p_memsz) + { + Debug(2, " partial"); + } + if (cur->p_flags & PF_X) + { + Debug(2, " executable"); + } + } + Debug(2, "\n"); + i++; + cur++; + } + + if (ui->n_threads == 0) + { + Debug(0, "No NT_PRSTATUS note found in '%s'\n", filename); + goto err; + } + + ui->prstatus = ui->threads[0]; + + return ui; + + err: + _UCD_destroy(ui); + return NULL; +} + +int _UCD_get_num_threads(struct UCD_info *ui) +{ + return ui->n_threads; +} + +void _UCD_select_thread(struct UCD_info *ui, int n) +{ + if (n >= 0 && n < ui->n_threads) + ui->prstatus = ui->threads[n]; +} + +pid_t _UCD_get_pid(struct UCD_info *ui) +{ + return ui->prstatus->pr_pid; +} + +int _UCD_get_cursig(struct UCD_info *ui) +{ + return ui->prstatus->pr_cursig; +} + +int _UCD_add_backing_file_at_segment(struct UCD_info *ui, int phdr_no, const char *filename) +{ + if ((unsigned)phdr_no >= ui->phdrs_count) + { + Debug(0, "There is no segment %d in this coredump\n", phdr_no); + return -1; + } + + struct coredump_phdr *phdr = &ui->phdrs[phdr_no]; + if (phdr->backing_filename) + { + Debug(0, "Backing file already added to segment %d\n", phdr_no); + return -1; + } + + int fd = open(filename, O_RDONLY); + if (fd < 0) + { + Debug(0, "Can't open '%s'\n", filename); + return -1; + } + + phdr->backing_fd = fd; + phdr->backing_filename = strdup(filename); + + struct stat statbuf; + if (fstat(fd, &statbuf) != 0) + { + Debug(0, "Can't stat '%s'\n", filename); + goto err; + } + phdr->backing_filesize = (uoff_t)statbuf.st_size; + + if (phdr->p_flags != (PF_X | PF_R)) + { + Debug(1, "Note: phdr[%u] is not r-x: flags are 0x%x\n", + phdr_no, phdr->p_flags); + } + + if (phdr->backing_filesize > phdr->p_memsz) + { + /* This is expected */ + Debug(2, "Note: phdr[%u] is %lld bytes, file is larger: %lld bytes\n", + phdr_no, + (unsigned long long)phdr->p_memsz, + (unsigned long long)phdr->backing_filesize + ); + } +//TODO: else loudly complain? Maybe even fail? + + if (phdr->p_filesz != 0) + { +//TODO: loop and compare in smaller blocks + char *core_buf = malloc(phdr->p_filesz); + char *file_buf = malloc(phdr->p_filesz); + if (lseek(ui->coredump_fd, phdr->p_offset, SEEK_SET) != (off_t)phdr->p_offset + || (uoff_t)read(ui->coredump_fd, core_buf, phdr->p_filesz) != phdr->p_filesz + ) + { + Debug(0, "Error reading from coredump file\n"); + err_read: + free(core_buf); + free(file_buf); + goto err; + } + if ((uoff_t)read(fd, file_buf, phdr->p_filesz) != phdr->p_filesz) + { + Debug(0, "Error reading from '%s'\n", filename); + goto err_read; + } + int r = memcmp(core_buf, file_buf, phdr->p_filesz); + free(core_buf); + free(file_buf); + if (r != 0) + { + Debug(1, "Note: phdr[%u] first %lld bytes in core dump and in file do not match\n", + phdr_no, (unsigned long long)phdr->p_filesz + ); + } else { + Debug(1, "Note: phdr[%u] first %lld bytes in core dump and in file match\n", + phdr_no, (unsigned long long)phdr->p_filesz + ); + } + } + + /* Success */ + return 0; + + err: + if (phdr->backing_fd >= 0) + { + close(phdr->backing_fd); + phdr->backing_fd = -1; + } + free(phdr->backing_filename); + phdr->backing_filename = NULL; + return -1; +} + +int _UCD_add_backing_file_at_vaddr(struct UCD_info *ui, + unsigned long vaddr, + const char *filename) +{ + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + struct coredump_phdr *phdr = &ui->phdrs[i]; + if (phdr->p_vaddr != vaddr) + continue; + /* It seems to match. Add it. */ + return _UCD_add_backing_file_at_segment(ui, i, filename); + } + return -1; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_destroy.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_destroy.c new file mode 100644 index 00000000000000..ddc36ec8986aad --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_destroy.c @@ -0,0 +1,52 @@ +/* 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. */ + +#include "_UCD_internal.h" + +void +_UCD_destroy (struct UCD_info *ui) +{ + if (!ui) + return; + + if (ui->coredump_fd >= 0) + close(ui->coredump_fd); + free(ui->coredump_filename); + + invalidate_edi (&ui->edi); + + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + struct coredump_phdr *phdr = &ui->phdrs[i]; + free(phdr->backing_filename); + if (phdr->backing_fd >= 0) + close(phdr->backing_fd); + } + + free(ui->phdrs); + free(ui->note_phdr); + free(ui->threads); + + free(ui); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_elf_map_image.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_elf_map_image.c new file mode 100644 index 00000000000000..4b3db0bbff7ee2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_elf_map_image.c @@ -0,0 +1,98 @@ +/* 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. */ + +#include + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +static coredump_phdr_t * +CD_elf_map_image(struct UCD_info *ui, coredump_phdr_t *phdr) +{ + struct elf_image *ei = &ui->edi.ei; + + if (phdr->backing_fd < 0) + { + /* Note: coredump file contains only phdr->p_filesz bytes. + * We want to map bigger area (phdr->p_memsz bytes) to make sure + * these pages are allocated, but non-accessible. + */ + /* addr, length, prot, flags, fd, fd_offset */ + ei->image = mmap(NULL, phdr->p_memsz, PROT_READ, MAP_PRIVATE, ui->coredump_fd, phdr->p_offset); + if (ei->image == MAP_FAILED) + { + ei->image = NULL; + return NULL; + } + ei->size = phdr->p_filesz; + size_t remainder_len = phdr->p_memsz - phdr->p_filesz; + if (remainder_len > 0) + { + void *remainder_base = (char*) ei->image + phdr->p_filesz; + munmap(remainder_base, remainder_len); + } + } else { + /* We have a backing file for this segment. + * This file is always longer than phdr->p_memsz, + * and if phdr->p_filesz !=0, first phdr->p_filesz bytes in coredump + * are the same as first bytes in the file. (Thus no need to map coredump) + * We map the entire file: + * unwinding may need data which is past phdr->p_memsz bytes. + */ + /* addr, length, prot, flags, fd, fd_offset */ + ei->image = mmap(NULL, phdr->backing_filesize, PROT_READ, MAP_PRIVATE, phdr->backing_fd, 0); + if (ei->image == MAP_FAILED) + { + ei->image = NULL; + return NULL; + } + ei->size = phdr->backing_filesize; + } + + /* Check ELF header for sanity */ + if (!elf_w(valid_object)(ei)) + { + munmap(ei->image, ei->size); + ei->image = NULL; + ei->size = 0; + return NULL; + } + + return phdr; +} + +HIDDEN coredump_phdr_t * +_UCD_get_elf_image(struct UCD_info *ui, unw_word_t ip) +{ + unsigned i; + for (i = 0; i < ui->phdrs_count; i++) + { + coredump_phdr_t *phdr = &ui->phdrs[i]; + if (phdr->p_vaddr <= ip && ip < phdr->p_vaddr + phdr->p_memsz) + { + phdr = CD_elf_map_image(ui, phdr); + return phdr; + } + } + return NULL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_find_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_find_proc_info.c new file mode 100644 index 00000000000000..33b66c8edbe1dc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_find_proc_info.c @@ -0,0 +1,163 @@ +/* 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. */ + +#include + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +static int +get_unwind_info(struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip) +{ + unsigned long segbase, mapoff; + +#if UNW_TARGET_IA64 && defined(__linux) + if (!ui->edi.ktab.start_ip && _Uia64_get_kernel_table (&ui->edi.ktab) < 0) + return -UNW_ENOINFO; + + if (ui->edi.ktab.format != -1 && ip >= ui->edi.ktab.start_ip && ip < ui->edi.ktab.end_ip) + return 0; +#endif + + if ((ui->edi.di_cache.format != -1 + && ip >= ui->edi.di_cache.start_ip && ip < ui->edi.di_cache.end_ip) +#if UNW_TARGET_ARM + || (ui->edi.di_debug.format != -1 + && ip >= ui->edi.di_arm.start_ip && ip < ui->edi.di_arm.end_ip) +#endif + || (ui->edi.di_debug.format != -1 + && ip >= ui->edi.di_debug.start_ip && ip < ui->edi.di_debug.end_ip)) + return 0; + + invalidate_edi (&ui->edi); + + /* Used to be tdep_get_elf_image() in ptrace unwinding code */ + coredump_phdr_t *phdr = _UCD_get_elf_image(ui, ip); + if (!phdr) + { + Debug(1, "returns error: _UCD_get_elf_image failed\n"); + return -UNW_ENOINFO; + } + /* segbase: where it is mapped in virtual memory */ + /* mapoff: offset in the file */ + segbase = phdr->p_vaddr; + /*mapoff = phdr->p_offset; WRONG! phdr->p_offset is the offset in COREDUMP file */ + mapoff = 0; +///FIXME. text segment is USUALLY, not always, at offset 0 in the binary/.so file. +// ensure that at initialization. + + /* Here, SEGBASE is the starting-address of the (mmap'ped) segment + which covers the IP we're looking for. */ + if (tdep_find_unwind_table(&ui->edi, as, phdr->backing_filename, segbase, mapoff, ip) < 0) + { + Debug(1, "returns error: tdep_find_unwind_table failed\n"); + return -UNW_ENOINFO; + } + + /* This can happen in corner cases where dynamically generated + code falls into the same page that contains the data-segment + and the page-offset of the code is within the first page of + the executable. */ + if (ui->edi.di_cache.format != -1 + && (ip < ui->edi.di_cache.start_ip || ip >= ui->edi.di_cache.end_ip)) + ui->edi.di_cache.format = -1; + + if (ui->edi.di_debug.format != -1 + && (ip < ui->edi.di_debug.start_ip || ip >= ui->edi.di_debug.end_ip)) + ui->edi.di_debug.format = -1; + + if (ui->edi.di_cache.format == -1 +#if UNW_TARGET_ARM + && ui->edi.di_arm.format == -1 +#endif + && ui->edi.di_debug.format == -1) + { + Debug(1, "returns error: all formats are -1\n"); + return -UNW_ENOINFO; + } + + Debug(1, "returns success\n"); + return 0; +} + +int +_UCD_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + struct UCD_info *ui = arg; + + Debug(1, "entering\n"); + + int ret = -UNW_ENOINFO; + + if (get_unwind_info(ui, as, ip) < 0) { + Debug(1, "returns error: get_unwind_info failed\n"); + return -UNW_ENOINFO; + } + +#if UNW_TARGET_IA64 + if (ui->edi.ktab.format != -1) + { + /* The kernel unwind table resides in local memory, so we have + to use the local address space to search it. Since + _UCD_put_unwind_info() has no easy way of detecting this + case, we simply make a copy of the unwind-info, so + _UCD_put_unwind_info() can always free() the unwind-info + without ill effects. */ + ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi, + need_unwind_info, arg); + if (ret >= 0) + { + if (!need_unwind_info) + pi->unwind_info = NULL; + else + { + void *mem = malloc (pi->unwind_info_size); + + if (!mem) + return -UNW_ENOMEM; + memcpy (mem, pi->unwind_info, pi->unwind_info_size); + pi->unwind_info = mem; + } + } + } +#endif + + if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache, + pi, need_unwind_info, arg); + +#if UNW_TARGET_ARM + if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_arm, pi, + need_unwind_info, arg); +#endif + + if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi, + need_unwind_info, arg); + + Debug(1, "returns %d\n", ret); + + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c new file mode 100644 index 00000000000000..3a4c9b8213c6db --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c @@ -0,0 +1,74 @@ +/* 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. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + + +/* Find the ELF image that contains IP and return the "closest" + procedure name, if there is one. With some caching, this could be + sped up greatly, but until an application materializes that's + sensitive to the performance of this routine, why bother... */ +static int +elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) +{ + unsigned long segbase, mapoff; + int ret; + + /* We're about to map an elf image. If there is an elf image currently mapped, + then make sure to unmap it. */ + invalidate_edi(&ui->edi); + + /* Used to be tdep_get_elf_image() in ptrace unwinding code */ + coredump_phdr_t *cphdr = _UCD_get_elf_image(ui, ip); + if (!cphdr) + { + Debug(1, "returns error: _UCD_get_elf_image failed\n"); + return -UNW_ENOINFO; + } + /* segbase: where it is mapped in virtual memory */ + /* mapoff: offset in the file */ + segbase = cphdr->p_vaddr; + /*mapoff = phdr->p_offset; WRONG! phdr->p_offset is the offset in COREDUMP file */ + mapoff = 0; + + ret = elf_w (get_proc_name_in_image) (as, &ui->edi.ei, segbase, mapoff, ip, buf, buf_len, offp); + + return ret; +} + +int +_UCD_get_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, void *arg) +{ + struct UCD_info *ui = arg; + +#if ELF_CLASS == ELFCLASS64 + return _Uelf64_CD_get_proc_name (ui, as, ip, buf, buf_len, offp); +#elif ELF_CLASS == ELFCLASS32 + return _Uelf32_CD_get_proc_name (ui, as, ip, buf, buf_len, offp); +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_internal.h b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_internal.h new file mode 100644 index 00000000000000..3c95a2a0038c7a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_internal.h @@ -0,0 +1,105 @@ +/* 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 _UCD_internal_h +#define _UCD_internal_h + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_PROCFS_H +#include /* struct elf_prstatus */ +#endif +#include +#include +#include +#include +#include + +#include + +#include "libunwind_i.h" + + +#if SIZEOF_OFF_T == 4 +typedef uint32_t uoff_t; +#elif SIZEOF_OFF_T == 8 +typedef uint64_t uoff_t; +#else +# error Unknown size of off_t! +#endif + + +/* Similar to ELF phdrs. p_paddr element is absent, + * since it's always 0 in coredumps. + */ +struct coredump_phdr + { + uint32_t p_type; + uint32_t p_flags; + uoff_t p_offset; + uoff_t p_vaddr; + uoff_t p_filesz; + uoff_t p_memsz; + uoff_t p_align; + /* Data for backing file. If backing_fd < 0, there is no file */ + uoff_t backing_filesize; + char *backing_filename; /* for error meesages only */ + int backing_fd; + }; + +typedef struct coredump_phdr coredump_phdr_t; + +#if defined(HAVE_STRUCT_ELF_PRSTATUS) +#define PRSTATUS_STRUCT elf_prstatus +#elif defined(HAVE_STRUCT_PRSTATUS) +#define PRSTATUS_STRUCT prstatus +#else +#define PRSTATUS_STRUCT non_existent +#endif + +struct UCD_info + { + int big_endian; /* bool */ + int coredump_fd; + char *coredump_filename; /* for error meesages only */ + coredump_phdr_t *phdrs; /* array, allocated */ + unsigned phdrs_count; + void *note_phdr; /* allocated or NULL */ + struct PRSTATUS_STRUCT *prstatus; /* points inside note_phdr */ + int n_threads; + struct PRSTATUS_STRUCT **threads; + + struct elf_dyn_info edi; + }; + +extern coredump_phdr_t * _UCD_get_elf_image(struct UCD_info *ui, unw_word_t ip); + +#define STRUCT_MEMBER_P(struct_p, struct_offset) ((void *) ((char*) (struct_p) + (long) (struct_offset))) +#define STRUCT_MEMBER(member_type, struct_p, struct_offset) (*(member_type*) STRUCT_MEMBER_P ((struct_p), (struct_offset))) + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_lib.h b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_lib.h new file mode 100644 index 00000000000000..22be32ed1efa1c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_lib.h @@ -0,0 +1,57 @@ +/* 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 _UCD_lib_h +#define _UCD_lib_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_access_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_access_fpreg.c new file mode 100644 index 00000000000000..0b8b86ac9072aa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_access_fpreg.c @@ -0,0 +1,34 @@ +/* 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. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +int +_UCD_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + print_error (__func__); + print_error (" not implemented\n"); + return -UNW_EINVAL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_elf.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_elf.c new file mode 100644 index 00000000000000..fb7b19a7cbd8ba --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_elf.c @@ -0,0 +1,5 @@ +/* We need to get a separate copy of the ELF-code into + libunwind-coredump since it cannot (and must not) have any ELF + dependencies on libunwind. */ +#include "libunwind_i.h" /* get ELFCLASS defined */ +#include "../elfxx.c" diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c new file mode 100644 index 00000000000000..739ed0569b9e6f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c @@ -0,0 +1,113 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +#if UNW_TARGET_IA64 && defined(__linux) +# include "elf64.h" +# include "os-linux.h" + +static inline int +get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, + int *countp) +{ + unsigned long lo, hi, off; + struct UPT_info *ui = arg; + struct map_iterator mi; + char path[PATH_MAX]; + unw_dyn_info_t *di; + unw_word_t res; + int count = 0; + + maps_init (&mi, ui->pid); + while (maps_next (&mi, &lo, &hi, &off)) + { + if (off) + continue; + + invalidate_edi (&ui->edi); + + if (elf_map_image (&ui->ei, path) < 0) + /* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */ + continue; + + Debug (16, "checking object %s\n", path); + + di = tdep_find_unwind_table (&ui->edi, as, path, lo, off); + if (di) + { + res = _Uia64_find_dyn_list (as, di, arg); + if (res && count++ == 0) + { + Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res); + *dil_addr = res; + } + } + } + maps_close (&mi); + *countp = count; + return 0; +} + +#else + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + +static inline int +get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, + int *countp) +{ +# warning Implement get_list_addr(), please. + *countp = 0; + return 0; +} + +#endif + +int +_UCD_get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, + void *arg) +{ + int count, ret; + + Debug (12, "looking for dyn_info list\n"); + + if ((ret = get_list_addr (as, dil_addr, arg, &count)) < 0) + return ret; + + /* If multiple dynamic-info list addresses are found, we would have + to determine which was is the one actually in use (since the + dynamic name resolution algorithm will pick one "winner"). + Perhaps we'd have to track them all until we find one that's + non-empty. Hopefully, this case simply will never arise, since + only libunwind defines the dynamic info list head. */ + assert (count <= 1); + + return (count > 0) ? 0 : -UNW_ENOINFO; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_put_unwind_info.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_put_unwind_info.c new file mode 100644 index 00000000000000..462e1d048c3906 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_put_unwind_info.c @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +void +_UCD_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + if (!pi->unwind_info) + return; + free (pi->unwind_info); + pi->unwind_info = NULL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_resume.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_resume.c new file mode 100644 index 00000000000000..a729c908cb123e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_resume.c @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UCD_lib.h" +#include "_UCD_internal.h" + +int +_UCD_resume (unw_addr_space_t as, unw_cursor_t *c, void *arg) +{ + print_error (__func__); + print_error (" not implemented\n"); + return -UNW_EINVAL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/libunwind-coredump.pc.in b/src/coreclr/src/pal/src/libunwind/src/coredump/libunwind-coredump.pc.in new file mode 100644 index 00000000000000..9cb62c086d23c3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/libunwind-coredump.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libunwind-coredump +Description: libunwind coredump library +Version: @VERSION@ +Requires: libunwind-generic libunwind +Libs: -L${libdir} -lunwind-coredump +Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c new file mode 100644 index 00000000000000..2af454332dd825 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c @@ -0,0 +1,702 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "dwarf_i.h" +#include "libunwind_i.h" + +/* The "pick" operator provides an index range of 0..255 indicating + that the stack could at least have a depth of up to 256 elements, + but the GCC unwinder restricts the depth to 64, which seems + reasonable so we use the same value here. */ +#define MAX_EXPR_STACK_SIZE 64 + +#define NUM_OPERANDS(signature) (((signature) >> 6) & 0x3) +#define OPND1_TYPE(signature) (((signature) >> 3) & 0x7) +#define OPND2_TYPE(signature) (((signature) >> 0) & 0x7) + +#define OPND_SIGNATURE(n, t1, t2) (((n) << 6) | ((t1) << 3) | ((t2) << 0)) +#define OPND1(t1) OPND_SIGNATURE(1, t1, 0) +#define OPND2(t1, t2) OPND_SIGNATURE(2, t1, t2) + +#define VAL8 0x0 +#define VAL16 0x1 +#define VAL32 0x2 +#define VAL64 0x3 +#define ULEB128 0x4 +#define SLEB128 0x5 +#define OFFSET 0x6 /* 32-bit offset for 32-bit DWARF, 64-bit otherwise */ +#define ADDR 0x7 /* Machine address. */ + +static const uint8_t operands[256] = + { + [DW_OP_addr] = OPND1 (ADDR), + [DW_OP_const1u] = OPND1 (VAL8), + [DW_OP_const1s] = OPND1 (VAL8), + [DW_OP_const2u] = OPND1 (VAL16), + [DW_OP_const2s] = OPND1 (VAL16), + [DW_OP_const4u] = OPND1 (VAL32), + [DW_OP_const4s] = OPND1 (VAL32), + [DW_OP_const8u] = OPND1 (VAL64), + [DW_OP_const8s] = OPND1 (VAL64), + [DW_OP_constu] = OPND1 (ULEB128), + [DW_OP_consts] = OPND1 (SLEB128), + [DW_OP_pick] = OPND1 (VAL8), + [DW_OP_plus_uconst] = OPND1 (ULEB128), + [DW_OP_skip] = OPND1 (VAL16), + [DW_OP_bra] = OPND1 (VAL16), + [DW_OP_breg0 + 0] = OPND1 (SLEB128), + [DW_OP_breg0 + 1] = OPND1 (SLEB128), + [DW_OP_breg0 + 2] = OPND1 (SLEB128), + [DW_OP_breg0 + 3] = OPND1 (SLEB128), + [DW_OP_breg0 + 4] = OPND1 (SLEB128), + [DW_OP_breg0 + 5] = OPND1 (SLEB128), + [DW_OP_breg0 + 6] = OPND1 (SLEB128), + [DW_OP_breg0 + 7] = OPND1 (SLEB128), + [DW_OP_breg0 + 8] = OPND1 (SLEB128), + [DW_OP_breg0 + 9] = OPND1 (SLEB128), + [DW_OP_breg0 + 10] = OPND1 (SLEB128), + [DW_OP_breg0 + 11] = OPND1 (SLEB128), + [DW_OP_breg0 + 12] = OPND1 (SLEB128), + [DW_OP_breg0 + 13] = OPND1 (SLEB128), + [DW_OP_breg0 + 14] = OPND1 (SLEB128), + [DW_OP_breg0 + 15] = OPND1 (SLEB128), + [DW_OP_breg0 + 16] = OPND1 (SLEB128), + [DW_OP_breg0 + 17] = OPND1 (SLEB128), + [DW_OP_breg0 + 18] = OPND1 (SLEB128), + [DW_OP_breg0 + 19] = OPND1 (SLEB128), + [DW_OP_breg0 + 20] = OPND1 (SLEB128), + [DW_OP_breg0 + 21] = OPND1 (SLEB128), + [DW_OP_breg0 + 22] = OPND1 (SLEB128), + [DW_OP_breg0 + 23] = OPND1 (SLEB128), + [DW_OP_breg0 + 24] = OPND1 (SLEB128), + [DW_OP_breg0 + 25] = OPND1 (SLEB128), + [DW_OP_breg0 + 26] = OPND1 (SLEB128), + [DW_OP_breg0 + 27] = OPND1 (SLEB128), + [DW_OP_breg0 + 28] = OPND1 (SLEB128), + [DW_OP_breg0 + 29] = OPND1 (SLEB128), + [DW_OP_breg0 + 30] = OPND1 (SLEB128), + [DW_OP_breg0 + 31] = OPND1 (SLEB128), + [DW_OP_regx] = OPND1 (ULEB128), + [DW_OP_fbreg] = OPND1 (SLEB128), + [DW_OP_bregx] = OPND2 (ULEB128, SLEB128), + [DW_OP_piece] = OPND1 (ULEB128), + [DW_OP_deref_size] = OPND1 (VAL8), + [DW_OP_xderef_size] = OPND1 (VAL8), + [DW_OP_call2] = OPND1 (VAL16), + [DW_OP_call4] = OPND1 (VAL32), + [DW_OP_call_ref] = OPND1 (OFFSET) + }; + +static inline unw_sword_t +sword (unw_addr_space_t as, unw_word_t val) +{ + switch (dwarf_addr_size (as)) + { + case 1: return (int8_t) val; + case 2: return (int16_t) val; + case 4: return (int32_t) val; + case 8: return (int64_t) val; + default: abort (); + } +} + +static inline unw_word_t +read_operand (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int operand_type, unw_word_t *val, void *arg) +{ + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + int ret; + + if (operand_type == ADDR) + switch (dwarf_addr_size (as)) + { + case 1: operand_type = VAL8; break; + case 2: operand_type = VAL16; break; + case 4: operand_type = VAL32; break; + case 8: operand_type = VAL64; break; + default: abort (); + } + + switch (operand_type) + { + case VAL8: + ret = dwarf_readu8 (as, a, addr, &u8, arg); + if (ret < 0) + return ret; + *val = u8; + break; + + case VAL16: + ret = dwarf_readu16 (as, a, addr, &u16, arg); + if (ret < 0) + return ret; + *val = u16; + break; + + case VAL32: + ret = dwarf_readu32 (as, a, addr, &u32, arg); + if (ret < 0) + return ret; + *val = u32; + break; + + case VAL64: + ret = dwarf_readu64 (as, a, addr, &u64, arg); + if (ret < 0) + return ret; + *val = u64; + break; + + case ULEB128: + ret = dwarf_read_uleb128 (as, a, addr, val, arg); + break; + + case SLEB128: + ret = dwarf_read_sleb128 (as, a, addr, val, arg); + break; + + case OFFSET: /* only used by DW_OP_call_ref, which we don't implement */ + default: + Debug (1, "Unexpected operand type %d\n", operand_type); + ret = -UNW_EINVAL; + } + return ret; +} + +HIDDEN int +dwarf_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr, + unw_word_t rbp_addr, unw_word_t *cfa_offset) { + unw_accessors_t *a; + int ret; + void *arg; + unw_word_t len; + uint8_t opcode; + unw_word_t operand1; + + a = unw_get_accessors_int (c->as); + arg = c->as_arg; + + ret = dwarf_read_uleb128(c->as, a, &rbp_addr, &len, arg); + if (len != 2 || ret < 0) + return 0; + + ret = dwarf_readu8(c->as, a, &rbp_addr, &opcode, arg); + if (ret < 0 || opcode != DW_OP_breg6) + return 0; + + ret = read_operand(c->as, a, &rbp_addr, + OPND1_TYPE(operands[opcode]), &operand1, arg); + + if (ret < 0 || operand1 != 0) + return 0; + + ret = dwarf_read_uleb128(c->as, a, &cfa_addr, &len, arg); + if (ret < 0 || len != 3) + return 0; + + ret = dwarf_readu8(c->as, a, &cfa_addr, &opcode, arg); + if (ret < 0 || opcode != DW_OP_breg6) + return 0; + + ret = read_operand(c->as, a, &cfa_addr, + OPND1_TYPE(operands[opcode]), &operand1, arg); + if (ret < 0) + return 0; + + ret = dwarf_readu8(c->as, a, &cfa_addr, &opcode, arg); + if (ret < 0 || opcode != DW_OP_deref) + return 0; + + *cfa_offset = operand1; + return 1; +} + +HIDDEN int +dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, + unw_word_t len, unw_word_t *valp, int *is_register) +{ + unw_word_t operand1 = 0, operand2 = 0, tmp1, tmp2 = 0, tmp3, end_addr; + uint8_t opcode, operands_signature, u8; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + unw_word_t stack[MAX_EXPR_STACK_SIZE]; + unsigned int tos = 0; + uint16_t u16; + uint32_t u32; + uint64_t u64; + int ret; +# define pop() \ +({ \ + if ((tos - 1) >= MAX_EXPR_STACK_SIZE) \ + { \ + Debug (1, "Stack underflow\n"); \ + return -UNW_EINVAL; \ + } \ + stack[--tos]; \ +}) +# define push(x) \ +do { \ + unw_word_t _x = (x); \ + if (tos >= MAX_EXPR_STACK_SIZE) \ + { \ + Debug (1, "Stack overflow\n"); \ + return -UNW_EINVAL; \ + } \ + stack[tos++] = _x; \ +} while (0) +# define pick(n) \ +({ \ + unsigned int _index = tos - 1 - (n); \ + if (_index >= MAX_EXPR_STACK_SIZE) \ + { \ + Debug (1, "Out-of-stack pick\n"); \ + return -UNW_EINVAL; \ + } \ + stack[_index]; \ +}) + + as = c->as; + arg = c->as_arg; + a = unw_get_accessors_int (as); + end_addr = *addr + len; + *is_register = 0; + + Debug (14, "len=%lu, pushing initial value=0x%lx\n", + (unsigned long) len, (unsigned long) stack_val); + + /* The DWARF standard requires the current CFA to be pushed onto the stack */ + /* before evaluating DW_CFA_expression and DW_CFA_val_expression programs. */ + /* DW_CFA_def_cfa_expressions do not take an initial value, but we push on */ + /* a dummy value to keep this logic consistent. */ + push (stack_val); + + while (*addr < end_addr) + { + if ((ret = dwarf_readu8 (as, a, addr, &opcode, arg)) < 0) + return ret; + + operands_signature = operands[opcode]; + + if (unlikely (NUM_OPERANDS (operands_signature) > 0)) + { + if ((ret = read_operand (as, a, addr, + OPND1_TYPE (operands_signature), + &operand1, arg)) < 0) + return ret; + if (NUM_OPERANDS (operands_signature) > 1) + if ((ret = read_operand (as, a, addr, + OPND2_TYPE (operands_signature), + &operand2, arg)) < 0) + return ret; + } + + switch ((dwarf_expr_op_t) opcode) + { + case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: + case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: + case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: + case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: + case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: + case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: + case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: + case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: + case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: + case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: + case DW_OP_lit30: case DW_OP_lit31: + Debug (15, "OP_lit(%d)\n", (int) opcode - DW_OP_lit0); + push (opcode - DW_OP_lit0); + break; + + case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: + case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: + case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: + case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: + case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: + case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: + case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: + case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: + case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: + case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: + case DW_OP_breg30: case DW_OP_breg31: + Debug (15, "OP_breg(r%d,0x%lx)\n", + (int) opcode - DW_OP_breg0, (unsigned long) operand1); + if ((ret = unw_get_reg (dwarf_to_cursor (c), + dwarf_to_unw_regnum (opcode - DW_OP_breg0), + &tmp1)) < 0) + return ret; + push (tmp1 + operand1); + break; + + case DW_OP_bregx: + Debug (15, "OP_bregx(r%d,0x%lx)\n", + (int) operand1, (unsigned long) operand2); + if ((ret = unw_get_reg (dwarf_to_cursor (c), + dwarf_to_unw_regnum (operand1), &tmp1)) < 0) + return ret; + push (tmp1 + operand2); + break; + + case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: + case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: + case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: + case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: + case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: + case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: + case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: + case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: + case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: + case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: + case DW_OP_reg30: case DW_OP_reg31: + Debug (15, "OP_reg(r%d)\n", (int) opcode - DW_OP_reg0); + *valp = dwarf_to_unw_regnum (opcode - DW_OP_reg0); + *is_register = 1; + return 0; + + case DW_OP_regx: + Debug (15, "OP_regx(r%d)\n", (int) operand1); + *valp = dwarf_to_unw_regnum (operand1); + *is_register = 1; + return 0; + + case DW_OP_addr: + case DW_OP_const1u: + case DW_OP_const2u: + case DW_OP_const4u: + case DW_OP_const8u: + case DW_OP_constu: + case DW_OP_const8s: + case DW_OP_consts: + Debug (15, "OP_const(0x%lx)\n", (unsigned long) operand1); + push (operand1); + break; + + case DW_OP_const1s: + if (operand1 & 0x80) + operand1 |= ((unw_word_t) -1) << 8; + Debug (15, "OP_const1s(%ld)\n", (long) operand1); + push (operand1); + break; + + case DW_OP_const2s: + if (operand1 & 0x8000) + operand1 |= ((unw_word_t) -1) << 16; + Debug (15, "OP_const2s(%ld)\n", (long) operand1); + push (operand1); + break; + + case DW_OP_const4s: + if (operand1 & 0x80000000) + operand1 |= (((unw_word_t) -1) << 16) << 16; + Debug (15, "OP_const4s(%ld)\n", (long) operand1); + push (operand1); + break; + + case DW_OP_deref: + Debug (15, "OP_deref\n"); + tmp1 = pop (); + if ((ret = dwarf_readw (as, a, &tmp1, &tmp2, arg)) < 0) + return ret; + push (tmp2); + break; + + case DW_OP_deref_size: + Debug (15, "OP_deref_size(%d)\n", (int) operand1); + tmp1 = pop (); + switch (operand1) + { + default: + Debug (1, "Unexpected DW_OP_deref_size size %d\n", + (int) operand1); + return -UNW_EINVAL; + + case 1: + if ((ret = dwarf_readu8 (as, a, &tmp1, &u8, arg)) < 0) + return ret; + tmp2 = u8; + break; + + case 2: + if ((ret = dwarf_readu16 (as, a, &tmp1, &u16, arg)) < 0) + return ret; + tmp2 = u16; + break; + + case 3: + case 4: + if ((ret = dwarf_readu32 (as, a, &tmp1, &u32, arg)) < 0) + return ret; + tmp2 = u32; + if (operand1 == 3) + { + if (dwarf_is_big_endian (as)) + tmp2 >>= 8; + else + tmp2 &= 0xffffff; + } + break; + case 5: + case 6: + case 7: + case 8: + if ((ret = dwarf_readu64 (as, a, &tmp1, &u64, arg)) < 0) + return ret; + tmp2 = u64; + if (operand1 != 8) + { + if (dwarf_is_big_endian (as)) + tmp2 >>= 64 - 8 * operand1; + else + tmp2 &= (~ (unw_word_t) 0) << (8 * operand1); + } + break; + } + push (tmp2); + break; + + case DW_OP_dup: + Debug (15, "OP_dup\n"); + push (pick (0)); + break; + + case DW_OP_drop: + Debug (15, "OP_drop\n"); + (void) pop (); + break; + + case DW_OP_pick: + Debug (15, "OP_pick(%d)\n", (int) operand1); + push (pick (operand1)); + break; + + case DW_OP_over: + Debug (15, "OP_over\n"); + push (pick (1)); + break; + + case DW_OP_swap: + Debug (15, "OP_swap\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp1); + push (tmp2); + break; + + case DW_OP_rot: + Debug (15, "OP_rot\n"); + tmp1 = pop (); + tmp2 = pop (); + tmp3 = pop (); + push (tmp1); + push (tmp3); + push (tmp2); + break; + + case DW_OP_abs: + Debug (15, "OP_abs\n"); + tmp1 = pop (); + if (tmp1 & ((unw_word_t) 1 << (8 * dwarf_addr_size (as) - 1))) + tmp1 = -tmp1; + push (tmp1); + break; + + case DW_OP_and: + Debug (15, "OP_and\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp1 & tmp2); + break; + + case DW_OP_div: + Debug (15, "OP_div\n"); + tmp1 = pop (); + tmp2 = pop (); + if (tmp1) + tmp1 = sword (as, tmp2) / sword (as, tmp1); + push (tmp1); + break; + + case DW_OP_minus: + Debug (15, "OP_minus\n"); + tmp1 = pop (); + tmp2 = pop (); + tmp1 = tmp2 - tmp1; + push (tmp1); + break; + + case DW_OP_mod: + Debug (15, "OP_mod\n"); + tmp1 = pop (); + tmp2 = pop (); + if (tmp1) + tmp1 = tmp2 % tmp1; + push (tmp1); + break; + + case DW_OP_mul: + Debug (15, "OP_mul\n"); + tmp1 = pop (); + tmp2 = pop (); + if (tmp1) + tmp1 = tmp2 * tmp1; + push (tmp1); + break; + + case DW_OP_neg: + Debug (15, "OP_neg\n"); + push (-pop ()); + break; + + case DW_OP_not: + Debug (15, "OP_not\n"); + push (~pop ()); + break; + + case DW_OP_or: + Debug (15, "OP_or\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp1 | tmp2); + break; + + case DW_OP_plus: + Debug (15, "OP_plus\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp1 + tmp2); + break; + + case DW_OP_plus_uconst: + Debug (15, "OP_plus_uconst(%lu)\n", (unsigned long) operand1); + tmp1 = pop (); + push (tmp1 + operand1); + break; + + case DW_OP_shl: + Debug (15, "OP_shl\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp2 << tmp1); + break; + + case DW_OP_shr: + Debug (15, "OP_shr\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp2 >> tmp1); + break; + + case DW_OP_shra: + Debug (15, "OP_shra\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) >> tmp1); + break; + + case DW_OP_xor: + Debug (15, "OP_xor\n"); + tmp1 = pop (); + tmp2 = pop (); + push (tmp1 ^ tmp2); + break; + + case DW_OP_le: + Debug (15, "OP_le\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) <= sword (as, tmp1)); + break; + + case DW_OP_ge: + Debug (15, "OP_ge\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) >= sword (as, tmp1)); + break; + + case DW_OP_eq: + Debug (15, "OP_eq\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) == sword (as, tmp1)); + break; + + case DW_OP_lt: + Debug (15, "OP_lt\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) < sword (as, tmp1)); + break; + + case DW_OP_gt: + Debug (15, "OP_gt\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) > sword (as, tmp1)); + break; + + case DW_OP_ne: + Debug (15, "OP_ne\n"); + tmp1 = pop (); + tmp2 = pop (); + push (sword (as, tmp2) != sword (as, tmp1)); + break; + + case DW_OP_skip: + Debug (15, "OP_skip(%d)\n", (int16_t) operand1); + *addr += (int16_t) operand1; + break; + + case DW_OP_bra: + Debug (15, "OP_skip(%d)\n", (int16_t) operand1); + tmp1 = pop (); + if (tmp1) + *addr += (int16_t) operand1; + break; + + case DW_OP_nop: + Debug (15, "OP_nop\n"); + break; + + case DW_OP_call2: + case DW_OP_call4: + case DW_OP_call_ref: + case DW_OP_fbreg: + case DW_OP_piece: + case DW_OP_push_object_address: + case DW_OP_xderef: + case DW_OP_xderef_size: + default: + Debug (1, "Unexpected opcode 0x%x\n", opcode); + return -UNW_EINVAL; + } + } + *valp = pop (); + Debug (14, "final value = 0x%lx\n", (unsigned long) *valp); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfde.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfde.c new file mode 100644 index 00000000000000..9250b895eabebd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfde.c @@ -0,0 +1,359 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "dwarf_i.h" + +static inline int +is_cie_id (unw_word_t val, int is_debug_frame) +{ + /* The CIE ID is normally 0xffffffff (for 32-bit ELF) or + 0xffffffffffffffff (for 64-bit ELF). However, .eh_frame + uses 0. */ + if (is_debug_frame) + return (val == (uint32_t)(-1) || val == (uint64_t)(-1)); + else + return (val == 0); +} + +/* Note: we don't need to keep track of more than the first four + characters of the augmentation string, because we (a) ignore any + augmentation string contents once we find an unrecognized character + and (b) those characters that we do recognize, can't be + repeated. */ +static inline int +parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr, + const unw_proc_info_t *pi, struct dwarf_cie_info *dci, + int is_debug_frame, void *arg) +{ + uint8_t version, ch, augstr[5], fde_encoding, handler_encoding; + unw_word_t len, cie_end_addr, aug_size; + uint32_t u32val; + uint64_t u64val; + size_t i; + int ret; +# define STR2(x) #x +# define STR(x) STR2(x) + + /* Pick appropriate default for FDE-encoding. DWARF spec says + start-IP (initial_location) and the code-size (address_range) are + "address-unit sized constants". The `R' augmentation can be used + to override this, but by default, we pick an address-sized unit + for fde_encoding. */ + switch (dwarf_addr_size (as)) + { + case 4: fde_encoding = DW_EH_PE_udata4; break; + case 8: fde_encoding = DW_EH_PE_udata8; break; + default: fde_encoding = DW_EH_PE_omit; break; + } + + dci->lsda_encoding = DW_EH_PE_omit; + dci->handler = 0; + + if ((ret = dwarf_readu32 (as, a, &addr, &u32val, arg)) < 0) + return ret; + + if (u32val != 0xffffffff) + { + /* the CIE is in the 32-bit DWARF format */ + uint32_t cie_id; + /* DWARF says CIE id should be 0xffffffff, but in .eh_frame, it's 0 */ + const uint32_t expected_id = (is_debug_frame) ? 0xffffffff : 0; + + len = u32val; + cie_end_addr = addr + len; + if ((ret = dwarf_readu32 (as, a, &addr, &cie_id, arg)) < 0) + return ret; + if (cie_id != expected_id) + { + Debug (1, "Unexpected CIE id %x\n", cie_id); + return -UNW_EINVAL; + } + } + else + { + /* the CIE is in the 64-bit DWARF format */ + uint64_t cie_id; + /* DWARF says CIE id should be 0xffffffffffffffff, but in + .eh_frame, it's 0 */ + const uint64_t expected_id = (is_debug_frame) ? 0xffffffffffffffffull : 0; + + if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0) + return ret; + len = u64val; + cie_end_addr = addr + len; + if ((ret = dwarf_readu64 (as, a, &addr, &cie_id, arg)) < 0) + return ret; + if (cie_id != expected_id) + { + Debug (1, "Unexpected CIE id %llx\n", (long long) cie_id); + return -UNW_EINVAL; + } + } + dci->cie_instr_end = cie_end_addr; + + if ((ret = dwarf_readu8 (as, a, &addr, &version, arg)) < 0) + return ret; + + /* GCC emits version 1??? */ + if (version != 1 && (version < DWARF_CIE_VERSION || version > DWARF_CIE_VERSION_MAX)) + { + Debug (1, "Got CIE version %u, expected version 1 or between " + STR (DWARF_CIE_VERSION) " and " STR (DWARF_CIE_VERSION_MAX) "\n", version); + return -UNW_EBADVERSION; + } + + /* read and parse the augmentation string: */ + memset (augstr, 0, sizeof (augstr)); + for (i = 0;;) + { + if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) + return ret; + + if (!ch) + break; /* end of augmentation string */ + + if (i < sizeof (augstr) - 1) + augstr[i++] = ch; + } + + if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->code_align, arg)) < 0 + || (ret = dwarf_read_sleb128 (as, a, &addr, &dci->data_align, arg)) < 0) + return ret; + + /* Read the return-address column either as a u8 or as a uleb128. */ + if (version == 1) + { + if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) + return ret; + dci->ret_addr_column = ch; + } + else if ((ret = dwarf_read_uleb128 (as, a, &addr, &dci->ret_addr_column, + arg)) < 0) + return ret; + + i = 0; + if (augstr[0] == 'z') + { + dci->sized_augmentation = 1; + if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0) + return ret; + i++; + } + + for (; i < sizeof (augstr) && augstr[i]; ++i) + switch (augstr[i]) + { + case 'L': + /* read the LSDA pointer-encoding format. */ + if ((ret = dwarf_readu8 (as, a, &addr, &ch, arg)) < 0) + return ret; + dci->lsda_encoding = ch; + break; + + case 'R': + /* read the FDE pointer-encoding format. */ + if ((ret = dwarf_readu8 (as, a, &addr, &fde_encoding, arg)) < 0) + return ret; + break; + + case 'P': + /* read the personality-routine pointer-encoding format. */ + if ((ret = dwarf_readu8 (as, a, &addr, &handler_encoding, arg)) < 0) + return ret; + if ((ret = dwarf_read_encoded_pointer (as, a, &addr, handler_encoding, + pi, &dci->handler, arg)) < 0) + return ret; + break; + + case 'S': + /* This is a signal frame. */ + dci->signal_frame = 1; + + /* Temporarily set it to one so dwarf_parse_fde() knows that + it should fetch the actual ABI/TAG pair from the FDE. */ + dci->have_abi_marker = 1; + break; + + default: + Debug (1, "Unexpected augmentation string `%s'\n", augstr); + if (dci->sized_augmentation) + /* If we have the size of the augmentation body, we can skip + over the parts that we don't understand, so we're OK. */ + goto done; + else + return -UNW_EINVAL; + } + done: + dci->fde_encoding = fde_encoding; + dci->cie_instr_start = addr; + Debug (15, "CIE parsed OK, augmentation = \"%s\", handler=0x%lx\n", + augstr, (long) dci->handler); + return 0; +} + +/* Extract proc-info from the FDE starting at adress ADDR. + + Pass BASE as zero for eh_frame behaviour, or a pointer to + debug_frame base for debug_frame behaviour. */ + +HIDDEN int +dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addrp, unw_proc_info_t *pi, + unw_word_t base, + int need_unwind_info, int is_debug_frame, + void *arg) +{ + unw_word_t fde_end_addr, cie_addr, cie_offset_addr, aug_end_addr = 0; + unw_word_t start_ip, ip_range, aug_size, addr = *addrp; + int ret, ip_range_encoding; + struct dwarf_cie_info dci; + uint64_t u64val; + uint32_t u32val; + + Debug (12, "FDE @ 0x%lx\n", (long) addr); + + memset (&dci, 0, sizeof (dci)); + + if ((ret = dwarf_readu32 (as, a, &addr, &u32val, arg)) < 0) + return ret; + + if (u32val != 0xffffffff) + { + int32_t cie_offset = 0; + + /* In some configurations, an FDE with a 0 length indicates the + end of the FDE-table. */ + if (u32val == 0) + return -UNW_ENOINFO; + + /* the FDE is in the 32-bit DWARF format */ + + *addrp = fde_end_addr = addr + u32val; + cie_offset_addr = addr; + + if ((ret = dwarf_reads32 (as, a, &addr, &cie_offset, arg)) < 0) + return ret; + + if (is_cie_id (cie_offset, is_debug_frame)) + /* ignore CIEs (happens during linear searches) */ + return 0; + + if (is_debug_frame) + cie_addr = base + cie_offset; + else + /* DWARF says that the CIE_pointer in the FDE is a + .debug_frame-relative offset, but the GCC-generated .eh_frame + sections instead store a "pcrelative" offset, which is just + as fine as it's self-contained. */ + cie_addr = cie_offset_addr - cie_offset; + } + else + { + int64_t cie_offset = 0; + + /* the FDE is in the 64-bit DWARF format */ + + if ((ret = dwarf_readu64 (as, a, &addr, &u64val, arg)) < 0) + return ret; + + *addrp = fde_end_addr = addr + u64val; + cie_offset_addr = addr; + + if ((ret = dwarf_reads64 (as, a, &addr, &cie_offset, arg)) < 0) + return ret; + + if (is_cie_id (cie_offset, is_debug_frame)) + /* ignore CIEs (happens during linear searches) */ + return 0; + + if (is_debug_frame) + cie_addr = base + cie_offset; + else + /* DWARF says that the CIE_pointer in the FDE is a + .debug_frame-relative offset, but the GCC-generated .eh_frame + sections instead store a "pcrelative" offset, which is just + as fine as it's self-contained. */ + cie_addr = (unw_word_t) ((uint64_t) cie_offset_addr - cie_offset); + } + + Debug (15, "looking for CIE at address %lx\n", (long) cie_addr); + + if ((ret = parse_cie (as, a, cie_addr, pi, &dci, is_debug_frame, arg)) < 0) + return ret; + + /* IP-range has same encoding as FDE pointers, except that it's + always an absolute value: */ + ip_range_encoding = dci.fde_encoding & DW_EH_PE_FORMAT_MASK; + + if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.fde_encoding, + pi, &start_ip, arg)) < 0 + || (ret = dwarf_read_encoded_pointer (as, a, &addr, ip_range_encoding, + pi, &ip_range, arg)) < 0) + return ret; + pi->start_ip = start_ip; + pi->end_ip = start_ip + ip_range; + pi->handler = dci.handler; + + if (dci.sized_augmentation) + { + if ((ret = dwarf_read_uleb128 (as, a, &addr, &aug_size, arg)) < 0) + return ret; + aug_end_addr = addr + aug_size; + } + + if ((ret = dwarf_read_encoded_pointer (as, a, &addr, dci.lsda_encoding, + pi, &pi->lsda, arg)) < 0) + return ret; + + Debug (15, "FDE covers IP 0x%lx-0x%lx, LSDA=0x%lx\n", + (long) pi->start_ip, (long) pi->end_ip, (long) pi->lsda); + + if (need_unwind_info) + { + pi->format = UNW_INFO_FORMAT_TABLE; + pi->unwind_info_size = sizeof (dci); + pi->unwind_info = mempool_alloc (&dwarf_cie_info_pool); + if (!pi->unwind_info) + return -UNW_ENOMEM; + + if (dci.have_abi_marker) + { + if ((ret = dwarf_readu16 (as, a, &addr, &dci.abi, arg)) < 0 + || (ret = dwarf_readu16 (as, a, &addr, &dci.tag, arg)) < 0) + return ret; + Debug (13, "Found ABI marker = (abi=%u, tag=%u)\n", + dci.abi, dci.tag); + } + + if (dci.sized_augmentation) + dci.fde_instr_start = aug_end_addr; + else + dci.fde_instr_start = addr; + dci.fde_instr_end = fde_end_addr; + + memcpy (pi->unwind_info, &dci, sizeof (dci)); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c new file mode 100644 index 00000000000000..0cfb4d4faea051 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c @@ -0,0 +1,990 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +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. */ + +/* Locate an FDE via the ELF data-structures defined by LSB v1.3 + (http://www.linuxbase.org/spec/). */ + +#include +#include +#include + +#include "dwarf_i.h" +#include "dwarf-eh.h" +#include "libunwind_i.h" + +#ifdef HAVE_ZLIB +#include +#endif /* HAVE_ZLIB */ + +struct table_entry + { + int32_t start_ip_offset; + int32_t fde_offset; + }; + +#ifndef UNW_REMOTE_ONLY + +#ifdef __linux +#include "os-linux.h" +#endif + +#ifndef __clang__ +static ALIAS(dwarf_search_unwind_table) int +dwarf_search_unwind_table_int (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); +#else +#define dwarf_search_unwind_table_int dwarf_search_unwind_table +#endif + +static int +linear_search (unw_addr_space_t as, unw_word_t ip, + unw_word_t eh_frame_start, unw_word_t eh_frame_end, + unw_word_t fde_count, + unw_proc_info_t *pi, int need_unwind_info, void *arg) +{ + unw_accessors_t *a = unw_get_accessors_int (unw_local_addr_space); + unw_word_t i = 0, fde_addr, addr = eh_frame_start; + int ret; + + while (i++ < fde_count && addr < eh_frame_end) + { + fde_addr = addr; + if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, + eh_frame_start, + 0, 0, arg)) < 0) + return ret; + + if (ip >= pi->start_ip && ip < pi->end_ip) + { + if (!need_unwind_info) + return 1; + addr = fde_addr; + if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, + eh_frame_start, + need_unwind_info, 0, + arg)) + < 0) + return ret; + return 1; + } + } + return -UNW_ENOINFO; +} +#endif /* !UNW_REMOTE_ONLY */ + +#ifdef CONFIG_DEBUG_FRAME +/* Load .debug_frame section from FILE. Allocates and returns space + in *BUF, and sets *BUFSIZE to its size. IS_LOCAL is 1 if using the + local process, in which case we can search the system debug file + directory; 0 for other address spaces, in which case we do + not. Returns 0 on success, 1 on error. Succeeds even if the file + contains no .debug_frame. */ +/* XXX: Could use mmap; but elf_map_image keeps tons mapped in. */ + +static int +load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local) +{ + struct elf_image ei; + Elf_W (Shdr) *shdr; + int ret; + + ei.image = NULL; + + ret = elf_w (load_debuglink) (file, &ei, is_local); + if (ret != 0) + return ret; + + shdr = elf_w (find_section) (&ei, ".debug_frame"); + if (!shdr || + (shdr->sh_offset + shdr->sh_size > ei.size)) + { + munmap(ei.image, ei.size); + return 1; + } + + if (shdr->sh_flags & SHF_COMPRESSED) + { + unsigned long destSize; + Elf_W (Chdr) *chdr = (shdr->sh_offset + ei.image); +#ifdef HAVE_ZLIB + if (chdr->ch_type == ELFCOMPRESS_ZLIB) + { + *bufsize = destSize = chdr->ch_size; + GET_MEMORY(*buf, *bufsize); + ret = uncompress((unsigned char *)*buf, &destSize, + shdr->sh_offset + ei.image + sizeof(*chdr), + shdr->sh_size - sizeof(*chdr)); + if (ret != Z_OK) + { + Debug (2, "failed to decompress zlib .debug_frame, skipping\n"); + munmap(*buf, *bufsize); + munmap(ei.image, ei.size); + return 1; + } + + Debug (4, "read %zd->%zd bytes of .debug_frame from offset %zd\n", + shdr->sh_size, *bufsize, shdr->sh_offset); + } + else +#endif /* HAVE_ZLIB */ + { + Debug (2, "unknown compression type %d, skipping\n", + chdr->ch_type); + munmap(ei.image, ei.size); + return 1; + } + } + else + { + *bufsize = shdr->sh_size; + GET_MEMORY(*buf, *bufsize); + + memcpy(*buf, shdr->sh_offset + ei.image, *bufsize); + + Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", + *bufsize, shdr->sh_offset); + } + munmap(ei.image, ei.size); + return 0; +} + +/* Locate the binary which originated the contents of address ADDR. Return + the name of the binary in *name (space is allocated by the caller) + Returns 0 if a binary is successfully found, or 1 if an error occurs. */ + +static int +find_binary_for_address (unw_word_t ip, char *name, size_t name_size) +{ +#if defined(__linux) && (!UNW_REMOTE_ONLY) + struct map_iterator mi; + int found = 0; + int pid = getpid (); + unsigned long segbase, mapoff, hi; + + if (maps_init (&mi, pid) != 0) + return 1; + + while (maps_next (&mi, &segbase, &hi, &mapoff)) + if (ip >= segbase && ip < hi) + { + size_t len = strlen (mi.path); + + if (len + 1 <= name_size) + { + memcpy (name, mi.path, len + 1); + found = 1; + } + break; + } + maps_close (&mi); + return !found; +#endif + + return 1; +} + +/* Locate and/or try to load a debug_frame section for address ADDR. Return + pointer to debug frame descriptor, or zero if not found. */ + +static struct unw_debug_frame_list * +locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, + unw_word_t start, unw_word_t end) +{ + struct unw_debug_frame_list *w, *fdesc = 0; + char path[PATH_MAX]; + char *name = path; + int err; + char *buf; + size_t bufsize; + + /* First, see if we loaded this frame already. */ + + for (w = as->debug_frames; w; w = w->next) + { + Debug (4, "checking %p: %lx-%lx\n", w, (long)w->start, (long)w->end); + if (addr >= w->start && addr < w->end) + return w; + } + + /* If the object name we receive is blank, there's still a chance of locating + the file by parsing /proc/self/maps. */ + + if (strcmp (dlname, "") == 0) + { + err = find_binary_for_address (addr, name, sizeof(path)); + if (err) + { + Debug (15, "tried to locate binary for 0x%" PRIx64 ", but no luck\n", + (uint64_t) addr); + return 0; + } + } + else + name = (char*) dlname; + + err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space); + + if (!err) + { + GET_MEMORY(fdesc, sizeof (struct unw_debug_frame_list)); + + fdesc->start = start; + fdesc->end = end; + fdesc->debug_frame = buf; + fdesc->debug_frame_size = bufsize; + fdesc->index = NULL; + fdesc->next = as->debug_frames; + + as->debug_frames = fdesc; + } + + return fdesc; +} + +static size_t +debug_frame_index_make (struct unw_debug_frame_list *fdesc) +{ + unw_accessors_t *a = unw_get_accessors_int (unw_local_addr_space); + char *buf = fdesc->debug_frame; + size_t bufsize = fdesc->debug_frame_size; + unw_word_t addr = (unw_word_t) (uintptr_t) buf; + size_t count = 0; + + while (addr < (unw_word_t) (uintptr_t) (buf + bufsize)) + { + unw_word_t item_start = addr, item_end = 0; + uint32_t u32val = 0; + uint64_t cie_id = 0; + uint64_t id_for_cie; + + dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL); + + if (u32val == 0) + break; + + if (u32val != 0xffffffff) + { + uint32_t cie_id32 = 0; + + item_end = addr + u32val; + dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32, NULL); + cie_id = cie_id32; + id_for_cie = 0xffffffff; + } + else + { + uint64_t u64val = 0; + + /* Extended length. */ + dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL); + item_end = addr + u64val; + + dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL); + id_for_cie = 0xffffffffffffffffull; + } + + /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/ + + if (cie_id == id_for_cie) + { + ; + /*Debug (1, "Found CIE at %.8x.\n", item_start);*/ + } + else + { + unw_word_t fde_addr = item_start; + unw_proc_info_t this_pi; + int err; + + /*Debug (1, "Found FDE at %.8x\n", item_start);*/ + + err = dwarf_extract_proc_info_from_fde (unw_local_addr_space, + a, &fde_addr, + &this_pi, + (uintptr_t) buf, 0, 1, + NULL); + + if (!err) + { + Debug (15, "start_ip = %lx, end_ip = %lx\n", + (long) this_pi.start_ip, (long) this_pi.end_ip); + + if (fdesc->index) + { + struct table_entry *e = &fdesc->index[count]; + + e->fde_offset = item_start - (unw_word_t) (uintptr_t) buf; + e->start_ip_offset = this_pi.start_ip; + } + + count++; + } + /*else + Debug (1, "FDE parse failed\n");*/ + } + + addr = item_end; + } + return count; +} + +static void +debug_frame_index_sort (struct unw_debug_frame_list *fdesc) +{ + size_t i, j, k, n = fdesc->index_size / sizeof (*fdesc->index); + struct table_entry *a = fdesc->index; + struct table_entry t; + + /* Use a simple Shell sort as it relatively fast and + * does not require additional memory. */ + + for (k = n / 2; k > 0; k /= 2) + { + for (i = k; i < n; i++) + { + t = a[i]; + + for (j = i; j >= k; j -= k) + { + if (t.start_ip_offset >= a[j - k].start_ip_offset) + break; + + a[j] = a[j - k]; + } + + a[j] = t; + } + } +} + +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) +{ + unw_dyn_info_t *di = di_debug; + struct unw_debug_frame_list *fdesc; + + Debug (15, "Trying to find .debug_frame for %s\n", obj_name); + + fdesc = locate_debug_info (unw_local_addr_space, ip, obj_name, start, end); + + if (!fdesc) + { + Debug (15, "couldn't load .debug_frame\n"); + return found; + } + + Debug (15, "loaded .debug_frame\n"); + + if (fdesc->debug_frame_size == 0) + { + Debug (15, "zero-length .debug_frame\n"); + return found; + } + + /* Now create a binary-search table, if it does not already exist. */ + + if (!fdesc->index) + { + /* Find all FDE entries in debug_frame, and make into a sorted + index. First determine an index element count. */ + + size_t count = debug_frame_index_make (fdesc); + + if (!count) + { + Debug (15, "no CIE/FDE found in .debug_frame\n"); + return found; + } + + fdesc->index_size = count * sizeof (*fdesc->index); + GET_MEMORY (fdesc->index, fdesc->index_size); + + if (!fdesc->index) + { + Debug (15, "couldn't allocate a frame index table\n"); + fdesc->index_size = 0; + return found; + } + + /* Then fill and sort the index. */ + + debug_frame_index_make (fdesc); + debug_frame_index_sort (fdesc); + + /*for (i = 0; i < count; i++) + { + const struct table_entry *e = &fdesc->index[i]; + + Debug (15, "ip %x, FDE offset %x\n", + e->start_ip_offset, e->fde_offset); + }*/ + } + + di->format = UNW_INFO_FORMAT_TABLE; + di->start_ip = fdesc->start; + di->end_ip = fdesc->end; + di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name; + di->u.ti.table_data = (unw_word_t *) fdesc; + di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t); + di->u.ti.segbase = segbase; + + found = 1; + Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, " + "gp=0x%lx, table_data=0x%lx\n", + (char *) (uintptr_t) di->u.ti.name_ptr, + (long) di->u.ti.segbase, (long) di->u.ti.table_len, + (long) di->gp, (long) di->u.ti.table_data); + + return found; +} + +#endif /* CONFIG_DEBUG_FRAME */ + +#ifndef UNW_REMOTE_ONLY + +static Elf_W (Addr) +dwarf_find_eh_frame_section(struct dl_phdr_info *info) +{ + int rc; + struct elf_image ei; + Elf_W (Addr) eh_frame = 0; + Elf_W (Shdr)* shdr; + const char *file = info->dlpi_name; + char exepath[PATH_MAX]; + + if (strlen(file) == 0) + { + tdep_get_exe_image_path(exepath); + file = exepath; + } + + Debug (1, "looking for .eh_frame section in %s\n", + file); + + rc = elf_map_image (&ei, file); + if (rc != 0) + return 0; + + shdr = elf_w (find_section) (&ei, ".eh_frame"); + if (!shdr) + goto out; + + eh_frame = shdr->sh_addr + info->dlpi_addr; + Debug (4, "found .eh_frame at address %lx\n", + eh_frame); + +out: + munmap (ei.image, ei.size); + + return eh_frame; +} + +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 */ + }; + +/* ptr is a pointer to a dwarf_callback_data structure and, on entry, + member ip contains the instruction-pointer we're looking + for. */ +HIDDEN int +dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) +{ + struct dwarf_callback_data *cb_data = ptr; + unw_dyn_info_t *di = &cb_data->di; + const Elf_W(Phdr) *phdr, *p_eh_hdr, *p_dynamic, *p_text; + unw_word_t addr, eh_frame_start, eh_frame_end, fde_count, ip; + Elf_W(Addr) load_base, max_load_addr = 0; + int ret, need_unwind_info = cb_data->need_unwind_info; + unw_proc_info_t *pi = cb_data->pi; + struct dwarf_eh_frame_hdr *hdr = NULL; + unw_accessors_t *a; + long n; + int found = 0; + struct dwarf_eh_frame_hdr synth_eh_frame_hdr; +#ifdef CONFIG_DEBUG_FRAME + unw_word_t start, end; +#endif /* CONFIG_DEBUG_FRAME*/ + + ip = cb_data->ip; + + /* Make sure struct dl_phdr_info is at least as big as we need. */ + if (size < offsetof (struct dl_phdr_info, dlpi_phnum) + + sizeof (info->dlpi_phnum)) + return -1; + + Debug (15, "checking %s, base=0x%lx)\n", + info->dlpi_name, (long) info->dlpi_addr); + + phdr = info->dlpi_phdr; + load_base = info->dlpi_addr; + p_text = NULL; + p_eh_hdr = NULL; + p_dynamic = NULL; + + /* See if PC falls into one of the loaded segments. Find the + eh-header segment at the same time. */ + for (n = info->dlpi_phnum; --n >= 0; phdr++) + { + if (phdr->p_type == PT_LOAD) + { + Elf_W(Addr) vaddr = phdr->p_vaddr + load_base; + + if (ip >= vaddr && ip < vaddr + phdr->p_memsz) + p_text = phdr; + + if (vaddr + phdr->p_filesz > max_load_addr) + max_load_addr = vaddr + phdr->p_filesz; + } + else if (phdr->p_type == PT_GNU_EH_FRAME) + p_eh_hdr = phdr; +#if defined __sun + else if (phdr->p_type == PT_SUNW_UNWIND) + p_eh_hdr = phdr; +#endif + else if (phdr->p_type == PT_DYNAMIC) + p_dynamic = phdr; + } + + if (!p_text) + return 0; + + if (p_eh_hdr) + { + hdr = (struct dwarf_eh_frame_hdr *) (p_eh_hdr->p_vaddr + load_base); + } + else + { + Elf_W (Addr) eh_frame; + Debug (1, "no .eh_frame_hdr section found\n"); + eh_frame = dwarf_find_eh_frame_section (info); + if (eh_frame) + { + Debug (1, "using synthetic .eh_frame_hdr section for %s\n", + info->dlpi_name); + synth_eh_frame_hdr.version = DW_EH_VERSION; + synth_eh_frame_hdr.eh_frame_ptr_enc = DW_EH_PE_absptr | + ((sizeof(Elf_W (Addr)) == 4) ? DW_EH_PE_udata4 : DW_EH_PE_udata8); + synth_eh_frame_hdr.fde_count_enc = DW_EH_PE_omit; + synth_eh_frame_hdr.table_enc = DW_EH_PE_omit; + synth_eh_frame_hdr.eh_frame = eh_frame; + hdr = &synth_eh_frame_hdr; + } + } + + if (hdr) + { + if (p_dynamic) + { + /* For dynamicly linked executables and shared libraries, + DT_PLTGOT is the value that data-relative addresses are + relative to for that object. We call this the "gp". */ + Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(p_dynamic->p_vaddr + load_base); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + /* Assume that _DYNAMIC is writable and GLIBC has + relocated it (true for x86 at least). */ + di->gp = dyn->d_un.d_ptr; + break; + } + } + else + /* Otherwise this is a static executable with no _DYNAMIC. Assume + that data-relative addresses are relative to 0, i.e., + absolute. */ + di->gp = 0; + pi->gp = di->gp; + + if (hdr->version != DW_EH_VERSION) + { + Debug (1, "table `%s' has unexpected version %d\n", + info->dlpi_name, hdr->version); + return 0; + } + + a = unw_get_accessors_int (unw_local_addr_space); + addr = (unw_word_t) (uintptr_t) (&hdr->eh_frame); + + /* (Optionally) read eh_frame_ptr: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->eh_frame_ptr_enc, pi, + &eh_frame_start, NULL)) < 0) + return ret; + + /* (Optionally) read fde_count: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->fde_count_enc, pi, + &fde_count, NULL)) < 0) + return ret; + + if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) + { + /* If there is no search table or it has an unsupported + encoding, fall back on linear search. */ + if (hdr->table_enc == DW_EH_PE_omit) + { + Debug (4, "table `%s' lacks search table; doing linear search\n", + info->dlpi_name); + } + else + { + Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", + info->dlpi_name, hdr->table_enc); + } + + eh_frame_end = max_load_addr; /* XXX can we do better? */ + + if (hdr->fde_count_enc == DW_EH_PE_omit) + fde_count = ~0UL; + if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) + abort (); + + Debug (1, "eh_frame_start = %lx eh_frame_end = %lx\n", + eh_frame_start, eh_frame_end); + + /* XXX we know how to build a local binary search table for + .debug_frame, so we could do that here too. */ + found = linear_search (unw_local_addr_space, ip, + eh_frame_start, eh_frame_end, fde_count, + pi, need_unwind_info, NULL); + if (found != 1) + found = 0; + else + cb_data->single_fde = 1; + } + else + { + di->format = UNW_INFO_FORMAT_REMOTE_TABLE; + di->start_ip = p_text->p_vaddr + load_base; + di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz; + di->u.rti.name_ptr = (unw_word_t) (uintptr_t) info->dlpi_name; + di->u.rti.table_data = addr; + assert (sizeof (struct table_entry) % sizeof (unw_word_t) == 0); + di->u.rti.table_len = (fde_count * sizeof (struct table_entry) + / sizeof (unw_word_t)); + /* For the binary-search table in the eh_frame_hdr, data-relative + means relative to the start of that section... */ + di->u.rti.segbase = (unw_word_t) (uintptr_t) hdr; + + found = 1; + Debug (15, "found table `%s': segbase=0x%lx, len=%lu, gp=0x%lx, " + "table_data=0x%lx\n", (char *) (uintptr_t) di->u.rti.name_ptr, + (long) di->u.rti.segbase, (long) di->u.rti.table_len, + (long) di->gp, (long) di->u.rti.table_data); + } + } + +#ifdef CONFIG_DEBUG_FRAME + /* Find the start/end of the described region by parsing the phdr_info + structure. */ + start = (unw_word_t) -1; + end = 0; + + for (n = 0; n < info->dlpi_phnum; n++) + { + if (info->dlpi_phdr[n].p_type == PT_LOAD) + { + unw_word_t seg_start = info->dlpi_addr + info->dlpi_phdr[n].p_vaddr; + unw_word_t seg_end = seg_start + info->dlpi_phdr[n].p_memsz; + + if (seg_start < start) + start = seg_start; + + if (seg_end > end) + end = seg_end; + } + } + + found = dwarf_find_debug_frame (found, &cb_data->di_debug, ip, + info->dlpi_addr, info->dlpi_name, start, + end); +#endif /* CONFIG_DEBUG_FRAME */ + + return found; +} + +HIDDEN 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) +{ + struct dwarf_callback_data cb_data; + intrmask_t saved_mask; + int ret; + + Debug (14, "looking for IP=0x%lx\n", (long) ip); + + memset (&cb_data, 0, sizeof (cb_data)); + cb_data.ip = ip; + cb_data.pi = pi; + cb_data.need_unwind_info = need_unwind_info; + cb_data.di.format = -1; + cb_data.di_debug.format = -1; + + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); + ret = dl_iterate_phdr (dwarf_callback, &cb_data); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + + if (ret > 0) + { + if (cb_data.single_fde) + /* already got the result in *pi */ + return 0; + + /* search the table: */ + if (cb_data.di.format != -1) + ret = dwarf_search_unwind_table_int (as, ip, &cb_data.di, + pi, need_unwind_info, arg); + else + ret = -UNW_ENOINFO; + + if (ret == -UNW_ENOINFO && cb_data.di_debug.format != -1) + ret = dwarf_search_unwind_table_int (as, ip, &cb_data.di_debug, pi, + need_unwind_info, arg); + } + else + ret = -UNW_ENOINFO; + + return ret; +} + +static inline const struct table_entry * +lookup (const struct table_entry *table, size_t table_size, int32_t rel_ip) +{ + unsigned long table_len = table_size / sizeof (struct table_entry); + const struct table_entry *e = NULL; + unsigned long lo, hi, mid; + + /* do a binary search for right entry: */ + for (lo = 0, hi = table_len; lo < hi;) + { + mid = (lo + hi) / 2; + e = table + mid; + Debug (15, "e->start_ip_offset = %lx\n", (long) e->start_ip_offset); + if (rel_ip < e->start_ip_offset) + hi = mid; + else + lo = mid + 1; + } + if (hi <= 0) + return NULL; + e = table + hi - 1; + return e; +} + +#endif /* !UNW_REMOTE_ONLY */ + +#ifndef UNW_LOCAL_ONLY + +/* Lookup an unwind-table entry in remote memory. Returns 1 if an + entry is found, 0 if no entry is found, negative if an error + occurred reading remote memory. */ +static int +remote_lookup (unw_addr_space_t as, + unw_word_t table, size_t table_size, int32_t rel_ip, + struct table_entry *e, int32_t *last_ip_offset, void *arg) +{ + unsigned long table_len = table_size / sizeof (struct table_entry); + unw_accessors_t *a = unw_get_accessors_int (as); + unsigned long lo, hi, mid; + unw_word_t e_addr = 0; + int32_t start = 0; + int ret; + + /* do a binary search for right entry: */ + for (lo = 0, hi = table_len; lo < hi;) + { + mid = (lo + hi) / 2; + e_addr = table + mid * sizeof (struct table_entry); + if ((ret = dwarf_reads32 (as, a, &e_addr, &start, arg)) < 0) + return ret; + + if (rel_ip < start) + hi = mid; + else + lo = mid + 1; + } + if (hi <= 0) + return 0; + e_addr = table + (hi - 1) * sizeof (struct table_entry); + if ((ret = dwarf_reads32 (as, a, &e_addr, &e->start_ip_offset, arg)) < 0 + || (ret = dwarf_reads32 (as, a, &e_addr, &e->fde_offset, arg)) < 0 + || (hi < table_len && + (ret = dwarf_reads32 (as, a, &e_addr, last_ip_offset, arg)) < 0)) + return ret; + return 1; +} + +#endif /* !UNW_LOCAL_ONLY */ + +static int is_remote_table(int format) +{ + return (format == UNW_INFO_FORMAT_REMOTE_TABLE || + format == UNW_INFO_FORMAT_IP_OFFSET); +} + +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) +{ + const struct table_entry *e = NULL, *table; + unw_word_t ip_base = 0, segbase = 0, last_ip, fde_addr; + unw_accessors_t *a; +#ifndef UNW_LOCAL_ONLY + struct table_entry ent; +#endif + int ret; + unw_word_t debug_frame_base; + size_t table_len; + +#ifdef UNW_REMOTE_ONLY + assert (is_remote_table(di->format)); +#else + assert (is_remote_table(di->format) + || di->format == UNW_INFO_FORMAT_TABLE); +#endif + assert (ip >= di->start_ip && ip < di->end_ip); + + if (is_remote_table(di->format)) + { + table = (const struct table_entry *) (uintptr_t) di->u.rti.table_data; + table_len = di->u.rti.table_len * sizeof (unw_word_t); + debug_frame_base = 0; + } + else + { + assert(di->format == UNW_INFO_FORMAT_TABLE); +#ifndef UNW_REMOTE_ONLY + struct unw_debug_frame_list *fdesc = (void *) di->u.ti.table_data; + + /* UNW_INFO_FORMAT_TABLE (i.e. .debug_frame) is read from local address + space. Both the index and the unwind tables live in local memory, but + the address space to check for properties like the address size and + endianness is the target one. */ + as = unw_local_addr_space; + table = fdesc->index; + table_len = fdesc->index_size; + debug_frame_base = (uintptr_t) fdesc->debug_frame; +#endif + } + + a = unw_get_accessors_int (as); + + segbase = di->u.rti.segbase; + if (di->format == UNW_INFO_FORMAT_IP_OFFSET) { + ip_base = di->start_ip; + } else { + ip_base = segbase; + } + +#ifndef UNW_REMOTE_ONLY + if (as == unw_local_addr_space) + { + e = lookup (table, table_len, ip - ip_base); + if (e && &e[1] < &table[table_len]) + last_ip = e[1].start_ip_offset + ip_base; + else + last_ip = di->end_ip; + } + else +#endif + { +#ifndef UNW_LOCAL_ONLY + int32_t last_ip_offset = di->end_ip - ip_base; + segbase = di->u.rti.segbase; + if ((ret = remote_lookup (as, (uintptr_t) table, table_len, + ip - ip_base, &ent, &last_ip_offset, arg)) < 0) + return ret; + if (ret) + { + e = &ent; + last_ip = last_ip_offset + ip_base; + } + else + e = NULL; /* no info found */ +#endif + } + if (!e) + { + Debug (1, "IP %lx inside range %lx-%lx, but no explicit unwind info found\n", + (long) ip, (long) di->start_ip, (long) di->end_ip); + /* IP is inside this table's range, but there is no explicit + unwind info. */ + return -UNW_ENOINFO; + } + Debug (15, "ip=0x%lx, start_ip=0x%lx\n", + (long) ip, (long) (e->start_ip_offset)); + if (debug_frame_base) + fde_addr = e->fde_offset + debug_frame_base; + else + fde_addr = e->fde_offset + segbase; + Debug (1, "e->fde_offset = %lx, segbase = %lx, debug_frame_base = %lx, " + "fde_addr = %lx\n", (long) e->fde_offset, (long) segbase, + (long) debug_frame_base, (long) fde_addr); + if ((ret = dwarf_extract_proc_info_from_fde (as, a, &fde_addr, pi, + debug_frame_base ? + debug_frame_base : segbase, + need_unwind_info, + debug_frame_base != 0, arg)) < 0) + return ret; + + /* .debug_frame uses an absolute encoding that does not know about any + shared library relocation. */ + if (di->format == UNW_INFO_FORMAT_TABLE) + { + pi->start_ip += segbase; + pi->end_ip += segbase; + pi->flags = UNW_PI_FLAG_DEBUG_FRAME; + } + +#if defined(NEED_LAST_IP) + pi->last_ip = last_ip; +#else + (void)last_ip; +#endif + if (ip < pi->start_ip || ip >= pi->end_ip) + return -UNW_ENOINFO; + + return 0; +} + +HIDDEN void +dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + return; /* always a nop */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c new file mode 100644 index 00000000000000..f5f7ad06c3b671 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c @@ -0,0 +1,233 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include + +#include + +#include "libunwind_i.h" +#include "dwarf-eh.h" +#include "dwarf_i.h" + +#define to_unw_word(p) ((unw_word_t) (uintptr_t) (p)) + +int +dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip) +{ + Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL; + unw_word_t addr, eh_frame_start, fde_count, load_base; + unw_word_t max_load_addr = 0; + unw_word_t start_ip = to_unw_word (-1); + unw_word_t end_ip = 0; + struct dwarf_eh_frame_hdr *hdr; + unw_proc_info_t pi; + unw_accessors_t *a; + Elf_W(Ehdr) *ehdr; +#if UNW_TARGET_ARM + const Elf_W(Phdr) *parm_exidx = NULL; +#endif + int i, ret, found = 0; + + /* XXX: Much of this code is Linux/LSB-specific. */ + + if (!elf_w(valid_object) (&edi->ei)) + return -UNW_ENOINFO; + + ehdr = edi->ei.image; + phdr = (Elf_W(Phdr) *) ((char *) edi->ei.image + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i) + { + switch (phdr[i].p_type) + { + case PT_LOAD: + if (phdr[i].p_vaddr < start_ip) + start_ip = phdr[i].p_vaddr; + + if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip) + end_ip = phdr[i].p_vaddr + phdr[i].p_memsz; + + if (phdr[i].p_offset == mapoff) + ptxt = phdr + i; + if ((uintptr_t) edi->ei.image + phdr->p_filesz > max_load_addr) + max_load_addr = (uintptr_t) edi->ei.image + phdr->p_filesz; + break; + + case PT_GNU_EH_FRAME: +#if defined __sun + case PT_SUNW_UNWIND: +#endif + peh_hdr = phdr + i; + break; + + case PT_DYNAMIC: + pdyn = phdr + i; + break; + +#if UNW_TARGET_ARM + case PT_ARM_EXIDX: + parm_exidx = phdr + i; + break; +#endif + + default: + break; + } + } + + if (!ptxt) + return 0; + + load_base = segbase - ptxt->p_vaddr; + start_ip += load_base; + end_ip += load_base; + + if (peh_hdr) + { + if (pdyn) + { + /* For dynamicly linked executables and shared libraries, + DT_PLTGOT is the value that data-relative addresses are + relative to for that object. We call this the "gp". */ + Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset + + (char *) edi->ei.image); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + /* Assume that _DYNAMIC is writable and GLIBC has + relocated it (true for x86 at least). */ + edi->di_cache.gp = dyn->d_un.d_ptr; + break; + } + } + else + /* Otherwise this is a static executable with no _DYNAMIC. Assume + that data-relative addresses are relative to 0, i.e., + absolute. */ + edi->di_cache.gp = 0; + + hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset + + (char *) edi->ei.image); + if (hdr->version != DW_EH_VERSION) + { + Debug (1, "table `%s' has unexpected version %d\n", + path, hdr->version); + return -UNW_ENOINFO; + } + + a = unw_get_accessors_int (unw_local_addr_space); + addr = to_unw_word (&hdr->eh_frame); + + /* Fill in a dummy proc_info structure. We just need to fill in + enough to ensure that dwarf_read_encoded_pointer() can do it's + job. Since we don't have a procedure-context at this point, all + we have to do is fill in the global-pointer. */ + memset (&pi, 0, sizeof (pi)); + pi.gp = edi->di_cache.gp; + + /* (Optionally) read eh_frame_ptr: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->eh_frame_ptr_enc, &pi, + &eh_frame_start, NULL)) < 0) + return -UNW_ENOINFO; + + /* (Optionally) read fde_count: */ + if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + &addr, hdr->fde_count_enc, &pi, + &fde_count, NULL)) < 0) + return -UNW_ENOINFO; + + if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) + { + #if 1 + abort (); + #else + unw_word_t eh_frame_end; + + /* If there is no search table or it has an unsupported + encoding, fall back on linear search. */ + if (hdr->table_enc == DW_EH_PE_omit) + Debug (4, "EH lacks search table; doing linear search\n"); + else + Debug (4, "EH table has encoding 0x%x; doing linear search\n", + hdr->table_enc); + + eh_frame_end = max_load_addr; /* XXX can we do better? */ + + if (hdr->fde_count_enc == DW_EH_PE_omit) + fde_count = ~0UL; + if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) + abort (); + + return linear_search (unw_local_addr_space, ip, + eh_frame_start, eh_frame_end, fde_count, + pi, need_unwind_info, NULL); + #endif + } + + edi->di_cache.start_ip = start_ip; + edi->di_cache.end_ip = end_ip; + edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE; + edi->di_cache.u.rti.name_ptr = 0; + /* two 32-bit values (ip_offset/fde_offset) per table-entry: */ + edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); + edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr) + + (addr - to_unw_word (edi->ei.image) + - peh_hdr->p_offset)); + + /* For the binary-search table in the eh_frame_hdr, data-relative + means relative to the start of that section... */ + edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr) + + (to_unw_word (hdr) - + to_unw_word (edi->ei.image) + - peh_hdr->p_offset)); + found = 1; + } + +#if UNW_TARGET_ARM + if (parm_exidx) + { + edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX; + edi->di_arm.start_ip = start_ip; + edi->di_arm.end_ip = end_ip; + edi->di_arm.u.rti.name_ptr = to_unw_word (path); + edi->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr; + edi->di_arm.u.rti.table_len = parm_exidx->p_memsz; + found = 1; + } +#endif + +#ifdef CONFIG_DEBUG_FRAME + /* Try .debug_frame. */ + found = dwarf_find_debug_frame (found, &edi->di_debug, ip, load_base, path, + start_ip, end_ip); +#endif + + return found; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c new file mode 100644 index 00000000000000..28fd73c6b0f7f7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c @@ -0,0 +1,1081 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "dwarf_i.h" +#include "libunwind_i.h" +#include +#include + +#define alloc_reg_state() (mempool_alloc (&dwarf_reg_state_pool)) +#define free_reg_state(rs) (mempool_free (&dwarf_reg_state_pool, rs)) + +#define DWARF_UNW_CACHE_SIZE(log_size) (1 << log_size) +#define DWARF_UNW_HASH_SIZE(log_size) (1 << (log_size + 1)) + +static inline int +read_regnum (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_word_t *valp, void *arg) +{ + int ret; + + if ((ret = dwarf_read_uleb128 (as, a, addr, valp, arg)) < 0) + return ret; + + if (*valp >= DWARF_NUM_PRESERVED_REGS) + { + Debug (1, "Invalid register number %u\n", (unsigned int) *valp); + return -UNW_EBADREG; + } + return 0; +} + +static inline void +set_reg (dwarf_state_record_t *sr, unw_word_t regnum, dwarf_where_t where, + unw_word_t val) +{ + sr->rs_current.reg.where[regnum] = where; + sr->rs_current.reg.val[regnum] = val; +} + +static inline int +push_rstate_stack(dwarf_stackable_reg_state_t **rs_stack) +{ + dwarf_stackable_reg_state_t *old_rs = *rs_stack; + if (NULL == (*rs_stack = alloc_reg_state ())) + { + *rs_stack = old_rs; + return -1; + } + (*rs_stack)->next = old_rs; + return 0; +} + +static inline void +pop_rstate_stack(dwarf_stackable_reg_state_t **rs_stack) +{ + dwarf_stackable_reg_state_t *old_rs = *rs_stack; + *rs_stack = old_rs->next; + free_reg_state (old_rs); +} + +static inline void +empty_rstate_stack(dwarf_stackable_reg_state_t **rs_stack) +{ + while (*rs_stack) + pop_rstate_stack(rs_stack); +} + +/* Run a CFI program to update the register state. */ +static int +run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr, + unw_word_t *ip, unw_word_t end_ip, + unw_word_t *addr, unw_word_t end_addr, + dwarf_stackable_reg_state_t **rs_stack, + struct dwarf_cie_info *dci) +{ + unw_addr_space_t as; + void *arg; + + if (c->pi.flags & UNW_PI_FLAG_DEBUG_FRAME) + { + /* .debug_frame CFI is stored in local address space. */ + as = unw_local_addr_space; + arg = NULL; + } + else + { + as = c->as; + arg = c->as_arg; + } + unw_accessors_t *a = unw_get_accessors_int (as); + int ret = 0; + + while (*ip <= end_ip && *addr < end_addr && ret >= 0) + { + unw_word_t operand = 0, regnum, val, len; + uint8_t u8, op; + uint16_t u16; + uint32_t u32; + + if ((ret = dwarf_readu8 (as, a, addr, &op, arg)) < 0) + break; + + if (op & DWARF_CFA_OPCODE_MASK) + { + operand = op & DWARF_CFA_OPERAND_MASK; + op &= ~DWARF_CFA_OPERAND_MASK; + } + switch ((dwarf_cfa_t) op) + { + case DW_CFA_advance_loc: + *ip += operand * dci->code_align; + Debug (15, "CFA_advance_loc to 0x%lx\n", (long) *ip); + break; + + case DW_CFA_advance_loc1: + if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0) + break; + *ip += u8 * dci->code_align; + Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) *ip); + break; + + case DW_CFA_advance_loc2: + if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0) + break; + *ip += u16 * dci->code_align; + Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) *ip); + break; + + case DW_CFA_advance_loc4: + if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0) + break; + *ip += u32 * dci->code_align; + Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) *ip); + break; + + case DW_CFA_MIPS_advance_loc8: +#ifdef UNW_TARGET_MIPS + { + uint64_t u64 = 0; + + if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0) + break; + *ip += u64 * dci->code_align; + Debug (15, "CFA_MIPS_advance_loc8\n"); + break; + } +#else + Debug (1, "DW_CFA_MIPS_advance_loc8 on non-MIPS target\n"); + ret = -UNW_EINVAL; + break; +#endif + + case DW_CFA_offset: + regnum = operand; + if (regnum >= DWARF_NUM_PRESERVED_REGS) + { + Debug (1, "Invalid register number %u in DW_cfa_OFFSET\n", + (unsigned int) regnum); + ret = -UNW_EBADREG; + break; + } + if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) + break; + set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); + Debug (15, "CFA_offset r%lu at cfa+0x%lx\n", + (long) regnum, (long) (val * dci->data_align)); + break; + + case DW_CFA_offset_extended: + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) + break; + set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); + Debug (15, "CFA_offset_extended r%lu at cf+0x%lx\n", + (long) regnum, (long) (val * dci->data_align)); + break; + + case DW_CFA_offset_extended_sf: + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)) + break; + set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); + Debug (15, "CFA_offset_extended_sf r%lu at cf+0x%lx\n", + (long) regnum, (long) (val * dci->data_align)); + break; + + case DW_CFA_restore: + regnum = operand; + if (regnum >= DWARF_NUM_PRESERVED_REGS) + { + Debug (1, "Invalid register number %u in DW_CFA_restore\n", + (unsigned int) regnum); + ret = -UNW_EINVAL; + break; + } + sr->rs_current.reg.where[regnum] = sr->rs_initial.reg.where[regnum]; + sr->rs_current.reg.val[regnum] = sr->rs_initial.reg.val[regnum]; + Debug (15, "CFA_restore r%lu\n", (long) regnum); + break; + + case DW_CFA_restore_extended: + if ((ret = dwarf_read_uleb128 (as, a, addr, ®num, arg)) < 0) + break; + if (regnum >= DWARF_NUM_PRESERVED_REGS) + { + Debug (1, "Invalid register number %u in " + "DW_CFA_restore_extended\n", (unsigned int) regnum); + ret = -UNW_EINVAL; + break; + } + sr->rs_current.reg.where[regnum] = sr->rs_initial.reg.where[regnum]; + sr->rs_current.reg.val[regnum] = sr->rs_initial.reg.val[regnum]; + Debug (15, "CFA_restore_extended r%lu\n", (long) regnum); + break; + + case DW_CFA_nop: + break; + + case DW_CFA_set_loc: + if ((ret = dwarf_read_encoded_pointer (as, a, addr, dci->fde_encoding, + &c->pi, ip, + arg)) < 0) + break; + Debug (15, "CFA_set_loc to 0x%lx\n", (long) *ip); + break; + + case DW_CFA_undefined: + if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + break; + set_reg (sr, regnum, DWARF_WHERE_UNDEF, 0); + Debug (15, "CFA_undefined r%lu\n", (long) regnum); + break; + + case DW_CFA_same_value: + if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + break; + set_reg (sr, regnum, DWARF_WHERE_SAME, 0); + Debug (15, "CFA_same_value r%lu\n", (long) regnum); + break; + + case DW_CFA_register: + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) + break; + set_reg (sr, regnum, DWARF_WHERE_REG, val); + Debug (15, "CFA_register r%lu to r%lu\n", (long) regnum, (long) val); + break; + + case DW_CFA_remember_state: + if (push_rstate_stack(rs_stack) < 0) + { + Debug (1, "Out of memory in DW_CFA_remember_state\n"); + ret = -UNW_ENOMEM; + break; + } + (*rs_stack)->state = sr->rs_current; + Debug (15, "CFA_remember_state\n"); + break; + + case DW_CFA_restore_state: + if (!*rs_stack) + { + Debug (1, "register-state stack underflow\n"); + ret = -UNW_EINVAL; + break; + } + sr->rs_current = (*rs_stack)->state; + pop_rstate_stack(rs_stack); + Debug (15, "CFA_restore_state\n"); + break; + + case DW_CFA_def_cfa: + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) + break; + set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); + set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */ + Debug (15, "CFA_def_cfa r%lu+0x%lx\n", (long) regnum, (long) val); + break; + + case DW_CFA_def_cfa_sf: + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)) + break; + set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); + set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, + val * dci->data_align); /* factored! */ + Debug (15, "CFA_def_cfa_sf r%lu+0x%lx\n", + (long) regnum, (long) (val * dci->data_align)); + break; + + case DW_CFA_def_cfa_register: + if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + break; + set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); + Debug (15, "CFA_def_cfa_register r%lu\n", (long) regnum); + break; + + case DW_CFA_def_cfa_offset: + if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) + break; + set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */ + Debug (15, "CFA_def_cfa_offset 0x%lx\n", (long) val); + break; + + case DW_CFA_def_cfa_offset_sf: + if ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0) + break; + set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, + val * dci->data_align); /* factored! */ + Debug (15, "CFA_def_cfa_offset_sf 0x%lx\n", + (long) (val * dci->data_align)); + break; + + case DW_CFA_def_cfa_expression: + /* Save the address of the DW_FORM_block for later evaluation. */ + set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_EXPR, *addr); + + if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) + break; + + Debug (15, "CFA_def_cfa_expr @ 0x%lx [%lu bytes]\n", + (long) *addr, (long) len); + *addr += len; + break; + + case DW_CFA_expression: + if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + break; + + /* Save the address of the DW_FORM_block for later evaluation. */ + set_reg (sr, regnum, DWARF_WHERE_EXPR, *addr); + + if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) + break; + + Debug (15, "CFA_expression r%lu @ 0x%lx [%lu bytes]\n", + (long) regnum, (long) addr, (long) len); + *addr += len; + break; + + case DW_CFA_val_expression: + if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + break; + + /* Save the address of the DW_FORM_block for later evaluation. */ + set_reg (sr, regnum, DWARF_WHERE_VAL_EXPR, *addr); + + if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) + break; + + Debug (15, "CFA_val_expression r%lu @ 0x%lx [%lu bytes]\n", + (long) regnum, (long) addr, (long) len); + *addr += len; + break; + + case DW_CFA_GNU_args_size: + if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) + break; + sr->args_size = val; + Debug (15, "CFA_GNU_args_size %lu\n", (long) val); + break; + + case DW_CFA_GNU_negative_offset_extended: + /* A comment in GCC says that this is obsoleted by + DW_CFA_offset_extended_sf, but that it's used by older + PowerPC code. */ + if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) + || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) + break; + set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dci->data_align)); + Debug (15, "CFA_GNU_negative_offset_extended cfa+0x%lx\n", + (long) -(val * dci->data_align)); + break; + + case DW_CFA_GNU_window_save: +#ifdef UNW_TARGET_SPARC + /* This is a special CFA to handle all 16 windowed registers + on SPARC. */ + for (regnum = 16; regnum < 32; ++regnum) + set_reg (sr, regnum, DWARF_WHERE_CFAREL, + (regnum - 16) * sizeof (unw_word_t)); + Debug (15, "CFA_GNU_window_save\n"); + break; +#else + /* FALL THROUGH */ +#endif + case DW_CFA_lo_user: + case DW_CFA_hi_user: + Debug (1, "Unexpected CFA opcode 0x%x\n", op); + ret = -UNW_EINVAL; + break; + } + } + + if (ret > 0) + ret = 0; + return ret; +} + +static int +fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip) +{ + int ret, dynamic = 1; + + /* The 'ip' can point either to the previous or next instruction + depending on what type of frame we have: normal call or a place + to resume execution (e.g. after signal frame). + + For a normal call frame we need to back up so we point within the + call itself; this is important because a) the call might be the + very last instruction of the function and the edge of the FDE, + and b) so that run_cfi_program() runs locations up to the call + but not more. + + For signal frame, we need to do the exact opposite and look + up using the current 'ip' value. That is where execution will + continue, and it's important we get this right, as 'ip' could be + right at the function entry and hence FDE edge, or at instruction + that manipulates CFA (push/pop). */ + + if (c->use_prev_instr) + { +#if defined(__arm__) + /* On arm, the least bit denotes thumb/arm mode, clear it. */ + ip &= ~(unw_word_t)0x1; +#endif + --ip; + } + + memset (&c->pi, 0, sizeof (c->pi)); + + /* check dynamic info first --- it overrides everything else */ + ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, 1, + c->as_arg); + if (ret == -UNW_ENOINFO) + { + dynamic = 0; + if ((ret = tdep_find_proc_info (c, ip, 1)) < 0) + return ret; + } + + if (c->pi.format != UNW_INFO_FORMAT_DYNAMIC + && c->pi.format != UNW_INFO_FORMAT_TABLE + && c->pi.format != UNW_INFO_FORMAT_REMOTE_TABLE) + return -UNW_ENOINFO; + + c->pi_valid = 1; + c->pi_is_dynamic = dynamic; + + /* Let system/machine-dependent code determine frame-specific attributes. */ + if (ret >= 0) + tdep_fetch_frame (c, ip, 1); + + return ret; +} + +static int +parse_dynamic (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr) +{ + Debug (1, "Not yet implemented\n"); + return -UNW_ENOINFO; +} + +static inline void +put_unwind_info (struct dwarf_cursor *c, unw_proc_info_t *pi) +{ + if (c->pi_is_dynamic) + unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg); + else if (pi->unwind_info && pi->format == UNW_INFO_FORMAT_TABLE) + { + mempool_free (&dwarf_cie_info_pool, pi->unwind_info); + pi->unwind_info = NULL; + } + c->pi_valid = 0; +} + +static inline int +setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr) +{ + int i, ret; + + assert (c->pi_valid); + + memset (sr, 0, sizeof (*sr)); + for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i) + set_reg (sr, i, DWARF_WHERE_SAME, 0); + + struct dwarf_cie_info *dci = c->pi.unwind_info; + sr->rs_current.ret_addr_column = dci->ret_addr_column; + unw_word_t addr = dci->cie_instr_start; + unw_word_t curr_ip = 0; + dwarf_stackable_reg_state_t *rs_stack = NULL; + ret = run_cfi_program (c, sr, &curr_ip, ~(unw_word_t) 0, &addr, + dci->cie_instr_end, + &rs_stack, dci); + empty_rstate_stack(&rs_stack); + if (ret < 0) + return ret; + + memcpy (&sr->rs_initial, &sr->rs_current, sizeof (sr->rs_initial)); + return 0; +} + +static inline int +parse_fde (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr) +{ + int ret; + struct dwarf_cie_info *dci = c->pi.unwind_info; + unw_word_t addr = dci->fde_instr_start; + unw_word_t curr_ip = c->pi.start_ip; + dwarf_stackable_reg_state_t *rs_stack = NULL; + /* Process up to current `ip` for signal frame and `ip - 1` for normal call frame + See `c->use_prev_instr` use in `fetch_proc_info` for details. */ + ret = run_cfi_program (c, sr, &curr_ip, ip - c->use_prev_instr, &addr, dci->fde_instr_end, + &rs_stack, dci); + empty_rstate_stack(&rs_stack); + if (ret < 0) + return ret; + + return 0; +} + +HIDDEN int +dwarf_flush_rs_cache (struct dwarf_rs_cache *cache) +{ + int i; + + if (cache->log_size == DWARF_DEFAULT_LOG_UNW_CACHE_SIZE + || !cache->hash) { + cache->hash = cache->default_hash; + cache->buckets = cache->default_buckets; + cache->links = cache->default_links; + cache->log_size = DWARF_DEFAULT_LOG_UNW_CACHE_SIZE; + } else { + if (cache->hash && cache->hash != cache->default_hash) + munmap(cache->hash, DWARF_UNW_HASH_SIZE(cache->prev_log_size) + * sizeof (cache->hash[0])); + if (cache->buckets && cache->buckets != cache->default_buckets) + munmap(cache->buckets, DWARF_UNW_CACHE_SIZE(cache->prev_log_size) + * sizeof (cache->buckets[0])); + if (cache->links && cache->links != cache->default_links) + munmap(cache->links, DWARF_UNW_CACHE_SIZE(cache->prev_log_size) + * sizeof (cache->links[0])); + GET_MEMORY(cache->hash, DWARF_UNW_HASH_SIZE(cache->log_size) + * sizeof (cache->hash[0])); + GET_MEMORY(cache->buckets, DWARF_UNW_CACHE_SIZE(cache->log_size) + * sizeof (cache->buckets[0])); + GET_MEMORY(cache->links, DWARF_UNW_CACHE_SIZE(cache->log_size) + * sizeof (cache->links[0])); + if (!cache->hash || !cache->buckets || !cache->links) + { + Debug (1, "Unable to allocate cache memory"); + return -UNW_ENOMEM; + } + cache->prev_log_size = cache->log_size; + } + + cache->rr_head = 0; + + for (i = 0; i < DWARF_UNW_CACHE_SIZE(cache->log_size); ++i) + { + cache->links[i].coll_chain = -1; + cache->links[i].ip = 0; + cache->links[i].valid = 0; + } + for (i = 0; i< DWARF_UNW_HASH_SIZE(cache->log_size); ++i) + cache->hash[i] = -1; + + return 0; +} + +static inline struct dwarf_rs_cache * +get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp) +{ + struct dwarf_rs_cache *cache = &as->global_cache; + unw_caching_policy_t caching = as->caching_policy; + + if (caching == UNW_CACHE_NONE) + return NULL; + +#if defined(HAVE___THREAD) && HAVE___THREAD + if (likely (caching == UNW_CACHE_PER_THREAD)) + { + static __thread struct dwarf_rs_cache tls_cache __attribute__((tls_model("initial-exec"))); + Debug (16, "using TLS cache\n"); + cache = &tls_cache; + } + else +#else + if (likely (caching == UNW_CACHE_GLOBAL)) +#endif + { + Debug (16, "acquiring lock\n"); + lock_acquire (&cache->lock, *saved_maskp); + } + + if ((atomic_read (&as->cache_generation) != atomic_read (&cache->generation)) + || !cache->hash) + { + /* cache_size is only set in the global_cache, copy it over before flushing */ + cache->log_size = as->global_cache.log_size; + if (dwarf_flush_rs_cache (cache) < 0) + return NULL; + cache->generation = as->cache_generation; + } + + return cache; +} + +static inline void +put_rs_cache (unw_addr_space_t as, struct dwarf_rs_cache *cache, + intrmask_t *saved_maskp) +{ + assert (as->caching_policy != UNW_CACHE_NONE); + + Debug (16, "unmasking signals/interrupts and releasing lock\n"); + if (likely (as->caching_policy == UNW_CACHE_GLOBAL)) + lock_release (&cache->lock, *saved_maskp); +} + +static inline unw_hash_index_t CONST_ATTR +hash (unw_word_t ip, unsigned short log_size) +{ + /* based on (sqrt(5)/2-1)*2^64 */ +# define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL) + + return ip * magic >> ((sizeof(unw_word_t) * 8) - (log_size + 1)); +} + +static inline long +cache_match (struct dwarf_rs_cache *cache, unsigned short index, unw_word_t ip) +{ + return (cache->links[index].valid && (ip == cache->links[index].ip)); +} + +static dwarf_reg_state_t * +rs_lookup (struct dwarf_rs_cache *cache, struct dwarf_cursor *c) +{ + unsigned short index; + unw_word_t ip = c->ip; + + if (c->hint > 0) + { + index = c->hint - 1; + if (cache_match (cache, index, ip)) + return &cache->buckets[index]; + } + + for (index = cache->hash[hash (ip, cache->log_size)]; + index < DWARF_UNW_CACHE_SIZE(cache->log_size); + index = cache->links[index].coll_chain) + { + if (cache_match (cache, index, ip)) + return &cache->buckets[index]; + } + return NULL; +} + +static inline dwarf_reg_state_t * +rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c) +{ + unw_hash_index_t index; + unsigned short head; + + head = cache->rr_head; + cache->rr_head = (head + 1) & (DWARF_UNW_CACHE_SIZE(cache->log_size) - 1); + + /* remove the old rs from the hash table (if it's there): */ + if (cache->links[head].ip) + { + unsigned short *pindex; + for (pindex = &cache->hash[hash (cache->links[head].ip, cache->log_size)]; + *pindex < DWARF_UNW_CACHE_SIZE(cache->log_size); + pindex = &cache->links[*pindex].coll_chain) + { + if (*pindex == head) + { + *pindex = cache->links[*pindex].coll_chain; + break; + } + } + } + + /* enter new rs in the hash table */ + index = hash (c->ip, cache->log_size); + cache->links[head].coll_chain = cache->hash[index]; + cache->hash[index] = head; + + cache->links[head].ip = c->ip; + cache->links[head].valid = 1; + cache->links[head].signal_frame = tdep_cache_frame(c); + return cache->buckets + head; +} + +static int +create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr, + unw_word_t ip) +{ + int ret; + switch (c->pi.format) + { + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: + if ((ret = setup_fde(c, sr)) < 0) + return ret; + ret = parse_fde (c, ip, sr); + break; + + case UNW_INFO_FORMAT_DYNAMIC: + ret = parse_dynamic (c, ip, sr); + break; + + default: + Debug (1, "Unexpected unwind-info format %d\n", c->pi.format); + ret = -UNW_EINVAL; + } + return ret; +} + +static inline int +eval_location_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_addr_space_t as, + unw_accessors_t *a, unw_word_t addr, + dwarf_loc_t *locp, void *arg) +{ + int ret, is_register; + unw_word_t len, val; + + /* read the length of the expression: */ + if ((ret = dwarf_read_uleb128 (as, a, &addr, &len, arg)) < 0) + return ret; + + /* evaluate the expression: */ + if ((ret = dwarf_eval_expr (c, stack_val, &addr, len, &val, &is_register)) < 0) + return ret; + + if (is_register) + *locp = DWARF_REG_LOC (c, dwarf_to_unw_regnum (val)); + else + *locp = DWARF_MEM_LOC (c, val); + + return 0; +} + +static int +apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) +{ + unw_word_t regnum, addr, cfa, ip; + unw_word_t prev_ip, prev_cfa; + unw_addr_space_t as; + dwarf_loc_t cfa_loc; + unw_accessors_t *a; + int i, ret; + void *arg; + + prev_ip = c->ip; + prev_cfa = c->cfa; + + as = c->as; + arg = c->as_arg; + a = unw_get_accessors_int (as); + + /* Evaluate the CFA first, because it may be referred to by other + expressions. */ + + if (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG) + { + /* CFA is equal to [reg] + offset: */ + + /* As a special-case, if the stack-pointer is the CFA and the + stack-pointer wasn't saved, popping the CFA implicitly pops + the stack-pointer as well. */ + if ((rs->reg.val[DWARF_CFA_REG_COLUMN] == UNW_TDEP_SP) + && (UNW_TDEP_SP < ARRAY_SIZE(rs->reg.val)) + && (rs->reg.where[UNW_TDEP_SP] == DWARF_WHERE_SAME)) + cfa = c->cfa; + else + { + regnum = dwarf_to_unw_regnum (rs->reg.val[DWARF_CFA_REG_COLUMN]); + if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0) + return ret; + } + cfa += rs->reg.val[DWARF_CFA_OFF_COLUMN]; + } + else + { + /* CFA is equal to EXPR: */ + + assert (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR); + + addr = rs->reg.val[DWARF_CFA_REG_COLUMN]; + /* The dwarf standard doesn't specify an initial value to be pushed on */ + /* the stack before DW_CFA_def_cfa_expression evaluation. We push on a */ + /* dummy value (0) to keep the eval_location_expr function consistent. */ + if ((ret = eval_location_expr (c, 0, as, a, addr, &cfa_loc, arg)) < 0) + return ret; + /* the returned location better be a memory location... */ + if (DWARF_IS_REG_LOC (cfa_loc)) + return -UNW_EBADFRAME; + cfa = DWARF_GET_LOC (cfa_loc); + } + + dwarf_loc_t new_loc[DWARF_NUM_PRESERVED_REGS]; + memcpy(new_loc, c->loc, sizeof(new_loc)); + + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + { + switch ((dwarf_where_t) rs->reg.where[i]) + { + case DWARF_WHERE_UNDEF: + new_loc[i] = DWARF_NULL_LOC; + break; + + case DWARF_WHERE_SAME: + break; + + case DWARF_WHERE_CFAREL: + new_loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg.val[i]); + break; + + case DWARF_WHERE_REG: +#ifdef __s390x__ + /* GPRs can be saved in FPRs on s390x */ + if (unw_is_fpreg (dwarf_to_unw_regnum (rs->reg.val[i]))) + { + new_loc[i] = DWARF_FPREG_LOC (c, dwarf_to_unw_regnum (rs->reg.val[i])); + break; + } +#endif + new_loc[i] = new_loc[rs->reg.val[i]]; + break; + + case DWARF_WHERE_EXPR: + addr = rs->reg.val[i]; + /* The dwarf standard requires the current CFA to be pushed on the */ + /* stack before DW_CFA_expression evaluation. */ + if ((ret = eval_location_expr (c, cfa, as, a, addr, new_loc + i, arg)) < 0) + return ret; + break; + + case DWARF_WHERE_VAL_EXPR: + addr = rs->reg.val[i]; + /* The dwarf standard requires the current CFA to be pushed on the */ + /* stack before DW_CFA_val_expression evaluation. */ + if ((ret = eval_location_expr (c, cfa, as, a, addr, new_loc + i, arg)) < 0) + return ret; + new_loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (new_loc[i])); + break; + } + } + + memcpy(c->loc, new_loc, sizeof(new_loc)); + + c->cfa = cfa; + /* DWARF spec says undefined return address location means end of stack. */ + if (DWARF_IS_NULL_LOC (c->loc[rs->ret_addr_column])) + { + c->ip = 0; + ret = 0; + } + else + { + ret = dwarf_get (c, c->loc[rs->ret_addr_column], &ip); + if (ret < 0) + return ret; + c->ip = ip; + ret = 1; + } + + /* XXX: check for ip to be code_aligned */ + if (c->ip == prev_ip && c->cfa == prev_cfa) + { + Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n", + __FUNCTION__, (long) c->ip); + return -UNW_EBADFRAME; + } + + if (c->stash_frames) + tdep_stash_frame (c, rs); + + return ret; +} + +/* Find the saved locations. */ +static int +find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr) +{ + dwarf_reg_state_t *rs; + struct dwarf_rs_cache *cache; + int ret = 0; + intrmask_t saved_mask; + + if ((cache = get_rs_cache(c->as, &saved_mask)) && + (rs = rs_lookup(cache, c))) + { + /* update hint; no locking needed: single-word writes are atomic */ + unsigned short index = rs - cache->buckets; + c->use_prev_instr = ! cache->links[index].signal_frame; + memcpy (&sr->rs_current, rs, sizeof (*rs)); + } + else + { + ret = fetch_proc_info (c, c->ip); + int next_use_prev_instr = c->use_prev_instr; + if (ret >= 0) + { + /* Update use_prev_instr for the next frame. */ + assert(c->pi.unwind_info); + struct dwarf_cie_info *dci = c->pi.unwind_info; + next_use_prev_instr = ! dci->signal_frame; + ret = create_state_record_for (c, sr, c->ip); + } + put_unwind_info (c, &c->pi); + c->use_prev_instr = next_use_prev_instr; + + if (cache && ret >= 0) + { + rs = rs_new (cache, c); + cache->links[rs - cache->buckets].hint = 0; + memcpy(rs, &sr->rs_current, sizeof(*rs)); + } + } + + unsigned short index = -1; + if (cache) + { + if (rs) + { + index = rs - cache->buckets; + c->hint = cache->links[index].hint; + cache->links[c->prev_rs].hint = index + 1; + c->prev_rs = index; + } + put_rs_cache (c->as, cache, &saved_mask); + } + if (ret < 0) + return ret; + if (cache) + tdep_reuse_frame (c, cache->links[index].signal_frame); + return 0; +} + +/* The function finds the saved locations and applies the register + state as well. */ +HIDDEN int +dwarf_step (struct dwarf_cursor *c) +{ + int ret; + dwarf_state_record_t sr; + if ((ret = find_reg_state (c, &sr)) < 0) + return ret; + return apply_reg_state (c, &sr.rs_current); +} + +HIDDEN int +dwarf_make_proc_info (struct dwarf_cursor *c) +{ +#if 0 + if (c->as->caching_policy == UNW_CACHE_NONE + || get_cached_proc_info (c) < 0) +#endif + /* Need to check if current frame contains + args_size, and set cursor appropriately. Only + needed for unw_resume */ + dwarf_state_record_t sr; + int ret; + + /* Lookup it up the slow way... */ + ret = fetch_proc_info (c, c->ip); + if (ret >= 0) + ret = create_state_record_for (c, &sr, c->ip); + put_unwind_info (c, &c->pi); + if (ret < 0) + return ret; + c->args_size = sr.args_size; + + return 0; +} + +static int +dwarf_reg_states_dynamic_iterate(struct dwarf_cursor *c, + unw_reg_states_callback cb, + void *token) +{ + Debug (1, "Not yet implemented\n"); + return -UNW_ENOINFO; +} + +static int +dwarf_reg_states_table_iterate(struct dwarf_cursor *c, + unw_reg_states_callback cb, + void *token) +{ + dwarf_state_record_t sr; + int ret = setup_fde(c, &sr); + struct dwarf_cie_info *dci = c->pi.unwind_info; + unw_word_t addr = dci->fde_instr_start; + unw_word_t curr_ip = c->pi.start_ip; + dwarf_stackable_reg_state_t *rs_stack = NULL; + while (ret >= 0 && curr_ip < c->pi.end_ip && addr < dci->fde_instr_end) + { + unw_word_t prev_ip = curr_ip; + ret = run_cfi_program (c, &sr, &curr_ip, prev_ip, &addr, dci->fde_instr_end, + &rs_stack, dci); + if (ret >= 0 && prev_ip < curr_ip) + ret = cb(token, &sr.rs_current, sizeof(sr.rs_current), prev_ip, curr_ip); + } + empty_rstate_stack(&rs_stack); +#if defined(NEED_LAST_IP) + if (ret >= 0 && curr_ip < c->pi.last_ip) + /* report the dead zone after the procedure ends */ + ret = cb(token, &sr.rs_current, sizeof(sr.rs_current), curr_ip, c->pi.last_ip); +#else + if (ret >= 0 && curr_ip < c->pi.end_ip) + /* report for whatever is left before procedure end */ + ret = cb(token, &sr.rs_current, sizeof(sr.rs_current), curr_ip, c->pi.end_ip); +#endif + return ret; +} + +HIDDEN int +dwarf_reg_states_iterate(struct dwarf_cursor *c, + unw_reg_states_callback cb, + void *token) +{ + int ret = fetch_proc_info (c, c->ip); + int next_use_prev_instr = c->use_prev_instr; + if (ret >= 0) + { + /* Update use_prev_instr for the next frame. */ + assert(c->pi.unwind_info); + struct dwarf_cie_info *dci = c->pi.unwind_info; + next_use_prev_instr = ! dci->signal_frame; + switch (c->pi.format) + { + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: + ret = dwarf_reg_states_table_iterate(c, cb, token); + break; + + case UNW_INFO_FORMAT_DYNAMIC: + ret = dwarf_reg_states_dynamic_iterate (c, cb, token); + break; + + default: + Debug (1, "Unexpected unwind-info format %d\n", c->pi.format); + ret = -UNW_EINVAL; + } + } + put_unwind_info (c, &c->pi); + c->use_prev_instr = next_use_prev_instr; + return ret; +} + +HIDDEN int +dwarf_apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) +{ + return apply_reg_state(c, rs); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gpe.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gpe.c new file mode 100644 index 00000000000000..a0e37ba2329df5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gpe.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "dwarf_i.h" +#include "libunwind_i.h" + +#include + +HIDDEN 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) +{ + return dwarf_read_encoded_pointer_inlined (as, a, addr, encoding, + pi, valp, arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lexpr.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lexpr.c new file mode 100644 index 00000000000000..245970c9e3f293 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lexpr.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gexpr.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfde.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfde.c new file mode 100644 index 00000000000000..e779e8f192e9ab --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfde.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfde.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_proc_info-lsb.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_proc_info-lsb.c new file mode 100644 index 00000000000000..27a5eeac188d06 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_proc_info-lsb.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfind_proc_info-lsb.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_unwind_table.c new file mode 100644 index 00000000000000..68e269f1d7f95f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lfind_unwind_table.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfind_unwind_table.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lparser.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lparser.c new file mode 100644 index 00000000000000..f23aaf48e9c27d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lparser.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gparser.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Lpe.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lpe.c new file mode 100644 index 00000000000000..a672358f063f80 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Lpe.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gpe.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/global.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/global.c new file mode 100644 index 00000000000000..70985071425d39 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/global.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "dwarf_i.h" + +HIDDEN struct mempool dwarf_reg_state_pool; +HIDDEN struct mempool dwarf_cie_info_pool; + +HIDDEN int +dwarf_init (void) +{ + mempool_init (&dwarf_reg_state_pool, sizeof (dwarf_stackable_reg_state_t), 0); + mempool_init (&dwarf_cie_info_pool, sizeof (struct dwarf_cie_info), 0); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/elf32.c b/src/coreclr/src/pal/src/libunwind/src/elf32.c new file mode 100644 index 00000000000000..a70bb58f24dee1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/elf32.c @@ -0,0 +1,4 @@ +#ifndef UNW_REMOTE_ONLY +# include "elf32.h" +# include "elfxx.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/elf32.h b/src/coreclr/src/pal/src/libunwind/src/elf32.h new file mode 100644 index 00000000000000..2c7bca4c9dcca4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/elf32.h @@ -0,0 +1,9 @@ +#ifndef elf32_h +#define elf32_h + +#ifndef ELF_CLASS +#define ELF_CLASS ELFCLASS32 +#endif +#include "elfxx.h" + +#endif /* elf32_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/elf64.c b/src/coreclr/src/pal/src/libunwind/src/elf64.c new file mode 100644 index 00000000000000..195b88794867e9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/elf64.c @@ -0,0 +1,4 @@ +#ifndef UNW_REMOTE_ONLY +# include "elf64.h" +# include "elfxx.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/elf64.h b/src/coreclr/src/pal/src/libunwind/src/elf64.h new file mode 100644 index 00000000000000..091fba8e1f84e0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/elf64.h @@ -0,0 +1,9 @@ +#ifndef elf64_h +#define elf64_h + +#ifndef ELF_CLASS +#define ELF_CLASS ELFCLASS64 +#endif +#include "elfxx.h" + +#endif /* elf64_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/elfxx.c b/src/coreclr/src/pal/src/libunwind/src/elfxx.c new file mode 100644 index 00000000000000..2589a3d43b628b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/elfxx.c @@ -0,0 +1,482 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +#include +#include +#include + +#ifdef HAVE_LZMA +#include +#endif /* HAVE_LZMA */ + +static Elf_W (Shdr)* +elf_w (section_table) (struct elf_image *ei) +{ + Elf_W (Ehdr) *ehdr = ei->image; + Elf_W (Off) soff; + + soff = ehdr->e_shoff; + if (soff + ehdr->e_shnum * ehdr->e_shentsize > ei->size) + { + Debug (1, "section table outside of image? (%lu > %lu)\n", + (unsigned long) (soff + ehdr->e_shnum * ehdr->e_shentsize), + (unsigned long) ei->size); + return NULL; + } + + return (Elf_W (Shdr) *) ((char *) ei->image + soff); +} + +static char* +elf_w (string_table) (struct elf_image *ei, int section) +{ + Elf_W (Ehdr) *ehdr = ei->image; + Elf_W (Off) soff, str_soff; + Elf_W (Shdr) *str_shdr; + + /* this offset is assumed to be OK */ + soff = ehdr->e_shoff; + + str_soff = soff + (section * ehdr->e_shentsize); + if (str_soff + ehdr->e_shentsize > ei->size) + { + Debug (1, "string shdr table outside of image? (%lu > %lu)\n", + (unsigned long) (str_soff + ehdr->e_shentsize), + (unsigned long) ei->size); + return NULL; + } + str_shdr = (Elf_W (Shdr) *) ((char *) ei->image + str_soff); + + if (str_shdr->sh_offset + str_shdr->sh_size > ei->size) + { + Debug (1, "string table outside of image? (%lu > %lu)\n", + (unsigned long) (str_shdr->sh_offset + str_shdr->sh_size), + (unsigned long) ei->size); + return NULL; + } + + Debug (16, "strtab=0x%lx\n", (long) str_shdr->sh_offset); + return ei->image + str_shdr->sh_offset; +} + +static int +elf_w (lookup_symbol) (unw_addr_space_t as, + unw_word_t ip, struct elf_image *ei, + Elf_W (Addr) load_offset, + char *buf, size_t buf_len, Elf_W (Addr) *min_dist) +{ + size_t syment_size; + Elf_W (Ehdr) *ehdr = ei->image; + Elf_W (Sym) *sym, *symtab, *symtab_end; + Elf_W (Shdr) *shdr; + Elf_W (Addr) val; + int i, ret = -UNW_ENOINFO; + char *strtab; + + if (!elf_w (valid_object) (ei)) + return -UNW_ENOINFO; + + shdr = elf_w (section_table) (ei); + if (!shdr) + return -UNW_ENOINFO; + + for (i = 0; i < ehdr->e_shnum; ++i) + { + switch (shdr->sh_type) + { + case SHT_SYMTAB: + case SHT_DYNSYM: + symtab = (Elf_W (Sym) *) ((char *) ei->image + shdr->sh_offset); + symtab_end = (Elf_W (Sym) *) ((char *) symtab + shdr->sh_size); + syment_size = shdr->sh_entsize; + + strtab = elf_w (string_table) (ei, shdr->sh_link); + if (!strtab) + break; + + Debug (16, "symtab=0x%lx[%d]\n", + (long) shdr->sh_offset, shdr->sh_type); + + for (sym = symtab; + sym < symtab_end; + sym = (Elf_W (Sym) *) ((char *) sym + syment_size)) + { + if (ELF_W (ST_TYPE) (sym->st_info) == STT_FUNC + && sym->st_shndx != SHN_UNDEF) + { + val = sym->st_value; + if (sym->st_shndx != SHN_ABS) + val += load_offset; + if (tdep_get_func_addr (as, val, &val) < 0) + continue; + Debug (16, "0x%016lx info=0x%02x %s\n", + (long) val, sym->st_info, strtab + sym->st_name); + + if ((Elf_W (Addr)) (ip - val) < *min_dist) + { + *min_dist = (Elf_W (Addr)) (ip - val); + strncpy (buf, strtab + sym->st_name, buf_len); + buf[buf_len - 1] = '\0'; + ret = (strlen (strtab + sym->st_name) >= buf_len + ? -UNW_ENOMEM : 0); + } + } + } + break; + + default: + break; + } + shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize); + } + return ret; +} + +static Elf_W (Addr) +elf_w (get_load_offset) (struct elf_image *ei, unsigned long segbase, + unsigned long mapoff) +{ + Elf_W (Addr) offset = 0; + Elf_W (Ehdr) *ehdr; + Elf_W (Phdr) *phdr; + int i; + + ehdr = ei->image; + phdr = (Elf_W (Phdr) *) ((char *) ei->image + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i) + if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == mapoff) + { + offset = segbase - phdr[i].p_vaddr; + break; + } + + return offset; +} + +#if HAVE_LZMA +static size_t +xz_uncompressed_size (uint8_t *compressed, size_t length) +{ + uint64_t memlimit = UINT64_MAX; + size_t ret = 0, pos = 0; + lzma_stream_flags options; + lzma_index *index; + + if (length < LZMA_STREAM_HEADER_SIZE) + return 0; + + uint8_t *footer = compressed + length - LZMA_STREAM_HEADER_SIZE; + if (lzma_stream_footer_decode (&options, footer) != LZMA_OK) + return 0; + + if (length < LZMA_STREAM_HEADER_SIZE + options.backward_size) + return 0; + + uint8_t *indexdata = footer - options.backward_size; + if (lzma_index_buffer_decode (&index, &memlimit, NULL, indexdata, + &pos, options.backward_size) != LZMA_OK) + return 0; + + if (lzma_index_size (index) == options.backward_size) + { + ret = lzma_index_uncompressed_size (index); + } + + lzma_index_end (index, NULL); + return ret; +} + +static int +elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) +{ + Elf_W (Shdr) *shdr; + uint8_t *compressed = NULL; + uint64_t memlimit = UINT64_MAX; /* no memory limit */ + size_t compressed_len, uncompressed_len; + + shdr = elf_w (find_section) (ei, ".gnu_debugdata"); + if (!shdr) + return 0; + + compressed = ((uint8_t *) ei->image) + shdr->sh_offset; + compressed_len = shdr->sh_size; + + uncompressed_len = xz_uncompressed_size (compressed, compressed_len); + if (uncompressed_len == 0) + { + Debug (1, "invalid .gnu_debugdata contents\n"); + return 0; + } + + mdi->size = uncompressed_len; + mdi->image = mmap (NULL, uncompressed_len, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + + if (mdi->image == MAP_FAILED) + return 0; + + size_t in_pos = 0, out_pos = 0; + lzma_ret lret; + lret = lzma_stream_buffer_decode (&memlimit, 0, NULL, + compressed, &in_pos, compressed_len, + mdi->image, &out_pos, mdi->size); + if (lret != LZMA_OK) + { + Debug (1, "LZMA decompression failed: %d\n", lret); + munmap (mdi->image, mdi->size); + return 0; + } + + return 1; +} +#else +static int +elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) +{ + return 0; +} +#endif /* !HAVE_LZMA */ + +/* Find the ELF image that contains IP and return the "closest" + procedure name, if there is one. With some caching, this could be + sped up greatly, but until an application materializes that's + sensitive to the performance of this routine, why bother... */ + +HIDDEN int +elf_w (get_proc_name_in_image) (unw_addr_space_t as, struct elf_image *ei, + unsigned long segbase, + unsigned long mapoff, + unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) +{ + Elf_W (Addr) load_offset; + Elf_W (Addr) min_dist = ~(Elf_W (Addr))0; + int ret; + + load_offset = elf_w (get_load_offset) (ei, segbase, mapoff); + ret = elf_w (lookup_symbol) (as, ip, ei, load_offset, buf, buf_len, &min_dist); + + /* If the ELF image has MiniDebugInfo embedded in it, look up the symbol in + there as well and replace the previously found if it is closer. */ + struct elf_image mdi; + if (elf_w (extract_minidebuginfo) (ei, &mdi)) + { + int ret_mdi = elf_w (lookup_symbol) (as, ip, &mdi, load_offset, buf, + buf_len, &min_dist); + + /* Closer symbol was found (possibly truncated). */ + if (ret_mdi == 0 || ret_mdi == -UNW_ENOMEM) + { + ret = ret_mdi; + } + + munmap (mdi.image, mdi.size); + } + + if (min_dist >= ei->size) + return -UNW_ENOINFO; /* not found */ + if (offp) + *offp = min_dist; + return ret; +} + +HIDDEN int +elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp) +{ + unsigned long segbase, mapoff; + struct elf_image ei; + int ret; + char file[PATH_MAX]; + + ret = tdep_get_elf_image (&ei, pid, ip, &segbase, &mapoff, file, PATH_MAX); + if (ret < 0) + return ret; + + ret = elf_w (load_debuglink) (file, &ei, 1); + if (ret < 0) + return ret; + + ret = elf_w (get_proc_name_in_image) (as, &ei, segbase, mapoff, ip, buf, buf_len, offp); + + munmap (ei.image, ei.size); + ei.image = NULL; + + return ret; +} + +HIDDEN Elf_W (Shdr)* +elf_w (find_section) (struct elf_image *ei, const char* secname) +{ + Elf_W (Ehdr) *ehdr = ei->image; + Elf_W (Shdr) *shdr; + char *strtab; + int i; + + if (!elf_w (valid_object) (ei)) + return 0; + + shdr = elf_w (section_table) (ei); + if (!shdr) + return 0; + + strtab = elf_w (string_table) (ei, ehdr->e_shstrndx); + if (!strtab) + return 0; + + for (i = 0; i < ehdr->e_shnum; ++i) + { + if (strcmp (strtab + shdr->sh_name, secname) == 0) + { + if (shdr->sh_offset + shdr->sh_size > ei->size) + { + Debug (1, "section \"%s\" outside image? (0x%lu > 0x%lu)\n", + secname, + (unsigned long) shdr->sh_offset + shdr->sh_size, + (unsigned long) ei->size); + return 0; + } + + Debug (16, "found section \"%s\" at 0x%lx\n", + secname, (unsigned long) shdr->sh_offset); + return shdr; + } + + shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize); + } + + /* section not found */ + return 0; +} + +/* Load a debug section, following .gnu_debuglink if appropriate + * Loads ei from file if not already mapped. + * If is_local, will also search sys directories /usr/local/dbg + * + * Returns 0 on success, failure otherwise. + * ei will be mapped to file or the located .gnu_debuglink from file + */ +HIDDEN int +elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local) +{ + int ret; + Elf_W (Shdr) *shdr; + Elf_W (Ehdr) *prev_image; + off_t prev_size; + + if (!ei->image) + { + ret = elf_map_image(ei, file); + if (ret) + return ret; + } + + prev_image = ei->image; + prev_size = ei->size; + + /* Ignore separate debug files which contain a .gnu_debuglink section. */ + if (is_local == -1) { + return 0; + } + + shdr = elf_w (find_section) (ei, ".gnu_debuglink"); + if (shdr) { + if (shdr->sh_size >= PATH_MAX || + (shdr->sh_offset + shdr->sh_size > ei->size)) + { + return 0; + } + + { + char linkbuf[shdr->sh_size]; + char *link = ((char *) ei->image) + shdr->sh_offset; + char *p; + static const char *debugdir = "/usr/lib/debug"; + char basedir[strlen(file) + 1]; + char newname[shdr->sh_size + strlen (debugdir) + strlen (file) + 9]; + + memcpy(linkbuf, link, shdr->sh_size); + + if (memchr (linkbuf, 0, shdr->sh_size) == NULL) + return 0; + + ei->image = NULL; + + Debug(1, "Found debuglink section, following %s\n", linkbuf); + + p = strrchr (file, '/'); + if (p != NULL) + { + memcpy (basedir, file, p - file); + basedir[p - file] = '\0'; + } + else + basedir[0] = 0; + + strcpy (newname, basedir); + strcat (newname, "/"); + strcat (newname, linkbuf); + ret = elf_w (load_debuglink) (newname, ei, -1); + + if (ret == -1) + { + strcpy (newname, basedir); + strcat (newname, "/.debug/"); + strcat (newname, linkbuf); + ret = elf_w (load_debuglink) (newname, ei, -1); + } + + if (ret == -1 && is_local == 1) + { + strcpy (newname, debugdir); + strcat (newname, basedir); + strcat (newname, "/"); + strcat (newname, linkbuf); + ret = elf_w (load_debuglink) (newname, ei, -1); + } + + if (ret == -1) + { + /* No debuglink file found even though .gnu_debuglink existed */ + ei->image = prev_image; + ei->size = prev_size; + + return 0; + } + else + { + munmap (prev_image, prev_size); + } + + return ret; + } + } + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/elfxx.h b/src/coreclr/src/pal/src/libunwind/src/elfxx.h new file mode 100644 index 00000000000000..830432c2ed1c9e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/elfxx.h @@ -0,0 +1,101 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003, 2005 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include +#include + +#include "libunwind_i.h" + +#if ELF_CLASS == ELFCLASS32 +# define ELF_W(x) ELF32_##x +# define Elf_W(x) Elf32_##x +# define elf_w(x) _Uelf32_##x +#else +# define ELF_W(x) ELF64_##x +# define Elf_W(x) Elf64_##x +# define elf_w(x) _Uelf64_##x +#endif + +extern int elf_w (get_proc_name) (unw_addr_space_t as, + pid_t pid, unw_word_t ip, + char *buf, size_t len, + unw_word_t *offp); + +extern int elf_w (get_proc_name_in_image) (unw_addr_space_t as, + struct elf_image *ei, + unsigned long segbase, + unsigned long mapoff, + unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp); + +extern Elf_W (Shdr)* elf_w (find_section) (struct elf_image *ei, const char* secname); +extern int elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local); + +static inline int +elf_w (valid_object) (struct elf_image *ei) +{ + if (ei->size <= EI_VERSION) + return 0; + + return (memcmp (ei->image, ELFMAG, SELFMAG) == 0 + && ((uint8_t *) ei->image)[EI_CLASS] == ELF_CLASS + && ((uint8_t *) ei->image)[EI_VERSION] != EV_NONE + && ((uint8_t *) ei->image)[EI_VERSION] <= EV_CURRENT); +} + +static inline int +elf_map_image (struct elf_image *ei, const char *path) +{ + struct stat stat; + int fd; + + fd = open (path, O_RDONLY); + if (fd < 0) + return -1; + + if (fstat (fd, &stat) < 0) + { + close (fd); + return -1; + } + + ei->size = stat.st_size; + ei->image = mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0); + close (fd); + if (ei->image == MAP_FAILED) + return -1; + + if (!elf_w (valid_object) (ei)) + { + munmap(ei->image, ei->size); + return -1; + } + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gcreate_addr_space.c new file mode 100644 index 00000000000000..8a6cb8b4e67a59 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Gcreate_addr_space.c @@ -0,0 +1,54 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * hppa supports only big-endian. + */ + if (byte_order != 0 && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_proc_info.c new file mode 100644 index 00000000000000..e10efcfca0d945 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_proc_info.c @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + + if (dwarf_make_proc_info (&c->dwarf) < 0) + { + /* On hppa, some key routines such as _start() and _dl_start() + are missing DWARF unwind info. We don't want to fail in that + case, because those frames are uninteresting and just mark + the end of the frame-chain anyhow. */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 4; + return 0; + } + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_save_loc.c new file mode 100644 index 00000000000000..02dfa3084f9117 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Gget_save_loc.c @@ -0,0 +1,59 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + /* struct cursor *c = (struct cursor *) cursor; */ + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + +#warning FIX ME! + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gglobal.c new file mode 100644 index 00000000000000..351a5015d6869b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Gglobal.c @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN define_lock (hppa_lock); +HIDDEN int tdep_init_done; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&hppa_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + hppa_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&hppa_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c new file mode 100644 index 00000000000000..265455a68c82a1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c @@ -0,0 +1,193 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2004 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + if ((unsigned) (reg - UNW_HPPA_GR) < 32) + addr = &uc->uc_mcontext.sc_gr[reg - UNW_HPPA_GR]; + else if ((unsigned) (reg - UNW_HPPA_FR) < 32) + addr = &uc->uc_mcontext.sc_fr[reg - UNW_HPPA_FR]; + else + addr = NULL; + return addr; +} + +# ifdef UNW_LOCAL_ONLY + +void * +_Uhppa_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (12, "mem[%x] <- %x\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "mem[%x] -> %x\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if ((unsigned int) (reg - UNW_HPPA_FR) < 32) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %x\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %x\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if ((unsigned) (reg - UNW_HPPA_FR) > 32) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08x.%08x\n", + unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08x.%08x\n", + unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +hppa_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = hppa_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_local.c new file mode 100644 index 00000000000000..1fdc7716fd5e09 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_local.c @@ -0,0 +1,77 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by ... + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + return common_init (c, use_prev_instr); +} + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_remote.c new file mode 100644 index 00000000000000..71096ce0e61813 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit_remote.c @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gis_signal_frame.c new file mode 100644 index 00000000000000..addb551818a450 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Gis_signal_frame.c @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, w2, w3, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + /* Check if IP points at sigreturn() sequence. On Linux, this normally is: + + rt_sigreturn: + 0x34190000 ldi 0, %r25 + 0x3414015a ldi __NR_rt_sigreturn,%r20 + 0xe4008200 be,l 0x100(%sr2,%r0),%sr0,%r31 + 0x08000240 nop + + When a signal interrupts a system call, the first word is instead: + + 0x34190002 ldi 1, %r25 + */ + ip = c->dwarf.ip; + if (!ip) + return 0; + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 8, &w2, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 12, &w3, 0, arg)) < 0) + { + Debug (1, "failed to read sigreturn code (ret=%d)\n", ret); + return ret; + } + ret = ((w0 == 0x34190000 || w0 == 0x34190002) + && w1 == 0x3414015a && w2 == 0xe4008200 && w3 == 0x08000240); + Debug (1, "(cursor=%p, ip=0x%08lx) -> %d\n", c, (unsigned) ip, ret); + return ret; +#else + printf ("%s: implement me\n", __FUNCTION__); +#endif + return -UNW_ENOINFO; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gregs.c new file mode 100644 index 00000000000000..da0542c81ff4b1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Gregs.c @@ -0,0 +1,87 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + struct dwarf_loc loc; + + switch (reg) + { + case UNW_HPPA_IP: + if (write) + c->dwarf.ip = *valp; /* update the IP cache */ + if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip + || *valp >= c->dwarf.pi.end_ip)) + c->dwarf.pi_valid = 0; /* new IP outside of current proc */ + break; + + case UNW_HPPA_CFA: + case UNW_HPPA_SP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + /* Do the exception-handling register remapping: */ + case UNW_HPPA_EH0: reg = UNW_HPPA_GR + 20; break; + case UNW_HPPA_EH1: reg = UNW_HPPA_GR + 21; break; + case UNW_HPPA_EH2: reg = UNW_HPPA_GR + 22; break; + case UNW_HPPA_EH3: reg = UNW_HPPA_GR + 31; break; + + default: + break; + } + + if ((unsigned) (reg - UNW_HPPA_GR) >= 32) + return -UNW_EBADREG; + + loc = c->dwarf.loc[reg]; + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + struct dwarf_loc loc; + + if ((unsigned) (reg - UNW_HPPA_FR) >= 32) + return -UNW_EBADREG; + + loc = c->dwarf.loc[reg]; + + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gresume.c new file mode 100644 index 00000000000000..6c11f140364b90 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Gresume.c @@ -0,0 +1,145 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +#if defined(__linux) + +# include + +static NORETURN inline long +my_rt_sigreturn (void *new_sp, int in_syscall) +{ + register unsigned long r25 __asm__ ("r25") = (in_syscall != 0); + register unsigned long r20 __asm__ ("r20") = SYS_rt_sigreturn; + + __asm__ __volatile__ ("copy %0, %%sp\n" + "be,l 0x100(%%sr2,%%r0),%%sr0,%%r31\n" + "nop" + : + : "r"(new_sp), "r"(r20), "r"(r25) + : "memory"); + abort (); +} + +#endif /* __linux */ + +HIDDEN inline int +hppa_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ +#if defined(__linux) + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = c->dwarf.as_arg; + + /* Ensure c->pi is up-to-date. On PA-RISC, it's relatively common to be + missing DWARF unwind info. We don't want to fail in that case, + because the frame-chain still would let us do a backtrace at + least. */ + dwarf_make_proc_info (&c->dwarf); + + if (unlikely (c->sigcontext_format != HPPA_SCF_NONE)) + { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); + my_rt_sigreturn (sc, (sc->sc_flags & PARISC_SC_FLAG_IN_SYSCALL) != 0); + } + else + { + Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); + setcontext (uc); + } +#else +# warning Implement me! +#endif + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int write, void *); + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int write, void *); + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + access_reg = as->acc.access_reg; + access_fpreg = as->acc.access_fpreg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + (*access_fpreg) (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + (*access_reg) (as, reg, &val, 1, arg); + } + } + return 0; +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if (!c->dwarf.ip) + { + /* This can happen easily when the frame-chain gets truncated + due to bad or missing unwind-info. */ + Debug (1, "refusing to resume execution at address 0\n"); + return -UNW_EINVAL; + } + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Gstep.c new file mode 100644 index 00000000000000..4fc8a8776bff59 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Gstep.c @@ -0,0 +1,95 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret, i; + + Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip); + + /* Try DWARF-based unwinding... */ + ret = dwarf_step (&c->dwarf); + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (unlikely (ret < 0)) + { + /* DWARF failed, let's see if we can follow the frame-chain + or skip over the signal trampoline. */ + + Debug (13, "dwarf_step() failed (ret=%d), trying fallback\n", ret); + + if (unw_is_signal_frame (cursor)) + { +#ifdef __linux__ + /* Assume that the trampoline is at the beginning of the + sigframe. */ + unw_word_t ip, sc_addr = c->dwarf.ip + LINUX_RT_SIGFRAME_UC_OFF; + dwarf_loc_t iaoq_loc = DWARF_LOC (sc_addr + LINUX_SC_IAOQ_OFF, 0); + + c->sigcontext_format = HPPA_SCF_LINUX_RT_SIGFRAME; + c->sigcontext_addr = sc_addr; + + if ((ret = dwarf_get (&c->dwarf, iaoq_loc, &ip)) < 0) + { + Debug (2, "failed to read IAOQ[1] (ret=%d)\n", ret); + return ret; + } + c->dwarf.ip = ip & ~0x3; /* mask out the privilege level */ + + for (i = 0; i < 32; ++i) + { + c->dwarf.loc[UNW_HPPA_GR + i] + = DWARF_LOC (sc_addr + LINUX_SC_GR_OFF + 4*i, 0); + c->dwarf.loc[UNW_HPPA_FR + i] + = DWARF_LOC (sc_addr + LINUX_SC_FR_OFF + 4*i, 0); + } + + if ((ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_SP], + &c->dwarf.cfa)) < 0) + { + Debug (2, "failed to read SP (ret=%d)\n", ret); + return ret; + } +#else +# error Implement me! +#endif + } + else + c->dwarf.ip = 0; + } + ret = (c->dwarf.ip == 0) ? 0 : 1; + Debug (2, "returning %d\n", ret); + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lglobal.c new file mode 100644 index 00000000000000..6d7b489e14bd9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Linit.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lis_signal_frame.c new file mode 100644 index 00000000000000..b9a7c4f51ad9fa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/get_accessors.c b/src/coreclr/src/pal/src/libunwind/src/hppa/get_accessors.c new file mode 100644 index 00000000000000..24795801b286e2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/get_accessors.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by ... + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN ALIAS(unw_get_accessors) unw_accessors_t * +unw_get_accessors_int (unw_addr_space_t as); + +unw_accessors_t * +unw_get_accessors (unw_addr_space_t as) +{ + if (!tdep_init_done) + tdep_init (); + + return &as->acc; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/hppa/getcontext.S new file mode 100644 index 00000000000000..ec7554a0259336 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/getcontext.S @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 SPILL(n) stw %r##n, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_GR_OFF+4*(n))(%r26) + +#include "offsets.h" + + .align 4 + .protected _Uhppa_getcontext + .global _Uhppa_getcontext + .proc + .callinfo +_Uhppa_getcontext: + SPILL (2) /* return-pointer */ + SPILL (3) /* frame pointer */ + SPILL (4) /* 2nd-ary frame pointer */ + SPILL (5) /* preserved register */ + SPILL (6) /* preserved register */ + SPILL (7) /* preserved register */ + SPILL (8) /* preserved register */ + SPILL (9) /* preserved register */ + SPILL (10) /* preserved register */ + SPILL (11) /* preserved register */ + SPILL (12) /* preserved register */ + SPILL (13) /* preserved register */ + SPILL (14) /* preserved register */ + SPILL (15) /* preserved register */ + SPILL (16) /* preserved register */ + SPILL (17) /* preserved register */ + SPILL (18) /* preserved register */ + SPILL (19) /* linkage-table register */ + SPILL (27) /* global-data pointer */ + SPILL (30) /* stack pointer */ + + ldo (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FR_OFF)(%r26), %r29 + fstds,ma %fr12, 8(%r29) + fstds,ma %fr13, 8(%r29) + fstds,ma %fr14, 8(%r29) + fstds,ma %fr15, 8(%r29) + fstds,ma %fr16, 8(%r29) + fstds,ma %fr17, 8(%r29) + fstds,ma %fr18, 8(%r29) + fstds,ma %fr19, 8(%r29) + fstds,ma %fr20, 8(%r29) + fstds %fr21, 8(%r29) + + bv,n %r0(%rp) + .procend +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/init.h b/src/coreclr/src/pal/src/libunwind/src/hppa/init.h new file mode 100644 index 00000000000000..4e23b8613273e9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/init.h @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by ... + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + + c->dwarf.loc[UNW_HPPA_IP] = DWARF_REG_LOC (&c->dwarf, UNW_HPPA_IP); + c->dwarf.loc[UNW_HPPA_SP] = DWARF_REG_LOC (&c->dwarf, UNW_HPPA_SP); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_IP], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_SP], &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/offsets.h b/src/coreclr/src/pal/src/libunwind/src/hppa/offsets.h new file mode 100644 index 00000000000000..24e6453ac4f546 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/offsets.h @@ -0,0 +1,17 @@ +#define LINUX_UC_FLAGS_OFF 0x000 +#define LINUX_UC_LINK_OFF 0x004 +#define LINUX_UC_STACK_OFF 0x008 +#define LINUX_UC_MCONTEXT_OFF 0x018 +#define LINUX_UC_SIGMASK_OFF 0x1b8 + +#define LINUX_SC_FLAGS_OFF 0x000 +#define LINUX_SC_GR_OFF 0x004 +#define LINUX_SC_FR_OFF 0x088 +#define LINUX_SC_IASQ_OFF 0x188 +#define LINUX_SC_IAOQ_OFF 0x190 +#define LINUX_SC_SAR_OFF 0x198 + +/* The signal frame contains 4 words of space for the sigreturn + trampoline, the siginfo structure, and then the sigcontext + structure. See include/asm-parisc/compat_rt_sigframe.h. */ +#define LINUX_RT_SIGFRAME_UC_OFF 0xac diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/regname.c b/src/coreclr/src/pal/src/libunwind/src/hppa/regname.c new file mode 100644 index 00000000000000..5698a58ada9c8e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/regname.c @@ -0,0 +1,50 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", + "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", + "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", + "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31", + "ip", + "eh0", "eh1", "eh2", "eh3", + "cfa" + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/hppa/setcontext.S new file mode 100644 index 00000000000000..a36ea35cc613ef --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/setcontext.S @@ -0,0 +1,77 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* The setcontext() in glibc is a no-op (as of 4 Dec 2004), so we have + to implement something useful on our own here. */ + +#define FILL(n) ldw (LINUX_UC_MCONTEXT_OFF+LINUX_SC_GR_OFF+4*(n))(%r26),%r##n + +#include "offsets.h" + + .align 4 + .global _Uhppa_setcontext + .protected _Uhppa_setcontext + .proc + .callinfo +_Uhppa_setcontext: + FILL (2) /* return-pointer */ + FILL (3) /* frame pointer */ + FILL (4) /* 2nd-ary frame pointer */ + FILL (5) /* preserved register */ + FILL (6) /* preserved register */ + FILL (7) /* preserved register */ + FILL (8) /* preserved register */ + FILL (9) /* preserved register */ + FILL (10) /* preserved register */ + FILL (11) /* preserved register */ + FILL (12) /* preserved register */ + FILL (13) /* preserved register */ + FILL (14) /* preserved register */ + FILL (15) /* preserved register */ + FILL (16) /* preserved register */ + FILL (17) /* preserved register */ + FILL (18) /* preserved register */ + FILL (19) /* linkage-table register */ + FILL (27) /* global-data pointer */ + FILL (30) /* stack pointer */ + + ldo (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FR_OFF)(%r26), %r29 + fldds,ma 8(%r29), %fr12 + fldds,ma 8(%r29), %fr13 + fldds,ma 8(%r29), %fr14 + fldds,ma 8(%r29), %fr15 + fldds,ma 8(%r29), %fr16 + fldds,ma 8(%r29), %fr17 + fldds,ma 8(%r29), %fr18 + fldds,ma 8(%r29), %fr19 + fldds,ma 8(%r29), %fr20 + fldds 8(%r29), %fr21 + + bv,n %r0(%rp) + .procend +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/hppa/siglongjmp.S new file mode 100644 index 00000000000000..34878dbe8f374a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/siglongjmp.S @@ -0,0 +1,16 @@ + /* Dummy implementation for now. */ + + .globl _UI_siglongjmp_cont + .globl _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + .proc + .callinfo +#warning fix me + bv %r0(%rp) + .procend +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/tables.c b/src/coreclr/src/pal/src/libunwind/src/hppa/tables.c new file mode 100644 index 00000000000000..5104d4d342971d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/tables.c @@ -0,0 +1,43 @@ +#include "unwind_i.h" + +static inline int +is_local_addr_space (unw_addr_space_t as) +{ + extern unw_addr_space_t _ULhppa_local_addr_space; + + return (as == _Uhppa_local_addr_space +#ifndef UNW_REMOTE_ONLY + || as == _ULhppa_local_addr_space +#endif + ); +} + +HIDDEN int +tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, void *arg) +{ + printf ("%s: begging to get implemented...\n", __FUNCTION__); + return 0; +} + +HIDDEN int +tdep_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) +{ + printf ("%s: the biggest beggar of them all...\n", __FUNCTION__); + return 0; +} + +HIDDEN void +tdep_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + if (!pi->unwind_info) + return; + + if (!is_local_addr_space (as)) + { + free (pi->unwind_info); + pi->unwind_info = NULL; + } +} diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/hppa/unwind_i.h new file mode 100644 index 00000000000000..cafeab57b88312 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/unwind_i.h @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" + +#define hppa_lock UNW_OBJ(lock) +#define hppa_local_resume UNW_OBJ(local_resume) +#define hppa_local_addr_space_init UNW_OBJ(local_addr_space_init) +#define hppa_scratch_loc UNW_OBJ(scratch_loc) +#define setcontext UNW_ARCH_OBJ (setcontext) + +extern void hppa_local_addr_space_init (void); +extern int hppa_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +extern dwarf_loc_t hppa_scratch_loc (struct cursor *c, unw_regnum_t reg); +extern int setcontext (const ucontext_t *ucp); + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gapply_reg_state.c new file mode 100644 index 00000000000000..b45d1b5d9cc411 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gapply_reg_state.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + // Needs dwarf support on ia64 + // return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); + return -UNW_EINVAL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gcreate_addr_space.c new file mode 100644 index 00000000000000..7ad29cbbd39357 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gcreate_addr_space.c @@ -0,0 +1,63 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * IA-64 supports only big or little-endian, not weird stuff like + * PDP_ENDIAN. + */ + if (byte_order != 0 + && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + if (byte_order == 0) + /* use host default: */ + as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + else + as->big_endian = (byte_order == __BIG_ENDIAN); + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gfind_unwind_table.c new file mode 100644 index 00000000000000..9fd2707ace499f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gfind_unwind_table.c @@ -0,0 +1,143 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include +#include +#include +#include + +#include + +#include "libunwind_i.h" +#include "elf64.h" + +static unw_word_t +find_gp (struct elf_dyn_info *edi, Elf64_Phdr *pdyn, Elf64_Addr load_base) +{ + Elf64_Off soff, str_soff; + Elf64_Ehdr *ehdr = edi->ei.image; + Elf64_Shdr *shdr; + Elf64_Shdr *str_shdr; + Elf64_Addr gp = 0; + char *strtab; + int i; + + if (pdyn) + { + /* If we have a PT_DYNAMIC program header, fetch the gp-value + from the DT_PLTGOT entry. */ + Elf64_Dyn *dyn = (Elf64_Dyn *) (pdyn->p_offset + (char *) edi->ei.image); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + gp = (Elf64_Addr) dyn->d_un.d_ptr + load_base; + goto done; + } + } + + /* Without a PT_DYAMIC header, lets try to look for a non-empty .opd + section. If there is such a section, we know it's full of + function descriptors, and we can simply pick up the gp from the + second word of the first entry in this table. */ + + soff = ehdr->e_shoff; + str_soff = soff + (ehdr->e_shstrndx * ehdr->e_shentsize); + + if (soff + ehdr->e_shnum * ehdr->e_shentsize > edi->ei.size) + { + Debug (1, "section table outside of image? (%lu > %lu)", + soff + ehdr->e_shnum * ehdr->e_shentsize, + edi->ei.size); + goto done; + } + + shdr = (Elf64_Shdr *) ((char *) edi->ei.image + soff); + str_shdr = (Elf64_Shdr *) ((char *) edi->ei.image + str_soff); + strtab = (char *) edi->ei.image + str_shdr->sh_offset; + for (i = 0; i < ehdr->e_shnum; ++i) + { + if (strcmp (strtab + shdr->sh_name, ".opd") == 0 + && shdr->sh_size >= 16) + { + gp = ((Elf64_Addr *) ((char *) edi->ei.image + shdr->sh_offset))[1]; + goto done; + } + shdr = (Elf64_Shdr *) (((char *) shdr) + ehdr->e_shentsize); + } + + done: + Debug (16, "image at %p, gp = %lx\n", edi->ei.image, gp); + return gp; +} + +int +ia64_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, + char *path, unw_word_t segbase, unw_word_t mapoff, + unw_word_t ip) +{ + Elf64_Phdr *phdr, *ptxt = NULL, *punw = NULL, *pdyn = NULL; + Elf64_Ehdr *ehdr; + int i; + + if (!_Uelf64_valid_object (&edi->ei)) + return -UNW_ENOINFO; + + ehdr = edi->ei.image; + phdr = (Elf64_Phdr *) ((char *) edi->ei.image + ehdr->e_phoff); + + for (i = 0; i < ehdr->e_phnum; ++i) + { + switch (phdr[i].p_type) + { + case PT_LOAD: + if (phdr[i].p_offset == mapoff) + ptxt = phdr + i; + break; + + case PT_IA_64_UNWIND: + punw = phdr + i; + break; + + case PT_DYNAMIC: + pdyn = phdr + i; + break; + + default: + break; + } + } + if (!ptxt || !punw) + return 0; + + edi->di_cache.start_ip = segbase; + edi->di_cache.end_ip = edi->di_cache.start_ip + ptxt->p_memsz; + edi->di_cache.gp = find_gp (edi, pdyn, segbase - ptxt->p_vaddr); + edi->di_cache.format = UNW_INFO_FORMAT_TABLE; + edi->di_cache.u.ti.name_ptr = 0; + edi->di_cache.u.ti.segbase = segbase; + edi->di_cache.u.ti.table_len = punw->p_memsz / sizeof (unw_word_t); + edi->di_cache.u.ti.table_data = (unw_word_t *) + ((char *) edi->ei.image + (punw->p_vaddr - ptxt->p_vaddr)); + return 1; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_proc_info.c new file mode 100644 index 00000000000000..3ec82b9f82c238 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_proc_info.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + if ((ret = ia64_make_proc_info (c)) < 0) + return ret; + *pi = c->pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_save_loc.c new file mode 100644 index 00000000000000..34efe99a752fc6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gget_save_loc.c @@ -0,0 +1,168 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "rse.h" + +#include "offsets.h" +#include "regs.h" + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + ia64_loc_t loc, reg_loc; + uint8_t nat_bitnr; + int ret; + + loc = IA64_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + /* frame registers */ + case UNW_IA64_BSP: + case UNW_REG_SP: + default: + break; + + case UNW_REG_IP: + loc = c->loc[IA64_REG_IP]; + break; + + /* preserved registers: */ + case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: + loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_GR + 4))]; + break; + + case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7: + loc = c->loc[IA64_REG_NAT4 + (reg - (UNW_IA64_NAT + 4))]; + reg_loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_NAT + 4))]; + nat_bitnr = c->nat_bitnr[reg - (UNW_IA64_NAT + 4)]; + if (IA64_IS_FP_LOC (reg_loc)) + /* NaT bit saved as a NaTVal. */ + loc = reg_loc; + break; + + case UNW_IA64_FR + 2: loc = c->loc[IA64_REG_F2]; break; + case UNW_IA64_FR + 3: loc = c->loc[IA64_REG_F3]; break; + case UNW_IA64_FR + 4: loc = c->loc[IA64_REG_F4]; break; + case UNW_IA64_FR + 5: loc = c->loc[IA64_REG_F5]; break; + case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: + loc = c->loc[IA64_REG_F16 + (reg - (UNW_IA64_FR + 16))]; + break; + + case UNW_IA64_AR_BSP: loc = c->loc[IA64_REG_BSP]; break; + case UNW_IA64_AR_BSPSTORE: loc = c->loc[IA64_REG_BSPSTORE]; break; + case UNW_IA64_AR_PFS: loc = c->loc[IA64_REG_PFS]; break; + case UNW_IA64_AR_RNAT: loc = c->loc[IA64_REG_RNAT]; break; + case UNW_IA64_AR_UNAT: loc = c->loc[IA64_REG_UNAT]; break; + case UNW_IA64_AR_LC: loc = c->loc[IA64_REG_LC]; break; + case UNW_IA64_AR_FPSR: loc = c->loc[IA64_REG_FPSR]; break; + case UNW_IA64_BR + 1: loc = c->loc[IA64_REG_B1]; break; + case UNW_IA64_BR + 2: loc = c->loc[IA64_REG_B2]; break; + case UNW_IA64_BR + 3: loc = c->loc[IA64_REG_B3]; break; + case UNW_IA64_BR + 4: loc = c->loc[IA64_REG_B4]; break; + case UNW_IA64_BR + 5: loc = c->loc[IA64_REG_B5]; break; + case UNW_IA64_CFM: loc = c->cfm_loc; break; + case UNW_IA64_PR: loc = c->loc[IA64_REG_PR]; break; + + case UNW_IA64_GR + 32 ... UNW_IA64_GR + 127: /* stacked reg */ + reg = rotate_gr (c, reg - UNW_IA64_GR); + ret = ia64_get_stacked (c, reg, &loc, NULL); + if (ret < 0) + return ret; + break; + + case UNW_IA64_NAT + 32 ... UNW_IA64_NAT + 127: /* stacked reg */ + reg = rotate_gr (c, reg - UNW_IA64_NAT); + ret = ia64_get_stacked (c, reg, NULL, &loc); + break; + + case UNW_IA64_AR_EC: + loc = c->cfm_loc; + break; + + /* scratch & special registers: */ + + case UNW_IA64_GR + 0: + case UNW_IA64_GR + 1: /* global pointer */ + case UNW_IA64_NAT + 0: + case UNW_IA64_NAT + 1: /* global pointer */ + case UNW_IA64_FR + 0: + case UNW_IA64_FR + 1: + break; + + case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: + case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: + loc = ia64_scratch_loc (c, reg, &nat_bitnr); + break; + + case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: + case UNW_IA64_GR + 8 ... UNW_IA64_GR + 31: + case UNW_IA64_BR + 0: + case UNW_IA64_BR + 6: + case UNW_IA64_BR + 7: + case UNW_IA64_AR_RSC: + case UNW_IA64_AR_CSD: + case UNW_IA64_AR_SSD: + case UNW_IA64_AR_CCV: + loc = ia64_scratch_loc (c, reg, NULL); + break; + + case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: + loc = ia64_scratch_loc (c, reg, NULL); + break; + + case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: + reg = rotate_fr (c, reg - UNW_IA64_FR) + UNW_IA64_FR; + loc = ia64_scratch_loc (c, reg, NULL); + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (IA64_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (IA64_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = IA64_GET_REG (loc); + sloc->extra.nat_bitnr = nat_bitnr; + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = IA64_GET_ADDR (loc); + sloc->extra.nat_bitnr = nat_bitnr; + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gglobal.c new file mode 100644 index 00000000000000..5c6156f0e22f57 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gglobal.c @@ -0,0 +1,122 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +HIDDEN struct ia64_global_unwind_state unw = + { + .lock = PTHREAD_MUTEX_INITIALIZER, + .save_order = { + IA64_REG_IP, IA64_REG_PFS, IA64_REG_PSP, IA64_REG_PR, + IA64_REG_UNAT, IA64_REG_LC, IA64_REG_FPSR, IA64_REG_PRI_UNAT_GR + }, +#if UNW_DEBUG + .preg_name = { + "pri_unat_gr", "pri_unat_mem", "psp", "bsp", "bspstore", + "ar.pfs", "ar.rnat", "rp", + "r4", "r5", "r6", "r7", + "nat4", "nat5", "nat6", "nat7", + "ar.unat", "pr", "ar.lc", "ar.fpsr", + "b1", "b2", "b3", "b4", "b5", + "f2", "f3", "f4", "f5", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" + } +#endif +}; + +HIDDEN void +tdep_init (void) +{ + const uint8_t f1_bytes[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + const uint8_t nat_val_bytes[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + const uint8_t int_val_bytes[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + intrmask_t saved_mask; + uint8_t *lep, *bep; + long i; + + sigfillset (&unwi_full_mask); + + lock_acquire (&unw.lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + mempool_init (&unw.reg_state_pool, sizeof (struct ia64_reg_state), 0); + mempool_init (&unw.labeled_state_pool, + sizeof (struct ia64_labeled_state), 0); + + unw.read_only.r0 = 0; + unw.read_only.f0.raw.bits[0] = 0; + unw.read_only.f0.raw.bits[1] = 0; + + lep = (uint8_t *) &unw.read_only.f1_le + 16; + bep = (uint8_t *) &unw.read_only.f1_be; + for (i = 0; i < 16; ++i) + { + *--lep = f1_bytes[i]; + *bep++ = f1_bytes[i]; + } + + lep = (uint8_t *) &unw.nat_val_le + 16; + bep = (uint8_t *) &unw.nat_val_be; + for (i = 0; i < 16; ++i) + { + *--lep = nat_val_bytes[i]; + *bep++ = nat_val_bytes[i]; + } + + lep = (uint8_t *) &unw.int_val_le + 16; + bep = (uint8_t *) &unw.int_val_be; + for (i = 0; i < 16; ++i) + { + *--lep = int_val_bytes[i]; + *bep++ = int_val_bytes[i]; + } + + assert (8*sizeof(unw_hash_index_t) >= IA64_LOG_UNW_HASH_SIZE); + +#ifndef UNW_REMOTE_ONLY + ia64_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&unw.lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c new file mode 100644 index 00000000000000..8601bb3ca885f3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c @@ -0,0 +1,506 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +#ifdef HAVE_SYS_UC_ACCESS_H +# include +#endif + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +#ifdef HAVE_SYS_UC_ACCESS_H + +#else /* !HAVE_SYS_UC_ACCESS_H */ + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg, uint8_t *nat_bitnr) +{ + return inlined_uc_addr (uc, reg, nat_bitnr); +} + +#endif /* !HAVE_SYS_UC_ACCESS_H */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (12, "mem[%lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "mem[%lx] -> %lx\n", addr, *val); + } + return 0; +} + +#ifdef HAVE_SYS_UC_ACCESS_H + +#define SYSCALL_CFM_SAVE_REG 11 /* on a syscall, ar.pfs is saved in r11 */ +#define REASON_SYSCALL 0 + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + ucontext_t *uc = arg; + unsigned int nat, mask; + uint64_t value; + uint16_t reason; + int ret; + + __uc_get_reason (uc, &reason); + + switch (reg) + { + case UNW_IA64_GR ... UNW_IA64_GR + 31: + if ((ret = __uc_get_grs (uc, (reg - UNW_IA64_GR), 1, &value, &nat))) + break; + + if (write) + ret = __uc_set_grs (uc, (reg - UNW_IA64_GR), 1, val, nat); + else + *val = value; + break; + + case UNW_IA64_NAT ... UNW_IA64_NAT + 31: + if ((ret = __uc_get_grs (uc, (reg - UNW_IA64_GR), 1, &value, &nat))) + break; + + mask = 1 << (reg - UNW_IA64_GR); + + if (write) + { + if (*val) + nat |= mask; + else + nat &= ~mask; + ret = __uc_set_grs (uc, (reg - UNW_IA64_GR), 1, &value, nat); + } + else + *val = (nat & mask) != 0; + break; + + case UNW_IA64_AR ... UNW_IA64_AR + 127: + if (reg == UNW_IA64_AR_BSP) + { + if (write) + ret = __uc_set_ar (uc, (reg - UNW_IA64_AR), *val); + else + ret = __uc_get_ar (uc, (reg - UNW_IA64_AR), val); + } + else if (reg == UNW_IA64_AR_PFS && reason == REASON_SYSCALL) + { + /* As of HP-UX 11.22, getcontext() does not have unwind info + and because of that, we need to hack thins manually here. + Hopefully, this is OK because the HP-UX kernel also needs + to know where AR.PFS has been saved, so the use of + register r11 for this purpose is pretty much nailed + down. */ + if (write) + ret = __uc_set_grs (uc, SYSCALL_CFM_SAVE_REG, 1, val, 0); + else + ret = __uc_get_grs (uc, SYSCALL_CFM_SAVE_REG, 1, val, &nat); + } + else + { + if (write) + ret = __uc_set_ar (uc, (reg - UNW_IA64_AR), *val); + else + ret = __uc_get_ar (uc, (reg - UNW_IA64_AR), val); + } + break; + + case UNW_IA64_BR ... UNW_IA64_BR + 7: + if (write) + ret = __uc_set_brs (uc, (reg - UNW_IA64_BR), 1, val); + else + ret = __uc_get_brs (uc, (reg - UNW_IA64_BR), 1, val); + break; + + case UNW_IA64_PR: + if (write) + ret = __uc_set_prs (uc, *val); + else + ret = __uc_get_prs (uc, val); + break; + + case UNW_IA64_IP: + if (write) + ret = __uc_set_ip (uc, *val); + else + ret = __uc_get_ip (uc, val); + break; + + case UNW_IA64_CFM: + if (write) + ret = __uc_set_cfm (uc, *val); + else + ret = __uc_get_cfm (uc, val); + break; + + case UNW_IA64_FR ... UNW_IA64_FR + 127: + default: + ret = EINVAL; + break; + } + + if (ret != 0) + { + Debug (1, "failed to %s %s (ret = %d)\n", + write ? "write" : "read", unw_regname (reg), ret); + return -UNW_EBADREG; + } + + if (write) + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + else + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + return 0; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + fp_regval_t fp_regval; + int ret; + + switch (reg) + { + case UNW_IA64_FR ... UNW_IA64_FR + 127: + if (write) + { + memcpy (&fp_regval, val, sizeof (fp_regval)); + ret = __uc_set_frs (uc, (reg - UNW_IA64_FR), 1, &fp_regval); + } + else + { + ret = __uc_get_frs (uc, (reg - UNW_IA64_FR), 1, &fp_regval); + memcpy (val, &fp_regval, sizeof (*val)); + } + break; + + default: + ret = EINVAL; + break; + } + if (ret != 0) + return -UNW_EBADREG; + + return 0; +} + +#else /* !HAVE_SYS_UC_ACCESS_H */ + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr, mask; + ucontext_t *uc = arg; + + if (reg >= UNW_IA64_NAT + 4 && reg <= UNW_IA64_NAT + 7) + { + mask = ((unw_word_t) 1) << (reg - UNW_IA64_NAT); + if (write) + { + if (*val) + uc->uc_mcontext.sc_nat |= mask; + else + uc->uc_mcontext.sc_nat &= ~mask; + } + else + *val = (uc->uc_mcontext.sc_nat & mask) != 0; + + if (write) + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + else + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + return 0; + } + + addr = tdep_uc_addr (uc, reg, NULL); + if (!addr) + goto badreg; + + if (write) + { + if (ia64_read_only_reg (addr)) + { + Debug (16, "attempt to write read-only register\n"); + return -UNW_EREADONLYREG; + } + *addr = *val; + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if (reg < UNW_IA64_FR || reg >= UNW_IA64_FR + 128) + goto badreg; + + addr = tdep_uc_addr (uc, reg, NULL); + if (!addr) + goto badreg; + + if (write) + { + if (ia64_read_only_reg (addr)) + { + Debug (16, "attempt to write read-only register\n"); + return -UNW_EREADONLYREG; + } + *addr = *val; + Debug (12, "%s <- %016lx.%016lx\n", + unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %016lx.%016lx\n", + unw_regname (reg), val->raw.bits[1], val->raw.bits[0]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +#endif /* !HAVE_SYS_UC_ACCESS_H */ + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +ia64_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); +#if defined(__linux) + local_addr_space.abi = ABI_LINUX; +#elif defined(__hpux) + local_addr_space.abi = ABI_HPUX; +#endif + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = tdep_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = ia64_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ + +#ifndef UNW_LOCAL_ONLY + +HIDDEN int +ia64_uc_access_reg (struct cursor *c, ia64_loc_t loc, unw_word_t *valp, + int write) +{ +#ifdef HAVE_SYS_UC_ACCESS_H + unw_word_t uc_addr = IA64_GET_AUX_ADDR (loc); + ucontext_t *ucp; + int ret; + + Debug (16, "%s location %s\n", + write ? "writing" : "reading", ia64_strloc (loc)); + + if (c->as == unw_local_addr_space) + ucp = (ucontext_t *) uc_addr; + else + { + unw_word_t *dst, src; + + /* Need to copy-in ucontext_t first. */ + ucp = alloca (sizeof (ucontext_t)); + if (!ucp) + return -UNW_ENOMEM; + + /* For now, there is no non-HP-UX implementation of the + uc_access(3) interface. Because of that, we cannot, e.g., + unwind an HP-UX program from a Linux program. Should that + become possible at some point in the future, the + copy-in/copy-out needs to be adjusted to do byte-swapping if + necessary. */ + assert (c->as->big_endian == (__BYTE_ORDER == __BIG_ENDIAN)); + + dst = (unw_word_t *) ucp; + for (src = uc_addr; src < uc_addr + sizeof (ucontext_t); src += 8) + if ((ret = (*c->as->acc.access_mem) (c->as, src, dst++, 0, c->as_arg)) + < 0) + return ret; + } + + if (IA64_IS_REG_LOC (loc)) + ret = access_reg (unw_local_addr_space, IA64_GET_REG (loc), valp, write, + ucp); + else + { + /* Must be an access to the RSE backing store in ucontext_t. */ + unw_word_t addr = IA64_GET_ADDR (loc); + + if (write) + ret = __uc_set_rsebs (ucp, (uint64_t *) addr, 1, valp); + else + ret = __uc_get_rsebs (ucp, (uint64_t *) addr, 1, valp); + if (ret != 0) + ret = -UNW_EBADREG; + } + if (ret < 0) + return ret; + + if (write && c->as != unw_local_addr_space) + { + /* need to copy-out ucontext_t: */ + unw_word_t dst, *src = (unw_word_t *) ucp; + for (dst = uc_addr; dst < uc_addr + sizeof (ucontext_t); dst += 8) + if ((ret = (*c->as->acc.access_mem) (c->as, dst, src++, 1, c->as_arg)) + < 0) + return ret; + } + return 0; +#else /* !HAVE_SYS_UC_ACCESS_H */ + return -UNW_EINVAL; +#endif /* !HAVE_SYS_UC_ACCESS_H */ +} + +HIDDEN int +ia64_uc_access_fpreg (struct cursor *c, ia64_loc_t loc, unw_fpreg_t *valp, + int write) +{ +#ifdef HAVE_SYS_UC_ACCESS_H + unw_word_t uc_addr = IA64_GET_AUX_ADDR (loc); + ucontext_t *ucp; + int ret; + + if (c->as == unw_local_addr_space) + ucp = (ucontext_t *) uc_addr; + else + { + unw_word_t *dst, src; + + /* Need to copy-in ucontext_t first. */ + ucp = alloca (sizeof (ucontext_t)); + if (!ucp) + return -UNW_ENOMEM; + + /* For now, there is no non-HP-UX implementation of the + uc_access(3) interface. Because of that, we cannot, e.g., + unwind an HP-UX program from a Linux program. Should that + become possible at some point in the future, the + copy-in/copy-out needs to be adjusted to do byte-swapping if + necessary. */ + assert (c->as->big_endian == (__BYTE_ORDER == __BIG_ENDIAN)); + + dst = (unw_word_t *) ucp; + for (src = uc_addr; src < uc_addr + sizeof (ucontext_t); src += 8) + if ((ret = (*c->as->acc.access_mem) (c->as, src, dst++, 0, c->as_arg)) + < 0) + return ret; + } + + if ((ret = access_fpreg (unw_local_addr_space, IA64_GET_REG (loc), valp, + write, ucp)) < 0) + return ret; + + if (write && c->as != unw_local_addr_space) + { + /* need to copy-out ucontext_t: */ + unw_word_t dst, *src = (unw_word_t *) ucp; + for (dst = uc_addr; dst < uc_addr + sizeof (ucontext_t); dst += 8) + if ((ret = (*c->as->acc.access_mem) (c->as, dst, src++, 1, c->as_arg)) + < 0) + return ret; + } + return 0; +#else /* !HAVE_SYS_UC_ACCESS_H */ + return -UNW_EINVAL; +#endif /* !HAVE_SYS_UC_ACCESS_H */ +} + +#endif /* UNW_LOCAL_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_local.c new file mode 100644 index 00000000000000..8fe1c679b29e94 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_local.c @@ -0,0 +1,110 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static inline void +set_as_arg (struct cursor *c, unw_context_t *uc) +{ +#if defined(__linux) && defined(__KERNEL__) + c->task = current; + c->as_arg = &uc->sw; +#else + c->as_arg = uc; +#endif +} + +static inline int +get_initial_stack_pointers (struct cursor *c, unw_context_t *uc, + unw_word_t *sp, unw_word_t *bsp) +{ +#if defined(__linux) + unw_word_t sol, bspstore; + +#ifdef __KERNEL__ + sol = (uc->sw.ar_pfs >> 7) & 0x7f; + bspstore = uc->sw.ar_bspstore; + *sp = uc->ksp; +# else + sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f; + bspstore = uc->uc_mcontext.sc_ar_bsp; + *sp = uc->uc_mcontext.sc_gr[12]; +# endif + *bsp = rse_skip_regs (bspstore, -sol); +#elif defined(__hpux) + int ret; + + if ((ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_GR + 12), sp)) < 0 + || (ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_AR_BSP), bsp)) < 0) + return ret; +#else +# error Fix me. +#endif + return 0; +} + +int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t sp, bsp; + int ret; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->as = unw_local_addr_space; + set_as_arg (c, uc); + + if ((ret = get_initial_stack_pointers (c, uc, &sp, &bsp)) < 0) + return ret; + + Debug (4, "initial bsp=%lx, sp=%lx\n", bsp, sp); + + if ((ret = common_init (c, sp, bsp)) < 0) + return ret; + +#ifdef __hpux + /* On HP-UX, the context created by getcontext() points to the + getcontext() system call stub. Step over it: */ + ret = unw_step (cursor); +#endif + return ret; +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_remote.c new file mode 100644 index 00000000000000..b570c7eab39ead --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit_remote.c @@ -0,0 +1,61 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + unw_word_t sp, bsp; + int ret; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + if (as == unw_local_addr_space) + /* This special-casing is unfortunate and shouldn't be needed; + however, both Linux and HP-UX need to adjust the context a bit + before it's usable. Try to think of a cleaner way of doing + this. Not sure it's possible though, as long as we want to be + able to use the context returned by getcontext() et al. */ + return unw_init_local (cursor, as_arg); + + c->as = as; + c->as_arg = as_arg; + + if ((ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_GR + 12), &sp)) < 0 + || (ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_AR_BSP), &bsp)) < 0) + return ret; + + return common_init (c, sp, bsp); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginstall_cursor.S b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginstall_cursor.S new file mode 100644 index 00000000000000..6fb4401faa2373 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginstall_cursor.S @@ -0,0 +1,348 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "ucontext_i.h" + +#ifdef UNW_LOCAL_ONLY +# include "Lcursor_i.h" +# define ia64_install_cursor _ULia64_install_cursor +#else +# include "Gcursor_i.h" +# define ia64_install_cursor _Uia64_install_cursor +#endif + +#define SYS_sigreturn 1181 + +#ifndef UNW_REMOTE_ONLY + +/* ia64_install_cursor (const cursor *c, long pri_unat, long *extra, + long bspstore, long dirty_size, long *dirty_partition, + long dirty_rnat) + + Restores the machine-state represented by C and thereby resumes execution + in that frame. If the frame or one of its descendants was interrupted + by a signal, all registers are restored (including the signal mask). + Otherwise, only the preserved registers, the global-pointer (r1), and + the exception-arguments (r15-r18) are restored. */ + +#define pRet p6 +#define pSig p7 + + .align 32 + .hidden ia64_install_cursor + .global ia64_install_cursor + .proc ia64_install_cursor +ia64_install_cursor: + alloc r3 = ar.pfs, 7, 0, 0, 0 + invala + add r2 = FR_LOC_OFF, in0 + ;; + + ld8 r16 = [r2], LOC_SIZE // r16 = loc[IA64_REG_FR16] + mov.m r10 = ar.rsc // (ar.rsc: ~ 12 cycle latency) + add r3 = FR_LOC_OFF + 16, in0 + ;; + + ld8 r17 = [r2], 2*LOC_SIZE // r17 = loc[IA64_REG_FR17] + ld8 r18 = [r3], 2*LOC_SIZE // r18 = loc[IA64_REG_FR18] + and r16 = -4, r16 + ;; + + ld8 r19 = [r2], 2*LOC_SIZE // r19 = loc[IA64_REG_FR19] + ld8 r20 = [r3], 2*LOC_SIZE // r20 = loc[IA64_REG_FR20] + and r17 = -4, r17 + ;; + + ldf.fill f16 = [r16] // f16 restored (don't touch no more) + ldf.fill f17 = [r17] // f17 restored (don't touch no more) + and r18 = -4, r18 + + ld8 r21 = [r2], 2*LOC_SIZE // r21 = loc[IA64_REG_FR21] + ld8 r22 = [r3], 2*LOC_SIZE // r22 = loc[IA64_REG_FR22] + and r19 = -4, r19 + ;; + + ldf.fill f18 = [r18] // f18 restored (don't touch no more) + ldf.fill f19 = [r19] // f19 restored (don't touch no more) + and r20 = -4, r20 + + ld8 r23 = [r2], 2*LOC_SIZE // r23 = loc[IA64_REG_FR23] + ld8 r24 = [r3], 2*LOC_SIZE // r24 = loc[IA64_REG_FR24] + and r21 = -4, r21 + ;; + + ldf.fill f20 = [r20] // f20 restored (don't touch no more) + ldf.fill f21 = [r21] // f21 restored (don't touch no more) + and r22 = -4, r22 + + ld8 r25 = [r2], 2*LOC_SIZE // r25 = loc[IA64_REG_FR25] + ld8 r26 = [r3], 2*LOC_SIZE // r26 = loc[IA64_REG_FR26] + and r23 = -4, r23 + ;; + + ldf.fill f22 = [r22] // f22 restored (don't touch no more) + ldf.fill f23 = [r23] // f23 restored (don't touch no more) + and r24 = -4, r24 + + ld8 r27 = [r2], 2*LOC_SIZE // r27 = loc[IA64_REG_FR27] + ld8 r28 = [r3], 2*LOC_SIZE // r28 = loc[IA64_REG_FR28] + and r25 = -4, r25 + ;; + + ldf.fill f24 = [r24] // f24 restored (don't touch no more) + ldf.fill f25 = [r25] // f25 restored (don't touch no more) + and r26 = -4, r26 + + ld8 r29 = [r2], 2*LOC_SIZE // r29 = loc[IA64_REG_FR29] + ld8 r30 = [r3], 2*LOC_SIZE // r30 = loc[IA64_REG_FR30] + and r27 = -4, r27 + ;; + + ldf.fill f26 = [r26] // f26 restored (don't touch no more) + ldf.fill f27 = [r27] // f27 restored (don't touch no more) + and r28 = -4, r28 + + ld8 r31 = [r2] // r31 = loc[IA64_REG_FR31] + mov.m ar.unat = in1 + and r29 = -4, r29 + ;; + + ldf.fill f28 = [r28] // f28 restored (don't touch no more) + ldf.fill f29 = [r29] // f29 restored (don't touch no more) + and r30 = -4, r30 + + ld8 r1 = [in2], 8 // gp restored (don't touch no more) + add r8 = SIGCONTEXT_ADDR_OFF, in0 + and r31 = -4, r31 + ;; + + ld8 r8 = [r8] // r8 = sigcontext_addr + and r11 = 0x1c, r10 // clear all but rsc.be and rsc.pl + add r2 = PFS_LOC_OFF, in0 + + ldf.fill f30 = [r30] // f30 restored (don't touch no more) + ldf.fill f31 = [r31] // f31 restored (don't touch no more) + add r3 = 8, in2 + ;; + + ld8.fill r4 = [in2], 16 // r4 restored (don't touch no more) + ld8.fill r5 = [r3], 16 // r5 restored (don't touch no more) + cmp.eq pRet, pSig = r0, r8 // sigcontext_addr == NULL? + ;; + ld8.fill r6 = [in2], 16 // r6 restored (don't touch no more) + ld8.fill r7 = [r3] // r7 restored (don't touch no more) + add r3 = IP_OFF, in0 + ;; + + ld8 r14 = [r2], (B1_LOC_OFF - PFS_LOC_OFF) // r14 = pfs_loc + ld8 r15 = [r3] // r15 = ip + add r3 = (B2_LOC_OFF - IP_OFF), r3 + ;; + + ld8 r16 = [r2], (B3_LOC_OFF - B1_LOC_OFF) // r16 = b1_loc + ld8 r17= [r3], (B4_LOC_OFF - B2_LOC_OFF) // r17 = b2_loc + and r14 = -4, r14 + ;; + + ld8 r18 = [r2], (B5_LOC_OFF - B3_LOC_OFF) // r18 = b3_loc + ld8 r19 = [r3], (F2_LOC_OFF - B4_LOC_OFF) // r19 = b4_loc + and r16 = -4, r16 + ;; + + ld8 r20 = [r2], (F3_LOC_OFF - B5_LOC_OFF) // r20 = b5_loc + ld8 r21 = [r3], (F4_LOC_OFF - F2_LOC_OFF) // r21 = f2_loc + and r17 = -4, r17 + ;; + + ld8 r16 = [r16] // r16 = *b1_loc + ld8 r17 = [r17] // r17 = *b2_loc + and r18 = -4, r18 + + ld8 r22 = [r2], (F5_LOC_OFF - F3_LOC_OFF) // r21 = f3_loc + ld8 r23 = [r3], (UNAT_LOC_OFF - F4_LOC_OFF) // r22 = f4_loc + and r19 = -4, r19 + ;; + + ld8 r18 = [r18] // r18 = *b3_loc + ld8 r19 = [r19] // r19 = *b4_loc + and r20 = -4, r20 + + ld8 r24 = [r2], (LC_LOC_OFF - F5_LOC_OFF) // r24 = f5_loc + ld8 r25 = [r3], (FPSR_LOC_OFF - UNAT_LOC_OFF) // r25 = unat_loc + and r21 = -4, r21 + ;; + + and r22 = -4, r22 + and r23 = -4, r23 + and r24 = -4, r24 + + ld8 r20 = [r20] // r20 = *b5_loc + ldf.fill f2 = [r21] // f2 restored (don't touch no more) + mov b1 = r16 // b1 restored (don't touch no more) + ;; + + ldf.fill f3 = [r22] // f3 restored (don't touch no more) + ldf.fill f4 = [r23] // f4 restored (don't touch no more) + mov b2 = r17 // b2 restored (don't touch no more) + + ld8 r26 = [r2], (RNAT_LOC_OFF - LC_LOC_OFF) // r26 = lc_loc + ld8 r27 = [r3] // r27 = fpsr_loc + and r25 = -4, r25 + + add r3 = (PSP_OFF - FPSR_LOC_OFF), r3 + nop 0 + nop 0 + ;; + + ldf.fill f5 = [r24] // f5 restored (don't touch no more) +(pRet) ld8 r25 = [r25] // r25 = *unat_loc + mov b3 = r18 // b3 restored (don't touch no more) + + ld8 r28 = [r2], (BSP_OFF - RNAT_LOC_OFF) // r28 = rnat_loc + ld8 r29 = [r3], (PR_OFF - PSP_OFF) // r29 = sp + mov b4 = r19 // b4 restored (don't touch no more) + + and r26 = -4, r26 + and r27 = -4, r27 + mov b5 = r20 // b5 restored (don't touch no more) + ;; + + ld8 r26 = [r26] // r26 = *lc_loc + ld8 r27 = [r27] // r27 = *fpsr_loc + and r28 = -4, r28 + + mov r30 = in3 // make backup-copy of new bsp + ld8 r31 = [r3] // r31 = pr + mov rp = r15 + ;; + + ld8 r28 = [r28] // r28 = rnat + mov.m ar.rsc = r11 // put RSE into enforced lazy mode + mov.i ar.lc = r26 // lc restored (don't touch no more) + ;; + + loadrs // drop dirty partition + mov r9 = in2 // make backup-copy of &extra[r16] + cmp.eq p8, p0 = in4, r0 // dirty-size == 0? +(p8) br.cond.dpnt.many .skip_load_dirty + + mov r2 = in4 // make backup-copy of dirty_size + mov r15 = in5 // make backup-copy of dirty_partition + mov r16 = in6 // make backup-copy of dirty_rnat + ;; + + alloc r3 = ar.pfs, 0, 0, 0, 0 // drop register frame + dep r11 = r2, r11, 16, 16 + ;; + mov.m ar.bspstore = r15 + ;; + mov.m ar.rnat = r16 + mov.m ar.rsc = r11 // 14 cycles latency to loadrs + ;; + loadrs // loadup new dirty partition + ;; + +.skip_load_dirty: + mov.m ar.bspstore = r30 // restore register backing-store + add r3 = 8, r9 // r3 = &extra[r16] + ;; + +(pRet) mov.m ar.fpsr = r27 // fpsr restored (don't touch no more) + mov.m ar.rnat = r28 +(pSig) br.cond.dpnt.many .next + +/****** Return via br.ret: */ + + ld8 r14 = [r14] // r14 = *pfs_loc + ld8 r15 = [r9], 16 // r15 restored (don't touch no more) + mov pr = r31, -1 // pr restored (don't touch no more) + ;; + + ld8 r16 = [r3], 16 // r16 restored (don't touch no more) + ld8 r17 = [r9] // r17 restored (don't touch no more) + nop.i 0 + ;; + + ld8 r18 = [r3] // r18 restored (don't touch no more) + mov.m ar.rsc = r10 // restore original ar.rsc + mov sp = r29 + + mov.m ar.unat = r25 // unat restored (don't touch no more) + mov.i ar.pfs = r14 + br.ret.sptk.many rp + ;; + +/****** Return via sigreturn(): */ + +.next: mov.m ar.rsc = r10 // restore original ar.rsc + add r2 = (SC_FR + 6*16), r8 + add r3 = (SC_FR + 7*16), r8 + ;; + + ldf.fill f6 = [r2], 32 + ldf.fill f7 = [r3], 32 + nop 0 + ;; + + ldf.fill f8 = [r2], 32 + ldf.fill f9 = [r3], 32 + nop 0 + ;; + + ldf.fill f10 = [r2], 32 + ldf.fill f11 = [r3], 32 + nop 0 + ;; + + ldf.fill f12 = [r2], 32 + ldf.fill f13 = [r3], 32 + nop 0 + ;; + + ldf.fill f14 = [r2], 32 + ldf.fill f15 = [r3], 32 + mov sp = r29 + ;; + +#if NEW_SYSCALL + add r2 = 8, tp;; + ld8 r2 = [r2] + mov r15 = SYS_sigreturn + mov b7 = r2 + br.call.sptk.many b6 = b7 + ;; +#else + mov r15 = SYS_sigreturn + break 0x100000 +#endif + break 0 // bug out if sigreturn() returns + + .endp ia64_install_cursor + +#endif /* !UNW_REMOTE_ONLY */ +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gis_signal_frame.c new file mode 100644 index 00000000000000..e268a0629986ae --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gis_signal_frame.c @@ -0,0 +1,54 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + struct ia64_state_record sr; + int ret; + + /* Crude and slow, but we need to peek ahead into the unwind + descriptors to find out if the current IP is inside the signal + trampoline. */ + ret = ia64_fetch_proc_info (c, c->ip, 1); + if (ret < 0) + return ret; + + ret = ia64_create_state_record (c, &sr); + if (ret < 0) + return ret; + + /* For now, we assume that any non-zero abi marker implies a signal frame. + This should get us pretty far. */ + ret = (sr.abi_marker != 0); + + ia64_free_state_record (&sr); + + Debug (1, "(cursor=%p, ip=0x%016lx) -> %d\n", c, c->ip, ret); + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gparser.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gparser.c new file mode 100644 index 00000000000000..b1f0f4a11826f2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gparser.c @@ -0,0 +1,1131 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* forward declaration: */ +static int create_state_record_for (struct cursor *c, + struct ia64_state_record *sr, + unw_word_t ip); + +typedef unsigned long unw_word; + +#define alloc_reg_state() (mempool_alloc (&unw.reg_state_pool)) +#define free_reg_state(rs) (mempool_free (&unw.reg_state_pool, rs)) +#define alloc_labeled_state() (mempool_alloc (&unw.labeled_state_pool)) +#define free_labeled_state(s) (mempool_free (&unw.labeled_state_pool, s)) + +/* Routines to manipulate the state stack. */ + +static inline void +push (struct ia64_state_record *sr) +{ + struct ia64_reg_state *rs; + + rs = alloc_reg_state (); + if (!rs) + { + print_error ("libunwind: cannot stack reg state!\n"); + return; + } + memcpy (rs, &sr->curr, sizeof (*rs)); + sr->curr.next = rs; +} + +static void +pop (struct ia64_state_record *sr) +{ + struct ia64_reg_state *rs = sr->curr.next; + + if (!rs) + { + print_error ("libunwind: stack underflow!\n"); + return; + } + memcpy (&sr->curr, rs, sizeof (*rs)); + free_reg_state (rs); +} + +/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */ +static struct ia64_reg_state * +dup_state_stack (struct ia64_reg_state *rs) +{ + struct ia64_reg_state *copy, *prev = NULL, *first = NULL; + + while (rs) + { + copy = alloc_reg_state (); + if (!copy) + { + print_error ("unwind.dup_state_stack: out of memory\n"); + return NULL; + } + memcpy (copy, rs, sizeof (*copy)); + if (first) + prev->next = copy; + else + first = copy; + rs = rs->next; + prev = copy; + } + return first; +} + +/* Free all stacked register states (but not RS itself). */ +static void +free_state_stack (struct ia64_reg_state *rs) +{ + struct ia64_reg_state *p, *next; + + for (p = rs->next; p != NULL; p = next) + { + next = p->next; + free_reg_state (p); + } + rs->next = NULL; +} + +/* Unwind decoder routines */ + +static enum ia64_pregnum CONST_ATTR +decode_abreg (unsigned char abreg, int memory) +{ + switch (abreg) + { + case 0x04 ... 0x07: + return IA64_REG_R4 + (abreg - 0x04); + case 0x22 ... 0x25: + return IA64_REG_F2 + (abreg - 0x22); + case 0x30 ... 0x3f: + return IA64_REG_F16 + (abreg - 0x30); + case 0x41 ... 0x45: + return IA64_REG_B1 + (abreg - 0x41); + case 0x60: + return IA64_REG_PR; + case 0x61: + return IA64_REG_PSP; + case 0x62: + return memory ? IA64_REG_PRI_UNAT_MEM : IA64_REG_PRI_UNAT_GR; + case 0x63: + return IA64_REG_IP; + case 0x64: + return IA64_REG_BSP; + case 0x65: + return IA64_REG_BSPSTORE; + case 0x66: + return IA64_REG_RNAT; + case 0x67: + return IA64_REG_UNAT; + case 0x68: + return IA64_REG_FPSR; + case 0x69: + return IA64_REG_PFS; + case 0x6a: + return IA64_REG_LC; + default: + break; + } + Dprintf ("libunwind: bad abreg=0x%x\n", abreg); + return IA64_REG_LC; +} + +static void +set_reg (struct ia64_reg_info *reg, enum ia64_where where, int when, + unsigned long val) +{ + reg->val = val; + reg->where = where; + if (reg->when == IA64_WHEN_NEVER) + reg->when = when; +} + +static void +alloc_spill_area (unsigned long *offp, unsigned long regsize, + struct ia64_reg_info *lo, struct ia64_reg_info *hi) +{ + struct ia64_reg_info *reg; + + for (reg = hi; reg >= lo; --reg) + { + if (reg->where == IA64_WHERE_SPILL_HOME) + { + reg->where = IA64_WHERE_PSPREL; + *offp -= regsize; + reg->val = *offp; + } + } +} + +static inline void +spill_next_when (struct ia64_reg_info **regp, struct ia64_reg_info *lim, + unw_word t) +{ + struct ia64_reg_info *reg; + + for (reg = *regp; reg <= lim; ++reg) + { + if (reg->where == IA64_WHERE_SPILL_HOME) + { + reg->when = t; + *regp = reg + 1; + return; + } + } + Dprintf ("libunwind: excess spill!\n"); +} + +static inline void +finish_prologue (struct ia64_state_record *sr) +{ + struct ia64_reg_info *reg; + unsigned long off; + int i; + + /* First, resolve implicit register save locations (see Section + "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */ + for (i = 0; i < (int) ARRAY_SIZE (unw.save_order); ++i) + { + reg = sr->curr.reg + unw.save_order[i]; + if (reg->where == IA64_WHERE_GR_SAVE) + { + reg->where = IA64_WHERE_GR; + reg->val = sr->gr_save_loc++; + } + } + + /* Next, compute when the fp, general, and branch registers get + saved. This must come before alloc_spill_area() because we need + to know which registers are spilled to their home locations. */ + + if (sr->imask) + { + unsigned char kind, mask = 0, *cp = sr->imask; + unsigned long t; + static const unsigned char limit[3] = + { + IA64_REG_F31, IA64_REG_R7, IA64_REG_B5 + }; + struct ia64_reg_info *(regs[3]); + + regs[0] = sr->curr.reg + IA64_REG_F2; + regs[1] = sr->curr.reg + IA64_REG_R4; + regs[2] = sr->curr.reg + IA64_REG_B1; + + for (t = 0; (int) t < sr->region_len; ++t) + { + if ((t & 3) == 0) + mask = *cp++; + kind = (mask >> 2 * (3 - (t & 3))) & 3; + if (kind > 0) + spill_next_when (®s[kind - 1], sr->curr.reg + limit[kind - 1], + sr->region_start + t); + } + } + + /* Next, lay out the memory stack spill area. */ + + if (sr->any_spills) + { + off = sr->spill_offset; + alloc_spill_area (&off, 16, sr->curr.reg + IA64_REG_F2, + sr->curr.reg + IA64_REG_F31); + alloc_spill_area (&off, 8, sr->curr.reg + IA64_REG_B1, + sr->curr.reg + IA64_REG_B5); + alloc_spill_area (&off, 8, sr->curr.reg + IA64_REG_R4, + sr->curr.reg + IA64_REG_R7); + } +} + +/* Region header descriptors. */ + +static void +desc_prologue (int body, unw_word rlen, unsigned char mask, + unsigned char grsave, struct ia64_state_record *sr) +{ + int i, region_start; + + if (!(sr->in_body || sr->first_region)) + finish_prologue (sr); + sr->first_region = 0; + + /* check if we're done: */ + if (sr->when_target < sr->region_start + sr->region_len) + { + sr->done = 1; + return; + } + + region_start = sr->region_start + sr->region_len; + + for (i = 0; i < sr->epilogue_count; ++i) + pop (sr); + sr->epilogue_count = 0; + sr->when_sp_restored = IA64_WHEN_NEVER; + + sr->region_start = region_start; + sr->region_len = rlen; + sr->in_body = body; + + if (!body) + { + push (sr); + + if (mask) + for (i = 0; i < 4; ++i) + { + if (mask & 0x8) + set_reg (sr->curr.reg + unw.save_order[i], IA64_WHERE_GR, + sr->region_start + sr->region_len - 1, grsave++); + mask <<= 1; + } + sr->gr_save_loc = grsave; + sr->any_spills = 0; + sr->imask = 0; + sr->spill_offset = 0x10; /* default to psp+16 */ + } +} + +/* Prologue descriptors. */ + +static inline void +desc_abi (unsigned char abi, unsigned char context, + struct ia64_state_record *sr) +{ + sr->abi_marker = (abi << 8) | context; +} + +static inline void +desc_br_gr (unsigned char brmask, unsigned char gr, + struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 5; ++i) + { + if (brmask & 1) + set_reg (sr->curr.reg + IA64_REG_B1 + i, IA64_WHERE_GR, + sr->region_start + sr->region_len - 1, gr++); + brmask >>= 1; + } +} + +static inline void +desc_br_mem (unsigned char brmask, struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 5; ++i) + { + if (brmask & 1) + { + set_reg (sr->curr.reg + IA64_REG_B1 + i, IA64_WHERE_SPILL_HOME, + sr->region_start + sr->region_len - 1, 0); + sr->any_spills = 1; + } + brmask >>= 1; + } +} + +static inline void +desc_frgr_mem (unsigned char grmask, unw_word frmask, + struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 4; ++i) + { + if ((grmask & 1) != 0) + { + set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_SPILL_HOME, + sr->region_start + sr->region_len - 1, 0); + sr->any_spills = 1; + } + grmask >>= 1; + } + for (i = 0; i < 20; ++i) + { + if ((frmask & 1) != 0) + { + int base = (i < 4) ? IA64_REG_F2 : IA64_REG_F16 - 4; + set_reg (sr->curr.reg + base + i, IA64_WHERE_SPILL_HOME, + sr->region_start + sr->region_len - 1, 0); + sr->any_spills = 1; + } + frmask >>= 1; + } +} + +static inline void +desc_fr_mem (unsigned char frmask, struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 4; ++i) + { + if ((frmask & 1) != 0) + { + set_reg (sr->curr.reg + IA64_REG_F2 + i, IA64_WHERE_SPILL_HOME, + sr->region_start + sr->region_len - 1, 0); + sr->any_spills = 1; + } + frmask >>= 1; + } +} + +static inline void +desc_gr_gr (unsigned char grmask, unsigned char gr, + struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 4; ++i) + { + if ((grmask & 1) != 0) + set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_GR, + sr->region_start + sr->region_len - 1, gr++); + grmask >>= 1; + } +} + +static inline void +desc_gr_mem (unsigned char grmask, struct ia64_state_record *sr) +{ + int i; + + for (i = 0; i < 4; ++i) + { + if ((grmask & 1) != 0) + { + set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_SPILL_HOME, + sr->region_start + sr->region_len - 1, 0); + sr->any_spills = 1; + } + grmask >>= 1; + } +} + +static inline void +desc_mem_stack_f (unw_word t, unw_word size, struct ia64_state_record *sr) +{ + set_reg (sr->curr.reg + IA64_REG_PSP, IA64_WHERE_NONE, + sr->region_start + MIN ((int) t, sr->region_len - 1), 16 * size); +} + +static inline void +desc_mem_stack_v (unw_word t, struct ia64_state_record *sr) +{ + sr->curr.reg[IA64_REG_PSP].when = + sr->region_start + MIN ((int) t, sr->region_len - 1); +} + +static inline void +desc_reg_gr (unsigned char reg, unsigned char dst, + struct ia64_state_record *sr) +{ + set_reg (sr->curr.reg + reg, IA64_WHERE_GR, + sr->region_start + sr->region_len - 1, dst); +} + +static inline void +desc_reg_psprel (unsigned char reg, unw_word pspoff, + struct ia64_state_record *sr) +{ + set_reg (sr->curr.reg + reg, IA64_WHERE_PSPREL, + sr->region_start + sr->region_len - 1, 0x10 - 4 * pspoff); +} + +static inline void +desc_reg_sprel (unsigned char reg, unw_word spoff, + struct ia64_state_record *sr) +{ + set_reg (sr->curr.reg + reg, IA64_WHERE_SPREL, + sr->region_start + sr->region_len - 1, 4 * spoff); +} + +static inline void +desc_rp_br (unsigned char dst, struct ia64_state_record *sr) +{ + sr->return_link_reg = dst; +} + +static inline void +desc_reg_when (unsigned char regnum, unw_word t, struct ia64_state_record *sr) +{ + struct ia64_reg_info *reg = sr->curr.reg + regnum; + + if (reg->where == IA64_WHERE_NONE) + reg->where = IA64_WHERE_GR_SAVE; + reg->when = sr->region_start + MIN ((int) t, sr->region_len - 1); +} + +static inline void +desc_spill_base (unw_word pspoff, struct ia64_state_record *sr) +{ + sr->spill_offset = 0x10 - 4 * pspoff; +} + +static inline unsigned char * +desc_spill_mask (unsigned char *imaskp, struct ia64_state_record *sr) +{ + sr->imask = imaskp; + return imaskp + (2 * sr->region_len + 7) / 8; +} + +/* Body descriptors. */ + +static inline void +desc_epilogue (unw_word t, unw_word ecount, struct ia64_state_record *sr) +{ + sr->when_sp_restored = sr->region_start + sr->region_len - 1 - t; + sr->epilogue_count = ecount + 1; +} + +static inline void +desc_copy_state (unw_word label, struct ia64_state_record *sr) +{ + struct ia64_labeled_state *ls; + + for (ls = sr->labeled_states; ls; ls = ls->next) + { + if (ls->label == label) + { + free_state_stack (&sr->curr); + memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr)); + sr->curr.next = dup_state_stack (ls->saved_state.next); + return; + } + } + print_error ("libunwind: failed to find labeled state\n"); +} + +static inline void +desc_label_state (unw_word label, struct ia64_state_record *sr) +{ + struct ia64_labeled_state *ls; + + ls = alloc_labeled_state (); + if (!ls) + { + print_error ("unwind.desc_label_state(): out of memory\n"); + return; + } + ls->label = label; + memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state)); + ls->saved_state.next = dup_state_stack (sr->curr.next); + + /* insert into list of labeled states: */ + ls->next = sr->labeled_states; + sr->labeled_states = ls; +} + +/* General descriptors. */ + +static inline int +desc_is_active (unsigned char qp, unw_word t, struct ia64_state_record *sr) +{ + if (sr->when_target <= sr->region_start + MIN ((int) t, sr->region_len - 1)) + return 0; + if (qp > 0) + { + if ((sr->pr_val & ((unw_word_t) 1 << qp)) == 0) + return 0; + sr->pr_mask |= ((unw_word_t) 1 << qp); + } + return 1; +} + +static inline void +desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg, + struct ia64_state_record *sr) +{ + struct ia64_reg_info *r; + + if (!desc_is_active (qp, t, sr)) + return; + + r = sr->curr.reg + decode_abreg (abreg, 0); + r->where = IA64_WHERE_NONE; + r->when = IA64_WHEN_NEVER; + r->val = 0; +} + +static inline void +desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg, + unsigned char x, unsigned char ytreg, + struct ia64_state_record *sr) +{ + enum ia64_where where = IA64_WHERE_GR; + struct ia64_reg_info *r; + + if (!desc_is_active (qp, t, sr)) + return; + + if (x) + where = IA64_WHERE_BR; + else if (ytreg & 0x80) + where = IA64_WHERE_FR; + + r = sr->curr.reg + decode_abreg (abreg, 0); + r->where = where; + r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); + r->val = (ytreg & 0x7f); +} + +static inline void +desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg, + unw_word pspoff, struct ia64_state_record *sr) +{ + struct ia64_reg_info *r; + + if (!desc_is_active (qp, t, sr)) + return; + + r = sr->curr.reg + decode_abreg (abreg, 1); + r->where = IA64_WHERE_PSPREL; + r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); + r->val = 0x10 - 4 * pspoff; +} + +static inline void +desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, + unw_word spoff, struct ia64_state_record *sr) +{ + struct ia64_reg_info *r; + + if (!desc_is_active (qp, t, sr)) + return; + + r = sr->curr.reg + decode_abreg (abreg, 1); + r->where = IA64_WHERE_SPREL; + r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); + r->val = 4 * spoff; +} + +#define UNW_DEC_BAD_CODE(code) \ + print_error ("libunwind: unknown code encountered\n") + +/* Register names. */ +#define UNW_REG_BSP IA64_REG_BSP +#define UNW_REG_BSPSTORE IA64_REG_BSPSTORE +#define UNW_REG_FPSR IA64_REG_FPSR +#define UNW_REG_LC IA64_REG_LC +#define UNW_REG_PFS IA64_REG_PFS +#define UNW_REG_PR IA64_REG_PR +#define UNW_REG_RNAT IA64_REG_RNAT +#define UNW_REG_PSP IA64_REG_PSP +#define UNW_REG_RP IA64_REG_IP +#define UNW_REG_UNAT IA64_REG_UNAT + +/* Region headers. */ +#define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg) +#define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg) + +/* Prologue descriptors. */ +#define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg) +#define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg) +#define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg) +#define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg) +#define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg) +#define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg) +#define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg) +#define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg) +#define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg) +#define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg) +#define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg) +#define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg) +#define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg) +#define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) \ + desc_reg_when(IA64_REG_PRI_UNAT_GR,t,arg) +#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) \ + desc_reg_when(IA64_REG_PRI_UNAT_MEM,t,arg) +#define UNW_DEC_PRIUNAT_GR(fmt,r,arg) \ + desc_reg_gr(IA64_REG_PRI_UNAT_GR,r,arg) +#define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) \ + desc_reg_psprel(IA64_REG_PRI_UNAT_MEM,o,arg) +#define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) \ + desc_reg_sprel(IA64_REG_PRI_UNAT_MEM,o,arg) +#define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg) +#define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg) +#define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg)) + +/* Body descriptors. */ +#define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg) +#define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg) +#define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg) + +/* General unwind descriptors. */ +#define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg) +#define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg) +#define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) \ + desc_spill_psprel_p(p,t,a,o,arg) +#define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) \ + desc_spill_psprel_p(0,t,a,o,arg) +#define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg) +#define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg) +#define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg) +#define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg) + +#include "unwind_decoder.h" + +#ifdef _U_dyn_op + +/* parse dynamic unwind info */ + +static struct ia64_reg_info * +lookup_preg (int regnum, int memory, struct ia64_state_record *sr) +{ + int preg; + + switch (regnum) + { + case UNW_IA64_AR_BSP: preg = IA64_REG_BSP; break; + case UNW_IA64_AR_BSPSTORE: preg = IA64_REG_BSPSTORE; break; + case UNW_IA64_AR_FPSR: preg = IA64_REG_FPSR; break; + case UNW_IA64_AR_LC: preg = IA64_REG_LC; break; + case UNW_IA64_AR_PFS: preg = IA64_REG_PFS; break; + case UNW_IA64_AR_RNAT: preg = IA64_REG_RNAT; break; + case UNW_IA64_AR_UNAT: preg = IA64_REG_UNAT; break; + case UNW_IA64_BR + 0: preg = IA64_REG_IP; break; + case UNW_IA64_PR: preg = IA64_REG_PR; break; + case UNW_IA64_SP: preg = IA64_REG_PSP; break; + + case UNW_IA64_NAT: + if (memory) + preg = IA64_REG_PRI_UNAT_MEM; + else + preg = IA64_REG_PRI_UNAT_GR; + break; + + case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: + preg = IA64_REG_R4 + (regnum - (UNW_IA64_GR + 4)); + break; + + case UNW_IA64_BR + 1 ... UNW_IA64_BR + 5: + preg = IA64_REG_B1 + (regnum - UNW_IA64_BR); + break; + + case UNW_IA64_FR + 2 ... UNW_IA64_FR + 5: + preg = IA64_REG_F2 + (regnum - (UNW_IA64_FR + 2)); + break; + + case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: + preg = IA64_REG_F16 + (regnum - (UNW_IA64_FR + 16)); + break; + + default: + Dprintf ("%s: invalid register number %d\n", __FUNCTION__, regnum); + return NULL; + } + return sr->curr.reg + preg; +} + +/* An alias directive inside a region of length RLEN is interpreted to + mean that the region behaves exactly like the first RLEN + instructions at the aliased IP. RLEN=0 implies that the current + state matches exactly that of before the instruction at the aliased + IP is executed. */ + +static int +desc_alias (unw_dyn_op_t *op, struct cursor *c, struct ia64_state_record *sr) +{ + struct ia64_state_record orig_sr = *sr; + int i, ret, when, rlen = sr->region_len; + unw_word_t new_ip; + + when = MIN (sr->when_target, rlen); + new_ip = op->val + ((when / 3) * 16 + (when % 3)); + + if ((ret = ia64_fetch_proc_info (c, new_ip, 1)) < 0) + return ret; + + if ((ret = create_state_record_for (c, sr, new_ip)) < 0) + return ret; + + sr->first_region = orig_sr.first_region; + sr->done = 0; + sr->any_spills |= orig_sr.any_spills; + sr->in_body = orig_sr.in_body; + sr->region_start = orig_sr.region_start; + sr->region_len = orig_sr.region_len; + if (sr->when_sp_restored != IA64_WHEN_NEVER) + sr->when_sp_restored = op->when + MIN (orig_sr.when_sp_restored, rlen); + sr->epilogue_count = orig_sr.epilogue_count; + sr->when_target = orig_sr.when_target; + + for (i = 0; i < IA64_NUM_PREGS; ++i) + if (sr->curr.reg[i].when != IA64_WHEN_NEVER) + sr->curr.reg[i].when = op->when + MIN (sr->curr.reg[i].when, rlen); + + ia64_free_state_record (sr); + sr->labeled_states = orig_sr.labeled_states; + sr->curr.next = orig_sr.curr.next; + return 0; +} + +static inline int +parse_dynamic (struct cursor *c, struct ia64_state_record *sr) +{ + unw_dyn_info_t *di = c->pi.unwind_info; + unw_dyn_proc_info_t *proc = &di->u.pi; + unw_dyn_region_info_t *r; + struct ia64_reg_info *ri; + enum ia64_where where; + int32_t when, len; + unw_dyn_op_t *op; + unw_word_t val; + int memory, ret; + int8_t qp; + + for (r = proc->regions; r; r = r->next) + { + len = r->insn_count; + if (len < 0) + { + if (r->next) + { + Debug (1, "negative region length allowed in last region only!"); + return -UNW_EINVAL; + } + len = -len; + /* hack old region info to set the start where we need it: */ + sr->region_start = (di->end_ip - di->start_ip) / 0x10 * 3 - len; + sr->region_len = 0; + } + /* all regions are treated as prologue regions: */ + desc_prologue (0, len, 0, 0, sr); + + if (sr->done) + return 0; + + for (op = r->op; op < r->op + r->op_count; ++op) + { + when = op->when; + val = op->val; + qp = op->qp; + + if (!desc_is_active (qp, when, sr)) + continue; + + when = sr->region_start + MIN ((int) when, sr->region_len - 1); + + switch (op->tag) + { + case UNW_DYN_SAVE_REG: + memory = 0; + if ((unsigned) (val - UNW_IA64_GR) < 128) + where = IA64_WHERE_GR; + else if ((unsigned) (val - UNW_IA64_FR) < 128) + where = IA64_WHERE_FR; + else if ((unsigned) (val - UNW_IA64_BR) < 8) + where = IA64_WHERE_BR; + else + { + Dprintf ("%s: can't save to register number %d\n", + __FUNCTION__, (int) op->reg); + return -UNW_EBADREG; + } + /* fall through */ + update_reg_info: + ri = lookup_preg (op->reg, memory, sr); + if (!ri) + return -UNW_EBADREG; + ri->where = where; + ri->when = when; + ri->val = val; + break; + + case UNW_DYN_SPILL_FP_REL: + memory = 1; + where = IA64_WHERE_PSPREL; + val = 0x10 - val; + goto update_reg_info; + + case UNW_DYN_SPILL_SP_REL: + memory = 1; + where = IA64_WHERE_SPREL; + goto update_reg_info; + + case UNW_DYN_ADD: + if (op->reg == UNW_IA64_SP) + { + if (val & 0xf) + { + Dprintf ("%s: frame-size %ld not an integer " + "multiple of 16\n", + __FUNCTION__, (long) op->val); + return -UNW_EINVAL; + } + desc_mem_stack_f (when, -((int64_t) val / 16), sr); + } + else + { + Dprintf ("%s: can only ADD to stack-pointer\n", + __FUNCTION__); + return -UNW_EBADREG; + } + break; + + case UNW_DYN_POP_FRAMES: + sr->when_sp_restored = when; + sr->epilogue_count = op->val; + break; + + case UNW_DYN_LABEL_STATE: + desc_label_state (op->val, sr); + break; + + case UNW_DYN_COPY_STATE: + desc_copy_state (op->val, sr); + break; + + case UNW_DYN_ALIAS: + if ((ret = desc_alias (op, c, sr)) < 0) + return ret; + + case UNW_DYN_STOP: + goto end_of_ops; + } + } + end_of_ops: + ; + } + return 0; +} +#else +# define parse_dynamic(c,sr) (-UNW_EINVAL) +#endif /* _U_dyn_op */ + + +HIDDEN int +ia64_fetch_proc_info (struct cursor *c, unw_word_t ip, int need_unwind_info) +{ + int ret, dynamic = 1; + + if (c->pi_valid && !need_unwind_info) + return 0; + + /* check dynamic info first --- it overrides everything else */ + ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info, + c->as_arg); + if (ret == -UNW_ENOINFO) + { + dynamic = 0; + ret = ia64_find_proc_info (c, ip, need_unwind_info); + } + + c->pi_valid = 1; + c->pi_is_dynamic = dynamic; + return ret; +} + +static inline void +put_unwind_info (struct cursor *c, unw_proc_info_t *pi) +{ + if (!c->pi_valid) + return; + + if (c->pi_is_dynamic) + unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg); + else + ia64_put_unwind_info (c, pi); +} + +static int +create_state_record_for (struct cursor *c, struct ia64_state_record *sr, + unw_word_t ip) +{ + unw_word_t predicates = c->pr; + struct ia64_reg_info *r; + uint8_t *dp, *desc_end; + int ret; + + assert (c->pi_valid); + + /* build state record */ + memset (sr, 0, sizeof (*sr)); + for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) + r->when = IA64_WHEN_NEVER; + sr->pr_val = predicates; + sr->first_region = 1; + + if (!c->pi.unwind_info) + { + /* No info, return default unwinder (leaf proc, no mem stack, no + saved regs), rp in b0, pfs in ar.pfs. */ + Debug (1, "no unwind info for ip=0x%lx (gp=%lx)\n", + (long) ip, (long) c->pi.gp); + sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR; + sr->curr.reg[IA64_REG_IP].when = -1; + sr->curr.reg[IA64_REG_IP].val = 0; + goto out; + } + + sr->when_target = (3 * ((ip & ~(unw_word_t) 0xf) - c->pi.start_ip) / 16 + + (ip & 0xf)); + + switch (c->pi.format) + { + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: + dp = c->pi.unwind_info; + desc_end = dp + c->pi.unwind_info_size; + while (!sr->done && dp < desc_end) + dp = unw_decode (dp, sr->in_body, sr); + ret = 0; + break; + + case UNW_INFO_FORMAT_DYNAMIC: + ret = parse_dynamic (c, sr); + break; + + default: + ret = -UNW_EINVAL; + } + + put_unwind_info (c, &c->pi); + + if (ret < 0) + return ret; + + if (sr->when_target > sr->when_sp_restored) + { + /* sp has been restored and all values on the memory stack below + psp also have been restored. */ + sr->curr.reg[IA64_REG_PSP].val = 0; + sr->curr.reg[IA64_REG_PSP].where = IA64_WHERE_NONE; + sr->curr.reg[IA64_REG_PSP].when = IA64_WHEN_NEVER; + for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) + if ((r->where == IA64_WHERE_PSPREL && r->val <= 0x10) + || r->where == IA64_WHERE_SPREL) + { + r->val = 0; + r->where = IA64_WHERE_NONE; + r->when = IA64_WHEN_NEVER; + } + } + + /* If RP did't get saved, generate entry for the return link + register. */ + if (sr->curr.reg[IA64_REG_IP].when >= sr->when_target) + { + sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR; + sr->curr.reg[IA64_REG_IP].when = -1; + sr->curr.reg[IA64_REG_IP].val = sr->return_link_reg; + } + + if (sr->when_target > sr->curr.reg[IA64_REG_BSP].when + && sr->when_target > sr->curr.reg[IA64_REG_BSPSTORE].when + && sr->when_target > sr->curr.reg[IA64_REG_RNAT].when) + { + Debug (8, "func 0x%lx may switch the register-backing-store\n", + c->pi.start_ip); + c->pi.flags |= UNW_PI_FLAG_IA64_RBS_SWITCH; + } + out: +#if UNW_DEBUG + if (unwi_debug_level > 2) + { + Dprintf ("%s: state record for func 0x%lx, t=%u (flags=0x%lx):\n", + __FUNCTION__, + (long) c->pi.start_ip, sr->when_target, (long) c->pi.flags); + for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) + { + if (r->where != IA64_WHERE_NONE || r->when != IA64_WHEN_NEVER) + { + Dprintf (" %s <- ", unw.preg_name[r - sr->curr.reg]); + switch (r->where) + { + case IA64_WHERE_GR: + Dprintf ("r%lu", (long) r->val); + break; + case IA64_WHERE_FR: + Dprintf ("f%lu", (long) r->val); + break; + case IA64_WHERE_BR: + Dprintf ("b%lu", (long) r->val); + break; + case IA64_WHERE_SPREL: + Dprintf ("[sp+0x%lx]", (long) r->val); + break; + case IA64_WHERE_PSPREL: + Dprintf ("[psp+0x%lx]", (long) r->val); + break; + case IA64_WHERE_NONE: + Dprintf ("%s+0x%lx", + unw.preg_name[r - sr->curr.reg], (long) r->val); + break; + default: + Dprintf ("BADWHERE(%d)", r->where); + break; + } + Dprintf ("\t\t%d\n", r->when); + } + } + } +#endif + return 0; +} + +/* The proc-info must be valid for IP before this routine can be + called. */ +HIDDEN int +ia64_create_state_record (struct cursor *c, struct ia64_state_record *sr) +{ + return create_state_record_for (c, sr, c->ip); +} + +HIDDEN int +ia64_free_state_record (struct ia64_state_record *sr) +{ + struct ia64_labeled_state *ls, *next; + + /* free labeled register states & stack: */ + + for (ls = sr->labeled_states; ls; ls = next) + { + next = ls->next; + free_state_stack (&ls->saved_state); + free_labeled_state (ls); + } + free_state_stack (&sr->curr); + + return 0; +} + +HIDDEN int +ia64_make_proc_info (struct cursor *c) +{ + int ret, caching = c->as->caching_policy != UNW_CACHE_NONE; + + if (!caching || ia64_get_cached_proc_info (c) < 0) + { + /* Lookup it up the slow way... */ + if ((ret = ia64_fetch_proc_info (c, c->ip, 0)) < 0) + return ret; + if (caching) + ia64_cache_proc_info (c); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Grbs.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Grbs.c new file mode 100644 index 00000000000000..e7c01fe219e9e5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Grbs.c @@ -0,0 +1,319 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* Logically, we like to think of the stack as a contiguous region of +memory. Unfortunately, this logical view doesn't work for the +register backing store, because the RSE is an asynchronous engine and +because UNIX/Linux allow for stack-switching via sigaltstack(2). +Specifically, this means that any given stacked register may or may +not be backed up by memory in the current stack. If not, then the +backing memory may be found in any of the "more inner" (younger) +stacks. The routines in this file help manage the discontiguous +nature of the register backing store. The routines are completely +independent of UNIX/Linux, but each stack frame that switches the +backing store is expected to reserve 4 words for use by libunwind. For +example, in the Linux sigcontext, sc_fr[0] and sc_fr[1] serve this +purpose. */ + +#include "unwind_i.h" + +#if UNW_DEBUG + +HIDDEN const char * +ia64_strloc (ia64_loc_t loc) +{ + static char buf[128]; + + if (IA64_IS_NULL_LOC (loc)) + return ""; + + buf[0] = '\0'; + + if (IA64_IS_MEMSTK_NAT (loc)) + strcat (buf, "memstk_nat("); + if (IA64_IS_UC_LOC (loc)) + strcat (buf, "uc("); + if (IA64_IS_FP_LOC (loc)) + strcat (buf, "fp("); + + if (IA64_IS_REG_LOC (loc)) + sprintf (buf + strlen (buf), "%s", unw_regname (IA64_GET_REG (loc))); + else + sprintf (buf + strlen (buf), "0x%llx", + (unsigned long long) IA64_GET_ADDR (loc)); + + if (IA64_IS_FP_LOC (loc)) + strcat (buf, ")"); + if (IA64_IS_UC_LOC (loc)) + strcat (buf, ")"); + if (IA64_IS_MEMSTK_NAT (loc)) + strcat (buf, ")"); + + return buf; +} + +#endif /* UNW_DEBUG */ + +HIDDEN int +rbs_switch (struct cursor *c, + unw_word_t saved_bsp, unw_word_t saved_bspstore, + ia64_loc_t saved_rnat_loc) +{ + struct rbs_area *rbs = &c->rbs_area[c->rbs_curr]; + unw_word_t lo, ndirty, rbs_base; + int ret; + + Debug (10, "(left=%u, curr=%u)\n", c->rbs_left_edge, c->rbs_curr); + + /* Calculate address "lo" at which the backing store starts: */ + ndirty = rse_num_regs (saved_bspstore, saved_bsp); + lo = rse_skip_regs (c->bsp, -ndirty); + + rbs->size = (rbs->end - lo); + + /* If the previously-recorded rbs-area is empty we don't need to + track it and we can simply overwrite it... */ + if (rbs->size) + { + Debug (10, "inner=[0x%lx-0x%lx)\n", + (long) (rbs->end - rbs->size), (long) rbs->end); + + c->rbs_curr = (c->rbs_curr + 1) % ARRAY_SIZE (c->rbs_area); + rbs = c->rbs_area + c->rbs_curr; + + if (c->rbs_curr == c->rbs_left_edge) + c->rbs_left_edge = (c->rbs_left_edge + 1) % ARRAY_SIZE (c->rbs_area); + } + + if ((ret = rbs_get_base (c, saved_bspstore, &rbs_base)) < 0) + return ret; + + rbs->end = saved_bspstore; + rbs->size = saved_bspstore - rbs_base; + rbs->rnat_loc = saved_rnat_loc; + + c->bsp = saved_bsp; + + Debug (10, "outer=[0x%llx-0x%llx), rnat@%s\n", (long long) rbs_base, + (long long) rbs->end, ia64_strloc (rbs->rnat_loc)); + return 0; +} + +HIDDEN int +rbs_find_stacked (struct cursor *c, unw_word_t regs_to_skip, + ia64_loc_t *locp, ia64_loc_t *rnat_locp) +{ + unw_word_t nregs, bsp = c->bsp, curr = c->rbs_curr, n; + unw_word_t left_edge = c->rbs_left_edge; +#if UNW_DEBUG + int reg = 32 + regs_to_skip; +#endif + + while (!rbs_contains (&c->rbs_area[curr], bsp)) + { + if (curr == left_edge) + { + Debug (1, "could not find register r%d!\n", reg); + return -UNW_EBADREG; + } + + n = rse_num_regs (c->rbs_area[curr].end, bsp); + curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) % ARRAY_SIZE (c->rbs_area); + bsp = rse_skip_regs (c->rbs_area[curr].end - c->rbs_area[curr].size, n); + } + + while (1) + { + nregs = rse_num_regs (bsp, c->rbs_area[curr].end); + + if (regs_to_skip < nregs) + { + /* found it: */ + unw_word_t addr; + + addr = rse_skip_regs (bsp, regs_to_skip); + if (locp) + *locp = rbs_loc (c->rbs_area + curr, addr); + if (rnat_locp) + *rnat_locp = rbs_get_rnat_loc (c->rbs_area + curr, addr); + return 0; + } + + if (curr == left_edge) + { + Debug (1, "could not find register r%d!\n", reg); + return -UNW_EBADREG; + } + + regs_to_skip -= nregs; + + curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) % ARRAY_SIZE (c->rbs_area); + bsp = c->rbs_area[curr].end - c->rbs_area[curr].size; + } +} + +#ifdef NEED_RBS_COVER_AND_FLUSH + +static inline int +get_rnat (struct cursor *c, struct rbs_area *rbs, unw_word_t bsp, + unw_word_t *__restrict rnatp) +{ + ia64_loc_t rnat_locp = rbs_get_rnat_loc (rbs, bsp); + + return ia64_get (c, rnat_locp, rnatp); +} + +/* Simulate the effect of "cover" followed by a "flushrs" for the + target-frame. However, since the target-frame's backing store + may not have space for the registers that got spilled onto other + rbs-areas, we save those registers to DIRTY_PARTITION where + we can then load them via a single "loadrs". + + This function returns the size of the dirty-partition that was + created or a negative error-code in case of error. + + Note: This does not modify the rbs_area[] structure in any way. */ +HIDDEN int +rbs_cover_and_flush (struct cursor *c, unw_word_t nregs, + unw_word_t *dirty_partition, unw_word_t *dirty_rnat, + unw_word_t *bspstore) +{ + unw_word_t n, src_mask, dst_mask, bsp, *dst, src_rnat, dst_rnat = 0; + unw_word_t curr = c->rbs_curr, left_edge = c->rbs_left_edge; + struct rbs_area *rbs = c->rbs_area + curr; + int ret; + + bsp = c->bsp; + c->bsp = rse_skip_regs (bsp, nregs); + + if (likely (rbs_contains (rbs, bsp))) + { + /* at least _some_ registers are on rbs... */ + n = rse_num_regs (bsp, rbs->end); + if (likely (n >= nregs)) + { + /* common case #1: all registers are on current rbs... */ + /* got lucky: _all_ registers are on rbs... */ + ia64_loc_t rnat_loc = rbs_get_rnat_loc (rbs, c->bsp); + + *bspstore = c->bsp; + + if (IA64_IS_REG_LOC (rnat_loc)) + { + unw_word_t rnat_addr = (unw_word_t) + tdep_uc_addr (c->as_arg, UNW_IA64_AR_RNAT, NULL); + rnat_loc = IA64_LOC_ADDR (rnat_addr, 0); + } + c->loc[IA64_REG_RNAT] = rnat_loc; + return 0; /* all done */ + } + nregs -= n; /* account for registers already on the rbs */ + + assert (rse_skip_regs (c->bsp, -nregs) == rse_skip_regs (rbs->end, 0)); + } + else + /* Earlier frames also didn't get spilled; need to "loadrs" those, + too... */ + nregs += rse_num_regs (rbs->end, bsp); + + /* OK, we need to copy NREGS registers to the dirty partition. */ + + *bspstore = bsp = rbs->end; + c->loc[IA64_REG_RNAT] = rbs->rnat_loc; + assert (!IA64_IS_REG_LOC (rbs->rnat_loc)); + + dst = dirty_partition; + + while (nregs > 0) + { + if (unlikely (!rbs_contains (rbs, bsp))) + { + /* switch to next non-empty rbs-area: */ + do + { + if (curr == left_edge) + { + Debug (0, "rbs-underflow while flushing %lu regs, " + "bsp=0x%lx, dst=0x%p\n", (unsigned long) nregs, + (unsigned long) bsp, dst); + return -UNW_EBADREG; + } + + assert (rse_num_regs (rbs->end, bsp) == 0); + + curr = (curr + ARRAY_SIZE (c->rbs_area) - 1) + % ARRAY_SIZE (c->rbs_area); + rbs = c->rbs_area + curr; + bsp = rbs->end - rbs->size; + } + while (rbs->size == 0); + + if ((ret = get_rnat (c, rbs, bsp, &src_rnat)) < 0) + return ret; + } + + if (unlikely (rse_is_rnat_slot (bsp))) + { + bsp += 8; + if ((ret = get_rnat (c, rbs, bsp, &src_rnat)) < 0) + return ret; + } + if (unlikely (rse_is_rnat_slot ((unw_word_t) dst))) + { + *dst++ = dst_rnat; + dst_rnat = 0; + } + + src_mask = ((unw_word_t) 1) << rse_slot_num (bsp); + dst_mask = ((unw_word_t) 1) << rse_slot_num ((unw_word_t) dst); + + if (src_rnat & src_mask) + dst_rnat |= dst_mask; + else + dst_rnat &= ~dst_mask; + + /* copy one slot: */ + if ((ret = ia64_get (c, rbs_loc (rbs, bsp), dst)) < 0) + return ret; + + /* advance to next slot: */ + --nregs; + bsp += 8; + ++dst; + } + if (unlikely (rse_is_rnat_slot ((unw_word_t) dst))) + { + /* The LOADRS instruction loads "the N bytes below the current + BSP" but BSP can never point to an RNaT slot so if the last + destination word happens to be an RNaT slot, we need to write + that slot now. */ + *dst++ = dst_rnat; + dst_rnat = 0; + } + *dirty_rnat = dst_rnat; + return (char *) dst - (char *) dirty_partition; +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Greg_states_iterate.c new file mode 100644 index 00000000000000..3570740af157c7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Greg_states_iterate.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + // Needs dwarf support on ia64 + // return dwarf_reg_states_iterate (&c->dwarf, cb, token); + return -UNW_EINVAL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gregs.c new file mode 100644 index 00000000000000..ac6f738a6cdbdb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gregs.c @@ -0,0 +1,612 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include "regs.h" +#include "unwind_i.h" + +static inline ia64_loc_t +linux_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) +{ +#if !defined(UNW_LOCAL_ONLY) || defined(__linux) + unw_word_t addr = c->sigcontext_addr, flags, tmp_addr; + int i; + + if (ia64_get_abi_marker (c) == ABI_MARKER_LINUX_SIGTRAMP + || ia64_get_abi_marker (c) == ABI_MARKER_OLD_LINUX_SIGTRAMP) + { + switch (reg) + { + case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: + case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: + /* Linux sigcontext contains the NaT bit of scratch register + N in bit position N of the sc_nat member. */ + *nat_bitnr = (reg - UNW_IA64_NAT); + addr += LINUX_SC_NAT_OFF; + break; + + case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: + case UNW_IA64_GR + 8 ... UNW_IA64_GR + 31: + addr += LINUX_SC_GR_OFF + 8 * (reg - UNW_IA64_GR); + break; + + case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: + addr += LINUX_SC_FR_OFF + 16 * (reg - UNW_IA64_FR); + return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); + + case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: + if (ia64_get (c, IA64_LOC_ADDR (addr + LINUX_SC_FLAGS_OFF, 0), + &flags) < 0) + return IA64_NULL_LOC; + + if (!(flags & IA64_SC_FLAG_FPH_VALID)) + { + /* initialize fph partition: */ + tmp_addr = addr + LINUX_SC_FR_OFF + 32*16; + for (i = 32; i < 128; ++i, tmp_addr += 16) + if (ia64_putfp (c, IA64_LOC_ADDR (tmp_addr, 0), + unw.read_only.f0) < 0) + return IA64_NULL_LOC; + /* mark fph partition as valid: */ + if (ia64_put (c, IA64_LOC_ADDR (addr + LINUX_SC_FLAGS_OFF, 0), + flags | IA64_SC_FLAG_FPH_VALID) < 0) + return IA64_NULL_LOC; + } + + addr += LINUX_SC_FR_OFF + 16 * (reg - UNW_IA64_FR); + return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); + + case UNW_IA64_BR + 0: addr += LINUX_SC_BR_OFF + 0; break; + case UNW_IA64_BR + 6: addr += LINUX_SC_BR_OFF + 6*8; break; + case UNW_IA64_BR + 7: addr += LINUX_SC_BR_OFF + 7*8; break; + case UNW_IA64_AR_RSC: addr += LINUX_SC_AR_RSC_OFF; break; + case UNW_IA64_AR_CSD: addr += LINUX_SC_AR_CSD_OFF; break; + case UNW_IA64_AR_SSD: addr += LINUX_SC_AR_SSD_OFF; break; + case UNW_IA64_AR_CCV: addr += LINUX_SC_AR_CCV; break; + + default: + if (unw_is_fpreg (reg)) + return IA64_FPREG_LOC (c, reg); + else + return IA64_REG_LOC (c, reg); + } + return IA64_LOC_ADDR (addr, 0); + } + else + { + int is_nat = 0; + + if ((unsigned) (reg - UNW_IA64_NAT) < 128) + { + is_nat = 1; + reg -= (UNW_IA64_NAT - UNW_IA64_GR); + } + if (ia64_get_abi_marker (c) == ABI_MARKER_LINUX_INTERRUPT) + { + switch (reg) + { + case UNW_IA64_BR + 6 ... UNW_IA64_BR + 7: + addr += LINUX_PT_B6_OFF + 8 * (reg - (UNW_IA64_BR + 6)); + break; + + case UNW_IA64_AR_CSD: addr += LINUX_PT_CSD_OFF; break; + case UNW_IA64_AR_SSD: addr += LINUX_PT_SSD_OFF; break; + + case UNW_IA64_GR + 8 ... UNW_IA64_GR + 11: + addr += LINUX_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8)); + break; + + case UNW_IA64_IP: addr += LINUX_PT_IIP_OFF; break; + case UNW_IA64_CFM: addr += LINUX_PT_IFS_OFF; break; + case UNW_IA64_AR_UNAT: addr += LINUX_PT_UNAT_OFF; break; + case UNW_IA64_AR_PFS: addr += LINUX_PT_PFS_OFF; break; + case UNW_IA64_AR_RSC: addr += LINUX_PT_RSC_OFF; break; + case UNW_IA64_AR_RNAT: addr += LINUX_PT_RNAT_OFF; break; + case UNW_IA64_AR_BSPSTORE: addr += LINUX_PT_BSPSTORE_OFF; break; + case UNW_IA64_PR: addr += LINUX_PT_PR_OFF; break; + case UNW_IA64_BR + 0: addr += LINUX_PT_B0_OFF; break; + + case UNW_IA64_GR + 1: + /* The saved r1 value is valid only in the frame in which + it was saved; for everything else we need to look up + the appropriate gp value. */ + if (c->sigcontext_addr != c->sp + 0x10) + return IA64_NULL_LOC; + addr += LINUX_PT_R1_OFF; + break; + + case UNW_IA64_GR + 12: addr += LINUX_PT_R12_OFF; break; + case UNW_IA64_GR + 13: addr += LINUX_PT_R13_OFF; break; + case UNW_IA64_AR_FPSR: addr += LINUX_PT_FPSR_OFF; break; + case UNW_IA64_GR + 15: addr += LINUX_PT_R15_OFF; break; + case UNW_IA64_GR + 14: addr += LINUX_PT_R14_OFF; break; + case UNW_IA64_GR + 2: addr += LINUX_PT_R2_OFF; break; + case UNW_IA64_GR + 3: addr += LINUX_PT_R3_OFF; break; + + case UNW_IA64_GR + 16 ... UNW_IA64_GR + 31: + addr += LINUX_PT_R16_OFF + 8 * (reg - (UNW_IA64_GR + 16)); + break; + + case UNW_IA64_AR_CCV: addr += LINUX_PT_CCV_OFF; break; + + case UNW_IA64_FR + 6 ... UNW_IA64_FR + 11: + addr += LINUX_PT_F6_OFF + 16 * (reg - (UNW_IA64_FR + 6)); + return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); + + default: + if (unw_is_fpreg (reg)) + return IA64_FPREG_LOC (c, reg); + else + return IA64_REG_LOC (c, reg); + } + } + else if (ia64_get_abi_marker (c) == ABI_MARKER_OLD_LINUX_INTERRUPT) + { + switch (reg) + { + case UNW_IA64_GR + 1: + /* The saved r1 value is valid only in the frame in which + it was saved; for everything else we need to look up + the appropriate gp value. */ + if (c->sigcontext_addr != c->sp + 0x10) + return IA64_NULL_LOC; + addr += LINUX_OLD_PT_R1_OFF; + break; + + case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: + addr += LINUX_OLD_PT_R2_OFF + 8 * (reg - (UNW_IA64_GR + 2)); + break; + + case UNW_IA64_GR + 8 ... UNW_IA64_GR + 11: + addr += LINUX_OLD_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8)); + break; + + case UNW_IA64_GR + 16 ... UNW_IA64_GR + 31: + addr += LINUX_OLD_PT_R16_OFF + 8 * (reg - (UNW_IA64_GR + 16)); + break; + + case UNW_IA64_FR + 6 ... UNW_IA64_FR + 9: + addr += LINUX_OLD_PT_F6_OFF + 16 * (reg - (UNW_IA64_FR + 6)); + return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); + + case UNW_IA64_BR + 0: addr += LINUX_OLD_PT_B0_OFF; break; + case UNW_IA64_BR + 6: addr += LINUX_OLD_PT_B6_OFF; break; + case UNW_IA64_BR + 7: addr += LINUX_OLD_PT_B7_OFF; break; + + case UNW_IA64_AR_RSC: addr += LINUX_OLD_PT_RSC_OFF; break; + case UNW_IA64_AR_CCV: addr += LINUX_OLD_PT_CCV_OFF; break; + + default: + if (unw_is_fpreg (reg)) + return IA64_FPREG_LOC (c, reg); + else + return IA64_REG_LOC (c, reg); + } + } + if (is_nat) + { + /* For Linux pt-regs structure, bit number is determined by + the UNaT slot number (as determined by st8.spill) and the + bits are saved wherever the (primary) UNaT was saved. */ + *nat_bitnr = ia64_unat_slot_num (addr); + return c->loc[IA64_REG_PRI_UNAT_MEM]; + } + return IA64_LOC_ADDR (addr, 0); + } +#endif + return IA64_NULL_LOC; +} + +static inline ia64_loc_t +hpux_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) +{ +#if !defined(UNW_LOCAL_ONLY) || defined(__hpux) + return IA64_LOC_UC_REG (reg, c->sigcontext_addr); +#else + return IA64_NULL_LOC; +#endif +} + +HIDDEN ia64_loc_t +ia64_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) +{ + if (c->sigcontext_addr) + { + if (ia64_get_abi (c) == ABI_LINUX) + return linux_scratch_loc (c, reg, nat_bitnr); + else if (ia64_get_abi (c) == ABI_HPUX) + return hpux_scratch_loc (c, reg, nat_bitnr); + else + return IA64_NULL_LOC; + } + else + return IA64_REG_LOC (c, reg); +} + +static inline int +update_nat (struct cursor *c, ia64_loc_t nat_loc, unw_word_t mask, + unw_word_t *valp, int write) +{ + unw_word_t nat_word; + int ret; + + ret = ia64_get (c, nat_loc, &nat_word); + if (ret < 0) + return ret; + + if (write) + { + if (*valp) + nat_word |= mask; + else + nat_word &= ~mask; + ret = ia64_put (c, nat_loc, nat_word); + } + else + *valp = (nat_word & mask) != 0; + return ret; +} + +static int +access_nat (struct cursor *c, + ia64_loc_t nat_loc, ia64_loc_t reg_loc, uint8_t nat_bitnr, + unw_word_t *valp, int write) +{ + unw_word_t mask = 0; + unw_fpreg_t tmp; + int ret; + + if (IA64_IS_FP_LOC (reg_loc)) + { + /* NaT bit is saved as a NaTVal. This happens when a general + register is saved to a floating-point register. */ + if (write) + { + if (*valp) + { + if (ia64_is_big_endian (c)) + ret = ia64_putfp (c, reg_loc, unw.nat_val_be); + else + ret = ia64_putfp (c, reg_loc, unw.nat_val_le); + } + else + { + unw_word_t *src, *dst; + unw_fpreg_t tmp; + + ret = ia64_getfp (c, reg_loc, &tmp); + if (ret < 0) + return ret; + + /* Reset the exponent to 0x1003e so that the significand + will be interpreted as an integer value. */ + src = (unw_word_t *) &unw.int_val_be; + dst = (unw_word_t *) &tmp; + if (!ia64_is_big_endian (c)) + ++src, ++dst; + *dst = *src; + + ret = ia64_putfp (c, reg_loc, tmp); + } + } + else + { + ret = ia64_getfp (c, reg_loc, &tmp); + if (ret < 0) + return ret; + + if (ia64_is_big_endian (c)) + *valp = (memcmp (&tmp, &unw.nat_val_be, sizeof (tmp)) == 0); + else + *valp = (memcmp (&tmp, &unw.nat_val_le, sizeof (tmp)) == 0); + } + return ret; + } + + if ((IA64_IS_REG_LOC (nat_loc) + && (unsigned) (IA64_GET_REG (nat_loc) - UNW_IA64_NAT) < 128) + || IA64_IS_UC_LOC (reg_loc)) + { + if (write) + return ia64_put (c, nat_loc, *valp); + else + return ia64_get (c, nat_loc, valp); + } + + if (IA64_IS_NULL_LOC (nat_loc)) + { + /* NaT bit is not saved. This happens if a general register is + saved to a branch register. Since the NaT bit gets lost, we + need to drop it here, too. Note that if the NaT bit had been + set when the save occurred, it would have caused a NaT + consumption fault. */ + if (write) + { + if (*valp) + return -UNW_EBADREG; /* can't set NaT bit */ + } + else + *valp = 0; + return 0; + } + + mask = (unw_word_t) 1 << nat_bitnr; + return update_nat (c, nat_loc, mask, valp, write); +} + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + ia64_loc_t loc, reg_loc, nat_loc; + unw_word_t mask, val; + uint8_t nat_bitnr; + int ret; + + switch (reg) + { + /* frame registers: */ + + case UNW_IA64_BSP: + if (write) + c->bsp = *valp; + else + *valp = c->bsp; + return 0; + + case UNW_REG_SP: + if (write) + c->sp = *valp; + else + *valp = c->sp; + return 0; + + case UNW_REG_IP: + if (write) + { + c->ip = *valp; /* also update the IP cache */ + if (c->pi_valid && (*valp < c->pi.start_ip || *valp >= c->pi.end_ip)) + c->pi_valid = 0; /* new IP outside of current proc */ + } + loc = c->loc[IA64_REG_IP]; + break; + + /* preserved registers: */ + + case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: + loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_GR + 4))]; + break; + + case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7: + loc = c->loc[IA64_REG_NAT4 + (reg - (UNW_IA64_NAT + 4))]; + reg_loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_NAT + 4))]; + nat_bitnr = c->nat_bitnr[reg - (UNW_IA64_NAT + 4)]; + return access_nat (c, loc, reg_loc, nat_bitnr, valp, write); + + case UNW_IA64_AR_BSP: loc = c->loc[IA64_REG_BSP]; break; + case UNW_IA64_AR_BSPSTORE: loc = c->loc[IA64_REG_BSPSTORE]; break; + case UNW_IA64_AR_PFS: loc = c->loc[IA64_REG_PFS]; break; + case UNW_IA64_AR_RNAT: loc = c->loc[IA64_REG_RNAT]; break; + case UNW_IA64_AR_UNAT: loc = c->loc[IA64_REG_UNAT]; break; + case UNW_IA64_AR_LC: loc = c->loc[IA64_REG_LC]; break; + case UNW_IA64_AR_FPSR: loc = c->loc[IA64_REG_FPSR]; break; + case UNW_IA64_BR + 1: loc = c->loc[IA64_REG_B1]; break; + case UNW_IA64_BR + 2: loc = c->loc[IA64_REG_B2]; break; + case UNW_IA64_BR + 3: loc = c->loc[IA64_REG_B3]; break; + case UNW_IA64_BR + 4: loc = c->loc[IA64_REG_B4]; break; + case UNW_IA64_BR + 5: loc = c->loc[IA64_REG_B5]; break; + + case UNW_IA64_CFM: + if (write) + c->cfm = *valp; /* also update the CFM cache */ + loc = c->cfm_loc; + break; + + case UNW_IA64_PR: + /* + * Note: broad-side access to the predicates is NOT rotated + * (i.e., it is done as if CFM.rrb.pr == 0. + */ + if (write) + { + c->pr = *valp; /* update the predicate cache */ + return ia64_put (c, c->loc[IA64_REG_PR], *valp); + } + else + return ia64_get (c, c->loc[IA64_REG_PR], valp); + + case UNW_IA64_GR + 32 ... UNW_IA64_GR + 127: /* stacked reg */ + reg = rotate_gr (c, reg - UNW_IA64_GR); + if (reg < 0) + return -UNW_EBADREG; + ret = ia64_get_stacked (c, reg, &loc, NULL); + if (ret < 0) + return ret; + break; + + case UNW_IA64_NAT + 32 ... UNW_IA64_NAT + 127: /* stacked reg */ + reg = rotate_gr (c, reg - UNW_IA64_NAT); + if (reg < 0) + return -UNW_EBADREG; + ret = ia64_get_stacked (c, reg, &loc, &nat_loc); + if (ret < 0) + return ret; + assert (!IA64_IS_REG_LOC (loc)); + mask = (unw_word_t) 1 << rse_slot_num (IA64_GET_ADDR (loc)); + return update_nat (c, nat_loc, mask, valp, write); + + case UNW_IA64_AR_EC: + if ((ret = ia64_get (c, c->ec_loc, &val)) < 0) + return ret; + + if (write) + { + val = ((val & ~((unw_word_t) 0x3f << 52)) | ((*valp & 0x3f) << 52)); + return ia64_put (c, c->ec_loc, val); + } + else + { + *valp = (val >> 52) & 0x3f; + return 0; + } + + /* scratch & special registers: */ + + case UNW_IA64_GR + 0: + if (write) + return -UNW_EREADONLYREG; + *valp = 0; + return 0; + + case UNW_IA64_NAT + 0: + if (write) + return -UNW_EREADONLYREG; + *valp = 0; + return 0; + + case UNW_IA64_NAT + 1: + case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: + case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: + loc = ia64_scratch_loc (c, reg, &nat_bitnr); + if (IA64_IS_NULL_LOC (loc) && reg == UNW_IA64_NAT + 1) + { + /* access to GP */ + if (write) + return -UNW_EREADONLYREG; + *valp = 0; + return 0; + } + if (!(IA64_IS_REG_LOC (loc) || IA64_IS_UC_LOC (loc) + || IA64_IS_FP_LOC (loc))) + /* We're dealing with a NaT bit stored in memory. */ + return update_nat(c, loc, (unw_word_t) 1 << nat_bitnr, valp, write); + break; + + case UNW_IA64_GR + 15 ... UNW_IA64_GR + 18: + mask = 1 << (reg - (UNW_IA64_GR + 15)); + if (write) + { + c->eh_args[reg - (UNW_IA64_GR + 15)] = *valp; + c->eh_valid_mask |= mask; + return 0; + } + else if ((c->eh_valid_mask & mask) != 0) + { + *valp = c->eh_args[reg - (UNW_IA64_GR + 15)]; + return 0; + } + else + loc = ia64_scratch_loc (c, reg, NULL); + break; + + case UNW_IA64_GR + 1: /* global pointer */ + case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: + case UNW_IA64_GR + 8 ... UNW_IA64_GR + 14: + case UNW_IA64_GR + 19 ... UNW_IA64_GR + 31: + case UNW_IA64_BR + 0: + case UNW_IA64_BR + 6: + case UNW_IA64_BR + 7: + case UNW_IA64_AR_RSC: + case UNW_IA64_AR_CSD: + case UNW_IA64_AR_SSD: + case UNW_IA64_AR_CCV: + loc = ia64_scratch_loc (c, reg, NULL); + if (IA64_IS_NULL_LOC (loc) && reg == UNW_IA64_GR + 1) + { + /* access to GP */ + if (write) + return -UNW_EREADONLYREG; + + /* ensure c->pi is up-to-date: */ + if ((ret = ia64_make_proc_info (c)) < 0) + return ret; + *valp = c->pi.gp; + return 0; + } + break; + + default: + Debug (1, "bad register number %d\n", reg); + return -UNW_EBADREG; + } + + if (write) + return ia64_put (c, loc, *valp); + else + return ia64_get (c, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, int reg, unw_fpreg_t *valp, + int write) +{ + ia64_loc_t loc; + + switch (reg) + { + case UNW_IA64_FR + 0: + if (write) + return -UNW_EREADONLYREG; + *valp = unw.read_only.f0; + return 0; + + case UNW_IA64_FR + 1: + if (write) + return -UNW_EREADONLYREG; + + if (ia64_is_big_endian (c)) + *valp = unw.read_only.f1_be; + else + *valp = unw.read_only.f1_le; + return 0; + + case UNW_IA64_FR + 2: loc = c->loc[IA64_REG_F2]; break; + case UNW_IA64_FR + 3: loc = c->loc[IA64_REG_F3]; break; + case UNW_IA64_FR + 4: loc = c->loc[IA64_REG_F4]; break; + case UNW_IA64_FR + 5: loc = c->loc[IA64_REG_F5]; break; + + case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: + loc = c->loc[IA64_REG_F16 + (reg - (UNW_IA64_FR + 16))]; + break; + + case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: + loc = ia64_scratch_loc (c, reg, NULL); + break; + + case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: + reg = rotate_fr (c, reg - UNW_IA64_FR) + UNW_IA64_FR; + loc = ia64_scratch_loc (c, reg, NULL); + break; + + default: + Debug (1, "bad register number %d\n", reg); + return -UNW_EBADREG; + } + + if (write) + return ia64_putfp (c, loc, *valp); + else + return ia64_getfp (c, loc, valp); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gresume.c new file mode 100644 index 00000000000000..68fe8a659efa33 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gresume.c @@ -0,0 +1,274 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" +#include "offsets.h" + +#ifndef UNW_REMOTE_ONLY + +static inline int +local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ +#if defined(__linux) + unw_word_t dirty_partition[2048]; /* AR.RSC.LOADRS is a 14-bit field */ + unw_word_t val, sol, sof, pri_unat, n, pfs, bspstore, dirty_rnat; + struct cursor *c = (struct cursor *) cursor; + struct + { + unw_word_t r1; + unw_word_t r4; + unw_word_t r5; + unw_word_t r6; + unw_word_t r7; + unw_word_t r15; + unw_word_t r16; + unw_word_t r17; + unw_word_t r18; + } + extra; + int ret, dirty_size; +# define GET_NAT(n) \ + do \ + { \ + ret = tdep_access_reg (c, UNW_IA64_NAT + (n), &val, 0); \ + if (ret < 0) \ + return ret; \ + if (val) \ + pri_unat |= (unw_word_t) 1 << n; \ + } \ + while (0) + + /* ensure c->pi is up-to-date: */ + if ((ret = ia64_make_proc_info (c)) < 0) + return ret; + + /* Copy contents of r4-r7 into "extra", so that their values end up + contiguous, so we can use a single (primary-) UNaT value. */ + if ((ret = ia64_get (c, c->loc[IA64_REG_R4], &extra.r4)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_R5], &extra.r5)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_R6], &extra.r6)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_R7], &extra.r7)) < 0) + return ret; + + /* Form the primary UNaT value: */ + pri_unat = 0; + GET_NAT (4); GET_NAT(5); + GET_NAT (6); GET_NAT(7); + n = (((uintptr_t) &extra.r4) / 8 - 4) % 64; + pri_unat = (pri_unat << n) | (pri_unat >> (64 - n)); + + if (unlikely (c->sigcontext_addr)) + { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; +# define PR_SCRATCH 0xffc0 /* p6-p15 are scratch */ +# define PR_PRESERVED (~(PR_SCRATCH | 1)) + + /* We're returning to a frame that was (either directly or + indirectly) interrupted by a signal. We have to restore + _both_ "preserved" and "scratch" registers. That doesn't + leave us any registers to work with, and the only way we can + achieve this is by doing a sigreturn(). + + Note: it might be tempting to think that we don't have to + restore the scratch registers when returning to a frame that + was indirectly interrupted by a signal. However, that is not + safe because that frame and its descendants could have been + using a special convention that stores "preserved" state in + scratch registers. For example, the Linux fsyscall + convention does this with r11 (to save ar.pfs) and b6 (to + save "rp"). */ + + sc->sc_gr[12] = c->psp; + c->psp = c->sigcontext_addr - c->sigcontext_off; + + sof = (c->cfm & 0x7f); + if ((dirty_size = rbs_cover_and_flush (c, sof, dirty_partition, + &dirty_rnat, &bspstore)) < 0) + return dirty_size; + + /* Clear the "in-syscall" flag, because in general we won't be + returning to the interruption-point and we need all registers + restored. */ + sc->sc_flags &= ~IA64_SC_FLAG_IN_SYSCALL; + sc->sc_ip = c->ip; + sc->sc_cfm = c->cfm & (((unw_word_t) 1 << 38) - 1); + sc->sc_pr = (c->pr & ~PR_SCRATCH) | (sc->sc_pr & ~PR_PRESERVED); + if ((ret = ia64_get (c, c->loc[IA64_REG_PFS], &sc->sc_ar_pfs)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_FPSR], &sc->sc_ar_fpsr)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_UNAT], &sc->sc_ar_unat)) < 0) + return ret; + + sc->sc_gr[1] = c->pi.gp; + if (c->eh_valid_mask & 0x1) sc->sc_gr[15] = c->eh_args[0]; + if (c->eh_valid_mask & 0x2) sc->sc_gr[16] = c->eh_args[1]; + if (c->eh_valid_mask & 0x4) sc->sc_gr[17] = c->eh_args[2]; + if (c->eh_valid_mask & 0x8) sc->sc_gr[18] = c->eh_args[3]; + Debug (9, "sc: r15=%lx,r16=%lx,r17=%lx,r18=%lx\n", + (long) sc->sc_gr[15], (long) sc->sc_gr[16], + (long) sc->sc_gr[17], (long) sc->sc_gr[18]); + } + else + { + /* Account for the fact that _Uia64_install_context() will + return via br.ret, which will decrement bsp by size-of-locals. */ + if ((ret = ia64_get (c, c->loc[IA64_REG_PFS], &pfs)) < 0) + return ret; + sol = (pfs >> 7) & 0x7f; + if ((dirty_size = rbs_cover_and_flush (c, sol, dirty_partition, + &dirty_rnat, &bspstore)) < 0) + return dirty_size; + + extra.r1 = c->pi.gp; + extra.r15 = c->eh_args[0]; + extra.r16 = c->eh_args[1]; + extra.r17 = c->eh_args[2]; + extra.r18 = c->eh_args[3]; + Debug (9, "extra: r15=%lx,r16=%lx,r17=%lx,r18=%lx\n", + (long) extra.r15, (long) extra.r16, + (long) extra.r17, (long) extra.r18); + } + Debug (8, "resuming at ip=%lx\n", (long) c->ip); + ia64_install_cursor (c, pri_unat, (unw_word_t *) &extra, + bspstore, dirty_size, dirty_partition + dirty_size/8, + dirty_rnat); +#elif defined(__hpux) + struct cursor *c = (struct cursor *) cursor; + + setcontext (c->as_arg); /* should not return */ +#endif + return -UNW_EINVAL; +} + +HIDDEN int +ia64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + return local_resume (as, cursor, arg); +} + +#endif /* !UNW_REMOTE_ONLY */ + +#ifndef UNW_LOCAL_ONLY + +static inline int +remote_install_cursor (struct cursor *c) +{ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int write, void *); + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int write, void *); + unw_fpreg_t fpval; + unw_word_t val; + int reg; + +#if defined(__linux) && !defined(UNW_REMOTE_ONLY) + if (c->as == unw_local_addr_space) + { + /* Take a short-cut: we directly resume out of the cursor and + all we need to do is make sure that all locations point to + memory, not registers. Furthermore, R4-R7 and NAT4-NAT7 are + taken care of by ia64_local_resume() so they don't need to be + handled here. */ +# define MEMIFY(preg, reg) \ + do { \ + if (IA64_IS_REG_LOC (c->loc[(preg)])) \ + c->loc[(preg)] = IA64_LOC_ADDR ((unw_word_t) \ + tdep_uc_addr(c->as_arg, (reg), \ + NULL), 0); \ + } while (0) + MEMIFY (IA64_REG_PR, UNW_IA64_PR); + MEMIFY (IA64_REG_PFS, UNW_IA64_AR_PFS); + MEMIFY (IA64_REG_RNAT, UNW_IA64_AR_RNAT); + MEMIFY (IA64_REG_UNAT, UNW_IA64_AR_UNAT); + MEMIFY (IA64_REG_LC, UNW_IA64_AR_LC); + MEMIFY (IA64_REG_FPSR, UNW_IA64_AR_FPSR); + MEMIFY (IA64_REG_IP, UNW_IA64_BR + 0); + MEMIFY (IA64_REG_B1, UNW_IA64_BR + 1); + MEMIFY (IA64_REG_B2, UNW_IA64_BR + 2); + MEMIFY (IA64_REG_B3, UNW_IA64_BR + 3); + MEMIFY (IA64_REG_B4, UNW_IA64_BR + 4); + MEMIFY (IA64_REG_B5, UNW_IA64_BR + 5); + MEMIFY (IA64_REG_F2, UNW_IA64_FR + 2); + MEMIFY (IA64_REG_F3, UNW_IA64_FR + 3); + MEMIFY (IA64_REG_F4, UNW_IA64_FR + 4); + MEMIFY (IA64_REG_F5, UNW_IA64_FR + 5); + MEMIFY (IA64_REG_F16, UNW_IA64_FR + 16); + MEMIFY (IA64_REG_F17, UNW_IA64_FR + 17); + MEMIFY (IA64_REG_F18, UNW_IA64_FR + 18); + MEMIFY (IA64_REG_F19, UNW_IA64_FR + 19); + MEMIFY (IA64_REG_F20, UNW_IA64_FR + 20); + MEMIFY (IA64_REG_F21, UNW_IA64_FR + 21); + MEMIFY (IA64_REG_F22, UNW_IA64_FR + 22); + MEMIFY (IA64_REG_F23, UNW_IA64_FR + 23); + MEMIFY (IA64_REG_F24, UNW_IA64_FR + 24); + MEMIFY (IA64_REG_F25, UNW_IA64_FR + 25); + MEMIFY (IA64_REG_F26, UNW_IA64_FR + 26); + MEMIFY (IA64_REG_F27, UNW_IA64_FR + 27); + MEMIFY (IA64_REG_F28, UNW_IA64_FR + 28); + MEMIFY (IA64_REG_F29, UNW_IA64_FR + 29); + MEMIFY (IA64_REG_F30, UNW_IA64_FR + 30); + MEMIFY (IA64_REG_F31, UNW_IA64_FR + 31); + } + else +#endif /* __linux && !UNW_REMOTE_ONLY */ + { + access_reg = c->as->acc.access_reg; + access_fpreg = c->as->acc.access_fpreg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + (*access_fpreg) (c->as, reg, &fpval, 1, c->as_arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + (*access_reg) (c->as, reg, &val, 1, c->as_arg); + } + } + } + return (*c->as->acc.resume) (c->as, (unw_cursor_t *) c, c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->ip); + +#ifdef UNW_LOCAL_ONLY + return local_resume (c->as, cursor, c->as_arg); +#else + return remote_install_cursor (c); +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gscript.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gscript.c new file mode 100644 index 00000000000000..526aeaf299edc3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gscript.c @@ -0,0 +1,765 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include "regs.h" +#include "unwind_i.h" + +enum ia64_script_insn_opcode + { + IA64_INSN_INC_PSP, /* psp += val */ + IA64_INSN_LOAD_PSP, /* psp = *psp_loc */ + IA64_INSN_ADD_PSP, /* s[dst] = (s.psp + val) */ + IA64_INSN_ADD_PSP_NAT, /* like above, but with NaT info */ + IA64_INSN_ADD_SP, /* s[dst] = (s.sp + val) */ + IA64_INSN_ADD_SP_NAT, /* like above, but with NaT info */ + IA64_INSN_MOVE, /* s[dst] = s[val] */ + IA64_INSN_MOVE_NAT, /* like above, but with NaT info */ + IA64_INSN_MOVE_NO_NAT, /* like above, but clear NaT info */ + IA64_INSN_MOVE_STACKED, /* s[dst] = rse_skip(*s.bsp_loc, val) */ + IA64_INSN_MOVE_STACKED_NAT, /* like above, but with NaT info */ + IA64_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */ + IA64_INSN_MOVE_SCRATCH_NAT, /* like above, but with NaT info */ + IA64_INSN_MOVE_SCRATCH_NO_NAT /* like above, but clear NaT info */ + }; + +#if defined(HAVE___THREAD) && HAVE___THREAD +static __thread struct ia64_script_cache ia64_per_thread_cache = + { +#ifdef HAVE_ATOMIC_OPS_H + .busy = AO_TS_INITIALIZER +#else + .lock = PTHREAD_MUTEX_INITIALIZER +#endif + }; +#endif + +static inline unw_hash_index_t CONST_ATTR +hash (unw_word_t ip) +{ + /* based on (sqrt(5)/2-1)*2^64 */ +# define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL) + + return (ip >> 4) * magic >> (64 - IA64_LOG_UNW_HASH_SIZE); +} + +static inline long +cache_match (struct ia64_script *script, unw_word_t ip, unw_word_t pr) +{ + if (ip == script->ip && ((pr ^ script->pr_val) & script->pr_mask) == 0) + return 1; + return 0; +} + +static inline void +flush_script_cache (struct ia64_script_cache *cache) +{ + int i; + + cache->lru_head = IA64_UNW_CACHE_SIZE - 1; + cache->lru_tail = 0; + + for (i = 0; i < IA64_UNW_CACHE_SIZE; ++i) + { + if (i > 0) + cache->buckets[i].lru_chain = (i - 1); + cache->buckets[i].coll_chain = -1; + cache->buckets[i].ip = 0; + } + for (i = 0; ihash[i] = -1; +} + +static inline struct ia64_script_cache * +get_script_cache (unw_addr_space_t as, intrmask_t *saved_maskp) +{ + struct ia64_script_cache *cache = &as->global_cache; + unw_caching_policy_t caching = as->caching_policy; + + if (caching == UNW_CACHE_NONE) + return NULL; + +#ifdef HAVE_ATOMIC_H + if (!spin_trylock_irqsave (&cache->busy, *saved_maskp)) + return NULL; +#else +# if defined(HAVE___THREAD) && HAVE___THREAD + if (as->caching_policy == UNW_CACHE_PER_THREAD) + cache = &ia64_per_thread_cache; +# endif +# ifdef HAVE_ATOMIC_OPS_H + if (AO_test_and_set (&cache->busy) == AO_TS_SET) + return NULL; +# else + if (likely (caching == UNW_CACHE_GLOBAL)) + { + Debug (16, "acquiring lock\n"); + lock_acquire (&cache->lock, *saved_maskp); + } +# endif +#endif + + if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation)) + { + flush_script_cache (cache); + cache->generation = as->cache_generation; + } + return cache; +} + +static inline void +put_script_cache (unw_addr_space_t as, struct ia64_script_cache *cache, + intrmask_t *saved_maskp) +{ + assert (as->caching_policy != UNW_CACHE_NONE); + + Debug (16, "unmasking signals/interrupts and releasing lock\n"); +#ifdef HAVE_ATOMIC_H + spin_unlock_irqrestore (&cache->busy, *saved_maskp); +#else +# ifdef HAVE_ATOMIC_OPS_H + AO_CLEAR (&cache->busy); +# else + if (likely (as->caching_policy == UNW_CACHE_GLOBAL)) + lock_release (&cache->lock, *saved_maskp); +# endif +#endif +} + +static struct ia64_script * +script_lookup (struct ia64_script_cache *cache, struct cursor *c) +{ + struct ia64_script *script = cache->buckets + c->hint; + unsigned short index; + unw_word_t ip, pr; + + ip = c->ip; + pr = c->pr; + + if (cache_match (script, ip, pr)) + return script; + + index = cache->hash[hash (ip)]; + if (index >= IA64_UNW_CACHE_SIZE) + return 0; + + script = cache->buckets + index; + while (1) + { + if (cache_match (script, ip, pr)) + { + /* update hint; no locking needed: single-word writes are atomic */ + c->hint = cache->buckets[c->prev_script].hint = + (script - cache->buckets); + return script; + } + if (script->coll_chain >= IA64_UNW_HASH_SIZE) + return 0; + script = cache->buckets + script->coll_chain; + } +} + +static inline void +script_init (struct ia64_script *script, unw_word_t ip) +{ + script->ip = ip; + script->hint = 0; + script->count = 0; + script->abi_marker = 0; +} + +static inline struct ia64_script * +script_new (struct ia64_script_cache *cache, unw_word_t ip) +{ + struct ia64_script *script, *prev, *tmp; + unw_hash_index_t index; + unsigned short head; + + head = cache->lru_head; + script = cache->buckets + head; + cache->lru_head = script->lru_chain; + + /* re-insert script at the tail of the LRU chain: */ + cache->buckets[cache->lru_tail].lru_chain = head; + cache->lru_tail = head; + + /* remove the old script from the hash table (if it's there): */ + if (script->ip) + { + index = hash (script->ip); + tmp = cache->buckets + cache->hash[index]; + prev = 0; + while (1) + { + if (tmp == script) + { + if (prev) + prev->coll_chain = tmp->coll_chain; + else + cache->hash[index] = tmp->coll_chain; + break; + } + else + prev = tmp; + if (tmp->coll_chain >= IA64_UNW_CACHE_SIZE) + /* old script wasn't in the hash-table */ + break; + tmp = cache->buckets + tmp->coll_chain; + } + } + + /* enter new script in the hash table */ + index = hash (ip); + script->coll_chain = cache->hash[index]; + cache->hash[index] = script - cache->buckets; + + script_init (script, ip); + return script; +} + +static inline void +script_finalize (struct ia64_script *script, struct cursor *c, + struct ia64_state_record *sr) +{ + script->pr_mask = sr->pr_mask; + script->pr_val = sr->pr_val; + script->pi = c->pi; +} + +static inline void +script_emit (struct ia64_script *script, struct ia64_script_insn insn) +{ + if (script->count >= IA64_MAX_SCRIPT_LEN) + { + Dprintf ("%s: script exceeds maximum size of %u instructions!\n", + __FUNCTION__, IA64_MAX_SCRIPT_LEN); + return; + } + script->insn[script->count++] = insn; +} + +static void +compile_reg (struct ia64_state_record *sr, int i, struct ia64_reg_info *r, + struct ia64_script *script) +{ + enum ia64_script_insn_opcode opc; + unsigned long val, rval; + struct ia64_script_insn insn; + long is_preserved_gr; + + if (r->where == IA64_WHERE_NONE || r->when >= sr->when_target) + return; + + opc = IA64_INSN_MOVE; + val = rval = r->val; + is_preserved_gr = (i >= IA64_REG_R4 && i <= IA64_REG_R7); + + if (r->where == IA64_WHERE_GR) + { + /* Handle most common case first... */ + if (rval >= 32) + { + /* register got spilled to a stacked register */ + if (is_preserved_gr) + opc = IA64_INSN_MOVE_STACKED_NAT; + else + opc = IA64_INSN_MOVE_STACKED; + val = rval; + } + else if (rval >= 4 && rval <= 7) + { + /* register got spilled to a preserved register */ + val = IA64_REG_R4 + (rval - 4); + if (is_preserved_gr) + opc = IA64_INSN_MOVE_NAT; + } + else + { + /* register got spilled to a scratch register */ + if (is_preserved_gr) + opc = IA64_INSN_MOVE_SCRATCH_NAT; + else + opc = IA64_INSN_MOVE_SCRATCH; + val = UNW_IA64_GR + rval; + } + } + else + { + switch (r->where) + { + case IA64_WHERE_FR: + /* Note: There is no need to handle NaT-bit info here + (indepent of is_preserved_gr), because for floating-point + NaTs are represented as NaTVal, so the NaT-info never + needs to be consulated. */ + if (rval >= 2 && rval <= 5) + val = IA64_REG_F2 + (rval - 2); + else if (rval >= 16 && rval <= 31) + val = IA64_REG_F16 + (rval - 16); + else + { + opc = IA64_INSN_MOVE_SCRATCH; + val = UNW_IA64_FR + rval; + } + break; + + case IA64_WHERE_BR: + if (rval >= 1 && rval <= 5) + { + val = IA64_REG_B1 + (rval - 1); + if (is_preserved_gr) + opc = IA64_INSN_MOVE_NO_NAT; + } + else + { + opc = IA64_INSN_MOVE_SCRATCH; + if (is_preserved_gr) + opc = IA64_INSN_MOVE_SCRATCH_NO_NAT; + val = UNW_IA64_BR + rval; + } + break; + + case IA64_WHERE_SPREL: + if (is_preserved_gr) + opc = IA64_INSN_ADD_SP_NAT; + else + { + opc = IA64_INSN_ADD_SP; + if (i >= IA64_REG_F2 && i <= IA64_REG_F31) + val |= IA64_LOC_TYPE_FP; + } + break; + + case IA64_WHERE_PSPREL: + if (is_preserved_gr) + opc = IA64_INSN_ADD_PSP_NAT; + else + { + opc = IA64_INSN_ADD_PSP; + if (i >= IA64_REG_F2 && i <= IA64_REG_F31) + val |= IA64_LOC_TYPE_FP; + } + break; + + default: + Dprintf ("%s: register %u has unexpected `where' value of %u\n", + __FUNCTION__, i, r->where); + break; + } + } + insn.opc = opc; + insn.dst = i; + insn.val = val; + script_emit (script, insn); + + if (i == IA64_REG_PSP) + { + /* c->psp must contain the _value_ of the previous sp, not it's + save-location. We get this by dereferencing the value we + just stored in loc[IA64_REG_PSP]: */ + insn.opc = IA64_INSN_LOAD_PSP; + script_emit (script, insn); + } +} + +/* Sort the registers which got saved in decreasing order of WHEN + value. This is needed to ensure that the save-locations are + updated in the proper order. For example, suppose r4 gets spilled + to memory and then r5 gets saved in r4. In this case, we need to + update the save location of r5 before the one of r4. */ + +static inline int +sort_regs (struct ia64_state_record *sr, int regorder[]) +{ + int r, i, j, max, max_reg, max_when, num_regs = 0; + + assert (IA64_REG_BSP == 3); + + for (r = IA64_REG_BSP; r < IA64_NUM_PREGS; ++r) + { + if (sr->curr.reg[r].where == IA64_WHERE_NONE + || sr->curr.reg[r].when >= sr->when_target) + continue; + + regorder[num_regs++] = r; + } + + /* Simple insertion-sort. Involves about N^2/2 comparisons and N + exchanges. N is often small (say, 2-5) so a fancier sorting + algorithm may not be worthwhile. */ + + for (i = max = 0; i < num_regs - 1; ++i) + { + max_reg = regorder[max]; + max_when = sr->curr.reg[max_reg].when; + + for (j = i + 1; j < num_regs; ++j) + if (sr->curr.reg[regorder[j]].when > max_when) + { + max = j; + max_reg = regorder[j]; + max_when = sr->curr.reg[max_reg].when; + } + if (i != max) + { + regorder[max] = regorder[i]; + regorder[i] = max_reg; + } + } + return num_regs; +} + +/* Build an unwind script that unwinds from state OLD_STATE to the + entrypoint of the function that called OLD_STATE. */ + +static inline int +build_script (struct cursor *c, struct ia64_script *script) +{ + int num_regs, i, ret, regorder[IA64_NUM_PREGS - 3]; + struct ia64_reg_info *pri_unat; + struct ia64_state_record sr; + struct ia64_script_insn insn; + + ret = ia64_create_state_record (c, &sr); + if (ret < 0) + return ret; + + /* First, compile the update for IA64_REG_PSP. This is important + because later save-locations may depend on it's correct (updated) + value. Fixed-size frames are handled specially and variable-size + frames get handled via the normal compile_reg(). */ + + if (sr.when_target > sr.curr.reg[IA64_REG_PSP].when + && (sr.curr.reg[IA64_REG_PSP].where == IA64_WHERE_NONE) + && sr.curr.reg[IA64_REG_PSP].val != 0) + { + /* new psp is psp plus frame size */ + insn.opc = IA64_INSN_INC_PSP; + insn.val = sr.curr.reg[IA64_REG_PSP].val; /* frame size */ + script_emit (script, insn); + } + else + compile_reg (&sr, IA64_REG_PSP, sr.curr.reg + IA64_REG_PSP, script); + + /* Second, compile the update for the primary UNaT, if any: */ + + if (sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_GR].when + || sr.when_target >= sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when) + { + if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_GR].when) + /* (primary) NaT bits were saved to memory only */ + pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM; + else if (sr.when_target < sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when) + /* (primary) NaT bits were saved to a register only */ + pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_GR; + else if (sr.curr.reg[IA64_REG_PRI_UNAT_MEM].when > + sr.curr.reg[IA64_REG_PRI_UNAT_GR].when) + /* (primary) NaT bits were last saved to memory */ + pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_MEM; + else + /* (primary) NaT bits were last saved to a register */ + pri_unat = sr.curr.reg + IA64_REG_PRI_UNAT_GR; + + /* Note: we always store the final primary-UNaT location in UNAT_MEM. */ + compile_reg (&sr, IA64_REG_PRI_UNAT_MEM, pri_unat, script); + } + + /* Third, compile the other register in decreasing order of WHEN values. */ + + num_regs = sort_regs (&sr, regorder); + for (i = 0; i < num_regs; ++i) + compile_reg (&sr, regorder[i], sr.curr.reg + regorder[i], script); + + script->abi_marker = sr.abi_marker; + script_finalize (script, c, &sr); + + ia64_free_state_record (&sr); + return 0; +} + +static inline void +set_nat_info (struct cursor *c, unsigned long dst, + ia64_loc_t nat_loc, uint8_t bitnr) +{ + assert (dst >= IA64_REG_R4 && dst <= IA64_REG_R7); + + c->loc[dst - IA64_REG_R4 + IA64_REG_NAT4] = nat_loc; + c->nat_bitnr[dst - IA64_REG_R4] = bitnr; +} + +/* Apply the unwinding actions represented by OPS and update SR to + reflect the state that existed upon entry to the function that this + unwinder represents. */ + +static inline int +run_script (struct ia64_script *script, struct cursor *c) +{ + struct ia64_script_insn *ip, *limit, next_insn; + ia64_loc_t loc, nat_loc; + unsigned long opc, dst; + uint8_t nat_bitnr; + unw_word_t val; + int ret; + + c->pi = script->pi; + ip = script->insn; + limit = script->insn + script->count; + next_insn = *ip; + c->abi_marker = script->abi_marker; + + while (ip++ < limit) + { + opc = next_insn.opc; + dst = next_insn.dst; + val = next_insn.val; + next_insn = *ip; + + /* This is by far the most common operation: */ + if (likely (opc == IA64_INSN_MOVE_STACKED)) + { + if ((ret = ia64_get_stacked (c, val, &loc, NULL)) < 0) + return ret; + } + else + switch (opc) + { + case IA64_INSN_INC_PSP: + c->psp += val; + continue; + + case IA64_INSN_LOAD_PSP: + if ((ret = ia64_get (c, c->loc[IA64_REG_PSP], &c->psp)) < 0) + return ret; + continue; + + case IA64_INSN_ADD_PSP: + loc = IA64_LOC_ADDR (c->psp + val, (val & IA64_LOC_TYPE_FP)); + break; + + case IA64_INSN_ADD_SP: + loc = IA64_LOC_ADDR (c->sp + val, (val & IA64_LOC_TYPE_FP)); + break; + + case IA64_INSN_MOVE_NO_NAT: + set_nat_info (c, dst, IA64_NULL_LOC, 0); + case IA64_INSN_MOVE: + loc = c->loc[val]; + break; + + case IA64_INSN_MOVE_SCRATCH_NO_NAT: + set_nat_info (c, dst, IA64_NULL_LOC, 0); + case IA64_INSN_MOVE_SCRATCH: + loc = ia64_scratch_loc (c, val, NULL); + break; + + case IA64_INSN_ADD_PSP_NAT: + loc = IA64_LOC_ADDR (c->psp + val, 0); + assert (!IA64_IS_REG_LOC (loc)); + set_nat_info (c, dst, + c->loc[IA64_REG_PRI_UNAT_MEM], + ia64_unat_slot_num (IA64_GET_ADDR (loc))); + break; + + case IA64_INSN_ADD_SP_NAT: + loc = IA64_LOC_ADDR (c->sp + val, 0); + assert (!IA64_IS_REG_LOC (loc)); + set_nat_info (c, dst, + c->loc[IA64_REG_PRI_UNAT_MEM], + ia64_unat_slot_num (IA64_GET_ADDR (loc))); + break; + + case IA64_INSN_MOVE_NAT: + loc = c->loc[val]; + set_nat_info (c, dst, + c->loc[val - IA64_REG_R4 + IA64_REG_NAT4], + c->nat_bitnr[val - IA64_REG_R4]); + break; + + case IA64_INSN_MOVE_STACKED_NAT: + if ((ret = ia64_get_stacked (c, val, &loc, &nat_loc)) < 0) + return ret; + assert (!IA64_IS_REG_LOC (loc)); + set_nat_info (c, dst, nat_loc, rse_slot_num (IA64_GET_ADDR (loc))); + break; + + case IA64_INSN_MOVE_SCRATCH_NAT: + loc = ia64_scratch_loc (c, val, NULL); + nat_loc = ia64_scratch_loc (c, val + (UNW_IA64_NAT - UNW_IA64_GR), + &nat_bitnr); + set_nat_info (c, dst, nat_loc, nat_bitnr); + break; + } + c->loc[dst] = loc; + } + return 0; +} + +static int +uncached_find_save_locs (struct cursor *c) +{ + struct ia64_script script; + int ret = 0; + + if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0) + return ret; + + script_init (&script, c->ip); + if ((ret = build_script (c, &script)) < 0) + { + if (ret != -UNW_ESTOPUNWIND) + Dprintf ("%s: failed to build unwind script for ip %lx\n", + __FUNCTION__, (long) c->ip); + return ret; + } + return run_script (&script, c); +} + +HIDDEN int +ia64_find_save_locs (struct cursor *c) +{ + struct ia64_script_cache *cache = NULL; + struct ia64_script *script = NULL; + intrmask_t saved_mask; + int ret = 0; + + if (c->as->caching_policy == UNW_CACHE_NONE) + return uncached_find_save_locs (c); + + cache = get_script_cache (c->as, &saved_mask); + if (!cache) + { + Debug (1, "contention on script-cache; doing uncached lookup\n"); + return uncached_find_save_locs (c); + } + { + script = script_lookup (cache, c); + Debug (8, "ip %lx %s in script cache\n", (long) c->ip, + script ? "hit" : "missed"); + + if (!script || (script->count == 0 && !script->pi.unwind_info)) + { + if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0) + goto out; + } + + if (!script) + { + script = script_new (cache, c->ip); + if (!script) + { + Dprintf ("%s: failed to create unwind script\n", __FUNCTION__); + ret = -UNW_EUNSPEC; + goto out; + } + } + cache->buckets[c->prev_script].hint = script - cache->buckets; + + if (script->count == 0) + ret = build_script (c, script); + + assert (script->count > 0); + + c->hint = script->hint; + c->prev_script = script - cache->buckets; + + if (ret < 0) + { + if (ret != -UNW_ESTOPUNWIND) + Dprintf ("%s: failed to locate/build unwind script for ip %lx\n", + __FUNCTION__, (long) c->ip); + goto out; + } + + ret = run_script (script, c); + } + out: + put_script_cache (c->as, cache, &saved_mask); + return ret; +} + +HIDDEN void +ia64_validate_cache (unw_addr_space_t as, void *arg) +{ +#ifndef UNW_REMOTE_ONLY + if (as == unw_local_addr_space && ia64_local_validate_cache (as, arg) == 1) + return; +#endif + +#ifndef UNW_LOCAL_ONLY + /* local info is up-to-date, check dynamic info. */ + unwi_dyn_validate_cache (as, arg); +#endif +} + +HIDDEN int +ia64_cache_proc_info (struct cursor *c) +{ + struct ia64_script_cache *cache; + struct ia64_script *script; + intrmask_t saved_mask; + int ret = 0; + + cache = get_script_cache (c->as, &saved_mask); + if (!cache) + return ret; /* cache is busy */ + + /* Re-check to see if a cache entry has been added in the meantime: */ + script = script_lookup (cache, c); + if (script) + goto out; + + script = script_new (cache, c->ip); + if (!script) + { + Dprintf ("%s: failed to create unwind script\n", __FUNCTION__); + ret = -UNW_EUNSPEC; + goto out; + } + + script->pi = c->pi; + + out: + put_script_cache (c->as, cache, &saved_mask); + return ret; +} + +HIDDEN int +ia64_get_cached_proc_info (struct cursor *c) +{ + struct ia64_script_cache *cache; + struct ia64_script *script; + intrmask_t saved_mask; + + cache = get_script_cache (c->as, &saved_mask); + if (!cache) + return -UNW_ENOINFO; /* cache is busy */ + { + script = script_lookup (cache, c); + if (script) + c->pi = script->pi; + } + put_script_cache (c->as, cache, &saved_mask); + return script ? 0 : -UNW_ENOINFO; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gstep.c new file mode 100644 index 00000000000000..df4ecb8796c6e8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gstep.c @@ -0,0 +1,359 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include "unwind_i.h" + +static inline int +linux_sigtramp (struct cursor *c, ia64_loc_t prev_cfm_loc, + unw_word_t *num_regsp) +{ +#if defined(UNW_LOCAL_ONLY) && !defined(__linux) + return -UNW_EINVAL; +#else + unw_word_t sc_addr; + int ret; + + if ((ret = ia64_get (c, IA64_LOC_ADDR (c->sp + 0x10 + + LINUX_SIGFRAME_ARG2_OFF, 0), + &sc_addr)) < 0) + return ret; + + c->sigcontext_addr = sc_addr; + + if (!IA64_IS_REG_LOC (c->loc[IA64_REG_IP]) + && IA64_GET_ADDR (c->loc[IA64_REG_IP]) == sc_addr + LINUX_SC_BR_OFF + 8) + { + /* Linux kernels before 2.4.19 and 2.5.10 had buggy + unwind info for sigtramp. Fix it up here. */ + c->loc[IA64_REG_IP] = IA64_LOC_ADDR (sc_addr + LINUX_SC_IP_OFF, 0); + c->cfm_loc = IA64_LOC_ADDR (sc_addr + LINUX_SC_CFM_OFF, 0); + } + + /* do what can't be described by unwind directives: */ + c->loc[IA64_REG_PFS] = IA64_LOC_ADDR (sc_addr + LINUX_SC_AR_PFS_OFF, 0); + c->ec_loc = prev_cfm_loc; + *num_regsp = c->cfm & 0x7f; /* size of frame */ + return 0; +#endif +} + +static inline int +linux_interrupt (struct cursor *c, ia64_loc_t prev_cfm_loc, + unw_word_t *num_regsp, int marker) +{ +#if defined(UNW_LOCAL_ONLY) && !(defined(__linux) && defined(__KERNEL__)) + return -UNW_EINVAL; +#else + unw_word_t sc_addr, num_regs; + ia64_loc_t pfs_loc; + + sc_addr = c->sigcontext_addr = c->sp + 0x10; + + if ((c->pr & (1UL << LINUX_PT_P_NONSYS)) != 0) + num_regs = c->cfm & 0x7f; + else + num_regs = 0; + + /* do what can't be described by unwind directives: */ + if (marker == ABI_MARKER_OLD_LINUX_INTERRUPT) + pfs_loc = IA64_LOC_ADDR (sc_addr + LINUX_OLD_PT_PFS_OFF, 0); + else + pfs_loc = IA64_LOC_ADDR (sc_addr + LINUX_PT_PFS_OFF, 0); + c->loc[IA64_REG_PFS] = pfs_loc; + c->ec_loc = prev_cfm_loc; + *num_regsp = num_regs; /* size of frame */ + return 0; +#endif +} + +static inline int +hpux_sigtramp (struct cursor *c, ia64_loc_t prev_cfm_loc, + unw_word_t *num_regsp) +{ +#if defined(UNW_LOCAL_ONLY) && !defined(__hpux) + return -UNW_EINVAL; +#else + unw_word_t sc_addr, bsp, bspstore; + ia64_loc_t sc_loc; + int ret, i; + + /* HP-UX passes the address of ucontext_t in r32: */ + if ((ret = ia64_get_stacked (c, 32, &sc_loc, NULL)) < 0) + return ret; + if ((ret = ia64_get (c, sc_loc, &sc_addr)) < 0) + return ret; + + c->sigcontext_addr = sc_addr; + + /* Now mark all (preserved) registers as coming from the + signal context: */ + c->cfm_loc = IA64_LOC_UC_REG (UNW_IA64_CFM, sc_addr); + c->loc[IA64_REG_PRI_UNAT_MEM] = IA64_NULL_LOC; + c->loc[IA64_REG_PSP] = IA64_LOC_UC_REG (UNW_IA64_GR + 12, sc_addr); + c->loc[IA64_REG_BSP] = IA64_LOC_UC_REG (UNW_IA64_AR_BSP, sc_addr); + c->loc[IA64_REG_BSPSTORE] = IA64_LOC_UC_REG (UNW_IA64_AR_BSPSTORE, sc_addr); + c->loc[IA64_REG_PFS] = IA64_LOC_UC_REG (UNW_IA64_AR_PFS, sc_addr); + c->loc[IA64_REG_RNAT] = IA64_LOC_UC_REG (UNW_IA64_AR_RNAT, sc_addr); + c->loc[IA64_REG_IP] = IA64_LOC_UC_REG (UNW_IA64_IP, sc_addr); + c->loc[IA64_REG_R4] = IA64_LOC_UC_REG (UNW_IA64_GR + 4, sc_addr); + c->loc[IA64_REG_R5] = IA64_LOC_UC_REG (UNW_IA64_GR + 5, sc_addr); + c->loc[IA64_REG_R6] = IA64_LOC_UC_REG (UNW_IA64_GR + 6, sc_addr); + c->loc[IA64_REG_R7] = IA64_LOC_UC_REG (UNW_IA64_GR + 7, sc_addr); + c->loc[IA64_REG_NAT4] = IA64_LOC_UC_REG (UNW_IA64_NAT + 4, sc_addr); + c->loc[IA64_REG_NAT5] = IA64_LOC_UC_REG (UNW_IA64_NAT + 5, sc_addr); + c->loc[IA64_REG_NAT6] = IA64_LOC_UC_REG (UNW_IA64_NAT + 6, sc_addr); + c->loc[IA64_REG_NAT7] = IA64_LOC_UC_REG (UNW_IA64_NAT + 7, sc_addr); + c->loc[IA64_REG_UNAT] = IA64_LOC_UC_REG (UNW_IA64_AR_UNAT, sc_addr); + c->loc[IA64_REG_PR] = IA64_LOC_UC_REG (UNW_IA64_PR, sc_addr); + c->loc[IA64_REG_LC] = IA64_LOC_UC_REG (UNW_IA64_AR_LC, sc_addr); + c->loc[IA64_REG_FPSR] = IA64_LOC_UC_REG (UNW_IA64_AR_FPSR, sc_addr); + c->loc[IA64_REG_B1] = IA64_LOC_UC_REG (UNW_IA64_BR + 1, sc_addr); + c->loc[IA64_REG_B2] = IA64_LOC_UC_REG (UNW_IA64_BR + 2, sc_addr); + c->loc[IA64_REG_B3] = IA64_LOC_UC_REG (UNW_IA64_BR + 3, sc_addr); + c->loc[IA64_REG_B4] = IA64_LOC_UC_REG (UNW_IA64_BR + 4, sc_addr); + c->loc[IA64_REG_B5] = IA64_LOC_UC_REG (UNW_IA64_BR + 5, sc_addr); + c->loc[IA64_REG_F2] = IA64_LOC_UC_REG (UNW_IA64_FR + 2, sc_addr); + c->loc[IA64_REG_F3] = IA64_LOC_UC_REG (UNW_IA64_FR + 3, sc_addr); + c->loc[IA64_REG_F4] = IA64_LOC_UC_REG (UNW_IA64_FR + 4, sc_addr); + c->loc[IA64_REG_F5] = IA64_LOC_UC_REG (UNW_IA64_FR + 5, sc_addr); + for (i = 0; i < 16; ++i) + c->loc[IA64_REG_F16 + i] = IA64_LOC_UC_REG (UNW_IA64_FR + 16 + i, sc_addr); + + c->pi.flags |= UNW_PI_FLAG_IA64_RBS_SWITCH; + + /* update the CFM cache: */ + if ((ret = ia64_get (c, c->cfm_loc, &c->cfm)) < 0) + return ret; + /* update the PSP cache: */ + if ((ret = ia64_get (c, c->loc[IA64_REG_PSP], &c->psp)) < 0) + return ret; + + if ((ret = ia64_get (c, c->loc[IA64_REG_BSP], &bsp)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_BSPSTORE], &bspstore)) < 0) + return ret; + if (bspstore < bsp) + /* Dirty partition got spilled into the ucontext_t structure + itself. We'll need to access it via uc_access(3). */ + rbs_switch (c, bsp, bspstore, IA64_LOC_UC_ADDR (bsp | 0x1f8, 0)); + + c->ec_loc = prev_cfm_loc; + + *num_regsp = 0; + return 0; +#endif +} + + +static inline int +check_rbs_switch (struct cursor *c) +{ + unw_word_t saved_bsp, saved_bspstore, loadrs, ndirty; + int ret = 0; + + saved_bsp = c->bsp; + if (c->pi.flags & UNW_PI_FLAG_IA64_RBS_SWITCH) + { + /* Got ourselves a frame that has saved ar.bspstore, ar.bsp, + and ar.rnat, so we're all set for rbs-switching: */ + if ((ret = ia64_get (c, c->loc[IA64_REG_BSP], &saved_bsp)) < 0 + || (ret = ia64_get (c, c->loc[IA64_REG_BSPSTORE], &saved_bspstore))) + return ret; + } + else if ((c->abi_marker == ABI_MARKER_LINUX_SIGTRAMP + || c->abi_marker == ABI_MARKER_OLD_LINUX_SIGTRAMP) + && !IA64_IS_REG_LOC (c->loc[IA64_REG_BSP]) + && (IA64_GET_ADDR (c->loc[IA64_REG_BSP]) + == c->sigcontext_addr + LINUX_SC_AR_BSP_OFF)) + { + /* When Linux delivers a signal on an alternate stack, it + does things a bit differently from what the unwind + conventions allow us to describe: instead of saving + ar.rnat, ar.bsp, and ar.bspstore, it saves the former two + plus the "loadrs" value. Because of this, we need to + detect & record a potential rbs-area switch + manually... */ + + /* If ar.bsp has been saved already AND the current bsp is + not equal to the saved value, then we know for sure that + we're past the point where the backing store has been + switched (and before the point where it's restored). */ + if ((ret = ia64_get (c, IA64_LOC_ADDR (c->sigcontext_addr + + LINUX_SC_AR_BSP_OFF, 0), + &saved_bsp) < 0) + || (ret = ia64_get (c, IA64_LOC_ADDR (c->sigcontext_addr + + LINUX_SC_LOADRS_OFF, 0), + &loadrs) < 0)) + return ret; + loadrs >>= 16; + ndirty = rse_num_regs (c->bsp - loadrs, c->bsp); + saved_bspstore = rse_skip_regs (saved_bsp, -ndirty); + } + + if (saved_bsp == c->bsp) + return 0; + + return rbs_switch (c, saved_bsp, saved_bspstore, c->loc[IA64_REG_RNAT]); +} + +static inline int +update_frame_state (struct cursor *c) +{ + unw_word_t prev_ip, prev_sp, prev_bsp, ip, num_regs; + ia64_loc_t prev_cfm_loc; + int ret; + + prev_cfm_loc = c->cfm_loc; + prev_ip = c->ip; + prev_sp = c->sp; + prev_bsp = c->bsp; + + /* Update the IP cache (do this first: if we reach the end of the + frame-chain, the rest of the info may not be valid/useful + anymore. */ + ret = ia64_get (c, c->loc[IA64_REG_IP], &ip); + if (ret < 0) + return ret; + c->ip = ip; + + if ((ip & 0xc) != 0) + { + /* don't let obviously bad addresses pollute the cache */ + Debug (1, "rejecting bad ip=0x%lx\n", (long) c->ip); + return -UNW_EINVALIDIP; + } + + c->cfm_loc = c->loc[IA64_REG_PFS]; + /* update the CFM cache: */ + ret = ia64_get (c, c->cfm_loc, &c->cfm); + if (ret < 0) + return ret; + + /* Normally, AR.EC is stored in the CFM save-location. That + save-location contains the full function-state as defined by + AR.PFS. However, interruptions only save the frame-marker, not + any other info in CFM. Instead, AR.EC gets saved on the first + call by the interruption-handler. Thus, interruption-related + frames need to track the _previous_ CFM save-location since + that's were AR.EC is saved. We support this by setting ec_loc to + cfm_loc by default and giving frames marked with an ABI-marker + the chance to override this value with prev_cfm_loc. */ + c->ec_loc = c->cfm_loc; + + num_regs = 0; + if (unlikely (c->abi_marker)) + { + c->last_abi_marker = c->abi_marker; + switch (ia64_get_abi_marker (c)) + { + case ABI_MARKER_LINUX_SIGTRAMP: + case ABI_MARKER_OLD_LINUX_SIGTRAMP: + ia64_set_abi (c, ABI_LINUX); + if ((ret = linux_sigtramp (c, prev_cfm_loc, &num_regs)) < 0) + return ret; + break; + + case ABI_MARKER_OLD_LINUX_INTERRUPT: + case ABI_MARKER_LINUX_INTERRUPT: + ia64_set_abi (c, ABI_LINUX); + if ((ret = linux_interrupt (c, prev_cfm_loc, &num_regs, + c->abi_marker)) < 0) + return ret; + break; + + case ABI_MARKER_HP_UX_SIGTRAMP: + ia64_set_abi (c, ABI_HPUX); + if ((ret = hpux_sigtramp (c, prev_cfm_loc, &num_regs)) < 0) + return ret; + break; + + default: + Debug (1, "unknown ABI marker: ABI=%u, context=%u\n", + c->abi_marker >> 8, c->abi_marker & 0xff); + return -UNW_EINVAL; + } + Debug (12, "sigcontext_addr=%lx (ret=%d)\n", + (unsigned long) c->sigcontext_addr, ret); + + c->sigcontext_off = c->sigcontext_addr - c->sp; + + /* update the IP cache: */ + if ((ret = ia64_get (c, c->loc[IA64_REG_IP], &ip)) < 0) + return ret; + c->ip = ip; + if (ip == 0) + /* end of frame-chain reached */ + return 0; + } + else + num_regs = (c->cfm >> 7) & 0x7f; /* size of locals */ + + if (!IA64_IS_NULL_LOC (c->loc[IA64_REG_BSP])) + { + ret = check_rbs_switch (c); + if (ret < 0) + return ret; + } + + c->bsp = rse_skip_regs (c->bsp, -num_regs); + + c->sp = c->psp; + c->abi_marker = 0; + + if (c->ip == prev_ip && c->sp == prev_sp && c->bsp == prev_bsp) + { + Dprintf ("%s: ip, sp, and bsp unchanged; stopping here (ip=0x%lx)\n", + __FUNCTION__, (long) ip); + return -UNW_EBADFRAME; + } + + /* as we unwind, the saved ar.unat becomes the primary unat: */ + c->loc[IA64_REG_PRI_UNAT_MEM] = c->loc[IA64_REG_UNAT]; + + /* restore the predicates: */ + ret = ia64_get (c, c->loc[IA64_REG_PR], &c->pr); + if (ret < 0) + return ret; + + c->pi_valid = 0; + return 0; +} + + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->ip); + + if ((ret = ia64_find_save_locs (c)) >= 0 + && (ret = update_frame_state (c)) >= 0) + ret = (c->ip == 0) ? 0 : 1; + + Debug (2, "returning %d (ip=0x%016lx)\n", ret, (unsigned long) c->ip); + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Gtables.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Gtables.c new file mode 100644 index 00000000000000..f5e8f2d8f4da81 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Gtables.c @@ -0,0 +1,731 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2001-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include + +#include "unwind_i.h" + +#ifdef HAVE_IA64INTRIN_H +# include +#endif + +extern unw_addr_space_t _ULia64_local_addr_space; + +struct ia64_table_entry + { + uint64_t start_offset; + uint64_t end_offset; + uint64_t info_offset; + }; + +#ifdef UNW_LOCAL_ONLY + +static inline int +is_local_addr_space (unw_addr_space_t as) +{ + return 1; +} + +static inline int +read_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, void *arg) +{ + *valp = *(unw_word_t *) addr; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +static inline int +is_local_addr_space (unw_addr_space_t as) +{ + return as == unw_local_addr_space; +} + +static inline int +read_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, void *arg) +{ + unw_accessors_t *a = unw_get_accessors_int (as); + + return (*a->access_mem) (as, addr, valp, 0, arg); +} + +/* Helper macro for reading an ia64_table_entry from remote memory. */ +#define remote_read(addr, member) \ + (*a->access_mem) (as, (addr) + offsetof (struct ia64_table_entry, \ + member), &member, 0, arg) + +/* Lookup an unwind-table entry in remote memory. Returns 1 if an + entry is found, 0 if no entry is found, negative if an error + occurred reading remote memory. */ +static int +remote_lookup (unw_addr_space_t as, + unw_word_t table, size_t table_size, unw_word_t rel_ip, + struct ia64_table_entry *e, void *arg) +{ + unw_word_t e_addr = 0, start_offset, end_offset, info_offset; + unw_accessors_t *a = unw_get_accessors_int (as); + unsigned long lo, hi, mid; + int ret; + + /* do a binary search for right entry: */ + for (lo = 0, hi = table_size / sizeof (struct ia64_table_entry); lo < hi;) + { + mid = (lo + hi) / 2; + e_addr = table + mid * sizeof (struct ia64_table_entry); + if ((ret = remote_read (e_addr, start_offset)) < 0) + return ret; + + if (rel_ip < start_offset) + hi = mid; + else + { + if ((ret = remote_read (e_addr, end_offset)) < 0) + return ret; + + if (rel_ip >= end_offset) + lo = mid + 1; + else + break; + } + } + if (rel_ip < start_offset || rel_ip >= end_offset) + return 0; + e->start_offset = start_offset; + e->end_offset = end_offset; + + if ((ret = remote_read (e_addr, info_offset)) < 0) + return ret; + e->info_offset = info_offset; + return 1; +} + +HIDDEN void +tdep_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + if (!pi->unwind_info) + return; + + if (is_local_addr_space (as)) + { + free (pi->unwind_info); + pi->unwind_info = NULL; + } +} + +unw_word_t +_Uia64_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg) +{ + unw_word_t hdr_addr, info_addr, hdr, directives, pers, cookie, off; + unw_word_t start_offset, end_offset, info_offset, segbase; + struct ia64_table_entry *e; + size_t table_size; + unw_word_t gp = di->gp; + int ret; + + switch (di->format) + { + case UNW_INFO_FORMAT_DYNAMIC: + default: + return 0; + + case UNW_INFO_FORMAT_TABLE: + e = (struct ia64_table_entry *) di->u.ti.table_data; + table_size = di->u.ti.table_len * sizeof (di->u.ti.table_data[0]); + segbase = di->u.ti.segbase; + if (table_size < sizeof (struct ia64_table_entry)) + return 0; + start_offset = e[0].start_offset; + end_offset = e[0].end_offset; + info_offset = e[0].info_offset; + break; + + case UNW_INFO_FORMAT_REMOTE_TABLE: + { + unw_accessors_t *a = unw_get_accessors_int (as); + unw_word_t e_addr = di->u.rti.table_data; + + table_size = di->u.rti.table_len * sizeof (unw_word_t); + segbase = di->u.rti.segbase; + if (table_size < sizeof (struct ia64_table_entry)) + return 0; + + if ( (ret = remote_read (e_addr, start_offset) < 0) + || (ret = remote_read (e_addr, end_offset) < 0) + || (ret = remote_read (e_addr, info_offset) < 0)) + return ret; + } + break; + } + + if (start_offset != end_offset) + /* dyn-list entry cover a zero-length "procedure" and should be + first entry (note: technically a binary could contain code + below the segment base, but this doesn't happen for normal + binaries and certainly doesn't happen when libunwind is a + separate shared object. For weird cases, the application may + have to provide its own (slower) version of this routine. */ + return 0; + + hdr_addr = info_offset + segbase; + info_addr = hdr_addr + 8; + + /* read the header word: */ + if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0) + return ret; + + if (IA64_UNW_VER (hdr) != 1 + || IA64_UNW_FLAG_EHANDLER (hdr) || IA64_UNW_FLAG_UHANDLER (hdr)) + /* dyn-list entry must be version 1 and doesn't have ehandler + or uhandler */ + return 0; + + if (IA64_UNW_LENGTH (hdr) != 1) + /* dyn-list entry must consist of a single word of NOP directives */ + return 0; + + if ( ((ret = read_mem (as, info_addr, &directives, arg)) < 0) + || ((ret = read_mem (as, info_addr + 0x08, &pers, arg)) < 0) + || ((ret = read_mem (as, info_addr + 0x10, &cookie, arg)) < 0) + || ((ret = read_mem (as, info_addr + 0x18, &off, arg)) < 0)) + return 0; + + if (directives != 0 || pers != 0 + || (!as->big_endian && cookie != 0x7473696c2d6e7964ULL) + || ( as->big_endian && cookie != 0x64796e2d6c697374ULL)) + return 0; + + /* OK, we ran the gauntlet and found it: */ + return off + gp; +} + +#endif /* !UNW_LOCAL_ONLY */ + +static inline const struct ia64_table_entry * +lookup (struct ia64_table_entry *table, size_t table_size, unw_word_t rel_ip) +{ + const struct ia64_table_entry *e = 0; + unsigned long lo, hi, mid; + + /* do a binary search for right entry: */ + for (lo = 0, hi = table_size / sizeof (struct ia64_table_entry); lo < hi;) + { + mid = (lo + hi) / 2; + e = table + mid; + if (rel_ip < e->start_offset) + hi = mid; + else if (rel_ip >= e->end_offset) + lo = mid + 1; + else + break; + } + if (rel_ip < e->start_offset || rel_ip >= e->end_offset) + return NULL; + return e; +} + +int +unw_search_ia64_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp; + const struct ia64_table_entry *e = NULL; + unw_word_t handler_offset, segbase = 0; + int ret, is_local; +#ifndef UNW_LOCAL_ONLY + struct ia64_table_entry ent; +#endif + + assert ((di->format == UNW_INFO_FORMAT_TABLE + || di->format == UNW_INFO_FORMAT_REMOTE_TABLE) + && (ip >= di->start_ip && ip < di->end_ip)); + + pi->flags = 0; + pi->unwind_info = 0; + pi->handler = 0; + + if (likely (di->format == UNW_INFO_FORMAT_TABLE)) + { + segbase = di->u.ti.segbase; + e = lookup ((struct ia64_table_entry *) di->u.ti.table_data, + di->u.ti.table_len * sizeof (unw_word_t), + ip - segbase); + } +#ifndef UNW_LOCAL_ONLY + else + { + segbase = di->u.rti.segbase; + if ((ret = remote_lookup (as, di->u.rti.table_data, + di->u.rti.table_len * sizeof (unw_word_t), + ip - segbase, &ent, arg)) < 0) + return ret; + if (ret) + e = &ent; + } +#endif + if (!e) + { + /* IP is inside this table's range, but there is no explicit + unwind info => use default conventions (i.e., this is NOT an + error). */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = 0; + pi->end_ip = 0; + pi->gp = di->gp; + pi->lsda = 0; + return 0; + } + + pi->start_ip = e->start_offset + segbase; + pi->end_ip = e->end_offset + segbase; + + hdr_addr = e->info_offset + segbase; + info_addr = hdr_addr + 8; + + /* Read the header word. Note: the actual unwind-info is always + assumed to reside in memory, independent of whether di->format is + UNW_INFO_FORMAT_TABLE or UNW_INFO_FORMAT_REMOTE_TABLE. */ + + if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0) + return ret; + + if (IA64_UNW_VER (hdr) != 1) + { + Debug (1, "Unknown header version %ld (hdr word=0x%lx @ 0x%lx)\n", + IA64_UNW_VER (hdr), (unsigned long) hdr, + (unsigned long) hdr_addr); + return -UNW_EBADVERSION; + } + + info_end_addr = info_addr + 8 * IA64_UNW_LENGTH (hdr); + + is_local = is_local_addr_space (as); + + /* If we must have the unwind-info, return it. Also, if we are in + the local address-space, return the unwind-info because it's so + cheap to do so and it may come in handy later on. */ + if (need_unwind_info || is_local) + { + pi->unwind_info_size = 8 * IA64_UNW_LENGTH (hdr); + + if (is_local) + pi->unwind_info = (void *) (uintptr_t) info_addr; + else + { + /* Internalize unwind info. Note: since we're doing this + only for non-local address spaces, there is no + signal-safety issue and it is OK to use malloc()/free(). */ + pi->unwind_info = malloc (8 * IA64_UNW_LENGTH (hdr)); + if (!pi->unwind_info) + return -UNW_ENOMEM; + + wp = (unw_word_t *) pi->unwind_info; + for (addr = info_addr; addr < info_end_addr; addr += 8, ++wp) + { + if ((ret = read_mem (as, addr, wp, arg)) < 0) + { + free (pi->unwind_info); + return ret; + } + } + } + } + + if (IA64_UNW_FLAG_EHANDLER (hdr) || IA64_UNW_FLAG_UHANDLER (hdr)) + { + /* read the personality routine address (address is gp-relative): */ + if ((ret = read_mem (as, info_end_addr, &handler_offset, arg)) < 0) + return ret; + Debug (4, "handler ptr @ offset=%lx, gp=%lx\n", handler_offset, di->gp); + if ((read_mem (as, handler_offset + di->gp, &pi->handler, arg)) < 0) + return ret; + } + pi->lsda = info_end_addr + 8; + pi->gp = di->gp; + pi->format = di->format; + return 0; +} + +#ifndef UNW_REMOTE_ONLY + +# if defined(HAVE_DL_ITERATE_PHDR) +# include +# include + +# if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) \ + || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && !defined(DT_CONFIG)) +# error You need GLIBC 2.2.4 or later on IA-64 Linux +# endif + +# if defined(HAVE_GETUNWIND) + extern unsigned long getunwind (void *buf, size_t len); +# else /* HAVE_GETUNWIND */ +# include +# include +# ifndef __NR_getunwind +# define __NR_getunwind 1215 +# endif + +static unsigned long +getunwind (void *buf, size_t len) +{ + return syscall (SYS_getunwind, buf, len); +} + +# endif /* HAVE_GETUNWIND */ + +static unw_dyn_info_t kernel_table; + +static int +get_kernel_table (unw_dyn_info_t *di) +{ + struct ia64_table_entry *ktab, *etab; + size_t size; + + Debug (16, "getting kernel table"); + + size = getunwind (NULL, 0); + ktab = sos_alloc (size); + if (!ktab) + { + Dprintf (__FILE__".%s: failed to allocate %zu bytes", + __FUNCTION__, size); + return -UNW_ENOMEM; + } + getunwind (ktab, size); + + /* Determine length of kernel's unwind table & relocate its entries. */ + for (etab = ktab; etab->start_offset; ++etab) + etab->info_offset += (uint64_t) ktab; + + di->format = UNW_INFO_FORMAT_TABLE; + di->gp = 0; + di->start_ip = ktab[0].start_offset; + di->end_ip = etab[-1].end_offset; + di->u.ti.name_ptr = (unw_word_t) ""; + di->u.ti.segbase = 0; + di->u.ti.table_len = ((char *) etab - (char *) ktab) / sizeof (unw_word_t); + di->u.ti.table_data = (unw_word_t *) ktab; + + Debug (16, "found table `%s': [%lx-%lx) segbase=%lx len=%lu\n", + (char *) di->u.ti.name_ptr, di->start_ip, di->end_ip, + di->u.ti.segbase, di->u.ti.table_len); + return 0; +} + +# ifndef UNW_LOCAL_ONLY + +/* This is exported for the benefit of libunwind-ptrace.a. */ +int +_Uia64_get_kernel_table (unw_dyn_info_t *di) +{ + int ret; + + if (!kernel_table.u.ti.table_data) + if ((ret = get_kernel_table (&kernel_table)) < 0) + return ret; + + memcpy (di, &kernel_table, sizeof (*di)); + return 0; +} + +# endif /* !UNW_LOCAL_ONLY */ + +static inline unsigned long +current_gp (void) +{ +# if defined(__GNUC__) && !defined(__INTEL_COMPILER) + register unsigned long gp __asm__("gp"); + return gp; +# elif HAVE_IA64INTRIN_H + return __getReg (_IA64_REG_GP); +# else +# error Implement me. +# endif +} + +static int +callback (struct dl_phdr_info *info, size_t size, void *ptr) +{ + unw_dyn_info_t *di = ptr; + const Elf64_Phdr *phdr, *p_unwind, *p_dynamic, *p_text; + long n; + Elf64_Addr load_base, segbase = 0; + + /* Make sure struct dl_phdr_info is at least as big as we need. */ + if (size < offsetof (struct dl_phdr_info, dlpi_phnum) + + sizeof (info->dlpi_phnum)) + return -1; + + Debug (16, "checking `%s' (load_base=%lx)\n", + info->dlpi_name, info->dlpi_addr); + + phdr = info->dlpi_phdr; + load_base = info->dlpi_addr; + p_text = NULL; + p_unwind = NULL; + p_dynamic = NULL; + + /* See if PC falls into one of the loaded segments. Find the unwind + segment at the same time. */ + for (n = info->dlpi_phnum; --n >= 0; phdr++) + { + if (phdr->p_type == PT_LOAD) + { + Elf64_Addr vaddr = phdr->p_vaddr + load_base; + if (di->u.ti.segbase >= vaddr + && di->u.ti.segbase < vaddr + phdr->p_memsz) + p_text = phdr; + } + else if (phdr->p_type == PT_IA_64_UNWIND) + p_unwind = phdr; + else if (phdr->p_type == PT_DYNAMIC) + p_dynamic = phdr; + } + if (!p_text || !p_unwind) + return 0; + + if (likely (p_unwind->p_vaddr >= p_text->p_vaddr + && p_unwind->p_vaddr < p_text->p_vaddr + p_text->p_memsz)) + /* normal case: unwind table is inside text segment */ + segbase = p_text->p_vaddr + load_base; + else + { + /* Special case: unwind table is in some other segment; this + happens for the Linux kernel's gate DSO, for example. */ + phdr = info->dlpi_phdr; + for (n = info->dlpi_phnum; --n >= 0; phdr++) + { + if (phdr->p_type == PT_LOAD && p_unwind->p_vaddr >= phdr->p_vaddr + && p_unwind->p_vaddr < phdr->p_vaddr + phdr->p_memsz) + { + segbase = phdr->p_vaddr + load_base; + break; + } + } + } + + if (p_dynamic) + { + /* For dynamicly linked executables and shared libraries, + DT_PLTGOT is the gp value for that object. */ + Elf64_Dyn *dyn = (Elf64_Dyn *)(p_dynamic->p_vaddr + load_base); + for (; dyn->d_tag != DT_NULL; ++dyn) + if (dyn->d_tag == DT_PLTGOT) + { + /* On IA-64, _DYNAMIC is writable and GLIBC has relocated it. */ + di->gp = dyn->d_un.d_ptr; + break; + } + } + else + /* Otherwise this is a static executable with no _DYNAMIC. + The gp is constant program-wide. */ + di->gp = current_gp(); + di->format = UNW_INFO_FORMAT_TABLE; + di->start_ip = p_text->p_vaddr + load_base; + di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz; + di->u.ti.name_ptr = (unw_word_t) info->dlpi_name; + di->u.ti.table_data = (void *) (p_unwind->p_vaddr + load_base); + di->u.ti.table_len = p_unwind->p_memsz / sizeof (unw_word_t); + di->u.ti.segbase = segbase; + + Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, " + "table_data=%p\n", (char *) di->u.ti.name_ptr, di->u.ti.segbase, + di->u.ti.table_len, di->gp, di->u.ti.table_data); + return 1; +} + +# ifdef HAVE_DL_PHDR_REMOVALS_COUNTER + +static inline int +validate_cache (unw_addr_space_t as) +{ + /* Note: we don't need to serialize here with respect to + dl_iterate_phdr() because if somebody were to remove an object + that is required to complete the unwind on whose behalf we're + validating the cache here, we'd be hosed anyhow. What we're + guarding against here is the case where library FOO gets mapped, + unwind info for FOO gets cached, FOO gets unmapped, BAR gets + mapped in the place where FOO was and then we unwind across a + function in FOO. Since no thread can execute in BAR before FOO + has been removed, we are guaranteed that + dl_phdr_removals_counter() would have been incremented before we + get here. */ + unsigned long long removals = dl_phdr_removals_counter (); + + if (removals == as->shared_object_removals) + return 1; + + as->shared_object_removals = removals; + unw_flush_cache (as, 0, 0); + return -1; +} + +# else /* !HAVE_DL_PHDR_REMOVALS_COUNTER */ + +/* Check whether any phdrs have been removed since we last flushed the + cache. If so we flush the cache and return -1, if not, we do + nothing and return 1. */ + +static int +check_callback (struct dl_phdr_info *info, size_t size, void *ptr) +{ +# ifdef HAVE_STRUCT_DL_PHDR_INFO_DLPI_SUBS + unw_addr_space_t as = ptr; + + if (size < + offsetof (struct dl_phdr_info, dlpi_subs) + sizeof (info->dlpi_subs)) + /* It would be safer to flush the cache here, but that would + disable caching for older libc's which would be incompatible + with the behavior of older versions of libunwind so we return 1 + instead and hope nobody runs into stale cache info... */ + return 1; + + if (info->dlpi_subs == as->shared_object_removals) + return 1; + + as->shared_object_removals = info->dlpi_subs; + unw_flush_cache (as, 0, 0); + return -1; /* indicate that there were removals */ +# else + return 1; +# endif +} + +static inline int +validate_cache (unw_addr_space_t as) +{ + intrmask_t saved_mask; + int ret; + + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); + ret = dl_iterate_phdr (check_callback, as); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + return ret; +} + +# endif /* HAVE_DL_PHDR_REMOVALS_COUNTER */ + +# elif defined(HAVE_DLMODINFO) + /* Support for HP-UX-style dlmodinfo() */ +# include + +static inline int +validate_cache (unw_addr_space_t as) +{ + return 1; +} + +# endif /* !HAVE_DLMODINFO */ + +HIDDEN int +tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, void *arg) +{ +# if defined(HAVE_DL_ITERATE_PHDR) + unw_dyn_info_t di, *dip = &di; + intrmask_t saved_mask; + int ret; + + di.u.ti.segbase = ip; /* this is cheap... */ + + SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); + ret = dl_iterate_phdr (callback, &di); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + + if (ret <= 0) + { + if (!kernel_table.u.ti.table_data) + { + if ((ret = get_kernel_table (&kernel_table)) < 0) + return ret; + } + if (ip < kernel_table.start_ip || ip >= kernel_table.end_ip) + return -UNW_ENOINFO; + dip = &kernel_table; + } +# elif defined(HAVE_DLMODINFO) +# define UNWIND_TBL_32BIT 0x8000000000000000 + struct load_module_desc lmd; + unw_dyn_info_t di, *dip = &di; + struct unwind_header + { + uint64_t header_version; + uint64_t start_offset; + uint64_t end_offset; + } + *uhdr; + + if (!dlmodinfo (ip, &lmd, sizeof (lmd), NULL, 0, 0)) + return -UNW_ENOINFO; + + di.format = UNW_INFO_FORMAT_TABLE; + di.start_ip = lmd.text_base; + di.end_ip = lmd.text_base + lmd.text_size; + di.gp = lmd.linkage_ptr; + di.u.ti.name_ptr = 0; /* no obvious table-name available */ + di.u.ti.segbase = lmd.text_base; + + uhdr = (struct unwind_header *) lmd.unwind_base; + + if ((uhdr->header_version & ~UNWIND_TBL_32BIT) != 1 + && (uhdr->header_version & ~UNWIND_TBL_32BIT) != 2) + { + Debug (1, "encountered unknown unwind header version %ld\n", + (long) (uhdr->header_version & ~UNWIND_TBL_32BIT)); + return -UNW_EBADVERSION; + } + if (uhdr->header_version & UNWIND_TBL_32BIT) + { + Debug (1, "32-bit unwind tables are not supported yet\n"); + return -UNW_EINVAL; + } + + di.u.ti.table_data = (unw_word_t *) (di.u.ti.segbase + uhdr->start_offset); + di.u.ti.table_len = ((uhdr->end_offset - uhdr->start_offset) + / sizeof (unw_word_t)); + + Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, " + "table_data=%p\n", (char *) di.u.ti.name_ptr, di.u.ti.segbase, + di.u.ti.table_len, di.gp, di.u.ti.table_data); +# endif + + /* now search the table: */ + return tdep_search_unwind_table (as, ip, dip, pi, need_unwind_info, arg); +} + +/* Returns 1 if the cache is up-to-date or -1 if the cache contained + stale data and had to be flushed. */ + +HIDDEN int +ia64_local_validate_cache (unw_addr_space_t as, void *arg) +{ + return validate_cache (as); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lfind_unwind_table.c new file mode 100644 index 00000000000000..68e269f1d7f95f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lfind_unwind_table.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfind_unwind_table.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lglobal.c new file mode 100644 index 00000000000000..6d7b489e14bd9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Linit.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Linstall_cursor.S b/src/coreclr/src/pal/src/libunwind/src/ia64/Linstall_cursor.S new file mode 100644 index 00000000000000..8c7233972521c8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Linstall_cursor.S @@ -0,0 +1,6 @@ +#define UNW_LOCAL_ONLY +#include "Ginstall_cursor.S" +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lis_signal_frame.c new file mode 100644 index 00000000000000..b9a7c4f51ad9fa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lparser.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lparser.c new file mode 100644 index 00000000000000..f23aaf48e9c27d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lparser.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gparser.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lrbs.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lrbs.c new file mode 100644 index 00000000000000..a91b5f2979a93a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lrbs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Grbs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lscript.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lscript.c new file mode 100644 index 00000000000000..57b926bf80124b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lscript.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gscript.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ltables.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ltables.c new file mode 100644 index 00000000000000..876b0aac03dd61 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Ltables.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gtables.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/NOTES b/src/coreclr/src/pal/src/libunwind/src/ia64/NOTES new file mode 100644 index 00000000000000..a5805e8345672b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/NOTES @@ -0,0 +1,65 @@ +- the frame state consists of the following: + + - ip current instruction pointer + - sp current stack pointer value + - bsp current backing store pointer + - cfm current frame mask + + these are derived from the next younger (more deeply nested) frame + as follows: + + - ip == saved return-link (may be b0 or an alternate branch-reg) + - sp == if younger frame has a fixed-sized frame, sp + size-of-frame, + else saved sp + - cfm == saved ar.pfs + - bsp == if ar.bsp has been saved, saved ar.bsp, otherwise, + ar.bsp \ominus saved ar.pfs.pfm.sol + +The unwind cursor should represent the machine state as it existed at +the address contained in register ip. This state consists of the +*current* frame state and the save locations in the next younger +frame. + +An unwind script current takes the old save locations and updates them +for the next older frame. With the new setup, we need to update the +frame state first, without updating the other save locations. For this +to work, we need the following info: + + - save location of return-link + - save location of ar.pfs + - save location of bsp (if it has been saved) + - size of stack frame (fixed case) or save location of sp + + +setup: + + func: ... + ... + ... + br.call foo <-- call site + ... <-- ip + ... + +initial state: + + The unwind cursor represents the (preserved) machine state + as it existed at "ip". + + Evaluating the unwind descriptors for "ip" yields the following + info: + + - frame size at call site (or previous sp) + - what registers where saved where by func before + the call site was reached + + + Note that there is some procedure info that needs to be obtained + for the new "ip" which is contained in the unwind descriptors. + Specifically, the following is needed: + + - procedure's start address + - personality address + - pointer to language-specific data area + + This info is stored in a separate proc_info structure and needs + to be obtained right after running the unwind script for func. diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/dyn_info_list.S b/src/coreclr/src/pal/src/libunwind/src/ia64/dyn_info_list.S new file mode 100644 index 00000000000000..31265f66a064d7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/dyn_info_list.S @@ -0,0 +1,26 @@ +#ifndef UNW_REMOTE_ONLY + +/* + * Create a special unwind-table entry which makes it easy for an + * unwinder to locate the dynamic registration list. The special + * entry covers address range [0-0) and is therefore guaranteed to be + * the first in the unwind-table. + */ + .global _U_dyn_info_list + .hidden _U_dyn_info_list + + .section .IA_64.unwind_info,"a","progbits" +.info: data8 (1<<48) | 1 /* v1, length==1 (8-byte word) */ + data8 0 /* 8 empty .prologue directives (nops) */ + data8 0 /* personality routine (ignored) */ + string "dyn-list" /* lsda */ + data8 @gprel(_U_dyn_info_list) + + .section .IA_64.unwind, "a", "progbits" + data8 0, 0, @segrel(.info) + +#endif +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/ia64/getcontext.S new file mode 100644 index 00000000000000..d8da732acc8ac9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/getcontext.S @@ -0,0 +1,177 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "ucontext_i.h" + +#define GR(n) (SC_GR + (n)*8) +#define BR(n) (SC_BR + (n)*8) +#define FR(n) (SC_FR + (n)*16) + +/* This should be compatible to the libc's getcontext(), except that + the sc->sc_mask field is always cleared and that the name is + prefixed with _Uia64_ so we don't step on the application's + name-space. */ + + .align 32 + .protected _Uia64_getcontext + .global _Uia64_getcontext + .proc _Uia64_getcontext +_Uia64_getcontext: + .prologue + alloc rPFS = ar.pfs, 1, 0, 0, 0 // M2 + mov rPR = pr // I0, 2 cycles + add r2 = GR(1), in0 // I1 + ;; + + .save ar.unat, rUNAT + mov.m rUNAT = ar.unat // M2, 5 cycles + .body + st8.spill [r2] = r1, (SC_FLAGS - GR(1)) // M3 + dep.z rFLAGS = -1, IA64_SC_FLAG_SYNCHRONOUS_BIT, 1 // I0, 1 cycle + ;; + + mov.m rRSC = ar.rsc // M2, 12 cyc. + st8 [r2] = rFLAGS, (SC_PR - SC_FLAGS) // M3 + add r3 = FR(2), in0 + ;; + + mov.m rBSP = ar.bsp // M2, 12 cyc. + st8 [r2] = rPR, (GR(12) - SC_PR) // M3 + add r8 = FR(16), in0 + ;; + + mov.m rFPSR = ar.fpsr // M2, 12 cyc. + st8.spill [r2] = r12, (GR(4) - GR(12)) // M3 + add r9 = FR(24), in0 + ;; + + stf.spill [r3] = f2 // M2 + stf.spill [r8] = f16 // M3 + add r3 = GR(7), in0 + ;; + + flushrs // M0 + stf.spill [r9] = f24, (FR(31) - FR(24)) // M2 + mov rB0 = b0 // I0, 2 cycles + ;; + + stf.spill [r9] = f31 // M2 + st8.spill [r2] = r4, (GR(5) - GR(4)) // M3, bank 1 + mov rB1 = b1 // I0, 2 cycles + ;; + +.mem.offset 0,0; st8.spill [r2] = r5, (GR(6) - GR(5)) // M4, bank 0 +.mem.offset 8,0; st8.spill [r3] = r7, (BR(0) - GR(7)) // M3, bank 0 + mov rB2 = b2 // I0, 2 cycles + ;; + + st8.spill [r2] = r6, (BR(1) - GR(6)) // M2, bank 1 + st8 [r3] = rB0, (BR(4) - BR(0)) // M3, bank 1 + mov rB4 = b4 // I0, 2 cycles + ;; + + mov.m rNAT = ar.unat // M2, 5 cycles + st8 [r2] = rB1, (BR(2) - BR(1)) // M3, bank 0 + mov rB3 = b3 + ;; + + st8 [r2] = rB2, (BR(3) - BR(2)) // M2, bank 1 + st8 [r3] = rB4, (SC_LC - BR(4)) // M3, bank 1 + mov rB5 = b5 // I0, 2 cycles + ;; + + and rTMP = ~0x3, rRSC // M0 + add rPOS = GR(0), in0 // rPOS <- &sc_gr[0] // M1 + mov.i rLC = ar.lc // I0, 2 cycles + ;; + + mov.m ar.rsc = rTMP // put RSE into lazy mode // M2, ? cycles + st8 [r2] = rB3, (BR(5) - BR(3)) // M3, bank 0 + extr.u rPOS = rPOS, 3, 6 // get NaT bitnr for r0 // I0 + ;; + + mov.m rRNAT = ar.rnat // M2, 5 cycles + st8 [r2] = rB5, (SC_PFS - BR(5)) // M3, bank 0 + sub rCPOS = 64, rPOS // I0 + ;; + + st8 [r2] = rPFS, (SC_UNAT - SC_PFS) // M2 + st8 [r3] = rLC, (SC_BSP - SC_LC) // M3 + shr.u rTMP = rNAT, rPOS // I0, 3 cycles + ;; + + st8 [r2] = rUNAT, (SC_FPSR - SC_UNAT) // M2 + st8 [r3] = rBSP // M3 + add r8 = FR(3), in0 + ;; + + st8 [r2] = rFPSR, (SC_RNAT - SC_FPSR) // M2 + stf.spill [r8] = f3, (FR(4) - FR(3)) // M3 + add r9 = FR(5), in0 + ;; + + stf.spill [r8] = f4, (FR(17) - FR(4)) // M2 + stf.spill [r9] = f5, (FR(19) - FR(5)) // M3 + shl rNAT = rNAT, rCPOS // I0, 3 cycles + ;; + + st8 [r2] = rRNAT, (SC_NAT - SC_RNAT) // M2 + stf.spill [r8] = f17, (FR(18) - FR(17)) // M3 + nop.i 0 + ;; + + stf.spill [r8] = f18, (FR(20) - FR(18)) // M2 + stf.spill [r9] = f19, (FR(21) - FR(19)) // M3 + nop.i 0 + ;; + + stf.spill [r8] = f20, (FR(22) - FR(20)) // M2 + stf.spill [r9] = f21, (FR(23) - FR(21)) // M3 + or rNAT = rNAT, rTMP // I0 + ;; + + st8 [r2] = rNAT // M2 + stf.spill [r8] = f22, (FR(25) - FR(22)) // M3 + ;; + stf.spill [r9] = f23, (FR(26) - FR(23)) // M2 + stf.spill [r8] = f25, (FR(27) - FR(25)) // M3 + ;; + stf.spill [r9] = f26, (FR(28) - FR(26)) // M2 + stf.spill [r8] = f27, (FR(29) - FR(27)) // M3 + ;; + mov.m ar.rsc = rRSC // restore RSE mode // M2 + stf.spill [r9] = f28, (FR(30) - FR(28)) // M3 + ;; + mov.m ar.unat = rUNAT // restore caller's UNaT // M2 + stf.spill [r8] = f29 // M3 + ;; + stf.spill [r9] = f30 // M2 + mov r8 = 0 + br.ret.sptk.many rp + .endp _Uia64_getcontext +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/init.h b/src/coreclr/src/pal/src/libunwind/src/ia64/init.h new file mode 100644 index 00000000000000..6628a1d8882481 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/init.h @@ -0,0 +1,132 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static ALWAYS_INLINE int +common_init (struct cursor *c, unw_word_t sp, unw_word_t bsp) +{ + unw_word_t bspstore, rbs_base; + int ret; + + if (c->as->caching_policy != UNW_CACHE_NONE) + /* ensure cache doesn't have any stale contents: */ + ia64_validate_cache (c->as, c->as_arg); + + c->cfm_loc = IA64_REG_LOC (c, UNW_IA64_CFM); + c->loc[IA64_REG_BSP] = IA64_NULL_LOC; + c->loc[IA64_REG_BSPSTORE] = IA64_REG_LOC (c, UNW_IA64_AR_BSPSTORE); + c->loc[IA64_REG_PFS] = IA64_REG_LOC (c, UNW_IA64_AR_PFS); + c->loc[IA64_REG_RNAT] = IA64_REG_LOC (c, UNW_IA64_AR_RNAT); + c->loc[IA64_REG_IP] = IA64_REG_LOC (c, UNW_IA64_IP); + c->loc[IA64_REG_PRI_UNAT_MEM] = IA64_NULL_LOC; /* no primary UNaT location */ + c->loc[IA64_REG_UNAT] = IA64_REG_LOC (c, UNW_IA64_AR_UNAT); + c->loc[IA64_REG_PR] = IA64_REG_LOC (c, UNW_IA64_PR); + c->loc[IA64_REG_LC] = IA64_REG_LOC (c, UNW_IA64_AR_LC); + c->loc[IA64_REG_FPSR] = IA64_REG_LOC (c, UNW_IA64_AR_FPSR); + + c->loc[IA64_REG_R4] = IA64_REG_LOC (c, UNW_IA64_GR + 4); + c->loc[IA64_REG_R5] = IA64_REG_LOC (c, UNW_IA64_GR + 5); + c->loc[IA64_REG_R6] = IA64_REG_LOC (c, UNW_IA64_GR + 6); + c->loc[IA64_REG_R7] = IA64_REG_LOC (c, UNW_IA64_GR + 7); + + c->loc[IA64_REG_NAT4] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 4, &c->nat_bitnr[0]); + c->loc[IA64_REG_NAT5] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 5, &c->nat_bitnr[1]); + c->loc[IA64_REG_NAT6] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 6, &c->nat_bitnr[2]); + c->loc[IA64_REG_NAT7] = IA64_REG_NAT_LOC (c, UNW_IA64_NAT + 7, &c->nat_bitnr[3]); + + c->loc[IA64_REG_B1] = IA64_REG_LOC (c, UNW_IA64_BR + 1); + c->loc[IA64_REG_B2] = IA64_REG_LOC (c, UNW_IA64_BR + 2); + c->loc[IA64_REG_B3] = IA64_REG_LOC (c, UNW_IA64_BR + 3); + c->loc[IA64_REG_B4] = IA64_REG_LOC (c, UNW_IA64_BR + 4); + c->loc[IA64_REG_B5] = IA64_REG_LOC (c, UNW_IA64_BR + 5); + + c->loc[IA64_REG_F2] = IA64_FPREG_LOC (c, UNW_IA64_FR + 2); + c->loc[IA64_REG_F3] = IA64_FPREG_LOC (c, UNW_IA64_FR + 3); + c->loc[IA64_REG_F4] = IA64_FPREG_LOC (c, UNW_IA64_FR + 4); + c->loc[IA64_REG_F5] = IA64_FPREG_LOC (c, UNW_IA64_FR + 5); + c->loc[IA64_REG_F16] = IA64_FPREG_LOC (c, UNW_IA64_FR + 16); + c->loc[IA64_REG_F17] = IA64_FPREG_LOC (c, UNW_IA64_FR + 17); + c->loc[IA64_REG_F18] = IA64_FPREG_LOC (c, UNW_IA64_FR + 18); + c->loc[IA64_REG_F19] = IA64_FPREG_LOC (c, UNW_IA64_FR + 19); + c->loc[IA64_REG_F20] = IA64_FPREG_LOC (c, UNW_IA64_FR + 20); + c->loc[IA64_REG_F21] = IA64_FPREG_LOC (c, UNW_IA64_FR + 21); + c->loc[IA64_REG_F22] = IA64_FPREG_LOC (c, UNW_IA64_FR + 22); + c->loc[IA64_REG_F23] = IA64_FPREG_LOC (c, UNW_IA64_FR + 23); + c->loc[IA64_REG_F24] = IA64_FPREG_LOC (c, UNW_IA64_FR + 24); + c->loc[IA64_REG_F25] = IA64_FPREG_LOC (c, UNW_IA64_FR + 25); + c->loc[IA64_REG_F26] = IA64_FPREG_LOC (c, UNW_IA64_FR + 26); + c->loc[IA64_REG_F27] = IA64_FPREG_LOC (c, UNW_IA64_FR + 27); + c->loc[IA64_REG_F28] = IA64_FPREG_LOC (c, UNW_IA64_FR + 28); + c->loc[IA64_REG_F29] = IA64_FPREG_LOC (c, UNW_IA64_FR + 29); + c->loc[IA64_REG_F30] = IA64_FPREG_LOC (c, UNW_IA64_FR + 30); + c->loc[IA64_REG_F31] = IA64_FPREG_LOC (c, UNW_IA64_FR + 31); + + ret = ia64_get (c, c->loc[IA64_REG_IP], &c->ip); + if (ret < 0) + return ret; + + ret = ia64_get (c, c->cfm_loc, &c->cfm); + if (ret < 0) + return ret; + + ret = ia64_get (c, c->loc[IA64_REG_PR], &c->pr); + if (ret < 0) + return ret; + + c->sp = c->psp = sp; + c->bsp = bsp; + + ret = ia64_get (c, c->loc[IA64_REG_BSPSTORE], &bspstore); + if (ret < 0) + return ret; + + c->rbs_curr = c->rbs_left_edge = 0; + + /* Try to find a base of the register backing-store. We may default + to a reasonable value (e.g., half the address-space down from + bspstore). If the BSPSTORE looks corrupt, we fail. */ + if ((ret = rbs_get_base (c, bspstore, &rbs_base)) < 0) + return ret; + + c->rbs_area[0].end = bspstore; + c->rbs_area[0].size = bspstore - rbs_base; + c->rbs_area[0].rnat_loc = IA64_REG_LOC (c, UNW_IA64_AR_RNAT); + Debug (10, "initial rbs-area: [0x%llx-0x%llx), rnat@%s\n", + (long long) rbs_base, (long long) c->rbs_area[0].end, + ia64_strloc (c->rbs_area[0].rnat_loc)); + + c->pi.flags = 0; + + c->sigcontext_addr = 0; + c->abi_marker = 0; + c->last_abi_marker = 0; + + c->hint = 0; + c->prev_script = 0; + c->eh_valid_mask = 0; + c->pi_valid = 0; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/longjmp.S b/src/coreclr/src/pal/src/libunwind/src/ia64/longjmp.S new file mode 100644 index 00000000000000..2a2f286594bb26 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/longjmp.S @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + + .global _UI_longjmp_cont + + .align 32 + .proc longjmp_continuation +longjmp_continuation: +_UI_longjmp_cont: // non-function label for {sig,}longjmp.c + .prologue + .save rp, r15 + .body + mov rp = r15 + mov r8 = r16 + br.sptk.many rp + .endp longjmp_continuation +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/mk_cursor_i b/src/coreclr/src/pal/src/libunwind/src/ia64/mk_cursor_i new file mode 100755 index 00000000000000..9211f91bbbb55c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/mk_cursor_i @@ -0,0 +1,7 @@ +#!/bin/sh +test -z "$1" && exit 1 +echo "/* GENERATED */" +echo "#ifndef cursor_i_h" +echo "#define cursor_i_h" +sed -ne 's/^->"\(\S*\)" \(\d*\)/#define \1 \2/p' < $1 || exit $? +echo "#endif" diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/offsets.h b/src/coreclr/src/pal/src/libunwind/src/ia64/offsets.h new file mode 100644 index 00000000000000..5ab7f8b31e61f9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/offsets.h @@ -0,0 +1,137 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* The first three 64-bit words in a signal frame contain the signal + number, siginfo pointer, and sigcontext pointer passed to the + signal handler. We use this to locate the sigcontext pointer. */ + +#define LINUX_SIGFRAME_ARG2_OFF 0x10 + +#define LINUX_SC_FLAGS_OFF 0x000 +#define LINUX_SC_NAT_OFF 0x008 +#define LINUX_SC_STACK_OFF 0x010 +#define LINUX_SC_IP_OFF 0x028 +#define LINUX_SC_CFM_OFF 0x030 +#define LINUX_SC_UM_OFF 0x038 +#define LINUX_SC_AR_RSC_OFF 0x040 +#define LINUX_SC_AR_BSP_OFF 0x048 +#define LINUX_SC_AR_RNAT_OFF 0x050 +#define LINUX_SC_AR_CCV 0x058 +#define LINUX_SC_AR_UNAT_OFF 0x060 +#define LINUX_SC_AR_FPSR_OFF 0x068 +#define LINUX_SC_AR_PFS_OFF 0x070 +#define LINUX_SC_AR_LC_OFF 0x078 +#define LINUX_SC_PR_OFF 0x080 +#define LINUX_SC_BR_OFF 0x088 +#define LINUX_SC_GR_OFF 0x0c8 +#define LINUX_SC_FR_OFF 0x1d0 +#define LINUX_SC_RBS_BASE_OFF 0x9d0 +#define LINUX_SC_LOADRS_OFF 0x9d8 +#define LINUX_SC_AR_CSD_OFF 0x9e0 +#define LINUX_SC_AR_SSD_OFF 0x9e8 +#define LINUX_SC_MASK 0xa50 + +/* Layout of old Linux kernel interrupt frame (struct pt_regs). */ + +#define LINUX_OLD_PT_IPSR_OFF 0x000 +#define LINUX_OLD_PT_IIP_OFF 0x008 +#define LINUX_OLD_PT_IFS_OFF 0x010 +#define LINUX_OLD_PT_UNAT_OFF 0x018 +#define LINUX_OLD_PT_PFS_OFF 0x020 +#define LINUX_OLD_PT_RSC_OFF 0x028 +#define LINUX_OLD_PT_RNAT_OFF 0x030 +#define LINUX_OLD_PT_BSPSTORE_OFF 0x038 +#define LINUX_OLD_PT_PR_OFF 0x040 +#define LINUX_OLD_PT_B6_OFF 0x048 +#define LINUX_OLD_PT_LOADRS_OFF 0x050 +#define LINUX_OLD_PT_R1_OFF 0x058 +#define LINUX_OLD_PT_R2_OFF 0x060 +#define LINUX_OLD_PT_R3_OFF 0x068 +#define LINUX_OLD_PT_R12_OFF 0x070 +#define LINUX_OLD_PT_R13_OFF 0x078 +#define LINUX_OLD_PT_R14_OFF 0x080 +#define LINUX_OLD_PT_R15_OFF 0x088 +#define LINUX_OLD_PT_R8_OFF 0x090 +#define LINUX_OLD_PT_R9_OFF 0x098 +#define LINUX_OLD_PT_R10_OFF 0x0a0 +#define LINUX_OLD_PT_R11_OFF 0x0a8 +#define LINUX_OLD_PT_R16_OFF 0x0b0 +#define LINUX_OLD_PT_R17_OFF 0x0b8 +#define LINUX_OLD_PT_R18_OFF 0x0c0 +#define LINUX_OLD_PT_R19_OFF 0x0c8 +#define LINUX_OLD_PT_R20_OFF 0x0d0 +#define LINUX_OLD_PT_R21_OFF 0x0d8 +#define LINUX_OLD_PT_R22_OFF 0x0e0 +#define LINUX_OLD_PT_R23_OFF 0x0e8 +#define LINUX_OLD_PT_R24_OFF 0x0f0 +#define LINUX_OLD_PT_R25_OFF 0x0f8 +#define LINUX_OLD_PT_R26_OFF 0x100 +#define LINUX_OLD_PT_R27_OFF 0x108 +#define LINUX_OLD_PT_R28_OFF 0x110 +#define LINUX_OLD_PT_R29_OFF 0x118 +#define LINUX_OLD_PT_R30_OFF 0x120 +#define LINUX_OLD_PT_R31_OFF 0x128 +#define LINUX_OLD_PT_CCV_OFF 0x130 +#define LINUX_OLD_PT_FPSR_OFF 0x138 +#define LINUX_OLD_PT_B0_OFF 0x140 +#define LINUX_OLD_PT_B7_OFF 0x148 +#define LINUX_OLD_PT_F6_OFF 0x150 +#define LINUX_OLD_PT_F7_OFF 0x160 +#define LINUX_OLD_PT_F8_OFF 0x170 +#define LINUX_OLD_PT_F9_OFF 0x180 + +/* Layout of new Linux kernel interrupt frame (struct pt_regs). */ + +#define LINUX_PT_B6_OFF 0 +#define LINUX_PT_B7_OFF 8 +#define LINUX_PT_CSD_OFF 16 +#define LINUX_PT_SSD_OFF 24 +#define LINUX_PT_R8_OFF 32 +#define LINUX_PT_R9_OFF 40 +#define LINUX_PT_R10_OFF 48 +#define LINUX_PT_R11_OFF 56 +#define LINUX_PT_IPSR_OFF 64 +#define LINUX_PT_IIP_OFF 72 +#define LINUX_PT_IFS_OFF 80 +#define LINUX_PT_UNAT_OFF 88 +#define LINUX_PT_PFS_OFF 96 +#define LINUX_PT_RSC_OFF 104 +#define LINUX_PT_RNAT_OFF 112 +#define LINUX_PT_BSPSTORE_OFF 120 +#define LINUX_PT_PR_OFF 128 +#define LINUX_PT_B0_OFF 136 +#define LINUX_PT_LOADRS_OFF 144 +#define LINUX_PT_R1_OFF 152 +#define LINUX_PT_R12_OFF 160 +#define LINUX_PT_R13_OFF 168 +#define LINUX_PT_FPSR_OFF 176 +#define LINUX_PT_R15_OFF 184 +#define LINUX_PT_R14_OFF 192 +#define LINUX_PT_R2_OFF 200 +#define LINUX_PT_R3_OFF 208 +#define LINUX_PT_R16_OFF 216 +#define LINUX_PT_R17_OFF 224 +#define LINUX_PT_R18_OFF 232 +#define LINUX_PT_R19_OFF 240 +#define LINUX_PT_R20_OFF 248 +#define LINUX_PT_R21_OFF 256 +#define LINUX_PT_R22_OFF 264 +#define LINUX_PT_R23_OFF 272 +#define LINUX_PT_R24_OFF 280 +#define LINUX_PT_R25_OFF 288 +#define LINUX_PT_R26_OFF 296 +#define LINUX_PT_R27_OFF 304 +#define LINUX_PT_R28_OFF 312 +#define LINUX_PT_R29_OFF 320 +#define LINUX_PT_R30_OFF 328 +#define LINUX_PT_R31_OFF 336 +#define LINUX_PT_CCV_OFF 344 +#define LINUX_PT_F6_OFF 352 +#define LINUX_PT_F7_OFF 368 +#define LINUX_PT_F8_OFF 384 +#define LINUX_PT_F9_OFF 400 +#define LINUX_PT_F10_OFF 416 +#define LINUX_PT_F11_OFF 432 + +#define LINUX_PT_P_NONSYS 5 /* must match pNonSys in entry.h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/regname.c b/src/coreclr/src/pal/src/libunwind/src/ia64/regname.c new file mode 100644 index 00000000000000..3636df87de5d9a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/regname.c @@ -0,0 +1,189 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* Logically, we like to think of the stack as a contiguous region of +memory. Unfortunately, this logical view doesn't work for the +register backing store, because the RSE is an asynchronous engine and +because UNIX/Linux allow for stack-switching via sigaltstack(2). +Specifically, this means that any given stacked register may or may +not be backed up by memory in the current stack. If not, then the +backing memory may be found in any of the "more inner" (younger) +stacks. The routines in this file help manage the discontiguous +nature of the register backing store. The routines are completely +independent of UNIX/Linux, but each stack frame that switches the +backing store is expected to reserve 4 words for use by libunwind. For +example, in the Linux sigcontext, sc_fr[0] and sc_fr[1] serve this +purpose. */ + +#include "libunwind_i.h" + +/* Maintain the register names as a single string to keep the number + of dynamic relocations in the shared object to a minimum. */ + +#define regname_len 9 +#define regname_str \ + "r0\0\0\0\0\0\0\0r1\0\0\0\0\0\0\0r2\0\0\0\0\0\0\0r3\0\0\0\0\0\0\0" \ + "r4\0\0\0\0\0\0\0r5\0\0\0\0\0\0\0r6\0\0\0\0\0\0\0r7\0\0\0\0\0\0\0" \ + "r8\0\0\0\0\0\0\0r9\0\0\0\0\0\0\0r10\0\0\0\0\0\0r11\0\0\0\0\0\0" \ + "r12\0\0\0\0\0\0r13\0\0\0\0\0\0r14\0\0\0\0\0\0r15\0\0\0\0\0\0" \ + "r16\0\0\0\0\0\0r17\0\0\0\0\0\0r18\0\0\0\0\0\0r19\0\0\0\0\0\0" \ + "r20\0\0\0\0\0\0r21\0\0\0\0\0\0r22\0\0\0\0\0\0r23\0\0\0\0\0\0" \ + "r24\0\0\0\0\0\0r25\0\0\0\0\0\0r26\0\0\0\0\0\0r27\0\0\0\0\0\0" \ + "r28\0\0\0\0\0\0r29\0\0\0\0\0\0r30\0\0\0\0\0\0r31\0\0\0\0\0\0" \ + "r32\0\0\0\0\0\0r33\0\0\0\0\0\0r34\0\0\0\0\0\0r35\0\0\0\0\0\0" \ + "r36\0\0\0\0\0\0r37\0\0\0\0\0\0r38\0\0\0\0\0\0r39\0\0\0\0\0\0" \ + "r40\0\0\0\0\0\0r41\0\0\0\0\0\0r42\0\0\0\0\0\0r43\0\0\0\0\0\0" \ + "r44\0\0\0\0\0\0r45\0\0\0\0\0\0r46\0\0\0\0\0\0r47\0\0\0\0\0\0" \ + "r48\0\0\0\0\0\0r49\0\0\0\0\0\0r50\0\0\0\0\0\0r51\0\0\0\0\0\0" \ + "r52\0\0\0\0\0\0r53\0\0\0\0\0\0r54\0\0\0\0\0\0r55\0\0\0\0\0\0" \ + "r56\0\0\0\0\0\0r57\0\0\0\0\0\0r58\0\0\0\0\0\0r59\0\0\0\0\0\0" \ + "r60\0\0\0\0\0\0r61\0\0\0\0\0\0r62\0\0\0\0\0\0r63\0\0\0\0\0\0" \ + "r64\0\0\0\0\0\0r65\0\0\0\0\0\0r66\0\0\0\0\0\0r67\0\0\0\0\0\0" \ + "r68\0\0\0\0\0\0r69\0\0\0\0\0\0r70\0\0\0\0\0\0r71\0\0\0\0\0\0" \ + "r72\0\0\0\0\0\0r73\0\0\0\0\0\0r74\0\0\0\0\0\0r75\0\0\0\0\0\0" \ + "r76\0\0\0\0\0\0r77\0\0\0\0\0\0r78\0\0\0\0\0\0r79\0\0\0\0\0\0" \ + "r80\0\0\0\0\0\0r81\0\0\0\0\0\0r82\0\0\0\0\0\0r83\0\0\0\0\0\0" \ + "r84\0\0\0\0\0\0r85\0\0\0\0\0\0r86\0\0\0\0\0\0r87\0\0\0\0\0\0" \ + "r88\0\0\0\0\0\0r89\0\0\0\0\0\0r90\0\0\0\0\0\0r91\0\0\0\0\0\0" \ + "r92\0\0\0\0\0\0r93\0\0\0\0\0\0r94\0\0\0\0\0\0r95\0\0\0\0\0\0" \ + "r96\0\0\0\0\0\0r97\0\0\0\0\0\0r98\0\0\0\0\0\0r99\0\0\0\0\0\0" \ + "r100\0\0\0\0\0r101\0\0\0\0\0r102\0\0\0\0\0r103\0\0\0\0\0" \ + "r104\0\0\0\0\0r105\0\0\0\0\0r106\0\0\0\0\0r107\0\0\0\0\0" \ + "r108\0\0\0\0\0r109\0\0\0\0\0r110\0\0\0\0\0r111\0\0\0\0\0" \ + "r112\0\0\0\0\0r113\0\0\0\0\0r114\0\0\0\0\0r115\0\0\0\0\0" \ + "r116\0\0\0\0\0r117\0\0\0\0\0r118\0\0\0\0\0r119\0\0\0\0\0" \ + "r120\0\0\0\0\0r121\0\0\0\0\0r122\0\0\0\0\0r123\0\0\0\0\0" \ + "r124\0\0\0\0\0r125\0\0\0\0\0r126\0\0\0\0\0r127\0\0\0\0\0" \ + "nat0\0\0\0\0\0nat1\0\0\0\0\0nat2\0\0\0\0\0nat3\0\0\0\0\0" \ + "nat4\0\0\0\0\0nat5\0\0\0\0\0nat6\0\0\0\0\0nat7\0\0\0\0\0" \ + "nat8\0\0\0\0\0nat9\0\0\0\0\0nat10\0\0\0\0nat11\0\0\0\0" \ + "nat12\0\0\0\0nat13\0\0\0\0nat14\0\0\0\0nat15\0\0\0\0" \ + "nat16\0\0\0\0nat17\0\0\0\0nat18\0\0\0\0nat19\0\0\0\0" \ + "nat20\0\0\0\0nat21\0\0\0\0nat22\0\0\0\0nat23\0\0\0\0" \ + "nat24\0\0\0\0nat25\0\0\0\0nat26\0\0\0\0nat27\0\0\0\0" \ + "nat28\0\0\0\0nat29\0\0\0\0nat30\0\0\0\0nat31\0\0\0\0" \ + "nat32\0\0\0\0nat33\0\0\0\0nat34\0\0\0\0nat35\0\0\0\0" \ + "nat36\0\0\0\0nat37\0\0\0\0nat38\0\0\0\0nat39\0\0\0\0" \ + "nat40\0\0\0\0nat41\0\0\0\0nat42\0\0\0\0nat43\0\0\0\0" \ + "nat44\0\0\0\0nat45\0\0\0\0nat46\0\0\0\0nat47\0\0\0\0" \ + "nat48\0\0\0\0nat49\0\0\0\0nat50\0\0\0\0nat51\0\0\0\0" \ + "nat52\0\0\0\0nat53\0\0\0\0nat54\0\0\0\0nat55\0\0\0\0" \ + "nat56\0\0\0\0nat57\0\0\0\0nat58\0\0\0\0nat59\0\0\0\0" \ + "nat60\0\0\0\0nat61\0\0\0\0nat62\0\0\0\0nat63\0\0\0\0" \ + "nat64\0\0\0\0nat65\0\0\0\0nat66\0\0\0\0nat67\0\0\0\0" \ + "nat68\0\0\0\0nat69\0\0\0\0nat70\0\0\0\0nat71\0\0\0\0" \ + "nat72\0\0\0\0nat73\0\0\0\0nat74\0\0\0\0nat75\0\0\0\0" \ + "nat76\0\0\0\0nat77\0\0\0\0nat78\0\0\0\0nat79\0\0\0\0" \ + "nat80\0\0\0\0nat81\0\0\0\0nat82\0\0\0\0nat83\0\0\0\0" \ + "nat84\0\0\0\0nat85\0\0\0\0nat86\0\0\0\0nat87\0\0\0\0" \ + "nat88\0\0\0\0nat89\0\0\0\0nat90\0\0\0\0nat91\0\0\0\0" \ + "nat92\0\0\0\0nat93\0\0\0\0nat94\0\0\0\0nat95\0\0\0\0" \ + "nat96\0\0\0\0nat97\0\0\0\0nat98\0\0\0\0nat99\0\0\0\0" \ + "nat100\0\0\0nat101\0\0\0nat102\0\0\0nat103\0\0\0" \ + "nat104\0\0\0nat105\0\0\0nat106\0\0\0nat107\0\0\0" \ + "nat108\0\0\0nat109\0\0\0nat110\0\0\0nat111\0\0\0" \ + "nat112\0\0\0nat113\0\0\0nat114\0\0\0nat115\0\0\0" \ + "nat116\0\0\0nat117\0\0\0nat118\0\0\0nat119\0\0\0" \ + "nat120\0\0\0nat121\0\0\0nat122\0\0\0nat123\0\0\0" \ + "nat124\0\0\0nat125\0\0\0nat126\0\0\0nat127\0\0\0" \ + "f0\0\0\0\0\0\0\0f1\0\0\0\0\0\0\0f2\0\0\0\0\0\0\0f3\0\0\0\0\0\0\0" \ + "f4\0\0\0\0\0\0\0f5\0\0\0\0\0\0\0f6\0\0\0\0\0\0\0f7\0\0\0\0\0\0\0" \ + "f8\0\0\0\0\0\0\0f9\0\0\0\0\0\0\0f10\0\0\0\0\0\0f11\0\0\0\0\0\0" \ + "f12\0\0\0\0\0\0f13\0\0\0\0\0\0f14\0\0\0\0\0\0f15\0\0\0\0\0\0" \ + "f16\0\0\0\0\0\0f17\0\0\0\0\0\0f18\0\0\0\0\0\0f19\0\0\0\0\0\0" \ + "f20\0\0\0\0\0\0f21\0\0\0\0\0\0f22\0\0\0\0\0\0f23\0\0\0\0\0\0" \ + "f24\0\0\0\0\0\0f25\0\0\0\0\0\0f26\0\0\0\0\0\0f27\0\0\0\0\0\0" \ + "f28\0\0\0\0\0\0f29\0\0\0\0\0\0f30\0\0\0\0\0\0f31\0\0\0\0\0\0" \ + "f32\0\0\0\0\0\0f33\0\0\0\0\0\0f34\0\0\0\0\0\0f35\0\0\0\0\0\0" \ + "f36\0\0\0\0\0\0f37\0\0\0\0\0\0f38\0\0\0\0\0\0f39\0\0\0\0\0\0" \ + "f40\0\0\0\0\0\0f41\0\0\0\0\0\0f42\0\0\0\0\0\0f43\0\0\0\0\0\0" \ + "f44\0\0\0\0\0\0f45\0\0\0\0\0\0f46\0\0\0\0\0\0f47\0\0\0\0\0\0" \ + "f48\0\0\0\0\0\0f49\0\0\0\0\0\0f50\0\0\0\0\0\0f51\0\0\0\0\0\0" \ + "f52\0\0\0\0\0\0f53\0\0\0\0\0\0f54\0\0\0\0\0\0f55\0\0\0\0\0\0" \ + "f56\0\0\0\0\0\0f57\0\0\0\0\0\0f58\0\0\0\0\0\0f59\0\0\0\0\0\0" \ + "f60\0\0\0\0\0\0f61\0\0\0\0\0\0f62\0\0\0\0\0\0f63\0\0\0\0\0\0" \ + "f64\0\0\0\0\0\0f65\0\0\0\0\0\0f66\0\0\0\0\0\0f67\0\0\0\0\0\0" \ + "f68\0\0\0\0\0\0f69\0\0\0\0\0\0f70\0\0\0\0\0\0f71\0\0\0\0\0\0" \ + "f72\0\0\0\0\0\0f73\0\0\0\0\0\0f74\0\0\0\0\0\0f75\0\0\0\0\0\0" \ + "f76\0\0\0\0\0\0f77\0\0\0\0\0\0f78\0\0\0\0\0\0f79\0\0\0\0\0\0" \ + "f80\0\0\0\0\0\0f81\0\0\0\0\0\0f82\0\0\0\0\0\0f83\0\0\0\0\0\0" \ + "f84\0\0\0\0\0\0f85\0\0\0\0\0\0f86\0\0\0\0\0\0f87\0\0\0\0\0\0" \ + "f88\0\0\0\0\0\0f89\0\0\0\0\0\0f90\0\0\0\0\0\0f91\0\0\0\0\0\0" \ + "f92\0\0\0\0\0\0f93\0\0\0\0\0\0f94\0\0\0\0\0\0f95\0\0\0\0\0\0" \ + "f96\0\0\0\0\0\0f97\0\0\0\0\0\0f98\0\0\0\0\0\0f99\0\0\0\0\0\0" \ + "f100\0\0\0\0\0f101\0\0\0\0\0f102\0\0\0\0\0f103\0\0\0\0\0" \ + "f104\0\0\0\0\0f105\0\0\0\0\0f106\0\0\0\0\0f107\0\0\0\0\0" \ + "f108\0\0\0\0\0f109\0\0\0\0\0f110\0\0\0\0\0f111\0\0\0\0\0" \ + "f112\0\0\0\0\0f113\0\0\0\0\0f114\0\0\0\0\0f115\0\0\0\0\0" \ + "f116\0\0\0\0\0f117\0\0\0\0\0f118\0\0\0\0\0f119\0\0\0\0\0" \ + "f120\0\0\0\0\0f121\0\0\0\0\0f122\0\0\0\0\0f123\0\0\0\0\0" \ + "f124\0\0\0\0\0f125\0\0\0\0\0f126\0\0\0\0\0f127\0\0\0\0\0" \ + "ar0\0\0\0\0\0\0ar1\0\0\0\0\0\0ar2\0\0\0\0\0\0ar3\0\0\0\0\0\0" \ + "ar4\0\0\0\0\0\0ar5\0\0\0\0\0\0ar6\0\0\0\0\0\0ar7\0\0\0\0\0\0" \ + "ar8\0\0\0\0\0\0ar9\0\0\0\0\0\0ar10\0\0\0\0\0ar11\0\0\0\0\0" \ + "ar12\0\0\0\0\0ar13\0\0\0\0\0ar14\0\0\0\0\0ar15\0\0\0\0\0" \ + "rsc\0\0\0\0\0\0bsp\0\0\0\0\0\0bspstore\0rnat\0\0\0\0\0" \ + "ar20\0\0\0\0\0ar21\0\0\0\0\0ar22\0\0\0\0\0ar23\0\0\0\0\0" \ + "ar24\0\0\0\0\0ar25\0\0\0\0\0ar26\0\0\0\0\0ar27\0\0\0\0\0" \ + "ar28\0\0\0\0\0ar29\0\0\0\0\0ar30\0\0\0\0\0ar31\0\0\0\0\0" \ + "ccv\0\0\0\0\0\0ar33\0\0\0\0\0ar34\0\0\0\0\0ar35\0\0\0\0\0" \ + "unat\0\0\0\0\0ar37\0\0\0\0\0ar38\0\0\0\0\0ar39\0\0\0\0\0" \ + "fpsr\0\0\0\0\0ar41\0\0\0\0\0ar42\0\0\0\0\0ar43\0\0\0\0\0" \ + "ar44\0\0\0\0\0ar45\0\0\0\0\0ar46\0\0\0\0\0ar47\0\0\0\0\0" \ + "ar48\0\0\0\0\0ar49\0\0\0\0\0ar50\0\0\0\0\0ar51\0\0\0\0\0" \ + "ar52\0\0\0\0\0ar53\0\0\0\0\0ar54\0\0\0\0\0ar55\0\0\0\0\0" \ + "ar56\0\0\0\0\0ar57\0\0\0\0\0ar58\0\0\0\0\0ar59\0\0\0\0\0" \ + "ar60\0\0\0\0\0ar61\0\0\0\0\0ar62\0\0\0\0\0ar63\0\0\0\0\0" \ + "pfs\0\0\0\0\0\0lc\0\0\0\0\0\0\0ec\0\0\0\0\0\0\0ar67\0\0\0\0\0" \ + "ar68\0\0\0\0\0ar69\0\0\0\0\0ar70\0\0\0\0\0ar71\0\0\0\0\0" \ + "ar72\0\0\0\0\0ar73\0\0\0\0\0ar74\0\0\0\0\0ar75\0\0\0\0\0" \ + "ar76\0\0\0\0\0ar77\0\0\0\0\0ar78\0\0\0\0\0ar79\0\0\0\0\0" \ + "ar80\0\0\0\0\0ar81\0\0\0\0\0ar82\0\0\0\0\0ar83\0\0\0\0\0" \ + "ar84\0\0\0\0\0ar85\0\0\0\0\0ar86\0\0\0\0\0ar87\0\0\0\0\0" \ + "ar88\0\0\0\0\0ar89\0\0\0\0\0ar90\0\0\0\0\0ar91\0\0\0\0\0" \ + "ar92\0\0\0\0\0ar93\0\0\0\0\0ar94\0\0\0\0\0ar95\0\0\0\0\0" \ + "ar96\0\0\0\0\0ar97\0\0\0\0\0ar98\0\0\0\0\0ar99\0\0\0\0\0" \ + "ar100\0\0\0\0ar101\0\0\0\0ar102\0\0\0\0ar103\0\0\0\0" \ + "ar104\0\0\0\0ar105\0\0\0\0ar106\0\0\0\0ar107\0\0\0\0" \ + "ar108\0\0\0\0ar109\0\0\0\0ar110\0\0\0\0ar111\0\0\0\0" \ + "ar112\0\0\0\0ar113\0\0\0\0ar114\0\0\0\0ar115\0\0\0\0" \ + "ar116\0\0\0\0ar117\0\0\0\0ar118\0\0\0\0ar119\0\0\0\0" \ + "ar120\0\0\0\0ar121\0\0\0\0ar122\0\0\0\0ar123\0\0\0\0" \ + "ar124\0\0\0\0ar125\0\0\0\0ar126\0\0\0\0ar127\0\0\0\0" \ + "rp\0\0\0\0\0\0\0b1\0\0\0\0\0\0\0b2\0\0\0\0\0\0\0b3\0\0\0\0\0\0\0" \ + "b4\0\0\0\0\0\0\0b5\0\0\0\0\0\0\0b6\0\0\0\0\0\0\0b7\0\0\0\0\0\0\0" \ + "pr\0\0\0\0\0\0\0cfm\0\0\0\0\0\0bsp\0\0\0\0\0\0ip\0\0\0\0\0\0\0" \ + "sp\0\0\0\0\0\0\0" + +#define NREGS ((int) (sizeof (regname_str) - 1) / regname_len) + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < NREGS) + return regname_str + reg * regname_len; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/regs.h b/src/coreclr/src/pal/src/libunwind/src/ia64/regs.h new file mode 100644 index 00000000000000..a22a818776ffb7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/regs.h @@ -0,0 +1,73 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* Apply rotation to a general register. REG must be in the range 0-127. */ + +static inline int +rotate_gr (struct cursor *c, int reg) +{ + unsigned int rrb_gr, sor; + int preg; + + sor = 8 * ((c->cfm >> 14) & 0xf); + rrb_gr = (c->cfm >> 18) & 0x7f; + + if ((unsigned) (reg - 32) >= sor) + preg = reg; + else + { + preg = reg + rrb_gr; /* apply rotation */ + if ((unsigned) (preg - 32) >= sor) + preg -= sor; /* wrap around */ + } + if (sor) + Debug (15, "sor=%u rrb.gr=%u, r%d -> r%d\n", sor, rrb_gr, reg, preg); + return preg; +} + +/* Apply rotation to a floating-point register. The number REG must + be in the range of 0-127. */ + +static inline int +rotate_fr (struct cursor *c, int reg) +{ + unsigned int rrb_fr; + int preg; + + rrb_fr = (c->cfm >> 25) & 0x7f; + if (reg < 32) + preg = reg; /* register not part of the rotating partition */ + else + { + preg = reg + rrb_fr; /* apply rotation */ + if (preg > 127) + preg -= 96; /* wrap around */ + } + if (rrb_fr) + Debug (15, "rrb.fr=%u, f%d -> f%d\n", rrb_fr, reg, preg); + return preg; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/setjmp.S b/src/coreclr/src/pal/src/libunwind/src/ia64/setjmp.S new file mode 100644 index 00000000000000..384615b840ece9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/setjmp.S @@ -0,0 +1,51 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "jmpbuf.h" + + .align 32 + + .global _setjmp + + .proc _setjmp + +_setjmp: + mov r2 = ar.bsp + st8 [r32] = r12 // jmp_buf[JB_SP] = sp + mov r3 = rp + + adds r16 = JB_RP*8, r32 + adds r17 = JB_BSP*8, r32 + mov r8 = 0 + ;; + st8 [r16] = r3 // jmp_buf[JB_RP] = rp + st8 [r17] = r2 // jmp_buf[JB_BSP] = bsp + br.ret.sptk.many rp + + .endp _setjmp +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/ia64/siglongjmp.S new file mode 100644 index 00000000000000..d77b43753bb29d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/siglongjmp.S @@ -0,0 +1,69 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 SIG_SETMASK 2 + + .global _UI_siglongjmp_cont + .global sigprocmask + + .align 32 + .proc siglongjmp_continuation +siglongjmp_continuation: +_UI_siglongjmp_cont: // non-function label for siglongjmp.c + .prologue + .save rp, r15 + .body + nop 0 + nop 0 + br.call.sptk.many b6 = .next + ;; + .prologue + .save ar.pfs, r33 +.next: alloc loc1 = ar.pfs, 0, 3, 3, 0 + /* + * Note: we can use the scratch stack are because the caller + * of sigsetjmp() by definition is not a leaf-procedure. + */ + st8 [sp] = r17 // store signal mask + .save rp, loc0 + mov loc0 = r15 // final continuation point + ;; + .body + mov loc2 = r16 // value to return in r8 + + mov out0 = SIG_SETMASK + mov out1 = sp + mov out2 = r0 + br.call.sptk.many rp = sigprocmask + ;; + mov rp = loc0 + mov ar.pfs = loc1 + mov r8 = loc2 + br.ret.sptk.many rp + .endp siglongjmp_continuation +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/sigsetjmp.S b/src/coreclr/src/pal/src/libunwind/src/ia64/sigsetjmp.S new file mode 100644 index 00000000000000..02f7af4b377fab --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/sigsetjmp.S @@ -0,0 +1,69 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "jmpbuf.h" + +#define SIG_BLOCK 0 + + .align 32 + + .global __sigsetjmp + .global sigprocmask + + .proc __sigsetjmp + +__sigsetjmp: + .prologue + .save ar.pfs, r35 + alloc loc1 = ar.pfs, 2, 3, 3, 0 + add out2 = JB_MASK*8, in0 + .save rp, loc0 + mov loc0 = rp + mov out0 = SIG_BLOCK + .body + ;; + cmp.ne p6, p0 = in1, r0 + mov out1 = r0 + mov loc2 = ar.bsp +(p6) br.call.sptk.many rp = sigprocmask // sigjmp_buf[JB_MASK] = sigmask + ;; + + add r16 = JB_MASK_SAVED*8, in0 + st8 [in0] = sp, (JB_RP-JB_SP)*8 // sigjmp_buf[JB_SP] = sp + mov r8 = 0 + ;; + st8 [in0] = loc0, (JB_BSP-JB_RP)*8 // sigjmp_buf[JB_RP] = rp + st8 [r16] = in1 // sigjmp_buf[JB_MASK_SAVED] = savemask + mov rp = loc0 + ;; + st8 [in0] = loc2 // sigjmp_buf[JB_BSP] = bsp + mov.i ar.pfs = loc1 + br.ret.sptk.many rp + + .endp __sigsetjmp +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/ia64/ucontext_i.h new file mode 100644 index 00000000000000..ea32c8aaa0922f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/ucontext_i.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2002 Hewlett-Packard Co. + Contributed by David Mosberger-Tang . + +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. */ + +/* Constants shared between setcontext() and getcontext(). Don't + install this header file. */ + +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 1 +#define SIG_SETMASK 2 + +#define IA64_SC_FLAG_SYNCHRONOUS_BIT 63 + +#define SC_FLAGS 0x000 +#define SC_NAT 0x008 +#define SC_BSP 0x048 +#define SC_RNAT 0x050 +#define SC_UNAT 0x060 +#define SC_FPSR 0x068 +#define SC_PFS 0x070 +#define SC_LC 0x078 +#define SC_PR 0x080 +#define SC_BR 0x088 +#define SC_GR 0x0c8 +#define SC_FR 0x1d0 +#define SC_MASK 0x9d0 + + +#define rTMP r10 +#define rPOS r11 +#define rCPOS r14 +#define rNAT r15 +#define rFLAGS r16 + +#define rB5 r18 +#define rB4 r19 +#define rB3 r20 +#define rB2 r21 +#define rB1 r22 +#define rB0 r23 +#define rRSC r24 +#define rBSP r25 +#define rRNAT r26 +#define rUNAT r27 +#define rFPSR r28 +#define rPFS r29 +#define rLC r30 +#define rPR r31 diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_decoder.h b/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_decoder.h new file mode 100644 index 00000000000000..7fd41740de808a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_decoder.h @@ -0,0 +1,477 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* + * Generic IA-64 unwind info decoder. + * + * This file is used both by the Linux kernel and objdump. Please keep + * the two copies of this file in sync. + * + * You need to customize the decoder by defining the following + * macros/constants before including this file: + * + * Types: + * unw_word Unsigned integer type with at least 64 bits + * + * Register names: + * UNW_REG_BSP + * UNW_REG_BSPSTORE + * UNW_REG_FPSR + * UNW_REG_LC + * UNW_REG_PFS + * UNW_REG_PR + * UNW_REG_RNAT + * UNW_REG_PSP + * UNW_REG_RP + * UNW_REG_UNAT + * + * Decoder action macros: + * UNW_DEC_BAD_CODE(code) + * UNW_DEC_ABI(fmt,abi,context,arg) + * UNW_DEC_BR_GR(fmt,brmask,gr,arg) + * UNW_DEC_BR_MEM(fmt,brmask,arg) + * UNW_DEC_COPY_STATE(fmt,label,arg) + * UNW_DEC_EPILOGUE(fmt,t,ecount,arg) + * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg) + * UNW_DEC_FR_MEM(fmt,frmask,arg) + * UNW_DEC_GR_GR(fmt,grmask,gr,arg) + * UNW_DEC_GR_MEM(fmt,grmask,arg) + * UNW_DEC_LABEL_STATE(fmt,label,arg) + * UNW_DEC_MEM_STACK_F(fmt,t,size,arg) + * UNW_DEC_MEM_STACK_V(fmt,t,arg) + * UNW_DEC_PRIUNAT_GR(fmt,r,arg) + * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) + * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) + * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg) + * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg) + * UNW_DEC_PROLOGUE(fmt,body,rlen,arg) + * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg) + * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg) + * UNW_DEC_REG_REG(fmt,src,dst,arg) + * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg) + * UNW_DEC_REG_WHEN(fmt,reg,t,arg) + * UNW_DEC_RESTORE(fmt,t,abreg,arg) + * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg) + * UNW_DEC_SPILL_BASE(fmt,pspoff,arg) + * UNW_DEC_SPILL_MASK(fmt,imaskp,arg) + * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg) + * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg) + * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg) + * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg) + * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg) + * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg) + */ + +static unw_word +unw_decode_uleb128 (unsigned char **dpp) +{ + unsigned shift = 0; + unw_word byte, result = 0; + unsigned char *bp = *dpp; + + while (1) + { + byte = *bp++; + result |= (byte & 0x7f) << shift; + if ((byte & 0x80) == 0) + break; + shift += 7; + } + *dpp = bp; + return result; +} + +static unsigned char * +unw_decode_x1 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char byte1, abreg; + unw_word t, off; + + byte1 = *dp++; + t = unw_decode_uleb128 (&dp); + off = unw_decode_uleb128 (&dp); + abreg = (byte1 & 0x7f); + if (byte1 & 0x80) + UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg); + else + UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg); + return dp; +} + +static unsigned char * +unw_decode_x2 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char byte1, byte2, abreg, x, ytreg; + unw_word t; + + byte1 = *dp++; byte2 = *dp++; + t = unw_decode_uleb128 (&dp); + abreg = (byte1 & 0x7f); + ytreg = byte2; + x = (byte1 >> 7) & 1; + if ((byte1 & 0x80) == 0 && ytreg == 0) + UNW_DEC_RESTORE(X2, t, abreg, arg); + else + UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg); + return dp; +} + +static unsigned char * +unw_decode_x3 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char byte1, byte2, abreg, qp; + unw_word t, off; + + byte1 = *dp++; byte2 = *dp++; + t = unw_decode_uleb128 (&dp); + off = unw_decode_uleb128 (&dp); + + qp = (byte1 & 0x3f); + abreg = (byte2 & 0x7f); + + if (byte1 & 0x80) + UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg); + else + UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg); + return dp; +} + +static unsigned char * +unw_decode_x4 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg; + unw_word t; + + byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; + t = unw_decode_uleb128 (&dp); + + qp = (byte1 & 0x3f); + abreg = (byte2 & 0x7f); + x = (byte2 >> 7) & 1; + ytreg = byte3; + + if ((byte2 & 0x80) == 0 && byte3 == 0) + UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg); + else + UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg); + return dp; +} + +static inline unsigned char * +unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg) +{ + int body = (code & 0x20) != 0; + unw_word rlen; + + rlen = (code & 0x1f); + UNW_DEC_PROLOGUE(R1, body, rlen, arg); + return dp; +} + +static inline unsigned char * +unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char byte1, mask, grsave; + unw_word rlen; + + byte1 = *dp++; + + mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); + grsave = (byte1 & 0x7f); + rlen = unw_decode_uleb128 (&dp); + UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg); + return dp; +} + +static inline unsigned char * +unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg) +{ + unw_word rlen; + + rlen = unw_decode_uleb128 (&dp); + UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg); + return dp; +} + +static inline unsigned char * +unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char brmask = (code & 0x1f); + + UNW_DEC_BR_MEM(P1, brmask, arg); + return dp; +} + +static inline unsigned char * +unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg) +{ + if ((code & 0x10) == 0) + { + unsigned char byte1 = *dp++; + + UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1), + (byte1 & 0x7f), arg); + } + else if ((code & 0x08) == 0) + { + unsigned char byte1 = *dp++, r, dst; + + r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); + dst = (byte1 & 0x7f); + switch (r) + { + case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break; + case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break; + case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break; + case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break; + case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break; + case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break; + case 6: UNW_DEC_RP_BR(P3, dst, arg); break; + case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break; + case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break; + case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break; + case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break; + case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break; + default: UNW_DEC_BAD_CODE(r); break; + } + } + else if ((code & 0x7) == 0) + UNW_DEC_SPILL_MASK(P4, dp, arg); + else if ((code & 0x7) == 1) + { + unw_word grmask, frmask, byte1, byte2, byte3; + + byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; + grmask = ((byte1 >> 4) & 0xf); + frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3; + UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg); + } + else + UNW_DEC_BAD_CODE(code); + return dp; +} + +static inline unsigned char * +unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg) +{ + int gregs = (code & 0x10) != 0; + unsigned char mask = (code & 0x0f); + + if (gregs) + UNW_DEC_GR_MEM(P6, mask, arg); + else + UNW_DEC_FR_MEM(P6, mask, arg); + return dp; +} + +static inline unsigned char * +unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg) +{ + unsigned char r, byte1, byte2; + unw_word t, size; + + if ((code & 0x10) == 0) + { + r = (code & 0xf); + t = unw_decode_uleb128 (&dp); + switch (r) + { + case 0: + size = unw_decode_uleb128 (&dp); + UNW_DEC_MEM_STACK_F(P7, t, size, arg); + break; + + case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break; + case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break; + case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break; + case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break; + case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break; + case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break; + case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break; + case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break; + case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break; + case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break; + case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break; + case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break; + case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break; + case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break; + case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break; + default: UNW_DEC_BAD_CODE(r); break; + } + } + else + { + switch (code & 0xf) + { + case 0x0: /* p8 */ + { + r = *dp++; + t = unw_decode_uleb128 (&dp); + switch (r) + { + case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break; + case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break; + case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break; + case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break; + case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break; + case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break; + case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break; + case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break; + case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break; + case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break; + case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break; + case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break; + case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break; + case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break; + case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break; + case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break; + case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break; + case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break; + case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break; + default: UNW_DEC_BAD_CODE(r); break; + } + } + break; + + case 0x1: + byte1 = *dp++; byte2 = *dp++; + UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg); + break; + + case 0xf: /* p10 */ + byte1 = *dp++; byte2 = *dp++; + UNW_DEC_ABI(P10, byte1, byte2, arg); + break; + + case 0x9: + return unw_decode_x1 (dp, code, arg); + + case 0xa: + return unw_decode_x2 (dp, code, arg); + + case 0xb: + return unw_decode_x3 (dp, code, arg); + + case 0xc: + return unw_decode_x4 (dp, code, arg); + + default: + UNW_DEC_BAD_CODE(code); + break; + } + } + return dp; +} + +static inline unsigned char * +unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg) +{ + unw_word label = (code & 0x1f); + + if ((code & 0x20) != 0) + UNW_DEC_COPY_STATE(B1, label, arg); + else + UNW_DEC_LABEL_STATE(B1, label, arg); + return dp; +} + +static inline unsigned char * +unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg) +{ + unw_word t; + + t = unw_decode_uleb128 (&dp); + UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg); + return dp; +} + +static inline unsigned char * +unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg) +{ + unw_word t, ecount, label; + + if ((code & 0x10) == 0) + { + t = unw_decode_uleb128 (&dp); + ecount = unw_decode_uleb128 (&dp); + UNW_DEC_EPILOGUE(B3, t, ecount, arg); + } + else if ((code & 0x07) == 0) + { + label = unw_decode_uleb128 (&dp); + if ((code & 0x08) != 0) + UNW_DEC_COPY_STATE(B4, label, arg); + else + UNW_DEC_LABEL_STATE(B4, label, arg); + } + else + switch (code & 0x7) + { + case 1: return unw_decode_x1 (dp, code, arg); + case 2: return unw_decode_x2 (dp, code, arg); + case 3: return unw_decode_x3 (dp, code, arg); + case 4: return unw_decode_x4 (dp, code, arg); + default: UNW_DEC_BAD_CODE(code); break; + } + return dp; +} + +typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *); + +/* + * Decode one descriptor and return address of next descriptor. + */ +static inline unsigned char * +unw_decode (unsigned char *dp, int inside_body, void *arg) +{ + unsigned char code, primary; + + code = *dp++; + primary = code >> 5; + + if (primary < 2) + dp = unw_decode_r1 (dp, code, arg); + else if (primary == 2) + dp = unw_decode_r2 (dp, code, arg); + else if (primary == 3) + dp = unw_decode_r3 (dp, code, arg); + else if (inside_body) + switch (primary) + { + case 4: + case 5: dp = unw_decode_b1 (dp, code, arg); break; + case 6: dp = unw_decode_b2 (dp, code, arg); break; + case 7: dp = unw_decode_b3_x4 (dp, code, arg); break; + } + else + switch (primary) + { + case 4: dp = unw_decode_p1 (dp, code, arg); break; + case 5: dp = unw_decode_p2_p5 (dp, code, arg); break; + case 6: dp = unw_decode_p6 (dp, code, arg); break; + case 7: dp = unw_decode_p7_p10 (dp, code, arg); break; + } + return dp; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_i.h new file mode 100644 index 00000000000000..8ccbb46c93067f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/unwind_i.h @@ -0,0 +1,633 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 unwind_i_h +#define unwind_i_h + +#include +#include + +#include + +#include "rse.h" + +#include "libunwind_i.h" + +#define IA64_UNW_VER(x) ((x) >> 48) +#define IA64_UNW_FLAG_MASK ((unw_word_t) 0x0000ffff00000000ULL) +#define IA64_UNW_FLAG_OSMASK ((unw_word_t) 0x0000f00000000000ULL) +#define IA64_UNW_FLAG_EHANDLER(x) ((x) & (unw_word_t) 0x0000000100000000ULL) +#define IA64_UNW_FLAG_UHANDLER(x) ((x) & (unw_word_t) 0x0000000200000000ULL) +#define IA64_UNW_LENGTH(x) ((x) & (unw_word_t) 0x00000000ffffffffULL) + +#ifdef MIN +# undef MIN +#endif +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +#if !defined(HAVE_SYS_UC_ACCESS_H) && !defined(UNW_REMOTE_ONLY) + +static ALWAYS_INLINE void * +inlined_uc_addr (ucontext_t *uc, int reg, uint8_t *nat_bitnr) +{ + unw_word_t reg_addr; + void *addr; + + switch (reg) + { + case UNW_IA64_GR + 0: addr = &unw.read_only.r0; break; + case UNW_IA64_NAT + 0: addr = &unw.read_only.r0; break; + case UNW_IA64_FR + 0: addr = &unw.read_only.f0; break; + case UNW_IA64_FR + 1: + if (__BYTE_ORDER == __BIG_ENDIAN) + addr = &unw.read_only.f1_be; + else + addr = &unw.read_only.f1_le; + break; + case UNW_IA64_IP: addr = &uc->uc_mcontext.sc_br[0]; break; + case UNW_IA64_CFM: addr = &uc->uc_mcontext.sc_ar_pfs; break; + case UNW_IA64_AR_RNAT: addr = &uc->uc_mcontext.sc_ar_rnat; break; + case UNW_IA64_AR_UNAT: addr = &uc->uc_mcontext.sc_ar_unat; break; + case UNW_IA64_AR_LC: addr = &uc->uc_mcontext.sc_ar_lc; break; + case UNW_IA64_AR_FPSR: addr = &uc->uc_mcontext.sc_ar_fpsr; break; + case UNW_IA64_PR: addr = &uc->uc_mcontext.sc_pr; break; + case UNW_IA64_AR_BSPSTORE: addr = &uc->uc_mcontext.sc_ar_bsp; break; + + case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: + case UNW_IA64_GR + 12: + addr = &uc->uc_mcontext.sc_gr[reg - UNW_IA64_GR]; + break; + + case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7: + case UNW_IA64_NAT + 12: + addr = &uc->uc_mcontext.sc_nat; + reg_addr = (unw_word_t) &uc->uc_mcontext.sc_gr[reg - UNW_IA64_NAT]; + *nat_bitnr = reg - UNW_IA64_NAT; + break; + + case UNW_IA64_BR + 1 ... UNW_IA64_BR + 5: + addr = &uc->uc_mcontext.sc_br[reg - UNW_IA64_BR]; + break; + + case UNW_IA64_FR+ 2 ... UNW_IA64_FR+ 5: + case UNW_IA64_FR+16 ... UNW_IA64_FR+31: + addr = &uc->uc_mcontext.sc_fr[reg - UNW_IA64_FR]; + break; + + default: + addr = NULL; + } + return addr; +} + +static inline void * +uc_addr (ucontext_t *uc, int reg, uint8_t *nat_bitnr) +{ + if (__builtin_constant_p (reg)) + return inlined_uc_addr (uc, reg, nat_bitnr); + else + return tdep_uc_addr (uc, reg, nat_bitnr); +} + +/* Return TRUE if ADDR points inside unw.read_only_reg. */ + +static inline long +ia64_read_only_reg (void *addr) +{ + return ((unsigned long) ((char *) addr - (char *) &unw.read_only) + < sizeof (unw.read_only)); +} + +#endif /* !defined(HAVE_SYS_UC_ACCESS_H) && !defined(UNW_REMOTE_ONLY) */ + +/* Bits 0 and 1 of a location are used to encode its type: + bit 0: set if location uses floating-point format. + bit 1: set if location is a NaT bit on memory stack. */ + +#define IA64_LOC_TYPE_FP (1 << 0) +#define IA64_LOC_TYPE_MEMSTK_NAT (1 << 1) + +#ifdef UNW_LOCAL_ONLY +#define IA64_LOC_REG(r,t) (((r) << 2) | (t)) +#define IA64_LOC_ADDR(a,t) (((a) & ~0x3) | (t)) +#define IA64_LOC_UC_ADDR(a,t) IA64_LOC_ADDR(a, t) +#define IA64_NULL_LOC (0) + +#define IA64_GET_REG(l) ((l) >> 2) +#define IA64_GET_ADDR(l) ((l) & ~0x3) +#define IA64_IS_NULL_LOC(l) ((l) == 0) +#define IA64_IS_FP_LOC(l) (((l) & IA64_LOC_TYPE_FP) != 0) +#define IA64_IS_MEMSTK_NAT(l) (((l) & IA64_LOC_TYPE_MEMSTK_NAT) != 0) +#define IA64_IS_REG_LOC(l) 0 +#define IA64_IS_UC_LOC(l) 0 + +#define IA64_REG_LOC(c,r) ((unw_word_t) uc_addr((c)->as_arg, r, NULL)) +#define IA64_REG_NAT_LOC(c,r,n) ((unw_word_t) uc_addr((c)->as_arg, r, n)) +#define IA64_FPREG_LOC(c,r) \ + ((unw_word_t) uc_addr((c)->as_arg, (r), NULL) | IA64_LOC_TYPE_FP) + +# define ia64_find_proc_info(c,ip,n) \ + tdep_find_proc_info(unw_local_addr_space, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define ia64_put_unwind_info(c, pi) do { ; } while (0) + +/* Note: the register accessors (ia64_{get,set}{,fp}()) must check for + NULL locations because uc_addr() returns NULL for unsaved + registers. */ + +static inline int +ia64_getfp (struct cursor *c, unw_word_t loc, unw_fpreg_t *val) +{ + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + *val = *(unw_fpreg_t *) IA64_GET_ADDR (loc); + return 0; +} + +static inline int +ia64_putfp (struct cursor *c, unw_word_t loc, unw_fpreg_t val) +{ + unw_fpreg_t *addr = (unw_fpreg_t *) IA64_GET_ADDR (loc); + + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + else if (ia64_read_only_reg (addr)) + { + Debug (16, "attempt to read-only register\n"); + return -UNW_EREADONLYREG; + } + *addr = val; + return 0; +} + +static inline int +ia64_get (struct cursor *c, unw_word_t loc, unw_word_t *val) +{ + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + *val = *(unw_word_t *) IA64_GET_ADDR (loc); + return 0; +} + +static inline int +ia64_put (struct cursor *c, unw_word_t loc, unw_word_t val) +{ + unw_word_t *addr = (unw_word_t *) IA64_GET_ADDR (loc); + + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + else if (ia64_read_only_reg (addr)) + { + Debug (16, "attempt to read-only register\n"); + return -UNW_EREADONLYREG; + } + *addr = val; + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +/* Bits 0 and 1 of the second word (w1) of a location are used + to further distinguish what location we're dealing with: + + bit 0: set if the location is a register + bit 1: set of the location is accessed via uc_access(3) */ +#define IA64_LOC_TYPE_REG (1 << 0) +#define IA64_LOC_TYPE_UC (1 << 1) + +#define IA64_LOC_REG(r,t) ((ia64_loc_t) { ((r) << 2) | (t), \ + IA64_LOC_TYPE_REG }) +#define IA64_LOC_ADDR(a,t) ((ia64_loc_t) { ((a) & ~0x3) | (t), 0 }) +#define IA64_LOC_UC_ADDR(a,t) ((ia64_loc_t) { ((a) & ~0x3) | (t), \ + IA64_LOC_TYPE_UC }) +#define IA64_LOC_UC_REG(r,a) ((ia64_loc_t) { ((r) << 2), \ + ((a) | IA64_LOC_TYPE_REG \ + | IA64_LOC_TYPE_UC) }) +#define IA64_NULL_LOC ((ia64_loc_t) { 0, 0 }) + +#define IA64_GET_REG(l) ((l).w0 >> 2) +#define IA64_GET_ADDR(l) ((l).w0 & ~0x3) +#define IA64_GET_AUX_ADDR(l) ((l).w1 & ~0x3) +#define IA64_IS_NULL_LOC(l) (((l).w0 | (l).w1) == 0) +#define IA64_IS_FP_LOC(l) (((l).w0 & IA64_LOC_TYPE_FP) != 0) +#define IA64_IS_MEMSTK_NAT(l) (((l).w0 & IA64_LOC_TYPE_MEMSTK_NAT) != 0) +#define IA64_IS_REG_LOC(l) (((l).w1 & IA64_LOC_TYPE_REG) != 0) +#define IA64_IS_UC_LOC(l) (((l).w1 & IA64_LOC_TYPE_UC) != 0) + +#define IA64_REG_LOC(c,r) IA64_LOC_REG ((r), 0) +#define IA64_REG_NAT_LOC(c,r,n) IA64_LOC_REG ((r), 0) +#define IA64_FPREG_LOC(c,r) IA64_LOC_REG ((r), IA64_LOC_TYPE_FP) + +# define ia64_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define ia64_put_unwind_info(c,pi) \ + (*(c)->as->acc.put_unwind_info)((c)->as, (pi), (c)->as_arg) + +#define ia64_uc_access_reg UNW_OBJ(uc_access_reg) +#define ia64_uc_access_fpreg UNW_OBJ(uc_access_fpreg) + +extern int ia64_uc_access_reg (struct cursor *c, ia64_loc_t loc, + unw_word_t *valp, int write); +extern int ia64_uc_access_fpreg (struct cursor *c, ia64_loc_t loc, + unw_fpreg_t *valp, int write); + +static inline int +ia64_getfp (struct cursor *c, ia64_loc_t loc, unw_fpreg_t *val) +{ + unw_word_t addr; + int ret; + + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + + if (IA64_IS_UC_LOC (loc)) + return ia64_uc_access_fpreg (c, loc, val, 0); + + if (IA64_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, IA64_GET_REG (loc), + val, 0, c->as_arg); + + addr = IA64_GET_ADDR (loc); + ret = (*c->as->acc.access_mem) (c->as, addr + 0, &val->raw.bits[0], 0, + c->as_arg); + if (ret < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, &val->raw.bits[1], 0, + c->as_arg); +} + +static inline int +ia64_putfp (struct cursor *c, ia64_loc_t loc, unw_fpreg_t val) +{ + unw_word_t addr; + int ret; + + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + + if (IA64_IS_UC_LOC (loc)) + return ia64_uc_access_fpreg (c, loc, &val, 1); + + if (IA64_IS_REG_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, IA64_GET_REG (loc), &val, 1, + c->as_arg); + + addr = IA64_GET_ADDR (loc); + ret = (*c->as->acc.access_mem) (c->as, addr + 0, &val.raw.bits[0], 1, + c->as_arg); + if (ret < 0) + return ret; + + return (*c->as->acc.access_mem) (c->as, addr + 8, &val.raw.bits[1], 1, + c->as_arg); +} + +/* Get the 64 data bits from location LOC. If bit 0 is cleared, LOC + is a memory address, otherwise it is a register number. If the + register is a floating-point register, the 64 bits are read from + the significand bits. */ + +static inline int +ia64_get (struct cursor *c, ia64_loc_t loc, unw_word_t *val) +{ + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + + if (IA64_IS_FP_LOC (loc)) + { + unw_fpreg_t tmp; + int ret; + + ret = ia64_getfp (c, loc, &tmp); + if (ret < 0) + return ret; + + if (c->as->big_endian) + *val = tmp.raw.bits[1]; + else + *val = tmp.raw.bits[0]; + return 0; + } + + if (IA64_IS_UC_LOC (loc)) + return ia64_uc_access_reg (c, loc, val, 0); + + if (IA64_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg)(c->as, IA64_GET_REG (loc), val, 0, + c->as_arg); + else + return (*c->as->acc.access_mem)(c->as, IA64_GET_ADDR (loc), val, 0, + c->as_arg); +} + +static inline int +ia64_put (struct cursor *c, ia64_loc_t loc, unw_word_t val) +{ + if (IA64_IS_NULL_LOC (loc)) + { + Debug (16, "access to unsaved register\n"); + return -UNW_EBADREG; + } + + if (IA64_IS_FP_LOC (loc)) + { + unw_fpreg_t tmp; + + memset (&tmp, 0, sizeof (tmp)); + if (c->as->big_endian) + tmp.raw.bits[1] = val; + else + tmp.raw.bits[0] = val; + return ia64_putfp (c, loc, tmp); + } + + if (IA64_IS_UC_LOC (loc)) + return ia64_uc_access_reg (c, loc, &val, 1); + + if (IA64_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg)(c->as, IA64_GET_REG (loc), &val, 1, + c->as_arg); + else + return (*c->as->acc.access_mem)(c->as, IA64_GET_ADDR (loc), &val, 1, + c->as_arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +struct ia64_unwind_block + { + unw_word_t header; + unw_word_t desc[0]; /* unwind descriptors */ + + /* Personality routine and language-specific data follow behind + descriptors. */ + }; + +enum ia64_where + { + IA64_WHERE_NONE, /* register isn't saved at all */ + IA64_WHERE_GR, /* register is saved in a general register */ + IA64_WHERE_FR, /* register is saved in a floating-point register */ + IA64_WHERE_BR, /* register is saved in a branch register */ + IA64_WHERE_SPREL, /* register is saved on memstack (sp-relative) */ + IA64_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */ + + /* At the end of each prologue these locations get resolved to + IA64_WHERE_PSPREL and IA64_WHERE_GR, respectively: */ + + IA64_WHERE_SPILL_HOME, /* register is saved in its spill home */ + IA64_WHERE_GR_SAVE /* register is saved in next general register */ + }; + +#define IA64_WHEN_NEVER 0x7fffffff + +struct ia64_reg_info + { + unw_word_t val; /* save location: register number or offset */ + enum ia64_where where; /* where the register gets saved */ + int when; /* when the register gets saved */ + }; + +struct ia64_labeled_state; /* opaque structure */ + +struct ia64_reg_state + { + struct ia64_reg_state *next; /* next (outer) element on state stack */ + struct ia64_reg_info reg[IA64_NUM_PREGS]; /* register save locations */ + }; + +struct ia64_state_record + { + unsigned int first_region : 1; /* is this the first region? */ + unsigned int done : 1; /* are we done scanning descriptors? */ + unsigned int any_spills : 1; /* got any register spills? */ + unsigned int in_body : 1; /* are we inside prologue or body? */ + uint8_t *imask; /* imask of spill_mask record or NULL */ + uint16_t abi_marker; + + unw_word_t pr_val; /* predicate values */ + unw_word_t pr_mask; /* predicate mask */ + + long spill_offset; /* psp-relative offset for spill base */ + int region_start; + int region_len; + int when_sp_restored; + int epilogue_count; + int when_target; + + uint8_t gr_save_loc; /* next save register */ + uint8_t return_link_reg; /* branch register used as return pointer */ + + struct ia64_labeled_state *labeled_states; + struct ia64_reg_state curr; + }; + +struct ia64_labeled_state + { + struct ia64_labeled_state *next; /* next label (or NULL) */ + unsigned long label; /* label for this state */ + struct ia64_reg_state saved_state; + }; + +/* Convenience macros: */ +#define ia64_make_proc_info UNW_OBJ(make_proc_info) +#define ia64_fetch_proc_info UNW_OBJ(fetch_proc_info) +#define ia64_create_state_record UNW_OBJ(create_state_record) +#define ia64_free_state_record UNW_OBJ(free_state_record) +#define ia64_find_save_locs UNW_OBJ(find_save_locs) +#define ia64_validate_cache UNW_OBJ(ia64_validate_cache) +#define ia64_local_validate_cache UNW_OBJ(ia64_local_validate_cache) +#define ia64_per_thread_cache UNW_OBJ(per_thread_cache) +#define ia64_scratch_loc UNW_OBJ(scratch_loc) +#define ia64_local_resume UNW_OBJ(local_resume) +#define ia64_local_addr_space_init UNW_OBJ(local_addr_space_init) +#define ia64_strloc UNW_OBJ(strloc) +#define ia64_install_cursor UNW_OBJ(install_cursor) +#define rbs_switch UNW_OBJ(rbs_switch) +#define rbs_find_stacked UNW_OBJ(rbs_find_stacked) + +extern int ia64_make_proc_info (struct cursor *c); +extern int ia64_fetch_proc_info (struct cursor *c, unw_word_t ip, + int need_unwind_info); +/* The proc-info must be valid for IP before this routine can be + called: */ +extern int ia64_create_state_record (struct cursor *c, + struct ia64_state_record *sr); +extern int ia64_free_state_record (struct ia64_state_record *sr); +extern int ia64_find_save_locs (struct cursor *c); +extern void ia64_validate_cache (unw_addr_space_t as, void *arg); +extern int ia64_local_validate_cache (unw_addr_space_t as, void *arg); +extern void ia64_local_addr_space_init (void); +extern ia64_loc_t ia64_scratch_loc (struct cursor *c, unw_regnum_t reg, + uint8_t *nat_bitnr); + +extern NORETURN void ia64_install_cursor (struct cursor *c, + unw_word_t pri_unat, + unw_word_t *extra, + unw_word_t bspstore, + unw_word_t dirty_size, + unw_word_t *dirty_partition, + unw_word_t dirty_rnat); +extern int ia64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +extern int rbs_switch (struct cursor *c, + unw_word_t saved_bsp, unw_word_t saved_bspstore, + ia64_loc_t saved_rnat_loc); +extern int rbs_find_stacked (struct cursor *c, unw_word_t regs_to_skip, + ia64_loc_t *locp, ia64_loc_t *rnat_locp); + +#ifndef UNW_REMOTE_ONLY +# define NEED_RBS_COVER_AND_FLUSH +# define rbs_cover_and_flush UNW_OBJ(rbs_cover_and_flush) + extern int rbs_cover_and_flush (struct cursor *c, unw_word_t nregs, + unw_word_t *dirty_partition, + unw_word_t *dirty_rnat, + unw_word_t *bspstore); +#endif + +/* Warning: ia64_strloc() is for debugging only and it is NOT re-entrant! */ +extern const char *ia64_strloc (ia64_loc_t loc); + +/* Return true if the register-backing store is inside a ucontext_t + that needs to be accessed via uc_access(3). */ + +static inline int +rbs_on_uc (struct rbs_area *rbs) +{ + return IA64_IS_UC_LOC (rbs->rnat_loc) && !IA64_IS_REG_LOC (rbs->rnat_loc); +} + +/* Return true if BSP points to a word that's stored on register + backing-store RBS. */ +static inline int +rbs_contains (struct rbs_area *rbs, unw_word_t bsp) +{ + int result; + + /* Caveat: this takes advantage of unsigned arithmetic. The full + test is (bsp >= rbs->end - rbs->size) && (bsp < rbs->end). We + take advantage of the fact that -n == ~n + 1. */ + result = bsp - rbs->end > ~rbs->size; + Debug (16, "0x%lx in [0x%lx-0x%lx) => %d\n", + (long) bsp, (long) (rbs->end - rbs->size), (long) rbs->end, result); + return result; +} + +static inline ia64_loc_t +rbs_get_rnat_loc (struct rbs_area *rbs, unw_word_t bsp) +{ + unw_word_t rnat_addr = rse_rnat_addr (bsp); + ia64_loc_t rnat_loc; + + if (rbs_contains (rbs, rnat_addr)) + { + if (rbs_on_uc (rbs)) + rnat_loc = IA64_LOC_UC_ADDR (rnat_addr, 0); + else + rnat_loc = IA64_LOC_ADDR (rnat_addr, 0); + } + else + rnat_loc = rbs->rnat_loc; + return rnat_loc; +} + +static inline ia64_loc_t +rbs_loc (struct rbs_area *rbs, unw_word_t bsp) +{ + if (rbs_on_uc (rbs)) + return IA64_LOC_UC_ADDR (bsp, 0); + else + return IA64_LOC_ADDR (bsp, 0); +} + +static inline int +ia64_get_stacked (struct cursor *c, unw_word_t reg, + ia64_loc_t *locp, ia64_loc_t *rnat_locp) +{ + struct rbs_area *rbs = c->rbs_area + c->rbs_curr; + unw_word_t addr, regs_to_skip = reg - 32; + int ret = 0; + + assert (reg >= 32 && reg < 128); + + addr = rse_skip_regs (c->bsp, regs_to_skip); + if (locp) + *locp = rbs_loc (rbs, addr); + if (rnat_locp) + *rnat_locp = rbs_get_rnat_loc (rbs, addr); + + if (!rbs_contains (rbs, addr)) + ret = rbs_find_stacked (c, regs_to_skip, locp, rnat_locp); + return ret; +} + +/* The UNaT slot # calculation is identical to the one for RNaT slots, + but for readability/clarity, we don't want to use + ia64_rnat_slot_num() directly. */ +#define ia64_unat_slot_num(addr) rse_slot_num(addr) + +/* The following are helper macros which makes it easier for libunwind + to be used in the kernel. They allow the kernel to optimize away + any unused code without littering everything with #ifdefs. */ +#define ia64_is_big_endian(c) ((c)->as->big_endian) +#define ia64_get_abi(c) ((c)->as->abi) +#define ia64_set_abi(c, v) ((c)->as->abi = (v)) +#define ia64_get_abi_marker(c) ((c)->last_abi_marker) + +/* XXX should be in glibc: */ +#ifndef IA64_SC_FLAG_ONSTACK +# define IA64_SC_FLAG_ONSTACK_BIT 0 /* running on signal stack? */ +# define IA64_SC_FLAG_IN_SYSCALL_BIT 1 /* did signal interrupt a syscall? */ +# define IA64_SC_FLAG_FPH_VALID_BIT 2 /* is state in f[32]-f[127] valid? */ + +# define IA64_SC_FLAG_ONSTACK (1 << IA64_SC_FLAG_ONSTACK_BIT) +# define IA64_SC_FLAG_IN_SYSCALL (1 << IA64_SC_FLAG_IN_SYSCALL_BIT) +# define IA64_SC_FLAG_FPH_VALID (1 << IA64_SC_FLAG_FPH_VALID_BIT) +#endif + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/libunwind-generic.pc.in b/src/coreclr/src/pal/src/libunwind/src/libunwind-generic.pc.in new file mode 100644 index 00000000000000..1f3baffe5bd147 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/libunwind-generic.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libunwind-generic +Description: libunwind generic library +Version: @VERSION@ +Requires: libunwind +Libs: -L${libdir} -lunwind-generic +Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gdestroy_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gdestroy_addr_space.c new file mode 100644 index 00000000000000..504558e1a7880c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gdestroy_addr_space.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +void +unw_destroy_addr_space (unw_addr_space_t as) +{ +#ifndef UNW_LOCAL_ONLY +# if UNW_DEBUG + memset (as, 0, sizeof (*as)); +# endif + free (as); +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-extract.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-extract.c new file mode 100644 index 00000000000000..5f7682e650d794 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-extract.c @@ -0,0 +1,64 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN int +unwi_extract_dynamic_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, unw_dyn_info_t *di, + int need_unwind_info, void *arg) +{ + pi->start_ip = di->start_ip; + pi->end_ip = di->end_ip; + pi->gp = di->gp; + pi->format = di->format; + switch (di->format) + { + case UNW_INFO_FORMAT_DYNAMIC: + pi->handler = di->u.pi.handler; + pi->lsda = 0; + pi->flags = di->u.pi.flags; + pi->unwind_info_size = 0; + if (need_unwind_info) + pi->unwind_info = di; + else + pi->unwind_info = NULL; + return 0; + + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: + case UNW_INFO_FORMAT_ARM_EXIDX: + case UNW_INFO_FORMAT_IP_OFFSET: +#ifdef tdep_search_unwind_table + /* call platform-specific search routine: */ + return tdep_search_unwind_table (as, ip, di, pi, need_unwind_info, arg); +#else + /* fall through */ +#endif + default: + break; + } + return -UNW_EINVAL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-remote.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-remote.c new file mode 100644 index 00000000000000..40a5ad8b5aba41 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gdyn-remote.c @@ -0,0 +1,326 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "libunwind_i.h" +#include "remote.h" + +static void +free_regions (unw_dyn_region_info_t *region) +{ + if (region->next) + free_regions (region->next); + free (region); +} + +static int +intern_op (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_dyn_op_t *op, void *arg) +{ + int ret; + + if ((ret = fetch8 (as, a, addr, &op->tag, arg)) < 0 + || (ret = fetch8 (as, a, addr, &op->qp, arg)) < 0 + || (ret = fetch16 (as, a, addr, &op->reg, arg)) < 0 + || (ret = fetch32 (as, a, addr, &op->when, arg)) < 0 + || (ret = fetchw (as, a, addr, &op->val, arg)) < 0) + return ret; + return 0; +} + +static int +intern_regions (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_dyn_region_info_t **regionp, void *arg) +{ + uint32_t insn_count, op_count, i; + unw_dyn_region_info_t *region; + unw_word_t next_addr; + int ret; + + *regionp = NULL; + + if (!*addr) + return 0; /* NULL region-list */ + + if ((ret = fetchw (as, a, addr, &next_addr, arg)) < 0 + || (ret = fetch32 (as, a, addr, (int32_t *) &insn_count, arg)) < 0 + || (ret = fetch32 (as, a, addr, (int32_t *) &op_count, arg)) < 0) + return ret; + + region = calloc (1, _U_dyn_region_info_size (op_count)); + if (!region) + { + ret = -UNW_ENOMEM; + goto out; + } + + region->insn_count = insn_count; + region->op_count = op_count; + for (i = 0; i < op_count; ++i) + if ((ret = intern_op (as, a, addr, region->op + i, arg)) < 0) + goto out; + + if (next_addr) + if ((ret = intern_regions (as, a, &next_addr, ®ion->next, arg)) < 0) + goto out; + + *regionp = region; + return 0; + + out: + if (region) + free_regions (region); + return ret; +} + +static int +intern_array (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_word_t table_len, unw_word_t **table_data, + void *arg) +{ + unw_word_t i, *data = calloc (table_len, WSIZE); + int ret = 0; + + if (!data) + { + ret = -UNW_ENOMEM; + goto out; + } + + for (i = 0; i < table_len; ++i) + if (fetchw (as, a, addr, data + i, arg) < 0) + goto out; + + *table_data = data; + return 0; + + out: + if (data) + free (data); + return ret; +} + +static void +free_dyn_info (unw_dyn_info_t *di) +{ + switch (di->format) + { + case UNW_INFO_FORMAT_DYNAMIC: + if (di->u.pi.regions) + { + free_regions (di->u.pi.regions); + di->u.pi.regions = NULL; + } + break; + + case UNW_INFO_FORMAT_TABLE: + if (di->u.ti.table_data) + { + free (di->u.ti.table_data); + di->u.ti.table_data = NULL; + } + break; + + case UNW_INFO_FORMAT_REMOTE_TABLE: + default: + break; + } +} + +static int +intern_dyn_info (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_dyn_info_t *di, void *arg) +{ + unw_word_t first_region; + int ret; + + switch (di->format) + { + case UNW_INFO_FORMAT_DYNAMIC: + if ((ret = fetchw (as, a, addr, &di->u.pi.name_ptr, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.pi.handler, arg)) < 0 + || (ret = fetch32 (as, a, addr, + (int32_t *) &di->u.pi.flags, arg)) < 0) + goto out; + *addr += 4; /* skip over pad0 */ + if ((ret = fetchw (as, a, addr, &first_region, arg)) < 0 + || (ret = intern_regions (as, a, &first_region, &di->u.pi.regions, + arg)) < 0) + goto out; + break; + + case UNW_INFO_FORMAT_TABLE: + if ((ret = fetchw (as, a, addr, &di->u.ti.name_ptr, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.ti.segbase, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.ti.table_len, arg)) < 0 + || (ret = intern_array (as, a, addr, di->u.ti.table_len, + &di->u.ti.table_data, arg)) < 0) + goto out; + break; + + case UNW_INFO_FORMAT_REMOTE_TABLE: + if ((ret = fetchw (as, a, addr, &di->u.rti.name_ptr, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.rti.segbase, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.rti.table_len, arg)) < 0 + || (ret = fetchw (as, a, addr, &di->u.rti.table_data, arg)) < 0) + goto out; + break; + + default: + ret = -UNW_ENOINFO; + goto out; + } + return 0; + + out: + free_dyn_info (di); + return ret; +} + +HIDDEN int +unwi_dyn_remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + unw_accessors_t *a = unw_get_accessors_int (as); + unw_word_t dyn_list_addr, addr, next_addr, gen1, gen2, start_ip, end_ip; + unw_dyn_info_t *di = NULL; + int ret; + + if (as->dyn_info_list_addr) + dyn_list_addr = as->dyn_info_list_addr; + else + { + if ((*a->get_dyn_info_list_addr) (as, &dyn_list_addr, arg) < 0) + return -UNW_ENOINFO; + if (as->caching_policy != UNW_CACHE_NONE) + as->dyn_info_list_addr = dyn_list_addr; + } + + do + { + addr = dyn_list_addr; + + ret = -UNW_ENOINFO; + + if (fetchw (as, a, &addr, &gen1, arg) < 0 + || fetchw (as, a, &addr, &next_addr, arg) < 0) + return ret; + + for (addr = next_addr; addr != 0; addr = next_addr) + { + if (fetchw (as, a, &addr, &next_addr, arg) < 0) + goto recheck; /* only fail if generation # didn't change */ + + addr += WSIZE; /* skip over prev_addr */ + + if (fetchw (as, a, &addr, &start_ip, arg) < 0 + || fetchw (as, a, &addr, &end_ip, arg) < 0) + goto recheck; /* only fail if generation # didn't change */ + + if (ip >= start_ip && ip < end_ip) + { + if (!di) + di = calloc (1, sizeof (*di)); + + di->start_ip = start_ip; + di->end_ip = end_ip; + + if (fetchw (as, a, &addr, &di->gp, arg) < 0 + || fetch32 (as, a, &addr, &di->format, arg) < 0) + goto recheck; /* only fail if generation # didn't change */ + + addr += 4; /* skip over padding */ + + if (need_unwind_info + && intern_dyn_info (as, a, &addr, di, arg) < 0) + goto recheck; /* only fail if generation # didn't change */ + + if (unwi_extract_dynamic_proc_info (as, ip, pi, di, + need_unwind_info, arg) < 0) + { + free_dyn_info (di); + goto recheck; /* only fail if generation # didn't change */ + } + ret = 0; /* OK, found it */ + break; + } + } + + /* Re-check generation number to ensure the data we have is + consistent. */ + recheck: + addr = dyn_list_addr; + if (fetchw (as, a, &addr, &gen2, arg) < 0) + return ret; + } + while (gen1 != gen2); + + if (ret < 0 && di) + free (di); + + return ret; +} + +HIDDEN void +unwi_dyn_remote_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, + void *arg) +{ + if (!pi->unwind_info) + return; + + free_dyn_info (pi->unwind_info); + free (pi->unwind_info); + pi->unwind_info = NULL; +} + +/* Returns 1 if the cache is up-to-date or -1 if the cache contained + stale data and had to be flushed. */ + +HIDDEN int +unwi_dyn_validate_cache (unw_addr_space_t as, void *arg) +{ + unw_word_t addr, gen; + unw_accessors_t *a; + + if (!as->dyn_info_list_addr) + /* If we don't have the dyn_info_list_addr, we don't have anything + in the cache. */ + return 0; + + a = unw_get_accessors_int (as); + addr = as->dyn_info_list_addr; + + if (fetchw (as, a, &addr, &gen, arg) < 0) + return 1; + + if (gen == as->dyn_generation) + return 1; + + unw_flush_cache (as, 0, 0); + as->dyn_generation = gen; + return -1; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c new file mode 100644 index 00000000000000..2e7c62e5e8623e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c @@ -0,0 +1,92 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +static inline int +local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + return -UNW_ENOINFO; +} + +#else /* !UNW_REMOTE_ONLY */ + +static inline int +local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + unw_dyn_info_list_t *list; + unw_dyn_info_t *di; + +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + list = (unw_dyn_info_list_t *) (uintptr_t) _U_dyn_info_list_addr (); + for (di = list->first; di; di = di->next) + if (ip >= di->start_ip && ip < di->end_ip) + return unwi_extract_dynamic_proc_info (as, ip, pi, di, need_unwind_info, + arg); + return -UNW_ENOINFO; +} + +#endif /* !UNW_REMOTE_ONLY */ + +#ifdef UNW_LOCAL_ONLY + +static inline int +remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + return -UNW_ENOINFO; +} + +#else /* !UNW_LOCAL_ONLY */ + +static inline int +remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + return unwi_dyn_remote_find_proc_info (as, ip, pi, need_unwind_info, arg); +} + +#endif /* !UNW_LOCAL_ONLY */ + +HIDDEN int +unwi_find_dynamic_proc_info (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, int need_unwind_info, + void *arg) +{ + if (as == unw_local_addr_space) + return local_find_proc_info (as, ip, pi, need_unwind_info, arg); + else + return remote_find_proc_info (as, ip, pi, need_unwind_info, arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_accessors.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_accessors.c new file mode 100644 index 00000000000000..31a6fbaf02f09e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_accessors.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN ALIAS(unw_get_accessors) unw_accessors_t * +unw_get_accessors_int (unw_addr_space_t as); + +unw_accessors_t * +unw_get_accessors (unw_addr_space_t as) +{ + if (!tdep_init_done) + tdep_init (); + return &as->acc; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_fpreg.c new file mode 100644 index 00000000000000..f32b12862573b9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_get_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t *valp) +{ + struct cursor *c = (struct cursor *) cursor; + + return tdep_access_fpreg (c, regnum, valp, 0); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_info_by_ip.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_info_by_ip.c new file mode 100644 index 00000000000000..2697ff84e79c33 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_info_by_ip.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_get_proc_info_by_ip (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, void *as_arg) +{ + unw_accessors_t *a = unw_get_accessors_int (as); + int ret; + + ret = unwi_find_dynamic_proc_info (as, ip, pi, 0, as_arg); + if (ret == -UNW_ENOINFO) + ret = (*a->find_proc_info) (as, ip, pi, 0, as_arg); + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c new file mode 100644 index 00000000000000..0b77fa59523cd7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c @@ -0,0 +1,126 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" +#include "remote.h" + +static inline int +intern_string (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t addr, char *buf, size_t buf_len, void *arg) +{ + size_t i; + int ret; + + for (i = 0; i < buf_len; ++i) + { + if ((ret = fetch8 (as, a, &addr, (int8_t *) buf + i, arg)) < 0) + return ret; + + if (buf[i] == '\0') + return 0; /* copied full string; return success */ + } + buf[buf_len - 1] = '\0'; /* ensure string is NUL terminated */ + return -UNW_ENOMEM; +} + +static inline int +get_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, void *arg) +{ + unw_accessors_t *a = unw_get_accessors_int (as); + unw_proc_info_t pi; + int ret; + + buf[0] = '\0'; /* always return a valid string, even if it's empty */ + + ret = unwi_find_dynamic_proc_info (as, ip, &pi, 1, arg); + if (ret == 0) + { + unw_dyn_info_t *di = pi.unwind_info; + + if (offp) + *offp = ip - pi.start_ip; + + switch (di->format) + { + case UNW_INFO_FORMAT_DYNAMIC: + ret = intern_string (as, a, di->u.pi.name_ptr, buf, buf_len, arg); + break; + + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: + /* XXX should we create a fake name, e.g.: "tablenameN", + where N is the index of the function in the table??? */ + ret = -UNW_ENOINFO; + break; + + default: + ret = -UNW_EINVAL; + break; + } + unwi_put_dynamic_unwind_info (as, &pi, arg); + return ret; + } + + if (ret != -UNW_ENOINFO) + return ret; + + /* not a dynamic procedure, try to lookup static procedure name: */ + + if (a->get_proc_name) + return (*a->get_proc_name) (as, ip, buf, buf_len, offp, arg); + + return -UNW_ENOINFO; +} + +int +unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len, + unw_word_t *offp) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t ip; + int error; + + ip = tdep_get_ip (c); +#if !defined(__ia64__) + if (c->dwarf.use_prev_instr) + { +#if defined(__arm__) + /* On arm, the least bit denotes thumb/arm mode, clear it. */ + ip &= ~(unw_word_t)0x1; +#endif + --ip; + } + + +#endif + error = get_proc_name (tdep_get_as (c), ip, buf, buf_len, offp, + tdep_get_as_arg (c)); +#if !defined(__ia64__) + if (c->dwarf.use_prev_instr && offp != NULL && error == 0) + *offp += 1; +#endif + return error; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_reg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_reg.c new file mode 100644 index 00000000000000..9fc725c9c8e205 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_reg.c @@ -0,0 +1,41 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_get_reg (unw_cursor_t *cursor, int regnum, unw_word_t *valp) +{ + struct cursor *c = (struct cursor *) cursor; + + // We can get the IP value directly without needing a lookup. + if (regnum == UNW_REG_IP) + { + *valp = tdep_get_ip (c); + return 0; + } + + return tdep_access_reg (c, regnum, valp, 0); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gput_dynamic_unwind_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gput_dynamic_unwind_info.c new file mode 100644 index 00000000000000..ca377c98a8c489 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gput_dynamic_unwind_info.c @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN void +unwi_put_dynamic_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, + void *arg) +{ + switch (pi->format) + { + case UNW_INFO_FORMAT_DYNAMIC: +#ifndef UNW_LOCAL_ONLY +# ifdef UNW_REMOTE_ONLY + unwi_dyn_remote_put_unwind_info (as, pi, arg); +# else + if (as != unw_local_addr_space) + unwi_dyn_remote_put_unwind_info (as, pi, arg); +# endif +#endif + break; + + case UNW_INFO_FORMAT_TABLE: + case UNW_INFO_FORMAT_REMOTE_TABLE: +#ifdef tdep_put_unwind_info + tdep_put_unwind_info (as, pi, arg); + break; +#endif + /* fall through */ + default: + break; + } +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_cache_size.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_cache_size.c new file mode 100644 index 00000000000000..07b282e2c1dce2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_cache_size.c @@ -0,0 +1,72 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2014 + Contributed by Milian Wolff + and Dave Watson + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_set_cache_size (unw_addr_space_t as, size_t size, int flag) +{ + size_t power = 1; + unsigned short log_size = 0; + + if (!tdep_init_done) + tdep_init (); + + if (flag != 0) + return -1; + + /* Currently not supported for per-thread cache due to memory leak */ + /* A pthread-key destructor would work, but is not signal safe */ +#if defined(HAVE___THREAD) && HAVE___THREAD + return -1; +#endif + + /* Round up to next power of two, slowly but portably */ + while(power < size) + { + power *= 2; + log_size++; + /* Largest size currently supported by rs_cache */ + if (log_size >= 15) + break; + } + +#if !defined(__ia64__) + if (log_size == as->global_cache.log_size) + return 0; /* no change */ + + as->global_cache.log_size = log_size; +#endif + + /* Ensure caches are empty (and initialized). */ + unw_flush_cache (as, 0, 0); +#ifdef __ia64__ + return 0; +#else + /* Synchronously purge cache, to ensure memory is allocated */ + return dwarf_flush_rs_cache(&as->global_cache); +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_caching_policy.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_caching_policy.c new file mode 100644 index 00000000000000..aa3d237146e7a8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_caching_policy.c @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_set_caching_policy (unw_addr_space_t as, unw_caching_policy_t policy) +{ + if (!tdep_init_done) + tdep_init (); + +#if !(defined(HAVE___THREAD) && HAVE___THREAD) + if (policy == UNW_CACHE_PER_THREAD) + policy = UNW_CACHE_GLOBAL; +#endif + + if (policy == as->caching_policy) + return 0; /* no change */ + + as->caching_policy = policy; + /* Ensure caches are empty (and initialized). */ + unw_flush_cache (as, 0, 0); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_fpreg.c new file mode 100644 index 00000000000000..8c37afd2267117 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_set_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t val) +{ + struct cursor *c = (struct cursor *) cursor; + + return tdep_access_fpreg (c, regnum, &val, 1); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gset_reg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_reg.c new file mode 100644 index 00000000000000..b1b17703370744 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gset_reg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_set_reg (unw_cursor_t *cursor, int regnum, unw_word_t valp) +{ + struct cursor *c = (struct cursor *) cursor; + + return tdep_access_reg (c, regnum, &valp, 1); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Ldestroy_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mi/Ldestroy_addr_space.c new file mode 100644 index 00000000000000..5bf9364bc73cd0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Ldestroy_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gdestroy_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-extract.c b/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-extract.c new file mode 100644 index 00000000000000..1802f865f77d30 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-extract.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gdyn-extract.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-remote.c b/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-remote.c new file mode 100644 index 00000000000000..260722a04b2d90 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Ldyn-remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gdyn-remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lfind_dynamic_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lfind_dynamic_proc_info.c new file mode 100644 index 00000000000000..bc88e1c53f06ce --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lfind_dynamic_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gfind_dynamic_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_accessors.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_accessors.c new file mode 100644 index 00000000000000..555e37f30da65e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_accessors.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_accessors.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_fpreg.c new file mode 100644 index 00000000000000..e3be4414378799 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_fpreg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_fpreg.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_info_by_ip.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_info_by_ip.c new file mode 100644 index 00000000000000..96910d83e45e1c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_info_by_ip.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info_by_ip.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_name.c new file mode 100644 index 00000000000000..378097b57a0288 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_proc_name.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_name.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lget_reg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_reg.c new file mode 100644 index 00000000000000..effe8a8063531a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lget_reg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_reg.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lput_dynamic_unwind_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lput_dynamic_unwind_info.c new file mode 100644 index 00000000000000..99597cd5fac12b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lput_dynamic_unwind_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gput_dynamic_unwind_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_cache_size.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_cache_size.c new file mode 100644 index 00000000000000..670f64d3a9fea1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_cache_size.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gset_cache_size.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_caching_policy.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_caching_policy.c new file mode 100644 index 00000000000000..cc18816b377126 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_caching_policy.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gset_caching_policy.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_fpreg.c new file mode 100644 index 00000000000000..2497d404f4657c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_fpreg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gset_fpreg.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Lset_reg.c b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_reg.c new file mode 100644 index 00000000000000..c7a872b016fb4b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Lset_reg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gset_reg.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/_ReadSLEB.c b/src/coreclr/src/pal/src/libunwind/src/mi/_ReadSLEB.c new file mode 100644 index 00000000000000..c041e37a0543f0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/_ReadSLEB.c @@ -0,0 +1,25 @@ +#include + +unw_word_t +_ReadSLEB (unsigned char **dpp) +{ + unsigned shift = 0; + unw_word_t byte, result = 0; + unsigned char *bp = *dpp; + + while (1) + { + byte = *bp++; + result |= (byte & 0x7f) << shift; + shift += 7; + if ((byte & 0x80) == 0) + break; + } + + if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0) + /* sign-extend negative value */ + result |= ((unw_word_t) -1) << shift; + + *dpp = bp; + return result; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/_ReadULEB.c b/src/coreclr/src/pal/src/libunwind/src/mi/_ReadULEB.c new file mode 100644 index 00000000000000..116f3e19bc9503 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/_ReadULEB.c @@ -0,0 +1,20 @@ +#include + +unw_word_t +_ReadULEB (unsigned char **dpp) +{ + unsigned shift = 0; + unw_word_t byte, result = 0; + unsigned char *bp = *dpp; + + while (1) + { + byte = *bp++; + result |= (byte & 0x7f) << shift; + if ((byte & 0x80) == 0) + break; + shift += 7; + } + *dpp = bp; + return result; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c b/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c new file mode 100644 index 00000000000000..b28151370cdccb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c @@ -0,0 +1,83 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +#if !defined(UNW_REMOTE_ONLY) && !defined(UNW_LOCAL_ONLY) +#define UNW_LOCAL_ONLY + +#include +#include +#include + +/* See glibc manual for a description of this function. */ + +static ALWAYS_INLINE int +slow_backtrace (void **buffer, int size, unw_context_t *uc) +{ + unw_cursor_t cursor; + unw_word_t ip; + int n = 0; + + if (unlikely (unw_init_local (&cursor, uc) < 0)) + return 0; + + while (unw_step (&cursor) > 0) + { + if (n >= size) + return n; + + if (unw_get_reg (&cursor, UNW_REG_IP, &ip) < 0) + return n; + buffer[n++] = (void *) (uintptr_t) ip; + } + return n; +} + +int +unw_backtrace (void **buffer, int size) +{ + unw_cursor_t cursor; + unw_context_t uc; + int n = size; + + tdep_getcontext_trace (&uc); + + if (unlikely (unw_init_local (&cursor, &uc) < 0)) + return 0; + + if (unlikely (tdep_trace (&cursor, buffer, &n) < 0)) + { + unw_getcontext (&uc); + return slow_backtrace (buffer, size, &uc); + } + + return n; +} + +#ifdef CONFIG_WEAK_BACKTRACE +extern int backtrace (void **buffer, int size) + WEAK ALIAS(unw_backtrace); +#endif + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/dyn-cancel.c b/src/coreclr/src/pal/src/libunwind/src/mi/dyn-cancel.c new file mode 100644 index 00000000000000..9d7472d5fdfb6c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/dyn-cancel.c @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +void +_U_dyn_cancel (unw_dyn_info_t *di) +{ + mutex_lock (&_U_dyn_info_list_lock); + { + ++_U_dyn_info_list.generation; + + if (di->prev) + di->prev->next = di->next; + else + _U_dyn_info_list.first = di->next; + + if (di->next) + di->next->prev = di->prev; + } + mutex_unlock (&_U_dyn_info_list_lock); + + di->next = di->prev = NULL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/dyn-info-list.c b/src/coreclr/src/pal/src/libunwind/src/mi/dyn-info-list.c new file mode 100644 index 00000000000000..1c7c55090a6711 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/dyn-info-list.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +unw_word_t +_U_dyn_info_list_addr (void) +{ + return (unw_word_t) (uintptr_t) &_U_dyn_info_list; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/dyn-register.c b/src/coreclr/src/pal/src/libunwind/src/mi/dyn-register.c new file mode 100644 index 00000000000000..efdad3de076be8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/dyn-register.c @@ -0,0 +1,44 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN define_lock (_U_dyn_info_list_lock); + +void +_U_dyn_register (unw_dyn_info_t *di) +{ + mutex_lock (&_U_dyn_info_list_lock); + { + ++_U_dyn_info_list.generation; + + di->next = _U_dyn_info_list.first; + di->prev = NULL; + if (di->next) + di->next->prev = di; + _U_dyn_info_list.first = di; + } + mutex_unlock (&_U_dyn_info_list_lock); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c b/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c new file mode 100644 index 00000000000000..f2b01158a0ec7b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c @@ -0,0 +1,62 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +void +unw_flush_cache (unw_addr_space_t as, unw_word_t lo, unw_word_t hi) +{ +#if !UNW_TARGET_IA64 + struct unw_debug_frame_list *w = as->debug_frames; + + while (w) + { + struct unw_debug_frame_list *n = w->next; + + if (w->index) + munmap (w->index, w->index_size); + + munmap (w->debug_frame, w->debug_frame_size); + munmap (w, sizeof (*w)); + w = n; + } + as->debug_frames = NULL; +#endif + + /* clear dyn_info_list_addr cache: */ + as->dyn_info_list_addr = 0; + + /* This lets us flush caches lazily. The implementation currently + ignores the flush range arguments (lo-hi). This is OK because + unw_flush_cache() is allowed to flush more than the requested + range. */ + +#ifdef HAVE_FETCH_AND_ADD + fetch_and_add1 (&as->cache_generation); +#else +# warning unw_flush_cache(): need a way to atomically increment an integer. + ++as->cache_generation; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/init.c b/src/coreclr/src/pal/src/libunwind/src/mi/init.c new file mode 100644 index 00000000000000..60a48c58928aa7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/init.c @@ -0,0 +1,60 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +HIDDEN intrmask_t unwi_full_mask; + +static const char rcsid[] UNUSED = + "$Id: " PACKAGE_STRING " --- report bugs to " PACKAGE_BUGREPORT " $"; + +#if UNW_DEBUG + +/* Must not be declared HIDDEN because libunwind.so and + libunwind-PLATFORM.so will both define their own copies of this + variable and we want to use only one or the other when both + libraries are loaded. */ +long unwi_debug_level; + +#endif /* UNW_DEBUG */ + +HIDDEN void +mi_init (void) +{ +#if UNW_DEBUG + const char *str = getenv ("UNW_DEBUG_LEVEL"); + + if (str) + unwi_debug_level = atoi (str); + + if (unwi_debug_level > 0) + { + setbuf (stdout, NULL); + setbuf (stderr, NULL); + } +#endif + + assert (sizeof (struct cursor) <= sizeof (unw_cursor_t)); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/mempool.c b/src/coreclr/src/pal/src/libunwind/src/mi/mempool.c new file mode 100644 index 00000000000000..536b64e815760e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/mempool.c @@ -0,0 +1,184 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +/* From GCC docs: ``Gcc also provides a target specific macro + * __BIGGEST_ALIGNMENT__, which is the largest alignment ever used for any data + * type on the target machine you are compiling for.'' */ +#ifdef __BIGGEST_ALIGNMENT__ +# define MAX_ALIGN __BIGGEST_ALIGNMENT__ +#else +/* Crude hack to check that MAX_ALIGN is power-of-two. + * sizeof(long double) = 12 on i386. */ +# define MAX_ALIGN_(n) (n < 8 ? 8 : \ + n < 16 ? 16 : n) +# define MAX_ALIGN MAX_ALIGN_(sizeof (long double)) +#endif + +static char sos_memory[SOS_MEMORY_SIZE] ALIGNED(MAX_ALIGN); +static size_t sos_memory_freepos; +static size_t pg_size; + +HIDDEN void * +sos_alloc (size_t size) +{ + size_t pos; + + size = UNW_ALIGN(size, MAX_ALIGN); + +#if defined(__GNUC__) && defined(HAVE_FETCH_AND_ADD) + /* Assume `sos_memory' is suitably aligned. */ + assert(((uintptr_t) &sos_memory[0] & (MAX_ALIGN-1)) == 0); + + pos = fetch_and_add (&sos_memory_freepos, size); +#else + static define_lock (sos_lock); + intrmask_t saved_mask; + + lock_acquire (&sos_lock, saved_mask); + { + /* No assumptions about `sos_memory' alignment. */ + if (sos_memory_freepos == 0) + { + unsigned align = UNW_ALIGN((uintptr_t) &sos_memory[0], MAX_ALIGN) + - (uintptr_t) &sos_memory[0]; + sos_memory_freepos = align; + } + pos = sos_memory_freepos; + sos_memory_freepos += size; + } + lock_release (&sos_lock, saved_mask); +#endif + + assert (((uintptr_t) &sos_memory[pos] & (MAX_ALIGN-1)) == 0); + assert ((pos+size) <= SOS_MEMORY_SIZE); + + return &sos_memory[pos]; +} + +/* Must be called while holding the mempool lock. */ + +static void +free_object (struct mempool *pool, void *object) +{ + struct object *obj = object; + + obj->next = pool->free_list; + pool->free_list = obj; + ++pool->num_free; +} + +static void +add_memory (struct mempool *pool, char *mem, size_t size, size_t obj_size) +{ + char *obj; + + for (obj = mem; obj <= mem + size - obj_size; obj += obj_size) + free_object (pool, obj); +} + +static void +expand (struct mempool *pool) +{ + size_t size; + char *mem; + + size = pool->chunk_size; + GET_MEMORY (mem, size); + if (!mem) + { + size = UNW_ALIGN(pool->obj_size, pg_size); + GET_MEMORY (mem, size); + if (!mem) + { + /* last chance: try to allocate one object from the SOS memory */ + size = pool->obj_size; + mem = sos_alloc (size); + } + } + add_memory (pool, mem, size, pool->obj_size); +} + +HIDDEN void +mempool_init (struct mempool *pool, size_t obj_size, size_t reserve) +{ + if (pg_size == 0) + pg_size = getpagesize (); + + memset (pool, 0, sizeof (*pool)); + + lock_init (&pool->lock); + + /* round object-size up to integer multiple of MAX_ALIGN */ + obj_size = UNW_ALIGN(obj_size, MAX_ALIGN); + + if (!reserve) + { + reserve = pg_size / obj_size / 4; + if (!reserve) + reserve = 16; + } + + pool->obj_size = obj_size; + pool->reserve = reserve; + pool->chunk_size = UNW_ALIGN(2*reserve*obj_size, pg_size); + + expand (pool); +} + +HIDDEN void * +mempool_alloc (struct mempool *pool) +{ + intrmask_t saved_mask; + struct object *obj; + + lock_acquire (&pool->lock, saved_mask); + { + if (pool->num_free <= pool->reserve) + expand (pool); + + assert (pool->num_free > 0); + + --pool->num_free; + obj = pool->free_list; + pool->free_list = obj->next; + } + lock_release (&pool->lock, saved_mask); + return obj; +} + +HIDDEN void +mempool_free (struct mempool *pool, void *object) +{ + intrmask_t saved_mask; + + lock_acquire (&pool->lock, saved_mask); + { + free_object (pool, object); + } + lock_release (&pool->lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/strerror.c b/src/coreclr/src/pal/src/libunwind/src/mi/strerror.c new file mode 100644 index 00000000000000..2cec73d1db9000 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mi/strerror.c @@ -0,0 +1,51 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 BEA Systems + Contributed by Thomas Hallgren + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +/* Returns the text corresponding to the given err_code or the + text "invalid error code" if the err_code is invalid. */ +const char * +unw_strerror (int err_code) +{ + const char *cp; + unw_error_t error = (unw_error_t)-err_code; + switch (error) + { + case UNW_ESUCCESS: cp = "no error"; break; + case UNW_EUNSPEC: cp = "unspecified (general) error"; break; + case UNW_ENOMEM: cp = "out of memory"; break; + case UNW_EBADREG: cp = "bad register number"; break; + case UNW_EREADONLYREG: cp = "attempt to write read-only register"; break; + case UNW_ESTOPUNWIND: cp = "stop unwinding"; break; + case UNW_EINVALIDIP: cp = "invalid IP"; break; + case UNW_EBADFRAME: cp = "bad frame"; break; + case UNW_EINVAL: cp = "unsupported operation or bad value"; break; + case UNW_EBADVERSION: cp = "unwind info has unsupported version"; break; + case UNW_ENOINFO: cp = "no unwind info found"; break; + default: cp = "invalid error code"; + } + return cp; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c new file mode 100644 index 00000000000000..24e0d3b1536a24 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c @@ -0,0 +1,73 @@ +/* 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. */ + +#include + +#include "unwind_i.h" + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * MIPS supports only big or little-endian, not weird stuff like + * PDP_ENDIAN. + */ + if (byte_order != 0 + && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + if (byte_order == 0) + /* use host default: */ + as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + else + as->big_endian = (byte_order == __BIG_ENDIAN); + + /* FIXME! There is no way to specify the ABI. */ +#if _MIPS_SIM == _ABIO32 + as->abi = UNW_MIPS_ABI_O32; +#elif _MIPS_SIM == _ABIN32 + as->abi = UNW_MIPS_ABI_N32; +#elif _MIPS_SIM == _ABI64 + as->abi = UNW_MIPS_ABI_N64; +#else +# error Unsupported ABI +#endif + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c new file mode 100644 index 00000000000000..04c4326d45c691 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c @@ -0,0 +1,44 @@ +/* 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. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = dwarf_make_proc_info (&c->dwarf); + if (ret < 0) { + /* Construct a dummy proc info if Dwarf failed */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 4; + return 0; + } + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_save_loc.c new file mode 100644 index 00000000000000..c21f9b06d060a1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_save_loc.c @@ -0,0 +1,100 @@ +/* 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. */ + +#include "unwind_i.h" + +/* FIXME for MIPS. */ + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_MIPS_R0: + case UNW_MIPS_R1: + case UNW_MIPS_R2: + case UNW_MIPS_R3: + case UNW_MIPS_R4: + case UNW_MIPS_R5: + case UNW_MIPS_R6: + case UNW_MIPS_R7: + case UNW_MIPS_R8: + case UNW_MIPS_R9: + case UNW_MIPS_R10: + case UNW_MIPS_R11: + case UNW_MIPS_R12: + case UNW_MIPS_R13: + case UNW_MIPS_R14: + case UNW_MIPS_R15: + case UNW_MIPS_R16: + case UNW_MIPS_R17: + case UNW_MIPS_R18: + case UNW_MIPS_R19: + case UNW_MIPS_R20: + case UNW_MIPS_R21: + case UNW_MIPS_R22: + case UNW_MIPS_R23: + case UNW_MIPS_R24: + case UNW_MIPS_R25: + case UNW_MIPS_R26: + case UNW_MIPS_R27: + case UNW_MIPS_R28: + case UNW_MIPS_R29: + case UNW_MIPS_R30: + case UNW_MIPS_R31: + case UNW_MIPS_PC: + loc = c->dwarf.loc[reg - UNW_MIPS_R0]; + break; + + default: + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gglobal.c new file mode 100644 index 00000000000000..fa9478eebe7050 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gglobal.c @@ -0,0 +1,55 @@ +/* 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. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (mips_lock); +HIDDEN int tdep_init_done; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&mips_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + mips_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&mips_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c new file mode 100644 index 00000000000000..bf7a8f5a8f4447 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c @@ -0,0 +1,209 @@ +/* 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. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +/* Return the address of the 64-bit slot in UC for REG (even for o32, + where registers are 32-bit, the slots are still 64-bit). */ + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + if (reg >= UNW_MIPS_R0 && reg < UNW_MIPS_R0 + 32) + return &uc->uc_mcontext.gregs[reg - UNW_MIPS_R0]; + else if (reg == UNW_MIPS_PC) + return &uc->uc_mcontext.pc; + else + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + char *addr = uc_addr (uc, reg); + + if (((reg >= UNW_MIPS_R0 && reg <= UNW_MIPS_R31) || reg == UNW_MIPS_PC) + && tdep_big_endian (unw_local_addr_space) + && unw_local_addr_space->abi == UNW_MIPS_ABI_O32) + addr += 4; + + return addr; +} + +# endif /* UNW_LOCAL_ONLY */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (16, "mem[%llx] <- %llx\n", (long long) addr, (long long) *val); + *(unw_word_t *) (intptr_t) addr = *val; + } + else + { + *val = *(unw_word_t *) (intptr_t) addr; + Debug (16, "mem[%llx] -> %llx\n", (long long) addr, (long long) *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if (unw_is_fpreg (reg)) + goto badreg; + + Debug (16, "reg = %s\n", unw_regname (reg)); + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) (intptr_t) addr = (mips_reg_t) *val; + Debug (12, "%s <- %llx\n", unw_regname (reg), (long long) *val); + } + else + { + *val = (mips_reg_t) *(unw_word_t *) (intptr_t) addr; + Debug (12, "%s -> %llx\n", unw_regname (reg), (long long) *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) (intptr_t) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) (intptr_t) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + + return elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +mips_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); +#if _MIPS_SIM == _ABIO32 + local_addr_space.abi = UNW_MIPS_ABI_O32; +#elif _MIPS_SIM == _ABIN32 + local_addr_space.abi = UNW_MIPS_ABI_N32; +#elif _MIPS_SIM == _ABI64 + local_addr_space.abi = UNW_MIPS_ABI_N64; +#else +# error Unsupported ABI +#endif + local_addr_space.addr_size = sizeof (void *); + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = NULL; /* mips_local_resume? FIXME! */ + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_local.c new file mode 100644 index 00000000000000..f3153b5ba03b34 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_local.c @@ -0,0 +1,76 @@ +/* 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. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + return common_init (c, use_prev_instr); +} + +int +unw_init_local(unw_cursor_t *cursor, ucontext_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_remote.c new file mode 100644 index 00000000000000..9b8ba5b89def1a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit_remote.c @@ -0,0 +1,45 @@ +/* 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. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gis_signal_frame.c new file mode 100644 index 00000000000000..c0e3b98368b056 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gis_signal_frame.c @@ -0,0 +1,78 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2015 Imagination Technologies Limited + 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. */ + +#include "unwind_i.h" +#include + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + /* syscall */ + if ((ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0) + return 0; + if ((w1 & 0xffffffff) != 0x0c) + return 0; + + /* li v0, 0x1061 (rt) or li v0, 0x1017 */ + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) + return 0; + + switch (c->dwarf.as->abi) + { + case UNW_MIPS_ABI_O32: + switch (w0 & 0xffffffff) + { + case 0x24021061: + return 1; + case 0x24021017: + return 2; + default: + return 0; + } + case UNW_MIPS_ABI_N64: + switch (w0 & 0xffffffff) + { + case 0x2402145b: + return 1; + default: + return 0; + } + default: + return 0; + } +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/mips/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c new file mode 100644 index 00000000000000..e967324d67d6e0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c @@ -0,0 +1,106 @@ +/* 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. */ + +#include "unwind_i.h" + +/* FIXME: The following is probably unfinished and/or at least partly bogus. */ + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_MIPS_R0: + case UNW_MIPS_R1: + case UNW_MIPS_R2: + case UNW_MIPS_R3: + case UNW_MIPS_R4: + case UNW_MIPS_R5: + case UNW_MIPS_R6: + case UNW_MIPS_R7: + case UNW_MIPS_R8: + case UNW_MIPS_R9: + case UNW_MIPS_R10: + case UNW_MIPS_R11: + case UNW_MIPS_R12: + case UNW_MIPS_R13: + case UNW_MIPS_R14: + case UNW_MIPS_R15: + case UNW_MIPS_R16: + case UNW_MIPS_R17: + case UNW_MIPS_R18: + case UNW_MIPS_R19: + case UNW_MIPS_R20: + case UNW_MIPS_R21: + case UNW_MIPS_R22: + case UNW_MIPS_R23: + case UNW_MIPS_R24: + case UNW_MIPS_R25: + case UNW_MIPS_R26: + case UNW_MIPS_R27: + case UNW_MIPS_R28: + + case UNW_MIPS_R30: + case UNW_MIPS_R31: + loc = c->dwarf.loc[reg - UNW_MIPS_R0]; + break; + + case UNW_MIPS_PC: + if (write) + c->dwarf.ip = *valp; /* update the IP cache */ + loc = c->dwarf.loc[reg]; + break; + + case UNW_MIPS_R29: + case UNW_MIPS_CFA: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + /* FIXME: IP? Copro & shadow registers? */ + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +/* FIXME for MIPS. */ + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gresume.c new file mode 100644 index 00000000000000..cb70abc8c5cc99 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gresume.c @@ -0,0 +1,45 @@ +/* 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. */ + +/* FIXME for MIPS. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +mips_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +int +unw_resume (unw_cursor_t *cursor) +{ + return -UNW_EINVAL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c new file mode 100644 index 00000000000000..0235d523f03991 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c @@ -0,0 +1,224 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2015 Imagination Technologies Limited + 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. */ + +#include "unwind_i.h" +#include "offsets.h" + +static int +mips_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t sc_addr, sp_addr = c->dwarf.cfa; + unw_word_t ra, fp; + int ret; + + switch (unw_is_signal_frame (cursor)) { + case 1: + sc_addr = sp_addr + LINUX_SF_TRAMP_SIZE + sizeof (siginfo_t) + + LINUX_UC_MCONTEXT_OFF; + break; + case 2: + sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF; + break; + default: + return -UNW_EUNSPEC; + } + + if (tdep_big_endian(c->dwarf.as)) + sc_addr += 4; + + c->sigcontext_addr = sc_addr; + + /* Update the dwarf cursor. */ + c->dwarf.loc[UNW_MIPS_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); + c->dwarf.loc[UNW_MIPS_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); + c->dwarf.loc[UNW_MIPS_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); + c->dwarf.loc[UNW_MIPS_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); + c->dwarf.loc[UNW_MIPS_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); + c->dwarf.loc[UNW_MIPS_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); + c->dwarf.loc[UNW_MIPS_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); + c->dwarf.loc[UNW_MIPS_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); + c->dwarf.loc[UNW_MIPS_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); + c->dwarf.loc[UNW_MIPS_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); + c->dwarf.loc[UNW_MIPS_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); + c->dwarf.loc[UNW_MIPS_R11] = DWARF_LOC (sc_addr + LINUX_SC_R11_OFF, 0); + c->dwarf.loc[UNW_MIPS_R12] = DWARF_LOC (sc_addr + LINUX_SC_R12_OFF, 0); + c->dwarf.loc[UNW_MIPS_R13] = DWARF_LOC (sc_addr + LINUX_SC_R13_OFF, 0); + c->dwarf.loc[UNW_MIPS_R14] = DWARF_LOC (sc_addr + LINUX_SC_R14_OFF, 0); + c->dwarf.loc[UNW_MIPS_R15] = DWARF_LOC (sc_addr + LINUX_SC_R15_OFF, 0); + c->dwarf.loc[UNW_MIPS_R16] = DWARF_LOC (sc_addr + LINUX_SC_R16_OFF, 0); + c->dwarf.loc[UNW_MIPS_R17] = DWARF_LOC (sc_addr + LINUX_SC_R17_OFF, 0); + c->dwarf.loc[UNW_MIPS_R18] = DWARF_LOC (sc_addr + LINUX_SC_R18_OFF, 0); + c->dwarf.loc[UNW_MIPS_R19] = DWARF_LOC (sc_addr + LINUX_SC_R19_OFF, 0); + c->dwarf.loc[UNW_MIPS_R20] = DWARF_LOC (sc_addr + LINUX_SC_R20_OFF, 0); + c->dwarf.loc[UNW_MIPS_R21] = DWARF_LOC (sc_addr + LINUX_SC_R21_OFF, 0); + c->dwarf.loc[UNW_MIPS_R22] = DWARF_LOC (sc_addr + LINUX_SC_R22_OFF, 0); + c->dwarf.loc[UNW_MIPS_R23] = DWARF_LOC (sc_addr + LINUX_SC_R23_OFF, 0); + c->dwarf.loc[UNW_MIPS_R24] = DWARF_LOC (sc_addr + LINUX_SC_R24_OFF, 0); + c->dwarf.loc[UNW_MIPS_R25] = DWARF_LOC (sc_addr + LINUX_SC_R25_OFF, 0); + c->dwarf.loc[UNW_MIPS_R26] = DWARF_LOC (sc_addr + LINUX_SC_R26_OFF, 0); + c->dwarf.loc[UNW_MIPS_R27] = DWARF_LOC (sc_addr + LINUX_SC_R27_OFF, 0); + c->dwarf.loc[UNW_MIPS_R28] = DWARF_LOC (sc_addr + LINUX_SC_R28_OFF, 0); + c->dwarf.loc[UNW_MIPS_R29] = DWARF_LOC (sc_addr + LINUX_SC_R29_OFF, 0); + c->dwarf.loc[UNW_MIPS_R30] = DWARF_LOC (sc_addr + LINUX_SC_R30_OFF, 0); + c->dwarf.loc[UNW_MIPS_R31] = DWARF_LOC (sc_addr + LINUX_SC_R31_OFF, 0); + c->dwarf.loc[UNW_MIPS_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_MIPS_R29], &c->dwarf.cfa); + + if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_PC_OFF, 0), + &c->dwarf.ip)) < 0) + return ret; + + if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_R31_OFF, 0), + &ra)) < 0) + return ret; + if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_R30_OFF, 0), + &fp)) < 0) + return ret; + + Debug (2, "SH (ip=0x%016llx, ra=0x%016llx, sp=0x%016llx, fp=0x%016llx)\n", + (unsigned long long)c->dwarf.ip, (unsigned long long)ra, + (unsigned long long)c->dwarf.cfa, (unsigned long long)fp); + + c->dwarf.pi_valid = 0; + c->dwarf.use_prev_instr = 0; + + return 1; +} + + + +static inline +int is_valid_fp_val(unw_word_t cfa_val, unw_word_t fp_val) +{ + return fp_val > 0 && cfa_val > 0 && fp_val >cfa_val && (fp_val - cfa_val < 0x4000); +} + +static int _step_n64(struct cursor *c) +{ + #define FP_REG UNW_MIPS_R30 + #define SP_REG UNW_MIPS_R29 + #define RA_REG UNW_MIPS_R31 + + //TODO:handle plt entry + int ret; + unw_word_t current_fp_val = 0; + unw_word_t current_ra_val = 0; + unw_word_t current_sp_val = 0; + struct dwarf_loc up_fp_loc = DWARF_NULL_LOC; + struct dwarf_loc up_ra_loc = DWARF_NULL_LOC; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[SP_REG], ¤t_sp_val); + if (ret < 0) + { + Debug (2, "returning %d [SP=0x%lx]\n", ret, + DWARF_GET_LOC (c->dwarf.loc[FP_REG])); + return ret; + } + ret = dwarf_get (&c->dwarf, c->dwarf.loc[FP_REG], ¤t_fp_val); + if (ret < 0) + { + Debug (2, "returning %d [FP=0x%lx]\n", ret, + DWARF_GET_LOC (c->dwarf.loc[FP_REG])); + return ret; + } + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RA_REG], ¤t_ra_val); + if (ret < 0) + { + Debug (2, "returning %d [RA=0x%lx]\n", ret, + DWARF_GET_LOC (c->dwarf.loc[RA_REG])); + return ret; + } + + Debug(2, "BEGIN GUESSING WITH SP:%p FP:%p CFA:%p at %p, RA:%p\n", + current_sp_val, current_fp_val, c->dwarf.cfa, + c->dwarf.ip, current_ra_val + ); + + if (current_fp_val == current_sp_val) { + // Don't adjust FP + up_fp_loc = c->dwarf.loc[FP_REG]; + up_ra_loc = c->dwarf.loc[RA_REG]; + } else if (is_valid_fp_val(c->dwarf.cfa, current_fp_val)) { + /* Heuristic to determine incorrect guess. For FP to be a + valid frame it needs to be above current CFA, but don't + let it go more than a little. Note that we can't deduce + anything about new FP (fp1) since it may not be a frame + pointer in the frame above. Just check we get the value. */ + up_fp_loc = DWARF_MEM_LOC (c, current_fp_val+16); + up_ra_loc = DWARF_MEM_LOC (c, current_fp_val+24); + unw_word_t up_fp_val = 0; + ret = dwarf_get (&c->dwarf, up_fp_loc, &up_fp_val); + if (ret > 0 && is_valid_fp_val(current_fp_val, up_fp_val)) { + c->dwarf.loc[FP_REG] = up_fp_loc; + } + } + + if (DWARF_IS_NULL_LOC (up_fp_loc)) + { + ret = 0; + Debug (2, "NULL %%fp loc, returning %d\n", ret); + return ret; + } + + c->dwarf.loc[UNW_MIPS_PC] = c->dwarf.loc[RA_REG]; + c->dwarf.loc[RA_REG] = up_ra_loc; + c->dwarf.loc[SP_REG] = up_fp_loc; + c->dwarf.loc[FP_REG] = up_fp_loc; + c->dwarf.use_prev_instr = 1; + + if (c->dwarf.ip == current_ra_val && current_fp_val == current_sp_val) { + // Backtrace stopped: frame did not save the PC + c->dwarf.ip = 0; + } else { + c->dwarf.ip = current_ra_val; + } + return (c->dwarf.ip == 0) ? 0 : 1; +} + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = mips_handle_signal_frame (cursor); + if (ret < 0) + /* Not a signal frame, try DWARF-based unwinding. */ + ret = dwarf_step (&c->dwarf); + + if (unlikely (ret == -UNW_ESTOPUNWIND)) + return ret; + +#if _MIPS_SIM == _ABI64 + if (unlikely (ret < 0)) + { + return _step_n64(c); + } +#endif + return (c->dwarf.ip == 0) ? 0 : 1; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lglobal.c new file mode 100644 index 00000000000000..6d7b489e14bd9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Linit.c b/src/coreclr/src/pal/src/libunwind/src/mips/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/mips/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/mips/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lis_signal_frame.c new file mode 100644 index 00000000000000..b9a7c4f51ad9fa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/mips/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/elfxx.c b/src/coreclr/src/pal/src/libunwind/src/mips/elfxx.c new file mode 100644 index 00000000000000..07d3d12b94fe00 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/elfxx.c @@ -0,0 +1,27 @@ +/* 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. */ + +#include "libunwind_i.h" + +#include "../src/elfxx.c" diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/gen-offsets.c b/src/coreclr/src/pal/src/libunwind/src/mips/gen-offsets.c new file mode 100644 index 00000000000000..448f6945326543 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/gen-offsets.c @@ -0,0 +1,30 @@ +#include +#include +#include + +#define UC(N,X) \ + printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) + +#define SC(N,X) \ + printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) + +int +main (void) +{ + printf ( +"/* Linux-specific definitions: */\n\n" + +"/* Define various structure offsets to simplify cross-compilation. */\n\n" + +"/* Offsets for MIPS Linux \"ucontext_t\": */\n\n"); + + UC ("FLAGS", uc_flags); + UC ("LINK", uc_link); + UC ("STACK", uc_stack); + UC ("MCONTEXT", uc_mcontext); + UC ("SIGMASK", uc_sigmask); + + UC ("MCONTEXT_GREGS", uc_mcontext.gregs); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/mips/getcontext.S new file mode 100644 index 00000000000000..d1dbd57932d098 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/getcontext.S @@ -0,0 +1,93 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include + + .text + +#if _MIPS_SIM == _ABIO32 +# if __BYTE_ORDER == __BIG_ENDIAN +# define OFFSET 4 +# else +# define OFFSET 0 +# endif +# define SREG(X) \ + sw $X, (LINUX_UC_MCONTEXT_GREGS + 8 * X + OFFSET) ($4); \ + sra $1, $X, 31; \ + sw $1, (LINUX_UC_MCONTEXT_GREGS + 8 * X + 4 - OFFSET) ($4) +/* Yes, we save the return address to PC. */ +# define SPC \ + sw $31, (LINUX_UC_MCONTEXT_PC + OFFSET) ($4); \ + sra $1, $31, 31; \ + sw $1, (LINUX_UC_MCONTEXT_PC + 4 - OFFSET) ($4) +#else +# define SREG(X) sd $X, (LINUX_UC_MCONTEXT_GREGS + 8 * X) ($4) +# define SPC sd $31, (LINUX_UC_MCONTEXT_PC) ($4) +#endif + + .global _Umips_getcontext + .type _Umips_getcontext, %function + # This is a stub version of getcontext() for MIPS which only stores core + # registers. +_Umips_getcontext: + .set noat + SREG (1) + SREG (0) + SREG (2) + SREG (3) + SREG (4) + SREG (5) + SREG (6) + SREG (7) + SREG (8) + SREG (9) + SREG (10) + SREG (11) + SREG (12) + SREG (13) + SREG (14) + SREG (15) + SREG (16) + SREG (17) + SREG (18) + SREG (19) + SREG (20) + SREG (21) + SREG (22) + SREG (23) + SREG (24) + SREG (25) + SREG (26) + SREG (27) + SREG (28) + SREG (29) + SREG (30) + SREG (31) + SPC + li $2, 0 + j $31 + + .size _Umips_getcontext, .-_Umips_getcontext diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/init.h b/src/coreclr/src/pal/src/libunwind/src/mips/init.h new file mode 100644 index 00000000000000..30c193a18f7146 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/init.h @@ -0,0 +1,59 @@ +/* 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. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret, i; + + for (i = 0; i < 32; i++) + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, UNW_MIPS_R0 + i); + for (i = 32; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + c->dwarf.loc[UNW_MIPS_PC] = DWARF_REG_LOC (&c->dwarf, UNW_MIPS_PC); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_MIPS_PC], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_MIPS_R29), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + /* FIXME: Initialisation for other registers. */ + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/mips/is_fpreg.c new file mode 100644 index 00000000000000..a92dd5ece7a6dd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/is_fpreg.c @@ -0,0 +1,35 @@ +/* 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. */ + +#include "libunwind_i.h" + +/* FIXME: I'm not sure if libunwind's GP/FP register distinction is very useful + on MIPS. */ + +int +unw_is_fpreg (int regnum) +{ + /* FIXME: Support FP. */ + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/offsets.h b/src/coreclr/src/pal/src/libunwind/src/mips/offsets.h new file mode 100644 index 00000000000000..b506051367720e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/offsets.h @@ -0,0 +1,86 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* FIXME: Currently these are only used in getcontext.S, which is only used + for a local unwinder, so we can use the compile-time ABI. At a later date + we will want all three here, to use for signal handlers. Also, because + of the three ABIs, gen-offsets.c can not quite generate this file. */ + +/* Offsets for MIPS Linux "ucontext_t": */ + +/* First 24 bytes in sigframe are argument save space and padding for +what used to be signal trampolines. Ref: arch/mips/kernel/signal.c */ +#define LINUX_SF_TRAMP_SIZE 0x18 + +#if _MIPS_SIM == _ABIO32 + +# define LINUX_UC_FLAGS_OFF 0x0 +# define LINUX_UC_LINK_OFF 0x4 +# define LINUX_UC_STACK_OFF 0x8 +# define LINUX_UC_MCONTEXT_OFF 0x18 +# define LINUX_UC_SIGMASK_OFF 0x268 +# define LINUX_UC_MCONTEXT_PC 0x20 +# define LINUX_UC_MCONTEXT_GREGS 0x28 + +#elif _MIPS_SIM == _ABIN32 + +# define LINUX_UC_FLAGS_OFF 0x0 +# define LINUX_UC_LINK_OFF 0x4 +# define LINUX_UC_STACK_OFF 0x8 +# define LINUX_UC_MCONTEXT_OFF 0x18 +# define LINUX_UC_SIGMASK_OFF 0x270 +# define LINUX_UC_MCONTEXT_PC 0x258 +# define LINUX_UC_MCONTEXT_GREGS 0x18 + +#elif _MIPS_SIM == _ABI64 + +# define LINUX_UC_FLAGS_OFF 0x0 +# define LINUX_UC_LINK_OFF 0x8 +# define LINUX_UC_STACK_OFF 0x10 +# define LINUX_UC_MCONTEXT_OFF 0x28 +# define LINUX_UC_SIGMASK_OFF 0x280 +# define LINUX_UC_MCONTEXT_PC 0x268 +# define LINUX_UC_MCONTEXT_GREGS 0x28 + +#else + +#error Unsupported ABI + +#endif + +#define LINUX_SC_R0_OFF (LINUX_UC_MCONTEXT_GREGS - LINUX_UC_MCONTEXT_OFF) +#define LINUX_SC_R1_OFF (LINUX_SC_R0_OFF + 1*8) +#define LINUX_SC_R2_OFF (LINUX_SC_R0_OFF + 2*8) +#define LINUX_SC_R3_OFF (LINUX_SC_R0_OFF + 3*8) +#define LINUX_SC_R4_OFF (LINUX_SC_R0_OFF + 4*8) +#define LINUX_SC_R5_OFF (LINUX_SC_R0_OFF + 5*8) +#define LINUX_SC_R6_OFF (LINUX_SC_R0_OFF + 6*8) +#define LINUX_SC_R7_OFF (LINUX_SC_R0_OFF + 7*8) +#define LINUX_SC_R8_OFF (LINUX_SC_R0_OFF + 8*8) +#define LINUX_SC_R9_OFF (LINUX_SC_R0_OFF + 9*8) +#define LINUX_SC_R10_OFF (LINUX_SC_R0_OFF + 10*8) +#define LINUX_SC_R11_OFF (LINUX_SC_R0_OFF + 11*8) +#define LINUX_SC_R12_OFF (LINUX_SC_R0_OFF + 12*8) +#define LINUX_SC_R13_OFF (LINUX_SC_R0_OFF + 13*8) +#define LINUX_SC_R14_OFF (LINUX_SC_R0_OFF + 14*8) +#define LINUX_SC_R15_OFF (LINUX_SC_R0_OFF + 15*8) +#define LINUX_SC_R16_OFF (LINUX_SC_R0_OFF + 16*8) +#define LINUX_SC_R17_OFF (LINUX_SC_R0_OFF + 17*8) +#define LINUX_SC_R18_OFF (LINUX_SC_R0_OFF + 18*8) +#define LINUX_SC_R19_OFF (LINUX_SC_R0_OFF + 19*8) +#define LINUX_SC_R20_OFF (LINUX_SC_R0_OFF + 20*8) +#define LINUX_SC_R21_OFF (LINUX_SC_R0_OFF + 21*8) +#define LINUX_SC_R22_OFF (LINUX_SC_R0_OFF + 22*8) +#define LINUX_SC_R23_OFF (LINUX_SC_R0_OFF + 23*8) +#define LINUX_SC_R24_OFF (LINUX_SC_R0_OFF + 24*8) +#define LINUX_SC_R25_OFF (LINUX_SC_R0_OFF + 25*8) +#define LINUX_SC_R26_OFF (LINUX_SC_R0_OFF + 26*8) +#define LINUX_SC_R27_OFF (LINUX_SC_R0_OFF + 27*8) +#define LINUX_SC_R28_OFF (LINUX_SC_R0_OFF + 28*8) +#define LINUX_SC_R29_OFF (LINUX_SC_R0_OFF + 29*8) +#define LINUX_SC_R30_OFF (LINUX_SC_R0_OFF + 30*8) +#define LINUX_SC_R31_OFF (LINUX_SC_R0_OFF + 31*8) + +#define LINUX_SC_SP_OFF LINUX_SC_R29_OFF +#define LINUX_SC_PC_OFF (LINUX_UC_MCONTEXT_PC - LINUX_UC_MCONTEXT_OFF) diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/regname.c b/src/coreclr/src/pal/src/libunwind/src/mips/regname.c new file mode 100644 index 00000000000000..b137b972b61762 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/regname.c @@ -0,0 +1,48 @@ +/* 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. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + /* 0. */ + "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", + /* 8. */ + "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", + /* 16. */ + "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", + /* 24. */ + "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else if (reg == UNW_MIPS_PC) + return "pc"; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/mips/siglongjmp.S new file mode 100644 index 00000000000000..9cbcf3dc014d79 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/siglongjmp.S @@ -0,0 +1,8 @@ + /* Dummy implementation for now. */ + + .globl _UI_siglongjmp_cont + .globl _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + j $31 diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/mips/unwind_i.h new file mode 100644 index 00000000000000..3382dcfe58cefc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/mips/unwind_i.h @@ -0,0 +1,43 @@ +/* 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 unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" + +#define mips_lock UNW_OBJ(lock) +#define mips_local_resume UNW_OBJ(local_resume) +#define mips_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern int mips_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); + +extern void mips_local_addr_space_init (void); + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/os-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/os-freebsd.c new file mode 100644 index 00000000000000..753e819dfe4f6f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/os-freebsd.c @@ -0,0 +1,166 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include +#include +#include +#include + +#include "libunwind_i.h" + +static void * +get_mem(size_t sz) +{ + void *res; + + res = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + if (res == MAP_FAILED) + return (NULL); + return (res); +} + +static void +free_mem(void *ptr, size_t sz) +{ + munmap(ptr, sz); +} + +static int +get_pid_by_tid(int tid) +{ + int mib[3], error; + size_t len, len1; + char *buf; + struct kinfo_proc *kv; + unsigned i, pid; + + len = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_ALL; + + error = sysctl(mib, 3, NULL, &len, NULL, 0); + if (error == -1) + return (-1); + len1 = len * 4 / 3; + buf = get_mem(len1); + if (buf == NULL) + return (-1); + len = len1; + error = sysctl(mib, 3, buf, &len, NULL, 0); + if (error == -1) { + free_mem(buf, len1); + return (-1); + } + pid = -1; + for (i = 0, kv = (struct kinfo_proc *)buf; i < len / sizeof(*kv); + i++, kv++) { + if (kv->ki_tid == tid) { + pid = kv->ki_pid; + break; + } + } + free_mem(buf, len1); + return (pid); +} + +int +tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, char *path, size_t pathlen) +{ + int mib[4], error, ret; + size_t len, len1; + char *buf, *bp, *eb; + struct kinfo_vmentry *kv; + + len = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_VMMAP; + mib[3] = pid; + + error = sysctl(mib, 4, NULL, &len, NULL, 0); + if (error == -1) { + if (errno == ESRCH) { + mib[3] = get_pid_by_tid(pid); + if (mib[3] != -1) + error = sysctl(mib, 4, NULL, &len, NULL, 0); + if (error == -1) + return (-UNW_EUNSPEC); + } else + return (-UNW_EUNSPEC); + } + len1 = len * 4 / 3; + buf = get_mem(len1); + if (buf == NULL) + return (-UNW_EUNSPEC); + len = len1; + error = sysctl(mib, 4, buf, &len, NULL, 0); + if (error == -1) { + free_mem(buf, len1); + return (-UNW_EUNSPEC); + } + ret = -UNW_EUNSPEC; + for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) { + kv = (struct kinfo_vmentry *)(uintptr_t)bp; + if (ip < kv->kve_start || ip >= kv->kve_end) + continue; + if (kv->kve_type != KVME_TYPE_VNODE) + continue; + *segbase = kv->kve_start; + *mapoff = kv->kve_offset; + if (path) + { + strncpy(path, kv->kve_path, pathlen); + } + ret = elf_map_image (ei, kv->kve_path); + break; + } + free_mem(buf, len1); + return (ret); +} + +#ifndef UNW_REMOTE_ONLY + +void +tdep_get_exe_image_path (char *path) +{ + int mib[4], error; + size_t len; + + len = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = getpid(); + + error = sysctl(mib, 4, path, &len, NULL, 0); + if (error == -1) + path[0] = 0; +} + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/os-hpux.c b/src/coreclr/src/pal/src/libunwind/src/os-hpux.c new file mode 100644 index 00000000000000..48bfb05cf54a00 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/os-hpux.c @@ -0,0 +1,78 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include + +#include "libunwind_i.h" + +#include "elf64.h" + +HIDDEN int +tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen) +{ + struct load_module_desc lmd; + const char *path2; + + if (pid != getpid ()) + { + printf ("%s: remote case not implemented yet\n", __FUNCTION__); + return -UNW_ENOINFO; + } + + if (!dlmodinfo (ip, &lmd, sizeof (lmd), NULL, 0, 0)) + return -UNW_ENOINFO; + + *segbase = lmd.text_base; + *mapoff = 0; /* XXX fix me? */ + + path2 = dlgetname (&lmd, sizeof (lmd), NULL, 0, 0); + if (!path2) + return -UNW_ENOINFO; + if (path) + { + strncpy(path, path2, pathlen); + path[pathlen - 1] = '\0'; + if (strcmp(path, path2) != 0) + Debug(1, "buffer size (%d) not big enough to hold path\n", pathlen); + } + Debug(1, "segbase=%lx, mapoff=%lx, path=%s\n", *segbase, *mapoff, path); + + return elf_map_image (ei, path); +} + +#ifndef UNW_REMOTE_ONLY + +void +tdep_get_exe_image_path (char *path) +{ + path[0] = 0; /* XXX */ +} + +#endif + diff --git a/src/coreclr/src/pal/src/libunwind/src/os-linux.c b/src/coreclr/src/pal/src/libunwind/src/os-linux.c new file mode 100644 index 00000000000000..8a00669fb3c0f2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/os-linux.c @@ -0,0 +1,73 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "libunwind_i.h" +#include "os-linux.h" + +int +tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen) +{ + struct map_iterator mi; + int found = 0, rc; + unsigned long hi; + + if (maps_init (&mi, pid) < 0) + return -1; + + while (maps_next (&mi, segbase, &hi, mapoff)) + if (ip >= *segbase && ip < hi) + { + found = 1; + break; + } + + if (!found) + { + maps_close (&mi); + return -1; + } + if (path) + { + strncpy(path, mi.path, pathlen); + } + rc = elf_map_image (ei, mi.path); + maps_close (&mi); + return rc; +} + +#ifndef UNW_REMOTE_ONLY + +void +tdep_get_exe_image_path (char *path) +{ + strcpy(path, "/proc/self/exe"); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/os-linux.h b/src/coreclr/src/pal/src/libunwind/src/os-linux.h new file mode 100644 index 00000000000000..3976b38cc293a1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/os-linux.h @@ -0,0 +1,297 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +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 os_linux_h +#define os_linux_h + +struct map_iterator + { + off_t offset; + int fd; + size_t buf_size; + char *buf; + char *buf_end; + char *path; + }; + +static inline char * +ltoa (char *buf, long val) +{ + char *cp = buf, tmp; + ssize_t i, len; + + do + { + *cp++ = '0' + (val % 10); + val /= 10; + } + while (val); + + /* reverse the order of the digits: */ + len = cp - buf; + --cp; + for (i = 0; i < len / 2; ++i) + { + tmp = buf[i]; + buf[i] = cp[-i]; + cp[-i] = tmp; + } + return buf + len; +} + +static inline int +maps_init (struct map_iterator *mi, pid_t pid) +{ + char path[sizeof ("/proc/0123456789/maps")], *cp; + + memcpy (path, "/proc/", 6); + cp = ltoa (path + 6, pid); + assert (cp + 6 < path + sizeof (path)); + memcpy (cp, "/maps", 6); + + mi->fd = open (path, O_RDONLY); + if (mi->fd >= 0) + { + /* Try to allocate a page-sized buffer. */ + mi->buf_size = getpagesize (); + cp = mmap (NULL, mi->buf_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (cp == MAP_FAILED) + { + close(mi->fd); + mi->fd = -1; + return -1; + } + else + { + mi->offset = 0; + mi->buf = mi->buf_end = cp + mi->buf_size; + return 0; + } + } + return -1; +} + +static inline char * +skip_whitespace (char *cp) +{ + if (!cp) + return NULL; + + while (*cp == ' ' || *cp == '\t') + ++cp; + return cp; +} + +static inline char * +scan_hex (char *cp, unsigned long *valp) +{ + unsigned long num_digits = 0, digit, val = 0; + + cp = skip_whitespace (cp); + if (!cp) + return NULL; + + while (1) + { + digit = *cp; + if ((digit - '0') <= 9) + digit -= '0'; + else if ((digit - 'a') < 6) + digit -= 'a' - 10; + else if ((digit - 'A') < 6) + digit -= 'A' - 10; + else + break; + val = (val << 4) | digit; + ++num_digits; + ++cp; + } + if (!num_digits) + return NULL; + *valp = val; + return cp; +} + +static inline char * +scan_dec (char *cp, unsigned long *valp) +{ + unsigned long num_digits = 0, digit, val = 0; + + if (!(cp = skip_whitespace (cp))) + return NULL; + + while (1) + { + digit = *cp; + if ((digit - '0') <= 9) + { + digit -= '0'; + ++cp; + } + else + break; + val = (10 * val) + digit; + ++num_digits; + } + if (!num_digits) + return NULL; + *valp = val; + return cp; +} + +static inline char * +scan_char (char *cp, char *valp) +{ + if (!cp) + return NULL; + + *valp = *cp; + + /* don't step over NUL terminator */ + if (*cp) + ++cp; + return cp; +} + +/* Scan a string delimited by white-space. Fails on empty string or + if string is doesn't fit in the specified buffer. */ +static inline char * +scan_string (char *cp, char *valp, size_t buf_size) +{ + size_t i = 0; + + if (!(cp = skip_whitespace (cp))) + return NULL; + + while (*cp != ' ' && *cp != '\t' && *cp != '\0') + { + if ((valp != NULL) && (i < buf_size - 1)) + valp[i++] = *cp; + ++cp; + } + if (i == 0 || i >= buf_size) + return NULL; + valp[i] = '\0'; + return cp; +} + +static inline int +maps_next (struct map_iterator *mi, + unsigned long *low, unsigned long *high, unsigned long *offset) +{ + char perm[16], dash = 0, colon = 0, *cp; + unsigned long major, minor, inum; + ssize_t i, nread; + + if (mi->fd < 0) + return 0; + + while (1) + { + ssize_t bytes_left = mi->buf_end - mi->buf; + char *eol = NULL; + + for (i = 0; i < bytes_left; ++i) + { + if (mi->buf[i] == '\n') + { + eol = mi->buf + i; + break; + } + else if (mi->buf[i] == '\0') + break; + } + if (!eol) + { + /* copy down the remaining bytes, if any */ + if (bytes_left > 0) + memmove (mi->buf_end - mi->buf_size, mi->buf, bytes_left); + + mi->buf = mi->buf_end - mi->buf_size; + nread = read (mi->fd, mi->buf + bytes_left, + mi->buf_size - bytes_left); + if (nread <= 0) + return 0; + else if ((size_t) (nread + bytes_left) < mi->buf_size) + { + /* Move contents to the end of the buffer so we + maintain the invariant that all bytes between + mi->buf and mi->buf_end are valid. */ + memmove (mi->buf_end - nread - bytes_left, mi->buf, + nread + bytes_left); + mi->buf = mi->buf_end - nread - bytes_left; + } + + eol = mi->buf + bytes_left + nread - 1; + + for (i = bytes_left; i < bytes_left + nread; ++i) + if (mi->buf[i] == '\n') + { + eol = mi->buf + i; + break; + } + } + cp = mi->buf; + mi->buf = eol + 1; + *eol = '\0'; + + /* scan: "LOW-HIGH PERM OFFSET MAJOR:MINOR INUM PATH" */ + cp = scan_hex (cp, low); + cp = scan_char (cp, &dash); + cp = scan_hex (cp, high); + cp = scan_string (cp, perm, sizeof (perm)); + cp = scan_hex (cp, offset); + cp = scan_hex (cp, &major); + cp = scan_char (cp, &colon); + cp = scan_hex (cp, &minor); + cp = scan_dec (cp, &inum); + cp = mi->path = skip_whitespace (cp); + if (!cp) + continue; + cp = scan_string (cp, NULL, 0); + if (dash != '-' || colon != ':') + continue; /* skip line with unknown or bad format */ + return 1; + } + return 0; +} + +static inline void +maps_close (struct map_iterator *mi) +{ + if (mi->fd < 0) + return; + close (mi->fd); + mi->fd = -1; + if (mi->buf) + { + munmap (mi->buf_end - mi->buf_size, mi->buf_size); + mi->buf = mi->buf_end = NULL; + } +} + +#endif /* os_linux_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/os-qnx.c b/src/coreclr/src/pal/src/libunwind/src/os-qnx.c new file mode 100644 index 00000000000000..4a76c7cda41a5f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/os-qnx.c @@ -0,0 +1,117 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2013 Garmin International + Contributed by Matt Fischer + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "libunwind_i.h" + +struct cb_info +{ + unw_word_t ip; + unsigned long segbase; + unsigned long offset; + const char *path; +}; + +static int callback(const struct dl_phdr_info *info, size_t size, void *data) +{ + int i; + struct cb_info *cbi = (struct cb_info*)data; + for(i=0; idlpi_phnum; i++) { + int segbase = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr; + if(cbi->ip >= segbase && cbi->ip < segbase + info->dlpi_phdr[i].p_memsz) + { + cbi->path = info->dlpi_name; + cbi->offset = info->dlpi_phdr[i].p_offset; + cbi->segbase = segbase; + return 1; + } + } + + return 0; +} + +int +tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen) +{ + struct cb_info cbi; + int ret = -1; + cbi.ip = ip; + cbi.segbase = 0; + cbi.offset = 0; + cbi.path = NULL; + + /* QNX's support for accessing symbol maps is severely broken. There is + a devctl() call that can be made on a proc node (DCMD_PROC_MAPDEBUG) + which returns information similar to Linux's /proc//maps + node, however the filename that is returned by this call is not an + absolute path, and there is no foolproof way to map the filename + back to the file that it came from. + + Therefore, the normal approach for implementing this function, + which works equally well for both local and remote unwinding, + will not work here. The only type of image lookup which works + reliably is locally, using dl_iterate_phdr(). However, the only + time that this function is required to look up a remote image is for + ptrace support, which doesn't work on QNX anyway. Local unwinding, + which is the main case that makes use of this function, will work + fine with dl_iterate_phdr(). Therefore, in lieu of any better + platform support for remote image lookup, this function has just + been implemented in terms of dl_iterate_phdr(). + */ + + if (pid != getpid()) + { + /* Return an error if an attempt is made to perform remote image lookup */ + return -1; + } + + if (dl_iterate_phdr (callback, &cbi) != 0) + { + if (path) + { + strncpy (path, cbi.path, pathlen); + } + + *mapoff = cbi.offset; + *segbase = cbi.segbase; + + ret = elf_map_image (ei, cbi.path); + } + + return ret; +} + +#ifndef UNW_REMOTE_ONLY + +void +tdep_get_exe_image_path (char *path) +{ + path[0] = 0; /* XXX */ +} + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/os-solaris.c b/src/coreclr/src/pal/src/libunwind/src/os-solaris.c new file mode 100644 index 00000000000000..3c140ef29c93e9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/os-solaris.c @@ -0,0 +1,73 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "libunwind_i.h" +#include "os-linux.h" // using linux header for map_iterator implementation + +int +tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen) +{ + struct map_iterator mi; + int found = 0, rc; + unsigned long hi; + + if (maps_init (&mi, pid) < 0) + return -1; + + while (maps_next (&mi, segbase, &hi, mapoff)) + if (ip >= *segbase && ip < hi) + { + found = 1; + break; + } + + if (!found) + { + maps_close (&mi); + return -1; + } + if (path) + { + strncpy(path, mi.path, pathlen); + } + rc = elf_map_image (ei, mi.path); + maps_close (&mi); + return rc; +} + +#ifndef UNW_REMOTE_ONLY + +void +tdep_get_exe_image_path (char *path) +{ + strcpy(path, getexecname()); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_proc_info.c new file mode 100644 index 00000000000000..7dfb6d4e4271b1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_proc_info.c @@ -0,0 +1,41 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = dwarf_make_proc_info (&c->dwarf); + if (ret < 0) + return ret; + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_save_loc.c new file mode 100644 index 00000000000000..5343fa4c7f3627 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Gget_save_loc.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + /* XXX: empty stub. */ + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_local.c new file mode 100644 index 00000000000000..366cf5bdaf3e36 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_local.c @@ -0,0 +1,88 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#ifdef UNW_TARGET_PPC64 +#include "../ppc64/init.h" +#else +#include "../ppc32/init.h" +#endif + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + /* XXX: empty stub. */ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + #ifdef UNW_TARGET_PPC64 + return common_init_ppc64 (c, use_prev_instr); + #else + return common_init_ppc32 (c, use_prev_instr); + #endif +} + +int +unw_init_local(unw_cursor_t *cursor, ucontext_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_remote.c new file mode 100644 index 00000000000000..ed85be8971f061 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Ginit_remote.c @@ -0,0 +1,60 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#ifdef UNW_TARGET_PPC64 +#include "../ppc64/init.h" +#else +#include "../ppc32/init.h" +#endif + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + + #ifdef UNW_TARGET_PPC64 + return common_init_ppc64 (c, 0); + #elif UNW_TARGET_PPC32 + return common_init_ppc32 (c, 0); + #else + #error init_remote :: NO VALID PPC ARCH! + #endif +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Gis_signal_frame.c new file mode 100644 index 00000000000000..6184dd5d410d71 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Gis_signal_frame.c @@ -0,0 +1,78 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +int +unw_is_signal_frame (unw_cursor_t * cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, i0, i1, i2, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + as->validate = 1; /* Don't trust the ip */ + arg = c->dwarf.as_arg; + + /* Check if return address points at sigreturn sequence. + on ppc64 Linux that is (see libc.so): + 0x38210080 addi r1, r1, 128 // pop the stack + 0x380000ac li r0, 172 // invoke system service 172 + 0x44000002 sc + */ + + ip = c->dwarf.ip; + if (ip == 0) + return 0; + + /* Read up two 8-byte words at the IP. We are only looking at 3 + consecutive 32-bit words, so the second 8-byte word needs to be + shifted right by 32 bits (think big-endian) */ + + a = unw_get_accessors_int (as); + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0) + return 0; + + if (tdep_big_endian (as)) + { + i0 = w0 >> 32; + i1 = w0 & 0xffffffffUL; + i2 = w1 >> 32; + } + else + { + i0 = w0 & 0xffffffffUL; + i1 = w0 >> 32; + i2 = w1 & 0xffffffffUL; + } + + return (i0 == 0x38210080 && i1 == 0x380000ac && i2 == 0x44000002); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Lis_signal_frame.c new file mode 100644 index 00000000000000..b9a7c4f51ad9fa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/longjmp.S b/src/coreclr/src/pal/src/libunwind/src/ppc/longjmp.S new file mode 100644 index 00000000000000..d363aef222f404 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/longjmp.S @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + + Copied from src/x86_64/, modified slightly (or made empty stubs) for + building frysk successfully on ppc64, by Wu Zhou + +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. */ + + .globl _UI_longjmp_cont + + .type _UI_longjmp_cont, @function +_UI_longjmp_cont: + .size _UI_longjmp_cont, .-_UI_longjmp_cont + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/ppc/siglongjmp.S new file mode 100644 index 00000000000000..64be36ce170281 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc/siglongjmp.S @@ -0,0 +1,31 @@ +/* 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. */ + + .globl _UI_siglongjmp_cont + + _UI_siglongjmp_cont: + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gcreate_addr_space.c new file mode 100644 index 00000000000000..aaa68bb3543d0c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gcreate_addr_space.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * We support only big-endian on Linux ppc32. + */ + if (byte_order != 0 && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gglobal.c new file mode 100644 index 00000000000000..a0f80beec6d95a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gglobal.c @@ -0,0 +1,135 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (ppc32_lock); +HIDDEN int tdep_init_done; + +/* The API register numbers are exactly the same as the .eh_frame + registers, for now at least. */ +HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] = + { + [UNW_PPC32_R0]=UNW_PPC32_R0, + [UNW_PPC32_R1]=UNW_PPC32_R1, + [UNW_PPC32_R2]=UNW_PPC32_R2, + [UNW_PPC32_R3]=UNW_PPC32_R3, + [UNW_PPC32_R4]=UNW_PPC32_R4, + [UNW_PPC32_R5]=UNW_PPC32_R5, + [UNW_PPC32_R6]=UNW_PPC32_R6, + [UNW_PPC32_R7]=UNW_PPC32_R7, + [UNW_PPC32_R8]=UNW_PPC32_R8, + [UNW_PPC32_R9]=UNW_PPC32_R9, + [UNW_PPC32_R10]=UNW_PPC32_R10, + [UNW_PPC32_R11]=UNW_PPC32_R11, + [UNW_PPC32_R12]=UNW_PPC32_R12, + [UNW_PPC32_R13]=UNW_PPC32_R13, + [UNW_PPC32_R14]=UNW_PPC32_R14, + [UNW_PPC32_R15]=UNW_PPC32_R15, + [UNW_PPC32_R16]=UNW_PPC32_R16, + [UNW_PPC32_R17]=UNW_PPC32_R17, + [UNW_PPC32_R18]=UNW_PPC32_R18, + [UNW_PPC32_R19]=UNW_PPC32_R19, + [UNW_PPC32_R20]=UNW_PPC32_R20, + [UNW_PPC32_R21]=UNW_PPC32_R21, + [UNW_PPC32_R22]=UNW_PPC32_R22, + [UNW_PPC32_R23]=UNW_PPC32_R23, + [UNW_PPC32_R24]=UNW_PPC32_R24, + [UNW_PPC32_R25]=UNW_PPC32_R25, + [UNW_PPC32_R26]=UNW_PPC32_R26, + [UNW_PPC32_R27]=UNW_PPC32_R27, + [UNW_PPC32_R28]=UNW_PPC32_R28, + [UNW_PPC32_R29]=UNW_PPC32_R29, + [UNW_PPC32_R30]=UNW_PPC32_R30, + [UNW_PPC32_R31]=UNW_PPC32_R31, + + [UNW_PPC32_CTR]=UNW_PPC32_CTR, + [UNW_PPC32_XER]=UNW_PPC32_XER, + [UNW_PPC32_CCR]=UNW_PPC32_CCR, + [UNW_PPC32_LR]=UNW_PPC32_LR, + [UNW_PPC32_FPSCR]=UNW_PPC32_FPSCR, + + [UNW_PPC32_F0]=UNW_PPC32_F0, + [UNW_PPC32_F1]=UNW_PPC32_F1, + [UNW_PPC32_F2]=UNW_PPC32_F2, + [UNW_PPC32_F3]=UNW_PPC32_F3, + [UNW_PPC32_F4]=UNW_PPC32_F4, + [UNW_PPC32_F5]=UNW_PPC32_F5, + [UNW_PPC32_F6]=UNW_PPC32_F6, + [UNW_PPC32_F7]=UNW_PPC32_F7, + [UNW_PPC32_F8]=UNW_PPC32_F8, + [UNW_PPC32_F9]=UNW_PPC32_F9, + [UNW_PPC32_F10]=UNW_PPC32_F10, + [UNW_PPC32_F11]=UNW_PPC32_F11, + [UNW_PPC32_F12]=UNW_PPC32_F12, + [UNW_PPC32_F13]=UNW_PPC32_F13, + [UNW_PPC32_F14]=UNW_PPC32_F14, + [UNW_PPC32_F15]=UNW_PPC32_F15, + [UNW_PPC32_F16]=UNW_PPC32_F16, + [UNW_PPC32_F17]=UNW_PPC32_F17, + [UNW_PPC32_F18]=UNW_PPC32_F18, + [UNW_PPC32_F19]=UNW_PPC32_F19, + [UNW_PPC32_F20]=UNW_PPC32_F20, + [UNW_PPC32_F21]=UNW_PPC32_F21, + [UNW_PPC32_F22]=UNW_PPC32_F22, + [UNW_PPC32_F23]=UNW_PPC32_F23, + [UNW_PPC32_F24]=UNW_PPC32_F24, + [UNW_PPC32_F25]=UNW_PPC32_F25, + [UNW_PPC32_F26]=UNW_PPC32_F26, + [UNW_PPC32_F27]=UNW_PPC32_F27, + [UNW_PPC32_F28]=UNW_PPC32_F28, + [UNW_PPC32_F29]=UNW_PPC32_F29, + [UNW_PPC32_F30]=UNW_PPC32_F30, + [UNW_PPC32_F31]=UNW_PPC32_F31, +}; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&ppc32_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + ppc32_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&ppc32_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c new file mode 100644 index 00000000000000..7b45455807c89c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c @@ -0,0 +1,219 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "ucontext_i.h" +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static void * +uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + if ((unsigned) (reg - UNW_PPC32_R0) < 32) + addr = &uc->uc_mcontext.uc_regs->gregs[reg - UNW_PPC32_R0]; + + else + if ( ((unsigned) (reg - UNW_PPC32_F0) < 32) && + ((unsigned) (reg - UNW_PPC32_F0) >= 0) ) + addr = &uc->uc_mcontext.uc_regs->fpregs.fpregs[reg - UNW_PPC32_F0]; + + else + { + unsigned gregs_idx; + + switch (reg) + { + case UNW_PPC32_CTR: + gregs_idx = CTR_IDX; + break; + case UNW_PPC32_LR: + gregs_idx = LINK_IDX; + break; + case UNW_PPC32_XER: + gregs_idx = XER_IDX; + break; + case UNW_PPC32_CCR: + gregs_idx = CCR_IDX; + break; + default: + return NULL; + } + addr = &uc->uc_mcontext.uc_regs->gregs[gregs_idx]; + } + return addr; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (12, "mem[%lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "mem[%lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if ( ((unsigned int) (reg - UNW_PPC32_F0) < 32) && + ((unsigned int) (reg - UNW_PPC32_F0) >= 0)) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + } + return 0; + +badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if ((unsigned) (reg - UNW_PPC32_F0) < 0) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + Debug (12, "%s <- %016Lf\n", unw_regname (reg), *val); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %016Lf\n", unw_regname (reg), *val); + } + return 0; + +badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +ppc32_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = ppc32_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gregs.c new file mode 100644 index 00000000000000..9344455e6cc467 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gregs.c @@ -0,0 +1,90 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + struct dwarf_loc loc; + + switch (reg) + { + case UNW_TDEP_IP: + if (write) + { + c->dwarf.ip = *valp; /* update the IP cache */ + if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip + || *valp >= c->dwarf.pi.end_ip)) + c->dwarf.pi_valid = 0; /* new IP outside of current proc */ + } + else + *valp = c->dwarf.ip; + return 0; + + case UNW_TDEP_SP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + + default: + break; + } + + /* make sure it's not an FP or VR register */ + if ((((unsigned) (reg - UNW_PPC32_F0)) <= 31)) + return -UNW_EBADREG; + + loc = c->dwarf.loc[reg]; + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + struct dwarf_loc loc; + + if ((unsigned) (reg - UNW_PPC32_F0) < 32) + { + loc = c->dwarf.loc[reg]; + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); + } + + return -UNW_EBADREG; +} + diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gresume.c new file mode 100644 index 00000000000000..c0f95837b33c18 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gresume.c @@ -0,0 +1,77 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford cjashfor@us.ibm.com + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +#include + +/* sigreturn() is a no-op on x86_64 glibc. */ + +static NORETURN inline long +my_rt_sigreturn (void *new_sp) +{ + /* XXX: empty stub. */ + abort (); +} + +HIDDEN inline int +ppc32_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + /* XXX: empty stub. */ + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + /* XXX: empty stub. */ + return 0; +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gstep.c new file mode 100644 index 00000000000000..478d3a6c1b89f5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Gstep.c @@ -0,0 +1,309 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" +#include + +/* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is + defined there only when __KERNEL__ is defined. We reproduce it here for + our use at the user level in order to locate the ucontext record, which + appears to be at this offset relative to the stack pointer when in the + context of the signal handler return trampoline code - + __kernel_sigtramp_rt64. */ +#define __SIGNAL_FRAMESIZE 128 + +/* This definition comes from the document "64-bit PowerPC ELF Application + Binary Interface Supplement 1.9", section 3.2.2. + http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */ + +typedef struct +{ + long unsigned back_chain; + long unsigned lr_save; + /* many more fields here, but they are unused by this code */ +} stack_frame_t; + + +int +unw_step (unw_cursor_t * cursor) +{ + struct cursor *c = (struct cursor *) cursor; + stack_frame_t dummy; + unw_word_t back_chain_offset, lr_save_offset; + struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc; + int ret; + + Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); + + if (c->dwarf.ip == 0) + { + /* Unless the cursor or stack is corrupt or uninitialized, + we've most likely hit the top of the stack */ + return 0; + } + + /* Try DWARF-based unwinding... */ + + ret = dwarf_step (&c->dwarf); + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (unlikely (ret < 0)) + { + if (likely (unw_is_signal_frame (cursor) <= 0)) + { + /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode + produces the mandatory level of traceback record in the code, but + I get the impression that this is transitory, that eventually gcc + will not produce any traceback records at all. So, for now, we + won't bother to try to find and use these records. + + We can, however, attempt to unwind the frame by using the callback + chain. This is very crude, however, and won't be able to unwind + any registers besides the IP, SP, and LR . */ + + back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy); + lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy); + + back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0); + + if ((ret = + dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0) + { + Debug (2, + "Unable to retrieve CFA from back chain in stack frame - %d\n", + ret); + return ret; + } + if (c->dwarf.cfa == 0) + /* Unless the cursor or stack is corrupt or uninitialized we've most + likely hit the top of the stack */ + return 0; + + lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0); + + if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0) + { + Debug (2, + "Unable to retrieve IP from lr save in stack frame - %d\n", + ret); + return ret; + } + ret = 1; + } + else + { + /* Find the sigcontext record by taking the CFA and adjusting by + the dummy signal frame size. + + Note that there isn't any way to determined if SA_SIGINFO was + set in the sa_flags parameter to sigaction when the signal + handler was established. If it was not set, the ucontext + record is not required to be on the stack, in which case the + following code will likely cause a seg fault or other crash + condition. */ + + unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE; + + Debug (1, "signal frame, skip over trampoline\n"); + + c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME; + c->sigcontext_addr = ucontext; + + sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); + ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); + + ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + /* Instead of just restoring the non-volatile registers, do all + of the registers for now. This will incur a performance hit, + but it's rare enough not to cause too much of a problem, and + might be useful in some cases. */ + c->dwarf.loc[UNW_PPC32_R0] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0); + c->dwarf.loc[UNW_PPC32_R1] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); + c->dwarf.loc[UNW_PPC32_R2] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0); + c->dwarf.loc[UNW_PPC32_R3] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0); + c->dwarf.loc[UNW_PPC32_R4] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0); + c->dwarf.loc[UNW_PPC32_R5] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0); + c->dwarf.loc[UNW_PPC32_R6] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0); + c->dwarf.loc[UNW_PPC32_R7] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0); + c->dwarf.loc[UNW_PPC32_R8] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); + c->dwarf.loc[UNW_PPC32_R9] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); + c->dwarf.loc[UNW_PPC32_R10] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); + c->dwarf.loc[UNW_PPC32_R11] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); + c->dwarf.loc[UNW_PPC32_R12] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); + c->dwarf.loc[UNW_PPC32_R13] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); + c->dwarf.loc[UNW_PPC32_R14] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); + c->dwarf.loc[UNW_PPC32_R15] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); + c->dwarf.loc[UNW_PPC32_R16] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0); + c->dwarf.loc[UNW_PPC32_R17] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0); + c->dwarf.loc[UNW_PPC32_R18] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0); + c->dwarf.loc[UNW_PPC32_R19] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0); + c->dwarf.loc[UNW_PPC32_R20] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0); + c->dwarf.loc[UNW_PPC32_R21] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0); + c->dwarf.loc[UNW_PPC32_R22] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0); + c->dwarf.loc[UNW_PPC32_R23] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0); + c->dwarf.loc[UNW_PPC32_R24] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0); + c->dwarf.loc[UNW_PPC32_R25] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0); + c->dwarf.loc[UNW_PPC32_R26] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0); + c->dwarf.loc[UNW_PPC32_R27] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0); + c->dwarf.loc[UNW_PPC32_R28] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0); + c->dwarf.loc[UNW_PPC32_R29] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0); + c->dwarf.loc[UNW_PPC32_R30] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0); + c->dwarf.loc[UNW_PPC32_R31] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0); + + c->dwarf.loc[UNW_PPC32_LR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); + c->dwarf.loc[UNW_PPC32_CTR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0); + + /* This CR0 assignment is probably wrong. There are 8 dwarf columns + assigned to the CR registers, but only one CR register in the + mcontext structure */ + c->dwarf.loc[UNW_PPC32_CCR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0); + c->dwarf.loc[UNW_PPC32_XER] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0); + + c->dwarf.loc[UNW_PPC32_F0] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0); + c->dwarf.loc[UNW_PPC32_F1] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0); + c->dwarf.loc[UNW_PPC32_F2] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0); + c->dwarf.loc[UNW_PPC32_F3] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0); + c->dwarf.loc[UNW_PPC32_F4] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0); + c->dwarf.loc[UNW_PPC32_F5] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0); + c->dwarf.loc[UNW_PPC32_F6] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0); + c->dwarf.loc[UNW_PPC32_F7] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0); + c->dwarf.loc[UNW_PPC32_F8] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0); + c->dwarf.loc[UNW_PPC32_F9] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0); + c->dwarf.loc[UNW_PPC32_F10] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0); + c->dwarf.loc[UNW_PPC32_F11] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0); + c->dwarf.loc[UNW_PPC32_F12] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0); + c->dwarf.loc[UNW_PPC32_F13] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0); + c->dwarf.loc[UNW_PPC32_F14] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0); + c->dwarf.loc[UNW_PPC32_F15] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0); + c->dwarf.loc[UNW_PPC32_F16] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0); + c->dwarf.loc[UNW_PPC32_F17] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0); + c->dwarf.loc[UNW_PPC32_F18] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0); + c->dwarf.loc[UNW_PPC32_F19] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0); + c->dwarf.loc[UNW_PPC32_F20] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0); + c->dwarf.loc[UNW_PPC32_F21] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0); + c->dwarf.loc[UNW_PPC32_F22] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0); + c->dwarf.loc[UNW_PPC32_F23] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0); + c->dwarf.loc[UNW_PPC32_F24] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0); + c->dwarf.loc[UNW_PPC32_F25] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0); + c->dwarf.loc[UNW_PPC32_F26] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0); + c->dwarf.loc[UNW_PPC32_F27] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0); + c->dwarf.loc[UNW_PPC32_F28] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0); + c->dwarf.loc[UNW_PPC32_F29] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0); + c->dwarf.loc[UNW_PPC32_F30] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0); + c->dwarf.loc[UNW_PPC32_F31] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0); + + ret = 1; + } + } + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lglobal.c new file mode 100644 index 00000000000000..6d7b489e14bd9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Linit.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Make-arch.in b/src/coreclr/src/pal/src/libunwind/src/ppc32/Make-arch.in new file mode 100644 index 00000000000000..947dd5fa03d767 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Make-arch.in @@ -0,0 +1,11 @@ +# Word size. +ELFW = 64 +# Does use dwarf2 unwind info. +dwarf_target = true + +libunwind_setjmp_OBJS += \ + $(arch)/longjmp.o \ + $(arch)/siglongjmp.o + +libunwind_OBJS_common += \ + $(arch)/is_fpreg.o diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/get_func_addr.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/get_func_addr.c new file mode 100644 index 00000000000000..66ff795fe7e163 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/get_func_addr.c @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +tdep_get_func_addr (unw_addr_space_t as, unw_word_t symbol_val_addr, + unw_word_t *real_func_addr) +{ + *real_func_addr = symbol_val_addr; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/init.h b/src/coreclr/src/pal/src/libunwind/src/ppc32/init.h new file mode 100644 index 00000000000000..87a69b1450ae19 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/init.h @@ -0,0 +1,72 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* Here is the "common" init, for remote and local debuging" */ + +static inline int +common_init_ppc32 (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + int i; + + for (i = UNW_PPC32_R0; i <= UNW_PPC32_R31; i++) { + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); + } + for (i = UNW_PPC32_F0; i <= UNW_PPC32_F31; i++) { + c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i); + } + + c->dwarf.loc[UNW_PPC32_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CTR); + c->dwarf.loc[UNW_PPC32_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_XER); + c->dwarf.loc[UNW_PPC32_CCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_CCR); + c->dwarf.loc[UNW_PPC32_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_LR); + c->dwarf.loc[UNW_PPC32_FPSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC32_FPSCR); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC32_LR], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_PPC32_R1), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = PPC_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/is_fpreg.c new file mode 100644 index 00000000000000..646ff2379c4976 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/is_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_is_fpreg (int regnum) +{ + return (regnum >= UNW_PPC32_F0 && regnum <= UNW_PPC32_F31); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/regname.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/regname.c new file mode 100644 index 00000000000000..459b83a4e559a2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/regname.c @@ -0,0 +1,112 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + [UNW_PPC32_R0]="GPR0", + [UNW_PPC32_R1]="GPR1", + [UNW_PPC32_R2]="GPR2", + [UNW_PPC32_R3]="GPR3", + [UNW_PPC32_R4]="GPR4", + [UNW_PPC32_R5]="GPR5", + [UNW_PPC32_R6]="GPR6", + [UNW_PPC32_R7]="GPR7", + [UNW_PPC32_R8]="GPR8", + [UNW_PPC32_R9]="GPR9", + [UNW_PPC32_R10]="GPR10", + [UNW_PPC32_R11]="GPR11", + [UNW_PPC32_R12]="GPR12", + [UNW_PPC32_R13]="GPR13", + [UNW_PPC32_R14]="GPR14", + [UNW_PPC32_R15]="GPR15", + [UNW_PPC32_R16]="GPR16", + [UNW_PPC32_R17]="GPR17", + [UNW_PPC32_R18]="GPR18", + [UNW_PPC32_R19]="GPR19", + [UNW_PPC32_R20]="GPR20", + [UNW_PPC32_R21]="GPR21", + [UNW_PPC32_R22]="GPR22", + [UNW_PPC32_R23]="GPR23", + [UNW_PPC32_R24]="GPR24", + [UNW_PPC32_R25]="GPR25", + [UNW_PPC32_R26]="GPR26", + [UNW_PPC32_R27]="GPR27", + [UNW_PPC32_R28]="GPR28", + [UNW_PPC32_R29]="GPR29", + [UNW_PPC32_R30]="GPR30", + [UNW_PPC32_R31]="GPR31", + + [UNW_PPC32_CTR]="CTR", + [UNW_PPC32_XER]="XER", + [UNW_PPC32_CCR]="CCR", + [UNW_PPC32_LR]="LR", + [UNW_PPC32_FPSCR]="FPSCR", + + [UNW_PPC32_F0]="FPR0", + [UNW_PPC32_F1]="FPR1", + [UNW_PPC32_F2]="FPR2", + [UNW_PPC32_F3]="FPR3", + [UNW_PPC32_F4]="FPR4", + [UNW_PPC32_F5]="FPR5", + [UNW_PPC32_F6]="FPR6", + [UNW_PPC32_F7]="FPR7", + [UNW_PPC32_F8]="FPR8", + [UNW_PPC32_F9]="FPR9", + [UNW_PPC32_F10]="FPR10", + [UNW_PPC32_F11]="FPR11", + [UNW_PPC32_F12]="FPR12", + [UNW_PPC32_F13]="FPR13", + [UNW_PPC32_F14]="FPR14", + [UNW_PPC32_F15]="FPR15", + [UNW_PPC32_F16]="FPR16", + [UNW_PPC32_F17]="FPR17", + [UNW_PPC32_F18]="FPR18", + [UNW_PPC32_F19]="FPR19", + [UNW_PPC32_F20]="FPR20", + [UNW_PPC32_F21]="FPR21", + [UNW_PPC32_F22]="FPR22", + [UNW_PPC32_F23]="FPR23", + [UNW_PPC32_F24]="FPR24", + [UNW_PPC32_F25]="FPR25", + [UNW_PPC32_F26]="FPR26", + [UNW_PPC32_F27]="FPR27", + [UNW_PPC32_F28]="FPR28", + [UNW_PPC32_F29]="FPR29", + [UNW_PPC32_F30]="FPR30", + [UNW_PPC32_F31]="FPR31" +}; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/ppc32/setcontext.S new file mode 100644 index 00000000000000..b54378a9dc249d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/setcontext.S @@ -0,0 +1,9 @@ + .global _UI_setcontext + +_UI_setcontext: + retq + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/ppc32/ucontext_i.h new file mode 100644 index 00000000000000..c6ba806a00caa5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/ucontext_i.h @@ -0,0 +1,128 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +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 ucontext_i_h +#define ucontext_i_h + +#include "compiler.h" +#include + +/* These values were derived by reading + /usr/src/linux-2.6.18-1.8/arch/um/include/sysdep-ppc/ptrace.h and + /usr/src/linux-2.6.18-1.8/arch/powerpc/kernel/ppc32.h +*/ + +//#define NIP_IDX 32 +#define CTR_IDX 32 +#define XER_IDX 33 +#define CCR_IDX 34 +#define MSR_IDX 35 +//#define MQ_IDX 36 +#define LINK_IDX 36 + +/* These are dummy structures used only for obtaining the offsets of the + various structure members. */ +static ucontext_t dmy_ctxt UNUSED; + +#define UC_MCONTEXT_GREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[0] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[1] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[2] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[3] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[4] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[5] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[6] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[7] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[8] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[9] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[10] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[11] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[12] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[13] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[14] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[15] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[16] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[17] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[18] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[19] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[20] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[21] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[22] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[23] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[24] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[25] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[26] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[27] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[28] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[29] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[30] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[31] - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[MSR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CTR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_LINK ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[LINK_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_XER ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[XER_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_CCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[CCR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_SOFTE ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[SOFTE_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_TRAP ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[TRAP_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_DAR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[DAR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_DSISR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[DSISR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_RESULT ((void *)&dmy_ctxt.uc_mcontext.uc_regs->gregs[RESULT_IDX] - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_FREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[0] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[1] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[2] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[3] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[4] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[5] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[6] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[7] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[8] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[9] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[10] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[11] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[12] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[13] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[14] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[15] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[16] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[17] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[18] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[19] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[20] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[21] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[22] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[23] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[24] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[25] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[26] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[27] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[28] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[29] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[30] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[31] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.uc_regs->fpregs.fpregs[32] - (void *)&dmy_ctxt) + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/ppc32/unwind_i.h new file mode 100644 index 00000000000000..ad32d0565441f4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/unwind_i.h @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include +#include + +#define ppc32_lock UNW_OBJ(lock) +#define ppc32_local_resume UNW_OBJ(local_resume) +#define ppc32_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern void ppc32_local_addr_space_init (void); +extern int ppc32_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gcreate_addr_space.c new file mode 100644 index 00000000000000..bd48555d4e8294 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gcreate_addr_space.c @@ -0,0 +1,71 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * We support both big- and little-endian on Linux ppc64. + */ + if (byte_order != 0 + && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + if (byte_order == 0) + /* use host default: */ + as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + else + as->big_endian = (byte_order == __BIG_ENDIAN); + + /* FIXME! There is no way to specify the ABI. + Default to ELFv1 on big-endian and ELFv2 on little-endian. */ + if (as->big_endian) + as->abi = UNW_PPC64_ABI_ELFv1; + else + as->abi = UNW_PPC64_ABI_ELFv2; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gglobal.c new file mode 100644 index 00000000000000..9d0b0f55a6c0d1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gglobal.c @@ -0,0 +1,182 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (ppc64_lock); +HIDDEN int tdep_init_done; + +/* The API register numbers are exactly the same as the .eh_frame + registers, for now at least. */ +HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH] = + { + [UNW_PPC64_R0]=UNW_PPC64_R0, + [UNW_PPC64_R1]=UNW_PPC64_R1, + [UNW_PPC64_R2]=UNW_PPC64_R2, + [UNW_PPC64_R3]=UNW_PPC64_R3, + [UNW_PPC64_R4]=UNW_PPC64_R4, + [UNW_PPC64_R5]=UNW_PPC64_R5, + [UNW_PPC64_R6]=UNW_PPC64_R6, + [UNW_PPC64_R7]=UNW_PPC64_R7, + [UNW_PPC64_R8]=UNW_PPC64_R8, + [UNW_PPC64_R9]=UNW_PPC64_R9, + [UNW_PPC64_R10]=UNW_PPC64_R10, + [UNW_PPC64_R11]=UNW_PPC64_R11, + [UNW_PPC64_R12]=UNW_PPC64_R12, + [UNW_PPC64_R13]=UNW_PPC64_R13, + [UNW_PPC64_R14]=UNW_PPC64_R14, + [UNW_PPC64_R15]=UNW_PPC64_R15, + [UNW_PPC64_R16]=UNW_PPC64_R16, + [UNW_PPC64_R17]=UNW_PPC64_R17, + [UNW_PPC64_R18]=UNW_PPC64_R18, + [UNW_PPC64_R19]=UNW_PPC64_R19, + [UNW_PPC64_R20]=UNW_PPC64_R20, + [UNW_PPC64_R21]=UNW_PPC64_R21, + [UNW_PPC64_R22]=UNW_PPC64_R22, + [UNW_PPC64_R23]=UNW_PPC64_R23, + [UNW_PPC64_R24]=UNW_PPC64_R24, + [UNW_PPC64_R25]=UNW_PPC64_R25, + [UNW_PPC64_R26]=UNW_PPC64_R26, + [UNW_PPC64_R27]=UNW_PPC64_R27, + [UNW_PPC64_R28]=UNW_PPC64_R28, + [UNW_PPC64_R29]=UNW_PPC64_R29, + [UNW_PPC64_R30]=UNW_PPC64_R30, + [UNW_PPC64_R31]=UNW_PPC64_R31, + + [UNW_PPC64_F0]=UNW_PPC64_F0, + [UNW_PPC64_F1]=UNW_PPC64_F1, + [UNW_PPC64_F2]=UNW_PPC64_F2, + [UNW_PPC64_F3]=UNW_PPC64_F3, + [UNW_PPC64_F4]=UNW_PPC64_F4, + [UNW_PPC64_F5]=UNW_PPC64_F5, + [UNW_PPC64_F6]=UNW_PPC64_F6, + [UNW_PPC64_F7]=UNW_PPC64_F7, + [UNW_PPC64_F8]=UNW_PPC64_F8, + [UNW_PPC64_F9]=UNW_PPC64_F9, + [UNW_PPC64_F10]=UNW_PPC64_F10, + [UNW_PPC64_F11]=UNW_PPC64_F11, + [UNW_PPC64_F12]=UNW_PPC64_F12, + [UNW_PPC64_F13]=UNW_PPC64_F13, + [UNW_PPC64_F14]=UNW_PPC64_F14, + [UNW_PPC64_F15]=UNW_PPC64_F15, + [UNW_PPC64_F16]=UNW_PPC64_F16, + [UNW_PPC64_F17]=UNW_PPC64_F17, + [UNW_PPC64_F18]=UNW_PPC64_F18, + [UNW_PPC64_F19]=UNW_PPC64_F19, + [UNW_PPC64_F20]=UNW_PPC64_F20, + [UNW_PPC64_F21]=UNW_PPC64_F21, + [UNW_PPC64_F22]=UNW_PPC64_F22, + [UNW_PPC64_F23]=UNW_PPC64_F23, + [UNW_PPC64_F24]=UNW_PPC64_F24, + [UNW_PPC64_F25]=UNW_PPC64_F25, + [UNW_PPC64_F26]=UNW_PPC64_F26, + [UNW_PPC64_F27]=UNW_PPC64_F27, + [UNW_PPC64_F28]=UNW_PPC64_F28, + [UNW_PPC64_F29]=UNW_PPC64_F29, + [UNW_PPC64_F30]=UNW_PPC64_F30, + [UNW_PPC64_F31]=UNW_PPC64_F31, + + [UNW_PPC64_LR]=UNW_PPC64_LR, + [UNW_PPC64_CTR]=UNW_PPC64_CTR, + [UNW_PPC64_ARG_POINTER]=UNW_PPC64_ARG_POINTER, + + [UNW_PPC64_CR0]=UNW_PPC64_CR0, + [UNW_PPC64_CR1]=UNW_PPC64_CR1, + [UNW_PPC64_CR2]=UNW_PPC64_CR2, + [UNW_PPC64_CR3]=UNW_PPC64_CR3, + [UNW_PPC64_CR4]=UNW_PPC64_CR4, + [UNW_PPC64_CR5]=UNW_PPC64_CR5, + [UNW_PPC64_CR6]=UNW_PPC64_CR6, + [UNW_PPC64_CR7]=UNW_PPC64_CR7, + + [UNW_PPC64_XER]=UNW_PPC64_XER, + + [UNW_PPC64_V0]=UNW_PPC64_V0, + [UNW_PPC64_V1]=UNW_PPC64_V1, + [UNW_PPC64_V2]=UNW_PPC64_V2, + [UNW_PPC64_V3]=UNW_PPC64_V3, + [UNW_PPC64_V4]=UNW_PPC64_V4, + [UNW_PPC64_V5]=UNW_PPC64_V5, + [UNW_PPC64_V6]=UNW_PPC64_V6, + [UNW_PPC64_V7]=UNW_PPC64_V7, + [UNW_PPC64_V8]=UNW_PPC64_V8, + [UNW_PPC64_V9]=UNW_PPC64_V9, + [UNW_PPC64_V10]=UNW_PPC64_V10, + [UNW_PPC64_V11]=UNW_PPC64_V11, + [UNW_PPC64_V12]=UNW_PPC64_V12, + [UNW_PPC64_V13]=UNW_PPC64_V13, + [UNW_PPC64_V14]=UNW_PPC64_V14, + [UNW_PPC64_V15]=UNW_PPC64_V15, + [UNW_PPC64_V16]=UNW_PPC64_V16, + [UNW_PPC64_V17]=UNW_PPC64_V17, + [UNW_PPC64_V18]=UNW_PPC64_V18, + [UNW_PPC64_V19]=UNW_PPC64_V19, + [UNW_PPC64_V20]=UNW_PPC64_V20, + [UNW_PPC64_V21]=UNW_PPC64_V21, + [UNW_PPC64_V22]=UNW_PPC64_V22, + [UNW_PPC64_V23]=UNW_PPC64_V23, + [UNW_PPC64_V24]=UNW_PPC64_V24, + [UNW_PPC64_V25]=UNW_PPC64_V25, + [UNW_PPC64_V26]=UNW_PPC64_V26, + [UNW_PPC64_V27]=UNW_PPC64_V27, + [UNW_PPC64_V28]=UNW_PPC64_V28, + [UNW_PPC64_V29]=UNW_PPC64_V29, + [UNW_PPC64_V30]=UNW_PPC64_V30, + [UNW_PPC64_V31]=UNW_PPC64_V31, + + [UNW_PPC64_VRSAVE]=UNW_PPC64_VRSAVE, + [UNW_PPC64_VSCR]=UNW_PPC64_VSCR, + [UNW_PPC64_SPE_ACC]=UNW_PPC64_SPE_ACC, + [UNW_PPC64_SPEFSCR]=UNW_PPC64_SPEFSCR, + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&ppc64_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + ppc64_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&ppc64_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c new file mode 100644 index 00000000000000..7bfb395a7923c0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c @@ -0,0 +1,232 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "ucontext_i.h" +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static void * +uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + if ((unsigned) (reg - UNW_PPC64_R0) < 32) + addr = &uc->uc_mcontext.gp_regs[reg - UNW_PPC64_R0]; + + else if ((unsigned) (reg - UNW_PPC64_F0) < 32) + addr = &uc->uc_mcontext.fp_regs[reg - UNW_PPC64_F0]; + + else if ((unsigned) (reg - UNW_PPC64_V0) < 32) + addr = (uc->uc_mcontext.v_regs == 0) ? NULL : &uc->uc_mcontext.v_regs->vrregs[reg - UNW_PPC64_V0][0]; + + else + { + unsigned gregs_idx; + + switch (reg) + { + case UNW_PPC64_NIP: + gregs_idx = NIP_IDX; + break; + case UNW_PPC64_CTR: + gregs_idx = CTR_IDX; + break; + case UNW_PPC64_LR: + gregs_idx = LINK_IDX; + break; + case UNW_PPC64_XER: + gregs_idx = XER_IDX; + break; + case UNW_PPC64_CR0: + gregs_idx = CCR_IDX; + break; + default: + return NULL; + } + addr = &uc->uc_mcontext.gp_regs[gregs_idx]; + } + return addr; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (12, "mem[%lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "mem[%lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if (UNW_PPC64_F0 <= reg && reg <= UNW_PPC64_F31) + goto badreg; + if (UNW_PPC64_V0 <= reg && reg <= UNW_PPC64_V31) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %lx\n", unw_regname (reg), *val); + } + return 0; + +badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + /* Allow only 32 fregs and 32 vregs */ + if (!(((unsigned) (reg - UNW_PPC64_F0) < 32) + ||((unsigned) (reg - UNW_PPC64_V0) < 32))) + goto badreg; + + addr = uc_addr (uc, reg); + if (!addr) + goto badreg; + + if (write) + { + Debug (12, "%s <- %016Lf\n", unw_regname (reg), *val); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %016Lf\n", unw_regname (reg), *val); + } + return 0; + +badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +ppc64_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); +#if _CALL_ELF == 2 + local_addr_space.abi = UNW_PPC64_ABI_ELFv2; +#else + local_addr_space.abi = UNW_PPC64_ABI_ELFv1; +#endif + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = ppc64_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gregs.c new file mode 100644 index 00000000000000..1cb5d9dc6537d6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gregs.c @@ -0,0 +1,141 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + struct dwarf_loc loc; + + switch (reg) + { + case UNW_PPC64_R0: + case UNW_PPC64_R2: + case UNW_PPC64_R3: + case UNW_PPC64_R4: + case UNW_PPC64_R5: + case UNW_PPC64_R6: + case UNW_PPC64_R7: + case UNW_PPC64_R8: + case UNW_PPC64_R9: + case UNW_PPC64_R10: + case UNW_PPC64_R11: + case UNW_PPC64_R12: + case UNW_PPC64_R13: + case UNW_PPC64_R14: + case UNW_PPC64_R15: + case UNW_PPC64_R16: + case UNW_PPC64_R17: + case UNW_PPC64_R18: + case UNW_PPC64_R19: + case UNW_PPC64_R20: + case UNW_PPC64_R21: + case UNW_PPC64_R22: + case UNW_PPC64_R23: + case UNW_PPC64_R24: + case UNW_PPC64_R25: + case UNW_PPC64_R26: + case UNW_PPC64_R27: + case UNW_PPC64_R28: + case UNW_PPC64_R29: + case UNW_PPC64_R30: + case UNW_PPC64_R31: + case UNW_PPC64_LR: + case UNW_PPC64_CTR: + case UNW_PPC64_CR0: + case UNW_PPC64_CR1: + case UNW_PPC64_CR2: + case UNW_PPC64_CR3: + case UNW_PPC64_CR4: + case UNW_PPC64_CR5: + case UNW_PPC64_CR6: + case UNW_PPC64_CR7: + case UNW_PPC64_VRSAVE: + case UNW_PPC64_VSCR: + case UNW_PPC64_SPE_ACC: + case UNW_PPC64_SPEFSCR: + loc = c->dwarf.loc[reg]; + break; + + case UNW_TDEP_IP: + if (write) + { + c->dwarf.ip = *valp; /* update the IP cache */ + if (c->dwarf.pi_valid && (*valp < c->dwarf.pi.start_ip + || *valp >= c->dwarf.pi.end_ip)) + c->dwarf.pi_valid = 0; /* new IP outside of current proc */ + } + else + *valp = c->dwarf.ip; + return 0; + + case UNW_TDEP_SP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + default: + return -UNW_EBADREG; + break; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + struct dwarf_loc loc; + + if ((unsigned) (reg - UNW_PPC64_F0) < 32) + { + loc = c->dwarf.loc[reg]; + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); + } + else + if ((unsigned) (reg - UNW_PPC64_V0) < 32) + { + loc = c->dwarf.loc[reg]; + if (write) + return dwarf_putvr (&c->dwarf, loc, *valp); + else + return dwarf_getvr (&c->dwarf, loc, valp); + } + + return -UNW_EBADREG; +} + diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gresume.c new file mode 100644 index 00000000000000..0d832d0d97bd34 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gresume.c @@ -0,0 +1,111 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford cjashfor@us.ibm.com + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +#include + +/* sigreturn() is a no-op on x86_64 glibc. */ + +static NORETURN inline long +my_rt_sigreturn (void *new_sp) +{ + /* XXX: empty stub. */ + abort (); +} + +HIDDEN inline int +ppc64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = (ucontext_t *)c->dwarf.as_arg; + + if (unlikely (c->sigcontext_format != PPC_SCF_NONE)) + { + my_rt_sigreturn(cursor); + abort(); + } + else + { + Debug (8, "resuming at ip=%llx via setcontext()\n", + (unsigned long long) c->dwarf.ip); + setcontext (uc); + } + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + as->acc.access_fpreg (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + } + return 0; +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gstep.c new file mode 100644 index 00000000000000..f44e9591054718 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Gstep.c @@ -0,0 +1,466 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" +#include "remote.h" +#include + +/* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is + defined there only when __KERNEL__ is defined. We reproduce it here for + our use at the user level in order to locate the ucontext record, which + appears to be at this offset relative to the stack pointer when in the + context of the signal handler return trampoline code - + __kernel_sigtramp_rt64. */ +#define __SIGNAL_FRAMESIZE 128 + +/* This definition comes from the document "64-bit PowerPC ELF Application + Binary Interface Supplement 1.9", section 3.2.2. + http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */ + +typedef struct +{ + long unsigned back_chain; + long unsigned cr_save; + long unsigned lr_save; + /* many more fields here, but they are unused by this code */ +} stack_frame_t; + + +int +unw_step (unw_cursor_t * cursor) +{ + struct cursor *c = (struct cursor *) cursor; + stack_frame_t dummy; + unw_word_t back_chain_offset, lr_save_offset, v_regs_ptr; + struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc, v_regs_loc; + int ret, i; + + Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip); + + /* Try DWARF-based unwinding... */ + + ret = dwarf_step (&c->dwarf); + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (unlikely (ret < 0)) + { + if (likely (unw_is_signal_frame (cursor) <= 0)) + { + /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode + produces the mandatory level of traceback record in the code, but + I get the impression that this is transitory, that eventually gcc + will not produce any traceback records at all. So, for now, we + won't bother to try to find and use these records. + + We can, however, attempt to unwind the frame by using the callback + chain. This is very crude, however, and won't be able to unwind + any registers besides the IP, SP, and LR . */ + + back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy); + lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy); + + back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0); + + if ((ret = + dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0) + { + Debug (2, + "Unable to retrieve CFA from back chain in stack frame - %d\n", + ret); + return ret; + } + if (c->dwarf.cfa == 0) + /* Unless the cursor or stack is corrupt or uninitialized we've most + likely hit the top of the stack */ + return 0; + + lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0); + + if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0) + { + Debug (2, + "Unable to retrieve IP from lr save in stack frame - %d\n", + ret); + return ret; + } + + /* Mark all registers unsaved */ + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + ret = 1; + } + else + { + /* Find the sigcontext record by taking the CFA and adjusting by + the dummy signal frame size. + + Note that there isn't any way to determined if SA_SIGINFO was + set in the sa_flags parameter to sigaction when the signal + handler was established. If it was not set, the ucontext + record is not required to be on the stack, in which case the + following code will likely cause a seg fault or other crash + condition. */ + + unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE; + + Debug (1, "signal frame, skip over trampoline\n"); + + c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME; + c->sigcontext_addr = ucontext; + + sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); + ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0); + + ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + /* Instead of just restoring the non-volatile registers, do all + of the registers for now. This will incur a performance hit, + but it's rare enough not to cause too much of a problem, and + might be useful in some cases. */ + c->dwarf.loc[UNW_PPC64_R0] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0); + c->dwarf.loc[UNW_PPC64_R1] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0); + c->dwarf.loc[UNW_PPC64_R2] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0); + c->dwarf.loc[UNW_PPC64_R3] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0); + c->dwarf.loc[UNW_PPC64_R4] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0); + c->dwarf.loc[UNW_PPC64_R5] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0); + c->dwarf.loc[UNW_PPC64_R6] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0); + c->dwarf.loc[UNW_PPC64_R7] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0); + c->dwarf.loc[UNW_PPC64_R8] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); + c->dwarf.loc[UNW_PPC64_R9] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); + c->dwarf.loc[UNW_PPC64_R10] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); + c->dwarf.loc[UNW_PPC64_R11] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); + c->dwarf.loc[UNW_PPC64_R12] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); + c->dwarf.loc[UNW_PPC64_R13] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); + c->dwarf.loc[UNW_PPC64_R14] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); + c->dwarf.loc[UNW_PPC64_R15] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); + c->dwarf.loc[UNW_PPC64_R16] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0); + c->dwarf.loc[UNW_PPC64_R17] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0); + c->dwarf.loc[UNW_PPC64_R18] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0); + c->dwarf.loc[UNW_PPC64_R19] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0); + c->dwarf.loc[UNW_PPC64_R20] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0); + c->dwarf.loc[UNW_PPC64_R21] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0); + c->dwarf.loc[UNW_PPC64_R22] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0); + c->dwarf.loc[UNW_PPC64_R23] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0); + c->dwarf.loc[UNW_PPC64_R24] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0); + c->dwarf.loc[UNW_PPC64_R25] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0); + c->dwarf.loc[UNW_PPC64_R26] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0); + c->dwarf.loc[UNW_PPC64_R27] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0); + c->dwarf.loc[UNW_PPC64_R28] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0); + c->dwarf.loc[UNW_PPC64_R29] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0); + c->dwarf.loc[UNW_PPC64_R30] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0); + c->dwarf.loc[UNW_PPC64_R31] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0); + + c->dwarf.loc[UNW_PPC64_LR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0); + c->dwarf.loc[UNW_PPC64_CTR] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0); + /* This CR0 assignment is probably wrong. There are 8 dwarf columns + assigned to the CR registers, but only one CR register in the + mcontext structure */ + c->dwarf.loc[UNW_PPC64_CR0] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0); + c->dwarf.loc[UNW_PPC64_XER] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0); + c->dwarf.loc[UNW_PPC64_NIP] = + DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0); + + /* TODO: Is there a way of obtaining the value of the + pseudo frame pointer (which is sp + some fixed offset, I + assume), based on the contents of the ucontext record + structure? For now, set this loc to null. */ + c->dwarf.loc[UNW_PPC64_FRAME_POINTER] = DWARF_NULL_LOC; + + c->dwarf.loc[UNW_PPC64_F0] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0); + c->dwarf.loc[UNW_PPC64_F1] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0); + c->dwarf.loc[UNW_PPC64_F2] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0); + c->dwarf.loc[UNW_PPC64_F3] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0); + c->dwarf.loc[UNW_PPC64_F4] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0); + c->dwarf.loc[UNW_PPC64_F5] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0); + c->dwarf.loc[UNW_PPC64_F6] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0); + c->dwarf.loc[UNW_PPC64_F7] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0); + c->dwarf.loc[UNW_PPC64_F8] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0); + c->dwarf.loc[UNW_PPC64_F9] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0); + c->dwarf.loc[UNW_PPC64_F10] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0); + c->dwarf.loc[UNW_PPC64_F11] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0); + c->dwarf.loc[UNW_PPC64_F12] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0); + c->dwarf.loc[UNW_PPC64_F13] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0); + c->dwarf.loc[UNW_PPC64_F14] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0); + c->dwarf.loc[UNW_PPC64_F15] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0); + c->dwarf.loc[UNW_PPC64_F16] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0); + c->dwarf.loc[UNW_PPC64_F17] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0); + c->dwarf.loc[UNW_PPC64_F18] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0); + c->dwarf.loc[UNW_PPC64_F19] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0); + c->dwarf.loc[UNW_PPC64_F20] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0); + c->dwarf.loc[UNW_PPC64_F21] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0); + c->dwarf.loc[UNW_PPC64_F22] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0); + c->dwarf.loc[UNW_PPC64_F23] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0); + c->dwarf.loc[UNW_PPC64_F24] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0); + c->dwarf.loc[UNW_PPC64_F25] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0); + c->dwarf.loc[UNW_PPC64_F26] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0); + c->dwarf.loc[UNW_PPC64_F27] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0); + c->dwarf.loc[UNW_PPC64_F28] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0); + c->dwarf.loc[UNW_PPC64_F29] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0); + c->dwarf.loc[UNW_PPC64_F30] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0); + c->dwarf.loc[UNW_PPC64_F31] = + DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0); + /* Note that there is no .eh_section register column for the + FPSCR register. I don't know why this is. */ + + v_regs_loc = DWARF_LOC (ucontext + UC_MCONTEXT_V_REGS, 0); + ret = dwarf_get (&c->dwarf, v_regs_loc, &v_regs_ptr); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + if (v_regs_ptr != 0) + { + /* The v_regs_ptr is not null. Set all of the AltiVec locs */ + + c->dwarf.loc[UNW_PPC64_V0] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R0, 0); + c->dwarf.loc[UNW_PPC64_V1] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R1, 0); + c->dwarf.loc[UNW_PPC64_V2] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R2, 0); + c->dwarf.loc[UNW_PPC64_V3] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R3, 0); + c->dwarf.loc[UNW_PPC64_V4] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R4, 0); + c->dwarf.loc[UNW_PPC64_V5] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R5, 0); + c->dwarf.loc[UNW_PPC64_V6] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R6, 0); + c->dwarf.loc[UNW_PPC64_V7] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R7, 0); + c->dwarf.loc[UNW_PPC64_V8] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R8, 0); + c->dwarf.loc[UNW_PPC64_V9] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R9, 0); + c->dwarf.loc[UNW_PPC64_V10] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R10, 0); + c->dwarf.loc[UNW_PPC64_V11] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R11, 0); + c->dwarf.loc[UNW_PPC64_V12] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R12, 0); + c->dwarf.loc[UNW_PPC64_V13] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R13, 0); + c->dwarf.loc[UNW_PPC64_V14] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R14, 0); + c->dwarf.loc[UNW_PPC64_V15] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R15, 0); + c->dwarf.loc[UNW_PPC64_V16] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R16, 0); + c->dwarf.loc[UNW_PPC64_V17] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R17, 0); + c->dwarf.loc[UNW_PPC64_V18] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R18, 0); + c->dwarf.loc[UNW_PPC64_V19] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R19, 0); + c->dwarf.loc[UNW_PPC64_V20] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R20, 0); + c->dwarf.loc[UNW_PPC64_V21] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R21, 0); + c->dwarf.loc[UNW_PPC64_V22] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R22, 0); + c->dwarf.loc[UNW_PPC64_V23] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R23, 0); + c->dwarf.loc[UNW_PPC64_V24] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R24, 0); + c->dwarf.loc[UNW_PPC64_V25] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R25, 0); + c->dwarf.loc[UNW_PPC64_V26] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R26, 0); + c->dwarf.loc[UNW_PPC64_V27] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R27, 0); + c->dwarf.loc[UNW_PPC64_V28] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R28, 0); + c->dwarf.loc[UNW_PPC64_V29] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R29, 0); + c->dwarf.loc[UNW_PPC64_V30] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R30, 0); + c->dwarf.loc[UNW_PPC64_V31] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R31, 0); + c->dwarf.loc[UNW_PPC64_VRSAVE] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VRSAVE, 0); + c->dwarf.loc[UNW_PPC64_VSCR] = + DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VSCR, 0); + } + else + { + c->dwarf.loc[UNW_PPC64_V0] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V1] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V2] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V3] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V4] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V5] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V6] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V7] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V8] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V9] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V10] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V11] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V12] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V13] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V14] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V15] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V16] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V17] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V18] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V19] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V20] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V21] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V22] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V23] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V24] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V25] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V26] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V27] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V28] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V29] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V30] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_V31] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_NULL_LOC; + c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_NULL_LOC; + } + ret = 1; + } + } + + if (c->dwarf.ip == 0) + { + /* Unless the cursor or stack is corrupt or uninitialized, + we've most likely hit the top of the stack */ + Debug (2, "returning 0\n"); + return 0; + } + + // on ppc64, R2 register is used as pointer to TOC + // section which is used for symbol lookup in PIC code + // ppc64 linker generates "ld r2, 40(r1)" (ELFv1) or + // "ld r2, 24(r1)" (ELFv2) instruction after each + // @plt call. We need restore R2, but only for @plt calls + { + unw_word_t ip = c->dwarf.ip; + unw_addr_space_t as = c->dwarf.as; + unw_accessors_t *a = unw_get_accessors_int (as); + void *arg = c->dwarf.as_arg; + uint32_t toc_save = (as->abi == UNW_PPC64_ABI_ELFv2)? 24 : 40; + int32_t inst; + + if (fetch32 (as, a, &ip, &inst, arg) >= 0 + && (uint32_t)inst == (0xE8410000U + toc_save)) + { + // @plt call, restoring R2 from CFA+toc_save + c->dwarf.loc[UNW_PPC64_R2] = DWARF_LOC(c->dwarf.cfa + toc_save, 0); + } + } + + Debug (2, "returning %d with last return statement\n", ret); + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lglobal.c new file mode 100644 index 00000000000000..6d7b489e14bd9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Linit.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/get_func_addr.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/get_func_addr.c new file mode 100644 index 00000000000000..80a58fa1f80935 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/get_func_addr.c @@ -0,0 +1,51 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +tdep_get_func_addr (unw_addr_space_t as, unw_word_t addr, + unw_word_t *entry_point) +{ + if (as->abi == UNW_PPC64_ABI_ELFv1) + { + unw_accessors_t *a; + int ret; + + a = unw_get_accessors_int (as); + /* Entry-point is stored in the 1st word of the function descriptor. + In case that changes in the future, we'd have to update the line + below and read the word at addr + offset: */ + ret = (*a->access_mem) (as, addr, entry_point, 0, NULL); + if (ret < 0) + return ret; + } + else + *entry_point = addr; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/init.h b/src/coreclr/src/pal/src/libunwind/src/ppc64/init.h new file mode 100644 index 00000000000000..9b8139343d688a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/init.h @@ -0,0 +1,82 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init_ppc64 (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + int i; + + for (i = UNW_PPC64_R0; i <= UNW_PPC64_R31; i++) { + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); + } + for (i = UNW_PPC64_F0; i <= UNW_PPC64_F31; i++) { + c->dwarf.loc[i] = DWARF_FPREG_LOC (&c->dwarf, i); + } + for (i = UNW_PPC64_V0; i <= UNW_PPC64_V31; i++) { + c->dwarf.loc[i] = DWARF_VREG_LOC (&c->dwarf, i); + } + + for (i = UNW_PPC64_CR0; i <= UNW_PPC64_CR7; i++) { + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, i); + } + c->dwarf.loc[UNW_PPC64_ARG_POINTER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_ARG_POINTER); + c->dwarf.loc[UNW_PPC64_CTR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_CTR); + c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_VSCR); + + c->dwarf.loc[UNW_PPC64_XER] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_XER); + c->dwarf.loc[UNW_PPC64_LR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_LR); + c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_VRSAVE); + c->dwarf.loc[UNW_PPC64_SPEFSCR] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_SPEFSCR); + c->dwarf.loc[UNW_PPC64_SPE_ACC] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_SPE_ACC); + + c->dwarf.loc[UNW_PPC64_NIP] = DWARF_REG_LOC (&c->dwarf, UNW_PPC64_NIP); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_PPC64_NIP], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_PPC64_R1), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = PPC_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/is_fpreg.c new file mode 100644 index 00000000000000..653964a7dad25a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/is_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_is_fpreg (int regnum) +{ + return (regnum >= UNW_PPC64_F0 && regnum <= UNW_PPC64_F31); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/regname.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/regname.c new file mode 100644 index 00000000000000..58c6fa6d87468e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/regname.c @@ -0,0 +1,164 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + [UNW_PPC64_R0]="GPR0", + [UNW_PPC64_R1]="GPR1", + [UNW_PPC64_R2]="GPR2", + [UNW_PPC64_R3]="GPR3", + [UNW_PPC64_R4]="GPR4", + [UNW_PPC64_R5]="GPR5", + [UNW_PPC64_R6]="GPR6", + [UNW_PPC64_R7]="GPR7", + [UNW_PPC64_R8]="GPR8", + [UNW_PPC64_R9]="GPR9", + [UNW_PPC64_R10]="GPR10", + [UNW_PPC64_R11]="GPR11", + [UNW_PPC64_R12]="GPR12", + [UNW_PPC64_R13]="GPR13", + [UNW_PPC64_R14]="GPR14", + [UNW_PPC64_R15]="GPR15", + [UNW_PPC64_R16]="GPR16", + [UNW_PPC64_R17]="GPR17", + [UNW_PPC64_R18]="GPR18", + [UNW_PPC64_R19]="GPR19", + [UNW_PPC64_R20]="GPR20", + [UNW_PPC64_R21]="GPR21", + [UNW_PPC64_R22]="GPR22", + [UNW_PPC64_R23]="GPR23", + [UNW_PPC64_R24]="GPR24", + [UNW_PPC64_R25]="GPR25", + [UNW_PPC64_R26]="GPR26", + [UNW_PPC64_R27]="GPR27", + [UNW_PPC64_R28]="GPR28", + [UNW_PPC64_R29]="GPR29", + [UNW_PPC64_R30]="GPR30", + [UNW_PPC64_R31]="GPR31", + + [UNW_PPC64_F0]="FPR0", + [UNW_PPC64_F1]="FPR1", + [UNW_PPC64_F2]="FPR2", + [UNW_PPC64_F3]="FPR3", + [UNW_PPC64_F4]="FPR4", + [UNW_PPC64_F5]="FPR5", + [UNW_PPC64_F6]="FPR6", + [UNW_PPC64_F7]="FPR7", + [UNW_PPC64_F8]="FPR8", + [UNW_PPC64_F9]="FPR9", + [UNW_PPC64_F10]="FPR10", + [UNW_PPC64_F11]="FPR11", + [UNW_PPC64_F12]="FPR12", + [UNW_PPC64_F13]="FPR13", + [UNW_PPC64_F14]="FPR14", + [UNW_PPC64_F15]="FPR15", + [UNW_PPC64_F16]="FPR16", + [UNW_PPC64_F17]="FPR17", + [UNW_PPC64_F18]="FPR18", + [UNW_PPC64_F19]="FPR19", + [UNW_PPC64_F20]="FPR20", + [UNW_PPC64_F21]="FPR21", + [UNW_PPC64_F22]="FPR22", + [UNW_PPC64_F23]="FPR23", + [UNW_PPC64_F24]="FPR24", + [UNW_PPC64_F25]="FPR25", + [UNW_PPC64_F26]="FPR26", + [UNW_PPC64_F27]="FPR27", + [UNW_PPC64_F28]="FPR28", + [UNW_PPC64_F29]="FPR29", + [UNW_PPC64_F30]="FPR30", + [UNW_PPC64_F31]="FPR31", + + [UNW_PPC64_LR]="LR", + [UNW_PPC64_CTR]="CTR", + [UNW_PPC64_ARG_POINTER]="ARG_POINTER", + + [UNW_PPC64_CR0]="CR0", + [UNW_PPC64_CR1]="CR1", + [UNW_PPC64_CR2]="CR2", + [UNW_PPC64_CR3]="CR3", + [UNW_PPC64_CR4]="CR4", + [UNW_PPC64_CR5]="CR5", + [UNW_PPC64_CR6]="CR6", + [UNW_PPC64_CR7]="CR7", + + [UNW_PPC64_XER]="XER", + + [UNW_PPC64_V0]="VR0", + [UNW_PPC64_V1]="VR1", + [UNW_PPC64_V2]="VR2", + [UNW_PPC64_V3]="VR3", + [UNW_PPC64_V4]="VR4", + [UNW_PPC64_V5]="VR5", + [UNW_PPC64_V6]="VR6", + [UNW_PPC64_V7]="VR7", + [UNW_PPC64_V8]="VR8", + [UNW_PPC64_V9]="VR9", + [UNW_PPC64_V10]="VR10", + [UNW_PPC64_V11]="VR11", + [UNW_PPC64_V12]="VR12", + [UNW_PPC64_V13]="VR13", + [UNW_PPC64_V14]="VR14", + [UNW_PPC64_V15]="VR15", + [UNW_PPC64_V16]="VR16", + [UNW_PPC64_V17]="VR17", + [UNW_PPC64_V18]="VR18", + [UNW_PPC64_V19]="VR19", + [UNW_PPC64_V20]="VR20", + [UNW_PPC64_V21]="VR21", + [UNW_PPC64_V22]="VR22", + [UNW_PPC64_V23]="VR23", + [UNW_PPC64_V24]="VR24", + [UNW_PPC64_V25]="VR25", + [UNW_PPC64_V26]="VR26", + [UNW_PPC64_V27]="VR27", + [UNW_PPC64_V28]="VR28", + [UNW_PPC64_V29]="VR29", + [UNW_PPC64_V30]="VR30", + [UNW_PPC64_V31]="VR31", + + [UNW_PPC64_VSCR]="VSCR", + + [UNW_PPC64_VRSAVE]="VRSAVE", + [UNW_PPC64_SPE_ACC]="SPE_ACC", + [UNW_PPC64_SPEFSCR]="SPEFSCR", + + [UNW_PPC64_FRAME_POINTER]="FRAME_POINTER", + [UNW_PPC64_NIP]="NIP", + + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/ppc64/setcontext.S new file mode 100644 index 00000000000000..ffc2500a517387 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/setcontext.S @@ -0,0 +1,9 @@ + .global _UI_setcontext + +_UI_setcontext: + blr + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/ppc64/ucontext_i.h new file mode 100644 index 00000000000000..2ddfdb865a71b0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/ucontext_i.h @@ -0,0 +1,173 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +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 ucontext_i_h +#define ucontext_i_h + +#include + +/* These values were derived by reading + /usr/src/linux-2.6.18-1.8/arch/um/include/sysdep-ppc/ptrace.h and + /usr/src/linux-2.6.18-1.8/arch/powerpc/kernel/ppc32.h +*/ + +#define NIP_IDX 32 +#define MSR_IDX 33 +#define ORIG_GPR3_IDX 34 +#define CTR_IDX 35 +#define LINK_IDX 36 +#define XER_IDX 37 +#define CCR_IDX 38 +#define SOFTE_IDX 39 +#define TRAP_IDX 40 +#define DAR_IDX 41 +#define DSISR_IDX 42 +#define RESULT_IDX 43 + +#define VSCR_IDX 32 +#define VRSAVE_IDX 33 + +/* These are dummy structures used only for obtaining the offsets of the + various structure members. */ +static ucontext_t dmy_ctxt; +static vrregset_t dmy_vrregset; + +#define UC_MCONTEXT_GREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[0] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[1] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[2] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[3] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[4] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[5] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[6] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[7] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[8] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[9] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[10] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[11] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[12] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[13] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[14] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[15] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[16] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[17] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[18] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[19] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[20] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[21] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[22] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[23] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[24] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[25] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[26] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[27] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[28] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[29] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[30] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[31] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_NIP ((void *)&dmy_ctxt.uc_mcontext.gp_regs[NIP_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_MSR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[MSR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_ORIG_GPR3 ((void *)&dmy_ctxt.uc_mcontext.gp_regs[ORIG_GPR3_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_CTR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[CTR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_LINK ((void *)&dmy_ctxt.uc_mcontext.gp_regs[LINK_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_XER ((void *)&dmy_ctxt.uc_mcontext.gp_regs[XER_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_CCR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[CCR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_SOFTE ((void *)&dmy_ctxt.uc_mcontext.gp_regs[SOFTE_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_TRAP ((void *)&dmy_ctxt.uc_mcontext.gp_regs[TRAP_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_DAR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[DAR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_DSISR ((void *)&dmy_ctxt.uc_mcontext.gp_regs[DSISR_IDX] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_GREGS_RESULT ((void *)&dmy_ctxt.uc_mcontext.gp_regs[RESULT_IDX] - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_FREGS_R0 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[0] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R1 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[1] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R2 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[2] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R3 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[3] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R4 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[4] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R5 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[5] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R6 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[6] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R7 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[7] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R8 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[8] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R9 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[9] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R10 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[10] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R11 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[11] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R12 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[12] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R13 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[13] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R14 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[14] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R15 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[15] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R16 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[16] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R17 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[17] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R18 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[18] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R19 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[19] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R20 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[20] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R21 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[21] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R22 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[22] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R23 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[23] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R24 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[24] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R25 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[25] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R26 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[26] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R27 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[27] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R28 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[28] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R29 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[29] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R30 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[30] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_R31 ((void *)&dmy_ctxt.uc_mcontext.fp_regs[31] - (void *)&dmy_ctxt) +#define UC_MCONTEXT_FREGS_FPSCR ((void *)&dmy_ctxt.uc_mcontext.fp_regs[32] - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_V_REGS ((void *)&dmy_ctxt.uc_mcontext.v_regs - (void *)&dmy_ctxt) + +#define UC_MCONTEXT_VREGS_R0 ((void *)&dmy_vrregset.vrregs[0] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R1 ((void *)&dmy_vrregset.vrregs[1] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R2 ((void *)&dmy_vrregset.vrregs[2] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R3 ((void *)&dmy_vrregset.vrregs[3] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R4 ((void *)&dmy_vrregset.vrregs[4] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R5 ((void *)&dmy_vrregset.vrregs[5] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R6 ((void *)&dmy_vrregset.vrregs[6] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R7 ((void *)&dmy_vrregset.vrregs[7] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R8 ((void *)&dmy_vrregset.vrregs[8] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R9 ((void *)&dmy_vrregset.vrregs[9] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R10 ((void *)&dmy_vrregset.vrregs[10] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R11 ((void *)&dmy_vrregset.vrregs[11] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R12 ((void *)&dmy_vrregset.vrregs[12] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R13 ((void *)&dmy_vrregset.vrregs[13] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R14 ((void *)&dmy_vrregset.vrregs[14] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R15 ((void *)&dmy_vrregset.vrregs[15] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R16 ((void *)&dmy_vrregset.vrregs[16] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R17 ((void *)&dmy_vrregset.vrregs[17] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R18 ((void *)&dmy_vrregset.vrregs[18] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R19 ((void *)&dmy_vrregset.vrregs[19] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R20 ((void *)&dmy_vrregset.vrregs[20] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R21 ((void *)&dmy_vrregset.vrregs[21] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R22 ((void *)&dmy_vrregset.vrregs[22] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R23 ((void *)&dmy_vrregset.vrregs[23] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R24 ((void *)&dmy_vrregset.vrregs[24] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R25 ((void *)&dmy_vrregset.vrregs[25] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R26 ((void *)&dmy_vrregset.vrregs[26] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R27 ((void *)&dmy_vrregset.vrregs[27] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R28 ((void *)&dmy_vrregset.vrregs[28] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R29 ((void *)&dmy_vrregset.vrregs[29] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R30 ((void *)&dmy_vrregset.vrregs[30] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_R31 ((void *)&dmy_vrregset.vrregs[31] - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_VSCR ((void *)&dmy_vrregset.vscr - (void *)&dmy_vrregset) +#define UC_MCONTEXT_VREGS_VRSAVE ((void *)&dmy_vrregset.vrsave - (void *)&dmy_vrregset) + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/ppc64/unwind_i.h new file mode 100644 index 00000000000000..26bbc2df83af7f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/unwind_i.h @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2006-2007 IBM + Contributed by + Corey Ashford + Jose Flavio Aguilar Paulino + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include +#include + +#define ppc64_lock UNW_OBJ(lock) +#define ppc64_local_resume UNW_OBJ(local_resume) +#define ppc64_local_addr_space_init UNW_OBJ(local_addr_space_init) +#if 0 +#define ppc64_scratch_loc UNW_OBJ(scratch_loc) +#endif + +extern void ppc64_local_addr_space_init (void); +extern int ppc64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +#if 0 +extern dwarf_loc_t ppc64_scratch_loc (struct cursor *c, unw_regnum_t reg); +#endif + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c new file mode 100644 index 00000000000000..37cd4ffe1c2f77 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c @@ -0,0 +1,128 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +#if HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE +int +_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + unw_word_t *wp = (unw_word_t *) val; + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + int i; + + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + return -UNW_EBADREG; + + errno = 0; + if (write) + for (i = 0; i < (int) (sizeof (*val) / sizeof (wp[i])); ++i) + { +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + ptrace (PTRACE_POKEUSER, pid, _UPT_reg_offset[reg] + i * sizeof(wp[i]), + wp[i]); +#endif + if (errno) + return -UNW_EBADREG; + } + else + for (i = 0; i < (int) (sizeof (*val) / sizeof (wp[i])); ++i) + { +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + wp[i] = ptrace (PTRACE_PEEKUSER, pid, + _UPT_reg_offset[reg] + i * sizeof(wp[i]), 0); +#endif + if (errno) + return -UNW_EBADREG; + } + return 0; +} +#elif HAVE_DECL_PT_GETFPREGS +int +_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + fpregset_t fpreg; + +#if defined(__amd64__) + if (1) /* XXXKIB */ + return -UNW_EBADREG; +#elif defined(__i386__) + if ((unsigned) reg < UNW_X86_ST0 || (unsigned) reg > UNW_X86_ST7) + return -UNW_EBADREG; +#elif defined(__arm__) + if ((unsigned) reg < UNW_ARM_F0 || (unsigned) reg > UNW_ARM_F7) + return -UNW_EBADREG; +#elif defined(__aarch64__) + if ((unsigned) reg < UNW_AARCH64_V0 || (unsigned) reg > UNW_AARCH64_V31) + return -UNW_EBADREG; +#else +#error Fix me +#endif + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + return -UNW_EBADREG; + + if (ptrace(PT_GETFPREGS, pid, (caddr_t)&fpreg, 0) == -1) + return -UNW_EBADREG; + if (write) { +#if defined(__amd64__) + memcpy(&fpreg.fpr_xacc[reg], val, sizeof(unw_fpreg_t)); +#elif defined(__i386__) + memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t)); +#elif defined(__arm__) + memcpy(&fpreg.fpr[reg], val, sizeof(unw_fpreg_t)); +#elif defined(__aarch64__) + memcpy(&fpreg.fp_q[reg], val, sizeof(unw_fpreg_t)); +#else +#error Fix me +#endif + if (ptrace(PT_SETFPREGS, pid, (caddr_t)&fpreg, 0) == -1) + return -UNW_EBADREG; + } else +#if defined(__amd64__) + memcpy(val, &fpreg.fpr_xacc[reg], sizeof(unw_fpreg_t)); +#elif defined(__i386__) + memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t)); +#elif defined(__arm__) + memcpy(val, &fpreg.fpr[reg], sizeof(unw_fpreg_t)); +#elif defined(__aarch64__) + memcpy(val, &fpreg.fp_q[reg], sizeof(unw_fpreg_t)); +#else +#error Fix me +#endif + return 0; +} +#else +#error Fix me +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_mem.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_mem.c new file mode 100644 index 00000000000000..79bde25dffc056 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_mem.c @@ -0,0 +1,123 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +#if HAVE_DECL_PTRACE_POKEDATA || HAVE_TTRACE +int +_UPT_access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + int i, end; + unw_word_t tmp_val; + + if (!ui) + return -UNW_EINVAL; + + pid_t pid = ui->pid; + + // Some 32-bit archs have to define a 64-bit unw_word_t. + // Callers of this function therefore expect a 64-bit + // return value, but ptrace only returns a 32-bit value + // in such cases. + if (sizeof(long) == 4 && sizeof(unw_word_t) == 8) + end = 2; + else + end = 1; + + for (i = 0; i < end; i++) + { + unw_word_t tmp_addr = i == 0 ? addr : addr + 4; + + errno = 0; + if (write) + { +#if __BYTE_ORDER == __LITTLE_ENDIAN + tmp_val = i == 0 ? *val : *val >> 32; +#else + tmp_val = i == 0 && end == 2 ? *val >> 32 : *val; +#endif + + Debug (16, "mem[%lx] <- %lx\n", (long) tmp_addr, (long) tmp_val); +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + ptrace (PTRACE_POKEDATA, pid, tmp_addr, tmp_val); + if (errno) + return -UNW_EINVAL; +#endif + } + else + { +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + tmp_val = (unsigned long) ptrace (PTRACE_PEEKDATA, pid, tmp_addr, 0); + + if (i == 0) + *val = 0; + +#if __BYTE_ORDER == __LITTLE_ENDIAN + *val |= tmp_val << (i * 32); +#else + *val |= i == 0 && end == 2 ? tmp_val << 32 : tmp_val; +#endif + + if (errno) + return -UNW_EINVAL; +#endif + Debug (16, "mem[%lx] -> %lx\n", (long) tmp_addr, (long) tmp_val); + } + } + return 0; +} +#elif HAVE_DECL_PT_IO +int +_UPT_access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + if (!ui) + return -UNW_EINVAL; + pid_t pid = ui->pid; + struct ptrace_io_desc iod; + + iod.piod_offs = (void *)addr; + iod.piod_addr = val; + iod.piod_len = sizeof(*val); + iod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D; + if (write) + Debug (16, "mem[%lx] <- %lx\n", (long) addr, (long) *val); + if (ptrace(PT_IO, pid, (caddr_t)&iod, 0) == -1) + return -UNW_EINVAL; + if (!write) + Debug (16, "mem[%lx] -> %lx\n", (long) addr, (long) *val); + return 0; +} +#else +#error Fix me +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_reg.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_reg.c new file mode 100644 index 00000000000000..ce25c783b043a3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_reg.c @@ -0,0 +1,352 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +#if UNW_TARGET_IA64 +# include +# ifdef HAVE_ASM_PTRACE_OFFSETS_H +# include +# endif +# include "tdep-ia64/rse.h" +#endif + +#if HAVE_DECL_PTRACE_SETREGSET +#include +int +_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + gregset_t regs; + char *r; + struct iovec loc; + +#if UNW_DEBUG + Debug(16, "using getregset: reg: %s [%u], val: %lx, write: %u\n", + unw_regname(reg), (unsigned) reg, (long) val, write); + + if (write) + Debug (16, "%s [%u] <- %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); +#endif + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + { + errno = EINVAL; + goto badreg; + } + + loc.iov_base = ®s; + loc.iov_len = sizeof(regs); + + r = (char *)®s + _UPT_reg_offset[reg]; + if (ptrace (PTRACE_GETREGSET, pid, NT_PRSTATUS, &loc) == -1) + goto badreg; + if (write) { + memcpy(r, val, sizeof(unw_word_t)); + if (ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &loc) == -1) + goto badreg; + } else + memcpy(val, r, sizeof(unw_word_t)); + return 0; + +badreg: + Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); + return -UNW_EBADREG; +} +#elif HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE +int +_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + +#if UNW_DEBUG + Debug(16, "using pokeuser: reg: %s [%u], val: %lx, write: %d\n", unw_regname(reg), (unsigned) reg, (long) val, write); + + if (write) + Debug (16, "%s <- %lx\n", unw_regname (reg), (long) *val); +#endif + +#if UNW_TARGET_IA64 + if ((unsigned) reg - UNW_IA64_NAT < 32) + { + unsigned long nat_bits, mask; + + /* The Linux ptrace represents the statc NaT bits as a single word. */ + mask = ((unw_word_t) 1) << (reg - UNW_IA64_NAT); + errno = 0; +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + nat_bits = ptrace (PTRACE_PEEKUSER, pid, PT_NAT_BITS, 0); + if (errno) + goto badreg; +#endif + + if (write) + { + if (*val) + nat_bits |= mask; + else + nat_bits &= ~mask; +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ptrace (PTRACE_POKEUSER, pid, PT_NAT_BITS, nat_bits); + if (errno) + goto badreg; +#endif + } + goto out; + } + else + switch (reg) + { + case UNW_IA64_GR + 0: + if (write) + goto badreg; + *val = 0; + return 0; + + case UNW_REG_IP: + { + unsigned long ip, psr; + + /* distribute bundle-addr. & slot-number across PT_IIP & PT_IPSR. */ +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + psr = ptrace (PTRACE_PEEKUSER, pid, PT_CR_IPSR, 0); + if (errno) + goto badreg; +#endif + if (write) + { + ip = *val & ~0xfUL; + psr = (psr & ~0x3UL << 41) | (*val & 0x3); +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ptrace (PTRACE_POKEUSER, pid, PT_CR_IIP, ip); + ptrace (PTRACE_POKEUSER, pid, PT_CR_IPSR, psr); + if (errno) + goto badreg; +#endif + } + else + { +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ip = ptrace (PTRACE_PEEKUSER, pid, PT_CR_IIP, 0); + if (errno) + goto badreg; +#endif + *val = ip + ((psr >> 41) & 0x3); + } + goto out; + } + + case UNW_IA64_AR_BSPSTORE: + reg = UNW_IA64_AR_BSP; + break; + + case UNW_IA64_AR_BSP: + case UNW_IA64_BSP: + { + unsigned long sof, cfm, bsp; + +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + /* Account for the fact that ptrace() expects bsp to point + _after_ the current register frame. */ + errno = 0; + cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0); + if (errno) + goto badreg; +#endif + sof = (cfm & 0x7f); + + if (write) + { + bsp = rse_skip_regs (*val, sof); +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ptrace (PTRACE_POKEUSER, pid, PT_AR_BSP, bsp); + if (errno) + goto badreg; +#endif + } + else + { +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0); + if (errno) + goto badreg; +#endif + *val = rse_skip_regs (bsp, -sof); + } + goto out; + } + + case UNW_IA64_CFM: + /* If we change CFM, we need to adjust ptrace's notion of bsp + accordingly, so that the real bsp remains unchanged. */ + if (write) + { + unsigned long new_sof, old_sof, cfm, bsp; + +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0); + cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0); +#endif + if (errno) + goto badreg; + old_sof = (cfm & 0x7f); + new_sof = (*val & 0x7f); + if (old_sof != new_sof) + { + bsp = rse_skip_regs (bsp, -old_sof + new_sof); +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ptrace (PTRACE_POKEUSER, pid, PT_AR_BSP, 0); + if (errno) + goto badreg; +#endif + } +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + ptrace (PTRACE_POKEUSER, pid, PT_CFM, *val); + if (errno) + goto badreg; +#endif + goto out; + } + break; + } +#endif /* End of IA64 */ + + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + { +#if UNW_DEBUG + Debug(2, "register out of range: >= %zu / %zu\n", sizeof(_UPT_reg_offset), sizeof(_UPT_reg_offset[0])); +#endif + errno = EINVAL; + goto badreg; + } + +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#else + errno = 0; + if (write) + ptrace (PTRACE_POKEUSER, pid, _UPT_reg_offset[reg], *val); + else { +#if UNW_DEBUG + Debug(16, "ptrace PEEKUSER pid: %lu , reg: %lu , offs: %lu\n", (unsigned long)pid, (unsigned long)reg, + (unsigned long)_UPT_reg_offset[reg]); +#endif + *val = ptrace (PTRACE_PEEKUSER, pid, _UPT_reg_offset[reg], 0); + } + if (errno) { +#if UNW_DEBUG + Debug(2, "ptrace failure\n"); +#endif + goto badreg; + } +#endif + +#ifdef UNW_TARGET_IA64 + out: +#endif +#if UNW_DEBUG + if (!write) + Debug (16, "%s[%u] -> %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); +#endif + return 0; + + badreg: + Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); + return -UNW_EBADREG; +} +#elif HAVE_DECL_PT_GETREGS +int +_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + gregset_t regs; + char *r; + +#if UNW_DEBUG + Debug(16, "using getregs: reg: %s [%u], val: %lx, write: %u\n", unw_regname(reg), (unsigned) reg, (long) val, write); + + if (write) + Debug (16, "%s [%u] <- %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); +#endif + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + { + errno = EINVAL; + goto badreg; + } + r = (char *)®s + _UPT_reg_offset[reg]; + if (ptrace(PT_GETREGS, pid, (caddr_t)®s, 0) == -1) + goto badreg; + if (write) { + memcpy(r, val, sizeof(unw_word_t)); + if (ptrace(PT_SETREGS, pid, (caddr_t)®s, 0) == -1) + goto badreg; + } else + memcpy(val, r, sizeof(unw_word_t)); + return 0; + + badreg: + Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); + return -UNW_EBADREG; +} +#else +#error Port me +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_accessors.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_accessors.c new file mode 100644 index 00000000000000..4724360bb99b9c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_accessors.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +unw_accessors_t _UPT_accessors = + { + .find_proc_info = _UPT_find_proc_info, + .put_unwind_info = _UPT_put_unwind_info, + .get_dyn_info_list_addr = _UPT_get_dyn_info_list_addr, + .access_mem = _UPT_access_mem, + .access_reg = _UPT_access_reg, + .access_fpreg = _UPT_access_fpreg, + .resume = _UPT_resume, + .get_proc_name = _UPT_get_proc_name + }; diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_create.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_create.c new file mode 100644 index 00000000000000..dd59e974a7eafc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_create.c @@ -0,0 +1,46 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "_UPT_internal.h" + +void * +_UPT_create (pid_t pid) +{ + struct UPT_info *ui = malloc (sizeof (struct UPT_info)); + + if (!ui) + return NULL; + + memset (ui, 0, sizeof (*ui)); + ui->pid = pid; + ui->edi.di_cache.format = -1; + ui->edi.di_debug.format = -1; +#if UNW_TARGET_IA64 + ui->edi.ktab.format = -1; +#endif + return ui; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_destroy.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_destroy.c new file mode 100644 index 00000000000000..edb664ce1235bb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_destroy.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +void +_UPT_destroy (void *ptr) +{ + struct UPT_info *ui = (struct UPT_info *) ptr; + invalidate_edi (&ui->edi); + free (ptr); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_elf.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_elf.c new file mode 100644 index 00000000000000..efc43b578bac0b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_elf.c @@ -0,0 +1,5 @@ +/* We need to get a separate copy of the ELF-code into + libunwind-ptrace since it cannot (and must not) have any ELF + dependencies on libunwind. */ +#include "libunwind_i.h" /* get ELFCLASS defined */ +#include "../elfxx.c" diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_find_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_find_proc_info.c new file mode 100644 index 00000000000000..b3209f451ea9f7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_find_proc_info.c @@ -0,0 +1,145 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include + +#include + +#include "_UPT_internal.h" + +static int +get_unwind_info (struct elf_dyn_info *edi, pid_t pid, unw_addr_space_t as, unw_word_t ip) +{ + unsigned long segbase, mapoff; + char path[PATH_MAX]; + +#if UNW_TARGET_IA64 && defined(__linux) + if (!edi->ktab.start_ip && _Uia64_get_kernel_table (&edi->ktab) < 0) + return -UNW_ENOINFO; + + if (edi->ktab.format != -1 && ip >= edi->ktab.start_ip && ip < edi->ktab.end_ip) + return 0; +#endif + + if ((edi->di_cache.format != -1 + && ip >= edi->di_cache.start_ip && ip < edi->di_cache.end_ip) +#if UNW_TARGET_ARM + || (edi->di_debug.format != -1 + && ip >= edi->di_arm.start_ip && ip < edi->di_arm.end_ip) +#endif + || (edi->di_debug.format != -1 + && ip >= edi->di_debug.start_ip && ip < edi->di_debug.end_ip)) + return 0; + + invalidate_edi(edi); + + if (tdep_get_elf_image (&edi->ei, pid, ip, &segbase, &mapoff, path, + sizeof(path)) < 0) + return -UNW_ENOINFO; + + /* Here, SEGBASE is the starting-address of the (mmap'ped) segment + which covers the IP we're looking for. */ + if (tdep_find_unwind_table (edi, as, path, segbase, mapoff, ip) < 0) + return -UNW_ENOINFO; + + /* This can happen in corner cases where dynamically generated + code falls into the same page that contains the data-segment + and the page-offset of the code is within the first page of + the executable. */ + if (edi->di_cache.format != -1 + && (ip < edi->di_cache.start_ip || ip >= edi->di_cache.end_ip)) + edi->di_cache.format = -1; + + if (edi->di_debug.format != -1 + && (ip < edi->di_debug.start_ip || ip >= edi->di_debug.end_ip)) + edi->di_debug.format = -1; + + if (edi->di_cache.format == -1 +#if UNW_TARGET_ARM + && edi->di_arm.format == -1 +#endif + && edi->di_debug.format == -1) + return -UNW_ENOINFO; + + return 0; +} + +int +_UPT_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + struct UPT_info *ui = arg; + int ret = -UNW_ENOINFO; + + if (get_unwind_info (&ui->edi, ui->pid, as, ip) < 0) + return -UNW_ENOINFO; + +#if UNW_TARGET_IA64 + if (ui->edi.ktab.format != -1) + { + /* The kernel unwind table resides in local memory, so we have + to use the local address space to search it. Since + _UPT_put_unwind_info() has no easy way of detecting this + case, we simply make a copy of the unwind-info, so + _UPT_put_unwind_info() can always free() the unwind-info + without ill effects. */ + ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi, + need_unwind_info, arg); + if (ret >= 0) + { + if (!need_unwind_info) + pi->unwind_info = NULL; + else + { + void *mem = malloc (pi->unwind_info_size); + + if (!mem) + return -UNW_ENOMEM; + memcpy (mem, pi->unwind_info, pi->unwind_info_size); + pi->unwind_info = mem; + } + } + } +#endif + + if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache, + pi, need_unwind_info, arg); + + if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi, + need_unwind_info, arg); + +#if UNW_TARGET_ARM + if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1) + ret = tdep_search_unwind_table (as, ip, &ui->edi.di_arm, pi, + need_unwind_info, arg); +#endif + + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c new file mode 100644 index 00000000000000..16671d453e1f2a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c @@ -0,0 +1,110 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +#if UNW_TARGET_IA64 && defined(__linux) +# include "elf64.h" +# include "os-linux.h" + +static inline int +get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, + int *countp) +{ + unsigned long lo, hi, off; + struct UPT_info *ui = arg; + struct map_iterator mi; + char path[PATH_MAX]; + unw_word_t res; + int count = 0; + + maps_init (&mi, ui->pid); + while (maps_next (&mi, &lo, &hi, &off)) + { + if (off) + continue; + + invalidate_edi(&ui->edi); + + if (elf_map_image (&ui->edi.ei, path) < 0) + /* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */ + continue; + + Debug (16, "checking object %s\n", path); + + if (tdep_find_unwind_table (&ui->edi, as, path, lo, off, 0) > 0) + { + res = _Uia64_find_dyn_list (as, &ui->edi.di_cache, arg); + if (res && count++ == 0) + { + Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res); + *dil_addr = res; + } + } + } + maps_close (&mi); + *countp = count; + return 0; +} + +#else + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + +static inline int +get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, + int *countp) +{ +# warning Implement get_list_addr(), please. + *countp = 0; + return 0; +} + +#endif + +int +_UPT_get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, + void *arg) +{ + int count, ret; + + Debug (12, "looking for dyn_info list\n"); + + if ((ret = get_list_addr (as, dil_addr, arg, &count)) < 0) + return ret; + + /* If multiple dynamic-info list addresses are found, we would have + to determine which was is the one actually in use (since the + dynamic name resolution algorithm will pick one "winner"). + Perhaps we'd have to track them all until we find one that's + non-empty. Hopefully, this case simply will never arise, since + only libunwind defines the dynamic info list head. */ + assert (count <= 1); + + return (count > 0) ? 0 : -UNW_ENOINFO; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_proc_name.c new file mode 100644 index 00000000000000..79c1f38e256ce7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_proc_name.c @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +int +_UPT_get_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, void *arg) +{ + struct UPT_info *ui = arg; + +#if ELF_CLASS == ELFCLASS64 + return _Uelf64_get_proc_name (as, ui->pid, ip, buf, buf_len, offp); +#elif ELF_CLASS == ELFCLASS32 + return _Uelf32_get_proc_name (as, ui->pid, ip, buf, buf_len, offp); +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_internal.h b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_internal.h new file mode 100644 index 00000000000000..5cef2573ee666b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_internal.h @@ -0,0 +1,59 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 _UPT_internal_h +#define _UPT_internal_h + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_PTRACE_H +#include +#endif +#ifdef HAVE_SYS_PROCFS_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "libunwind_i.h" + +struct UPT_info + { + pid_t pid; /* the process-id of the child we're unwinding */ + struct elf_dyn_info edi; + }; + +extern const int _UPT_reg_offset[UNW_REG_LAST + 1]; + +#endif /* _UPT_internal_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_put_unwind_info.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_put_unwind_info.c new file mode 100644 index 00000000000000..d4b84631476b6b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_put_unwind_info.c @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +void +_UPT_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) +{ + if (!pi->unwind_info) + return; + free (pi->unwind_info); + pi->unwind_info = NULL; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c new file mode 100644 index 00000000000000..52be799980db30 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c @@ -0,0 +1,672 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + 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. */ + +#include "_UPT_internal.h" + +#include + +#ifdef HAVE_ASM_PTRACE_OFFSETS_H +# include +#endif + +const int _UPT_reg_offset[UNW_REG_LAST + 1] = + { +#ifdef HAVE_ASM_PTRACE_OFFSETS_H +# ifndef PT_AR_CSD +# define PT_AR_CSD -1 /* this was introduced with rev 2.1 of ia64 */ +# endif + + [UNW_IA64_GR + 0] = -1, [UNW_IA64_GR + 1] = PT_R1, + [UNW_IA64_GR + 2] = PT_R2, [UNW_IA64_GR + 3] = PT_R3, + [UNW_IA64_GR + 4] = PT_R4, [UNW_IA64_GR + 5] = PT_R5, + [UNW_IA64_GR + 6] = PT_R6, [UNW_IA64_GR + 7] = PT_R7, + [UNW_IA64_GR + 8] = PT_R8, [UNW_IA64_GR + 9] = PT_R9, + [UNW_IA64_GR + 10] = PT_R10, [UNW_IA64_GR + 11] = PT_R11, + [UNW_IA64_GR + 12] = PT_R12, [UNW_IA64_GR + 13] = PT_R13, + [UNW_IA64_GR + 14] = PT_R14, [UNW_IA64_GR + 15] = PT_R15, + [UNW_IA64_GR + 16] = PT_R16, [UNW_IA64_GR + 17] = PT_R17, + [UNW_IA64_GR + 18] = PT_R18, [UNW_IA64_GR + 19] = PT_R19, + [UNW_IA64_GR + 20] = PT_R20, [UNW_IA64_GR + 21] = PT_R21, + [UNW_IA64_GR + 22] = PT_R22, [UNW_IA64_GR + 23] = PT_R23, + [UNW_IA64_GR + 24] = PT_R24, [UNW_IA64_GR + 25] = PT_R25, + [UNW_IA64_GR + 26] = PT_R26, [UNW_IA64_GR + 27] = PT_R27, + [UNW_IA64_GR + 28] = PT_R28, [UNW_IA64_GR + 29] = PT_R29, + [UNW_IA64_GR + 30] = PT_R30, [UNW_IA64_GR + 31] = PT_R31, + + [UNW_IA64_NAT+ 0] = -1, [UNW_IA64_NAT+ 1] = PT_NAT_BITS, + [UNW_IA64_NAT+ 2] = PT_NAT_BITS, [UNW_IA64_NAT+ 3] = PT_NAT_BITS, + [UNW_IA64_NAT+ 4] = PT_NAT_BITS, [UNW_IA64_NAT+ 5] = PT_NAT_BITS, + [UNW_IA64_NAT+ 6] = PT_NAT_BITS, [UNW_IA64_NAT+ 7] = PT_NAT_BITS, + [UNW_IA64_NAT+ 8] = PT_NAT_BITS, [UNW_IA64_NAT+ 9] = PT_NAT_BITS, + [UNW_IA64_NAT+ 10] = PT_NAT_BITS, [UNW_IA64_NAT+ 11] = PT_NAT_BITS, + [UNW_IA64_NAT+ 12] = PT_NAT_BITS, [UNW_IA64_NAT+ 13] = PT_NAT_BITS, + [UNW_IA64_NAT+ 14] = PT_NAT_BITS, [UNW_IA64_NAT+ 15] = PT_NAT_BITS, + [UNW_IA64_NAT+ 16] = PT_NAT_BITS, [UNW_IA64_NAT+ 17] = PT_NAT_BITS, + [UNW_IA64_NAT+ 18] = PT_NAT_BITS, [UNW_IA64_NAT+ 19] = PT_NAT_BITS, + [UNW_IA64_NAT+ 20] = PT_NAT_BITS, [UNW_IA64_NAT+ 21] = PT_NAT_BITS, + [UNW_IA64_NAT+ 22] = PT_NAT_BITS, [UNW_IA64_NAT+ 23] = PT_NAT_BITS, + [UNW_IA64_NAT+ 24] = PT_NAT_BITS, [UNW_IA64_NAT+ 25] = PT_NAT_BITS, + [UNW_IA64_NAT+ 26] = PT_NAT_BITS, [UNW_IA64_NAT+ 27] = PT_NAT_BITS, + [UNW_IA64_NAT+ 28] = PT_NAT_BITS, [UNW_IA64_NAT+ 29] = PT_NAT_BITS, + [UNW_IA64_NAT+ 30] = PT_NAT_BITS, [UNW_IA64_NAT+ 31] = PT_NAT_BITS, + + [UNW_IA64_FR + 0] = -1, [UNW_IA64_FR + 1] = -1, + [UNW_IA64_FR + 2] = PT_F2, [UNW_IA64_FR + 3] = PT_F3, + [UNW_IA64_FR + 4] = PT_F4, [UNW_IA64_FR + 5] = PT_F5, + [UNW_IA64_FR + 6] = PT_F6, [UNW_IA64_FR + 7] = PT_F7, + [UNW_IA64_FR + 8] = PT_F8, [UNW_IA64_FR + 9] = PT_F9, + [UNW_IA64_FR + 10] = PT_F10, [UNW_IA64_FR + 11] = PT_F11, + [UNW_IA64_FR + 12] = PT_F12, [UNW_IA64_FR + 13] = PT_F13, + [UNW_IA64_FR + 14] = PT_F14, [UNW_IA64_FR + 15] = PT_F15, + [UNW_IA64_FR + 16] = PT_F16, [UNW_IA64_FR + 17] = PT_F17, + [UNW_IA64_FR + 18] = PT_F18, [UNW_IA64_FR + 19] = PT_F19, + [UNW_IA64_FR + 20] = PT_F20, [UNW_IA64_FR + 21] = PT_F21, + [UNW_IA64_FR + 22] = PT_F22, [UNW_IA64_FR + 23] = PT_F23, + [UNW_IA64_FR + 24] = PT_F24, [UNW_IA64_FR + 25] = PT_F25, + [UNW_IA64_FR + 26] = PT_F26, [UNW_IA64_FR + 27] = PT_F27, + [UNW_IA64_FR + 28] = PT_F28, [UNW_IA64_FR + 29] = PT_F29, + [UNW_IA64_FR + 30] = PT_F30, [UNW_IA64_FR + 31] = PT_F31, + [UNW_IA64_FR + 32] = PT_F32, [UNW_IA64_FR + 33] = PT_F33, + [UNW_IA64_FR + 34] = PT_F34, [UNW_IA64_FR + 35] = PT_F35, + [UNW_IA64_FR + 36] = PT_F36, [UNW_IA64_FR + 37] = PT_F37, + [UNW_IA64_FR + 38] = PT_F38, [UNW_IA64_FR + 39] = PT_F39, + [UNW_IA64_FR + 40] = PT_F40, [UNW_IA64_FR + 41] = PT_F41, + [UNW_IA64_FR + 42] = PT_F42, [UNW_IA64_FR + 43] = PT_F43, + [UNW_IA64_FR + 44] = PT_F44, [UNW_IA64_FR + 45] = PT_F45, + [UNW_IA64_FR + 46] = PT_F46, [UNW_IA64_FR + 47] = PT_F47, + [UNW_IA64_FR + 48] = PT_F48, [UNW_IA64_FR + 49] = PT_F49, + [UNW_IA64_FR + 50] = PT_F50, [UNW_IA64_FR + 51] = PT_F51, + [UNW_IA64_FR + 52] = PT_F52, [UNW_IA64_FR + 53] = PT_F53, + [UNW_IA64_FR + 54] = PT_F54, [UNW_IA64_FR + 55] = PT_F55, + [UNW_IA64_FR + 56] = PT_F56, [UNW_IA64_FR + 57] = PT_F57, + [UNW_IA64_FR + 58] = PT_F58, [UNW_IA64_FR + 59] = PT_F59, + [UNW_IA64_FR + 60] = PT_F60, [UNW_IA64_FR + 61] = PT_F61, + [UNW_IA64_FR + 62] = PT_F62, [UNW_IA64_FR + 63] = PT_F63, + [UNW_IA64_FR + 64] = PT_F64, [UNW_IA64_FR + 65] = PT_F65, + [UNW_IA64_FR + 66] = PT_F66, [UNW_IA64_FR + 67] = PT_F67, + [UNW_IA64_FR + 68] = PT_F68, [UNW_IA64_FR + 69] = PT_F69, + [UNW_IA64_FR + 70] = PT_F70, [UNW_IA64_FR + 71] = PT_F71, + [UNW_IA64_FR + 72] = PT_F72, [UNW_IA64_FR + 73] = PT_F73, + [UNW_IA64_FR + 74] = PT_F74, [UNW_IA64_FR + 75] = PT_F75, + [UNW_IA64_FR + 76] = PT_F76, [UNW_IA64_FR + 77] = PT_F77, + [UNW_IA64_FR + 78] = PT_F78, [UNW_IA64_FR + 79] = PT_F79, + [UNW_IA64_FR + 80] = PT_F80, [UNW_IA64_FR + 81] = PT_F81, + [UNW_IA64_FR + 82] = PT_F82, [UNW_IA64_FR + 83] = PT_F83, + [UNW_IA64_FR + 84] = PT_F84, [UNW_IA64_FR + 85] = PT_F85, + [UNW_IA64_FR + 86] = PT_F86, [UNW_IA64_FR + 87] = PT_F87, + [UNW_IA64_FR + 88] = PT_F88, [UNW_IA64_FR + 89] = PT_F89, + [UNW_IA64_FR + 90] = PT_F90, [UNW_IA64_FR + 91] = PT_F91, + [UNW_IA64_FR + 92] = PT_F92, [UNW_IA64_FR + 93] = PT_F93, + [UNW_IA64_FR + 94] = PT_F94, [UNW_IA64_FR + 95] = PT_F95, + [UNW_IA64_FR + 96] = PT_F96, [UNW_IA64_FR + 97] = PT_F97, + [UNW_IA64_FR + 98] = PT_F98, [UNW_IA64_FR + 99] = PT_F99, + [UNW_IA64_FR +100] = PT_F100, [UNW_IA64_FR +101] = PT_F101, + [UNW_IA64_FR +102] = PT_F102, [UNW_IA64_FR +103] = PT_F103, + [UNW_IA64_FR +104] = PT_F104, [UNW_IA64_FR +105] = PT_F105, + [UNW_IA64_FR +106] = PT_F106, [UNW_IA64_FR +107] = PT_F107, + [UNW_IA64_FR +108] = PT_F108, [UNW_IA64_FR +109] = PT_F109, + [UNW_IA64_FR +110] = PT_F110, [UNW_IA64_FR +111] = PT_F111, + [UNW_IA64_FR +112] = PT_F112, [UNW_IA64_FR +113] = PT_F113, + [UNW_IA64_FR +114] = PT_F114, [UNW_IA64_FR +115] = PT_F115, + [UNW_IA64_FR +116] = PT_F116, [UNW_IA64_FR +117] = PT_F117, + [UNW_IA64_FR +118] = PT_F118, [UNW_IA64_FR +119] = PT_F119, + [UNW_IA64_FR +120] = PT_F120, [UNW_IA64_FR +121] = PT_F121, + [UNW_IA64_FR +122] = PT_F122, [UNW_IA64_FR +123] = PT_F123, + [UNW_IA64_FR +124] = PT_F124, [UNW_IA64_FR +125] = PT_F125, + [UNW_IA64_FR +126] = PT_F126, [UNW_IA64_FR +127] = PT_F127, + + [UNW_IA64_AR + 0] = -1, [UNW_IA64_AR + 1] = -1, + [UNW_IA64_AR + 2] = -1, [UNW_IA64_AR + 3] = -1, + [UNW_IA64_AR + 4] = -1, [UNW_IA64_AR + 5] = -1, + [UNW_IA64_AR + 6] = -1, [UNW_IA64_AR + 7] = -1, + [UNW_IA64_AR + 8] = -1, [UNW_IA64_AR + 9] = -1, + [UNW_IA64_AR + 10] = -1, [UNW_IA64_AR + 11] = -1, + [UNW_IA64_AR + 12] = -1, [UNW_IA64_AR + 13] = -1, + [UNW_IA64_AR + 14] = -1, [UNW_IA64_AR + 15] = -1, + [UNW_IA64_AR + 16] = PT_AR_RSC, [UNW_IA64_AR + 17] = PT_AR_BSP, + [UNW_IA64_AR + 18] = PT_AR_BSPSTORE,[UNW_IA64_AR + 19] = PT_AR_RNAT, + [UNW_IA64_AR + 20] = -1, [UNW_IA64_AR + 21] = -1, + [UNW_IA64_AR + 22] = -1, [UNW_IA64_AR + 23] = -1, + [UNW_IA64_AR + 24] = -1, [UNW_IA64_AR + 25] = PT_AR_CSD, + [UNW_IA64_AR + 26] = -1, [UNW_IA64_AR + 27] = -1, + [UNW_IA64_AR + 28] = -1, [UNW_IA64_AR + 29] = -1, + [UNW_IA64_AR + 30] = -1, [UNW_IA64_AR + 31] = -1, + [UNW_IA64_AR + 32] = PT_AR_CCV, [UNW_IA64_AR + 33] = -1, + [UNW_IA64_AR + 34] = -1, [UNW_IA64_AR + 35] = -1, + [UNW_IA64_AR + 36] = PT_AR_UNAT, [UNW_IA64_AR + 37] = -1, + [UNW_IA64_AR + 38] = -1, [UNW_IA64_AR + 39] = -1, + [UNW_IA64_AR + 40] = PT_AR_FPSR, [UNW_IA64_AR + 41] = -1, + [UNW_IA64_AR + 42] = -1, [UNW_IA64_AR + 43] = -1, + [UNW_IA64_AR + 44] = -1, [UNW_IA64_AR + 45] = -1, + [UNW_IA64_AR + 46] = -1, [UNW_IA64_AR + 47] = -1, + [UNW_IA64_AR + 48] = -1, [UNW_IA64_AR + 49] = -1, + [UNW_IA64_AR + 50] = -1, [UNW_IA64_AR + 51] = -1, + [UNW_IA64_AR + 52] = -1, [UNW_IA64_AR + 53] = -1, + [UNW_IA64_AR + 54] = -1, [UNW_IA64_AR + 55] = -1, + [UNW_IA64_AR + 56] = -1, [UNW_IA64_AR + 57] = -1, + [UNW_IA64_AR + 58] = -1, [UNW_IA64_AR + 59] = -1, + [UNW_IA64_AR + 60] = -1, [UNW_IA64_AR + 61] = -1, + [UNW_IA64_AR + 62] = -1, [UNW_IA64_AR + 63] = -1, + [UNW_IA64_AR + 64] = PT_AR_PFS, [UNW_IA64_AR + 65] = PT_AR_LC, + [UNW_IA64_AR + 66] = PT_AR_EC, [UNW_IA64_AR + 67] = -1, + [UNW_IA64_AR + 68] = -1, [UNW_IA64_AR + 69] = -1, + [UNW_IA64_AR + 70] = -1, [UNW_IA64_AR + 71] = -1, + [UNW_IA64_AR + 72] = -1, [UNW_IA64_AR + 73] = -1, + [UNW_IA64_AR + 74] = -1, [UNW_IA64_AR + 75] = -1, + [UNW_IA64_AR + 76] = -1, [UNW_IA64_AR + 77] = -1, + [UNW_IA64_AR + 78] = -1, [UNW_IA64_AR + 79] = -1, + [UNW_IA64_AR + 80] = -1, [UNW_IA64_AR + 81] = -1, + [UNW_IA64_AR + 82] = -1, [UNW_IA64_AR + 83] = -1, + [UNW_IA64_AR + 84] = -1, [UNW_IA64_AR + 85] = -1, + [UNW_IA64_AR + 86] = -1, [UNW_IA64_AR + 87] = -1, + [UNW_IA64_AR + 88] = -1, [UNW_IA64_AR + 89] = -1, + [UNW_IA64_AR + 90] = -1, [UNW_IA64_AR + 91] = -1, + [UNW_IA64_AR + 92] = -1, [UNW_IA64_AR + 93] = -1, + [UNW_IA64_AR + 94] = -1, [UNW_IA64_AR + 95] = -1, + [UNW_IA64_AR + 96] = -1, [UNW_IA64_AR + 97] = -1, + [UNW_IA64_AR + 98] = -1, [UNW_IA64_AR + 99] = -1, + [UNW_IA64_AR +100] = -1, [UNW_IA64_AR +101] = -1, + [UNW_IA64_AR +102] = -1, [UNW_IA64_AR +103] = -1, + [UNW_IA64_AR +104] = -1, [UNW_IA64_AR +105] = -1, + [UNW_IA64_AR +106] = -1, [UNW_IA64_AR +107] = -1, + [UNW_IA64_AR +108] = -1, [UNW_IA64_AR +109] = -1, + [UNW_IA64_AR +110] = -1, [UNW_IA64_AR +111] = -1, + [UNW_IA64_AR +112] = -1, [UNW_IA64_AR +113] = -1, + [UNW_IA64_AR +114] = -1, [UNW_IA64_AR +115] = -1, + [UNW_IA64_AR +116] = -1, [UNW_IA64_AR +117] = -1, + [UNW_IA64_AR +118] = -1, [UNW_IA64_AR +119] = -1, + [UNW_IA64_AR +120] = -1, [UNW_IA64_AR +121] = -1, + [UNW_IA64_AR +122] = -1, [UNW_IA64_AR +123] = -1, + [UNW_IA64_AR +124] = -1, [UNW_IA64_AR +125] = -1, + [UNW_IA64_AR +126] = -1, [UNW_IA64_AR +127] = -1, + + [UNW_IA64_BR + 0] = PT_B0, [UNW_IA64_BR + 1] = PT_B1, + [UNW_IA64_BR + 2] = PT_B2, [UNW_IA64_BR + 3] = PT_B3, + [UNW_IA64_BR + 4] = PT_B4, [UNW_IA64_BR + 5] = PT_B5, + [UNW_IA64_BR + 6] = PT_B6, [UNW_IA64_BR + 7] = PT_B7, + + [UNW_IA64_PR] = PT_PR, + [UNW_IA64_CFM] = PT_CFM, + [UNW_IA64_IP] = PT_CR_IIP +#elif defined(HAVE_TTRACE) +# warning No support for ttrace() yet. +#elif defined(UNW_TARGET_HPPA) + [UNW_HPPA_GR + 0] = 0x000, [UNW_HPPA_GR + 1] = 0x004, + [UNW_HPPA_GR + 2] = 0x008, [UNW_HPPA_GR + 3] = 0x00c, + [UNW_HPPA_GR + 4] = 0x010, [UNW_HPPA_GR + 5] = 0x014, + [UNW_HPPA_GR + 6] = 0x018, [UNW_HPPA_GR + 7] = 0x01c, + [UNW_HPPA_GR + 8] = 0x020, [UNW_HPPA_GR + 9] = 0x024, + [UNW_HPPA_GR + 10] = 0x028, [UNW_HPPA_GR + 11] = 0x02c, + [UNW_HPPA_GR + 12] = 0x030, [UNW_HPPA_GR + 13] = 0x034, + [UNW_HPPA_GR + 14] = 0x038, [UNW_HPPA_GR + 15] = 0x03c, + [UNW_HPPA_GR + 16] = 0x040, [UNW_HPPA_GR + 17] = 0x044, + [UNW_HPPA_GR + 18] = 0x048, [UNW_HPPA_GR + 19] = 0x04c, + [UNW_HPPA_GR + 20] = 0x050, [UNW_HPPA_GR + 21] = 0x054, + [UNW_HPPA_GR + 22] = 0x058, [UNW_HPPA_GR + 23] = 0x05c, + [UNW_HPPA_GR + 24] = 0x060, [UNW_HPPA_GR + 25] = 0x064, + [UNW_HPPA_GR + 26] = 0x068, [UNW_HPPA_GR + 27] = 0x06c, + [UNW_HPPA_GR + 28] = 0x070, [UNW_HPPA_GR + 29] = 0x074, + [UNW_HPPA_GR + 30] = 0x078, [UNW_HPPA_GR + 31] = 0x07c, + + [UNW_HPPA_FR + 0] = 0x080, [UNW_HPPA_FR + 1] = 0x088, + [UNW_HPPA_FR + 2] = 0x090, [UNW_HPPA_FR + 3] = 0x098, + [UNW_HPPA_FR + 4] = 0x0a0, [UNW_HPPA_FR + 5] = 0x0a8, + [UNW_HPPA_FR + 6] = 0x0b0, [UNW_HPPA_FR + 7] = 0x0b8, + [UNW_HPPA_FR + 8] = 0x0c0, [UNW_HPPA_FR + 9] = 0x0c8, + [UNW_HPPA_FR + 10] = 0x0d0, [UNW_HPPA_FR + 11] = 0x0d8, + [UNW_HPPA_FR + 12] = 0x0e0, [UNW_HPPA_FR + 13] = 0x0e8, + [UNW_HPPA_FR + 14] = 0x0f0, [UNW_HPPA_FR + 15] = 0x0f8, + [UNW_HPPA_FR + 16] = 0x100, [UNW_HPPA_FR + 17] = 0x108, + [UNW_HPPA_FR + 18] = 0x110, [UNW_HPPA_FR + 19] = 0x118, + [UNW_HPPA_FR + 20] = 0x120, [UNW_HPPA_FR + 21] = 0x128, + [UNW_HPPA_FR + 22] = 0x130, [UNW_HPPA_FR + 23] = 0x138, + [UNW_HPPA_FR + 24] = 0x140, [UNW_HPPA_FR + 25] = 0x148, + [UNW_HPPA_FR + 26] = 0x150, [UNW_HPPA_FR + 27] = 0x158, + [UNW_HPPA_FR + 28] = 0x160, [UNW_HPPA_FR + 29] = 0x168, + [UNW_HPPA_FR + 30] = 0x170, [UNW_HPPA_FR + 31] = 0x178, + + [UNW_HPPA_IP] = 0x1a8 /* IAOQ[0] */ +#elif defined(UNW_TARGET_X86) +#if defined __FreeBSD__ +#define UNW_R_OFF(R, r) \ + [UNW_X86_##R] = offsetof(gregset_t, r_##r), + UNW_R_OFF(EAX, eax) + UNW_R_OFF(EDX, edx) + UNW_R_OFF(ECX, ecx) + UNW_R_OFF(EBX, ebx) + UNW_R_OFF(ESI, esi) + UNW_R_OFF(EDI, edi) + UNW_R_OFF(EBP, ebp) + UNW_R_OFF(ESP, esp) + UNW_R_OFF(EIP, eip) +// UNW_R_OFF(CS, cs) +// UNW_R_OFF(EFLAGS, eflags) +// UNW_R_OFF(SS, ss) +#elif defined __linux__ + [UNW_X86_EAX] = 0x18, + [UNW_X86_EBX] = 0x00, + [UNW_X86_ECX] = 0x04, + [UNW_X86_EDX] = 0x08, + [UNW_X86_ESI] = 0x0c, + [UNW_X86_EDI] = 0x10, + [UNW_X86_EBP] = 0x14, + [UNW_X86_EIP] = 0x30, + [UNW_X86_ESP] = 0x3c +/* CS = 0x34, */ +/* DS = 0x1c, */ +/* ES = 0x20, */ +/* FS = 0x24, */ +/* GS = 0x28, */ +/* ORIG_EAX = 0x2c, */ +/* EFLAGS = 0x38, */ +/* SS = 0x40 */ +#else +#error Port me +#endif +#elif defined(UNW_TARGET_X86_64) +#if defined __FreeBSD__ +#define UNW_R_OFF(R, r) \ + [UNW_X86_64_##R] = offsetof(gregset_t, r_##r), + UNW_R_OFF(RAX, rax) + UNW_R_OFF(RDX, rdx) + UNW_R_OFF(RCX, rcx) + UNW_R_OFF(RBX, rbx) + UNW_R_OFF(RSI, rsi) + UNW_R_OFF(RDI, rdi) + UNW_R_OFF(RBP, rbp) + UNW_R_OFF(RSP, rsp) + UNW_R_OFF(R8, r8) + UNW_R_OFF(R9, r9) + UNW_R_OFF(R10, r10) + UNW_R_OFF(R11, r11) + UNW_R_OFF(R12, r12) + UNW_R_OFF(R13, r13) + UNW_R_OFF(R14, r14) + UNW_R_OFF(R15, r15) + UNW_R_OFF(RIP, rip) +// UNW_R_OFF(CS, cs) +// UNW_R_OFF(EFLAGS, rflags) +// UNW_R_OFF(SS, ss) +#undef UNW_R_OFF +#elif defined __linux__ + [UNW_X86_64_RAX] = 0x50, + [UNW_X86_64_RDX] = 0x60, + [UNW_X86_64_RCX] = 0x58, + [UNW_X86_64_RBX] = 0x28, + [UNW_X86_64_RSI] = 0x68, + [UNW_X86_64_RDI] = 0x70, + [UNW_X86_64_RBP] = 0x20, + [UNW_X86_64_RSP] = 0x98, + [UNW_X86_64_R8] = 0x48, + [UNW_X86_64_R9] = 0x40, + [UNW_X86_64_R10] = 0x38, + [UNW_X86_64_R11] = 0x30, + [UNW_X86_64_R12] = 0x18, + [UNW_X86_64_R13] = 0x10, + [UNW_X86_64_R14] = 0x08, + [UNW_X86_64_R15] = 0x00, + [UNW_X86_64_RIP] = 0x80 +// [UNW_X86_64_CS] = 0x88, +// [UNW_X86_64_EFLAGS] = 0x90, +// [UNW_X86_64_RSP] = 0x98, +// [UNW_X86_64_SS] = 0xa0 +#else +#error Port me +#endif +#elif defined(UNW_TARGET_PPC32) || defined(UNW_TARGET_PPC64) + +#define UNW_REG_SLOT_SIZE sizeof(unsigned long) +#define UNW_PPC_R(v) ((v) * UNW_REG_SLOT_SIZE) +#define UNW_PPC_PT(p) UNW_PPC_R(PT_##p) + +#define UNW_FP_OFF(b, i) \ + [UNW_PPC##b##_F##i] = UNW_PPC_R(PT_FPR0 + i * 8/UNW_REG_SLOT_SIZE) + +#define UNW_R_OFF(b, i) \ + [UNW_PPC##b##_R##i] = UNW_PPC_R(PT_R##i) + +#define UNW_PPC_REGS(b) \ + UNW_R_OFF(b, 0), \ + UNW_R_OFF(b, 1), \ + UNW_R_OFF(b, 2), \ + UNW_R_OFF(b, 3), \ + UNW_R_OFF(b, 4), \ + UNW_R_OFF(b, 5), \ + UNW_R_OFF(b, 6), \ + UNW_R_OFF(b, 7), \ + UNW_R_OFF(b, 8), \ + UNW_R_OFF(b, 9), \ + UNW_R_OFF(b, 10), \ + UNW_R_OFF(b, 11), \ + UNW_R_OFF(b, 12), \ + UNW_R_OFF(b, 13), \ + UNW_R_OFF(b, 14), \ + UNW_R_OFF(b, 15), \ + UNW_R_OFF(b, 16), \ + UNW_R_OFF(b, 17), \ + UNW_R_OFF(b, 18), \ + UNW_R_OFF(b, 19), \ + UNW_R_OFF(b, 20), \ + UNW_R_OFF(b, 21), \ + UNW_R_OFF(b, 22), \ + UNW_R_OFF(b, 23), \ + UNW_R_OFF(b, 24), \ + UNW_R_OFF(b, 25), \ + UNW_R_OFF(b, 26), \ + UNW_R_OFF(b, 27), \ + UNW_R_OFF(b, 28), \ + UNW_R_OFF(b, 29), \ + UNW_R_OFF(b, 30), \ + UNW_R_OFF(b, 31), \ + \ + [UNW_PPC##b##_CTR] = UNW_PPC_PT(CTR), \ + [UNW_PPC##b##_XER] = UNW_PPC_PT(XER), \ + [UNW_PPC##b##_LR] = UNW_PPC_PT(LNK), \ + \ + UNW_FP_OFF(b, 0), \ + UNW_FP_OFF(b, 1), \ + UNW_FP_OFF(b, 2), \ + UNW_FP_OFF(b, 3), \ + UNW_FP_OFF(b, 4), \ + UNW_FP_OFF(b, 5), \ + UNW_FP_OFF(b, 6), \ + UNW_FP_OFF(b, 7), \ + UNW_FP_OFF(b, 8), \ + UNW_FP_OFF(b, 9), \ + UNW_FP_OFF(b, 10), \ + UNW_FP_OFF(b, 11), \ + UNW_FP_OFF(b, 12), \ + UNW_FP_OFF(b, 13), \ + UNW_FP_OFF(b, 14), \ + UNW_FP_OFF(b, 15), \ + UNW_FP_OFF(b, 16), \ + UNW_FP_OFF(b, 17), \ + UNW_FP_OFF(b, 18), \ + UNW_FP_OFF(b, 19), \ + UNW_FP_OFF(b, 20), \ + UNW_FP_OFF(b, 21), \ + UNW_FP_OFF(b, 22), \ + UNW_FP_OFF(b, 23), \ + UNW_FP_OFF(b, 24), \ + UNW_FP_OFF(b, 25), \ + UNW_FP_OFF(b, 26), \ + UNW_FP_OFF(b, 27), \ + UNW_FP_OFF(b, 28), \ + UNW_FP_OFF(b, 29), \ + UNW_FP_OFF(b, 30), \ + UNW_FP_OFF(b, 31) + +#define UNW_PPC32_REGS \ + [UNW_PPC32_FPSCR] = UNW_PPC_PT(FPSCR), \ + [UNW_PPC32_CCR] = UNW_PPC_PT(CCR) + +#define UNW_VR_OFF(i) \ + [UNW_PPC64_V##i] = UNW_PPC_R(PT_VR0 + i * 2) + +#define UNW_PPC64_REGS \ + [UNW_PPC64_NIP] = UNW_PPC_PT(NIP), \ + [UNW_PPC64_FRAME_POINTER] = -1, \ + [UNW_PPC64_ARG_POINTER] = -1, \ + [UNW_PPC64_CR0] = -1, \ + [UNW_PPC64_CR1] = -1, \ + [UNW_PPC64_CR2] = -1, \ + [UNW_PPC64_CR3] = -1, \ + [UNW_PPC64_CR4] = -1, \ + [UNW_PPC64_CR5] = -1, \ + [UNW_PPC64_CR6] = -1, \ + [UNW_PPC64_CR7] = -1, \ + [UNW_PPC64_VRSAVE] = UNW_PPC_PT(VRSAVE), \ + [UNW_PPC64_VSCR] = UNW_PPC_PT(VSCR), \ + [UNW_PPC64_SPE_ACC] = -1, \ + [UNW_PPC64_SPEFSCR] = -1, \ + UNW_VR_OFF(0), \ + UNW_VR_OFF(1), \ + UNW_VR_OFF(2), \ + UNW_VR_OFF(3), \ + UNW_VR_OFF(4), \ + UNW_VR_OFF(5), \ + UNW_VR_OFF(6), \ + UNW_VR_OFF(7), \ + UNW_VR_OFF(8), \ + UNW_VR_OFF(9), \ + UNW_VR_OFF(10), \ + UNW_VR_OFF(11), \ + UNW_VR_OFF(12), \ + UNW_VR_OFF(13), \ + UNW_VR_OFF(14), \ + UNW_VR_OFF(15), \ + UNW_VR_OFF(16), \ + UNW_VR_OFF(17), \ + UNW_VR_OFF(18), \ + UNW_VR_OFF(19), \ + UNW_VR_OFF(20), \ + UNW_VR_OFF(21), \ + UNW_VR_OFF(22), \ + UNW_VR_OFF(23), \ + UNW_VR_OFF(24), \ + UNW_VR_OFF(25), \ + UNW_VR_OFF(26), \ + UNW_VR_OFF(27), \ + UNW_VR_OFF(28), \ + UNW_VR_OFF(29), \ + UNW_VR_OFF(30), \ + UNW_VR_OFF(31) + +#if defined(UNW_TARGET_PPC32) + UNW_PPC_REGS(32), + UNW_PPC32_REGS, +#else + UNW_PPC_REGS(64), + UNW_PPC64_REGS, +#endif + +#elif defined(UNW_TARGET_ARM) +#if defined(__linux__) || defined(__FreeBSD__) + [UNW_ARM_R0] = 0x00, + [UNW_ARM_R1] = 0x04, + [UNW_ARM_R2] = 0x08, + [UNW_ARM_R3] = 0x0c, + [UNW_ARM_R4] = 0x10, + [UNW_ARM_R5] = 0x14, + [UNW_ARM_R6] = 0x18, + [UNW_ARM_R7] = 0x1c, + [UNW_ARM_R8] = 0x20, + [UNW_ARM_R9] = 0x24, + [UNW_ARM_R10] = 0x28, + [UNW_ARM_R11] = 0x2c, + [UNW_ARM_R12] = 0x30, + [UNW_ARM_R13] = 0x34, + [UNW_ARM_R14] = 0x38, + [UNW_ARM_R15] = 0x3c, +#else +#error Fix me +#endif +#elif defined(UNW_TARGET_MIPS) + [UNW_MIPS_R0] = 0, + [UNW_MIPS_R1] = 1, + [UNW_MIPS_R2] = 2, + [UNW_MIPS_R3] = 3, + [UNW_MIPS_R4] = 4, + [UNW_MIPS_R5] = 5, + [UNW_MIPS_R6] = 6, + [UNW_MIPS_R7] = 7, + [UNW_MIPS_R8] = 8, + [UNW_MIPS_R9] = 9, + [UNW_MIPS_R10] = 10, + [UNW_MIPS_R11] = 11, + [UNW_MIPS_R12] = 12, + [UNW_MIPS_R13] = 13, + [UNW_MIPS_R14] = 14, + [UNW_MIPS_R15] = 15, + [UNW_MIPS_R16] = 16, + [UNW_MIPS_R17] = 17, + [UNW_MIPS_R18] = 18, + [UNW_MIPS_R19] = 19, + [UNW_MIPS_R20] = 20, + [UNW_MIPS_R21] = 21, + [UNW_MIPS_R22] = 22, + [UNW_MIPS_R23] = 23, + [UNW_MIPS_R24] = 24, + [UNW_MIPS_R25] = 25, + [UNW_MIPS_R26] = 26, + [UNW_MIPS_R27] = 27, + [UNW_MIPS_R28] = 28, + [UNW_MIPS_R29] = 29, + [UNW_MIPS_R30] = 30, + [UNW_MIPS_R31] = 31, + [UNW_MIPS_PC] = 64, +#elif defined(UNW_TARGET_SH) +#elif defined(UNW_TARGET_AARCH64) + [UNW_AARCH64_X0] = 0x00, + [UNW_AARCH64_X1] = 0x08, + [UNW_AARCH64_X2] = 0x10, + [UNW_AARCH64_X3] = 0x18, + [UNW_AARCH64_X4] = 0x20, + [UNW_AARCH64_X5] = 0x28, + [UNW_AARCH64_X6] = 0x30, + [UNW_AARCH64_X7] = 0x38, + [UNW_AARCH64_X8] = 0x40, + [UNW_AARCH64_X9] = 0x48, + [UNW_AARCH64_X10] = 0x50, + [UNW_AARCH64_X11] = 0x58, + [UNW_AARCH64_X12] = 0x60, + [UNW_AARCH64_X13] = 0x68, + [UNW_AARCH64_X14] = 0x70, + [UNW_AARCH64_X15] = 0x78, + [UNW_AARCH64_X16] = 0x80, + [UNW_AARCH64_X17] = 0x88, + [UNW_AARCH64_X18] = 0x90, + [UNW_AARCH64_X19] = 0x98, + [UNW_AARCH64_X20] = 0xa0, + [UNW_AARCH64_X21] = 0xa8, + [UNW_AARCH64_X22] = 0xb0, + [UNW_AARCH64_X23] = 0xb8, + [UNW_AARCH64_X24] = 0xc0, + [UNW_AARCH64_X25] = 0xc8, + [UNW_AARCH64_X26] = 0xd0, + [UNW_AARCH64_X27] = 0xd8, + [UNW_AARCH64_X28] = 0xe0, + [UNW_AARCH64_X29] = 0xe8, + [UNW_AARCH64_X30] = 0xf0, + [UNW_AARCH64_SP] = 0xf8, + [UNW_AARCH64_PC] = 0x100, + [UNW_AARCH64_PSTATE] = 0x108 +#elif defined(UNW_TARGET_TILEGX) + [UNW_TILEGX_R0] = 0x00, + [UNW_TILEGX_R1] = 0x08, + [UNW_TILEGX_R2] = 0x10, + [UNW_TILEGX_R3] = 0x08, + [UNW_TILEGX_R4] = 0x20, + [UNW_TILEGX_R5] = 0x28, + [UNW_TILEGX_R6] = 0x30, + [UNW_TILEGX_R7] = 0x38, + [UNW_TILEGX_R8] = 0x40, + [UNW_TILEGX_R9] = 0x48, + [UNW_TILEGX_R10] = 0x50, + [UNW_TILEGX_R11] = 0x58, + [UNW_TILEGX_R12] = 0x60, + [UNW_TILEGX_R13] = 0x68, + [UNW_TILEGX_R14] = 0x70, + [UNW_TILEGX_R15] = 0x78, + [UNW_TILEGX_R16] = 0x80, + [UNW_TILEGX_R17] = 0x88, + [UNW_TILEGX_R18] = 0x90, + [UNW_TILEGX_R19] = 0x98, + [UNW_TILEGX_R20] = 0xa0, + [UNW_TILEGX_R21] = 0xa8, + [UNW_TILEGX_R22] = 0xb0, + [UNW_TILEGX_R23] = 0xb8, + [UNW_TILEGX_R24] = 0xc0, + [UNW_TILEGX_R25] = 0xc8, + [UNW_TILEGX_R26] = 0xd0, + [UNW_TILEGX_R27] = 0xd8, + [UNW_TILEGX_R28] = 0xe0, + [UNW_TILEGX_R29] = 0xe8, + [UNW_TILEGX_R30] = 0xf0, + [UNW_TILEGX_R31] = 0xf8, + [UNW_TILEGX_R32] = 0x100, + [UNW_TILEGX_R33] = 0x108, + [UNW_TILEGX_R34] = 0x110, + [UNW_TILEGX_R35] = 0x118, + [UNW_TILEGX_R36] = 0x120, + [UNW_TILEGX_R37] = 0x128, + [UNW_TILEGX_R38] = 0x130, + [UNW_TILEGX_R39] = 0x138, + [UNW_TILEGX_R40] = 0x140, + [UNW_TILEGX_R41] = 0x148, + [UNW_TILEGX_R42] = 0x150, + [UNW_TILEGX_R43] = 0x158, + [UNW_TILEGX_R44] = 0x160, + [UNW_TILEGX_R45] = 0x168, + [UNW_TILEGX_R46] = 0x170, + [UNW_TILEGX_R47] = 0x178, + [UNW_TILEGX_R48] = 0x180, + [UNW_TILEGX_R49] = 0x188, + [UNW_TILEGX_R50] = 0x190, + [UNW_TILEGX_R51] = 0x198, + [UNW_TILEGX_R52] = 0x1a0, + [UNW_TILEGX_R53] = 0x1a8, + [UNW_TILEGX_R54] = 0x1b0, + [UNW_TILEGX_R55] = 0x1b8, + [UNW_TILEGX_PC] = 0x1a0 +#elif defined(UNW_TARGET_S390X) + [UNW_S390X_R0] = 0x10, + [UNW_S390X_R1] = 0x18, + [UNW_S390X_R2] = 0x20, + [UNW_S390X_R3] = 0x28, + [UNW_S390X_R4] = 0x30, + [UNW_S390X_R5] = 0x38, + [UNW_S390X_R6] = 0x40, + [UNW_S390X_R7] = 0x48, + [UNW_S390X_R8] = 0x50, + [UNW_S390X_R9] = 0x58, + [UNW_S390X_R10] = 0x60, + [UNW_S390X_R11] = 0x68, + [UNW_S390X_R12] = 0x70, + [UNW_S390X_R13] = 0x78, + [UNW_S390X_R14] = 0x80, + [UNW_S390X_R15] = 0x88, + [UNW_S390X_F0] = 0xe0, + [UNW_S390X_F1] = 0xe8, + [UNW_S390X_F2] = 0xf0, + [UNW_S390X_F3] = 0xf8, + [UNW_S390X_F4] = 0x100, + [UNW_S390X_F5] = 0x108, + [UNW_S390X_F6] = 0x110, + [UNW_S390X_F7] = 0x118, + [UNW_S390X_F8] = 0x120, + [UNW_S390X_F9] = 0x128, + [UNW_S390X_F10] = 0x130, + [UNW_S390X_F11] = 0x138, + [UNW_S390X_F12] = 0x140, + [UNW_S390X_F13] = 0x148, + [UNW_S390X_F14] = 0x150, + [UNW_S390X_F15] = 0x150, + [UNW_S390X_IP] = 0x08 +#else +# error Fix me. +#endif + }; diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_resume.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_resume.c new file mode 100644 index 00000000000000..d70a0d48218f05 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_resume.c @@ -0,0 +1,40 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "_UPT_internal.h" + +int +_UPT_resume (unw_addr_space_t as, unw_cursor_t *c, void *arg) +{ + struct UPT_info *ui = arg; + +#ifdef HAVE_TTRACE +# warning No support for ttrace() yet. +#elif HAVE_DECL_PTRACE_CONT + return ptrace (PTRACE_CONT, ui->pid, 0, 0); +#elif HAVE_DECL_PT_CONTINUE + return ptrace(PT_CONTINUE, ui->pid, (caddr_t)1, 0); +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/libunwind-ptrace.pc.in b/src/coreclr/src/pal/src/libunwind/src/ptrace/libunwind-ptrace.pc.in new file mode 100644 index 00000000000000..673004b69ef0f7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/libunwind-ptrace.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libunwind-ptrace +Description: libunwind ptrace library +Version: @VERSION@ +Requires: libunwind-generic libunwind +Libs: -L${libdir} -lunwind-ptrace +Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c new file mode 100644 index 00000000000000..d411454932bc4f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c @@ -0,0 +1,62 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Copyright (C) 2012 Tommi Rantala + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#if defined(_BIG_ENDIAN) && !defined(__BIG_ENDIAN) +#define __BIG_ENDIAN _BIG_ENDIAN +#endif + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * s390x supports only big-endian. + */ + if (byte_order != 0 && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c new file mode 100644 index 00000000000000..50de1e423c2c9e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + + if (dwarf_make_proc_info (&c->dwarf) < 0) + { + /* On x86-64, some key routines such as _start() and _dl_start() + are missing DWARF unwind info. We don't want to fail in that + case, because those frames are uninteresting and just mark + the end of the frame-chain anyhow. */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 1; + return 0; + } + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c new file mode 100644 index 00000000000000..dc462c966e5673 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c @@ -0,0 +1,86 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_S390X_R6: + case UNW_S390X_R7: + case UNW_S390X_R8: + case UNW_S390X_R9: + case UNW_S390X_R10: + case UNW_S390X_R11: + case UNW_S390X_R12: + case UNW_S390X_R13: + case UNW_S390X_R15: + case UNW_S390X_F8: + case UNW_S390X_F9: + case UNW_S390X_F10: + case UNW_S390X_F11: + case UNW_S390X_F12: + case UNW_S390X_F13: + case UNW_S390X_F14: + case UNW_S390X_F15: + loc = c->dwarf.loc[reg]; + break; + + default: + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c new file mode 100644 index 00000000000000..e2abe89d30743a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c @@ -0,0 +1,101 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "config.h" +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (s390x_lock); +HIDDEN int tdep_init_done; + +/* The API register numbers are exactly the same as the .eh_frame + registers, for now at least. */ +HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_NUM_PRESERVED_REGS] = + { + UNW_S390X_R0, + UNW_S390X_R1, + UNW_S390X_R2, + UNW_S390X_R3, + UNW_S390X_R4, + UNW_S390X_R5, + UNW_S390X_R6, + UNW_S390X_R7, + UNW_S390X_R8, + UNW_S390X_R9, + UNW_S390X_R10, + UNW_S390X_R11, + UNW_S390X_R12, + UNW_S390X_R13, + UNW_S390X_R14, + UNW_S390X_R15, + + UNW_S390X_F0, + UNW_S390X_F2, + UNW_S390X_F4, + UNW_S390X_F6, + UNW_S390X_F1, + UNW_S390X_F3, + UNW_S390X_F5, + UNW_S390X_F7, + UNW_S390X_F8, + UNW_S390X_F10, + UNW_S390X_F12, + UNW_S390X_F14, + UNW_S390X_F9, + UNW_S390X_F11, + UNW_S390X_F13, + UNW_S390X_F15, + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&s390x_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + + tdep_init_mem_validate (); + +#ifndef UNW_REMOTE_ONLY + s390x_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&s390x_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c new file mode 100644 index 00000000000000..db01743c062763 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c @@ -0,0 +1,365 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +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. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + if (reg >= UNW_S390X_R0 && reg <= UNW_S390X_R15) + return &uc->uc_mcontext.gregs[reg - UNW_S390X_R0]; + if (reg >= UNW_S390X_F0 && reg <= UNW_S390X_F15) + return &uc->uc_mcontext.fpregs.fprs[reg - UNW_S390X_F0]; + if (reg == UNW_S390X_IP) + return &uc->uc_mcontext.psw.addr; + + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +#define PAGE_SIZE 4096 +#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) + +static int mem_validate_pipe[2] = {-1, -1}; + +static inline void +open_pipe (void) +{ + /* ignore errors for closing invalid fd's */ + close (mem_validate_pipe[0]); + close (mem_validate_pipe[1]); + + pipe2 (mem_validate_pipe, O_CLOEXEC | O_NONBLOCK); +} + +ALWAYS_INLINE +static int +write_validate (void *addr) +{ + int ret = -1; + ssize_t bytes = 0; + + do + { + char buf; + bytes = read (mem_validate_pipe[0], &buf, 1); + } + while ( errno == EINTR ); + + int valid_read = (bytes > 0 || errno == EAGAIN || errno == EWOULDBLOCK); + if (!valid_read) + { + // re-open closed pipe + open_pipe (); + } + + do + { + /* use syscall insteadof write() so that ASAN does not complain */ + ret = syscall (SYS_write, mem_validate_pipe[1], addr, 1); + } + while ( errno == EINTR ); + + return ret; +} + +static int (*mem_validate_func) (void *addr, size_t len); +static int msync_validate (void *addr, size_t len) +{ + if (msync (addr, len, MS_ASYNC) != 0) + { + return -1; + } + + return write_validate (addr); +} + +#ifdef HAVE_MINCORE +static int mincore_validate (void *addr, size_t len) +{ + unsigned char mvec[2]; /* Unaligned access may cross page boundary */ + size_t i; + + /* mincore could fail with EAGAIN but we conservatively return -1 + instead of looping. */ + if (mincore (addr, len, mvec) != 0) + { + return -1; + } + + for (i = 0; i < (len + PAGE_SIZE - 1) / PAGE_SIZE; i++) + { + if (!(mvec[i] & 1)) return -1; + } + + return write_validate (addr); +} +#endif + +/* Initialise memory validation method. On linux kernels <2.6.21, + mincore() returns incorrect value for MAP_PRIVATE mappings, + such as stacks. If mincore() was available at compile time, + check if we can actually use it. If not, use msync() instead. */ +HIDDEN void +tdep_init_mem_validate (void) +{ + open_pipe (); + +#ifdef HAVE_MINCORE + unsigned char present = 1; + unw_word_t addr = PAGE_START((unw_word_t)&present); + unsigned char mvec[1]; + int ret; + while ((ret = mincore ((void*)addr, PAGE_SIZE, mvec)) == -1 && + errno == EAGAIN) {} + if (ret == 0 && (mvec[0] & 1)) + { + Debug(1, "using mincore to validate memory\n"); + mem_validate_func = mincore_validate; + } + else +#endif + { + Debug(1, "using msync to validate memory\n"); + mem_validate_func = msync_validate; + } +} + +/* Cache of already validated addresses */ +#define NLGA 4 +static unw_word_t last_good_addr[NLGA]; +static int lga_victim; + +static int +validate_mem (unw_word_t addr) +{ + int i, victim; + size_t len; + + if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) + len = PAGE_SIZE; + else + len = PAGE_SIZE * 2; + + addr = PAGE_START(addr); + + if (addr == 0) + return -1; + + for (i = 0; i < NLGA; i++) + { + if (last_good_addr[i] && (addr == last_good_addr[i])) + return 0; + } + + if (mem_validate_func ((void *) addr, len) == -1) + return -1; + + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (!last_good_addr[victim]) { + last_good_addr[victim++] = addr; + return 0; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; + + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (unlikely (write)) + { + Debug (16, "mem[%016lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + /* validate address */ + const struct cursor *c = (const struct cursor *)arg; + if (likely (c != NULL) && unlikely (c->validate) + && unlikely (validate_mem (addr))) { + Debug (16, "mem[%016lx] -> invalid\n", addr); + return -1; + } + *val = *(unw_word_t *) addr; + Debug (16, "mem[%016lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = ((struct cursor *)arg)->uc; + + if (unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- 0x%016lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> 0x%016lx\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = ((struct cursor *)arg)->uc; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +s390x_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = s390x_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); + + memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); + lga_victim = 0; +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c new file mode 100644 index 00000000000000..5eaead0f840bb2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c @@ -0,0 +1,81 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (unlikely (!tdep_init_done)) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = c; + c->uc = uc; + c->validate = 0; + return common_init (c, use_prev_instr); +} + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c new file mode 100644 index 00000000000000..efd61d64d4b8f2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + if (as == unw_local_addr_space) + { + c->dwarf.as_arg = c; + c->uc = as_arg; + } + else + { + c->dwarf.as_arg = as_arg; + c->uc = NULL; + } + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c new file mode 100644 index 00000000000000..7ed91e3ccfc027 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c @@ -0,0 +1,77 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + Copyright (C) 2017 IBM + + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* The restorer stub will be a system call: + - rt_sigreturn: svc 173 (0x0aad) + - sigreturn: svc 119 (0x0a77) +*/ + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret, shift = 48; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + /* Align the instruction pointer to 8 bytes so that we guarantee + an 8 byte read from it won't cross a page boundary. + Instructions on s390x are 2 byte aligned. */ + ip = c->dwarf.ip & ~7; + shift -= (c->dwarf.ip - ip) * 8; + + ret = (*a->access_mem) (as, ip, &w0, 0, arg); + if (ret < 0) + return ret; + + /* extract first 2 bytes of the next instruction */ + w0 = (w0 >> shift) & 0xffff; + + /* sigreturn */ + if (w0 == 0x0a77) + return 1; + + /* rt_sigreturn */ + if (w0 == 0x0aad) + return 2; + + return 0; + +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c new file mode 100644 index 00000000000000..1a48833d56e733 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c @@ -0,0 +1,116 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_S390X_CFA: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + case UNW_S390X_R0: + case UNW_S390X_R1: + case UNW_S390X_R2: + case UNW_S390X_R3: + case UNW_S390X_R4: + case UNW_S390X_R5: + case UNW_S390X_R6: + case UNW_S390X_R7: + case UNW_S390X_R8: + case UNW_S390X_R9: + case UNW_S390X_R10: + case UNW_S390X_R11: + case UNW_S390X_R12: + case UNW_S390X_R13: + case UNW_S390X_R14: + case UNW_S390X_IP: + loc = c->dwarf.loc[reg]; + break; + + case UNW_S390X_R15: + if (write) + return -UNW_EREADONLYREG; + loc = c->dwarf.loc[reg]; + break; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_S390X_F0: + case UNW_S390X_F1: + case UNW_S390X_F2: + case UNW_S390X_F3: + case UNW_S390X_F4: + case UNW_S390X_F5: + case UNW_S390X_F6: + case UNW_S390X_F7: + case UNW_S390X_F8: + case UNW_S390X_F9: + case UNW_S390X_F10: + case UNW_S390X_F11: + case UNW_S390X_F12: + case UNW_S390X_F13: + case UNW_S390X_F14: + case UNW_S390X_F15: + loc = c->dwarf.loc[reg]; + break; + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c new file mode 100644 index 00000000000000..fd9d13027e2a85 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c @@ -0,0 +1,160 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +s390x_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t uc = *c->uc; + ucontext_t *rt = NULL; + struct sigcontext *sc = NULL; + int i; + unw_word_t sp, ip; + uc.uc_mcontext.psw.addr = c->dwarf.ip; + + /* Ensure c->pi is up-to-date. On x86-64, it's relatively common to + be missing DWARF unwind info. We don't want to fail in that + case, because the frame-chain still would let us do a backtrace + at least. */ + dwarf_make_proc_info (&c->dwarf); + + switch (c->sigcontext_format) + { + case S390X_SCF_NONE: + Debug (8, "resuming at ip=%llx via setcontext()\n", + (unsigned long long) c->dwarf.ip); + setcontext (&uc); + abort(); /* unreachable */ + case S390X_SCF_LINUX_SIGFRAME: + Debug (8, "resuming at ip=%llx via signal trampoline\n", + (unsigned long long) c->dwarf.ip); + sc = (struct sigcontext*)c->sigcontext_addr; + for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) + sc->sregs->regs.gprs[i-UNW_S390X_R0] = uc.uc_mcontext.gregs[i-UNW_S390X_R0]; + for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) + sc->sregs->fpregs.fprs[i-UNW_S390X_F0] = uc.uc_mcontext.fpregs.fprs[i-UNW_S390X_F0].d; + sc->sregs->regs.psw.addr = uc.uc_mcontext.psw.addr; + + sp = c->sigcontext_sp; + ip = c->sigcontext_pc; + __asm__ __volatile__ ( + "lgr 15, %[sp]\n" + "br %[ip]\n" + : : [sp] "r" (sp), [ip] "r" (ip) + ); + abort(); /* unreachable */ + case S390X_SCF_LINUX_RT_SIGFRAME: + Debug (8, "resuming at ip=%llx via signal trampoline\n", + (unsigned long long) c->dwarf.ip); + rt = (ucontext_t*)c->sigcontext_addr; + for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) + rt->uc_mcontext.gregs[i-UNW_S390X_R0] = uc.uc_mcontext.gregs[i-UNW_S390X_R0]; + for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) + rt->uc_mcontext.fpregs.fprs[i-UNW_S390X_F0] = uc.uc_mcontext.fpregs.fprs[i-UNW_S390X_F0]; + rt->uc_mcontext.psw.addr = uc.uc_mcontext.psw.addr; + + sp = c->sigcontext_sp; + ip = c->sigcontext_pc; + __asm__ __volatile__ ( + "lgr 15, %[sp]\n" + "br %[ip]\n" + : : [sp] "r" (sp), [ip] "r" (ip) + ); + abort(); /* unreachable */ + } + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int write, void *); + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int write, void *); + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + access_reg = as->acc.access_reg; + access_fpreg = as->acc.access_fpreg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + (*access_fpreg) (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + (*access_reg) (as, reg, &val, 1, arg); + } + } + + if (c->dwarf.args_size) + { + if (tdep_access_reg (c, UNW_S390X_R15, &val, 0) >= 0) + { + val += c->dwarf.args_size; + (*access_reg) (as, UNW_S390X_R15, &val, 1, arg); + } + } + return 0; +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c new file mode 100644 index 00000000000000..0b79580b256bc2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c @@ -0,0 +1,146 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include + +static int +s390x_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret, i; + unw_word_t sc_addr, sp, *gprs, *fprs, *psw; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_R15], &sp); + if (ret < 0) + return ret; + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = sp; + c->sigcontext_pc = c->dwarf.ip; + switch (c->sigcontext_format) + { + case S390X_SCF_LINUX_SIGFRAME: /* sigreturn */ + sc_addr = sp + 160; + gprs = ((struct sigcontext*)sc_addr)->sregs->regs.gprs; + fprs = (unw_word_t*)((struct sigcontext*)sc_addr)->sregs->fpregs.fprs; + psw = &((struct sigcontext*)sc_addr)->sregs->regs.psw.addr; + break; + case S390X_SCF_LINUX_RT_SIGFRAME: /* rt_sigreturn */ + sc_addr = sp + sizeof(siginfo_t) + 8 + 160; + gprs = ((ucontext_t*)sc_addr)->uc_mcontext.gregs; + fprs = (unw_word_t*)((ucontext_t*)sc_addr)->uc_mcontext.fpregs.fprs; + psw = &((ucontext_t*)sc_addr)->uc_mcontext.psw.addr; + break; + default: + return -UNW_EUNSPEC; + } + + c->sigcontext_addr = sc_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) + c->dwarf.loc[i] = DWARF_MEM_LOC (c, (unw_word_t) &gprs[i-UNW_S390X_R0]); + for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) + c->dwarf.loc[i] = DWARF_MEM_LOC (c, (unw_word_t) &fprs[i-UNW_S390X_F0]); + + c->dwarf.loc[UNW_S390X_IP] = DWARF_MEM_LOC (c, (unw_word_t) psw); + + /* Set SP/CFA and PC/IP. + Normally the default CFA on s390x is r15+160. We do not add that offset + here because dwarf_step will add the offset. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_R15], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_IP], &c->dwarf.ip); + + c->dwarf.pi_valid = 0; + c->dwarf.use_prev_instr = 0; + + return 1; +} + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret = 0, val = c->validate, sig; + +#if CONSERVATIVE_CHECKS + c->validate = 1; +#endif + + Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n", + c, c->dwarf.ip, c->dwarf.cfa); + + /* Try DWARF-based unwinding... */ + c->sigcontext_format = S390X_SCF_NONE; + ret = dwarf_step (&c->dwarf); + +#if CONSERVATIVE_CHECKS + c->validate = val; +#endif + + if (unlikely (ret == -UNW_ENOINFO)) + { + /* GCC doesn't currently emit debug information for signal + trampolines on s390x so we check for them explicitly. + + If there isn't debug information available we could also + try using the backchain (if available). + + Other platforms also detect PLT entries here. That's + tricky to do reliably on s390x so I've left it out for + now. */ + + /* Memory accesses here are quite likely to be unsafe. */ + c->validate = 1; + + /* Check if this is a signal frame. */ + sig = unw_is_signal_frame (cursor); + if (sig > 0) + { + c->sigcontext_format = sig; + ret = s390x_handle_signal_frame (cursor); + } + else + { + c->dwarf.ip = 0; + ret = 0; + } + + c->validate = val; + return ret; + } + + if (unlikely (ret > 0 && c->dwarf.ip == 0)) + return 0; + + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c new file mode 100644 index 00000000000000..8c43a67c0fff23 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c @@ -0,0 +1,6 @@ +#define UNW_LOCAL_ONLY +#include "config.h" +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c new file mode 100644 index 00000000000000..b9a7c4f51ad9fa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S new file mode 100644 index 00000000000000..d35a3cf3a953d6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 Google, Inc + Contributed by Paul Pluzhnikov + Copyright (C) 2010 Konstantin Belousov + Copyright (C) 2017 IBM + + Modified for s390x by Michael Munday + +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. */ + +// int _Us390x_getcontext (unw_tdep_context_t *ucp) + + .global _Us390x_getcontext + .type _Us390x_getcontext, @function +_Us390x_getcontext: + .cfi_startproc + + // Save the minimal set of registers required to restore the + // context. Generally speaking this is just the preserved + // registers but we've also saved the parameter registers + // so that return values can be modified too. + + // save PSW address + // (not strictly needed but makes other code simpler) + stg %r14,0x30(%r2) + + // floating point parameters (not strictly needed) + std %f0,0x100(%r2) + std %f2,0x110(%r2) + std %f4,0x120(%r2) + std %f6,0x130(%r2) + + // floating point preserved registers + stfpc 0xf8(%r2) + std %f8,0x140(%r2) + std %f9,0x148(%r2) + std %f10,0x150(%r2) + std %f11,0x158(%r2) + std %f12,0x160(%r2) + std %f13,0x168(%r2) + std %f14,0x170(%r2) + std %f15,0x178(%r2) + + // preserved registers and parameters + lgr %r1,%r2 + lghi %r2,0 + stmg %r2,%r15,0x48(%r1) + + br %r14 + + .cfi_endproc + .size _Us390x_getcontext, . - _Us390x_getcontext + + // We do not need executable stack. + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/init.h b/src/coreclr/src/pal/src/libunwind/src/s390x/init.h new file mode 100644 index 00000000000000..86ced38f66ca55 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/init.h @@ -0,0 +1,71 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + int i; + + for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) { + c->dwarf.loc[i] = DWARF_REG_LOC(&c->dwarf, i); + } + for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) { + c->dwarf.loc[i] = DWARF_FPREG_LOC(&c->dwarf, i); + } + /* IP isn't a real register, it is encoded in the PSW */ + c->dwarf.loc[UNW_S390X_IP] = DWARF_REG_LOC(&c->dwarf, UNW_S390X_IP); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_IP], &c->dwarf.ip); + if (ret < 0) + return ret; + + /* Normally the CFA offset on s390x is biased, however this is taken + into account by the CFA offset in dwarf_step, so here we just mark + make it equal to the stack pointer. */ + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_S390X_R15), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = S390X_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + c->dwarf.eh_valid_mask = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c new file mode 100644 index 00000000000000..bc31f3e917011b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_is_fpreg (int regnum) +{ + /* vector registers? */ + return regnum >= UNW_S390X_F0 && regnum <= UNW_S390X_F15; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c b/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c new file mode 100644 index 00000000000000..2421b37ebb0d35 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + + Contributed by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + [UNW_S390X_R0]="R0", + [UNW_S390X_R1]="R1", + [UNW_S390X_R2]="R2", + [UNW_S390X_R3]="R3", + [UNW_S390X_R4]="R4", + [UNW_S390X_R5]="R5", + [UNW_S390X_R6]="R6", + [UNW_S390X_R7]="R7", + [UNW_S390X_R8]="R8", + [UNW_S390X_R9]="R9", + [UNW_S390X_R10]="R10", + [UNW_S390X_R11]="R11", + [UNW_S390X_R12]="R12", + [UNW_S390X_R13]="R13", + [UNW_S390X_R14]="R14", + [UNW_S390X_R15]="R15", + + [UNW_S390X_IP]="IP" + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S new file mode 100644 index 00000000000000..6cf55688aa436f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S @@ -0,0 +1,76 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 Google, Inc + Contributed by Paul Pluzhnikov + Copyright (C) 2010 Konstantin Belousov + Copyright (C) 2017 IBM + + Modified for s390x by Michael Munday + +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. */ + +// int _Us390x_setcontext (const ucontext_t *ucp) + + .global _Us390x_setcontext + .type _Us390x_setcontext, @function +_Us390x_setcontext: + .cfi_startproc + + // Must only restore registers saved by getcontext, other fields + // in the ucontext_t might be uninitialised. + + // Stop this function being unwound. We are clobbering callee-save + // registers in this function so unwinding it is unsafe. + // Ideally we'd save callee-save registers, update the CFI for them + // and then switch to the new CFI once the context switch is + // complete. + .cfi_undefined %r14 + + // floating point parameters + ld %f0,0x100(%r2) + ld %f2,0x110(%r2) + ld %f4,0x120(%r2) + ld %f6,0x130(%r2) + + // floating point preserved registers + lfpc 0xf8(%r2) + ld %f8,0x140(%r2) + ld %f9,0x148(%r2) + ld %f10,0x150(%r2) + ld %f11,0x158(%r2) + ld %f12,0x160(%r2) + ld %f13,0x168(%r2) + ld %f14,0x170(%r2) + ld %f15,0x178(%r2) + + // preserved registers and parameters + lgr %r1,%r2 + lmg %r2,%r15,0x48(%r1) + + // restore PSW address + lg %r1,0x30(%r1) + br %r1 + + .cfi_endproc + .size _Us390x_setcontext, . - _Us390x_setcontext + + // We do not need executable stack. + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h new file mode 100644 index 00000000000000..6e4b99baaa8dac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +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 unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" +#include + +#define s390x_lock UNW_OBJ(lock) +#define s390x_local_resume UNW_OBJ(local_resume) +#define s390x_local_addr_space_init UNW_OBJ(local_addr_space_init) +#define setcontext UNW_ARCH_OBJ(setcontext) + +extern void s390x_local_addr_space_init (void); +extern int s390x_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg); +extern int setcontext (const ucontext_t *ucp); + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/libunwind-setjmp.pc.in b/src/coreclr/src/pal/src/libunwind/src/setjmp/libunwind-setjmp.pc.in new file mode 100644 index 00000000000000..7b71126535b0e5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/setjmp/libunwind-setjmp.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libunwind-setjmp +Description: libunwind setjmp library +Version: @VERSION@ +Requires: libunwind +Libs: -L${libdir} -lunwind-setjmp +Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/longjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/longjmp.c new file mode 100644 index 00000000000000..8295a9b8ed40de --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/setjmp/longjmp.c @@ -0,0 +1,115 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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_LOCAL_ONLY + +#undef _FORTIFY_SOURCE +#include +#include +#include +#include +#include + +#include "jmpbuf.h" +#include "setjmp_i.h" + +#if defined(__GLIBC__) +#if __GLIBC_PREREQ(2, 4) + +/* Starting with glibc-2.4, {sig,}setjmp in GLIBC obfuscates the + register values in jmp_buf by XORing them with a "random" + canary value. + + This makes it impossible to implement longjmp, as we + can never match wp[JB_SP], unless we decode the canary first. + + Doing so is possible, but doesn't appear to be worth the trouble, + so we simply defer to glibc longjmp here. */ +#define _longjmp __nonworking__longjmp +#define longjmp __nonworking_longjmp +static void _longjmp (jmp_buf env, int val); +static void longjmp (jmp_buf env, int val); +#endif +#endif /* __GLIBC__ */ + +void +_longjmp (jmp_buf env, int val) +{ + extern int _UI_longjmp_cont; + unw_context_t uc; + unw_cursor_t c; + unw_word_t sp; + unw_word_t *wp = (unw_word_t *) env; + + if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0) + abort (); + + do + { + if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) + abort (); +#ifdef __FreeBSD__ + if (sp != wp[JB_SP] + sizeof(unw_word_t)) +#else + if (sp != wp[JB_SP]) +#endif + continue; + + if (!bsp_match (&c, wp)) + continue; + + /* found the right frame: */ + + assert (UNW_NUM_EH_REGS >= 2); + + if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0 + || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0 + || unw_set_reg (&c, UNW_REG_IP, + (unw_word_t) (uintptr_t) &_UI_longjmp_cont)) + abort (); + + unw_resume (&c); + + abort (); + } + while (unw_step (&c) > 0); + + abort (); +} + +#ifdef __GNUC__ +#define STRINGIFY1(x) #x +#define STRINGIFY(x) STRINGIFY1(x) +void longjmp (jmp_buf env, int val) + __attribute__ ((alias (STRINGIFY(_longjmp)))); +#else + +void +longjmp (jmp_buf env, int val) +{ + _longjmp (env, val); +} + +#endif /* __GNUC__ */ diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp.c new file mode 100644 index 00000000000000..bec9fc7d5bfad9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp.c @@ -0,0 +1,49 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "jmpbuf.h" + +/* Why use K&R syntax here? setjmp() is often a macro and that + expands into a call to, say, __setjmp() and we need to define the + libunwind-version of setjmp() with the name of the actual function. + Using K&R syntax lets us keep the setjmp() macro while keeping the + syntax valid... This trick works provided setjmp() doesn't do + anything other than a function call. */ + +int +setjmp (env) + jmp_buf env; +{ + void **wp = (void **) env; + + /* this should work on most platforms, but may not be + performance-optimal; check the code! */ + wp[JB_SP] = __builtin_frame_address (0); + wp[JB_RP] = (void *) __builtin_return_address (0); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp_i.h b/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp_i.h new file mode 100644 index 00000000000000..4d9139693ecfb7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/setjmp/setjmp_i.h @@ -0,0 +1,118 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +#if UNW_TARGET_IA64 + +#include "libunwind_i.h" +#include "tdep-ia64/rse.h" + +static inline int +bsp_match (unw_cursor_t *c, unw_word_t *wp) +{ + unw_word_t bsp, pfs, sol; + + if (unw_get_reg (c, UNW_IA64_BSP, &bsp) < 0 + || unw_get_reg (c, UNW_IA64_AR_PFS, &pfs) < 0) + abort (); + + /* simulate the effect of "br.call sigsetjmp" on ar.bsp: */ + sol = (pfs >> 7) & 0x7f; + bsp = rse_skip_regs (bsp, sol); + + if (bsp != wp[JB_BSP]) + return 0; + + if (unlikely (sol == 0)) + { + unw_word_t sp, prev_sp; + unw_cursor_t tmp = *c; + + /* The caller of {sig,}setjmp() cannot have a NULL-frame. If we + see a NULL-frame, we haven't reached the right target yet. + To have a NULL-frame, the number of locals must be zero and + the stack-frame must also be empty. */ + + if (unw_step (&tmp) < 0) + abort (); + + if (unw_get_reg (&tmp, UNW_REG_SP, &sp) < 0 + || unw_get_reg (&tmp, UNW_REG_SP, &prev_sp) < 0) + abort (); + + if (sp == prev_sp) + /* got a NULL-frame; keep looking... */ + return 0; + } + return 1; +} + +/* On ia64 we cannot always call sigprocmask() at + _UI_siglongjmp_cont() because the signal may have switched stacks + and the old stack's register-backing store may have overflown, + leaving us no space to allocate the stacked registers needed to + call sigprocmask(). Fortunately, we can just let unw_resume() (via + sigreturn) take care of restoring the signal-mask. That's faster + anyhow. */ +static inline int +resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp) +{ + unw_word_t sc_addr = ((struct cursor *) c)->sigcontext_addr; + struct sigcontext *sc = (struct sigcontext *) sc_addr; + sigset_t current_mask; + void *mp; + + if (!sc_addr) + return 0; + + /* let unw_resume() install the desired signal mask */ + + if (wp[JB_MASK_SAVED]) + mp = &wp[JB_MASK]; + else + { + if (sigprocmask (SIG_BLOCK, NULL, ¤t_mask) < 0) + abort (); + mp = ¤t_mask; + } + memcpy (&sc->sc_mask, mp, sizeof (sc->sc_mask)); + return 1; +} + +#else /* !UNW_TARGET_IA64 */ + +static inline int +bsp_match (unw_cursor_t *c, unw_word_t *wp) +{ + return 1; +} + +static inline int +resume_restores_sigmask (unw_cursor_t *c, unw_word_t *wp) +{ + /* We may want to do this analogously as for ia64... */ + return 0; +} + +#endif /* !UNW_TARGET_IA64 */ diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c new file mode 100644 index 00000000000000..dd330ce9e19db6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c @@ -0,0 +1,131 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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_LOCAL_ONLY + +#include + +#include "libunwind_i.h" +#include "jmpbuf.h" +#include "setjmp_i.h" + +#if !defined(_NSIG) +# if defined(_SIG_MAXSIG) +# define _NSIG (_SIG_MAXSIG - 1) +# elif defined(NSIG) +# define _NSIG NSIG +# endif +#endif + +#if defined(__GLIBC__) +#if __GLIBC_PREREQ(2, 4) + +/* Starting with glibc-2.4, {sig,}setjmp in GLIBC obfuscates the + register values in jmp_buf by XORing them with a "random" + canary value. + + This makes it impossible to implement longjmp, as we + can never match wp[JB_SP], unless we decode the canary first. + + Doing so is possible, but doesn't appear to be worth the trouble, + so we simply defer to glibc siglongjmp here. */ + +#define siglongjmp __nonworking_siglongjmp +static void siglongjmp (sigjmp_buf env, int val) UNUSED; +#endif +#endif /* __GLIBC_PREREQ */ + +void +siglongjmp (sigjmp_buf env, int val) +{ + unw_word_t *wp = (unw_word_t *) env; + extern int _UI_siglongjmp_cont; + extern int _UI_longjmp_cont; + unw_context_t uc; + unw_cursor_t c; + unw_word_t sp; + int *cont; + + if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0) + abort (); + + do + { + if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) + abort (); +#ifdef __FreeBSD__ + if (sp != wp[JB_SP] + sizeof(unw_word_t)) +#else + if (sp != wp[JB_SP]) +#endif + continue; + + if (!bsp_match (&c, wp)) + continue; + + /* found the right frame: */ + + /* default to resuming without restoring signal-mask */ + cont = &_UI_longjmp_cont; + + /* Order of evaluation is important here: if unw_resume() + restores signal mask, we must set it up appropriately, even + if wp[JB_MASK_SAVED] is FALSE. */ + if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED]) + { + /* sigmask was saved */ +#if defined(__linux__) || defined(__sun) + if (UNW_NUM_EH_REGS < 4 || _NSIG > 16 * sizeof (unw_word_t)) + /* signal mask doesn't fit into EH arguments and we can't + put it on the stack without overwriting something + else... */ + abort (); + else + if (unw_set_reg (&c, UNW_REG_EH + 2, wp[JB_MASK]) < 0 + || (_NSIG > 8 * sizeof (unw_word_t) + && unw_set_reg (&c, UNW_REG_EH + 3, wp[JB_MASK + 1]) < 0)) + abort (); +#elif defined(__FreeBSD__) + if (unw_set_reg (&c, UNW_REG_EH + 2, &wp[JB_MASK]) < 0) + abort(); +#else +#error Port me +#endif + cont = &_UI_siglongjmp_cont; + } + + if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0 + || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0 + || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) (uintptr_t) cont)) + abort (); + + unw_resume (&c); + + abort (); + } + while (unw_step (&c) > 0); + + abort (); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/sigsetjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/sigsetjmp.c new file mode 100644 index 00000000000000..f84935d638ac06 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/setjmp/sigsetjmp.c @@ -0,0 +1,50 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include + +#include "jmpbuf.h" + +int +sigsetjmp (sigjmp_buf env, int savemask) +{ + unw_word_t *wp = (unw_word_t *) env; + + /* This should work on most platforms, but may not be + performance-optimal; check the code! */ + + wp[JB_SP] = (unw_word_t) __builtin_frame_address (0); + wp[JB_RP] = (unw_word_t) __builtin_return_address (0); + wp[JB_MASK_SAVED] = savemask; + + /* Note: we assume here that "wp" has same or better alignment as + sigset_t. */ + if (savemask + && sigprocmask (SIG_BLOCK, NULL, (sigset_t *) (wp + JB_MASK)) < 0) + abort (); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gcreate_addr_space.c new file mode 100644 index 00000000000000..6ca3a384da0b7d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gcreate_addr_space.c @@ -0,0 +1,59 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* SH supports little-endian and big-endian. */ + if (byte_order != 0 && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + /* Default to little-endian for SH. */ + if (byte_order == 0 || byte_order == __LITTLE_ENDIAN) + as->big_endian = 0; + else + as->big_endian = 1; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gget_proc_info.c new file mode 100644 index 00000000000000..c363d2405d748a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gget_proc_info.c @@ -0,0 +1,39 @@ +/* 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. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = dwarf_make_proc_info (&c->dwarf); + if (ret < 0) + return ret; + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gget_save_loc.c new file mode 100644 index 00000000000000..24d9f63bc329d7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gget_save_loc.c @@ -0,0 +1,83 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + switch (reg) + { + case UNW_SH_R0: + case UNW_SH_R1: + case UNW_SH_R2: + case UNW_SH_R3: + case UNW_SH_R4: + case UNW_SH_R5: + case UNW_SH_R6: + case UNW_SH_R7: + case UNW_SH_R8: + case UNW_SH_R9: + case UNW_SH_R10: + case UNW_SH_R11: + case UNW_SH_R12: + case UNW_SH_R13: + case UNW_SH_R14: + case UNW_SH_R15: + case UNW_SH_PC: + case UNW_SH_PR: + loc = c->dwarf.loc[reg]; + break; + + default: + loc = DWARF_NULL_LOC; /* default to "not saved" */ + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gglobal.c new file mode 100644 index 00000000000000..ed2733397680f9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gglobal.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (sh_lock); +HIDDEN int tdep_init_done; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&sh_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + sh_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&sh_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c new file mode 100644 index 00000000000000..9fe96d2bd4d8eb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c @@ -0,0 +1,185 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + if (reg >= UNW_SH_R0 && reg <= UNW_SH_PR) + return &uc->uc_mcontext.gregs[reg]; + else + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (16, "mem[%x] <- %x\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + *val = *(unw_word_t *) addr; + Debug (16, "mem[%x] -> %x\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if (unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %x\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %x\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = arg; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +sh_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = sh_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c new file mode 100644 index 00000000000000..45631306bcd814 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c @@ -0,0 +1,78 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 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. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = uc; + + return common_init (c, use_prev_instr); +} + +int +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_remote.c new file mode 100644 index 00000000000000..9b8ba5b89def1a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_remote.c @@ -0,0 +1,45 @@ +/* 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. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gis_signal_frame.c new file mode 100644 index 00000000000000..4481fe1a498e11 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gis_signal_frame.c @@ -0,0 +1,119 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* Disassembly of the Linux VDSO sigreturn functions: + +00000000 <__kernel_sigreturn>: + 0: 05 93 mov.w e <__kernel_sigreturn+0xe>,r3 ! 77 + 2: 10 c3 trapa #16 + 4: 0b 20 or r0,r0 + 6: 0b 20 or r0,r0 + 8: 0b 20 or r0,r0 + a: 0b 20 or r0,r0 + c: 0b 20 or r0,r0 + e: 77 00 .word 0x0077 + 10: 09 00 nop + 12: 09 00 nop + 14: 09 00 nop + 16: 09 00 nop + 18: 09 00 nop + 1a: 09 00 nop + 1c: 09 00 nop + 1e: 09 00 nop + +00000020 <__kernel_rt_sigreturn>: + 20: 05 93 mov.w 2e <__kernel_rt_sigreturn+0xe>,r3 ! ad + 22: 10 c3 trapa #16 + 24: 0b 20 or r0,r0 + 26: 0b 20 or r0,r0 + 28: 0b 20 or r0,r0 + 2a: 0b 20 or r0,r0 + 2c: 0b 20 or r0,r0 + 2e: ad 00 mov.w @(r0,r10),r0 + 30: 09 00 nop + 32: 09 00 nop + 34: 09 00 nop + 36: 09 00 nop + 38: 09 00 nop + 3a: 09 00 nop + 3c: 09 00 nop + 3e: 09 00 nop +*/ + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + ret = (*a->access_mem) (as, ip, &w0, 0, arg); + if (ret < 0) + return ret; + + if (w0 != 0xc3109305) + return 0; + + ret = (*a->access_mem) (as, ip+4, &w0, 0, arg); + if (ret < 0) + return ret; + + if (w0 != 0x200b200b) + return 0; + + ret = (*a->access_mem) (as, ip+8, &w0, 0, arg); + if (ret < 0) + return ret; + + if (w0 != 0x200b200b) + return 0; + + ret = (*a->access_mem) (as, ip+12, &w0, 0, arg); + if (ret < 0) + return ret; + + if (w0 == 0x0077200b) + return 1; /* non-RT */ + else if (w0 == 0x00ad200b) + return 2; /* RT */ + + /* does not look like a signal frame */ + return 0; + +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/sh/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gregs.c new file mode 100644 index 00000000000000..7d8e8e93da0426 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gregs.c @@ -0,0 +1,81 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_SH_PC: + if (write) + c->dwarf.ip = *valp; /* update the IP cache */ + case UNW_SH_R0: + case UNW_SH_R1: + case UNW_SH_R2: + case UNW_SH_R3: + case UNW_SH_R4: + case UNW_SH_R5: + case UNW_SH_R6: + case UNW_SH_R7: + case UNW_SH_R8: + case UNW_SH_R9: + case UNW_SH_R10: + case UNW_SH_R11: + case UNW_SH_R12: + case UNW_SH_R13: + case UNW_SH_R14: + case UNW_SH_PR: + loc = c->dwarf.loc[reg]; + break; + + case UNW_SH_R15: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c new file mode 100644 index 00000000000000..5590bafa61242b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c @@ -0,0 +1,165 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_tdep_context_t *uc = c->dwarf.as_arg; + + if (c->sigcontext_format == SH_SCF_NONE) + { + /* Since there are no signals involved here we restore the non scratch + registers only. */ + unsigned long regs[8]; + regs[0] = uc->uc_mcontext.gregs[8]; + regs[1] = uc->uc_mcontext.gregs[9]; + regs[2] = uc->uc_mcontext.gregs[10]; + regs[3] = uc->uc_mcontext.gregs[11]; + regs[4] = uc->uc_mcontext.gregs[12]; + regs[5] = uc->uc_mcontext.gregs[13]; + regs[6] = uc->uc_mcontext.gregs[14]; + regs[7] = uc->uc_mcontext.gregs[15]; + unsigned long pc = uc->uc_mcontext.pr; + + struct regs_overlay { + char x[sizeof(regs)]; + }; + + __asm__ __volatile__ ( + "mov.l @%0+, r8\n" + "mov.l @%0+, r9\n" + "mov.l @%0+, r10\n" + "mov.l @%0+, r11\n" + "mov.l @%0+, r12\n" + "mov.l @%0+, r13\n" + "mov.l @%0+, r14\n" + "mov.l @%0, r15\n" + "lds %1, pr\n" + "rts\n" + "nop\n" + : + : "r" (regs), + "r" (pc), + "m" (*(struct regs_overlay *)regs) + ); + } + else + { + /* In case a signal frame is involved, we're using its trampoline which + calls sigreturn. */ + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + sc->sc_regs[0] = uc->uc_mcontext.gregs[0]; + sc->sc_regs[1] = uc->uc_mcontext.gregs[1]; + sc->sc_regs[2] = uc->uc_mcontext.gregs[2]; + sc->sc_regs[3] = uc->uc_mcontext.gregs[3]; + sc->sc_regs[4] = uc->uc_mcontext.gregs[4]; + sc->sc_regs[5] = uc->uc_mcontext.gregs[5]; + sc->sc_regs[6] = uc->uc_mcontext.gregs[6]; + sc->sc_regs[7] = uc->uc_mcontext.gregs[7]; + sc->sc_regs[8] = uc->uc_mcontext.gregs[8]; + sc->sc_regs[9] = uc->uc_mcontext.gregs[9]; + sc->sc_regs[10] = uc->uc_mcontext.gregs[10]; + sc->sc_regs[11] = uc->uc_mcontext.gregs[11]; + sc->sc_regs[12] = uc->uc_mcontext.gregs[12]; + sc->sc_regs[13] = uc->uc_mcontext.gregs[13]; + sc->sc_regs[14] = uc->uc_mcontext.gregs[14]; + sc->sc_regs[15] = uc->uc_mcontext.gregs[15]; + sc->sc_pc = uc->uc_mcontext.pc; + sc->sc_pr = uc->uc_mcontext.pr; + + /* Set the SP and the PC in order to continue execution at the modified + trampoline which restores the signal mask and the registers. */ + __asm__ __volatile__ ( + "mov %0, r15\n" + "lds %1, pr\n" + "rts\n" + "nop\n" + : + : "r" (c->sigcontext_sp), + "r" (c->sigcontext_pc) + ); + } + unreachable(); +#endif + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +static inline void +establish_machine_state (struct cursor *c) +{ + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + as->acc.access_fpreg (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + } +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + Debug (1, "(cursor=%p)\n", c); + + if (!c->dwarf.ip) + { + /* This can happen easily when the frame-chain gets truncated + due to bad or missing unwind-info. */ + Debug (1, "refusing to resume execution at address 0\n"); + return -UNW_EINVAL; + } + + establish_machine_state (c); + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gstep.c new file mode 100644 index 00000000000000..60d7ec2ba9f6e3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gstep.c @@ -0,0 +1,117 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +static int +sh_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + + ret = unw_is_signal_frame (cursor); + Debug(1, "unw_is_signal_frame()=%d\n", ret); + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + if (ret == 1) + { + /* Handle non-RT signal frame. */ + c->sigcontext_format = SH_SCF_LINUX_SIGFRAME; + sc_addr = sp_addr; + } + else if (ret == 2) + { + /* Handle RT signal frame. */ + c->sigcontext_format = SH_SCF_LINUX_RT_SIGFRAME; + sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + } + else + return -UNW_EUNSPEC; + + c->sigcontext_addr = sc_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + c->dwarf.loc[UNW_SH_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); + c->dwarf.loc[UNW_SH_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); + c->dwarf.loc[UNW_SH_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); + c->dwarf.loc[UNW_SH_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); + c->dwarf.loc[UNW_SH_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); + c->dwarf.loc[UNW_SH_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); + c->dwarf.loc[UNW_SH_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); + c->dwarf.loc[UNW_SH_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); + c->dwarf.loc[UNW_SH_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); + c->dwarf.loc[UNW_SH_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); + c->dwarf.loc[UNW_SH_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); + c->dwarf.loc[UNW_SH_R11] = DWARF_LOC (sc_addr + LINUX_SC_R11_OFF, 0); + c->dwarf.loc[UNW_SH_R12] = DWARF_LOC (sc_addr + LINUX_SC_R12_OFF, 0); + c->dwarf.loc[UNW_SH_R13] = DWARF_LOC (sc_addr + LINUX_SC_R13_OFF, 0); + c->dwarf.loc[UNW_SH_R14] = DWARF_LOC (sc_addr + LINUX_SC_R14_OFF, 0); + c->dwarf.loc[UNW_SH_R15] = DWARF_LOC (sc_addr + LINUX_SC_R15_OFF, 0); + c->dwarf.loc[UNW_SH_PR] = DWARF_LOC (sc_addr + LINUX_SC_PR_OFF, 0); + c->dwarf.loc[UNW_SH_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_R15], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_PC], &c->dwarf.ip); + + c->dwarf.pi_valid = 0; + + return 1; +} + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if (unw_is_signal_frame (cursor) > 0) + return sh_handle_signal_frame (cursor); + + ret = dwarf_step (&c->dwarf); + + if (unlikely (ret == -UNW_ESTOPUNWIND)) + return ret; + + if (unlikely (ret < 0)) + return 0; + + return (c->dwarf.ip == 0) ? 0 : 1; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lglobal.c new file mode 100644 index 00000000000000..6d7b489e14bd9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Linit.c b/src/coreclr/src/pal/src/libunwind/src/sh/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/sh/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/sh/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lis_signal_frame.c new file mode 100644 index 00000000000000..b9a7c4f51ad9fa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/sh/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/gen-offsets.c b/src/coreclr/src/pal/src/libunwind/src/sh/gen-offsets.c new file mode 100644 index 00000000000000..16695a64896fc9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/gen-offsets.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +#define UC(N,X) \ + printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) + +#define SC(N,X) \ + printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) + +int +main (void) +{ + printf ( +"/* Linux-specific definitions: */\n\n" + +"/* Define various structure offsets to simplify cross-compilation. */\n\n" + +"/* Offsets for SH Linux \"ucontext_t\": */\n\n"); + + UC ("FLAGS", uc_flags); + UC ("LINK", uc_link); + UC ("STACK", uc_stack); + UC ("MCONTEXT", uc_mcontext); + UC ("SIGMASK", uc_sigmask); + + printf ("\n/* Offsets for SH Linux \"struct sigcontext\": */\n\n"); + + SC ("R0", sc_regs[0]); + SC ("R1", sc_regs[1]); + SC ("R2", sc_regs[2]); + SC ("R3", sc_regs[3]); + SC ("R4", sc_regs[4]); + SC ("R5", sc_regs[5]); + SC ("R6", sc_regs[6]); + SC ("R7", sc_regs[7]); + SC ("R8", sc_regs[8]); + SC ("R9", sc_regs[9]); + SC ("R10", sc_regs[10]); + SC ("R11", sc_regs[11]); + SC ("R12", sc_regs[12]); + SC ("R13", sc_regs[13]); + SC ("R14", sc_regs[14]); + SC ("R15", sc_regs[15]); + + SC ("PC", sc_pc); + SC ("PR", sc_pr); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/init.h b/src/coreclr/src/pal/src/libunwind/src/sh/init.h new file mode 100644 index 00000000000000..36713fe89b0c04 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/init.h @@ -0,0 +1,73 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + + c->dwarf.loc[UNW_SH_R0] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R0); + c->dwarf.loc[UNW_SH_R1] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R1); + c->dwarf.loc[UNW_SH_R2] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R2); + c->dwarf.loc[UNW_SH_R3] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R3); + c->dwarf.loc[UNW_SH_R4] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R4); + c->dwarf.loc[UNW_SH_R5] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R5); + c->dwarf.loc[UNW_SH_R6] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R6); + c->dwarf.loc[UNW_SH_R7] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R7); + c->dwarf.loc[UNW_SH_R8] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R8); + c->dwarf.loc[UNW_SH_R9] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R9); + c->dwarf.loc[UNW_SH_R10] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R10); + c->dwarf.loc[UNW_SH_R11] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R11); + c->dwarf.loc[UNW_SH_R12] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R12); + c->dwarf.loc[UNW_SH_R13] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R13); + c->dwarf.loc[UNW_SH_R14] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R14); + c->dwarf.loc[UNW_SH_R15] = DWARF_REG_LOC (&c->dwarf, UNW_SH_R15); + c->dwarf.loc[UNW_SH_PC] = DWARF_REG_LOC (&c->dwarf, UNW_SH_PC); + c->dwarf.loc[UNW_SH_PR] = DWARF_REG_LOC (&c->dwarf, UNW_SH_PR); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_PC], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TDEP_SP], &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = SH_SCF_NONE; + c->sigcontext_addr = 0; + c->sigcontext_sp = 0; + c->sigcontext_pc = 0; + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/sh/is_fpreg.c new file mode 100644 index 00000000000000..de0934019413ec --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/is_fpreg.c @@ -0,0 +1,32 @@ +/* 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. */ + +#include "libunwind_i.h" + +int +unw_is_fpreg (int regnum) +{ + /* FIXME: Support FP. */ + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/offsets.h b/src/coreclr/src/pal/src/libunwind/src/sh/offsets.h new file mode 100644 index 00000000000000..b02d8aee1e0008 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/offsets.h @@ -0,0 +1,32 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* Offsets for SH Linux "ucontext_t": */ + +#define LINUX_UC_FLAGS_OFF 0x0 +#define LINUX_UC_LINK_OFF 0x4 +#define LINUX_UC_STACK_OFF 0x8 +#define LINUX_UC_MCONTEXT_OFF 0x14 +#define LINUX_UC_SIGMASK_OFF 0xFC + +/* Offsets for SH Linux "struct sigcontext": */ + +#define LINUX_SC_R0_OFF 0x4 +#define LINUX_SC_R1_OFF 0x8 +#define LINUX_SC_R2_OFF 0xC +#define LINUX_SC_R3_OFF 0x10 +#define LINUX_SC_R4_OFF 0x14 +#define LINUX_SC_R5_OFF 0x18 +#define LINUX_SC_R6_OFF 0x1C +#define LINUX_SC_R7_OFF 0x20 +#define LINUX_SC_R8_OFF 0x24 +#define LINUX_SC_R9_OFF 0x28 +#define LINUX_SC_R10_OFF 0x2C +#define LINUX_SC_R11_OFF 0x30 +#define LINUX_SC_R12_OFF 0x34 +#define LINUX_SC_R13_OFF 0x38 +#define LINUX_SC_R14_OFF 0x3C +#define LINUX_SC_R15_OFF 0x40 +#define LINUX_SC_PC_OFF 0x44 +#define LINUX_SC_PR_OFF 0x48 diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/regname.c b/src/coreclr/src/pal/src/libunwind/src/sh/regname.c new file mode 100644 index 00000000000000..b52925b4da7ec4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/regname.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *const regname[] = + { + [UNW_SH_R0] = "r0", + [UNW_SH_R1] = "r1", + [UNW_SH_R2] = "r2", + [UNW_SH_R3] = "r3", + [UNW_SH_R4] = "r4", + [UNW_SH_R5] = "r5", + [UNW_SH_R6] = "r6", + [UNW_SH_R7] = "r7", + [UNW_SH_R8] = "r8", + [UNW_SH_R9] = "r9", + [UNW_SH_R10] = "r10", + [UNW_SH_R11] = "r11", + [UNW_SH_R12] = "r12", + [UNW_SH_R13] = "r13", + [UNW_SH_R14] = "r14", + [UNW_SH_R15] = "r15", + [UNW_SH_PC] = "pc", + [UNW_SH_PR] = "pr", + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname) && regname[reg] != NULL) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/sh/siglongjmp.S new file mode 100644 index 00000000000000..9ca53d124b98d1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/siglongjmp.S @@ -0,0 +1,8 @@ + /* Dummy implementation for now. */ + + .globl _UI_siglongjmp_cont + .globl _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + rts diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/sh/unwind_i.h new file mode 100644 index 00000000000000..3066d84631e96b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/sh/unwind_i.h @@ -0,0 +1,40 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +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 unwind_i_h +#define unwind_i_h + +#include + +#include "libunwind_i.h" + +#define sh_lock UNW_OBJ(lock) +#define sh_local_resume UNW_OBJ(local_resume) +#define sh_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern void sh_local_addr_space_init (void); +extern int sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gcreate_addr_space.c new file mode 100644 index 00000000000000..39acdc2c3d3abb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gcreate_addr_space.c @@ -0,0 +1,65 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as = malloc (sizeof (*as)); + + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + /* + * Tilegx supports only big or little-endian, not weird stuff like + * PDP_ENDIAN. + */ + if (byte_order != 0 + && byte_order != __LITTLE_ENDIAN + && byte_order != __BIG_ENDIAN) + return NULL; + + if (byte_order == 0) + /* use host default: */ + as->big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + else + as->big_endian = (byte_order == __BIG_ENDIAN); + + as->abi = UNW_TILEGX_ABI_N64; + as->addr_size = 8; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_proc_info.c new file mode 100644 index 00000000000000..3a158da2df7aa6 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_proc_info.c @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + ret = dwarf_make_proc_info (&c->dwarf); + + if (ret < 0) + { + /* On Tilegx, some routines i.e. _start() etc has no dwarf info. + Just simply mark the end of the frames. */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 1; + return 0; + } + + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_save_loc.c new file mode 100644 index 00000000000000..fcf0697892880b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gget_save_loc.c @@ -0,0 +1,62 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + if (reg <= UNW_TILEGX_R55) + loc = c->dwarf.loc[reg - UNW_TILEGX_R0]; + else + printf("\nInvalid register!"); + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gglobal.c new file mode 100644 index 00000000000000..e18f50a50f3b3e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gglobal.c @@ -0,0 +1,64 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +__attribute__((weak)) +pthread_mutex_t tilegx_lock = PTHREAD_MUTEX_INITIALIZER; +HIDDEN int tdep_init_done; + +HIDDEN const uint8_t dwarf_to_unw_regnum_map[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55 + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&tilegx_lock, saved_mask); + + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + tilegx_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + + out: + lock_release (&tilegx_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c new file mode 100644 index 00000000000000..925e6413246bed --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c @@ -0,0 +1,166 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +/* Return the address of the 64-bit slot in UC for REG (even for o32, + where registers are 32-bit, the slots are still 64-bit). */ + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + if (reg >= UNW_TILEGX_R0 && reg < UNW_TILEGX_R0 + 56) + return &uc->uc_mcontext.gregs[reg - UNW_TILEGX_R0]; + else if (reg == UNW_TILEGX_PC) + return &uc->uc_mcontext.pc; + else + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + char *addr = uc_addr (uc, reg); + return addr; +} + +# endif /* UNW_LOCAL_ONLY */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if ((long long)addr & (sizeof(unw_word_t) - 1)) + return 0; + + if (write) + { + Debug (16, "mem[%llx] <- %llx\n", (long long) addr, (long long) *val); + *(unw_word_t *) (intptr_t) addr = *val; + } + else + { + *val = *(unw_word_t *) (intptr_t) addr; + Debug (16, "mem[%llx] -> %llx\n", (long long) addr, (long long) *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = arg; + + if (unw_is_fpreg (reg)) + goto badreg; + + Debug (16, "reg = %s\n", unw_regname (reg)); + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) (intptr_t) addr = (tilegx_reg_t) *val; + Debug (12, "%s <- %llx\n", unw_regname (reg), (long long) *val); + } + else + { + *val = (tilegx_reg_t) *(unw_word_t *) (intptr_t) addr; + Debug (12, "%s -> %llx\n", unw_regname (reg), (long long) *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp); +} + +__attribute__((weak)) void +tilegx_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + + local_addr_space.abi = UNW_TILEGX_ABI_N64; + local_addr_space.addr_size = sizeof (void *); + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = NULL; + local_addr_space.acc.resume = tilegx_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_local.c new file mode 100644 index 00000000000000..31a716df348e3b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_local.c @@ -0,0 +1,80 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + memset(c, 0, sizeof(unw_cursor_t)); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + + c->dwarf.as_arg = uc; + return common_init (c, use_prev_instr); +} + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_remote.c new file mode 100644 index 00000000000000..2a31b18aaef78d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit_remote.c @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gis_signal_frame.c new file mode 100644 index 00000000000000..5452c2cb2aaf1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gis_signal_frame.c @@ -0,0 +1,115 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include +#include "offsets.h" + +#ifdef __linux__ +#include +#include +#else +# error "Only support Linux!" +#endif + +#define MOVELI_R10_RT_SIGRETURN \ + ( 0x000007e051483000ULL | \ + ((unsigned long)__NR_rt_sigreturn << 43) | \ + ((unsigned long)TREG_SYSCALL_NR << 31) ) +#define SWINT1 0x286b180051485000ULL + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor*) cursor; + unw_word_t w0, w1, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + if (!ip || !a->access_mem || (ip & (sizeof(unw_word_t) - 1))) + return 0; + + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) + return ret; + + if ((ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0) + return ret; + + /* Return 1 if the IP points to a RT sigreturn sequence. */ + if (w0 == MOVELI_R10_RT_SIGRETURN && + w1 == SWINT1) + { + return 1; + } + return 0; +} + + +HIDDEN int +tilegx_handle_signal_frame (unw_cursor_t *cursor) +{ + int i; + struct cursor *c = (struct cursor *) cursor; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + int ret; + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + c->sigcontext_addr = sp_addr + sizeof (siginfo_t) + + C_ABI_SAVE_AREA_SIZE; + sc_addr = c->sigcontext_addr + LINUX_UC_MCONTEXT_OFF; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + +#define SC_REG_OFFSET(X) (8 * X) + + for (i = UNW_TILEGX_R0; i <= UNW_TILEGX_R55; i++) + { + c->dwarf.loc[i] = DWARF_LOC (sc_addr + SC_REG_OFFSET(i), 0); + } + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TILEGX_R54], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_TILEGX_R55], &c->dwarf.ip); + + return 1; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gregs.c new file mode 100644 index 00000000000000..565c6f4432a28e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gregs.c @@ -0,0 +1,76 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + if (reg == UNW_TILEGX_R54 && !write) + { + reg = UNW_TILEGX_CFA; + } + + if (reg <= UNW_TILEGX_R55) + loc = c->dwarf.loc[reg - UNW_TILEGX_R0]; + else if (reg == UNW_TILEGX_CFA) + { + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + } + else + { + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + { + if (ci->dwarf.use_prev_instr == 0) { + if (reg == UNW_TILEGX_PC) + c->dwarf.ip = *valp; /* update the IP cache */ + } + else { + if (reg == UNW_TILEGX_R55) + c->dwarf.ip = *valp; /* update the IP cache */ + } + return dwarf_put (&c->dwarf, loc, *valp); + } + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gresume.c new file mode 100644 index 00000000000000..ece443a5b56fc9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gresume.c @@ -0,0 +1,94 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + +#include "unwind_i.h" +#include "offsets.h" +#include + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +tilegx_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + int i; + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = c->dwarf.as_arg; + + Debug (1, "(cursor=%p\n", c); + + return setcontext(uc); +} + +#endif /* !UNW_REMOTE_ONLY */ + +static inline void +establish_machine_state (struct cursor *c) +{ + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + + if (unw_is_fpreg (reg)) + { + Debug (1, "no fp!"); + abort (); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + as->acc.access_reg (as, reg, &val, 1, arg); + } + } +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + Debug (1, "(cursor=%p) ip=0x%lx\n", c, c->dwarf.ip); + + if (!c->dwarf.ip) + { + /* This can happen easily when the frame-chain gets truncated + due to bad or missing unwind-info. */ + Debug (1, "refusing to resume execution at address 0\n"); + return -UNW_EINVAL; + } + + establish_machine_state (c); + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gstep.c new file mode 100644 index 00000000000000..c748dbc588a856 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Gstep.c @@ -0,0 +1,53 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p, ip=0x%016lx, sp=0x%016lx)\n", + c, c->dwarf.ip, c->dwarf.cfa); + + /* Special handling the singal frame. */ + if (unw_is_signal_frame (cursor) > 0) + return tilegx_handle_signal_frame (cursor); + + /* Try DWARF-based unwinding... */ + ret = dwarf_step (&c->dwarf); + + if (unlikely (ret == -UNW_ESTOPUNWIND)) + return ret; + + /* Dwarf unwinding didn't work, stop. */ + if (unlikely (ret < 0)) + return 0; + + return (c->dwarf.ip == 0) ? 0 : 1; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lglobal.c new file mode 100644 index 00000000000000..6d7b489e14bd9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lis_signal_frame.c new file mode 100644 index 00000000000000..b9a7c4f51ad9fa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/elfxx.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/elfxx.c new file mode 100644 index 00000000000000..07d3d12b94fe00 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/elfxx.c @@ -0,0 +1,27 @@ +/* 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. */ + +#include "libunwind_i.h" + +#include "../src/elfxx.c" diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/gen-offsets.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/gen-offsets.c new file mode 100644 index 00000000000000..8704bb215e3cb7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/gen-offsets.c @@ -0,0 +1,30 @@ +#include +#include +#include + +#define UC(N,X) \ + printf ("#define LINUX_UC_" N "_OFF\t0x%X\n", offsetof (ucontext_t, X)) + +#define SC(N,X) \ + printf ("#define LINUX_SC_" N "_OFF\t0x%X\n", offsetof (struct sigcontext, X)) + +int +main (void) +{ + printf ( +"/* Linux-specific definitions: */\n\n" + +"/* Define various structure offsets to simplify cross-compilation. */\n\n" + +"/* Offsets for TILEGX Linux \"ucontext_t\": */\n\n"); + + UC ("FLAGS", uc_flags); + UC ("LINK", uc_link); + UC ("STACK", uc_stack); + UC ("MCONTEXT", uc_mcontext); + UC ("SIGMASK", uc_sigmask); + + UC ("MCONTEXT_GREGS", uc_mcontext.gregs); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/tilegx/getcontext.S new file mode 100644 index 00000000000000..fbc8654bc7f1f9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/getcontext.S @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include + + .text + # define REG(X) LINUX_UC_MCONTEXT_GREGS + 8 * (X) + .global _Utilegx_getcontext + .type _Utilegx_getcontext, %function + # This is a stub version of getcontext() for TILEGX. +_Utilegx_getcontext: + + diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/init.h b/src/coreclr/src/pal/src/libunwind/src/tilegx/init.h new file mode 100644 index 00000000000000..0e0f7fd1da819c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/init.h @@ -0,0 +1,63 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret, i; + + for (i = 0; i < 56; i++) + c->dwarf.loc[i] = DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R0 + i); + for (i = 56; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + if (use_prev_instr == 0) + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_PC), + &c->dwarf.ip); + else + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R55), + &c->dwarf.ip); + + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_TILEGX_R54), + &c->dwarf.cfa); + + if (ret < 0) + return ret; + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/is_fpreg.c new file mode 100644 index 00000000000000..d6d58969018882 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/is_fpreg.c @@ -0,0 +1,33 @@ +/* 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. */ + +#include "libunwind_i.h" + +/* TILEGX has no FP. */ + +int +unw_is_fpreg (int regnum) +{ + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/offsets.h b/src/coreclr/src/pal/src/libunwind/src/tilegx/offsets.h new file mode 100644 index 00000000000000..6d30f1edcff1ef --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/offsets.h @@ -0,0 +1,12 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* Offsets for TILEGX Linux "ucontext_t": */ + +#define LINUX_UC_FLAGS_OFF 0x0 +#define LINUX_UC_LINK_OFF 0x8 +#define LINUX_UC_STACK_OFF 0x10 +#define LINUX_UC_MCONTEXT_OFF 0x28 +#define LINUX_UC_SIGMASK_OFF 0x228 +#define LINUX_UC_MCONTEXT_GREGS 0x28 diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/regname.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/regname.c new file mode 100644 index 00000000000000..0ce47b9d66ed85 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/regname.c @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2014 Tilera Corp. + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + /* 0. */ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + /* 8. */ + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + /* 16. */ + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + /* 24. */ + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + /* 32. */ + "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", + /* 40. */ + "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", + /* 48. */ + "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", + /* pc, cfa */ + "pc", "cfa" + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/tilegx/siglongjmp.S new file mode 100644 index 00000000000000..bccb1c77854339 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/siglongjmp.S @@ -0,0 +1,7 @@ + /* Dummy implementation for now. */ + .globl _UI_siglongjmp_cont + .globl _UI_longjmp_cont + +_UI_siglongjmp_cont: +_UI_longjmp_cont: + jrp lr diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/tilegx/unwind_i.h new file mode 100644 index 00000000000000..9d41c90b4d10bc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/unwind_i.h @@ -0,0 +1,46 @@ +/* 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 unwind_i_h +#define unwind_i_h + +#include +#include + +#include + +#include "libunwind_i.h" + +#define tilegx_local_resume UNW_OBJ(local_resume) +#define tilegx_local_addr_space_init UNW_OBJ(local_addr_space_init) + +extern int tilegx_local_resume (unw_addr_space_t as, + unw_cursor_t *cursor, + void *arg); +#define tilegx_handle_signal_frame UNW_OBJ(handle_signal_frame) +extern int tilegx_handle_signal_frame(unw_cursor_t *cursor); + +extern void tilegx_local_addr_space_init (void); + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/Backtrace.c b/src/coreclr/src/pal/src/libunwind/src/unwind/Backtrace.c new file mode 100644 index 00000000000000..0b14df4cb9da60 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/Backtrace.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +_Unwind_Reason_Code +_Unwind_Backtrace (_Unwind_Trace_Fn trace, void *trace_parameter) +{ + struct _Unwind_Context context; + unw_context_t uc; + int ret; + + if (_Unwind_InitContext (&context, &uc) < 0) + return _URC_FATAL_PHASE1_ERROR; + + /* Phase 1 (search phase) */ + + while (1) + { + if ((ret = unw_step (&context.cursor)) <= 0) + { + if (ret == 0) + return _URC_END_OF_STACK; + else + return _URC_FATAL_PHASE1_ERROR; + } + + if ((*trace) (&context, trace_parameter) != _URC_NO_REASON) + return _URC_FATAL_PHASE1_ERROR; + } +} + +_Unwind_Reason_Code __libunwind_Unwind_Backtrace (_Unwind_Trace_Fn, void *) + ALIAS (_Unwind_Backtrace); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/DeleteException.c b/src/coreclr/src/pal/src/libunwind/src/unwind/DeleteException.c new file mode 100644 index 00000000000000..ad38eaf651e063 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/DeleteException.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +void +_Unwind_DeleteException (struct _Unwind_Exception *exception_object) +{ + _Unwind_Exception_Cleanup_Fn cleanup = exception_object->exception_cleanup; + + if (cleanup) + (*cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exception_object); +} + +void __libunwind_Unwind_DeleteException (struct _Unwind_Exception *) + ALIAS (_Unwind_DeleteException); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/FindEnclosingFunction.c b/src/coreclr/src/pal/src/libunwind/src/unwind/FindEnclosingFunction.c new file mode 100644 index 00000000000000..4f106661725f28 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/FindEnclosingFunction.c @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +void * +_Unwind_FindEnclosingFunction (void *ip) +{ + unw_proc_info_t pi; + + if (unw_get_proc_info_by_ip (unw_local_addr_space, + (unw_word_t) (uintptr_t) ip, &pi, 0) + < 0) + return NULL; + + return (void *) (uintptr_t) pi.start_ip; +} + +void *__libunwind_Unwind_FindEnclosingFunction (void *) + ALIAS (_Unwind_FindEnclosingFunction); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/ForcedUnwind.c b/src/coreclr/src/pal/src/libunwind/src/unwind/ForcedUnwind.c new file mode 100644 index 00000000000000..905b31cd873508 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/ForcedUnwind.c @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +_Unwind_Reason_Code +_Unwind_ForcedUnwind (struct _Unwind_Exception *exception_object, + _Unwind_Stop_Fn stop, void *stop_parameter) +{ + struct _Unwind_Context context; + unw_context_t uc; + + /* We check "stop" here to tell the compiler's inliner that + exception_object->private_1 isn't NULL when calling + _Unwind_Phase2(). */ + if (!stop) + return _URC_FATAL_PHASE2_ERROR; + + if (_Unwind_InitContext (&context, &uc) < 0) + return _URC_FATAL_PHASE2_ERROR; + + exception_object->private_1 = (unsigned long) stop; + exception_object->private_2 = (unsigned long) stop_parameter; + + return _Unwind_Phase2 (exception_object, &context); +} + +_Unwind_Reason_Code __libunwind_Unwind_ForcedUnwind (struct _Unwind_Exception*, + _Unwind_Stop_Fn, void *) + ALIAS (_Unwind_ForcedUnwind); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetBSP.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetBSP.c new file mode 100644 index 00000000000000..d1bc84e0d20f84 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/GetBSP.c @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +unsigned long +_Unwind_GetBSP (struct _Unwind_Context *context) +{ +#ifdef UNW_TARGET_IA64 + unw_word_t val; + + unw_get_reg (&context->cursor, UNW_IA64_BSP, &val); + return val; +#else + return 0; +#endif +} + +unsigned long __libunwind_Unwind_GetBSP (struct _Unwind_Context *) + ALIAS (_Unwind_GetBSP); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetCFA.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetCFA.c new file mode 100644 index 00000000000000..5ca63903dda0dd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/GetCFA.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +unsigned long +_Unwind_GetCFA (struct _Unwind_Context *context) +{ + unw_word_t val; + + unw_get_reg (&context->cursor, UNW_REG_SP, &val); + return val; +} + +unsigned long __libunwind_Unwind_GetCFA (struct _Unwind_Context *) + ALIAS (_Unwind_GetCFA); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetDataRelBase.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetDataRelBase.c new file mode 100644 index 00000000000000..8e6914f4f35415 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/GetDataRelBase.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +unsigned long +_Unwind_GetDataRelBase (struct _Unwind_Context *context) +{ + unw_proc_info_t pi; + + pi.gp = 0; + unw_get_proc_info (&context->cursor, &pi); + return pi.gp; +} + +unsigned long __libunwind_Unwind_GetDataRelBase (struct _Unwind_Context *) + ALIAS (_Unwind_GetDataRelBase); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetGR.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetGR.c new file mode 100644 index 00000000000000..fa709434353f62 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/GetGR.c @@ -0,0 +1,43 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +unsigned long +_Unwind_GetGR (struct _Unwind_Context *context, int index) +{ + unw_word_t val; + + if (index == UNW_REG_SP && context->end_of_stack) + /* _Unwind_ForcedUnwind() requires us to return a NULL + stack-pointer after reaching the end of the stack. */ + return 0; + + unw_get_reg (&context->cursor, index, &val); + return val; +} + +unsigned long __libunwind_Unwind_GetGR (struct _Unwind_Context *, int) + ALIAS (_Unwind_GetGR); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetIP.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetIP.c new file mode 100644 index 00000000000000..e9fc4944025de4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/GetIP.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +unsigned long +_Unwind_GetIP (struct _Unwind_Context *context) +{ + unw_word_t val; + + unw_get_reg (&context->cursor, UNW_REG_IP, &val); + return val; +} + +unsigned long __libunwind_Unwind_GetIP (struct _Unwind_Context *) + ALIAS (_Unwind_GetIP); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetIPInfo.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetIPInfo.c new file mode 100644 index 00000000000000..e8ee7fd7f1b1ca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/GetIPInfo.c @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2009 Red Hat + Contributed by Jan Kratochvil + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +/* gcc/unwind-dw2.c: Retrieve the return address and flag whether that IP is + before or after first not yet fully executed instruction. */ + +unsigned long +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) +{ + unw_word_t val; + + unw_get_reg (&context->cursor, UNW_REG_IP, &val); + *ip_before_insn = unw_is_signal_frame (&context->cursor); + return val; +} + +unsigned long __libunwind_Unwind_GetIPInfo (struct _Unwind_Context *, int *) + ALIAS (_Unwind_GetIPInfo); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetLanguageSpecificData.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetLanguageSpecificData.c new file mode 100644 index 00000000000000..e7ca9b453c388b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/GetLanguageSpecificData.c @@ -0,0 +1,40 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +unsigned long +_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context) +{ + unw_proc_info_t pi; + + pi.lsda = 0; + unw_get_proc_info (&context->cursor, &pi); + return pi.lsda; +} + +unsigned long +__libunwind_Unwind_GetLanguageSpecificData (struct _Unwind_Context *) + ALIAS (_Unwind_GetLanguageSpecificData); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetRegionStart.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetRegionStart.c new file mode 100644 index 00000000000000..f4995813face3d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/GetRegionStart.c @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +unsigned long +_Unwind_GetRegionStart (struct _Unwind_Context *context) +{ + unw_proc_info_t pi; + + pi.start_ip = 0; + unw_get_proc_info (&context->cursor, &pi); + return pi.start_ip; +} + +unsigned long __libunwind_Unwind_GetRegionStart (struct _Unwind_Context *) + ALIAS (_Unwind_GetRegionStart); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/GetTextRelBase.c b/src/coreclr/src/pal/src/libunwind/src/unwind/GetTextRelBase.c new file mode 100644 index 00000000000000..ce65ae93e77d8f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/GetTextRelBase.c @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +unsigned long +_Unwind_GetTextRelBase (struct _Unwind_Context *context) +{ + return 0; +} + +unsigned long __libunwind_Unwind_GetTextRelBase (struct _Unwind_Context *) + ALIAS (_Unwind_GetTextRelBase); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/RaiseException.c b/src/coreclr/src/pal/src/libunwind/src/unwind/RaiseException.c new file mode 100644 index 00000000000000..3c3ca19e989f68 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/RaiseException.c @@ -0,0 +1,103 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +_Unwind_Reason_Code +_Unwind_RaiseException (struct _Unwind_Exception *exception_object) +{ + uint64_t exception_class = exception_object->exception_class; + _Unwind_Personality_Fn personality; + struct _Unwind_Context context; + _Unwind_Reason_Code reason; + unw_proc_info_t pi; + unw_context_t uc; + unw_word_t ip; + int ret; + + Debug (1, "(exception_object=%p)\n", exception_object); + + if (_Unwind_InitContext (&context, &uc) < 0) + return _URC_FATAL_PHASE1_ERROR; + + /* Phase 1 (search phase) */ + + while (1) + { + if ((ret = unw_step (&context.cursor)) <= 0) + { + if (ret == 0) + { + Debug (1, "no handler found\n"); + return _URC_END_OF_STACK; + } + else + return _URC_FATAL_PHASE1_ERROR; + } + + if (unw_get_proc_info (&context.cursor, &pi) < 0) + return _URC_FATAL_PHASE1_ERROR; + + personality = (_Unwind_Personality_Fn) (uintptr_t) pi.handler; + if (personality) + { + reason = (*personality) (_U_VERSION, _UA_SEARCH_PHASE, + exception_class, exception_object, + &context); + if (reason != _URC_CONTINUE_UNWIND) + { + if (reason == _URC_HANDLER_FOUND) + break; + else + { + Debug (1, "personality returned %d\n", reason); + return _URC_FATAL_PHASE1_ERROR; + } + } + } + } + + /* Exceptions are associated with IP-ranges. If a given exception + is handled at a particular IP, it will _always_ be handled at + that IP. If this weren't true, we'd have to track the tuple + (IP,SP,BSP) to uniquely identify the stack frame that's handling + the exception. */ + if (unw_get_reg (&context.cursor, UNW_REG_IP, &ip) < 0) + return _URC_FATAL_PHASE1_ERROR; + exception_object->private_1 = 0; /* clear "stop" pointer */ + exception_object->private_2 = ip; /* save frame marker */ + + Debug (1, "found handler for IP=%lx; entering cleanup phase\n", (long) ip); + + /* Reset the cursor to the first frame: */ + if (unw_init_local (&context.cursor, &uc) < 0) + return _URC_FATAL_PHASE1_ERROR; + + return _Unwind_Phase2 (exception_object, &context); +} + +_Unwind_Reason_Code +__libunwind_Unwind_RaiseException (struct _Unwind_Exception *) + ALIAS (_Unwind_RaiseException); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/Resume.c b/src/coreclr/src/pal/src/libunwind/src/unwind/Resume.c new file mode 100644 index 00000000000000..e23d6be27cf8da --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/Resume.c @@ -0,0 +1,42 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +void +_Unwind_Resume (struct _Unwind_Exception *exception_object) +{ + struct _Unwind_Context context; + unw_context_t uc; + + if (_Unwind_InitContext (&context, &uc) < 0) + abort (); + + _Unwind_Phase2 (exception_object, &context); + abort (); +} + +void __libunwind_Unwind_Resume (struct _Unwind_Exception *) + ALIAS (_Unwind_Resume); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/Resume_or_Rethrow.c b/src/coreclr/src/pal/src/libunwind/src/unwind/Resume_or_Rethrow.c new file mode 100644 index 00000000000000..9c76443b365acc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/Resume_or_Rethrow.c @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +_Unwind_Reason_Code +_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exception_object) +{ + struct _Unwind_Context context; + unw_context_t uc; + + if (exception_object->private_1) + { + if (_Unwind_InitContext (&context, &uc) < 0) + return _URC_FATAL_PHASE2_ERROR; + + return _Unwind_Phase2 (exception_object, &context); + } + else + return _Unwind_RaiseException (exception_object); +} + +_Unwind_Reason_Code +__libunwind_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *) + ALIAS (_Unwind_Resume_or_Rethrow); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/SetGR.c b/src/coreclr/src/pal/src/libunwind/src/unwind/SetGR.c new file mode 100644 index 00000000000000..ae77a8e8258e84 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/SetGR.c @@ -0,0 +1,47 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" +#ifdef UNW_TARGET_X86 +#include "dwarf_i.h" +#endif + +void +_Unwind_SetGR (struct _Unwind_Context *context, int index, + unsigned long new_value) +{ +#ifdef UNW_TARGET_X86 + index = dwarf_to_unw_regnum(index); +#endif + unw_set_reg (&context->cursor, index, new_value); +#ifdef UNW_TARGET_IA64 + if (index >= UNW_IA64_GR && index <= UNW_IA64_GR + 127) + /* Clear the NaT bit. */ + unw_set_reg (&context->cursor, UNW_IA64_NAT + (index - UNW_IA64_GR), 0); +#endif +} + +void __libunwind_Unwind_SetGR (struct _Unwind_Context *, int, unsigned long) + ALIAS (_Unwind_SetGR); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/SetIP.c b/src/coreclr/src/pal/src/libunwind/src/unwind/SetIP.c new file mode 100644 index 00000000000000..fccc2f0dd57da8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/SetIP.c @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind-internal.h" + +void +_Unwind_SetIP (struct _Unwind_Context *context, unsigned long new_value) +{ + unw_set_reg (&context->cursor, UNW_REG_IP, new_value); +} + +void __libunwind_Unwind_SetIP (struct _Unwind_Context *, unsigned long) + ALIAS (_Unwind_SetIP); diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in b/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in new file mode 100644 index 00000000000000..9a65faf39e1255 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libunwind +Description: libunwind base library +Version: @VERSION@ +Libs: -L${libdir} -lunwind +Libs.private: @LIBLZMA@ @LIBZ@ +Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/unwind-internal.h b/src/coreclr/src/pal/src/libunwind/src/unwind/unwind-internal.h new file mode 100644 index 00000000000000..c68fc3c5ed34ad --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/unwind-internal.h @@ -0,0 +1,140 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 unwind_internal_h +#define unwind_internal_h + +#define UNW_LOCAL_ONLY + +#include +#include +#include + +#include "libunwind_i.h" + +/* The version of the _Unwind_*() interface implemented by this code. */ +#define _U_VERSION 1 + +typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) + (int, _Unwind_Action, uint64_t, struct _Unwind_Exception *, + struct _Unwind_Context *); + +struct _Unwind_Context { + unw_cursor_t cursor; + int end_of_stack; /* set to 1 if the end of stack was reached */ +}; + +/* This must be a macro because unw_getcontext() must be invoked from + the callee, even if optimization (and hence inlining) is turned + off. The macro arguments MUST NOT have any side-effects. */ +#define _Unwind_InitContext(context, uc) \ + ((context)->end_of_stack = 0, \ + ((unw_getcontext (uc) < 0 || unw_init_local (&(context)->cursor, uc) < 0) \ + ? -1 : 0)) + +static _Unwind_Reason_Code ALWAYS_INLINE +_Unwind_Phase2 (struct _Unwind_Exception *exception_object, + struct _Unwind_Context *context) +{ + _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) exception_object->private_1; + uint64_t exception_class = exception_object->exception_class; + void *stop_parameter = (void *) exception_object->private_2; + _Unwind_Personality_Fn personality; + _Unwind_Reason_Code reason; + _Unwind_Action actions; + unw_proc_info_t pi; + unw_word_t ip; + int ret; + + actions = _UA_CLEANUP_PHASE; + if (stop) + actions |= _UA_FORCE_UNWIND; + + while (1) + { + ret = unw_step (&context->cursor); + if (ret <= 0) + { + if (ret == 0) + { + actions |= _UA_END_OF_STACK; + context->end_of_stack = 1; + } + else + return _URC_FATAL_PHASE2_ERROR; + } + + if (stop) + { + reason = (*stop) (_U_VERSION, actions, exception_class, + exception_object, context, stop_parameter); + if (reason != _URC_NO_REASON) + /* Stop function may return _URC_FATAL_PHASE2_ERROR if + it's unable to handle end-of-stack condition or + _URC_FATAL_PHASE2_ERROR if something is wrong. Not + that it matters: the resulting state is indeterminate + anyhow so we must return _URC_FATAL_PHASE2_ERROR... */ + return _URC_FATAL_PHASE2_ERROR; + } + + if (context->end_of_stack + || unw_get_proc_info (&context->cursor, &pi) < 0) + return _URC_FATAL_PHASE2_ERROR; + + personality = (_Unwind_Personality_Fn) (uintptr_t) pi.handler; + if (personality) + { + if (!stop) + { + if (unw_get_reg (&context->cursor, UNW_REG_IP, &ip) < 0) + return _URC_FATAL_PHASE2_ERROR; + + if ((unsigned long) stop_parameter == ip) + actions |= _UA_HANDLER_FRAME; + } + + reason = (*personality) (_U_VERSION, actions, exception_class, + exception_object, context); + if (reason != _URC_CONTINUE_UNWIND) + { + if (reason == _URC_INSTALL_CONTEXT) + { + /* we may regain control via _Unwind_Resume() */ + unw_resume (&context->cursor); + abort (); + } + else + return _URC_FATAL_PHASE2_ERROR; + } + if (actions & _UA_HANDLER_FRAME) + /* The personality routine for the handler-frame changed + it's mind; that's a no-no... */ + abort (); + } + } + return _URC_FATAL_PHASE2_ERROR; /* shouldn't be reached */ +} + +#endif /* unwind_internal_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gcreate_addr_space.c new file mode 100644 index 00000000000000..a7e41a58f48a25 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Gcreate_addr_space.c @@ -0,0 +1,58 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#if defined(_LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#endif + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * x86 supports only little-endian. + */ + if (byte_order != 0 && byte_order != __LITTLE_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gget_proc_info.c new file mode 100644 index 00000000000000..4dc2cff3660794 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Gget_proc_info.c @@ -0,0 +1,45 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + + if (dwarf_make_proc_info (&c->dwarf) < 0) + { + /* On x86, it's relatively common to be missing DWARF unwind + info. We don't want to fail in that case, because the + frame-chain still would let us do a backtrace at least. */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 1; + return 0; + } + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gget_save_loc.c new file mode 100644 index 00000000000000..e459382f6d3cfc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Gget_save_loc.c @@ -0,0 +1,133 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_X86_EIP: loc = c->dwarf.loc[EIP]; break; + case UNW_X86_CFA: break; + case UNW_X86_EAX: loc = c->dwarf.loc[EAX]; break; + case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; + case UNW_X86_EDX: loc = c->dwarf.loc[EDX]; break; + case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; + case UNW_X86_ESP: loc = c->dwarf.loc[ESP]; break; + case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; + case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break; + case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break; + case UNW_X86_EFLAGS: loc = c->dwarf.loc[EFLAGS]; break; + case UNW_X86_TRAPNO: loc = c->dwarf.loc[TRAPNO]; break; + case UNW_X86_ST0: loc = c->dwarf.loc[ST0]; break; + + case UNW_X86_FCW: + case UNW_X86_FSW: + case UNW_X86_FTW: + case UNW_X86_FOP: + case UNW_X86_FCS: + case UNW_X86_FIP: + case UNW_X86_FEA: + case UNW_X86_FDS: + case UNW_X86_MXCSR: + case UNW_X86_GS: + case UNW_X86_FS: + case UNW_X86_ES: + case UNW_X86_DS: + case UNW_X86_SS: + case UNW_X86_CS: + case UNW_X86_TSS: + case UNW_X86_LDT: + loc = x86_scratch_loc (c, reg); + break; + + /* stacked fp registers */ + case UNW_X86_ST1: + case UNW_X86_ST2: + case UNW_X86_ST3: + case UNW_X86_ST4: + case UNW_X86_ST5: + case UNW_X86_ST6: + case UNW_X86_ST7: + /* SSE fp registers */ + case UNW_X86_XMM0_lo: + case UNW_X86_XMM0_hi: + case UNW_X86_XMM1_lo: + case UNW_X86_XMM1_hi: + case UNW_X86_XMM2_lo: + case UNW_X86_XMM2_hi: + case UNW_X86_XMM3_lo: + case UNW_X86_XMM3_hi: + case UNW_X86_XMM4_lo: + case UNW_X86_XMM4_hi: + case UNW_X86_XMM5_lo: + case UNW_X86_XMM5_hi: + case UNW_X86_XMM6_lo: + case UNW_X86_XMM6_hi: + case UNW_X86_XMM7_lo: + case UNW_X86_XMM7_hi: + case UNW_X86_XMM0: + case UNW_X86_XMM1: + case UNW_X86_XMM2: + case UNW_X86_XMM3: + case UNW_X86_XMM4: + case UNW_X86_XMM5: + case UNW_X86_XMM6: + case UNW_X86_XMM7: + loc = x86_scratch_loc (c, reg); + break; + + default: + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gglobal.c new file mode 100644 index 00000000000000..132b8249944115 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Gglobal.c @@ -0,0 +1,67 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (x86_lock); +HIDDEN int tdep_init_done; + +/* See comments for svr4_dbx_register_map[] in gcc/config/i386/i386.c. */ + +HIDDEN const uint8_t dwarf_to_unw_regnum_map[19] = + { + UNW_X86_EAX, UNW_X86_ECX, UNW_X86_EDX, UNW_X86_EBX, + UNW_X86_ESP, UNW_X86_EBP, UNW_X86_ESI, UNW_X86_EDI, + UNW_X86_EIP, UNW_X86_EFLAGS, UNW_X86_TRAPNO, + UNW_X86_ST0, UNW_X86_ST1, UNW_X86_ST2, UNW_X86_ST3, + UNW_X86_ST4, UNW_X86_ST5, UNW_X86_ST6, UNW_X86_ST7 + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&x86_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + +#ifndef UNW_REMOTE_ONLY + x86_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&x86_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c new file mode 100644 index 00000000000000..3cec74a216b1fa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c @@ -0,0 +1,242 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + +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. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return x86_r_uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +#define PAGE_SIZE 4096 +#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) + +/* Cache of already validated addresses */ +#define NLGA 4 +static unw_word_t last_good_addr[NLGA]; +static int lga_victim; + +static int +validate_mem (unw_word_t addr) +{ + int i, victim; +#ifdef HAVE_MINCORE + unsigned char mvec[2]; /* Unaligned access may cross page boundary */ +#endif + size_t len; + + if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) + len = PAGE_SIZE; + else + len = PAGE_SIZE * 2; + + addr = PAGE_START(addr); + + if (addr == 0) + return -1; + + for (i = 0; i < NLGA; i++) + { + if (last_good_addr[i] && (addr == last_good_addr[i])) + return 0; + } + +#ifdef HAVE_MINCORE + if (mincore ((void *) addr, len, mvec) == -1) +#else + if (msync ((void *) addr, len, MS_ASYNC) == -1) +#endif + return -1; + + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (!last_good_addr[victim]) { + last_good_addr[victim++] = addr; + return 0; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; + + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (write) + { + Debug (16, "mem[%x] <- %x\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + /* validate address */ + const struct cursor *c = (const struct cursor *)arg; + if (c && c->validate && validate_mem(addr)) + return -1; + *val = *(unw_word_t *) addr; + Debug (16, "mem[%x] -> %x\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = ((struct cursor *)arg)->uc; + + if (unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = x86_r_uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- %x\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> %x\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = ((struct cursor *)arg)->uc; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = x86_r_uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +x86_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = x86_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_local.c new file mode 100644 index 00000000000000..bff068704def7f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_local.c @@ -0,0 +1,79 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common(unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = c; + c->uc = uc; + c->validate = 0; + return common_init (c, use_prev_instr); +} + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_remote.c new file mode 100644 index 00000000000000..7c15096e4f7f75 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit_remote.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + c->dwarf.as_arg = as_arg; + if (as == unw_local_addr_space) + { + c->dwarf.as_arg = c; + c->uc = as_arg; + } + else + { + c->dwarf.as_arg = as_arg; + c->uc = 0; + } + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gos-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gos-freebsd.c new file mode 100644 index 00000000000000..7dd0140463859a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Gos-freebsd.c @@ -0,0 +1,374 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010 Konstantin Belousov + +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. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "unwind_i.h" +#include "offsets.h" + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, w2, w3, w4, w5, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + /* Check if EIP points at sigreturn() sequence. It can be: +sigcode+4: from amd64 freebsd32 environment +8d 44 24 20 lea 0x20(%esp),%eax +50 push %eax +b8 a1 01 00 00 mov $0x1a1,%eax +50 push %eax +cd 80 int $0x80 + +sigcode+4: from real i386 +8d 44 24 20 lea 0x20(%esp),%eax +50 push %eax +f7 40 54 00 02 00 testl $0x20000,0x54(%eax) +75 03 jne sigcode+21 +8e 68 14 mov 0x14(%eax),%gs +b8 a1 01 00 00 mov $0x1a1,%eax +50 push %eax +cd 80 int $0x80 + +freebsd4_sigcode+4: +XXX +osigcode: +XXX + */ + ip = c->dwarf.ip; + ret = X86_SCF_NONE; + c->sigcontext_format = ret; + if ((*a->access_mem) (as, ip, &w0, 0, arg) < 0 || + (*a->access_mem) (as, ip + 4, &w1, 0, arg) < 0 || + (*a->access_mem) (as, ip + 8, &w2, 0, arg) < 0 || + (*a->access_mem) (as, ip + 12, &w3, 0, arg) < 0) + return ret; + if (w0 == 0x2024448d && w1 == 0x01a1b850 && w2 == 0xcd500000 && + (w3 & 0xff) == 0x80) + ret = X86_SCF_FREEBSD_SIGFRAME; + else { + if ((*a->access_mem) (as, ip + 16, &w4, 0, arg) < 0 || + (*a->access_mem) (as, ip + 20, &w5, 0, arg) < 0) + return ret; + if (w0 == 0x2024448d && w1 == 0x5440f750 && w2 == 0x75000200 && + w3 == 0x14688e03 && w4 == 0x0001a1b8 && w5 == 0x80cd5000) + ret = X86_SCF_FREEBSD_SIGFRAME; + } + + /* Check for syscall */ + if (ret == X86_SCF_NONE && (*a->access_mem) (as, ip - 2, &w0, 0, arg) >= 0 && + (w0 & 0xffff) == 0x80cd) + ret = X86_SCF_FREEBSD_SYSCALL; + Debug (16, "returning %d\n", ret); + c->sigcontext_format = ret; + return (ret); +} + +HIDDEN int +x86_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) { + struct sigframe *sf; + uintptr_t uc_addr; + struct dwarf_loc esp_loc; + + sf = (struct sigframe *)c->dwarf.cfa; + uc_addr = (uintptr_t)&(sf->sf_uc); + c->sigcontext_addr = c->dwarf.cfa; + + esp_loc = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0); + ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + + c->dwarf.loc[EIP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EIP_OFF, 0); + c->dwarf.loc[ESP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0); + c->dwarf.loc[EAX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EAX_OFF, 0); + c->dwarf.loc[ECX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ECX_OFF, 0); + c->dwarf.loc[EDX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EDX_OFF, 0); + c->dwarf.loc[EBX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBX_OFF, 0); + c->dwarf.loc[EBP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBP_OFF, 0); + c->dwarf.loc[ESI] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESI_OFF, 0); + c->dwarf.loc[EDI] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EDI_OFF, 0); + c->dwarf.loc[EFLAGS] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EFLAGS_OFF, 0); + c->dwarf.loc[TRAPNO] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_TRAPNO_OFF, 0); + c->dwarf.loc[ST0] = DWARF_NULL_LOC; + } else if (c->sigcontext_format == X86_SCF_FREEBSD_SYSCALL) { + c->dwarf.loc[EIP] = DWARF_LOC (c->dwarf.cfa, 0); + c->dwarf.loc[EAX] = DWARF_NULL_LOC; + c->dwarf.cfa += 4; + c->dwarf.use_prev_instr = 1; + } else { + Debug (8, "Gstep: not handling frame format %d\n", c->sigcontext_format); + abort(); + } + return 0; +} + +HIDDEN dwarf_loc_t +x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg) +{ + unw_word_t addr = c->sigcontext_addr, off, xmm_off; + unw_word_t fpstate, fpformat; + int ret, is_fpstate = 0, is_xmmstate = 0; + + switch (c->sigcontext_format) + { + case X86_SCF_NONE: + return DWARF_REG_LOC (&c->dwarf, reg); + + case X86_SCF_FREEBSD_SIGFRAME: + addr += offsetof(struct sigframe, sf_uc) + FREEBSD_UC_MCONTEXT_OFF; + break; + + case X86_SCF_FREEBSD_SIGFRAME4: + abort(); + break; + + case X86_SCF_FREEBSD_OSIGFRAME: + /* XXXKIB */ + abort(); + break; + + case X86_SCF_FREEBSD_SYSCALL: + /* XXXKIB */ + abort(); + break; + + default: + /* XXXKIB */ + abort(); + break; + } + + off = 0; /* shut gcc warning */ + switch (reg) + { + case UNW_X86_GS: off = FREEBSD_UC_MCONTEXT_GS_OFF; break; + case UNW_X86_FS: off = FREEBSD_UC_MCONTEXT_FS_OFF; break; + case UNW_X86_ES: off = FREEBSD_UC_MCONTEXT_ES_OFF; break; + case UNW_X86_DS: off = FREEBSD_UC_MCONTEXT_SS_OFF; break; + case UNW_X86_EDI: off = FREEBSD_UC_MCONTEXT_EDI_OFF; break; + case UNW_X86_ESI: off = FREEBSD_UC_MCONTEXT_ESI_OFF; break; + case UNW_X86_EBP: off = FREEBSD_UC_MCONTEXT_EBP_OFF; break; + case UNW_X86_ESP: off = FREEBSD_UC_MCONTEXT_ESP_OFF; break; + case UNW_X86_EBX: off = FREEBSD_UC_MCONTEXT_EBX_OFF; break; + case UNW_X86_EDX: off = FREEBSD_UC_MCONTEXT_EDX_OFF; break; + case UNW_X86_ECX: off = FREEBSD_UC_MCONTEXT_ECX_OFF; break; + case UNW_X86_EAX: off = FREEBSD_UC_MCONTEXT_EAX_OFF; break; + case UNW_X86_TRAPNO: off = FREEBSD_UC_MCONTEXT_TRAPNO_OFF; break; + case UNW_X86_EIP: off = FREEBSD_UC_MCONTEXT_EIP_OFF; break; + case UNW_X86_CS: off = FREEBSD_UC_MCONTEXT_CS_OFF; break; + case UNW_X86_EFLAGS: off = FREEBSD_UC_MCONTEXT_EFLAGS_OFF; break; + case UNW_X86_SS: off = FREEBSD_UC_MCONTEXT_SS_OFF; break; + + case UNW_X86_FCW: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_CW_OFF; + xmm_off = FREEBSD_UC_MCONTEXT_CW_XMM_OFF; + break; + case UNW_X86_FSW: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_SW_OFF; + xmm_off = FREEBSD_UC_MCONTEXT_SW_XMM_OFF; + break; + case UNW_X86_FTW: + is_fpstate = 1; + xmm_off = FREEBSD_UC_MCONTEXT_TAG_XMM_OFF; + off = FREEBSD_UC_MCONTEXT_TAG_OFF; + break; + case UNW_X86_FCS: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_CSSEL_OFF; + xmm_off = FREEBSD_UC_MCONTEXT_CSSEL_XMM_OFF; + break; + case UNW_X86_FIP: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_IPOFF_OFF; + xmm_off = FREEBSD_UC_MCONTEXT_IPOFF_XMM_OFF; + break; + case UNW_X86_FEA: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_DATAOFF_OFF; + xmm_off = FREEBSD_UC_MCONTEXT_DATAOFF_XMM_OFF; + break; + case UNW_X86_FDS: + is_fpstate = 1; + off = FREEBSD_US_MCONTEXT_DATASEL_OFF; + xmm_off = FREEBSD_US_MCONTEXT_DATASEL_XMM_OFF; + break; + case UNW_X86_MXCSR: + is_fpstate = 1; + is_xmmstate = 1; + xmm_off = FREEBSD_UC_MCONTEXT_MXCSR_XMM_OFF; + break; + + /* stacked fp registers */ + case UNW_X86_ST0: case UNW_X86_ST1: case UNW_X86_ST2: case UNW_X86_ST3: + case UNW_X86_ST4: case UNW_X86_ST5: case UNW_X86_ST6: case UNW_X86_ST7: + is_fpstate = 1; + off = FREEBSD_UC_MCONTEXT_ST0_OFF + 10*(reg - UNW_X86_ST0); + xmm_off = FREEBSD_UC_MCONTEXT_ST0_XMM_OFF + 10*(reg - UNW_X86_ST0); + break; + + /* SSE fp registers */ + case UNW_X86_XMM0_lo: case UNW_X86_XMM0_hi: + case UNW_X86_XMM1_lo: case UNW_X86_XMM1_hi: + case UNW_X86_XMM2_lo: case UNW_X86_XMM2_hi: + case UNW_X86_XMM3_lo: case UNW_X86_XMM3_hi: + case UNW_X86_XMM4_lo: case UNW_X86_XMM4_hi: + case UNW_X86_XMM5_lo: case UNW_X86_XMM5_hi: + case UNW_X86_XMM6_lo: case UNW_X86_XMM6_hi: + case UNW_X86_XMM7_lo: case UNW_X86_XMM7_hi: + is_fpstate = 1; + is_xmmstate = 1; + xmm_off = FREEBSD_UC_MCONTEXT_XMM0_OFF + 8*(reg - UNW_X86_XMM0_lo); + break; + case UNW_X86_XMM0: + case UNW_X86_XMM1: + case UNW_X86_XMM2: + case UNW_X86_XMM3: + case UNW_X86_XMM4: + case UNW_X86_XMM5: + case UNW_X86_XMM6: + case UNW_X86_XMM7: + is_fpstate = 1; + is_xmmstate = 1; + xmm_off = FREEBSD_UC_MCONTEXT_XMM0_OFF + 16*(reg - UNW_X86_XMM0); + break; + + case UNW_X86_FOP: + case UNW_X86_TSS: + case UNW_X86_LDT: + default: + return DWARF_REG_LOC (&c->dwarf, reg); + } + + if (is_fpstate) + { + if ((ret = dwarf_get (&c->dwarf, + DWARF_MEM_LOC (&c->dwarf, addr + FREEBSD_UC_MCONTEXT_FPSTATE_OFF), + &fpstate)) < 0) + return DWARF_NULL_LOC; + if (fpstate == FREEBSD_UC_MCONTEXT_FPOWNED_NONE) + return DWARF_NULL_LOC; + if ((ret = dwarf_get (&c->dwarf, + DWARF_MEM_LOC (&c->dwarf, addr + FREEBSD_UC_MCONTEXT_FPFORMAT_OFF), + &fpformat)) < 0) + return DWARF_NULL_LOC; + if (fpformat == FREEBSD_UC_MCONTEXT_FPFMT_NODEV || + (is_xmmstate && fpformat != FREEBSD_UC_MCONTEXT_FPFMT_XMM)) + return DWARF_NULL_LOC; + if (is_xmmstate) + off = xmm_off; + } + + return DWARF_MEM_LOC (c, addr + off); +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_r_uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + switch (reg) + { + case UNW_X86_GS: addr = &uc->uc_mcontext.mc_gs; break; + case UNW_X86_FS: addr = &uc->uc_mcontext.mc_fs; break; + case UNW_X86_ES: addr = &uc->uc_mcontext.mc_es; break; + case UNW_X86_DS: addr = &uc->uc_mcontext.mc_ds; break; + case UNW_X86_EAX: addr = &uc->uc_mcontext.mc_eax; break; + case UNW_X86_EBX: addr = &uc->uc_mcontext.mc_ebx; break; + case UNW_X86_ECX: addr = &uc->uc_mcontext.mc_ecx; break; + case UNW_X86_EDX: addr = &uc->uc_mcontext.mc_edx; break; + case UNW_X86_ESI: addr = &uc->uc_mcontext.mc_esi; break; + case UNW_X86_EDI: addr = &uc->uc_mcontext.mc_edi; break; + case UNW_X86_EBP: addr = &uc->uc_mcontext.mc_ebp; break; + case UNW_X86_EIP: addr = &uc->uc_mcontext.mc_eip; break; + case UNW_X86_ESP: addr = &uc->uc_mcontext.mc_esp; break; + case UNW_X86_TRAPNO: addr = &uc->uc_mcontext.mc_trapno; break; + case UNW_X86_CS: addr = &uc->uc_mcontext.mc_cs; break; + case UNW_X86_EFLAGS: addr = &uc->uc_mcontext.mc_eflags; break; + case UNW_X86_SS: addr = &uc->uc_mcontext.mc_ss; break; + + default: + addr = NULL; + } + return addr; +} + +HIDDEN int +x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = c->uc; + + /* Ensure c->pi is up-to-date. On x86, it's relatively common to be + missing DWARF unwind info. We don't want to fail in that case, + because the frame-chain still would let us do a backtrace at + least. */ + dwarf_make_proc_info (&c->dwarf); + + if (c->sigcontext_format == X86_SCF_NONE) { + Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); + setcontext (uc); + abort(); + } else if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); + sigreturn((ucontext_t *)((const char *)sc + FREEBSD_SC_UCONTEXT_OFF)); + abort(); + } else { + Debug (8, "resuming at ip=%x for sigcontext format %d not implemented\n", + c->dwarf.ip, c->sigcontext_format); + abort(); + } + return -UNW_EINVAL; +} + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gos-linux.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gos-linux.c new file mode 100644 index 00000000000000..fb9a5e346123a4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Gos-linux.c @@ -0,0 +1,331 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +#include + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + /* Check if EIP points at sigreturn() sequence. On Linux, this is: + + __restore: + 0x58 pop %eax + 0xb8 0x77 0x00 0x00 0x00 movl 0x77,%eax + 0xcd 0x80 int 0x80 + + without SA_SIGINFO, and + + __restore_rt: + 0xb8 0xad 0x00 0x00 0x00 movl 0xad,%eax + 0xcd 0x80 int 0x80 + 0x00 + + if SA_SIGINFO is specified. + */ + ip = c->dwarf.ip; + if ((*a->access_mem) (as, ip, &w0, 0, arg) < 0 + || (*a->access_mem) (as, ip + 4, &w1, 0, arg) < 0) + ret = 0; + else + ret = ((w0 == 0x0077b858 && w1 == 0x80cd0000) + || (w0 == 0x0000adb8 && (w1 & 0xffffff) == 0x80cd00)); + Debug (16, "returning %d\n", ret); + return ret; +} + +HIDDEN int +x86_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + /* c->esp points at the arguments to the handler. Without + SA_SIGINFO, the arguments consist of a signal number + followed by a struct sigcontext. With SA_SIGINFO, the + arguments consist a signal number, a siginfo *, and a + ucontext *. */ + unw_word_t sc_addr; + unw_word_t siginfo_ptr_addr = c->dwarf.cfa + 4; + unw_word_t sigcontext_ptr_addr = c->dwarf.cfa + 8; + unw_word_t siginfo_ptr, sigcontext_ptr; + struct dwarf_loc esp_loc, siginfo_ptr_loc, sigcontext_ptr_loc; + + siginfo_ptr_loc = DWARF_LOC (siginfo_ptr_addr, 0); + sigcontext_ptr_loc = DWARF_LOC (sigcontext_ptr_addr, 0); + ret = (dwarf_get (&c->dwarf, siginfo_ptr_loc, &siginfo_ptr) + | dwarf_get (&c->dwarf, sigcontext_ptr_loc, &sigcontext_ptr)); + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + if (siginfo_ptr < c->dwarf.cfa + || siginfo_ptr > c->dwarf.cfa + 256 + || sigcontext_ptr < c->dwarf.cfa + || sigcontext_ptr > c->dwarf.cfa + 256) + { + /* Not plausible for SA_SIGINFO signal */ + c->sigcontext_format = X86_SCF_LINUX_SIGFRAME; + c->sigcontext_addr = sc_addr = c->dwarf.cfa + 4; + } + else + { + /* If SA_SIGINFO were not specified, we actually read + various segment pointers instead. We believe that at + least fs and _fsh are always zero for linux, so it is + not just unlikely, but impossible that we would end + up here. */ + c->sigcontext_format = X86_SCF_LINUX_RT_SIGFRAME; + c->sigcontext_addr = sigcontext_ptr; + sc_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF; + } + esp_loc = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0); + ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + + c->dwarf.loc[EAX] = DWARF_LOC (sc_addr + LINUX_SC_EAX_OFF, 0); + c->dwarf.loc[ECX] = DWARF_LOC (sc_addr + LINUX_SC_ECX_OFF, 0); + c->dwarf.loc[EDX] = DWARF_LOC (sc_addr + LINUX_SC_EDX_OFF, 0); + c->dwarf.loc[EBX] = DWARF_LOC (sc_addr + LINUX_SC_EBX_OFF, 0); + c->dwarf.loc[EBP] = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0); + c->dwarf.loc[ESI] = DWARF_LOC (sc_addr + LINUX_SC_ESI_OFF, 0); + c->dwarf.loc[EDI] = DWARF_LOC (sc_addr + LINUX_SC_EDI_OFF, 0); + c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC; + c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC; + c->dwarf.loc[ST0] = DWARF_NULL_LOC; + c->dwarf.loc[EIP] = DWARF_LOC (sc_addr + LINUX_SC_EIP_OFF, 0); + c->dwarf.loc[ESP] = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0); + + return 0; +} + +HIDDEN dwarf_loc_t +x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg) +{ + unw_word_t addr = c->sigcontext_addr, fpstate_addr, off; + int ret, is_fpstate = 0; + + switch (c->sigcontext_format) + { + case X86_SCF_NONE: + return DWARF_REG_LOC (&c->dwarf, reg); + + case X86_SCF_LINUX_SIGFRAME: + break; + + case X86_SCF_LINUX_RT_SIGFRAME: + addr += LINUX_UC_MCONTEXT_OFF; + break; + + default: + return DWARF_NULL_LOC; + } + + switch (reg) + { + case UNW_X86_GS: off = LINUX_SC_GS_OFF; break; + case UNW_X86_FS: off = LINUX_SC_FS_OFF; break; + case UNW_X86_ES: off = LINUX_SC_ES_OFF; break; + case UNW_X86_DS: off = LINUX_SC_DS_OFF; break; + case UNW_X86_EDI: off = LINUX_SC_EDI_OFF; break; + case UNW_X86_ESI: off = LINUX_SC_ESI_OFF; break; + case UNW_X86_EBP: off = LINUX_SC_EBP_OFF; break; + case UNW_X86_ESP: off = LINUX_SC_ESP_OFF; break; + case UNW_X86_EBX: off = LINUX_SC_EBX_OFF; break; + case UNW_X86_EDX: off = LINUX_SC_EDX_OFF; break; + case UNW_X86_ECX: off = LINUX_SC_ECX_OFF; break; + case UNW_X86_EAX: off = LINUX_SC_EAX_OFF; break; + case UNW_X86_TRAPNO: off = LINUX_SC_TRAPNO_OFF; break; + case UNW_X86_EIP: off = LINUX_SC_EIP_OFF; break; + case UNW_X86_CS: off = LINUX_SC_CS_OFF; break; + case UNW_X86_EFLAGS: off = LINUX_SC_EFLAGS_OFF; break; + case UNW_X86_SS: off = LINUX_SC_SS_OFF; break; + + /* The following is probably not correct for all possible cases. + Somebody who understands this better should review this for + correctness. */ + + case UNW_X86_FCW: is_fpstate = 1; off = LINUX_FPSTATE_CW_OFF; break; + case UNW_X86_FSW: is_fpstate = 1; off = LINUX_FPSTATE_SW_OFF; break; + case UNW_X86_FTW: is_fpstate = 1; off = LINUX_FPSTATE_TAG_OFF; break; + case UNW_X86_FCS: is_fpstate = 1; off = LINUX_FPSTATE_CSSEL_OFF; break; + case UNW_X86_FIP: is_fpstate = 1; off = LINUX_FPSTATE_IPOFF_OFF; break; + case UNW_X86_FEA: is_fpstate = 1; off = LINUX_FPSTATE_DATAOFF_OFF; break; + case UNW_X86_FDS: is_fpstate = 1; off = LINUX_FPSTATE_DATASEL_OFF; break; + case UNW_X86_MXCSR: is_fpstate = 1; off = LINUX_FPSTATE_MXCSR_OFF; break; + + /* stacked fp registers */ + case UNW_X86_ST0: case UNW_X86_ST1: case UNW_X86_ST2: case UNW_X86_ST3: + case UNW_X86_ST4: case UNW_X86_ST5: case UNW_X86_ST6: case UNW_X86_ST7: + is_fpstate = 1; + off = LINUX_FPSTATE_ST0_OFF + 10*(reg - UNW_X86_ST0); + break; + + /* SSE fp registers */ + case UNW_X86_XMM0_lo: case UNW_X86_XMM0_hi: + case UNW_X86_XMM1_lo: case UNW_X86_XMM1_hi: + case UNW_X86_XMM2_lo: case UNW_X86_XMM2_hi: + case UNW_X86_XMM3_lo: case UNW_X86_XMM3_hi: + case UNW_X86_XMM4_lo: case UNW_X86_XMM4_hi: + case UNW_X86_XMM5_lo: case UNW_X86_XMM5_hi: + case UNW_X86_XMM6_lo: case UNW_X86_XMM6_hi: + case UNW_X86_XMM7_lo: case UNW_X86_XMM7_hi: + is_fpstate = 1; + off = LINUX_FPSTATE_XMM0_OFF + 8*(reg - UNW_X86_XMM0_lo); + break; + case UNW_X86_XMM0: + case UNW_X86_XMM1: + case UNW_X86_XMM2: + case UNW_X86_XMM3: + case UNW_X86_XMM4: + case UNW_X86_XMM5: + case UNW_X86_XMM6: + case UNW_X86_XMM7: + is_fpstate = 1; + off = LINUX_FPSTATE_XMM0_OFF + 16*(reg - UNW_X86_XMM0); + break; + + case UNW_X86_FOP: + case UNW_X86_TSS: + case UNW_X86_LDT: + default: + return DWARF_REG_LOC (&c->dwarf, reg); + } + + if (is_fpstate) + { + if ((ret = dwarf_get (&c->dwarf, + DWARF_MEM_LOC (&c->dwarf, + addr + LINUX_SC_FPSTATE_OFF), + &fpstate_addr)) < 0) + return DWARF_NULL_LOC; + + if (!fpstate_addr) + return DWARF_NULL_LOC; + + return DWARF_MEM_LOC (c, fpstate_addr + off); + } + else + return DWARF_MEM_LOC (c, addr + off); +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_r_uc_addr (ucontext_t *uc, int reg) +{ + void *addr; + + switch (reg) + { + case UNW_X86_GS: addr = &uc->uc_mcontext.gregs[REG_GS]; break; + case UNW_X86_FS: addr = &uc->uc_mcontext.gregs[REG_FS]; break; + case UNW_X86_ES: addr = &uc->uc_mcontext.gregs[REG_ES]; break; + case UNW_X86_DS: addr = &uc->uc_mcontext.gregs[REG_DS]; break; + case UNW_X86_EAX: addr = &uc->uc_mcontext.gregs[REG_EAX]; break; + case UNW_X86_EBX: addr = &uc->uc_mcontext.gregs[REG_EBX]; break; + case UNW_X86_ECX: addr = &uc->uc_mcontext.gregs[REG_ECX]; break; + case UNW_X86_EDX: addr = &uc->uc_mcontext.gregs[REG_EDX]; break; + case UNW_X86_ESI: addr = &uc->uc_mcontext.gregs[REG_ESI]; break; + case UNW_X86_EDI: addr = &uc->uc_mcontext.gregs[REG_EDI]; break; + case UNW_X86_EBP: addr = &uc->uc_mcontext.gregs[REG_EBP]; break; + case UNW_X86_EIP: addr = &uc->uc_mcontext.gregs[REG_EIP]; break; + case UNW_X86_ESP: addr = &uc->uc_mcontext.gregs[REG_ESP]; break; + case UNW_X86_TRAPNO: addr = &uc->uc_mcontext.gregs[REG_TRAPNO]; break; + case UNW_X86_CS: addr = &uc->uc_mcontext.gregs[REG_CS]; break; + case UNW_X86_EFLAGS: addr = &uc->uc_mcontext.gregs[REG_EFL]; break; + case UNW_X86_SS: addr = &uc->uc_mcontext.gregs[REG_SS]; break; + + default: + addr = NULL; + } + return addr; +} + +HIDDEN int +x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = c->uc; + + /* Ensure c->pi is up-to-date. On x86, it's relatively common to be + missing DWARF unwind info. We don't want to fail in that case, + because the frame-chain still would let us do a backtrace at + least. */ + dwarf_make_proc_info (&c->dwarf); + + if (unlikely (c->sigcontext_format != X86_SCF_NONE)) + { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); + x86_sigreturn (sc); + } + else + { + Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip); + setcontext (uc); + } + return -UNW_EINVAL; +} + +/* sigreturn() is a no-op on x86 glibc. */ +HIDDEN void +x86_sigreturn (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + mcontext_t *sc_mcontext = &((ucontext_t*)sc)->uc_mcontext; + /* Copy in saved uc - all preserved regs are at the start of sigcontext */ + memcpy(sc_mcontext, &c->uc->uc_mcontext, + DWARF_NUM_PRESERVED_REGS * sizeof(unw_word_t)); + + Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", + (unsigned long long) c->dwarf.ip, sc); + __asm__ __volatile__ ("mov %0, %%esp;" + "mov %1, %%eax;" + "syscall" + :: "r"(sc), "i"(SYS_rt_sigreturn) + : "memory"); + abort(); +} +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/x86/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gregs.c new file mode 100644 index 00000000000000..4a9592617d0d46 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Gregs.c @@ -0,0 +1,178 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" +#include "unwind_i.h" + +HIDDEN dwarf_loc_t +x86_scratch_loc (struct cursor *c, unw_regnum_t reg) +{ + if (c->sigcontext_addr) + return x86_get_scratch_loc (c, reg); + else + return DWARF_REG_LOC (&c->dwarf, reg); +} + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + unsigned int mask; + int arg_num; + + switch (reg) + { + + case UNW_X86_EIP: + if (write) + c->dwarf.ip = *valp; /* also update the EIP cache */ + loc = c->dwarf.loc[EIP]; + break; + + case UNW_X86_CFA: + case UNW_X86_ESP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + case UNW_X86_EAX: + case UNW_X86_EDX: + arg_num = reg - UNW_X86_EAX; + mask = (1 << arg_num); + if (write) + { + c->dwarf.eh_args[arg_num] = *valp; + c->dwarf.eh_valid_mask |= mask; + return 0; + } + else if ((c->dwarf.eh_valid_mask & mask) != 0) + { + *valp = c->dwarf.eh_args[arg_num]; + return 0; + } + else + loc = c->dwarf.loc[(reg == UNW_X86_EAX) ? EAX : EDX]; + break; + + case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; + case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; + + case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; + case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break; + case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break; + case UNW_X86_EFLAGS: loc = c->dwarf.loc[EFLAGS]; break; + case UNW_X86_TRAPNO: loc = c->dwarf.loc[TRAPNO]; break; + + case UNW_X86_FCW: + case UNW_X86_FSW: + case UNW_X86_FTW: + case UNW_X86_FOP: + case UNW_X86_FCS: + case UNW_X86_FIP: + case UNW_X86_FEA: + case UNW_X86_FDS: + case UNW_X86_MXCSR: + case UNW_X86_GS: + case UNW_X86_FS: + case UNW_X86_ES: + case UNW_X86_DS: + case UNW_X86_SS: + case UNW_X86_CS: + case UNW_X86_TSS: + case UNW_X86_LDT: + loc = x86_scratch_loc (c, reg); + break; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + struct dwarf_loc loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_X86_ST0: + loc = c->dwarf.loc[ST0]; + break; + + /* stacked fp registers */ + case UNW_X86_ST1: + case UNW_X86_ST2: + case UNW_X86_ST3: + case UNW_X86_ST4: + case UNW_X86_ST5: + case UNW_X86_ST6: + case UNW_X86_ST7: + /* SSE fp registers */ + case UNW_X86_XMM0: + case UNW_X86_XMM1: + case UNW_X86_XMM2: + case UNW_X86_XMM3: + case UNW_X86_XMM4: + case UNW_X86_XMM5: + case UNW_X86_XMM6: + case UNW_X86_XMM7: + case UNW_X86_XMM0_lo: + case UNW_X86_XMM0_hi: + case UNW_X86_XMM1_lo: + case UNW_X86_XMM1_hi: + case UNW_X86_XMM2_lo: + case UNW_X86_XMM2_hi: + case UNW_X86_XMM3_lo: + case UNW_X86_XMM3_hi: + case UNW_X86_XMM4_lo: + case UNW_X86_XMM4_hi: + case UNW_X86_XMM5_lo: + case UNW_X86_XMM5_hi: + case UNW_X86_XMM6_lo: + case UNW_X86_XMM6_hi: + case UNW_X86_XMM7_lo: + case UNW_X86_XMM7_hi: + loc = x86_scratch_loc (c, reg); + break; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gresume.c new file mode 100644 index 00000000000000..5072c4ba089991 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Gresume.c @@ -0,0 +1,91 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" +#include "offsets.h" + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int write, void *); + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int write, void *); + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + access_reg = as->acc.access_reg; + access_fpreg = as->acc.access_fpreg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + (*access_fpreg) (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + (*access_reg) (as, reg, &val, 1, arg); + } + } + + if (c->dwarf.args_size) + { + if (tdep_access_reg (c, UNW_X86_ESP, &val, 0) >= 0) + { + val += c->dwarf.args_size; + (*access_reg) (as, UNW_X86_ESP, &val, 1, arg); + } + } + return 0; +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/x86/Gstep.c new file mode 100644 index 00000000000000..129b739a3e78f2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Gstep.c @@ -0,0 +1,115 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "offsets.h" + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret, i; + + Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip); + + /* Try DWARF-based unwinding... */ + ret = dwarf_step (&c->dwarf); + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (unlikely (ret < 0)) + { + /* DWARF failed, let's see if we can follow the frame-chain + or skip over the signal trampoline. */ + struct dwarf_loc ebp_loc, eip_loc; + + /* We could get here because of missing/bad unwind information. + Validate all addresses before dereferencing. */ + c->validate = 1; + + Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); + + if (unw_is_signal_frame (cursor) > 0) + { + ret = x86_handle_signal_frame(cursor); + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + } + else + { + ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + Debug (13, "[EBP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EBP]), + c->dwarf.cfa); + + ebp_loc = DWARF_LOC (c->dwarf.cfa, 0); + eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0); + c->dwarf.cfa += 8; + + /* Mark all registers unsaved, since we don't know where + they are saved (if at all), except for the EBP and + EIP. */ + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + c->dwarf.loc[EBP] = ebp_loc; + c->dwarf.loc[EIP] = eip_loc; + c->dwarf.use_prev_instr = 1; + } + + if (!DWARF_IS_NULL_LOC (c->dwarf.loc[EBP])) + { + ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip); + if (ret < 0) + { + Debug (13, "dwarf_get([EIP=0x%x]) failed\n", DWARF_GET_LOC (c->dwarf.loc[EIP])); + Debug (2, "returning %d\n", ret); + return ret; + } + else + { + Debug (13, "[EIP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EIP]), + c->dwarf.ip); + } + } + else + c->dwarf.ip = 0; + } + ret = (c->dwarf.ip == 0) ? 0 : 1; + Debug (2, "returning %d\n", ret); + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lglobal.c new file mode 100644 index 00000000000000..6d7b489e14bd9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Lglobal.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Linit.c b/src/coreclr/src/pal/src/libunwind/src/x86/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Los-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/x86/Los-freebsd.c new file mode 100644 index 00000000000000..a75a205df19c01 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Los-freebsd.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-freebsd.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Los-linux.c b/src/coreclr/src/pal/src/libunwind/src/x86/Los-linux.c new file mode 100644 index 00000000000000..3cc18aabcc399c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Los-linux.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-linux.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/x86/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-freebsd.S b/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-freebsd.S new file mode 100644 index 00000000000000..670eff1ae178e7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-freebsd.S @@ -0,0 +1,112 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" + + .global _Ux86_getcontext + .type _Ux86_getcontext, @function +_Ux86_getcontext: + .cfi_startproc + pushl %eax + .cfi_adjust_cfa_offset 4 + mov 8(%esp),%eax /* ucontext_t* */ + popl FREEBSD_UC_MCONTEXT_EAX_OFF(%eax) + .cfi_adjust_cfa_offset 4 + movl %ebx, FREEBSD_UC_MCONTEXT_EBX_OFF(%eax) + movl %ecx, FREEBSD_UC_MCONTEXT_ECX_OFF(%eax) + movl %edx, FREEBSD_UC_MCONTEXT_EDX_OFF(%eax) + movl %edi, FREEBSD_UC_MCONTEXT_EDI_OFF(%eax) + movl %esi, FREEBSD_UC_MCONTEXT_ESI_OFF(%eax) + movl %ebp, FREEBSD_UC_MCONTEXT_EBP_OFF(%eax) + + movl (%esp), %ecx + movl %ecx, FREEBSD_UC_MCONTEXT_EIP_OFF(%eax) + + leal 4(%esp), %ecx /* Exclude the return address. */ + movl %ecx, FREEBSD_UC_MCONTEXT_ESP_OFF(%eax) + + xorl %ecx, %ecx + movw %fs, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_FS_OFF(%eax) + movw %gs, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_GS_OFF(%eax) + movw %ds, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_DS_OFF(%eax) + movw %es, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_ES_OFF(%eax) + movw %ss, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_SS_OFF(%eax) + movw %cs, %cx + movl %ecx, FREEBSD_UC_MCONTEXT_CS_OFF(%eax) + + pushfl + .cfi_adjust_cfa_offset 4 + popl FREEBSD_UC_MCONTEXT_EFLAGS_OFF(%eax) + .cfi_adjust_cfa_offset -4 + + movl $0, FREEBSD_UC_MCONTEXT_TRAPNO_OFF(%eax) + + movl $FREEBSD_UC_MCONTEXT_FPOWNED_FPU,\ + FREEBSD_UC_MCONTEXT_OWNEDFP_OFF(%eax) + movl $FREEBSD_UC_MCONTEXT_FPFMT_XMM,\ + FREEBSD_UC_MCONTEXT_FPFORMAT_OFF(%eax) + + /* + * Require CPU with fxsave implemented, and enabled by OS. + * + * If passed ucontext is not aligned to 16-byte boundary, + * save fpu context into temporary aligned location on stack + * and then copy. + */ + leal FREEBSD_UC_MCONTEXT_FPSTATE_OFF(%eax), %edx + testl $0xf, %edx + jne 2f + fxsave (%edx) /* fast path, passed ucontext save area was aligned */ +1: movl $FREEBSD_UC_MCONTEXT_MC_LEN_VAL,\ + FREEBSD_UC_MCONTEXT_MC_LEN_OFF(%eax) + + xorl %eax, %eax + ret + +2: movl %edx, %edi /* not aligned, do the dance */ + subl $512 + 16, %esp /* save area and 16 bytes for alignment */ + .cfi_adjust_cfa_offset 512 + 16 + movl %esp, %edx + orl $0xf, %edx /* align *%edx to 16-byte up */ + incl %edx + fxsave (%edx) + movl %edx, %esi /* copy to the final destination */ + movl $512/4,%ecx + rep; movsl + addl $512 + 16, %esp /* restore the stack */ + .cfi_adjust_cfa_offset -512 - 16 + movl FREEBSD_UC_MCONTEXT_ESI_OFF(%eax), %esi + movl FREEBSD_UC_MCONTEXT_EDI_OFF(%eax), %edi + jmp 1b + + .cfi_endproc + .size _Ux86_getcontext, . - _Ux86_getcontext + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-linux.S b/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-linux.S new file mode 100644 index 00000000000000..c469dadbac60eb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/getcontext-linux.S @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2009 Google, Inc + Contributed by Paul Pluzhnikov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "offsets.h" + +/* int _Ux86_getcontext (ucontext_t *ucp) + + Saves the machine context in UCP necessary for libunwind. + Unlike the libc implementation, we don't save the signal mask + and hence avoid the cost of a system call per unwind. + +*/ + + .global _Ux86_getcontext + .type _Ux86_getcontext, @function +_Ux86_getcontext: + .cfi_startproc + mov 4(%esp),%eax /* ucontext_t* */ + + /* EAX is not preserved. */ + movl $0, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EAX_OFF)(%eax) + + movl %ebx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EBX_OFF)(%eax) + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ECX_OFF)(%eax) + movl %edx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EDX_OFF)(%eax) + movl %edi, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EDI_OFF)(%eax) + movl %esi, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ESI_OFF)(%eax) + movl %ebp, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EBP_OFF)(%eax) + + movl (%esp), %ecx + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EIP_OFF)(%eax) + + leal 4(%esp), %ecx /* Exclude the return address. */ + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ESP_OFF)(%eax) + + /* glibc getcontext saves FS, but not GS */ + xorl %ecx, %ecx + movw %fs, %cx + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FS_OFF)(%eax) + + leal LINUX_UC_FPREGS_MEM_OFF(%eax), %ecx + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FPSTATE_OFF)(%eax) + fnstenv (%ecx) + fldenv (%ecx) + + xor %eax, %eax + ret + .cfi_endproc + .size _Ux86_getcontext, . - _Ux86_getcontext + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/init.h b/src/coreclr/src/pal/src/libunwind/src/x86/init.h new file mode 100644 index 00000000000000..b0db8d337dfd36 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/init.h @@ -0,0 +1,69 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret, i; + + c->dwarf.loc[EAX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EAX); + c->dwarf.loc[ECX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ECX); + c->dwarf.loc[EDX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EDX); + c->dwarf.loc[EBX] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EBX); + c->dwarf.loc[ESP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ESP); + c->dwarf.loc[EBP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EBP); + c->dwarf.loc[ESI] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ESI); + c->dwarf.loc[EDI] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EDI); + c->dwarf.loc[EIP] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EIP); + c->dwarf.loc[EFLAGS] = DWARF_REG_LOC (&c->dwarf, UNW_X86_EFLAGS); + c->dwarf.loc[TRAPNO] = DWARF_REG_LOC (&c->dwarf, UNW_X86_TRAPNO); + c->dwarf.loc[ST0] = DWARF_REG_LOC (&c->dwarf, UNW_X86_ST0); + for (i = ST0 + 1; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_X86_ESP), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = X86_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/x86/is_fpreg.c new file mode 100644 index 00000000000000..a3a98ac8d3381c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/is_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_is_fpreg (int regnum) +{ + return ((regnum >= UNW_X86_ST0 && regnum <= UNW_X86_ST7) + || (regnum >= UNW_X86_XMM0_lo && regnum <= UNW_X86_XMM7_hi) + || (regnum >= UNW_X86_XMM0 && regnum <= UNW_X86_XMM7)); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/longjmp.S b/src/coreclr/src/pal/src/libunwind/src/x86/longjmp.S new file mode 100644 index 00000000000000..05173d0c109825 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/longjmp.S @@ -0,0 +1,39 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + + .globl _UI_longjmp_cont + + .type _UI_longjmp_cont, @function +_UI_longjmp_cont: + .cfi_startproc + .cfi_register 8, 0 /* IP saved in EAX */ + push %eax /* push target IP as return address */ + .cfi_restore 8 + mov %edx, %eax /* set up return-value */ + ret + .cfi_endproc + .size _UI_siglongjmp_cont, .-_UI_longjmp_cont + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/offsets.h b/src/coreclr/src/pal/src/libunwind/src/x86/offsets.h new file mode 100644 index 00000000000000..e5aec7f588849f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/offsets.h @@ -0,0 +1,140 @@ +/* Linux-specific definitions: */ + +/* Define various structure offsets to simplify cross-compilation. */ + +/* Offsets for x86 Linux "ucontext_t": */ + +#define LINUX_UC_FLAGS_OFF 0x00 +#define LINUX_UC_LINK_OFF 0x04 +#define LINUX_UC_STACK_OFF 0x08 +#define LINUX_UC_MCONTEXT_OFF 0x14 +#define LINUX_UC_SIGMASK_OFF 0x6c +#define LINUX_UC_FPREGS_MEM_OFF 0xec + +/* The struct sigcontext is located at an offset of 4 + from the stack pointer in the signal frame. */ + +/* Offsets for x86 Linux "struct sigcontext": */ + +#define LINUX_SC_GS_OFF 0x00 +#define LINUX_SC_GSH_OFF 0x02 +#define LINUX_SC_FS_OFF 0x04 +#define LINUX_SC_FSH_OFF 0x06 +#define LINUX_SC_ES_OFF 0x08 +#define LINUX_SC_ESH_OFF 0x0a +#define LINUX_SC_DS_OFF 0x0c +#define LINUX_SC_DSH_OFF 0x0e +#define LINUX_SC_EDI_OFF 0x10 +#define LINUX_SC_ESI_OFF 0x14 +#define LINUX_SC_EBP_OFF 0x18 +#define LINUX_SC_ESP_OFF 0x1c +#define LINUX_SC_EBX_OFF 0x20 +#define LINUX_SC_EDX_OFF 0x24 +#define LINUX_SC_ECX_OFF 0x28 +#define LINUX_SC_EAX_OFF 0x2c +#define LINUX_SC_TRAPNO_OFF 0x30 +#define LINUX_SC_ERR_OFF 0x34 +#define LINUX_SC_EIP_OFF 0x38 +#define LINUX_SC_CS_OFF 0x3c +#define LINUX_SC_CSH_OFF 0x3e +#define LINUX_SC_EFLAGS_OFF 0x40 +#define LINUX_SC_ESP_AT_SIGNAL_OFF 0x44 +#define LINUX_SC_SS_OFF 0x48 +#define LINUX_SC_SSH_OFF 0x4a +#define LINUX_SC_FPSTATE_OFF 0x4c +#define LINUX_SC_OLDMASK_OFF 0x50 +#define LINUX_SC_CR2_OFF 0x54 + +/* Offsets for x86 Linux "struct _fpstate": */ + +#define LINUX_FPSTATE_CW_OFF 0x000 +#define LINUX_FPSTATE_SW_OFF 0x004 +#define LINUX_FPSTATE_TAG_OFF 0x008 +#define LINUX_FPSTATE_IPOFF_OFF 0x00c +#define LINUX_FPSTATE_CSSEL_OFF 0x010 +#define LINUX_FPSTATE_DATAOFF_OFF 0x014 +#define LINUX_FPSTATE_DATASEL_OFF 0x018 +#define LINUX_FPSTATE_ST0_OFF 0x01c +#define LINUX_FPSTATE_ST1_OFF 0x026 +#define LINUX_FPSTATE_ST2_OFF 0x030 +#define LINUX_FPSTATE_ST3_OFF 0x03a +#define LINUX_FPSTATE_ST4_OFF 0x044 +#define LINUX_FPSTATE_ST5_OFF 0x04e +#define LINUX_FPSTATE_ST6_OFF 0x058 +#define LINUX_FPSTATE_ST7_OFF 0x062 +#define LINUX_FPSTATE_STATUS_OFF 0x06c +#define LINUX_FPSTATE_MAGIC_OFF 0x06e +#define LINUX_FPSTATE_FXSR_ENV_OFF 0x070 +#define LINUX_FPSTATE_MXCSR_OFF 0x088 +#define LINUX_FPSTATE_FXSR_ST0_OFF 0x090 +#define LINUX_FPSTATE_FXSR_ST1_OFF 0x0a0 +#define LINUX_FPSTATE_FXSR_ST2_OFF 0x0b0 +#define LINUX_FPSTATE_FXSR_ST3_OFF 0x0c0 +#define LINUX_FPSTATE_FXSR_ST4_OFF 0x0d0 +#define LINUX_FPSTATE_FXSR_ST5_OFF 0x0e0 +#define LINUX_FPSTATE_FXSR_ST6_OFF 0x0f0 +#define LINUX_FPSTATE_FXSR_ST7_OFF 0x100 +#define LINUX_FPSTATE_XMM0_OFF 0x110 +#define LINUX_FPSTATE_XMM1_OFF 0x120 +#define LINUX_FPSTATE_XMM2_OFF 0x130 +#define LINUX_FPSTATE_XMM3_OFF 0x140 +#define LINUX_FPSTATE_XMM4_OFF 0x150 +#define LINUX_FPSTATE_XMM5_OFF 0x160 +#define LINUX_FPSTATE_XMM6_OFF 0x170 +#define LINUX_FPSTATE_XMM7_OFF 0x180 + +/* FreeBSD-specific definitions: */ + +#define FREEBSD_SC_UCONTEXT_OFF 0x20 +#define FREEBSD_UC_MCONTEXT_OFF 0x10 + +#define FREEBSD_UC_MCONTEXT_GS_OFF 0x14 +#define FREEBSD_UC_MCONTEXT_FS_OFF 0x18 +#define FREEBSD_UC_MCONTEXT_ES_OFF 0x1c +#define FREEBSD_UC_MCONTEXT_DS_OFF 0x20 +#define FREEBSD_UC_MCONTEXT_EDI_OFF 0x24 +#define FREEBSD_UC_MCONTEXT_ESI_OFF 0x28 +#define FREEBSD_UC_MCONTEXT_EBP_OFF 0x2c +#define FREEBSD_UC_MCONTEXT_EBX_OFF 0x34 +#define FREEBSD_UC_MCONTEXT_EDX_OFF 0x38 +#define FREEBSD_UC_MCONTEXT_ECX_OFF 0x3c +#define FREEBSD_UC_MCONTEXT_EAX_OFF 0x40 +#define FREEBSD_UC_MCONTEXT_TRAPNO_OFF 0x44 +#define FREEBSD_UC_MCONTEXT_EIP_OFF 0x4c +#define FREEBSD_UC_MCONTEXT_ESP_OFF 0x58 +#define FREEBSD_UC_MCONTEXT_CS_OFF 0x50 +#define FREEBSD_UC_MCONTEXT_EFLAGS_OFF 0x54 +#define FREEBSD_UC_MCONTEXT_SS_OFF 0x5c +#define FREEBSD_UC_MCONTEXT_MC_LEN_OFF 0x60 +#define FREEBSD_UC_MCONTEXT_FPFORMAT_OFF 0x64 +#define FREEBSD_UC_MCONTEXT_OWNEDFP_OFF 0x68 +#define FREEBSD_UC_MCONTEXT_FPSTATE_OFF 0x70 + +#define FREEBSD_UC_MCONTEXT_CW_OFF 0x70 +#define FREEBSD_UC_MCONTEXT_SW_OFF 0x74 +#define FREEBSD_UC_MCONTEXT_TAG_OFF 0x78 +#define FREEBSD_UC_MCONTEXT_IPOFF_OFF 0x7c +#define FREEBSD_UC_MCONTEXT_CSSEL_OFF 0x80 +#define FREEBSD_UC_MCONTEXT_DATAOFF_OFF 0x84 +#define FREEBSD_US_MCONTEXT_DATASEL_OFF 0x88 +#define FREEBSD_UC_MCONTEXT_ST0_OFF 0x8c + +#define FREEBSD_UC_MCONTEXT_CW_XMM_OFF 0x70 +#define FREEBSD_UC_MCONTEXT_SW_XMM_OFF 0x72 +#define FREEBSD_UC_MCONTEXT_TAG_XMM_OFF 0x74 +#define FREEBSD_UC_MCONTEXT_IPOFF_XMM_OFF 0x78 +#define FREEBSD_UC_MCONTEXT_CSSEL_XMM_OFF 0x7c +#define FREEBSD_UC_MCONTEXT_DATAOFF_XMM_OFF 0x80 +#define FREEBSD_US_MCONTEXT_DATASEL_XMM_OFF 0x84 +#define FREEBSD_UC_MCONTEXT_MXCSR_XMM_OFF 0x88 +#define FREEBSD_UC_MCONTEXT_ST0_XMM_OFF 0x90 +#define FREEBSD_UC_MCONTEXT_XMM0_OFF 0x110 + +#define FREEBSD_UC_MCONTEXT_MC_LEN_VAL 0x280 +#define FREEBSD_UC_MCONTEXT_FPFMT_NODEV 0x10000 +#define FREEBSD_UC_MCONTEXT_FPFMT_387 0x10001 +#define FREEBSD_UC_MCONTEXT_FPFMT_XMM 0x10002 +#define FREEBSD_UC_MCONTEXT_FPOWNED_NONE 0x20000 +#define FREEBSD_UC_MCONTEXT_FPOWNED_FPU 0x20001 +#define FREEBSD_UC_MCONTEXT_FPOWNED_PCB 0x20002 + diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/regname.c b/src/coreclr/src/pal/src/libunwind/src/x86/regname.c new file mode 100644 index 00000000000000..11f62280413007 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/regname.c @@ -0,0 +1,27 @@ +#include "unwind_i.h" + +static const char *regname[] = + { + "eax", "edx", "ecx", "ebx", "esi", "edi", "ebp", "esp", "eip", + "eflags", "trapno", + "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", + "fcw", "fsw", "ftw", "fop", "fcs", "fip", "fea", "fds", + "xmm0_lo", "xmm0_hi", "xmm1_lo", "xmm1_hi", + "xmm2_lo", "xmm2_hi", "xmm3_lo", "xmm3_hi", + "xmm4_lo", "xmm4_hi", "xmm5_lo", "xmm5_hi", + "xmm6_lo", "xmm6_hi", "xmm7_lo", "xmm7_hi", + "mxcsr", + "gs", "fs", "es", "ds", "ss", "cs", + "tss", "ldt", + "cfi", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/x86/siglongjmp.S new file mode 100644 index 00000000000000..32bba3b3b69411 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/siglongjmp.S @@ -0,0 +1,92 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2011 Konstantin Belousov + +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. */ + + .globl _UI_siglongjmp_cont + +#if defined(__linux__) +#define SIG_SETMASK 2 +#elif defined(__FreeBSD__) +#define SIG_SETMASK 3 +#endif + + /* Stack layout at this point: + + +------------+ <- original $esp (at time of setjmp() call) + | sigmask[1] | + +------------+ + | sigmask[0] | + +------------+ + */ + + .type _UI_siglongjmp_cont, @function +_UI_siglongjmp_cont: + .cfi_startproc +#ifdef __linux__ + .cfi_register 8, 0 /* IP saved in EAX */ + .cfi_def_cfa_offset 8 + mov %esp, %ecx /* pass address of signal mask in 3rd sc arg */ + push %eax /* save target IP */ + .cfi_adjust_cfa_offset 4 + .cfi_offset 8, -12 + push %edx /* save return value */ + .cfi_adjust_cfa_offset 4 + push %ebx /* save %ebx (preserved) */ + .cfi_adjust_cfa_offset 4 + .cfi_offset 3, -20 + mov $SIG_SETMASK, %ebx /* 1st syscall arg (how) */ + xor %edx, %edx /* pass NULL as 3rd syscall arg (old maskp) */ + int $0x80 + pop %ebx /* restore %ebx */ + .cfi_adjust_cfa_offset -4 + .cfi_restore 3 + pop %eax /* fetch return value */ + .cfi_adjust_cfa_offset -4 + pop %edx /* pop target IP */ + .cfi_adjust_cfa_offset -4 + .cfi_register 8, 2 /* saved IP is now n EDX */ + lea 8(%esp), %esp /* pop sigmask */ + .cfi_adjust_cfa_offset -4 + jmp *%edx +#elif defined(__FreeBSD__) + pushl %eax + pushl %edx + pushl $0 + pushl %ecx + pushl $SIG_SETMASK + movl $340,%eax + pushl %eax + int $0x80 + addl $16,%esp + popl %eax + popl %edx + jmp *%edx +#else +#error Port me +#endif + .cfi_endproc + .size _UI_siglongjmp_cont, .-_UI_siglongjmp_cont + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/x86/unwind_i.h new file mode 100644 index 00000000000000..caa7e02dee40e0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86/unwind_i.h @@ -0,0 +1,68 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" + +/* DWARF column numbers: */ +#define EAX 0 +#define ECX 1 +#define EDX 2 +#define EBX 3 +#define ESP 4 +#define EBP 5 +#define ESI 6 +#define EDI 7 +#define EIP 8 +#define EFLAGS 9 +#define TRAPNO 10 +#define ST0 11 + +#define x86_lock UNW_OBJ(lock) +#define x86_local_resume UNW_OBJ(local_resume) +#define x86_local_addr_space_init UNW_OBJ(local_addr_space_init) +#define x86_scratch_loc UNW_OBJ(scratch_loc) +#define x86_get_scratch_loc UNW_OBJ(get_scratch_loc) +#define x86_r_uc_addr UNW_OBJ(r_uc_addr) +#define x86_sigreturn UNW_OBJ(sigreturn) + +extern void x86_local_addr_space_init (void); +extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +extern dwarf_loc_t x86_scratch_loc (struct cursor *c, unw_regnum_t reg); +extern dwarf_loc_t x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg); +extern void *x86_r_uc_addr (ucontext_t *uc, int reg); + +extern void x86_sigreturn (unw_cursor_t *cursor); +#define x86_handle_signal_frame UNW_OBJ(handle_signal_frame) +extern int x86_handle_signal_frame(unw_cursor_t *cursor); + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gapply_reg_state.c new file mode 100644 index 00000000000000..82f056da67ebf5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gcreate_addr_space.c new file mode 100644 index 00000000000000..9b2db9810abe00 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gcreate_addr_space.c @@ -0,0 +1,61 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#if defined(_LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#endif + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * x86_64 supports only little-endian. + */ + if (byte_order != 0 && byte_order != __LITTLE_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_proc_info.c new file mode 100644 index 00000000000000..50de1e423c2c9e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_proc_info.c @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + + if (dwarf_make_proc_info (&c->dwarf) < 0) + { + /* On x86-64, some key routines such as _start() and _dl_start() + are missing DWARF unwind info. We don't want to fail in that + case, because those frames are uninteresting and just mark + the end of the frame-chain anyhow. */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 1; + return 0; + } + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c new file mode 100644 index 00000000000000..40568700e0e401 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break; + case UNW_X86_64_RSP: loc = c->dwarf.loc[RSP]; break; + case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break; + case UNW_X86_64_R12: loc = c->dwarf.loc[R12]; break; + case UNW_X86_64_R13: loc = c->dwarf.loc[R13]; break; + case UNW_X86_64_R14: loc = c->dwarf.loc[R14]; break; + case UNW_X86_64_R15: loc = c->dwarf.loc[R15]; break; + case UNW_X86_64_RIP: loc = c->dwarf.loc[RIP]; break; + + default: + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c new file mode 100644 index 00000000000000..9a7b1957eb8d99 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c @@ -0,0 +1,109 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "config.h" +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (x86_64_lock); +#ifdef HAVE_ATOMIC_OPS_H + HIDDEN AO_t tdep_init_done; +#else + HIDDEN int tdep_init_done; +#endif + +/* See comments for svr4_dbx_register_map[] in gcc/config/i386/i386.c. */ + +HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_NUM_PRESERVED_REGS] = + { + UNW_X86_64_RAX, + UNW_X86_64_RDX, + UNW_X86_64_RCX, + UNW_X86_64_RBX, + UNW_X86_64_RSI, + UNW_X86_64_RDI, + UNW_X86_64_RBP, + UNW_X86_64_RSP, + UNW_X86_64_R8, + UNW_X86_64_R9, + UNW_X86_64_R10, + UNW_X86_64_R11, + UNW_X86_64_R12, + UNW_X86_64_R13, + UNW_X86_64_R14, + UNW_X86_64_R15, + UNW_X86_64_RIP, +#ifdef CONFIG_MSABI_SUPPORT + UNW_X86_64_XMM0, + UNW_X86_64_XMM1, + UNW_X86_64_XMM2, + UNW_X86_64_XMM3, + UNW_X86_64_XMM4, + UNW_X86_64_XMM5, + UNW_X86_64_XMM6, + UNW_X86_64_XMM7, + UNW_X86_64_XMM8, + UNW_X86_64_XMM9, + UNW_X86_64_XMM10, + UNW_X86_64_XMM11, + UNW_X86_64_XMM12, + UNW_X86_64_XMM13, + UNW_X86_64_XMM14, + UNW_X86_64_XMM15 +#endif + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + intrmask_t full_mask; + sigfillset (&full_mask); + + SIGPROCMASK (SIG_SETMASK, &full_mask, &saved_mask); + mutex_lock (&x86_64_lock); + { + if (atomic_read(&tdep_init_done)) + /* another thread else beat us to it... */ + goto out; + + sigfillset (&unwi_full_mask); + mi_init (); + + dwarf_init (); + + tdep_init_mem_validate (); + +#ifndef UNW_REMOTE_ONLY + x86_64_local_addr_space_init (); +#endif + fetch_and_add1(&tdep_init_done); /* signal that we're initialized... */ + } + out: + mutex_unlock(&x86_64_lock); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c new file mode 100644 index 00000000000000..fd8d418b1a5762 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c @@ -0,0 +1,427 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +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. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +#define PAGE_SIZE 4096 +#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) + +static int mem_validate_pipe[2] = {-1, -1}; + +#ifdef HAVE_PIPE2 +static inline void +do_pipe2 (int pipefd[2]) +{ + pipe2 (pipefd, O_CLOEXEC | O_NONBLOCK); +} +#else +static inline void +set_pipe_flags (int fd) +{ + int fd_flags = fcntl (fd, F_GETFD, 0); + int status_flags = fcntl (fd, F_GETFL, 0); + + fd_flags |= FD_CLOEXEC; + fcntl (fd, F_SETFD, fd_flags); + + status_flags |= O_NONBLOCK; + fcntl (fd, F_SETFL, status_flags); +} + +static inline void +do_pipe2 (int pipefd[2]) +{ + pipe (pipefd); + set_pipe_flags(pipefd[0]); + set_pipe_flags(pipefd[1]); +} +#endif + +static inline void +open_pipe (void) +{ + if (mem_validate_pipe[0] != -1) + close (mem_validate_pipe[0]); + if (mem_validate_pipe[1] != -1) + close (mem_validate_pipe[1]); + + do_pipe2 (mem_validate_pipe); +} + +ALWAYS_INLINE +static int +write_validate (void *addr) +{ + int ret = -1; + ssize_t bytes = 0; + + do + { + char buf; + bytes = read (mem_validate_pipe[0], &buf, 1); + } + while ( errno == EINTR ); + + int valid_read = (bytes > 0 || errno == EAGAIN || errno == EWOULDBLOCK); + if (!valid_read) + { + // re-open closed pipe + open_pipe (); + } + + do + { + /* use syscall insteadof write() so that ASAN does not complain */ + ret = syscall (SYS_write, mem_validate_pipe[1], addr, 1); + } + while ( errno == EINTR ); + + return ret; +} + +static int (*mem_validate_func) (void *addr, size_t len); +static int msync_validate (void *addr, size_t len) +{ + if (msync (addr, len, MS_ASYNC) != 0) + { + return -1; + } + + return write_validate (addr); +} + +#ifdef HAVE_MINCORE +static int mincore_validate (void *addr, size_t len) +{ + unsigned char mvec[2]; /* Unaligned access may cross page boundary */ + + /* mincore could fail with EAGAIN but we conservatively return -1 + instead of looping. */ + if (mincore (addr, len, (char *)mvec) != 0) + { + return -1; + } + + return write_validate (addr); +} +#endif + +/* Initialise memory validation method. On linux kernels <2.6.21, + mincore() returns incorrect value for MAP_PRIVATE mappings, + such as stacks. If mincore() was available at compile time, + check if we can actually use it. If not, use msync() instead. */ +HIDDEN void +tdep_init_mem_validate (void) +{ + open_pipe (); + +#ifdef HAVE_MINCORE + unsigned char present = 1; + unw_word_t addr = PAGE_START((unw_word_t)&present); + unsigned char mvec[1]; + int ret; + while ((ret = mincore ((void*)addr, PAGE_SIZE, (char *)mvec)) == -1 && + errno == EAGAIN) {} + if (ret == 0) + { + Debug(1, "using mincore to validate memory\n"); + mem_validate_func = mincore_validate; + } + else +#endif + { + Debug(1, "using msync to validate memory\n"); + mem_validate_func = msync_validate; + } +} + +/* Cache of already validated addresses */ +#define NLGA 4 +#if defined(HAVE___THREAD) && HAVE___THREAD +// thread-local variant +static __thread unw_word_t last_good_addr[NLGA]; +static __thread int lga_victim; + +static int +is_cached_valid_mem(unw_word_t addr) +{ + int i; + for (i = 0; i < NLGA; i++) + { + if (addr == last_good_addr[i]) + return 1; + } + return 0; +} + +static void +cache_valid_mem(unw_word_t addr) +{ + int i, victim; + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (last_good_addr[victim] == 0) { + last_good_addr[victim] = addr; + return; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; +} + +#elif HAVE_ATOMIC_OPS_H +// global, thread safe variant +static AO_T last_good_addr[NLGA]; +static AO_T lga_victim; + +static int +is_cached_valid_mem(unw_word_t addr) +{ + int i; + for (i = 0; i < NLGA; i++) + { + if (addr == AO_load(&last_good_addr[i])) + return 1; + } + return 0; +} + +static void +cache_valid_mem(unw_word_t addr) +{ + int i, victim; + victim = AO_load(&lga_victim); + for (i = 0; i < NLGA; i++) { + if (AO_compare_and_swap(&last_good_addr[victim], 0, addr)) { + return; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + AO_store(&last_good_addr[victim], addr); + victim = (victim + 1) % NLGA; + AO_store(&lga_victim, victim); +} +#else +// disabled, no cache +static int +is_cached_valid_mem(unw_word_t addr UNUSED) +{ + return 0; +} + +static void +cache_valid_mem(unw_word_t addr UNUSED) +{ +} +#endif + +static int +validate_mem (unw_word_t addr) +{ + size_t len; + + if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) + len = PAGE_SIZE; + else + len = PAGE_SIZE * 2; + + addr = PAGE_START(addr); + + if (addr == 0) + return -1; + + if (is_cached_valid_mem(addr)) + return 0; + + if (mem_validate_func ((void *) addr, len) == -1) + return -1; + + cache_valid_mem(addr); + + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (unlikely (write)) + { + Debug (16, "mem[%016lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + /* validate address */ + const struct cursor *c = (const struct cursor *)arg; + if (likely (c != NULL) && unlikely (c->validate) + && unlikely (validate_mem (addr))) { + Debug (16, "mem[%016lx] -> invalid\n", addr); + return -1; + } + *val = *(unw_word_t *) addr; + Debug (16, "mem[%016lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = ((struct cursor *)arg)->uc; + + if (unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = x86_64_r_uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- 0x%016lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> 0x%016lx\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = ((struct cursor *)arg)->uc; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = x86_64_r_uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +x86_64_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = x86_64_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c new file mode 100644 index 00000000000000..12a9e3e4c96aa8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c @@ -0,0 +1,81 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (unlikely (!atomic_read(&tdep_init_done))) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = c; + c->uc = uc; + c->validate = 0; + return common_init (c, use_prev_instr); +} + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c new file mode 100644 index 00000000000000..f411b233317823 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!atomic_read(&tdep_init_done)) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + if (as == unw_local_addr_space) + { + c->dwarf.as_arg = c; + c->uc = as_arg; + } + else + { + c->dwarf.as_arg = as_arg; + c->uc = NULL; + } + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-freebsd.c new file mode 100644 index 00000000000000..883025c88ddc99 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-freebsd.c @@ -0,0 +1,218 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010 Konstantin Belousov + +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. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include "unwind_i.h" +#include "ucontext_i.h" + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + /* XXXKIB */ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, w2, b0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + /* Check if RIP points at sigreturn sequence. +48 8d 7c 24 10 lea SIGF_UC(%rsp),%rdi +6a 00 pushq $0 +48 c7 c0 a1 01 00 00 movq $SYS_sigreturn,%rax +0f 05 syscall +f4 0: hlt +eb fd jmp 0b + */ + + ip = c->dwarf.ip; + c->sigcontext_format = X86_64_SCF_NONE; + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 16, &w2, 0, arg)) < 0) + return 0; + w2 &= 0xffffff; + if (w0 == 0x48006a10247c8d48 && + w1 == 0x050f000001a1c0c7 && + w2 == 0x0000000000fdebf4) + { + c->sigcontext_format = X86_64_SCF_FREEBSD_SIGFRAME; + return (c->sigcontext_format); + } + /* Check if RIP points at standard syscall sequence. +49 89 ca mov %rcx,%r10 +0f 05 syscall + */ + if ((ret = (*a->access_mem) (as, ip - 5, &b0, 0, arg)) < 0) + return (0); + Debug (12, "b0 0x%lx\n", b0); + if ((b0 & 0xffffffffffffff) == 0x050fca89490000 || + (b0 & 0xffffffffff) == 0x050fca8949) + { + c->sigcontext_format = X86_64_SCF_FREEBSD_SYSCALL; + return (c->sigcontext_format); + } + return (X86_64_SCF_NONE); +} + +HIDDEN int +x86_64_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t ucontext; + int ret; + + if (c->sigcontext_format == X86_64_SCF_FREEBSD_SIGFRAME) + { + ucontext = c->dwarf.cfa + offsetof(struct sigframe, sf_uc); + c->sigcontext_addr = c->dwarf.cfa; + Debug(1, "signal frame, skip over trampoline\n"); + + struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); + ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0); + c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0); + c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0); + c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0); + c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0); + c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0); + c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0); + c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); + c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); + c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); + c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); + c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); + c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); + c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); + c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); + c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); + c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0); + + return 0; + } + else if (c->sigcontext_format == X86_64_SCF_FREEBSD_SYSCALL) + { + c->dwarf.loc[RCX] = c->dwarf.loc[R10]; + /* rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0); */ + /* rbp_loc = c->dwarf.loc[RBP]; */ + c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); + Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", + (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]), + (unsigned long long) c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + c->dwarf.cfa += 8; + c->dwarf.use_prev_instr = 1; + return 1; + } + else + return -UNW_EBADFRAME; + +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_64_r_uc_addr (ucontext_t *uc, int reg) +{ + /* NOTE: common_init() in init.h inlines these for fast path access. */ + void *addr; + + switch (reg) + { + case UNW_X86_64_R8: addr = &uc->uc_mcontext.mc_r8; break; + case UNW_X86_64_R9: addr = &uc->uc_mcontext.mc_r9; break; + case UNW_X86_64_R10: addr = &uc->uc_mcontext.mc_r10; break; + case UNW_X86_64_R11: addr = &uc->uc_mcontext.mc_r11; break; + case UNW_X86_64_R12: addr = &uc->uc_mcontext.mc_r12; break; + case UNW_X86_64_R13: addr = &uc->uc_mcontext.mc_r13; break; + case UNW_X86_64_R14: addr = &uc->uc_mcontext.mc_r14; break; + case UNW_X86_64_R15: addr = &uc->uc_mcontext.mc_r15; break; + case UNW_X86_64_RDI: addr = &uc->uc_mcontext.mc_rdi; break; + case UNW_X86_64_RSI: addr = &uc->uc_mcontext.mc_rsi; break; + case UNW_X86_64_RBP: addr = &uc->uc_mcontext.mc_rbp; break; + case UNW_X86_64_RBX: addr = &uc->uc_mcontext.mc_rbx; break; + case UNW_X86_64_RDX: addr = &uc->uc_mcontext.mc_rdx; break; + case UNW_X86_64_RAX: addr = &uc->uc_mcontext.mc_rax; break; + case UNW_X86_64_RCX: addr = &uc->uc_mcontext.mc_rcx; break; + case UNW_X86_64_RSP: addr = &uc->uc_mcontext.mc_rsp; break; + case UNW_X86_64_RIP: addr = &uc->uc_mcontext.mc_rip; break; + + default: + addr = NULL; + } + return addr; +} + +HIDDEN NORETURN void +x86_64_sigreturn (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = (ucontext_t *)(c->sigcontext_addr + + offsetof(struct sigframe, sf_uc)); + + uc->uc_mcontext.mc_r8 = c->uc->uc_mcontext.mc_r8; + uc->uc_mcontext.mc_r9 = c->uc->uc_mcontext.mc_r9; + uc->uc_mcontext.mc_r10 = c->uc->uc_mcontext.mc_r10; + uc->uc_mcontext.mc_r11 = c->uc->uc_mcontext.mc_r11; + uc->uc_mcontext.mc_r12 = c->uc->uc_mcontext.mc_r12; + uc->uc_mcontext.mc_r13 = c->uc->uc_mcontext.mc_r13; + uc->uc_mcontext.mc_r14 = c->uc->uc_mcontext.mc_r14; + uc->uc_mcontext.mc_r15 = c->uc->uc_mcontext.mc_r15; + uc->uc_mcontext.mc_rdi = c->uc->uc_mcontext.mc_rdi; + uc->uc_mcontext.mc_rsi = c->uc->uc_mcontext.mc_rsi; + uc->uc_mcontext.mc_rbp = c->uc->uc_mcontext.mc_rbp; + uc->uc_mcontext.mc_rbx = c->uc->uc_mcontext.mc_rbx; + uc->uc_mcontext.mc_rdx = c->uc->uc_mcontext.mc_rdx; + uc->uc_mcontext.mc_rax = c->uc->uc_mcontext.mc_rax; + uc->uc_mcontext.mc_rcx = c->uc->uc_mcontext.mc_rcx; + uc->uc_mcontext.mc_rsp = c->uc->uc_mcontext.mc_rsp; + uc->uc_mcontext.mc_rip = c->uc->uc_mcontext.mc_rip; + + Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", + (unsigned long long) c->dwarf.ip, uc); + sigreturn(uc); + abort(); +} +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-linux.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-linux.c new file mode 100644 index 00000000000000..bd142345eddd4f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-linux.c @@ -0,0 +1,156 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" + +#include + +HIDDEN void +tdep_fetch_frame (struct dwarf_cursor *dw, unw_word_t ip, int need_unwind_info) +{ + struct cursor *c = (struct cursor *) dw; + assert(! need_unwind_info || dw->pi_valid); + assert(! need_unwind_info || dw->pi.unwind_info); + if (dw->pi_valid + && dw->pi.unwind_info + && ((struct dwarf_cie_info *) dw->pi.unwind_info)->signal_frame) + c->sigcontext_format = X86_64_SCF_LINUX_RT_SIGFRAME; + else + c->sigcontext_format = X86_64_SCF_NONE; + + Debug(5, "fetch frame ip=0x%lx cfa=0x%lx format=%d\n", + dw->ip, dw->cfa, c->sigcontext_format); +} + +HIDDEN int +tdep_cache_frame (struct dwarf_cursor *dw) +{ + struct cursor *c = (struct cursor *) dw; + + Debug(5, "cache frame ip=0x%lx cfa=0x%lx format=%d\n", + dw->ip, dw->cfa, c->sigcontext_format); + return c->sigcontext_format; +} + +HIDDEN void +tdep_reuse_frame (struct dwarf_cursor *dw, int frame) +{ + struct cursor *c = (struct cursor *) dw; + c->sigcontext_format = frame; + if (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME) + { + c->frame_info.frame_type = UNW_X86_64_FRAME_SIGRETURN; + /* Offset from cfa to ucontext_t in signal frame. */ + c->frame_info.cfa_reg_offset = 0; + c->sigcontext_addr = dw->cfa; + } + + Debug(5, "reuse frame ip=0x%lx cfa=0x%lx format=%d addr=0x%lx offset=%+d\n", + dw->ip, dw->cfa, c->sigcontext_format, c->sigcontext_addr, + (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME + ? c->frame_info.cfa_reg_offset : 0)); +} + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + return c->sigcontext_format != X86_64_SCF_NONE; +} + +HIDDEN int +x86_64_handle_signal_frame (unw_cursor_t *cursor) +{ +#if UNW_DEBUG /* To silence compiler warnings */ + /* Should not get here because we now use kernel-provided dwarf + information for the signal trampoline and dwarf_step() works. + Hence unw_step() should never call this function. Maybe + restore old non-dwarf signal handling here, but then the + gating on unw_is_signal_frame() needs to be removed. */ + struct cursor *c = (struct cursor *) cursor; + Debug(1, "old format signal frame? format=%d addr=0x%lx cfa=0x%lx\n", + c->sigcontext_format, c->sigcontext_addr, c->dwarf.cfa); +#endif + return -UNW_EBADFRAME; +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_64_r_uc_addr (ucontext_t *uc, int reg) +{ + /* NOTE: common_init() in init.h inlines these for fast path access. */ + void *addr; + + switch (reg) + { + case UNW_X86_64_R8: addr = &uc->uc_mcontext.gregs[REG_R8]; break; + case UNW_X86_64_R9: addr = &uc->uc_mcontext.gregs[REG_R9]; break; + case UNW_X86_64_R10: addr = &uc->uc_mcontext.gregs[REG_R10]; break; + case UNW_X86_64_R11: addr = &uc->uc_mcontext.gregs[REG_R11]; break; + case UNW_X86_64_R12: addr = &uc->uc_mcontext.gregs[REG_R12]; break; + case UNW_X86_64_R13: addr = &uc->uc_mcontext.gregs[REG_R13]; break; + case UNW_X86_64_R14: addr = &uc->uc_mcontext.gregs[REG_R14]; break; + case UNW_X86_64_R15: addr = &uc->uc_mcontext.gregs[REG_R15]; break; + case UNW_X86_64_RDI: addr = &uc->uc_mcontext.gregs[REG_RDI]; break; + case UNW_X86_64_RSI: addr = &uc->uc_mcontext.gregs[REG_RSI]; break; + case UNW_X86_64_RBP: addr = &uc->uc_mcontext.gregs[REG_RBP]; break; + case UNW_X86_64_RBX: addr = &uc->uc_mcontext.gregs[REG_RBX]; break; + case UNW_X86_64_RDX: addr = &uc->uc_mcontext.gregs[REG_RDX]; break; + case UNW_X86_64_RAX: addr = &uc->uc_mcontext.gregs[REG_RAX]; break; + case UNW_X86_64_RCX: addr = &uc->uc_mcontext.gregs[REG_RCX]; break; + case UNW_X86_64_RSP: addr = &uc->uc_mcontext.gregs[REG_RSP]; break; + case UNW_X86_64_RIP: addr = &uc->uc_mcontext.gregs[REG_RIP]; break; + + default: + addr = NULL; + } + return addr; +} + +/* sigreturn() is a no-op on x86_64 glibc. */ +HIDDEN NORETURN void +x86_64_sigreturn (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + mcontext_t *sc_mcontext = &((ucontext_t*)sc)->uc_mcontext; + /* Copy in saved uc - all preserved regs are at the start of sigcontext */ + memcpy(sc_mcontext, &c->uc->uc_mcontext, + DWARF_NUM_PRESERVED_REGS * sizeof(unw_word_t)); + + Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", + (unsigned long long) c->dwarf.ip, sc); + __asm__ __volatile__ ("mov %0, %%rsp;" + "mov %1, %%rax;" + "syscall" + :: "r"(sc), "i"(SYS_rt_sigreturn) + : "memory"); + abort(); +} + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c new file mode 100644 index 00000000000000..75258d61d8755b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c @@ -0,0 +1,133 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" + +#include + +struct sigframe { + uint64_t signo; + uint64_t sip; +}; + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + c->sigcontext_format = (c->dwarf.ip == (unw_word_t)-1) ? + X86_64_SCF_SOLARIS_SIGFRAME : X86_64_SCF_NONE; + + return (c->sigcontext_format); +} + +HIDDEN int +x86_64_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t ucontext = c->dwarf.cfa + sizeof (struct sigframe); + + if (c->sigcontext_format != X86_64_SCF_SOLARIS_SIGFRAME) + return -UNW_EBADFRAME; + + c->sigcontext_addr = c->dwarf.cfa; + + Debug(1, "signal frame cfa = %lx ucontext = %lx\n", + (uint64_t)c->dwarf.cfa, (uint64_t)ucontext); + + struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); + int ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa); + + if (ret < 0) + { + Debug (2, "return %d\n", ret); + return ret; + } + + c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0); + c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0); + c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0); + c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0); + c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0); + c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0); + c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0); + c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); + c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); + c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); + c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); + c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); + c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); + c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); + c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); + c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); + c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0); + + c->dwarf.use_prev_instr = 1; + return 0; +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_64_r_uc_addr (ucontext_t *uc, int reg) +{ + /* NOTE: common_init() in init.h inlines these for fast path access. */ + void *addr; + + switch (reg) + { + case UNW_X86_64_R8: addr = &uc->uc_mcontext.gregs[REG_R8]; break; + case UNW_X86_64_R9: addr = &uc->uc_mcontext.gregs[REG_R9]; break; + case UNW_X86_64_R10: addr = &uc->uc_mcontext.gregs[REG_R10]; break; + case UNW_X86_64_R11: addr = &uc->uc_mcontext.gregs[REG_R11]; break; + case UNW_X86_64_R12: addr = &uc->uc_mcontext.gregs[REG_R12]; break; + case UNW_X86_64_R13: addr = &uc->uc_mcontext.gregs[REG_R13]; break; + case UNW_X86_64_R14: addr = &uc->uc_mcontext.gregs[REG_R14]; break; + case UNW_X86_64_R15: addr = &uc->uc_mcontext.gregs[REG_R15]; break; + case UNW_X86_64_RDI: addr = &uc->uc_mcontext.gregs[REG_RDI]; break; + case UNW_X86_64_RSI: addr = &uc->uc_mcontext.gregs[REG_RSI]; break; + case UNW_X86_64_RBP: addr = &uc->uc_mcontext.gregs[REG_RBP]; break; + case UNW_X86_64_RBX: addr = &uc->uc_mcontext.gregs[REG_RBX]; break; + case UNW_X86_64_RDX: addr = &uc->uc_mcontext.gregs[REG_RDX]; break; + case UNW_X86_64_RAX: addr = &uc->uc_mcontext.gregs[REG_RAX]; break; + case UNW_X86_64_RCX: addr = &uc->uc_mcontext.gregs[REG_RCX]; break; + case UNW_X86_64_RSP: addr = &uc->uc_mcontext.gregs[REG_RSP]; break; + case UNW_X86_64_RIP: addr = &uc->uc_mcontext.gregs[REG_RIP]; break; + + default: + addr = NULL; + } + return addr; +} + +HIDDEN NORETURN void +x86_64_sigreturn (unw_cursor_t *cursor) +{ + abort(); +} + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Greg_states_iterate.c new file mode 100644 index 00000000000000..a17dc1b561d6f8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gregs.c new file mode 100644 index 00000000000000..baf8a24f0b9123 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gregs.c @@ -0,0 +1,138 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +#if 0 +static inline dwarf_loc_t +linux_scratch_loc (struct cursor *c, unw_regnum_t reg) +{ + unw_word_t addr = c->sigcontext_addr; + + switch (c->sigcontext_format) + { + case X86_64_SCF_NONE: + return DWARF_REG_LOC (&c->dwarf, reg); + + case X86_64_SCF_LINUX_RT_SIGFRAME: + addr += LINUX_UC_MCONTEXT_OFF; + break; + + case X86_64_SCF_FREEBSD_SIGFRAME: + addr += FREEBSD_UC_MCONTEXT_OFF; + break; + } + + return DWARF_REG_LOC (&c->dwarf, reg); + +} + +HIDDEN dwarf_loc_t +x86_64_scratch_loc (struct cursor *c, unw_regnum_t reg) +{ + if (c->sigcontext_addr) + return linux_scratch_loc (c, reg); + else + return DWARF_REG_LOC (&c->dwarf, reg); +} +#endif + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + unsigned int mask; + int arg_num; + + switch (reg) + { + + case UNW_X86_64_RIP: + if (write) + c->dwarf.ip = *valp; /* also update the RIP cache */ + loc = c->dwarf.loc[RIP]; + break; + + case UNW_X86_64_CFA: + case UNW_X86_64_RSP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + case UNW_X86_64_RAX: + case UNW_X86_64_RDX: + arg_num = reg - UNW_X86_64_RAX; + mask = (1 << arg_num); + if (write) + { + c->dwarf.eh_args[arg_num] = *valp; + c->dwarf.eh_valid_mask |= mask; + return 0; + } + else if ((c->dwarf.eh_valid_mask & mask) != 0) + { + *valp = c->dwarf.eh_args[arg_num]; + return 0; + } + else + loc = c->dwarf.loc[(reg == UNW_X86_64_RAX) ? RAX : RDX]; + break; + + case UNW_X86_64_RCX: loc = c->dwarf.loc[RCX]; break; + case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break; + + case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break; + case UNW_X86_64_RSI: loc = c->dwarf.loc[RSI]; break; + case UNW_X86_64_RDI: loc = c->dwarf.loc[RDI]; break; + case UNW_X86_64_R8: loc = c->dwarf.loc[R8]; break; + case UNW_X86_64_R9: loc = c->dwarf.loc[R9]; break; + case UNW_X86_64_R10: loc = c->dwarf.loc[R10]; break; + case UNW_X86_64_R11: loc = c->dwarf.loc[R11]; break; + case UNW_X86_64_R12: loc = c->dwarf.loc[R12]; break; + case UNW_X86_64_R13: loc = c->dwarf.loc[R13]; break; + case UNW_X86_64_R14: loc = c->dwarf.loc[R14]; break; + case UNW_X86_64_R15: loc = c->dwarf.loc[R15]; break; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + return -UNW_EBADREG; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gresume.c new file mode 100644 index 00000000000000..944cdaae192d86 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gresume.c @@ -0,0 +1,123 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "offsets.h" +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = c->uc; + + /* Ensure c->pi is up-to-date. On x86-64, it's relatively common to + be missing DWARF unwind info. We don't want to fail in that + case, because the frame-chain still would let us do a backtrace + at least. */ + dwarf_make_proc_info (&c->dwarf); + + if (unlikely (c->sigcontext_addr != X86_64_SCF_NONE)) + { + x86_64_sigreturn(cursor); + abort(); + } + else + { + Debug (8, "resuming at ip=%llx via setcontext()\n", + (unsigned long long) c->dwarf.ip); + setcontext (uc); + } + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int write, void *); + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int write, void *); + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + access_reg = as->acc.access_reg; + access_fpreg = as->acc.access_fpreg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + (*access_fpreg) (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + (*access_reg) (as, reg, &val, 1, arg); + } + } + + if (c->dwarf.args_size) + { + if (tdep_access_reg (c, UNW_X86_64_RSP, &val, 0) >= 0) + { + val += c->dwarf.args_size; + (*access_reg) (as, UNW_X86_64_RSP, &val, 1, arg); + } + } + return 0; +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c new file mode 100644 index 00000000000000..2a44f873e9edf4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c @@ -0,0 +1,119 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" + +HIDDEN void +tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) +{ + struct cursor *c = (struct cursor *) dwarf_to_cursor (d); + unw_tdep_frame_t *f = &c->frame_info; + + Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld" + " ra=0x%lx rbp [where=%d val=%ld @0x%lx] rsp [where=%d val=%ld @0x%lx]\n", + d->ip, d->cfa, f->frame_type, + rs->reg.where[DWARF_CFA_REG_COLUMN], + rs->reg.val[DWARF_CFA_REG_COLUMN], + rs->reg.val[DWARF_CFA_OFF_COLUMN], + DWARF_GET_LOC(d->loc[rs->ret_addr_column]), + rs->reg.where[RBP], rs->reg.val[RBP], DWARF_GET_LOC(d->loc[RBP]), + rs->reg.where[RSP], rs->reg.val[RSP], DWARF_GET_LOC(d->loc[RSP])); + + if (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR && + rs->reg.where[RBP] == DWARF_WHERE_EXPR) { + /* Check for GCC generated alignment frame for rsp. A simple + * def_cfa_expr that loads a constant offset from rbp, where the + * addres of the rip was pushed on the stack */ + unw_word_t cfa_addr = rs->reg.val[DWARF_CFA_REG_COLUMN]; + unw_word_t rbp_addr = rs->reg.val[RBP]; + unw_word_t cfa_offset; + + int ret = dwarf_stack_aligned(d, cfa_addr, rbp_addr, &cfa_offset); + if (ret) { + f->frame_type = UNW_X86_64_FRAME_ALIGNED; + f->cfa_reg_offset = cfa_offset; + f->cfa_reg_rsp = 0; + } + } + + /* A standard frame is defined as: + - CFA is register-relative offset off RBP or RSP; + - Return address is saved at CFA-8; + - RBP is unsaved or saved at CFA+offset, offset != -1; + - RSP is unsaved or saved at CFA+offset, offset != -1. */ + if (f->frame_type == UNW_X86_64_FRAME_OTHER + && (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG) + && (rs->reg.val[DWARF_CFA_REG_COLUMN] == RBP + || rs->reg.val[DWARF_CFA_REG_COLUMN] == RSP) + && labs((long) rs->reg.val[DWARF_CFA_OFF_COLUMN]) < (1 << 28) + && DWARF_GET_LOC(d->loc[rs->ret_addr_column]) == d->cfa-8 + && (rs->reg.where[RBP] == DWARF_WHERE_UNDEF + || rs->reg.where[RBP] == DWARF_WHERE_SAME + || (rs->reg.where[RBP] == DWARF_WHERE_CFAREL + && labs((long) rs->reg.val[RBP]) < (1 << 14) + && rs->reg.val[RBP]+1 != 0)) + && (rs->reg.where[RSP] == DWARF_WHERE_UNDEF + || rs->reg.where[RSP] == DWARF_WHERE_SAME + || (rs->reg.where[RSP] == DWARF_WHERE_CFAREL + && labs((long) rs->reg.val[RSP]) < (1 << 14) + && rs->reg.val[RSP]+1 != 0))) + { + /* Save information for a standard frame. */ + f->frame_type = UNW_X86_64_FRAME_STANDARD; + f->cfa_reg_rsp = (rs->reg.val[DWARF_CFA_REG_COLUMN] == RSP); + f->cfa_reg_offset = rs->reg.val[DWARF_CFA_OFF_COLUMN]; + if (rs->reg.where[RBP] == DWARF_WHERE_CFAREL) + f->rbp_cfa_offset = rs->reg.val[RBP]; + if (rs->reg.where[RSP] == DWARF_WHERE_CFAREL) + f->rsp_cfa_offset = rs->reg.val[RSP]; + Debug (4, " standard frame\n"); + } + + /* Signal frame was detected via augmentation in tdep_fetch_frame() */ + else if (f->frame_type == UNW_X86_64_FRAME_SIGRETURN) + { + /* Later we are going to fish out {RBP,RSP,RIP} from sigcontext via + their ucontext_t offsets. Confirm DWARF info agrees with the + offsets we expect. */ + +#ifndef NDEBUG + const unw_word_t uc = c->sigcontext_addr; + + assert (DWARF_GET_LOC(d->loc[RIP]) - uc == UC_MCONTEXT_GREGS_RIP); + assert (DWARF_GET_LOC(d->loc[RBP]) - uc == UC_MCONTEXT_GREGS_RBP); + assert (DWARF_GET_LOC(d->loc[RSP]) - uc == UC_MCONTEXT_GREGS_RSP); +#endif + + Debug (4, " sigreturn frame\n"); + } + + else if (f->frame_type == UNW_X86_64_FRAME_ALIGNED) { + Debug (4, " aligned frame, offset %i\n", f->cfa_reg_offset); + } + /* PLT and guessed RBP-walked frames are handled in unw_step(). */ + else { + Debug (4, " unusual frame\n"); + } +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c new file mode 100644 index 00000000000000..d4831197cb39ed --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c @@ -0,0 +1,290 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include + +/* Recognise PLT entries such as: + 3bdf0: ff 25 e2 49 13 00 jmpq *0x1349e2(%rip) + 3bdf6: 68 ae 03 00 00 pushq $0x3ae + 3bdfb: e9 00 c5 ff ff jmpq 38300 <_init+0x18> */ +static int +is_plt_entry (struct dwarf_cursor *c) +{ + unw_word_t w0, w1; + unw_accessors_t *a; + int ret; + + a = unw_get_accessors_int (c->as); + if ((ret = (*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg)) < 0 + || (ret = (*a->access_mem) (c->as, c->ip + 8, &w1, 0, c->as_arg)) < 0) + return 0; + + ret = (((w0 & 0xffff) == 0x25ff) + && (((w0 >> 48) & 0xff) == 0x68) + && (((w1 >> 24) & 0xff) == 0xe9)); + + Debug (14, "ip=0x%lx => 0x%016lx 0x%016lx, ret = %d\n", c->ip, w0, w1, ret); + return ret; +} + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret, i; + +#if CONSERVATIVE_CHECKS + int val = c->validate; + c->validate = 1; +#endif + + Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n", + c, c->dwarf.ip, c->dwarf.cfa); + + /* Try DWARF-based unwinding... */ + c->sigcontext_format = X86_64_SCF_NONE; + ret = dwarf_step (&c->dwarf); + +#if CONSERVATIVE_CHECKS + c->validate = val; +#endif + + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + if (likely (ret >= 0)) + { + /* x86_64 ABI specifies that end of call-chain is marked with a + NULL RBP or undefined return address */ + if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) + { + c->dwarf.ip = 0; + ret = 0; + } + } + else + { + /* DWARF failed. There isn't much of a usable frame-chain on x86-64, + but we do need to handle two special-cases: + + (i) signal trampoline: Old kernels and older libcs don't + export the vDSO needed to get proper unwind info for the + trampoline. Recognize that case by looking at the code + and filling in things by hand. + + (ii) PLT (shared-library) call-stubs: PLT stubs are invoked + via CALLQ. Try this for all non-signal trampoline + code. */ + + unw_word_t invalid_prev_rip = 0; + unw_word_t prev_ip = c->dwarf.ip, prev_cfa = c->dwarf.cfa; + struct dwarf_loc rbp_loc, rsp_loc, rip_loc; + + /* We could get here because of missing/bad unwind information. + Validate all addresses before dereferencing. */ + c->validate = 1; + + Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); + + if (unw_is_signal_frame (cursor) > 0) + { + ret = x86_64_handle_signal_frame(cursor); + if (ret < 0) + { + Debug (2, "returning 0\n"); + return 0; + } + } + else if (is_plt_entry (&c->dwarf)) + { + /* Like regular frame, CFA = RSP+8, RA = [CFA-8], no regs saved. */ + Debug (2, "found plt entry\n"); + c->frame_info.cfa_reg_offset = 8; + c->frame_info.cfa_reg_rsp = -1; + c->frame_info.frame_type = UNW_X86_64_FRAME_STANDARD; + c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); + c->dwarf.cfa += 8; + } + else if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) + { + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + } + else + { + unw_word_t rbp; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RBP], &rbp); + if (ret < 0) + { + Debug (2, "returning %d [RBP=0x%lx]\n", ret, + DWARF_GET_LOC (c->dwarf.loc[RBP])); + return ret; + } + + unw_word_t not_used; + invalid_prev_rip = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, prev_ip), ¬_used); + + if (!rbp && invalid_prev_rip == 0) + { + /* Looks like we may have reached the end of the call-chain. */ + rbp_loc = DWARF_NULL_LOC; + rsp_loc = DWARF_NULL_LOC; + rip_loc = DWARF_NULL_LOC; + } + else + { + /* + * Check if previous RIP was invalid + * This could happen if a bad function pointer was + * followed and so the stack wasn't updated by the + * preamble + */ + int rip_fixup_success = 0; + if (invalid_prev_rip != 0) + { + Debug (2, "Previous RIP 0x%lx was invalid, attempting fixup\n", prev_ip); + unw_word_t rsp; + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RSP], &rsp); + + /*Test to see if what we think is the previous RIP is valid*/ + unw_word_t new_ip = 0; + if (dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip) == 0) + { + Debug (2, "RSP 0x%lx looks valid\n", rsp); + if ((ret = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used)) == 0) + { + Debug (2, "new_ip 0x%lx looks valid\n", new_ip); + rip_fixup_success = 1; + c->frame_info.cfa_reg_offset = 8; + c->frame_info.cfa_reg_rsp = 1; + c->frame_info.rbp_cfa_offset = -1; + c->frame_info.rsp_cfa_offset = -1; + c->frame_info.frame_type = UNW_X86_64_FRAME_OTHER; + /* + * The call should have pushed RIP to the stack + * and since there was no preamble RSP hasn't been + * touched so RIP should be at RSP. + */ + c->dwarf.cfa += 8; + /* Optimised x64 binaries don't use RBP it seems? */ + rbp_loc = DWARF_LOC (rbp, 0); + rsp_loc = DWARF_LOC (rsp, 0); + rip_loc = DWARF_LOC (rsp, 0); + } + else + Debug (2, "new_ip 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used) != 0\n", new_ip); + } + else + Debug (2, "rsp 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip) != 0\n", rsp); + } + /* + * If the previous rip we found on the stack didn't look valid fall back + * to the previous method for finding a valid stack frame + */ + if (!rip_fixup_success) + { + Debug (2, "RIP fixup didn't work, falling back\n"); + unw_word_t rbp1 = 0; + rbp_loc = DWARF_LOC(rbp, 0); + rsp_loc = DWARF_NULL_LOC; + rip_loc = DWARF_LOC (rbp + 8, 0); + ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); + Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", + (unsigned long) DWARF_GET_LOC (c->dwarf.loc[RBP]), + rbp, c->dwarf.cfa, rbp1); + + /* Heuristic to determine incorrect guess. For RBP to be a + valid frame it needs to be above current CFA, but don't + let it go more than a little. Note that we can't deduce + anything about new RBP (rbp1) since it may not be a frame + pointer in the frame above. Just check we get the value. */ + if (ret < 0 + || rbp < c->dwarf.cfa + || (rbp - c->dwarf.cfa) > 0x4000) + { + rip_loc = DWARF_NULL_LOC; + rbp_loc = DWARF_NULL_LOC; + } + + c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; + c->frame_info.cfa_reg_rsp = 0; + c->frame_info.cfa_reg_offset = 16; + c->frame_info.rbp_cfa_offset = -16; + c->dwarf.cfa += 16; + + } + } + /* Mark all registers unsaved */ + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + c->dwarf.loc[RBP] = rbp_loc; + c->dwarf.loc[RSP] = rsp_loc; + c->dwarf.loc[RIP] = rip_loc; + c->dwarf.use_prev_instr = 1; + } + + if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]) && invalid_prev_rip == 0) + { + ret = 0; + Debug (2, "NULL %%rbp loc, returning %d\n", ret); + return ret; + } + if (!DWARF_IS_NULL_LOC (c->dwarf.loc[RIP])) + { + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); + Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", + (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]), + (unsigned long long) c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } +#if __sun + if (c->dwarf.ip == 0) + { + Debug (2, "returning 0\n"); + return ret; + } +#endif + ret = 1; + } + else + c->dwarf.ip = 0; + + if (c->dwarf.ip == prev_ip && c->dwarf.cfa == prev_cfa) + return -UNW_EBADFRAME; + } + Debug (2, "returning %d\n", ret); + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c new file mode 100644 index 00000000000000..824527f9beaac0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c @@ -0,0 +1,551 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" +#include +#include + +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific + +/* Initial hash table size. Table expands by 2 bits (times four). */ +#define HASH_MIN_BITS 14 + +typedef struct +{ + unw_tdep_frame_t *frames; + size_t log_size; + size_t used; + size_t dtor_count; /* Counts how many times our destructor has already + been called. */ +} unw_trace_cache_t; + +static const unw_tdep_frame_t empty_frame = { 0, UNW_X86_64_FRAME_OTHER, -1, -1, 0, -1, -1 }; +static define_lock (trace_init_lock); +static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; +static sig_atomic_t trace_cache_once_happen; +static pthread_key_t trace_cache_key; +static struct mempool trace_cache_pool; +static __thread unw_trace_cache_t *tls_cache; +static __thread int tls_cache_destroyed; + +/* Free memory for a thread's trace cache. */ +static void +trace_cache_free (void *arg) +{ + unw_trace_cache_t *cache = arg; + if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS) + { + /* Not yet our turn to get destroyed. Re-install ourselves into the key. */ + pthread_setspecific(trace_cache_key, cache); + Debug(5, "delayed freeing cache %p (%zx to go)\n", cache, + PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count); + return; + } + tls_cache_destroyed = 1; + tls_cache = NULL; + munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); + mempool_free (&trace_cache_pool, cache); + Debug(5, "freed cache %p\n", cache); +} + +/* Initialise frame tracing for threaded use. */ +static void +trace_cache_init_once (void) +{ + pthread_key_create (&trace_cache_key, &trace_cache_free); + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + trace_cache_once_happen = 1; +} + +static unw_tdep_frame_t * +trace_cache_buckets (size_t n) +{ + unw_tdep_frame_t *frames; + size_t i; + + GET_MEMORY(frames, n * sizeof (unw_tdep_frame_t)); + if (likely(frames != NULL)) + for (i = 0; i < n; ++i) + frames[i] = empty_frame; + + return frames; +} + +/* Allocate and initialise hash table for frame cache lookups. + Returns the cache initialised with (1u << HASH_LOW_BITS) hash + buckets, or NULL if there was a memory allocation problem. */ +static unw_trace_cache_t * +trace_cache_create (void) +{ + unw_trace_cache_t *cache; + + if (tls_cache_destroyed) + { + /* The current thread is in the process of exiting. Don't recreate + cache, as we wouldn't have another chance to free it. */ + Debug(5, "refusing to reallocate cache: " + "thread-locals are being deallocated\n"); + return NULL; + } + + if (! (cache = mempool_alloc(&trace_cache_pool))) + { + Debug(5, "failed to allocate cache\n"); + return NULL; + } + + if (! (cache->frames = trace_cache_buckets(1u << HASH_MIN_BITS))) + { + Debug(5, "failed to allocate buckets\n"); + mempool_free(&trace_cache_pool, cache); + return NULL; + } + + cache->log_size = HASH_MIN_BITS; + cache->used = 0; + cache->dtor_count = 0; + tls_cache_destroyed = 0; /* Paranoia: should already be 0. */ + Debug(5, "allocated cache %p\n", cache); + return cache; +} + +/* Expand the hash table in the frame cache if possible. This always + quadruples the hash size, and clears all previous frame entries. */ +static int +trace_cache_expand (unw_trace_cache_t *cache) +{ + size_t old_size = (1u << cache->log_size); + size_t new_log_size = cache->log_size + 2; + unw_tdep_frame_t *new_frames = trace_cache_buckets (1u << new_log_size); + + if (unlikely(! new_frames)) + { + Debug(5, "failed to expand cache to 2^%lu buckets\n", new_log_size); + return -UNW_ENOMEM; + } + + Debug(5, "expanded cache from 2^%lu to 2^%lu buckets\n", cache->log_size, new_log_size); + munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); + cache->frames = new_frames; + cache->log_size = new_log_size; + cache->used = 0; + return 0; +} + +static unw_trace_cache_t * +trace_cache_get_unthreaded (void) +{ + unw_trace_cache_t *cache; + intrmask_t saved_mask; + static unw_trace_cache_t *global_cache = NULL; + lock_acquire (&trace_init_lock, saved_mask); + if (! global_cache) + { + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + global_cache = trace_cache_create (); + } + cache = global_cache; + lock_release (&trace_init_lock, saved_mask); + Debug(5, "using cache %p\n", cache); + return cache; +} + +/* Get the frame cache for the current thread. Create it if there is none. */ +static unw_trace_cache_t * +trace_cache_get (void) +{ + unw_trace_cache_t *cache; + if (likely (pthread_once != NULL)) + { + pthread_once(&trace_cache_once, &trace_cache_init_once); + if (!trace_cache_once_happen) + { + return trace_cache_get_unthreaded(); + } + if (! (cache = tls_cache)) + { + cache = trace_cache_create(); + pthread_setspecific(trace_cache_key, cache); + tls_cache = cache; + } + Debug(5, "using cache %p\n", cache); + return cache; + } + else + { + return trace_cache_get_unthreaded(); + } +} + +/* Initialise frame properties for address cache slot F at address + RIP using current CFA, RBP and RSP values. Modifies CURSOR to + that location, performs one unw_step(), and fills F with what + was discovered about the location. Returns F. + + FIXME: This probably should tell DWARF handling to never evaluate + or use registers other than RBP, RSP and RIP in case there is + highly unusual unwind info which uses these creatively. */ +static unw_tdep_frame_t * +trace_init_addr (unw_tdep_frame_t *f, + unw_cursor_t *cursor, + unw_word_t cfa, + unw_word_t rip, + unw_word_t rbp, + unw_word_t rsp) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + int ret = -UNW_EINVAL; + + /* Initialise frame properties: unknown, not last. */ + f->virtual_address = rip; + f->frame_type = UNW_X86_64_FRAME_OTHER; + f->last_frame = 0; + f->cfa_reg_rsp = -1; + f->cfa_reg_offset = 0; + f->rbp_cfa_offset = -1; + f->rsp_cfa_offset = -1; + + /* Reinitialise cursor to this instruction - but undo next/prev RIP + adjustment because unw_step will redo it - and force RIP, RBP + RSP into register locations (=~ ucontext we keep), then set + their desired values. Then perform the step. */ + d->ip = rip + d->use_prev_instr; + d->cfa = cfa; + d->loc[UNW_X86_64_RIP] = DWARF_REG_LOC (d, UNW_X86_64_RIP); + d->loc[UNW_X86_64_RBP] = DWARF_REG_LOC (d, UNW_X86_64_RBP); + d->loc[UNW_X86_64_RSP] = DWARF_REG_LOC (d, UNW_X86_64_RSP); + c->frame_info = *f; + + if (likely(dwarf_put (d, d->loc[UNW_X86_64_RIP], rip) >= 0) + && likely(dwarf_put (d, d->loc[UNW_X86_64_RBP], rbp) >= 0) + && likely(dwarf_put (d, d->loc[UNW_X86_64_RSP], rsp) >= 0) + && likely((ret = unw_step (cursor)) >= 0)) + *f = c->frame_info; + + /* If unw_step() stopped voluntarily, remember that, even if it + otherwise could not determine anything useful. This avoids + failing trace if we hit frames without unwind info, which is + common for the outermost frame (CRT stuff) on many systems. + This avoids failing trace in very common circumstances; failing + to unw_step() loop wouldn't produce any better result. */ + if (ret == 0) + f->last_frame = -1; + + Debug (3, "frame va %lx type %d last %d cfa %s+%d rbp @ cfa%+d rsp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_rsp ? "rsp" : "rbp", f->cfa_reg_offset, + f->rbp_cfa_offset, f->rsp_cfa_offset); + + return f; +} + +/* Look up and if necessary fill in frame attributes for address RIP + in CACHE using current CFA, RBP and RSP values. Uses CURSOR to + perform any unwind steps necessary to fill the cache. Returns the + frame cache slot which describes RIP. */ +static unw_tdep_frame_t * +trace_lookup (unw_cursor_t *cursor, + unw_trace_cache_t *cache, + unw_word_t cfa, + unw_word_t rip, + unw_word_t rbp, + unw_word_t rsp) +{ + /* First look up for previously cached information using cache as + linear probing hash table with probe step of 1. Majority of + lookups should be completed within few steps, but it is very + important the hash table does not fill up, or performance falls + off the cliff. */ + uint64_t i, addr; + uint64_t cache_size = 1u << cache->log_size; + uint64_t slot = ((rip * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); + unw_tdep_frame_t *frame; + + for (i = 0; i < 16; ++i) + { + frame = &cache->frames[slot]; + addr = frame->virtual_address; + + /* Return if we found the address. */ + if (likely(addr == rip)) + { + Debug (4, "found address after %ld steps\n", i); + return frame; + } + + /* If slot is empty, reuse it. */ + if (likely(! addr)) + break; + + /* Linear probe to next slot candidate, step = 1. */ + if (++slot >= cache_size) + slot -= cache_size; + } + + /* If we collided after 16 steps, or if the hash is more than half + full, force the hash to expand. Fill the selected slot, whether + it's free or collides. Note that hash expansion drops previous + contents; further lookups will refill the hash. */ + Debug (4, "updating slot %lu after %ld steps, replacing 0x%lx\n", slot, i, addr); + if (unlikely(addr || cache->used >= cache_size / 2)) + { + if (unlikely(trace_cache_expand (cache) < 0)) + return NULL; + + cache_size = 1u << cache->log_size; + slot = ((rip * 0x9e3779b97f4a7c16) >> 43) & (cache_size-1); + frame = &cache->frames[slot]; + addr = frame->virtual_address; + } + + if (! addr) + ++cache->used; + + return trace_init_addr (frame, cursor, cfa, rip, rbp, rsp); +} + +/* Fast stack backtrace for x86-64. + + This is used by backtrace() implementation to accelerate frequent + queries for current stack, without any desire to unwind. It fills + BUFFER with the call tree from CURSOR upwards for at most SIZE + stack levels. The first frame, backtrace itself, is omitted. When + called, SIZE should give the maximum number of entries that can be + stored into BUFFER. Uses an internal thread-specific cache to + accelerate queries. + + The caller should fall back to a unw_step() loop if this function + fails by returning -UNW_ESTOPUNWIND, meaning the routine hit a + stack frame that is too complex to be traced in the fast path. + + This function is tuned for clients which only need to walk the + stack to get the call tree as fast as possible but without any + other details, for example profilers sampling the stack thousands + to millions of times per second. The routine handles the most + common x86-64 ABI stack layouts: CFA is RBP or RSP plus/minus + constant offset, return address is at CFA-8, and RBP and RSP are + either unchanged or saved on stack at constant offset from the CFA; + the signal return frame; and frames without unwind info provided + they are at the outermost (final) frame or can conservatively be + assumed to be frame-pointer based. + + Any other stack layout will cause the routine to give up. There + are only a handful of relatively rarely used functions which do + not have a stack in the standard form: vfork, longjmp, setcontext + and _dl_runtime_profile on common linux systems for example. + + On success BUFFER and *SIZE reflect the trace progress up to *SIZE + stack levels or the outermost frame, which ever is less. It may + stop short of outermost frame if unw_step() loop would also do so, + e.g. if there is no more unwind information; this is not reported + as an error. + + The function returns a negative value for errors, -UNW_ESTOPUNWIND + if tracing stopped because of an unusual frame unwind info. The + BUFFER and *SIZE reflect tracing progress up to the error frame. + + Callers of this function would normally look like this: + + unw_cursor_t cur; + unw_context_t ctx; + void addrs[128]; + int depth = 128; + int ret; + + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + if ((ret = unw_tdep_trace(&cur, addrs, &depth)) < 0) + { + depth = 0; + unw_getcontext(&ctx); + unw_init_local(&cur, &ctx); + while ((ret = unw_step(&cur)) > 0 && depth < 128) + { + unw_word_t ip; + unw_get_reg(&cur, UNW_REG_IP, &ip); + addresses[depth++] = (void *) ip; + } + } +*/ +HIDDEN int +tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) +{ + struct cursor *c = (struct cursor *) cursor; + struct dwarf_cursor *d = &c->dwarf; + unw_trace_cache_t *cache; + unw_word_t rbp, rsp, rip, cfa; + int maxdepth = 0; + int depth = 0; + int ret; + + /* Check input parametres. */ + if (unlikely(! cursor || ! buffer || ! size || (maxdepth = *size) <= 0)) + return -UNW_EINVAL; + + Debug (1, "begin ip 0x%lx cfa 0x%lx\n", d->ip, d->cfa); + + /* Tell core dwarf routines to call back to us. */ + d->stash_frames = 1; + + /* Determine initial register values. These are direct access safe + because we know they come from the initial machine context. */ + rip = d->ip; + rsp = cfa = d->cfa; + ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_X86_64_RBP]), rbp); + assert(ret == 0); + + /* Get frame cache. */ + if (unlikely(! (cache = trace_cache_get()))) + { + Debug (1, "returning %d, cannot get trace cache\n", -UNW_ENOMEM); + *size = 0; + d->stash_frames = 0; + return -UNW_ENOMEM; + } + + /* Trace the stack upwards, starting from current RIP. Adjust + the RIP address for previous/next instruction as the main + unwinding logic would also do. We undo this before calling + back into unw_step(). */ + while (depth < maxdepth) + { + rip -= d->use_prev_instr; + Debug (2, "depth %d cfa 0x%lx rip 0x%lx rsp 0x%lx rbp 0x%lx\n", + depth, cfa, rip, rsp, rbp); + + /* See if we have this address cached. If not, evaluate enough of + the dwarf unwind information to fill the cache line data, or to + decide this frame cannot be handled in fast trace mode. We + cache negative results too to prevent unnecessary dwarf parsing + for common failures. */ + unw_tdep_frame_t *f = trace_lookup (cursor, cache, cfa, rip, rbp, rsp); + + /* If we don't have information for this frame, give up. */ + if (unlikely(! f)) + { + ret = -UNW_ENOINFO; + break; + } + + Debug (3, "frame va %lx type %d last %d cfa %s+%d rbp @ cfa%+d rsp @ cfa%+d\n", + f->virtual_address, f->frame_type, f->last_frame, + f->cfa_reg_rsp ? "rsp" : "rbp", f->cfa_reg_offset, + f->rbp_cfa_offset, f->rsp_cfa_offset); + + assert (f->virtual_address == rip); + + /* Stop if this was the last frame. In particular don't evaluate + new register values as it may not be safe - we don't normally + run with full validation on, and do not want to - and there's + enough bad unwind info floating around that we need to trust + what unw_step() previously said, in potentially bogus frames. */ + if (f->last_frame) + break; + + /* Evaluate CFA and registers for the next frame. */ + switch (f->frame_type) + { + case UNW_X86_64_FRAME_GUESSED: + /* Fall thru to standard processing after forcing validation. */ + c->validate = 1; + + case UNW_X86_64_FRAME_STANDARD: + /* Advance standard traceable frame. */ + cfa = (f->cfa_reg_rsp ? rsp : rbp) + f->cfa_reg_offset; + ACCESS_MEM_FAST(ret, c->validate, d, cfa - 8, rip); + if (likely(ret >= 0) && likely(f->rbp_cfa_offset != -1)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->rbp_cfa_offset, rbp); + + /* Don't bother reading RSP from DWARF, CFA becomes new RSP. */ + rsp = cfa; + + /* Next frame needs to back up for unwind info lookup. */ + d->use_prev_instr = 1; + break; + + case UNW_X86_64_FRAME_SIGRETURN: + cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ + + ACCESS_MEM_FAST(ret, c->validate, d, cfa + UC_MCONTEXT_GREGS_RIP, rip); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + UC_MCONTEXT_GREGS_RBP, rbp); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa + UC_MCONTEXT_GREGS_RSP, rsp); + + /* Resume stack at signal restoration point. The stack is not + necessarily continuous here, especially with sigaltstack(). */ + cfa = rsp; + + /* Next frame should not back up. */ + d->use_prev_instr = 0; + break; + + case UNW_X86_64_FRAME_ALIGNED: + /* Address of RIP was pushed on the stack via a simple + * def_cfa_expr - result stack offset stored in cfa_reg_offset */ + cfa = (f->cfa_reg_rsp ? rsp : rbp) + f->cfa_reg_offset; + ACCESS_MEM_FAST(ret, c->validate, d, cfa, cfa); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, cfa - 8, rip); + if (likely(ret >= 0)) + ACCESS_MEM_FAST(ret, c->validate, d, rbp, rbp); + + /* Don't bother reading RSP from DWARF, CFA becomes new RSP. */ + rsp = cfa; + + /* Next frame needs to back up for unwind info lookup. */ + d->use_prev_instr = 1; + + break; + + default: + /* We cannot trace through this frame, give up and tell the + caller we had to stop. Data collected so far may still be + useful to the caller, so let it know how far we got. */ + ret = -UNW_ESTOPUNWIND; + break; + } + + Debug (4, "new cfa 0x%lx rip 0x%lx rsp 0x%lx rbp 0x%lx\n", + cfa, rip, rsp, rbp); + + /* If we failed or ended up somewhere bogus, stop. */ + if (unlikely(ret < 0 || rip < 0x4000)) + break; + + /* Record this address in stack trace. We skipped the first address. */ + buffer[depth++] = (void *) rip; + } + +#if UNW_DEBUG + Debug (1, "returning %d, depth %d\n", ret, depth); +#endif + *size = depth; + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lapply_reg_state.c new file mode 100644 index 00000000000000..7ebada480e5640 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lcreate_addr_space.c new file mode 100644 index 00000000000000..0f2dc6be901453 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_proc_info.c new file mode 100644 index 00000000000000..69028b019fcd51 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_save_loc.c new file mode 100644 index 00000000000000..9ea048a9076ba8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lglobal.c new file mode 100644 index 00000000000000..8c43a67c0fff23 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lglobal.c @@ -0,0 +1,6 @@ +#define UNW_LOCAL_ONLY +#include "config.h" +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit.c new file mode 100644 index 00000000000000..e9abfdd46a3e0f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_local.c new file mode 100644 index 00000000000000..68a1687e85444b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_remote.c new file mode 100644 index 00000000000000..58cb04ab7cd1fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-freebsd.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-freebsd.c new file mode 100644 index 00000000000000..a75a205df19c01 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-freebsd.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-freebsd.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-linux.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-linux.c new file mode 100644 index 00000000000000..3cc18aabcc399c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-linux.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-linux.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c new file mode 100644 index 00000000000000..be64b2c695b896 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-solaris.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lreg_states_iterate.c new file mode 100644 index 00000000000000..f1eb1e79dcdcca --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lregs.c new file mode 100644 index 00000000000000..2c9c75cd7d9a1e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lresume.c new file mode 100644 index 00000000000000..41a8cf003de4ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstash_frame.c new file mode 100644 index 00000000000000..77587803d083d7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstash_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstash_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstep.c new file mode 100644 index 00000000000000..c1ac3c7547f00d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ltrace.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ltrace.c new file mode 100644 index 00000000000000..fcd3f239c9e422 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ltrace.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gtrace.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S new file mode 100644 index 00000000000000..e1450719b7da1a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S @@ -0,0 +1,136 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 Google, Inc + Contributed by Paul Pluzhnikov + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "ucontext_i.h" + +/* int _Ux86_64_getcontext (ucontext_t *ucp) + + Saves the machine context in UCP necessary for libunwind. + Unlike the libc implementation, we don't save the signal mask + and hence avoid the cost of a system call per unwind. + +*/ + + .global _Ux86_64_getcontext + .type _Ux86_64_getcontext, @function +_Ux86_64_getcontext: + .cfi_startproc + + /* Callee saved: RBX, RBP, R12-R15 */ + movq %r12, UC_MCONTEXT_GREGS_R12(%rdi) + movq %r13, UC_MCONTEXT_GREGS_R13(%rdi) + movq %r14, UC_MCONTEXT_GREGS_R14(%rdi) + movq %r15, UC_MCONTEXT_GREGS_R15(%rdi) + movq %rbp, UC_MCONTEXT_GREGS_RBP(%rdi) + movq %rbx, UC_MCONTEXT_GREGS_RBX(%rdi) + + /* Save argument registers (not strictly needed, but setcontext + restores them, so don't restore garbage). */ + movq %r8, UC_MCONTEXT_GREGS_R8(%rdi) + movq %r9, UC_MCONTEXT_GREGS_R9(%rdi) + movq %rdi, UC_MCONTEXT_GREGS_RDI(%rdi) + movq %rsi, UC_MCONTEXT_GREGS_RSI(%rdi) + movq %rdx, UC_MCONTEXT_GREGS_RDX(%rdi) + movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi) + movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi) + +#if defined __linux__ || defined __sun + /* Save fp state (not needed, except for setcontext not + restoring garbage). */ + leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 +#ifdef UC_MCONTEXT_FPREGS_PTR + movq %r8, UC_MCONTEXT_FPREGS_PTR(%rdi) +#endif // UC_MCONTEXT_FPREGS_PTR + fnstenv (%r8) + stmxcsr FPREGS_OFFSET_MXCSR(%r8) +#elif defined __FreeBSD__ + fxsave UC_MCONTEXT_FPSTATE(%rdi) + movq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi) + movq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi) + /* Save rflags and segment registers, so that sigreturn(2) + does not complain. */ + pushfq + .cfi_adjust_cfa_offset 8 + popq UC_MCONTEXT_RFLAGS(%rdi) + .cfi_adjust_cfa_offset -8 + movl $0, UC_MCONTEXT_FLAGS(%rdi) + movw %cs, UC_MCONTEXT_CS(%rdi) + movw %ss, UC_MCONTEXT_SS(%rdi) +#if 0 + /* Setting the flags to 0 above disables restore of segment + registers from the context */ + movw %ds, UC_MCONTEXT_DS(%rdi) + movw %es, UC_MCONTEXT_ES(%rdi) + movw %fs, UC_MCONTEXT_FS(%rdi) + movw %gs, UC_MCONTEXT_GS(%rdi) +#endif + movq $UC_MCONTEXT_MC_LEN_VAL, UC_MCONTEXT_MC_LEN(%rdi) +#else +#error Port me +#endif + + leaq 8(%rsp), %rax /* exclude this call. */ + movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi) + + movq 0(%rsp), %rax + movq %rax, UC_MCONTEXT_GREGS_RIP(%rdi) + + xorq %rax, %rax + retq + .cfi_endproc + .size _Ux86_64_getcontext, . - _Ux86_64_getcontext + +/* int _Ux86_64_getcontext_trace (ucontext_t *ucp) + + Saves limited machine context in UCP necessary for libunwind. + Unlike _Ux86_64_getcontext, saves only the parts needed for + fast trace. If fast trace fails, caller will have to get the + full context. +*/ + + .global _Ux86_64_getcontext_trace + .hidden _Ux86_64_getcontext_trace + .type _Ux86_64_getcontext_trace, @function +_Ux86_64_getcontext_trace: + .cfi_startproc + + /* Save only RBP, RBX, RSP, RIP - exclude this call. */ + movq %rbp, UC_MCONTEXT_GREGS_RBP(%rdi) + movq %rbx, UC_MCONTEXT_GREGS_RBX(%rdi) + + leaq 8(%rsp), %rax + movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi) + + movq 0(%rsp), %rax + movq %rax, UC_MCONTEXT_GREGS_RIP(%rdi) + + xorq %rax, %rax + retq + .cfi_endproc + .size _Ux86_64_getcontext_trace, . - _Ux86_64_getcontext_trace + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/init.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/init.h new file mode 100644 index 00000000000000..a7a996f1272758 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/init.h @@ -0,0 +1,89 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* Avoid a trip to x86_64_r_uc_addr() for purely local initialisation. */ +#if defined UNW_LOCAL_ONLY && defined __linux +# define REG_INIT_LOC(c, rlc, ruc) \ + DWARF_LOC ((unw_word_t) &c->uc->uc_mcontext.gregs[REG_ ## ruc], 0) + +#elif defined UNW_LOCAL_ONLY && defined __FreeBSD__ +# define REG_INIT_LOC(c, rlc, ruc) \ + DWARF_LOC ((unw_word_t) &c->uc->uc_mcontext.mc_ ## rlc, 0) + +#else +# define REG_INIT_LOC(c, rlc, ruc) \ + DWARF_REG_LOC (&c->dwarf, UNW_X86_64_ ## ruc) +#endif + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + + c->dwarf.loc[RAX] = REG_INIT_LOC(c, rax, RAX); + c->dwarf.loc[RDX] = REG_INIT_LOC(c, rdx, RDX); + c->dwarf.loc[RCX] = REG_INIT_LOC(c, rcx, RCX); + c->dwarf.loc[RBX] = REG_INIT_LOC(c, rbx, RBX); + c->dwarf.loc[RSI] = REG_INIT_LOC(c, rsi, RSI); + c->dwarf.loc[RDI] = REG_INIT_LOC(c, rdi, RDI); + c->dwarf.loc[RBP] = REG_INIT_LOC(c, rbp, RBP); + c->dwarf.loc[RSP] = REG_INIT_LOC(c, rsp, RSP); + c->dwarf.loc[R8] = REG_INIT_LOC(c, r8, R8); + c->dwarf.loc[R9] = REG_INIT_LOC(c, r9, R9); + c->dwarf.loc[R10] = REG_INIT_LOC(c, r10, R10); + c->dwarf.loc[R11] = REG_INIT_LOC(c, r11, R11); + c->dwarf.loc[R12] = REG_INIT_LOC(c, r12, R12); + c->dwarf.loc[R13] = REG_INIT_LOC(c, r13, R13); + c->dwarf.loc[R14] = REG_INIT_LOC(c, r14, R14); + c->dwarf.loc[R15] = REG_INIT_LOC(c, r15, R15); + c->dwarf.loc[RIP] = REG_INIT_LOC(c, rip, RIP); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); + if (ret < 0) + return ret; + + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_X86_64_RSP), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = X86_64_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + c->dwarf.eh_valid_mask = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/is_fpreg.c new file mode 100644 index 00000000000000..5c036137b630fc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/is_fpreg.c @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_is_fpreg (int regnum) +{ +#if 0 + return ((regnum >= UNW_X86_ST0 && regnum <= UNW_X86_ST7) + || (regnum >= UNW_X86_XMM0_lo && regnum <= UNW_X86_XMM7_hi)); +#endif + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/longjmp.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/longjmp.S new file mode 100644 index 00000000000000..274778fd80f365 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/longjmp.S @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + + .globl _UI_longjmp_cont + .type _UI_longjmp_cont, @function +_UI_longjmp_cont: + push %rax /* push target IP as return address */ + mov %rdx, %rax /* set up return-value */ + retq + .size _UI_longjmp_cont, .-_UI_longjmp_cont + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/offsets.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/offsets.h new file mode 100644 index 00000000000000..0807960f30c0c9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/offsets.h @@ -0,0 +1,3 @@ +/* FreeBSD specific definitions */ + +#define FREEBSD_UC_MCONTEXT_OFF 0x10 diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/regname.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/regname.c new file mode 100644 index 00000000000000..77660af4a2edae --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/regname.c @@ -0,0 +1,56 @@ +/* libunwind - a platform-independent unwind library + + Contributed by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + "RAX", + "RDX", + "RCX", + "RBX", + "RSI", + "RDI", + "RBP", + "RSP", + "R8", + "R9", + "R10", + "R11", + "R12", + "R13", + "R14", + "R15", + "RIP", + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S new file mode 100644 index 00000000000000..17e5ae12032aad --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S @@ -0,0 +1,87 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2007 Google, Inc + Contributed by Arun Sharma + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "ucontext_i.h" + +/* int _Ux86_64_setcontext (const ucontext_t *ucp) + + Restores the machine context provided. + Unlike the libc implementation, doesn't clobber %rax + +*/ + .global _Ux86_64_setcontext + .type _Ux86_64_setcontext, @function + +_Ux86_64_setcontext: + +#if defined __linux__ || defined __sun + /* restore fp state */ +#ifdef UC_MCONTEXT_FPREGS_PTR + mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8 +#else // UC_MCONTEXT_FPREGS_PTR + leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 +#endif // UC_MCONTEXT_FPREGS_PTR + fldenv (%r8) + ldmxcsr FPREGS_OFFSET_MXCSR(%r8) +#elif defined __FreeBSD__ + /* restore fp state */ + cmpq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi) + jne 1f + cmpq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi) + jne 1f + fxrstor UC_MCONTEXT_FPSTATE(%rdi) +1: +#else +#error Port me +#endif + + /* restore the rest of the state */ + mov UC_MCONTEXT_GREGS_R8(%rdi),%r8 + mov UC_MCONTEXT_GREGS_R9(%rdi),%r9 + mov UC_MCONTEXT_GREGS_RBX(%rdi),%rbx + mov UC_MCONTEXT_GREGS_RBP(%rdi),%rbp + mov UC_MCONTEXT_GREGS_R12(%rdi),%r12 + mov UC_MCONTEXT_GREGS_R13(%rdi),%r13 + mov UC_MCONTEXT_GREGS_R14(%rdi),%r14 + mov UC_MCONTEXT_GREGS_R15(%rdi),%r15 + mov UC_MCONTEXT_GREGS_RSI(%rdi),%rsi + mov UC_MCONTEXT_GREGS_RDX(%rdi),%rdx + mov UC_MCONTEXT_GREGS_RAX(%rdi),%rax + mov UC_MCONTEXT_GREGS_RCX(%rdi),%rcx + mov UC_MCONTEXT_GREGS_RSP(%rdi),%rsp + + /* push the return address on the stack */ + mov UC_MCONTEXT_GREGS_RIP(%rdi),%rcx + push %rcx + + mov UC_MCONTEXT_GREGS_RCX(%rdi),%rcx + mov UC_MCONTEXT_GREGS_RDI(%rdi),%rdi + retq + + .size _Ux86_64_setcontext, . - _Ux86_64_setcontext + + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/siglongjmp.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/siglongjmp.S new file mode 100644 index 00000000000000..32489e53a9f19c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/siglongjmp.S @@ -0,0 +1,32 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + + .globl _UI_siglongjmp_cont + .type _UI_siglongjmp_cont, @function +_UI_siglongjmp_cont: + retq + .size _UI_siglongjmp_cont, . - _UI_siglongjmp_cont + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h new file mode 100644 index 00000000000000..e886c948453ceb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h @@ -0,0 +1,102 @@ +/* Copyright (C) 2004 Hewlett-Packard Co. + Contributed by David Mosberger-Tang . + +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. */ + +#if defined __linux__ +#define UC_MCONTEXT_GREGS_R8 0x28 +#define UC_MCONTEXT_GREGS_R9 0x30 +#define UC_MCONTEXT_GREGS_R10 0x38 +#define UC_MCONTEXT_GREGS_R11 0x40 +#define UC_MCONTEXT_GREGS_R12 0x48 +#define UC_MCONTEXT_GREGS_R13 0x50 +#define UC_MCONTEXT_GREGS_R14 0x58 +#define UC_MCONTEXT_GREGS_R15 0x60 +#define UC_MCONTEXT_GREGS_RDI 0x68 +#define UC_MCONTEXT_GREGS_RSI 0x70 +#define UC_MCONTEXT_GREGS_RBP 0x78 +#define UC_MCONTEXT_GREGS_RBX 0x80 +#define UC_MCONTEXT_GREGS_RDX 0x88 +#define UC_MCONTEXT_GREGS_RAX 0x90 +#define UC_MCONTEXT_GREGS_RCX 0x98 +#define UC_MCONTEXT_GREGS_RSP 0xa0 +#define UC_MCONTEXT_GREGS_RIP 0xa8 +#define UC_MCONTEXT_FPREGS_PTR 0x1a8 +#define UC_MCONTEXT_FPREGS_MEM 0xe0 +#define UC_SIGMASK 0x128 +#define FPREGS_OFFSET_MXCSR 0x18 +#elif defined __FreeBSD__ +#define UC_SIGMASK 0x0 +#define UC_MCONTEXT_GREGS_RDI 0x18 +#define UC_MCONTEXT_GREGS_RSI 0x20 +#define UC_MCONTEXT_GREGS_RDX 0x28 +#define UC_MCONTEXT_GREGS_RCX 0x30 +#define UC_MCONTEXT_GREGS_R8 0x38 +#define UC_MCONTEXT_GREGS_R9 0x40 +#define UC_MCONTEXT_GREGS_RAX 0x48 +#define UC_MCONTEXT_GREGS_RBX 0x50 +#define UC_MCONTEXT_GREGS_RBP 0x58 +#define UC_MCONTEXT_GREGS_R10 0x60 +#define UC_MCONTEXT_GREGS_R11 0x68 +#define UC_MCONTEXT_GREGS_R12 0x70 +#define UC_MCONTEXT_GREGS_R13 0x78 +#define UC_MCONTEXT_GREGS_R14 0x80 +#define UC_MCONTEXT_GREGS_R15 0x88 +#define UC_MCONTEXT_FS 0x94 +#define UC_MCONTEXT_GS 0x96 +#define UC_MCONTEXT_FLAGS 0xa0 +#define UC_MCONTEXT_ES 0xa4 +#define UC_MCONTEXT_DS 0xa6 +#define UC_MCONTEXT_GREGS_RIP 0xb0 +#define UC_MCONTEXT_CS 0xb8 +#define UC_MCONTEXT_RFLAGS 0xc0 +#define UC_MCONTEXT_GREGS_RSP 0xc8 +#define UC_MCONTEXT_SS 0xd0 +#define UC_MCONTEXT_MC_LEN 0xd8 +#define UC_MCONTEXT_FPFORMAT 0xe0 +#define UC_MCONTEXT_OWNEDFP 0xe8 +#define UC_MCONTEXT_FPSTATE 0xf0 +#define UC_MCONTEXT_FPOWNED_FPU 0x20001 +#define UC_MCONTEXT_FPFMT_XMM 0x10002 +#define UC_MCONTEXT_MC_LEN_VAL 0x320 +#elif defined __sun +#define UC_MCONTEXT_GREGS_R8 0x78 +#define UC_MCONTEXT_GREGS_R9 0x70 +#define UC_MCONTEXT_GREGS_R10 0x68 +#define UC_MCONTEXT_GREGS_R11 0x60 +#define UC_MCONTEXT_GREGS_R12 0x58 +#define UC_MCONTEXT_GREGS_R13 0x50 +#define UC_MCONTEXT_GREGS_R14 0x48 +#define UC_MCONTEXT_GREGS_R15 0x40 +#define UC_MCONTEXT_GREGS_RDI 0x80 +#define UC_MCONTEXT_GREGS_RSI 0x88 +#define UC_MCONTEXT_GREGS_RBP 0x90 +#define UC_MCONTEXT_GREGS_RBX 0x98 +#define UC_MCONTEXT_GREGS_RDX 0xa0 +#define UC_MCONTEXT_GREGS_RAX 0xb0 +#define UC_MCONTEXT_GREGS_RCX 0xa8 +#define UC_MCONTEXT_GREGS_RSP 0xe0 +#define UC_MCONTEXT_GREGS_RIP 0xc8 +#define UC_MCONTEXT_FPREGS_MEM 0x120 +#define FPREGS_OFFSET_MXCSR 0x18 + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/unwind_i.h new file mode 100644 index 00000000000000..e95a60ff37676e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/unwind_i.h @@ -0,0 +1,93 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +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 unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" +#include + +/* DWARF column numbers for x86_64: */ +#define RAX 0 +#define RDX 1 +#define RCX 2 +#define RBX 3 +#define RSI 4 +#define RDI 5 +#define RBP 6 +#define RSP 7 +#define R8 8 +#define R9 9 +#define R10 10 +#define R11 11 +#define R12 12 +#define R13 13 +#define R14 14 +#define R15 15 +#define RIP 16 + +#define x86_64_lock UNW_OBJ(lock) +#define x86_64_local_resume UNW_OBJ(local_resume) +#define x86_64_local_addr_space_init UNW_OBJ(local_addr_space_init) +#define setcontext UNW_ARCH_OBJ (setcontext) +#if 0 +#define x86_64_scratch_loc UNW_OBJ(scratch_loc) +#endif +#define x86_64_r_uc_addr UNW_OBJ(r_uc_addr) +#define x86_64_sigreturn UNW_OBJ(sigreturn) + +/* By-pass calls to access_mem() when known to be safe. */ +#ifdef UNW_LOCAL_ONLY +# undef ACCESS_MEM_FAST +# define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ + do { \ + if (unlikely(validate)) \ + (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); \ + else \ + (ret) = 0, (to) = *(unw_word_t *)(addr); \ + } while (0) +#endif + +extern void x86_64_local_addr_space_init (void); +extern int x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, + void *arg); +extern int setcontext (const ucontext_t *ucp); + +#if 0 +extern dwarf_loc_t x86_64_scratch_loc (struct cursor *c, unw_regnum_t reg); +#endif + +extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg); +extern NORETURN void x86_64_sigreturn (unw_cursor_t *cursor); +#define x86_64_handle_signal_frame UNW_OBJ(handle_signal_frame) +extern int x86_64_handle_signal_frame(unw_cursor_t *cursor); + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-nat.c b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-nat.c new file mode 100644 index 00000000000000..89df54e0b0ee36 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-nat.c @@ -0,0 +1,626 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 tests corner-cases of NaT-bit handling. */ + +#include +#include +#include +#include + +#include +#include "compiler.h" + +#ifdef HAVE_SYS_UC_ACCESS_H +# include +#endif + +#include "tdep-ia64/rse.h" + +#define NUM_RUNS 1024 +//#define NUM_RUNS 1 +#define MAX_CHECKS 1024 +//#define MAX_CHECKS 2 +#define MAX_VALUES_PER_FUNC 4 + +#define panic(args...) \ + do { printf (args); ++nerrors; } while (0) + +typedef void save_func_t (void *funcs, unsigned long *vals); +typedef unw_word_t *check_func_t (unw_cursor_t *c, unsigned long *vals); + +extern void flushrs (void); + +extern save_func_t save_static_to_stacked; +static check_func_t check_static_to_stacked; + +extern save_func_t save_static_to_fr; +static check_func_t check_static_to_fr; + +extern save_func_t save_static_to_br; +static check_func_t check_static_to_br; + +extern save_func_t save_static_to_mem; +static check_func_t check_static_to_mem; + +extern save_func_t save_static_to_mem2; +static check_func_t check_static_to_mem2; + +extern save_func_t save_static_to_mem3; +static check_func_t check_static_to_mem3; + +extern save_func_t save_static_to_mem4; +static check_func_t check_static_to_mem4; + +extern save_func_t save_static_to_mem5; +static check_func_t check_static_to_mem5; + +extern save_func_t save_static_to_scratch; +static check_func_t check_static_to_scratch; + +extern save_func_t rotate_regs; +static check_func_t check_rotate_regs; + +extern save_func_t save_pr; +static check_func_t check_pr; + +static int verbose; +static int nerrors; + +static int num_checks; +static save_func_t *funcs[MAX_CHECKS + 1]; +static check_func_t *checks[MAX_CHECKS]; +static unw_word_t values[MAX_CHECKS*MAX_VALUES_PER_FUNC]; + +static struct + { + save_func_t *func; + check_func_t *check; + } +all_funcs[] = + { + { save_static_to_stacked, check_static_to_stacked }, + { save_static_to_fr, check_static_to_fr }, + { save_static_to_br, check_static_to_br }, + { save_static_to_mem, check_static_to_mem }, + { save_static_to_mem2, check_static_to_mem2 }, + { save_static_to_mem3, check_static_to_mem3 }, + { save_static_to_mem4, check_static_to_mem4 }, + { save_static_to_mem5, check_static_to_mem5 }, + { save_static_to_scratch, check_static_to_scratch }, + { save_pr, check_pr }, + { rotate_regs, check_rotate_regs }, + }; + +static unw_word_t +random_word (void) +{ + unw_word_t val = random (); + + if (sizeof (unw_word_t) > 4) + val |= ((unw_word_t) random ()) << 32; + + return val; +} + +void +sighandler (int signal, void *siginfo, void *context) +{ + unsigned long *bsp, *arg1; + save_func_t **arg0; + ucontext_t *uc = context; + +#if defined(__linux) + { + long sof; + int sp; + + if (verbose) + printf ("sighandler: signal %d sp=%p nat=%08lx pr=%lx\n", + signal, &sp, uc->uc_mcontext.sc_nat, uc->uc_mcontext.sc_pr); + sof = uc->uc_mcontext.sc_cfm & 0x7f; + bsp = (unsigned long *) rse_skip_regs (uc->uc_mcontext.sc_ar_bsp, -sof); + } +#elif defined(__hpux) + if (__uc_get_ar (uc, UNW_IA64_AR_BSP - UNW_IA64_AR, &bsp) != 0) + { + panic ("%s: reading of ar.bsp failed, errno=%d", __FUNCTION__, errno); + return; + } +#endif + + flushrs (); + arg0 = (save_func_t **) *bsp; + bsp = (unsigned long *) rse_skip_regs ((uint64_t) bsp, 1); + arg1 = (unsigned long *) *bsp; + + (*arg0[0]) (arg0 + 1, arg1); + + /* skip over the instruction which triggered sighandler() */ +#if defined(__linux) + ++uc->uc_mcontext.sc_ip; +#elif defined(HAVE_SYS_UC_ACCESS_H) + { + unsigned long ip; + + if (__uc_get_ip (uc, &ip) != 0) + { + panic ("%s: reading of ip failed, errno=%d", __FUNCTION__, errno); + return; + } + if (__uc_set_ip (uc, ip) != 0) + { + panic ("%s: writing of ip failed, errno=%d", __FUNCTION__, errno); + return; + } + } +#endif +} + +static void +enable_sighandler (void) +{ + struct sigaction act; + + memset (&act, 0, sizeof (act)); + act.sa_handler = (void (*)(int)) sighandler; + act.sa_flags = SA_SIGINFO | SA_NODEFER; + if (sigaction (SIGSEGV, &act, NULL) < 0) + panic ("sigaction: %s\n", strerror (errno)); +} + +static void +disable_sighandler (void) +{ + struct sigaction act; + + memset (&act, 0, sizeof (act)); + act.sa_handler = SIG_DFL; + act.sa_flags = SA_SIGINFO | SA_NODEFER; + if (sigaction (SIGSEGV, &act, NULL) < 0) + panic ("sigaction: %s\n", strerror (errno)); +} + +static unw_word_t * +check_static_to_stacked (unw_cursor_t *c, unw_word_t *vals) +{ + unw_word_t r[4]; + unw_word_t nat[4]; + int i, ret; + + if (verbose) + printf (" %s()\n", __FUNCTION__); + + vals -= 4; + + for (i = 0; i < 4; ++i) + if ((ret = unw_get_reg (c, UNW_IA64_GR + 4 + i, &r[i])) < 0) + panic ("%s: failed to read register r%d, error=%d\n", + __FUNCTION__, 4 + i, ret); + + for (i = 0; i < 4; ++i) + if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4 + i, &nat[i])) < 0) + panic ("%s: failed to read register nat%d, error=%d\n", + __FUNCTION__, 4 + i, ret); + + for (i = 0; i < 4; ++i) + { + if (verbose) + printf (" r%d = %c%016lx (expected %c%016lx)\n", + 4 + i, nat[i] ? '*' : ' ', r[i], + (vals[i] & 1) ? '*' : ' ', vals[i]); + + if (vals[i] & 1) + { + if (!nat[i]) + panic ("%s: r%d not a NaT!\n", __FUNCTION__, 4 + i); + } + else + { + if (nat[i]) + panic ("%s: r%d a NaT!\n", __FUNCTION__, 4 + i); + if (r[i] != vals[i]) + panic ("%s: r%d=%lx instead of %lx!\n", + __FUNCTION__, 4 + i, r[i], vals[i]); + } + } + return vals; +} + +static unw_word_t * +check_static_to_fr (unw_cursor_t *c, unw_word_t *vals) +{ + unw_word_t r4; + unw_word_t nat4; + int ret; + + if (verbose) + printf (" %s()\n", __FUNCTION__); + + vals -= 1; + + if ((ret = unw_get_reg (c, UNW_IA64_GR + 4, &r4)) < 0) + panic ("%s: failed to read register r4, error=%d\n", __FUNCTION__, ret); + + if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4, &nat4)) < 0) + panic ("%s: failed to read register nat4, error=%d\n", __FUNCTION__, ret); + + if (verbose) + printf (" r4 = %c%016lx (expected %c%016lx)\n", + nat4 ? '*' : ' ', r4, (vals[0] & 1) ? '*' : ' ', vals[0]); + + if (vals[0] & 1) + { + if (!nat4) + panic ("%s: r4 not a NaT!\n", __FUNCTION__); + } + else + { + if (nat4) + panic ("%s: r4 a NaT!\n", __FUNCTION__); + if (r4 != vals[0]) + panic ("%s: r4=%lx instead of %lx!\n", __FUNCTION__, r4, vals[0]); + } + return vals; +} + +static unw_word_t * +check_static_to_br (unw_cursor_t *c, unw_word_t *vals) +{ + unw_word_t r4, nat4; + int ret; + + if (verbose) + printf (" %s()\n", __FUNCTION__); + + vals -= 1; + + if ((ret = unw_get_reg (c, UNW_IA64_GR + 4, &r4)) < 0) + panic ("%s: failed to read register r4, error=%d\n", __FUNCTION__, ret); + + if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4, &nat4)) < 0) + panic ("%s: failed to read register nat4, error=%d\n", __FUNCTION__, ret); + + if (verbose) + printf (" r4 = %c%016lx (expected %c%016lx)\n", + nat4 ? '*' : ' ', r4, (vals[0] & 1) ? '*' : ' ', vals[0]); + + if (vals[0] & 1) + { + if (!nat4) + panic ("%s: r4 not a NaT!\n", __FUNCTION__); + } + else + { + if (nat4) + panic ("%s: r4 a NaT!\n", __FUNCTION__); + if (r4 != vals[0]) + panic ("%s: r4=%lx instead of %lx!\n", __FUNCTION__, r4, vals[0]); + } + return vals; +} + +static unw_word_t * +check_static_to_mem (unw_cursor_t *c, unw_word_t *vals) +{ + unw_word_t r5, nat5; + int ret; + + if (verbose) + printf (" %s()\n", __FUNCTION__); + + vals -= 1; + + if ((ret = unw_get_reg (c, UNW_IA64_GR + 5, &r5)) < 0) + panic ("%s: failed to read register r5, error=%d\n", __FUNCTION__, ret); + + if ((ret = unw_get_reg (c, UNW_IA64_NAT + 5, &nat5)) < 0) + panic ("%s: failed to read register nat5, error=%d\n", __FUNCTION__, ret); + + if (verbose) + printf (" r5 = %c%016lx (expected %c%016lx)\n", + nat5 ? '*' : ' ', r5, (vals[0] & 1) ? '*' : ' ', vals[0]); + + if (vals[0] & 1) + { + if (!nat5) + panic ("%s: r5 not a NaT!\n", __FUNCTION__); + } + else + { + if (nat5) + panic ("%s: r5 a NaT!\n", __FUNCTION__); + if (r5 != vals[0]) + panic ("%s: r5=%lx instead of %lx!\n", __FUNCTION__, r5, vals[0]); + } + return vals; +} + +static unw_word_t * +check_static_to_memN (unw_cursor_t *c, unw_word_t *vals, const char *func) +{ + unw_word_t r6, nat6; + int ret; + + if (verbose) + printf (" %s()\n", func); + + vals -= 1; + + if ((ret = unw_get_reg (c, UNW_IA64_GR + 6, &r6)) < 0) + panic ("%s: failed to read register r6, error=%d\n", __FUNCTION__, ret); + + if ((ret = unw_get_reg (c, UNW_IA64_NAT + 6, &nat6)) < 0) + panic ("%s: failed to read register nat6, error=%d\n", __FUNCTION__, ret); + + if (verbose) + printf (" r6 = %c%016lx (expected %c%016lx)\n", + nat6 ? '*' : ' ', r6, (vals[0] & 1) ? '*' : ' ', vals[0]); + + if (vals[0] & 1) + { + if (!nat6) + panic ("%s: r6 not a NaT!\n", __FUNCTION__); + } + else + { + if (nat6) + panic ("%s: r6 a NaT!\n", __FUNCTION__); + if (r6 != vals[0]) + panic ("%s: r6=%lx instead of %lx!\n", __FUNCTION__, r6, vals[0]); + } + return vals; +} + +static unw_word_t * +check_static_to_mem2 (unw_cursor_t *c, unw_word_t *vals) +{ + return check_static_to_memN (c, vals, __FUNCTION__); +} + +static unw_word_t * +check_static_to_mem3 (unw_cursor_t *c, unw_word_t *vals) +{ + return check_static_to_memN (c, vals, __FUNCTION__); +} + +static unw_word_t * +check_static_to_mem4 (unw_cursor_t *c, unw_word_t *vals) +{ + return check_static_to_memN (c, vals, __FUNCTION__); +} + +static unw_word_t * +check_static_to_mem5 (unw_cursor_t *c, unw_word_t *vals) +{ + return check_static_to_memN (c, vals, __FUNCTION__); +} + +static unw_word_t * +check_static_to_scratch (unw_cursor_t *c, unw_word_t *vals) +{ + unw_word_t r[4], nat[4], ec, expected; + unw_fpreg_t f4; + int i, ret; + + if (verbose) + printf (" %s()\n", __FUNCTION__); + + vals -= 4; + + while (!unw_is_signal_frame (c)) + if ((ret = unw_step (c)) < 0) + panic ("%s: unw_step (ret=%d): Failed to skip over signal handler\n", + __FUNCTION__, ret); + if ((ret = unw_step (c)) < 0) + panic ("%s: unw_step (ret=%d): Failed to skip over signal handler\n", + __FUNCTION__, ret); + + for (i = 0; i < 4; ++i) + if ((ret = unw_get_reg (c, UNW_IA64_GR + 4 + i, &r[i])) < 0) + panic ("%s: failed to read register r%d, error=%d\n", + __FUNCTION__, 4 + i, ret); + + for (i = 0; i < 4; ++i) + if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4 + i, &nat[i])) < 0) + panic ("%s: failed to read register nat%d, error=%d\n", + __FUNCTION__, 4 + i, ret); + + for (i = 0; i < 4; ++i) + { + if (verbose) + printf (" r%d = %c%016lx (expected %c%016lx)\n", + 4 + i, nat[i] ? '*' : ' ', r[i], + (vals[i] & 1) ? '*' : ' ', vals[i]); + + if (vals[i] & 1) + { + if (!nat[i]) + panic ("%s: r%d not a NaT!\n", __FUNCTION__, 4 + i); + } + else + { + if (nat[i]) + panic ("%s: r%d a NaT!\n", __FUNCTION__, 4 + i); + if (r[i] != vals[i]) + panic ("%s: r%d=%lx instead of %lx!\n", + __FUNCTION__, 4 + i, r[i], vals[i]); + } + } + if ((ret = unw_get_fpreg (c, UNW_IA64_FR + 4, &f4)) < 0) + panic ("%s: failed to read f4, error=%d\n", __FUNCTION__, ret); + + /* These tests are little-endian specific: */ + if (nat[0]) + { + if (f4.raw.bits[0] != 0 || f4.raw.bits[1] != 0x1fffe) + panic ("%s: f4=%016lx.%016lx instead of NaTVal!\n", + __FUNCTION__, f4.raw.bits[1], f4.raw.bits[0]); + } + else + { + if (f4.raw.bits[0] != r[0] || f4.raw.bits[1] != 0x1003e) + panic ("%s: f4=%016lx.%016lx instead of %lx!\n", + __FUNCTION__, f4.raw.bits[1], f4.raw.bits[0], r[0]); + } + + if ((unw_get_reg (c, UNW_IA64_AR_EC, &ec)) < 0) + panic ("%s: failed to read register ar.ec, error=%d\n", __FUNCTION__, ret); + + expected = vals[0] & 0x3f; + if (ec != expected) + panic ("%s: ar.ec=%016lx instead of %016lx!\n", + __FUNCTION__, ec, expected); + + return vals; +} + +static unw_word_t * +check_pr (unw_cursor_t *c, unw_word_t *vals) +{ + unw_word_t pr, expected; + int ret; +# define BIT(n) ((unw_word_t) 1 << (n)) +# define DONTCARE (BIT( 6) | BIT( 7) | BIT( 8) | BIT( 9) | BIT(10) \ + | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15)) + + if (verbose) + printf (" %s()\n", __FUNCTION__); + + vals -= 1; + + if ((ret = unw_get_reg (c, UNW_IA64_PR, &pr)) < 0) + panic ("%s: failed to read register pr, error=%d\n", __FUNCTION__, ret); + + pr &= ~DONTCARE; + expected = (vals[0] & ~DONTCARE) | 1; + + if (verbose) + printf (" pr = %016lx (expected %016lx)\n", pr, expected); + + if (pr != expected) + panic ("%s: pr=%lx instead of %lx!\n", __FUNCTION__, pr, expected); + + if ((ret = unw_set_reg (c, UNW_IA64_PR, vals[0])) < 0) + panic ("%s: failed to write register pr, error=%d\n", __FUNCTION__, ret); + + if ((ret = unw_get_reg (c, UNW_IA64_PR, &pr)) < 0) + panic ("%s: failed to read register pr, error=%d\n", __FUNCTION__, ret); + + if (pr != vals[0]) + panic ("%s: secondary pr=%lx instead of %lx!\n", + __FUNCTION__, pr, vals[0]); + return vals; +} + +static unw_word_t * +check_rotate_regs (unw_cursor_t *c, unw_word_t *vals) +{ + if (verbose) + printf (" %s()\n", __FUNCTION__); + return check_pr (c, vals - 1); +} + +static void +start_checks (void *funcs, unsigned long *vals) +{ + unw_context_t uc; + unw_cursor_t c; + int i, ret; + + disable_sighandler (); + + unw_getcontext (&uc); + + if ((ret = unw_init_local (&c, &uc)) < 0) + panic ("%s: unw_init_local (ret=%d)\n", __FUNCTION__, ret); + + if ((ret = unw_step (&c)) < 0) + panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret); + + for (i = 0; i < num_checks; ++i) + { + vals = (*checks[num_checks - 1 - i]) (&c, vals); + + if ((ret = unw_step (&c)) < 0) + panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret); + } +} + +static void +run_check (int test) +{ + int index, i; + + if (test == 1) + /* Make first test always go the full depth... */ + num_checks = MAX_CHECKS; + else + num_checks = (random () % MAX_CHECKS) + 1; + + for (i = 0; i < num_checks * MAX_VALUES_PER_FUNC; ++i) + values[i] = random_word (); + + for (i = 0; i < num_checks; ++i) + { + if (test == 1) + /* Make first test once go through each test... */ + index = i % (int) ARRAY_SIZE (all_funcs); + else + index = random () % (int) ARRAY_SIZE (all_funcs); + funcs[i] = all_funcs[index].func; + checks[i] = all_funcs[index].check; + } + + funcs[num_checks] = start_checks; + + enable_sighandler (); + (*funcs[0]) (funcs + 1, values); +} + +int +main (int argc, char **argv) +{ + int i; + + if (argc > 1) + verbose = 1; + + for (i = 0; i < NUM_RUNS; ++i) + { + if (verbose) + printf ("Run %d\n", i + 1); + run_check (i + 1); + } + + if (nerrors > 0) + { + fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); + exit (-1); + } + if (verbose) + printf ("SUCCESS.\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-rbs.c b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-rbs.c new file mode 100644 index 00000000000000..2181e70fd306c1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-rbs.c @@ -0,0 +1,193 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 tests corner-cases of unwinding across multiple stacks. + In particular, it verifies that the extreme case with a frame of 96 + stacked registers that are all backed up by separate stacks works + as expected. */ + +#include +#include + +#include +#include "compiler.h" + +#include "ia64-test-rbs.h" + +#define panic(args...) \ + do { fprintf (stderr, args); ++nerrors; return -9999; } while (0) + +/* The loadrs field in ar.rsc is 14 bits wide, which limits all ia64 + implementations to at most 2048 physical stacked registers + (actually, slightly less than that, because loadrs also counts RNaT + slots). Since we can dirty 93 stacked registers per recursion, we + need to recurse RECURSION_DEPTH times to ensure all physical + stacked registers are in use. */ +#define MAX_PHYS_STACKED 2048 +#define RECURSION_DEPTH ((MAX_PHYS_STACKED + 92) / 93) + +typedef int spill_func_t (long iteration, int (*next_func[])()); + +extern int loadup (long iteration, int *values, int (*next_func[])()); +extern char resumption_point_label; + +#define DCL(n) \ + extern int rbs_spill_##n (long iteration, int (*next_func[])()) + DCL(2); DCL(3); DCL(4); DCL(5); DCL(6); DCL(7); + DCL(8); DCL(9); DCL(10); DCL(11); DCL(12); DCL(13); DCL(14); DCL(15); + DCL(16); DCL(17); DCL(18); DCL(19); DCL(20); DCL(21); DCL(22); DCL(23); + DCL(24); DCL(25); DCL(26); DCL(27); DCL(28); DCL(29); DCL(30); DCL(31); + DCL(32); DCL(33); DCL(34); DCL(35); DCL(36); DCL(37); DCL(38); DCL(39); + DCL(40); DCL(41); DCL(42); DCL(43); DCL(44); DCL(45); DCL(46); DCL(47); + DCL(48); DCL(49); DCL(50); DCL(51); DCL(52); DCL(53); DCL(54); DCL(55); + DCL(56); DCL(57); DCL(58); DCL(59); DCL(60); DCL(61); DCL(62); DCL(63); + DCL(64); DCL(65); DCL(66); DCL(67); DCL(68); DCL(69); DCL(70); DCL(71); + DCL(72); DCL(73); DCL(74); DCL(75); DCL(76); DCL(77); DCL(78); DCL(79); + DCL(80); DCL(81); DCL(82); DCL(83); DCL(84); DCL(85); DCL(86); DCL(87); + DCL(88); DCL(89); DCL(90); DCL(91); DCL(92); DCL(93); DCL(94); + +#define SPL(n) rbs_spill_##n +spill_func_t *spill_funcs[] = + { + SPL(2), SPL(3), SPL(4), SPL(5), SPL(6), SPL(7), + SPL(8), SPL(9), SPL(10), SPL(11), SPL(12), SPL(13), SPL(14), SPL(15), + SPL(16), SPL(17), SPL(18), SPL(19), SPL(20), SPL(21), SPL(22), SPL(23), + SPL(24), SPL(25), SPL(26), SPL(27), SPL(28), SPL(29), SPL(30), SPL(31), + SPL(32), SPL(33), SPL(34), SPL(35), SPL(36), SPL(37), SPL(38), SPL(39), + SPL(40), SPL(41), SPL(42), SPL(43), SPL(44), SPL(45), SPL(46), SPL(47), + SPL(48), SPL(49), SPL(50), SPL(51), SPL(52), SPL(53), SPL(54), SPL(55), + SPL(56), SPL(57), SPL(58), SPL(59), SPL(60), SPL(61), SPL(62), SPL(63), + SPL(64), SPL(65), SPL(66), SPL(67), SPL(68), SPL(69), SPL(70), SPL(71), + SPL(72), SPL(73), SPL(74), SPL(75), SPL(76), SPL(77), SPL(78), SPL(79), + SPL(80), SPL(81), SPL(82), SPL(83), SPL(84), SPL(85), SPL(86), SPL(87), + SPL(88), SPL(89), SPL(90), SPL(91), SPL(92), SPL(93), SPL(94) + }; + +static int verbose; +static int nerrors; +static int unwind_count; + +static int +unwind_and_resume (long iteration, int (*next_func[])()) +{ + unw_context_t uc; + unw_cursor_t c; + unw_word_t ip; + int i, ret; + + if (verbose) + printf (" %s(iteration=%ld, next_func=%p)\n", + __FUNCTION__, iteration, next_func); + + unw_getcontext (&uc); + if ((ret = unw_init_local (&c, &uc)) < 0) + panic ("unw_init_local (ret=%d)", ret); + + for (i = 0; i < unwind_count; ++i) + if ((ret = unw_step (&c)) < 0) + panic ("unw_step (ret=%d)", ret); + + if (unw_get_reg (&c, UNW_REG_IP, &ip) < 0 + || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) &resumption_point_label) < 0 + || unw_set_reg (&c, UNW_REG_EH + 0, 0) /* ret val */ + || unw_set_reg (&c, UNW_REG_EH + 1, ip)) + panic ("failed to redirect to resumption_point\n"); + + if (verbose) + { + unw_word_t bsp; + if (unw_get_reg (&c, UNW_IA64_BSP, &bsp) < 0) + panic ("unw_get_reg() failed\n"); + printf (" bsp=%lx, old ip=%lx, new ip=%p\n", bsp, + ip, &resumption_point_label); + } + + ret = unw_resume (&c); + panic ("unw_resume() returned (ret=%d)!!\n", ret); + return 0; +} + +static int +run_check (int test) +{ + int nfuncs, nspills, n, ret, i, reg_values[88]; + spill_func_t *func[NSTACKS + 1]; + + /* First, generate a set of 88 random values which loadup() will load + into loc2-loc89 (r37-r124). */ + for (i = 0; i < (int) ARRAY_SIZE (reg_values); ++i) + { + reg_values[i] = random (); + /* Generate NaTs with a reasonably probability (1/16th): */ + if (reg_values[i] < 0x10000000) + reg_values[i] = 0; + } + + nspills = 0; + nfuncs = 0; + do + { + n = random () % (int) ARRAY_SIZE (spill_funcs); + func[nfuncs++] = spill_funcs[n]; + nspills += 2 + n; + } + while (nspills < 128); + func[nfuncs++] = unwind_and_resume; + + unwind_count = 1 + (random () % (nfuncs + RECURSION_DEPTH - 1)); + + if (verbose) + printf ("test%d: nfuncs=%d, unwind_count=%d\n", + test, nfuncs, unwind_count); + + ret = loadup (RECURSION_DEPTH, reg_values, func); + if (ret < 0) + panic ("test%d: load() returned %d\n", test, ret); + else if (ret != RECURSION_DEPTH + nfuncs - unwind_count) + panic ("test%d: resumed wrong frame: expected %d, got %d\n", + test, RECURSION_DEPTH + nfuncs - unwind_count, ret); + return 0; +} + +int +main (int argc, char **argv) +{ + int i; + + if (argc > 1) + verbose = 1; + + for (i = 0; i < 100000; ++i) + run_check (i + 1); + + if (nerrors > 0) + { + fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); + exit (-1); + } + if (verbose) + printf ("SUCCESS.\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-readonly.c b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-readonly.c new file mode 100644 index 00000000000000..25f0506102d43c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-readonly.c @@ -0,0 +1,89 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 verifies that read-only registers cannot be written to. */ + +#include +#include +#include +#include + +#include + +#define panic(args...) \ + do { printf (args); ++nerrors; } while (0) + +static int verbose; +static int nerrors; + +extern void test_func (void (*) (void)); + +void +checker (void) +{ + unw_fpreg_t fpval; + unw_context_t uc; + unw_cursor_t c; + int ret; + + fpval.raw.bits[0] = 100; + fpval.raw.bits[1] = 101; + + unw_getcontext (&uc); + + if ((ret = unw_init_local (&c, &uc)) < 0) + panic ("%s: unw_init_local (ret=%d)\n", __FUNCTION__, ret); + + if ((ret = unw_step (&c)) < 0) + panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret); + + if ((ret = unw_step (&c)) < 0) + panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret); + + if ((ret = unw_set_reg (&c, UNW_IA64_IP, 99)) != -UNW_EREADONLYREG) + panic ("%s: unw_set_reg (ip) returned %d instead of %d\n", + __FUNCTION__, ret, -UNW_EREADONLYREG); + if ((ret = unw_set_reg (&c, UNW_IA64_AR_LC, 99)) != -UNW_EREADONLYREG) + panic ("%s: unw_set_reg (ar.lc) returned %d instead of %d\n", + __FUNCTION__, ret, -UNW_EREADONLYREG); +} + +int +main (int argc, char **argv) +{ + if (argc > 1) + verbose = 1; + + test_func (checker); + + if (nerrors > 0) + { + fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); + exit (-1); + } + if (verbose) + printf ("SUCCESS.\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-stack.c b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-stack.c new file mode 100644 index 00000000000000..05874b291f3b3b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gia64-test-stack.c @@ -0,0 +1,176 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 tests corner-cases of unwinding across multiple stacks. + In particular, it verifies that the extreme case with a frame of 96 + stacked registers that are all backed up by separate stacks works + as expected. */ + +#include +#include +#include + +#include "ia64-test-stack.h" + +#define panic(args...) \ + { printf (args); ++nerrors; } + +/* The loadrs field in ar.rsc is 14 bits wide, which limits all ia64 + implementations to at most 2048 physical stacked registers + (actually, slightly less than that, because loadrs also counts RNaT + slots). Since we can dirty 95 stacked registers per recursion, we + need to recurse RECURSION_DEPTH times to ensure all physical + stacked registers are in use. */ +#define MAX_PHYS_STACKED 2048 +#define RECURSION_DEPTH ((MAX_PHYS_STACKED + 94) / 95) + +extern void touch_all (unsigned long recursion_depth); +extern void flushrs (void); + +int nerrors; +int verbose; + +void +do_unwind_tests (void) +{ + unw_word_t ip, sp, bsp, v0, v1, v2, v3, n0, n1, n2, n3, cfm, sof, sol, r32; + int ret, reg, i, l; + unw_context_t uc; + unw_cursor_t c; + + if (verbose) + printf ("do_unwind_tests: here we go!\n"); + + /* do a full stack-dump: */ + unw_getcontext (&uc); + unw_init_local (&c, &uc); + i = 0; + do + { + if (verbose) + { + if ((ret = unw_get_reg (&c, UNW_IA64_IP, &ip)) < 0 + || (ret = unw_get_reg (&c, UNW_IA64_SP, &sp)) < 0 + || (ret = unw_get_reg (&c, UNW_IA64_BSP, &bsp)) < 0) + break; + printf ("ip=0x%16lx sp=0x%16lx bsp=0x%16lx\n", ip, sp, bsp); + + for (reg = 32; reg < 128; reg += 4) + { + v0 = v1 = v2 = v3 = 0; + n0 = n1 = n2 = n3 = 0; + (void) + ((ret = unw_get_reg (&c, UNW_IA64_GR + reg, &v0)) < 0 + || (ret = unw_get_reg (&c, UNW_IA64_NAT + reg, &n0)) < 0 + || (ret = unw_get_reg (&c, UNW_IA64_GR + reg + 1, &v1)) < 0 + || (ret = unw_get_reg (&c, UNW_IA64_NAT + reg + 1, &n1)) < 0 + || (ret = unw_get_reg (&c, UNW_IA64_GR + reg + 2, &v2)) < 0 + || (ret = unw_get_reg (&c, UNW_IA64_NAT + reg + 2, &n2)) < 0 + || (ret = unw_get_reg (&c, UNW_IA64_GR + reg + 3, &v3)) < 0 + || (ret = unw_get_reg (&c, UNW_IA64_NAT + reg + 3, &n3)) < 0); + if (reg < 100) + printf (" r%d", reg); + else + printf (" r%d", reg); + printf (" %c%016lx %c%016lx %c%016lx %c%016lx\n", + n0 ? '*' : ' ', v0, n1 ? '*' : ' ', v1, + n2 ? '*' : ' ', v2, n3 ? '*' : ' ', v3); + if (ret < 0) + break; + } + } + + if (i >= 1 && i <= NSTACKS) + { + if ((ret = unw_get_reg (&c, UNW_IA64_CFM, &cfm)) < 0) + break; + sof = cfm & 0x7f; + if (sof != (unw_word_t) (i & 1)) + panic ("\texpected sof=%d, found sof=%lu\n", i - 1, sof); + if (sof == 1) + { + if ((ret = unw_get_reg (&c, UNW_IA64_GR + 32, &r32)) < 0) + break; + if (r32 != (unw_word_t) (i - 1)) + panic ("\texpected r32=%d, found r32=%lu\n", i - 1, r32); + } + } + else if (i > NSTACKS && i <= NSTACKS + RECURSION_DEPTH) + { + if ((ret = unw_get_reg (&c, UNW_IA64_CFM, &cfm)) < 0) + break; + sof = cfm & 0x7f; + sol = (cfm >> 7) & 0x7f; + if (sof != 96) + panic ("\texpected sof=96, found sof=%lu\n", sof); + if (sol != 95) + panic ("\texpected sol=95, found sol=%lu\n", sol); + + for (l = 2; l <= 93; ++l) + { + if ((ret = unw_get_reg (&c, UNW_IA64_GR + 33 + l, &v0)) < 0 + || (ret = unw_get_reg (&c, UNW_IA64_NAT + 33 + l, &n0)) < 0) + break; + switch (l) + { + case 2: case 31: case 73: case 93: + if (!n0) + panic ("\texpected loc%d to be a NaT!\n", l); + break; + + default: + if (n0) + panic ("\tloc%d is unexpectedly a NaT!\n", l); + v1 = ((unw_word_t) (i - NSTACKS) << 32) + l; + if (v0 != v1) + panic ("\tloc%d expected to be %lx, found to be %lx\n", + l, v1, v0); + } + } + } + ++i; + } + while ((ret = unw_step (&c)) > 0); + + if (ret < 0) + panic ("libunwind returned %d\n", ret); +} + +int +main (int argc, char **argv) +{ + if (argc > 1) + ++verbose; + + touch_all (RECURSION_DEPTH); + if (nerrors) + { + printf ("FAILURE: detected %d errors\n", nerrors); + exit (-1); + } + if (verbose) + printf ("SUCCESS\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gperf-simple.c b/src/coreclr/src/pal/src/libunwind/tests/Gperf-simple.c new file mode 100644 index 00000000000000..e1819182140349 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gperf-simple.c @@ -0,0 +1,264 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include + +#include +#include "compiler.h" + +#include +#include + +#define panic(args...) \ + do { fprintf (stderr, args); exit (-1); } while (0) + +long dummy; + +static long iterations = 10000; +static int maxlevel = 100; + +#define KB 1024 +#define MB (1024*1024) + +static char big[64*MB]; /* should be >> max. cache size */ + +static inline double +gettime (void) +{ + struct timeval tv; + + gettimeofday (&tv, NULL); + return tv.tv_sec + 1e-6*tv.tv_usec; +} + +static int NOINLINE +measure_unwind (int maxlevel, double *step) +{ + double stop, start; + unw_cursor_t cursor; + unw_context_t uc; + int ret, level = 0; + + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + panic ("unw_init_local() failed\n"); + + start = gettime (); + + do + { + ret = unw_step (&cursor); + if (ret < 0) + panic ("unw_step() failed\n"); + ++level; + } + while (ret > 0); + + stop = gettime (); + + if (level <= maxlevel) + panic ("Unwound only %d levels, expected at least %d levels\n", + level, maxlevel); + + *step = (stop - start) / (double) level; + return 0; +} + +static int f1 (int, int, double *); + +static int NOINLINE +g1 (int level, int maxlevel, double *step) +{ + if (level == maxlevel) + return measure_unwind (maxlevel, step); + else + /* defeat last-call/sibcall optimization */ + return f1 (level + 1, maxlevel, step) + level; +} + +static int NOINLINE +f1 (int level, int maxlevel, double *step) +{ + if (level == maxlevel) + return measure_unwind (maxlevel, step); + else + /* defeat last-call/sibcall optimization */ + return g1 (level + 1, maxlevel, step) + level; +} + +static void +doit (const char *label) +{ + double step, min_step, first_step, sum_step; + int i; + + sum_step = first_step = 0.0; + min_step = 1e99; + for (i = 0; i < iterations; ++i) + { + f1 (0, maxlevel, &step); + + sum_step += step; + + if (step < min_step) + min_step = step; + + if (i == 0) + first_step = step; + } + printf ("%s: unw_step : 1st=%9.3f min=%9.3f avg=%9.3f nsec\n", label, + 1e9*first_step, 1e9*min_step, 1e9*sum_step/iterations); +} + +static long +sum (void *buf, size_t size) +{ + long s = 0; + char *cp = buf; + size_t i; + + for (i = 0; i < size; i += 8) + s += cp[i]; + return s; +} + +static void +measure_init (void) +{ +# define N 100 +# define M 10 /* must be at least 2 to get steady-state */ + double stop, start, get_cold, get_warm, init_cold, init_warm, delta; + struct + { + unw_cursor_t c; + char padding[1024]; /* should be > 2 * max. cacheline size */ + } + cursor[N]; + struct + { + unw_context_t uc; + char padding[1024]; /* should be > 2 * max. cacheline size */ + } + uc[N]; + int i, j; + + /* Run each test M times and take the minimum to filter out noise + such dynamic linker resolving overhead, context-switches, + page-in, cache, and TLB effects. */ + + get_cold = 1e99; + for (j = 0; j < M; ++j) + { + dummy += sum (big, sizeof (big)); /* flush the cache */ + for (i = 0; i < N; ++i) + uc[i].padding[511] = i; /* warm up the TLB */ + start = gettime (); + for (i = 0; i < N; ++i) + unw_getcontext (&uc[i].uc); + stop = gettime (); + delta = (stop - start) / N; + if (delta < get_cold) + get_cold = delta; + } + + init_cold = 1e99; + for (j = 0; j < M; ++j) + { + dummy += sum (big, sizeof (big)); /* flush cache */ + for (i = 0; i < N; ++i) + uc[i].padding[511] = i; /* warm up the TLB */ + start = gettime (); + for (i = 0; i < N; ++i) + unw_init_local (&cursor[i].c, &uc[i].uc); + stop = gettime (); + delta = (stop - start) / N; + if (delta < init_cold) + init_cold = delta; + } + + get_warm = 1e99; + for (j = 0; j < M; ++j) + { + start = gettime (); + for (i = 0; i < N; ++i) + unw_getcontext (&uc[0].uc); + stop = gettime (); + delta = (stop - start) / N; + if (delta < get_warm) + get_warm = delta; + } + + init_warm = 1e99; + for (j = 0; j < M; ++j) + { + start = gettime (); + for (i = 0; i < N; ++i) + unw_init_local (&cursor[0].c, &uc[0].uc); + stop = gettime (); + delta = (stop - start) / N; + if (delta < init_warm) + init_warm = delta; + } + + printf ("unw_getcontext : cold avg=%9.3f nsec, warm avg=%9.3f nsec\n", + 1e9 * get_cold, 1e9 * get_warm); + printf ("unw_init_local : cold avg=%9.3f nsec, warm avg=%9.3f nsec\n", + 1e9 * init_cold, 1e9 * init_warm); +} + +int +main (int argc, char **argv) +{ + struct rlimit rlim; + + rlim.rlim_cur = RLIM_INFINITY; + rlim.rlim_max = RLIM_INFINITY; + setrlimit (RLIMIT_STACK, &rlim); + + memset (big, 0xaa, sizeof (big)); + + if (argc > 1) + { + maxlevel = atol (argv[1]); + if (argc > 2) + iterations = atol (argv[2]); + } + + measure_init (); + + doit ("default "); + + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); + doit ("no cache "); + + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); + doit ("global cache "); + + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); + doit ("per-thread cache"); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gperf-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Gperf-trace.c new file mode 100644 index 00000000000000..4d24fa5ca86574 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gperf-trace.c @@ -0,0 +1,250 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include + +#include +#include "compiler.h" + +#include +#include + +#define panic(args...) \ + do { fprintf (stderr, args); exit (-1); } while (0) + +long dummy; + +static long iterations = 10000; +static int maxlevel = 100; + +#define KB 1024 +#define MB (1024*1024) + +static char big[64*MB]; /* should be >> max. cache size */ + +static inline double +gettime (void) +{ + struct timeval tv; + + gettimeofday (&tv, NULL); + return tv.tv_sec + 1e-6*tv.tv_usec; +} + +static int NOINLINE +measure_unwind (int maxlevel, double *step) +{ + double stop, start; + int level = 0; + void *buffer[128]; + + start = gettime (); + level = unw_backtrace(buffer, 128); + stop = gettime (); + + if (level <= maxlevel) + panic ("Unwound only %d levels, expected at least %d levels\n", + level, maxlevel); + + *step = (stop - start) / (double) level; + return 0; +} + +static int f1 (int, int, double *); + +static int NOINLINE +g1 (int level, int maxlevel, double *step) +{ + if (level == maxlevel) + return measure_unwind (maxlevel, step); + else + /* defeat last-call/sibcall optimization */ + return f1 (level + 1, maxlevel, step) + level; +} + +static int NOINLINE +f1 (int level, int maxlevel, double *step) +{ + if (level == maxlevel) + return measure_unwind (maxlevel, step); + else + /* defeat last-call/sibcall optimization */ + return g1 (level + 1, maxlevel, step) + level; +} + +static void +doit (const char *label) +{ + double step, min_step, first_step, sum_step; + int i; + + sum_step = first_step = 0.0; + min_step = 1e99; + for (i = 0; i < iterations; ++i) + { + f1 (0, maxlevel, &step); + + sum_step += step; + + if (step < min_step) + min_step = step; + + if (i == 0) + first_step = step; + } + printf ("%s: unw_step : 1st=%9.3f min=%9.3f avg=%9.3f nsec\n", label, + 1e9*first_step, 1e9*min_step, 1e9*sum_step/iterations); +} + +static long +sum (void *buf, size_t size) +{ + long s = 0; + char *cp = buf; + size_t i; + + for (i = 0; i < size; i += 8) + s += cp[i]; + return s; +} + +static void +measure_init (void) +{ +# define N 100 +# define M 10 /* must be at least 2 to get steady-state */ + double stop, start, get_cold, get_warm, init_cold, init_warm, delta; + struct + { + unw_cursor_t c; + char padding[1024]; /* should be > 2 * max. cacheline size */ + } + cursor[N]; + struct + { + unw_context_t uc; + char padding[1024]; /* should be > 2 * max. cacheline size */ + } + uc[N]; + int i, j; + + /* Run each test M times and take the minimum to filter out noise + such dynamic linker resolving overhead, context-switches, + page-in, cache, and TLB effects. */ + + get_cold = 1e99; + for (j = 0; j < M; ++j) + { + dummy += sum (big, sizeof (big)); /* flush the cache */ + for (i = 0; i < N; ++i) + uc[i].padding[511] = i; /* warm up the TLB */ + start = gettime (); + for (i = 0; i < N; ++i) + unw_getcontext (&uc[i].uc); + stop = gettime (); + delta = (stop - start) / N; + if (delta < get_cold) + get_cold = delta; + } + + init_cold = 1e99; + for (j = 0; j < M; ++j) + { + dummy += sum (big, sizeof (big)); /* flush cache */ + for (i = 0; i < N; ++i) + uc[i].padding[511] = i; /* warm up the TLB */ + start = gettime (); + for (i = 0; i < N; ++i) + unw_init_local (&cursor[i].c, &uc[i].uc); + stop = gettime (); + delta = (stop - start) / N; + if (delta < init_cold) + init_cold = delta; + } + + get_warm = 1e99; + for (j = 0; j < M; ++j) + { + start = gettime (); + for (i = 0; i < N; ++i) + unw_getcontext (&uc[0].uc); + stop = gettime (); + delta = (stop - start) / N; + if (delta < get_warm) + get_warm = delta; + } + + init_warm = 1e99; + for (j = 0; j < M; ++j) + { + start = gettime (); + for (i = 0; i < N; ++i) + unw_init_local (&cursor[0].c, &uc[0].uc); + stop = gettime (); + delta = (stop - start) / N; + if (delta < init_warm) + init_warm = delta; + } + + printf ("unw_getcontext : cold avg=%9.3f nsec, warm avg=%9.3f nsec\n", + 1e9 * get_cold, 1e9 * get_warm); + printf ("unw_init_local : cold avg=%9.3f nsec, warm avg=%9.3f nsec\n", + 1e9 * init_cold, 1e9 * init_warm); +} + +int +main (int argc, char **argv) +{ + struct rlimit rlim; + + rlim.rlim_cur = RLIM_INFINITY; + rlim.rlim_max = RLIM_INFINITY; + setrlimit (RLIMIT_STACK, &rlim); + + memset (big, 0xaa, sizeof (big)); + + if (argc > 1) + { + maxlevel = atol (argv[1]); + if (argc > 2) + iterations = atol (argv[2]); + } + + measure_init (); + + doit ("default "); + + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); + doit ("no cache "); + + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); + doit ("global cache "); + + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); + doit ("per-thread cache"); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c new file mode 100644 index 00000000000000..d5b484478705c7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c @@ -0,0 +1,263 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "compiler.h" + +#include +#if HAVE_EXECINFO_H +# include +#else + extern int backtrace (void **, int); +#endif +#include +#include +#include +#include +#include +#include +#include + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +#define SIG_STACK_SIZE 0x100000 + +int verbose; +int num_errors; + +/* These variables are global because they + * cause the signal stack to overflow */ +char buf[512], name[256]; +unw_cursor_t cursor; +unw_context_t uc; + +static void +do_backtrace (void) +{ + unw_word_t ip, sp, off; + unw_proc_info_t pi; + int ret; + + if (verbose) + printf ("\texplicit backtrace:\n"); + + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + panic ("unw_init_local failed!\n"); + + do + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + unw_get_reg (&cursor, UNW_REG_SP, &sp); + buf[0] = '\0'; + if (unw_get_proc_name (&cursor, name, sizeof (name), &off) == 0) + { + if (off) + snprintf (buf, sizeof (buf), "<%s+0x%lx>", name, (long) off); + else + snprintf (buf, sizeof (buf), "<%s>", name); + } + if (verbose) + { + printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); + + if (unw_get_proc_info (&cursor, &pi) == 0) + { + printf ("\tproc=0x%lx-0x%lx\n\thandler=0x%lx lsda=0x%lx gp=0x%lx", + (long) pi.start_ip, (long) pi.end_ip, + (long) pi.handler, (long) pi.lsda, (long) pi.gp); + } + +#if UNW_TARGET_IA64 + { + unw_word_t bsp; + + unw_get_reg (&cursor, UNW_IA64_BSP, &bsp); + printf (" bsp=%lx", bsp); + } +#endif + printf ("\n"); + } + + ret = unw_step (&cursor); + if (ret < 0) + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + printf ("FAILURE: unw_step() returned %d for ip=%lx\n", + ret, (long) ip); + ++num_errors; + } + } + while (ret > 0); + + { + void *buffer[20]; + int i, n; + + if (verbose) + printf ("\n\tvia backtrace():\n"); + n = backtrace (buffer, 20); + if (verbose) + for (i = 0; i < n; ++i) + printf ("[%d] ip=%p\n", i, buffer[i]); + } +} + +void +foo (long val UNUSED) +{ + do_backtrace (); +} + +void +bar (long v) +{ + extern long f (long); + int arr[v]; + + /* This is a vain attempt to use up lots of registers to force + the frame-chain info to be saved on the memory stack on ia64. + It happens to work with gcc v3.3.4 and gcc v3.4.1 but perhaps + not with any other compiler. */ + foo (f (arr[0]) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + f (v)) + )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + ))))))))))))))))))))))))))))))))))))))))))))))))))))))); +} + +void +sighandler (int signal, void *siginfo UNUSED, void *context) +{ + ucontext_t *uc UNUSED; + int sp; + + uc = context; + + if (verbose) + { + printf ("sighandler: got signal %d, sp=%p", signal, &sp); +#if UNW_TARGET_IA64 +# if defined(__linux__) || defined __sun + printf (" @ %lx", uc->uc_mcontext.sc_ip); +# else + { + uint16_t reason; + uint64_t ip; + + __uc_get_reason (uc, &reason); + __uc_get_ip (uc, &ip); + printf (" @ %lx (reason=%d)", ip, reason); + } +# endif +#elif UNW_TARGET_X86 +#if defined __linux__ || defined __sun + printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]); +#elif defined __FreeBSD__ + printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); +#endif +#elif UNW_TARGET_X86_64 +#if defined __linux__ || defined __sun + printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); +#elif defined __FreeBSD__ + printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); +#endif +#endif + printf ("\n"); + } + do_backtrace(); +} + +int +main (int argc, char **argv UNUSED) +{ + struct sigaction act; + stack_t stk; + + verbose = (argc > 1); + + if (verbose) + printf ("Normal backtrace:\n"); + + bar (1); + + memset (&act, 0, sizeof (act)); + act.sa_handler = (void (*)(int)) sighandler; + act.sa_flags = SA_SIGINFO; + if (sigaction (SIGTERM, &act, NULL) < 0) + panic ("sigaction: %s\n", strerror (errno)); + + if (verbose) + printf ("\nBacktrace across signal handler:\n"); + kill (getpid (), SIGTERM); + + if (verbose) + printf ("\nBacktrace across signal handler on alternate stack:\n"); + stk.ss_sp = malloc (SIG_STACK_SIZE); + if (!stk.ss_sp) + panic ("failed to allocate %u bytes\n", SIG_STACK_SIZE); + stk.ss_size = SIG_STACK_SIZE; + stk.ss_flags = 0; + if (sigaltstack (&stk, NULL) < 0) + panic ("sigaltstack: %s\n", strerror (errno)); + + memset (&act, 0, sizeof (act)); + act.sa_handler = (void (*)(int)) sighandler; + act.sa_flags = SA_ONSTACK | SA_SIGINFO; + if (sigaction (SIGTERM, &act, NULL) < 0) + panic ("sigaction: %s\n", strerror (errno)); + kill (getpid (), SIGTERM); + + if (num_errors > 0) + { + fprintf (stderr, "FAILURE: detected %d errors\n", num_errors); + exit (-1); + } + if (verbose) + printf ("SUCCESS.\n"); + + signal (SIGTERM, SIG_DFL); + stk.ss_flags = SS_DISABLE; + sigaltstack (&stk, NULL); + free (stk.ss_sp); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-concurrent.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-concurrent.c new file mode 100644 index 00000000000000..6f3447fd844da1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-concurrent.c @@ -0,0 +1,136 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* Verify that multi-threaded concurrent unwinding works as expected. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "compiler.h" + +#include +#include +#include +#include +#include +#include +#include + +#define NTHREADS 128 + +#define panic(args...) \ + do { fprintf (stderr, args); ++nerrors; } while (0) + +int verbose; +int nerrors; +int got_usr1, got_usr2; +char *sigusr1_sp; + +void +handler (int sig UNUSED) +{ + unw_word_t ip; + unw_context_t uc; + unw_cursor_t c; + int ret; + + unw_getcontext (&uc); + unw_init_local (&c, &uc); + do + { + unw_get_reg (&c, UNW_REG_IP, &ip); + if (verbose) + printf ("%lx: IP=%lx\n", (long) pthread_self (), (unsigned long) ip); + } + while ((ret = unw_step (&c)) > 0); + + if (ret < 0) + panic ("unw_step() returned %d\n", ret); +} + +void * +worker (void *arg UNUSED) +{ + signal (SIGUSR1, handler); + + if (verbose) + printf ("sending SIGUSR1\n"); + pthread_kill (pthread_self (), SIGUSR1); + return NULL; +} + +static void +doit (void) +{ + pthread_t th[NTHREADS]; + pthread_attr_t attr; + int i; + + pthread_attr_init (&attr); + pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN + 64*1024); + + for (i = 0; i < NTHREADS; ++i) + if (pthread_create (th + i, &attr, worker, NULL)) + { + fprintf (stderr, "FAILURE: Failed to create %u threads " + "(after %u threads)\n", + NTHREADS, i); + exit (-1); + } + + for (i = 0; i < NTHREADS; ++i) + pthread_join (th[i], NULL); +} + +int +main (int argc, char **argv UNUSED) +{ + if (argc > 1) + verbose = 1; + + if (verbose) + printf ("Caching: none\n"); + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); + doit (); + + if (verbose) + printf ("Caching: global\n"); + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); + doit (); + + if (verbose) + printf ("Caching: per-thread\n"); + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); + doit (); + + if (nerrors) + { + fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); + exit (-1); + } + + if (verbose) + printf ("SUCCESS\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-dyn1.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-dyn1.c new file mode 100644 index 00000000000000..bc7dc9cf7feb93 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-dyn1.c @@ -0,0 +1,223 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 tests dynamic code-generation via function-cloning. */ + +#include "flush-cache.h" + +#include "compiler.h" + +#include +#include +#include +#include +#include +#include +#include + +#if UNW_TARGET_ARM +#define MAX_FUNC_SIZE 96 /* FIXME: arch/compiler dependent */ +#else +#define MAX_FUNC_SIZE 2048 /* max. size of cloned function */ +#endif + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +typedef void (*template_t) (int, void (*)(), + int (*)(const char *, ...), const char *, + const char **); + +int verbose; + +static const char *strarr[] = + { + "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x", NULL + }; + +#ifdef __ia64__ +struct fdesc + { + long code; + long gp; + }; +# define get_fdesc(fdesc,func) (fdesc = *(struct fdesc *) &(func)) +# define get_funcp(fdesc) ((template_t) &(fdesc)) +# define get_gp(fdesc) ((fdesc).gp) +#elif __arm__ +struct fdesc + { + long code; + long is_thumb; + }; +/* Workaround GCC bug: https://bugs.launchpad.net/gcc-linaro/+bug/721531 */ +# define get_fdesc(fdesc,func) ({long tmp = (long) &(func); \ + (fdesc).code = (long) &(func) & ~0x1; \ + (fdesc).is_thumb = tmp & 0x1;}) +/*# define get_fdesc(fdesc,func) ({(fdesc).code = (long) &(func) & ~0x1; \ + (fdesc).is_thumb = (long) &(func) & 0x1;})*/ +# define get_funcp(fdesc) ((template_t) ((fdesc).code | (fdesc).is_thumb)) +# define get_gp(fdesc) (0) +#else +struct fdesc + { + long code; + }; +# define get_fdesc(fdesc,func) (fdesc.code = (long) &(func)) +# define get_funcp(fdesc) ((template_t) (fdesc).code) +# define get_gp(fdesc) (0) +#endif + +void +template (int i, template_t self, + int (*printer)(const char *, ...), const char *fmt, const char **arr) +{ + (*printer) (fmt, arr[11 - i][0], arr[11 - i] + 1); + if (i > 0) + (*self) (i - 1, self, printer, fmt, arr); +} + +static void +sighandler (int signal) +{ + unw_cursor_t cursor; + char name[128], off[32]; + unw_word_t ip, offset; + unw_context_t uc; + int count; + + if (verbose) + printf ("caught signal %d\n", signal); + + unw_getcontext (&uc); + unw_init_local (&cursor, &uc); + + count = 0; + while (!unw_is_signal_frame (&cursor)) + { + if (unw_step (&cursor) < 0) + panic ("failed to find signal frame!\n"); + + if (count++ > 20) + { + panic ("Too many steps to the signal frame (%d)\n", count); + break; + } + } + unw_step (&cursor); + + count = 0; + do + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + name[0] = '\0'; + off[0] = '\0'; + if (unw_get_proc_name (&cursor, name, sizeof (name), &offset) == 0 + && offset > 0) + snprintf (off, sizeof (off), "+0x%lx", (long) offset); + if (verbose) + printf ("ip = %lx <%s%s>\n", (long) ip, name, off); + ++count; + + if (count > 20) + { + panic ("Too many steps (%d)\n", count); + break; + } + + } + while (unw_step (&cursor) > 0); + + if (count != 13) + panic ("FAILURE: expected 13, not %d frames below signal frame\n", count); + + if (verbose) + printf ("SUCCESS\n"); + exit (0); +} + +int +dev_null (const char *format UNUSED, ...) +{ + return 0; +} + +int +main (int argc, char *argv[] UNUSED) +{ + unw_dyn_region_info_t *region; + unw_dyn_info_t di; + struct fdesc fdesc; + template_t funcp; + void *mem; + + if (argc > 1) + ++verbose; + + mem = malloc (getpagesize ()); + + get_fdesc (fdesc, template); + + if (verbose) + printf ("old code @ %p, new code @ %p\n", (void *) fdesc.code, mem); + + memcpy (mem, (void *) fdesc.code, MAX_FUNC_SIZE); + mprotect ((void *) ((long) mem & ~(getpagesize () - 1)), + 2*getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC); + + flush_cache (mem, MAX_FUNC_SIZE); + + signal (SIGSEGV, sighandler); + + /* register the new function: */ + region = alloca (_U_dyn_region_info_size (2)); + region->next = NULL; + region->insn_count = 3 * (MAX_FUNC_SIZE / 16); + region->op_count = 2; + _U_dyn_op_alias (®ion->op[0], 0, -1, fdesc.code); + _U_dyn_op_stop (®ion->op[1]); + + memset (&di, 0, sizeof (di)); + di.start_ip = (long) mem; + di.end_ip = (long) mem + 16*region->insn_count/3; + di.gp = get_gp (fdesc); + di.format = UNW_INFO_FORMAT_DYNAMIC; + di.u.pi.name_ptr = (unw_word_t) "copy_of_template"; + di.u.pi.regions = region; + + _U_dyn_register (&di); + + /* call new function: */ + fdesc.code = (long) mem; + funcp = get_funcp (fdesc); + + if (verbose) + (*funcp) (10, funcp, printf, "iteration %c%s\n", strarr); + else + (*funcp) (10, funcp, dev_null, "iteration %c%s\n", strarr); + + _U_dyn_cancel (&di); + return -1; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-exc.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-exc.c new file mode 100644 index 00000000000000..1170bdd03fd981 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-exc.c @@ -0,0 +1,162 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 illustrates the basics of using the unwind interface for + exception handling. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include + +#ifdef HAVE_IA64INTRIN_H +# include +#endif + +#define panic(args...) \ + { ++nerrors; fprintf (stderr, args); } + +int nerrors = 0; +int verbose = 0; +int depth = 13; +volatile int got_here = 0; + +extern void b (int); + +void +raise_exception (void) +{ + unw_cursor_t cursor; + unw_context_t uc; + int i; + + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + { + panic ("unw_init_local() failed!\n"); + return; + } + + /* unwind to top-most frame a(), skipping over b() and raise_exception(): */ + for (i = 0; i < depth + 2; ++i) + if (unw_step (&cursor) < 0) + { + panic ("unw_step() failed!\n"); + return; + } + unw_resume (&cursor); /* transfer control to exception handler */ +} + +uintptr_t +get_bsp (void) +{ +#if UNW_TARGET_IA64 +# ifdef __INTEL_COMPILER + return __getReg (_IA64_REG_AR_BSP); +# else + return (uintptr_t) __builtin_ia64_bsp (); +# endif +#else + return 0; +#endif +} + +int +a (int n) +{ + long stack; + int result = 99; + + if (verbose) + printf ("a(n=%d): sp=%p bsp=0x%lx\n", + n, &stack, (unsigned long) get_bsp ()); + + if (n > 0) + a (n - 1); + else + b (16); + + if (verbose) + { + printf ("exception handler: here we go (sp=%p, bsp=0x%lx)...\n", + &stack, (unsigned long) get_bsp ()); + /* This call works around a bug in gcc (up-to pre3.4) which + causes invalid assembly code to be generated when + __builtin_ia64_bsp() gets predicated. */ + getpid (); + } + if (n == depth) + { + result = 0; + got_here = 1; + } + return result; +} + +void +b (int n) +{ + if ((n & 1) == 0) + { + if (verbose) + printf ("b(n=%d) calling raise_exception()\n", n); + raise_exception (); + } + panic ("FAILURE: b() returned from raise_exception()!!\n"); +} + +int +main (int argc, char **argv) +{ + int result; + + if (argc > 1) + { + ++verbose; + depth = atol (argv[1]); + if (depth < 1) + { + fprintf (stderr, "Usage: %s depth\n" + " depth must be >= 1\n", argv[0]); + exit (-1); + } + } + + result = a (depth); + if (result != 0 || !got_here || nerrors > 0) + { + fprintf (stderr, + "FAILURE: test failed: result=%d got_here=%d nerrors=%d\n", + result, got_here, nerrors); + exit (-1); + } + + if (verbose) + printf ("SUCCESS!\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-init.cxx b/src/coreclr/src/pal/src/libunwind/tests/Gtest-init.cxx new file mode 100644 index 00000000000000..afded019273f53 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-init.cxx @@ -0,0 +1,107 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 tests unwinding from a constructor from within an + atexit() handler. */ + +#include +#include +#include + +#include +#include "compiler.h" + +int verbose, errors; + +#define panic(args...) \ + { ++errors; fprintf (stderr, args); return; } + +class Test_Class { + public: + Test_Class (void); +}; + +static Test_Class t; + +static void +do_backtrace (void) +{ + char name[128], off[32]; + unw_word_t ip, offset; + unw_cursor_t cursor; + unw_context_t uc; + int ret, count = 0; + + unw_getcontext (&uc); + unw_init_local (&cursor, &uc); + + do + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + name[0] = '\0'; + off[0] = '\0'; + if (unw_get_proc_name (&cursor, name, sizeof (name), &offset) == 0 + && offset > 0) + snprintf (off, sizeof (off), "+0x%lx", (long) offset); + if (verbose) + printf (" [%lx] <%s%s>\n", (long) ip, name, off); + if (++count > 32) + panic ("FAILURE: didn't reach beginning of unwind-chain\n"); + } + while ((ret = unw_step (&cursor)) > 0); + + if (ret < 0) + panic ("FAILURE: unw_step() returned %d\n", ret); +} + +static void +b (void) +{ + do_backtrace(); +} + +static void +a (void) +{ + if (verbose) + printf ("do_backtrace() from atexit()-handler:\n"); + b(); + if (errors) + abort (); /* cannot portably call exit() from an atexit() handler */ +} + +Test_Class::Test_Class (void) +{ + if (verbose) + printf ("do_backtrace() from constructor:\n"); + b(); +} + +int +main (int argc, char **argv UNUSED) +{ + verbose = argc > 1; + return atexit (a); +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-nomalloc.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-nomalloc.c new file mode 100644 index 00000000000000..5b97fc70918c45 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-nomalloc.c @@ -0,0 +1,110 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2009 Google, Inc + Contributed by Arun Sharma + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include +#include + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +int verbose; +int num_errors; +int in_unwind; + +void * +malloc(size_t s) +{ + static void * (*func)(); + + if(!func) + func = (void *(*)()) dlsym(RTLD_NEXT, "malloc"); + + if (in_unwind) { + num_errors++; + return NULL; + } else { + return func(s); + } +} + +static void +do_backtrace (void) +{ + unw_word_t ip, sp; + unw_cursor_t cursor; + unw_context_t uc; + int ret; + + in_unwind = 1; + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + panic ("unw_init_local failed!\n"); + + do + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + unw_get_reg (&cursor, UNW_REG_SP, &sp); + + ret = unw_step (&cursor); + if (ret < 0) + { + ++num_errors; + } + } + while (ret > 0); + in_unwind = 0; +} + +void +foo3 (void) +{ + do_backtrace (); +} + +void +foo2 (void) +{ + foo3 (); +} + +void +foo1 (void) +{ + foo2 (); +} + +int +main (void) +{ + foo1(); + + if (num_errors > 0) + { + fprintf (stderr, "FAILURE: detected %d errors\n", num_errors); + exit (-1); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig-rt.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig-rt.c new file mode 100644 index 00000000000000..df515fc1953938 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig-rt.c @@ -0,0 +1,31 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + Copyright (C) 2012 Tommi Rantala + +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. */ + +/* The purpose of this test is to invoke different code paths in libunwind (on + * some architectures), that are executed when the SA_SIGINFO sigaction() flag + * is used. + */ + +#define TEST_WITH_SIGINFO 1 +#include "Gtest-resume-sig.c" diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig.c new file mode 100644 index 00000000000000..18ec65da713440 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-resume-sig.c @@ -0,0 +1,200 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* Verify that unw_resume() restores the signal mask at proper time. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "compiler.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_IA64INTRIN_H +# include +#endif + +#define panic(args...) \ + do { fprintf (stderr, args); ++nerrors; } while (0) + +int verbose; +int nerrors; +int got_usr1, got_usr2; +char *sigusr1_sp; + +uintptr_t +get_bsp (void) +{ +#if UNW_TARGET_IA64 +# ifdef __INTEL_COMPILER + return __getReg (_IA64_REG_AR_BSP); +# else + return (uintptr_t) __builtin_ia64_bsp (); +# endif +#else + return 0; +#endif +} + +#ifdef TEST_WITH_SIGINFO +void +handler (int sig, + siginfo_t *si UNUSED, + void *ucontext UNUSED) +#else +void +handler (int sig) +#endif +{ + unw_word_t ip; + sigset_t mask; + unw_context_t uc; + unw_cursor_t c; + char foo; + int ret; + // The test rely on SIGUSR2 mask to be cleared when the handler returns. + // For local context from the signal handler, there doesn't seem to be a way + // currently to set it so just clear the whole struct to make sure the signal mask is cleared. + // This should probably be fixed to avoid signal mask being set to random values + // by `unw_resume` if the context was not pre-zeroed., + // Using the signal ucontext direction should also work automatically but currently doesn't + // on ARM/AArch64 (or any other archs that doesn't have a proper sigreturn implementation) + memset(&uc, 0x0, sizeof(uc)); + +#if UNW_TARGET_IA64 + if (verbose) + printf ("bsp = %llx\n", (unsigned long long) get_bsp ()); +#endif + + if (verbose) + printf ("got signal %d\n", sig); + + if (sig == SIGUSR1) + { + ++got_usr1; + sigusr1_sp = &foo; + + sigemptyset (&mask); + sigaddset (&mask, SIGUSR2); + sigprocmask (SIG_BLOCK, &mask, NULL); + kill (getpid (), SIGUSR2); /* pend SIGUSR2 */ + + signal (SIGUSR1, SIG_IGN); + + if ((ret = unw_getcontext (&uc)) < 0) + panic ("unw_getcontext() failed: ret=%d\n", ret); + if ((ret = unw_init_local (&c, &uc)) < 0) + panic ("unw_init_local() failed: ret=%d\n", ret); + + if ((ret = unw_step (&c)) < 0) /* step to signal trampoline */ + panic ("unw_step(1) failed: ret=%d\n", ret); + + if ((ret = unw_step (&c)) < 0) /* step to kill() */ + panic ("unw_step(2) failed: ret=%d\n", ret); + +#if defined(UNW_TARGET_TILEGX) + if ((ret = unw_step (&c)) < 0) /* step to signal trampoline */ + panic ("unw_step(2) failed: ret=%d\n", ret); +#endif + + if ((ret = unw_get_reg (&c, UNW_REG_IP, &ip)) < 0) + panic ("unw_get_reg(IP) failed: ret=%d\n", ret); + if (verbose) + printf ("resuming at 0x%lx, with SIGUSR2 pending\n", + (unsigned long) ip); + unw_resume (&c); + } + else if (sig == SIGUSR2) + { + ++got_usr2; + if (got_usr1) + { + if (verbose) + printf ("OK: stack still at %p\n", &foo); + } + signal (SIGUSR2, SIG_IGN); + } + else + panic ("Got unexpected signal %d\n", sig); +} + +int +main (int argc, char **argv UNUSED) +{ + struct sigaction sa; + float d = 1.0; + int n = 0; + + if (argc > 1) + verbose = 1; + + memset (&sa, 0, sizeof(sa)); +#ifdef TEST_WITH_SIGINFO + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO; +#else + sa.sa_handler = handler; +#endif + + if (sigaction (SIGUSR1, &sa, NULL) != 0 || + sigaction (SIGUSR2, &sa, NULL) != 0) + { + fprintf (stderr, "sigaction() failed: %s\n", strerror (errno)); + return -1; + } + + /* Use the FPU a bit; otherwise we get spurious errors should the + signal handler need to use the FPU for any reason. This seems to + happen on x86-64. */ + while (d > 0.0) + { + d /= 2.0; + ++n; + } + if (n > 9999) + return -1; /* can't happen, but don't tell the compiler... */ + + if (verbose) + printf ("sending SIGUSR1\n"); + kill (getpid (), SIGUSR1); + + if (!got_usr2) + panic ("failed to get SIGUSR2\n"); + + if (nerrors) + { + fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); + exit (-1); + } + + if (verbose) + printf ("SUCCESS\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c new file mode 100644 index 00000000000000..48667bb9f4df30 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c @@ -0,0 +1,282 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010, 2011 by FERMI NATIONAL ACCELERATOR LABORATORY + +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. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "compiler.h" + +#include +#if HAVE_EXECINFO_H +# include +#else + extern int backtrace (void **, int); +#endif +#include +#include +#include +#include +#include +#include +#include + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +#define SIG_STACK_SIZE 0x100000 + +int verbose; +int num_errors; + +/* These variables are global because they + * cause the signal stack to overflow */ +char buf[512], name[256]; +void *addresses[3][128]; +unw_cursor_t cursor; +unw_context_t uc; + +static void +do_backtrace (void) +{ + unw_word_t ip; + int ret = -UNW_ENOINFO; + int depth = 0; + int i, n, m; + + if (verbose) + printf ("\tnormal trace:\n"); + + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + panic ("unw_init_local failed!\n"); + + do + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + addresses[0][depth] = (void *) ip; + } + while ((ret = unw_step (&cursor)) > 0 && ++depth < 128); + + if (ret < 0) + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + printf ("FAILURE: unw_step() returned %d for ip=%lx\n", ret, (long) ip); + ++num_errors; + } + + if (verbose) + for (i = 0; i < depth; ++i) + printf ("\t #%-3d ip=%p\n", i, addresses[0][i]); + + if (verbose) + printf ("\n\tvia backtrace():\n"); + + n = backtrace (addresses[1], 128); + + if (verbose) + for (i = 0; i < n; ++i) + printf ("\t #%-3d ip=%p\n", i, addresses[1][i]); + + if (verbose) + printf ("\n\tvia unw_backtrace():\n"); + + m = unw_backtrace (addresses[2], 128); + + if (verbose) + for (i = 0; i < m; ++i) + printf ("\t #%-3d ip=%p\n", i, addresses[2][i]); + + if (m != depth+1) + { + printf ("FAILURE: unw_step() loop and unw_backtrace() depths differ: %d vs. %d\n", depth, m); + ++num_errors; + } + + if (n != depth+1) + { + printf ("FAILURE: unw_step() loop and backtrace() depths differ: %d vs. %d\n", depth, n); + ++num_errors; + } + + if (n == m) + for (i = 1; i < n; ++i) + /* Allow one in difference in comparison, trace returns adjusted addresses. */ + if (labs((unw_word_t) addresses[1][i] - (unw_word_t) addresses[2][i]) > 1) + { + printf ("FAILURE: backtrace() and unw_backtrace() addresses differ at %d: %p vs. %p\n", + i, addresses[1][i], addresses[2][i]); + ++num_errors; + } + + if (n == depth+1) + for (i = 1; i < depth; ++i) + /* Allow one in difference in comparison, trace returns adjusted addresses. */ + if (labs((unw_word_t) addresses[0][i] - (unw_word_t) addresses[1][i]) > 1) + { + printf ("FAILURE: unw_step() loop and backtrace() addresses differ at %d: %p vs. %p\n", + i, addresses[0][i], addresses[1][i]); + ++num_errors; + } +} + +void +foo (long val UNUSED) +{ + do_backtrace (); +} + +void +bar (long v) +{ + extern long f (long); + int arr[v]; + + /* This is a vain attempt to use up lots of registers to force + the frame-chain info to be saved on the memory stack on ia64. + It happens to work with gcc v3.3.4 and gcc v3.4.1 but perhaps + not with any other compiler. */ + foo (f (arr[0]) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + f (v)) + )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + ))))))))))))))))))))))))))))))))))))))))))))))))))))))); +} + +void +sighandler (int signal, void *siginfo UNUSED, void *context) +{ + ucontext_t *uc UNUSED; + int sp; + + uc = context; + + if (verbose) + { + printf ("sighandler: got signal %d, sp=%p", signal, &sp); +#if UNW_TARGET_IA64 +# if defined(__linux__) + printf (" @ %lx", uc->uc_mcontext.sc_ip); +# else + { + uint16_t reason; + uint64_t ip; + + __uc_get_reason (uc, &reason); + __uc_get_ip (uc, &ip); + printf (" @ %lx (reason=%d)", ip, reason); + } +# endif +#elif UNW_TARGET_X86 +#if defined __linux__ + printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]); +#elif defined __FreeBSD__ + printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); +#endif +#elif UNW_TARGET_X86_64 +#if defined __linux__ || defined __sun + printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); +#elif defined __FreeBSD__ + printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); +#endif +#elif defined UNW_TARGET_ARM +#if defined __linux__ + printf (" @ %lx", (unsigned long) uc->uc_mcontext.arm_pc); +#elif defined __FreeBSD__ + printf (" @ %lx", (unsigned long) uc->uc_mcontext.__gregs[_REG_PC]); +#endif +#endif + printf ("\n"); + } + do_backtrace(); +} + +int +main (int argc, char **argv UNUSED) +{ + struct sigaction act; + stack_t stk; + + verbose = (argc > 1); + + if (verbose) + printf ("Normal backtrace:\n"); + + bar (1); + + memset (&act, 0, sizeof (act)); + act.sa_handler = (void (*)(int)) sighandler; + act.sa_flags = SA_SIGINFO; + if (sigaction (SIGTERM, &act, NULL) < 0) + panic ("sigaction: %s\n", strerror (errno)); + + if (verbose) + printf ("\nBacktrace across signal handler:\n"); + kill (getpid (), SIGTERM); + + if (verbose) + printf ("\nBacktrace across signal handler on alternate stack:\n"); + stk.ss_sp = malloc (SIG_STACK_SIZE); + if (!stk.ss_sp) + panic ("failed to allocate %u bytes\n", SIG_STACK_SIZE); + stk.ss_size = SIG_STACK_SIZE; + stk.ss_flags = 0; + if (sigaltstack (&stk, NULL) < 0) + panic ("sigaltstack: %s\n", strerror (errno)); + + memset (&act, 0, sizeof (act)); + act.sa_handler = (void (*)(int)) sighandler; + act.sa_flags = SA_ONSTACK | SA_SIGINFO; + if (sigaction (SIGTERM, &act, NULL) < 0) + panic ("sigaction: %s\n", strerror (errno)); + kill (getpid (), SIGTERM); + + if (num_errors > 0) + { + fprintf (stderr, "FAILURE: detected %d errors\n", num_errors); + exit (-1); + } + + if (verbose) + printf ("SUCCESS.\n"); + + signal (SIGTERM, SIG_DFL); + stk.ss_flags = SS_DISABLE; + sigaltstack (&stk, NULL); + free (stk.ss_sp); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c b/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c new file mode 100644 index 00000000000000..209f87131248da --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c @@ -0,0 +1,68 @@ +#include +#include +#include + +#include + +static int verbose; +static int nerrors; + +#define panic(args...) \ + do { printf (args); ++nerrors; } while (0) + +// Assembly routine which sets up the stack for the test then calls another one +// which clobbers the stack, and which in turn calls recover_register below +extern int64_t DW_CFA_expression_testcase(int64_t regnum, int64_t height); + +// recover_register is called by the assembly routines. It returns the value of +// a register at a specified height from the inner-most frame. The return value +// is propagated back through the assembly routines to the testcase. +extern int64_t recover_register(int64_t regnum, int64_t height) +{ + // Initialize cursor to current frame + int rc, i; + unw_cursor_t cursor; + unw_context_t context; + unw_getcontext(&context); + unw_init_local(&cursor, &context); + // Unwind frames until required height from inner-most frame (i.e. this one) + for (i = 0; i < height; ++i) + { + rc = unw_step(&cursor); + if (rc < 0) + panic("%s: unw_step failed on step %d with return code %d", __FUNCTION__, i, rc); + else if (rc == 0) + panic("%s: unw_step failed to reach the end of the stack", __FUNCTION__); + unw_word_t pc; + rc = unw_get_reg(&cursor, UNW_REG_IP, &pc); + if (rc < 0 || pc == 0) + panic("%s: unw_get_reg failed to locate the program counter", __FUNCTION__); + } + // We're now at the required height, extract register + uint64_t value; + if ((rc = unw_get_reg(&cursor, (unw_regnum_t) regnum, &value)) != 0) + panic("%s: unw_get_reg failed to retrieve register %lu", __FUNCTION__, regnum); + return value; +} + +int +main (int argc, char **argv) +{ + if (argc > 1) + verbose = 1; + + if (DW_CFA_expression_testcase(12, 1) != 0) + panic("r12 should be clobbered at height 1 (DW_CFA_expression_inner)"); + if (DW_CFA_expression_testcase(12, 2) != 111222333) + panic("r12 should be restored at height 2 (DW_CFA_expression_testcase)"); + + if (nerrors > 0) + { + fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); + exit (-1); + } + + if (verbose) + printf ("SUCCESS.\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-nat.c b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-nat.c new file mode 100644 index 00000000000000..15ef0caccc0dab --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-nat.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gia64-test-nat.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-rbs.c b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-rbs.c new file mode 100644 index 00000000000000..b838ebe42f7a1a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-rbs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gia64-test-rbs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-readonly.c b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-readonly.c new file mode 100644 index 00000000000000..cd23e92613e90a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-readonly.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gia64-test-readonly.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-stack.c b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-stack.c new file mode 100644 index 00000000000000..3647629c90bd40 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Lia64-test-stack.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gia64-test-stack.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lperf-simple.c b/src/coreclr/src/pal/src/libunwind/tests/Lperf-simple.c new file mode 100644 index 00000000000000..cdf38c207a0d5f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Lperf-simple.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gperf-simple.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lperf-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Lperf-trace.c new file mode 100644 index 00000000000000..1c3cf21c2137da --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Lperf-trace.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gperf-trace.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lrs-race.c b/src/coreclr/src/pal/src/libunwind/tests/Lrs-race.c new file mode 100644 index 00000000000000..6fe4972020d022 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Lrs-race.c @@ -0,0 +1,1514 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by Paul Pluzhnikov + +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. */ + +/* Verify that register state caches work under all caching policies + in a multi-threaded environment with a large number IPs */ + +#define UNW_LOCAL_ONLY +#include +#include "compiler.h" + +#include +#include +#include + +/* ITERS=1000, NTHREAD=10 caught some bugs in the past */ +#ifndef ITERS +#define ITERS 100 +#endif + +#ifndef NTHREAD +#define NTHREAD 2 +#endif + +int verbose; + +void +foo_0 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_1 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_2 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_3 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_4 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_5 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_6 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_7 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_8 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_9 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_10 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_11 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_12 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_13 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_14 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_15 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_16 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_17 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_18 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_19 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_20 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_21 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_22 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_23 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_24 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_25 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_26 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_27 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_28 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_29 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_30 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_31 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_32 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_33 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_34 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_35 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_36 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_37 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_38 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_39 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_40 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_41 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_42 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_43 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_44 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_45 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_46 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_47 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_48 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_49 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_50 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_51 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_52 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_53 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_54 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_55 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_56 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_57 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_58 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_59 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_60 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_61 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_62 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_63 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_64 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_65 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_66 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_67 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_68 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_69 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_70 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_71 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_72 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_73 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_74 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_75 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_76 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_77 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_78 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_79 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_80 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_81 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_82 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_83 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_84 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_85 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_86 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_87 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_88 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_89 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_90 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_91 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_92 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_93 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_94 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_95 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_96 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_97 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_98 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_99 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_100 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_101 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_102 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_103 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_104 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_105 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_106 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_107 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_108 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_109 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_110 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_111 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_112 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_113 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_114 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_115 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_116 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_117 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_118 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_119 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_120 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_121 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_122 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_123 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_124 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_125 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_126 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_127 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void +foo_128 (void) +{ + void *buf[20]; + int n; + + if ((n = unw_backtrace (buf, 20)) < 3) + abort (); +} + +void * +bar(void *p UNUSED) +{ + int i; + for (i = 0; i < ITERS; ++i) { + foo_0 (); + foo_1 (); + foo_2 (); + foo_3 (); + foo_4 (); + foo_5 (); + foo_6 (); + foo_7 (); + foo_8 (); + foo_9 (); + foo_10 (); + foo_11 (); + foo_12 (); + foo_13 (); + foo_14 (); + foo_15 (); + foo_16 (); + foo_17 (); + foo_18 (); + foo_19 (); + foo_20 (); + foo_21 (); + foo_22 (); + foo_23 (); + foo_24 (); + foo_25 (); + foo_26 (); + foo_27 (); + foo_28 (); + foo_29 (); + foo_30 (); + foo_31 (); + foo_32 (); + foo_33 (); + foo_34 (); + foo_35 (); + foo_36 (); + foo_37 (); + foo_38 (); + foo_39 (); + foo_40 (); + foo_41 (); + foo_42 (); + foo_43 (); + foo_44 (); + foo_45 (); + foo_46 (); + foo_47 (); + foo_48 (); + foo_49 (); + foo_50 (); + foo_51 (); + foo_52 (); + foo_53 (); + foo_54 (); + foo_55 (); + foo_56 (); + foo_57 (); + foo_58 (); + foo_59 (); + foo_60 (); + foo_61 (); + foo_62 (); + foo_63 (); + foo_64 (); + foo_65 (); + foo_66 (); + foo_67 (); + foo_68 (); + foo_69 (); + foo_70 (); + foo_71 (); + foo_72 (); + foo_73 (); + foo_74 (); + foo_75 (); + foo_76 (); + foo_77 (); + foo_78 (); + foo_79 (); + foo_80 (); + foo_81 (); + foo_82 (); + foo_83 (); + foo_84 (); + foo_85 (); + foo_86 (); + foo_87 (); + foo_88 (); + foo_89 (); + foo_90 (); + foo_91 (); + foo_92 (); + foo_93 (); + foo_94 (); + foo_95 (); + foo_96 (); + foo_97 (); + foo_98 (); + foo_99 (); + foo_100 (); + foo_101 (); + foo_102 (); + foo_103 (); + foo_104 (); + foo_105 (); + foo_106 (); + foo_107 (); + foo_108 (); + foo_109 (); + foo_110 (); + foo_111 (); + foo_112 (); + foo_113 (); + foo_114 (); + foo_115 (); + foo_116 (); + foo_117 (); + foo_118 (); + foo_119 (); + foo_120 (); + foo_121 (); + foo_122 (); + foo_123 (); + foo_124 (); + foo_125 (); + foo_126 (); + foo_127 (); + foo_128 (); + } + return NULL; +} + +int doit (void) +{ + pthread_t tid[NTHREAD]; + int i; + + for (i = 0; i < NTHREAD; ++i) + if (pthread_create (&tid[i], NULL, bar, NULL)) + return 1; + + for (i = 0; i < NTHREAD; ++i) + if (pthread_join (tid[i], NULL)) + return 1; + + return 0; +} + +int +main (int argc, char **argv UNUSED) +{ + if (argc > 1) + verbose = 1; + + if (verbose) + printf ("Caching: none\n"); + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); + doit (); + + if (verbose) + printf ("Caching: global\n"); + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); + doit (); + + if (verbose) + printf ("Caching: per-thread\n"); + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); + doit (); + + if (verbose) + printf ("SUCCESS\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-bt.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-bt.c new file mode 100644 index 00000000000000..3489bf0b51e163 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-bt.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gtest-bt.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-concurrent.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-concurrent.c new file mode 100644 index 00000000000000..9462607ec8fb6c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-concurrent.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gtest-concurrent.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-cxx-exceptions.cxx b/src/coreclr/src/pal/src/libunwind/tests/Ltest-cxx-exceptions.cxx new file mode 100644 index 00000000000000..24bcd13e3dc219 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-cxx-exceptions.cxx @@ -0,0 +1,80 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010 stefan.demharter@gmx.net + Copyright (C) 2010 arun.sharma@google.com + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include +#include "compiler.h" + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +static int verbose; + +struct Test +{ + public: // --- ctor/dtor --- + Test() { ++counter_; } + ~Test() { -- counter_; } + Test(const Test&) { ++counter_; } + + public: // --- static members --- + static int counter_; +}; + +int Test::counter_ = 0; + +// Called by foo +extern "C" void bar() +{ + Test t; + try { + Test t; + throw 5; + } catch (...) { + Test t; + if (verbose) + printf("Throwing an int\n"); + throw 6; + } +} + +int main(int argc, char **argv UNUSED) +{ + if (argc > 1) + verbose = 1; + try { + Test t; + bar(); + } catch (int) { + // Dtor of all Test-object has to be called. + if (Test::counter_ != 0) + panic("Counter non-zero\n"); + return Test::counter_; + } catch (...) { + // An int was thrown - we should not get here. + panic("Int was thrown why are we here?\n"); + } + exit(0); +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-dyn1.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-dyn1.c new file mode 100644 index 00000000000000..c2cab6b9a06a21 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-dyn1.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gtest-dyn1.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-exc.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-exc.c new file mode 100644 index 00000000000000..36a234ca82cb25 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-exc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gtest-exc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal-lib.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal-lib.c new file mode 100644 index 00000000000000..7474f71f49db85 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal-lib.c @@ -0,0 +1,6 @@ +#include + +/* To prevent inlining and optimizing away */ +int foo(volatile int* f) { + return *f; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal.c new file mode 100644 index 00000000000000..4bde218f3bb2cf --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-init-local-signal.c @@ -0,0 +1,60 @@ +#include "libunwind.h" +#include +#include +#include + +#include + +#include +#include +#include + +int stepper(unw_cursor_t* c) { + int steps = 0; + int ret = 1; + while (ret) { + + ret = unw_step(c); + if (!ret) { + break; + } + steps++; + } + return steps; +} + +/* Verify that we can step from both ucontext, and from getcontext() + * roughly the same. This tests that the IP from ucontext is used + * correctly (see impl of unw_init_local2) */ +void handler(int num, siginfo_t* info, void* ucontext) { + unw_cursor_t c; + unw_context_t context; + unw_getcontext(&context); + int ret = unw_init_local2(&c, ucontext, UNW_INIT_SIGNAL_FRAME); + assert(!ret); + int ucontext_steps = stepper(&c); + + ret = unw_init_local(&c, &context); + (void)ret; + assert(!ret); + int getcontext_steps = stepper(&c); + if (ucontext_steps == getcontext_steps - 2) { + exit(0); + } + printf("unw_getcontext steps was %i, ucontext steps was %i, should be %i\n", + getcontext_steps, ucontext_steps, getcontext_steps - 2); + exit(-1); +} + +int foo(volatile int* f); + +int main(){ + struct sigaction a; + memset(&a, 0, sizeof(struct sigaction)); + a.sa_sigaction = &handler; + a.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &a, NULL); + + foo(NULL); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-init.cxx b/src/coreclr/src/pal/src/libunwind/tests/Ltest-init.cxx new file mode 100644 index 00000000000000..58a6ea42798ffa --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-init.cxx @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gtest-init.cxx" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c new file mode 100644 index 00000000000000..e5127b90628fc3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c @@ -0,0 +1,145 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Copyright (c) 2003 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. */ + +#include "compiler.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +void * stack_start; + +#define PAGE_SIZE 4096 + +void do_backtrace (void) +{ + void* buffer[1024]; + int size = 1024; + mprotect((void*)((uintptr_t)stack_start & ~(PAGE_SIZE - 1)), + PAGE_SIZE, PROT_NONE); + + unw_cursor_t cursor; + unw_word_t ip, sp; + unw_context_t uc; + int ret; + int steps = 0; + + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + panic ("unw_init_local failed!\n"); + + do + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + unw_get_reg (&cursor, UNW_REG_SP, &sp); + + ret = unw_step (&cursor); + if (ret < 0) + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + } + steps ++; + } + while (ret > 0); + + if (steps < 5) + { + exit(-1); + } + + mprotect((void*)((uintptr_t)stack_start & ~(PAGE_SIZE - 1)), + PAGE_SIZE, PROT_READ|PROT_WRITE); +} + +void consume_and_run (int depth) +{ + unw_cursor_t cursor; + unw_context_t uc; + char string[1024]; + + sprintf (string, "hello %p %p\n", &cursor, &uc); + if (depth == 0) { + do_backtrace(); + } else { + consume_and_run(depth - 1); + } +} + +int +main (int argc, char **argv UNUSED) +{ + int start; + unw_context_t uc; + unw_cursor_t cursor; + + stack_start = &start; + + // Initialize pipe mem validate check, opens file descriptors + unw_getcontext(&uc); + if (unw_init_local (&cursor, &uc) < 0) + panic ("unw_init_local failed!\n"); + + int i; + for (i = 3; i < 10; i++) + { + + pid_t childpid = fork(); + if (!childpid) + { + /* Close fds and make sure we still work */ + int ret = close(i); + } + + int status; + if (childpid) + { + wait(&status); + if (WIFEXITED(status)) + return WEXITSTATUS(status); + else + return -1; + } + else + { + consume_and_run (10); + + return 0; + } + } + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-nocalloc.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-nocalloc.c new file mode 100644 index 00000000000000..f5c31b2a3ee259 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-nocalloc.c @@ -0,0 +1,137 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2011 Google, Inc + Contributed by Paul Pluzhnikov + +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_LOCAL_ONLY +#include + +#include +#include +#include +#include +#include + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +int num_mallocs; +int num_callocs; +int in_unwind; + +void * +calloc(size_t n, size_t s) +{ + static void * (*func)(size_t, size_t); + +#ifdef __GLIBC__ + /* In glibc, dlsym() calls calloc. Calling dlsym(RTLD_NEXT, "calloc") here + causes infinite recursion. Instead, we simply use it by its other + name. */ + extern void *__libc_calloc(size_t, size_t); + if (!func) + func = &__libc_calloc; +#else + if(!func) + func = dlsym(RTLD_NEXT, "calloc"); +#endif + + if (in_unwind) { + num_callocs++; + return NULL; + } else { + return func(n, s); + } +} + +void * +malloc(size_t s) +{ + static void * (*func)(size_t); + + if(!func) + func = dlsym(RTLD_NEXT, "malloc"); + + if (in_unwind) { + num_mallocs++; + return NULL; + } else { + return func(s); + } +} + +static void +do_backtrace (void) +{ + const int num_levels = 100; + void *pc[num_levels]; + + in_unwind = 1; + unw_backtrace(pc, num_levels); + in_unwind = 0; +} + +void +foo3 (void) +{ + do_backtrace (); +} + +void +foo2 (void) +{ + foo3 (); +} + +void +foo1 (void) +{ + foo2 (); +} + +int +main (void) +{ + int i, num_errors; + + /* Create (and leak) 100 TSDs, then call backtrace() + and check that it doesn't call malloc()/calloc(). */ + for (i = 0; i < 100; ++i) { + pthread_key_t key; + if (pthread_key_create (&key, NULL)) + panic ("FAILURE: unable to create key %d\n", i); + } + /* Call backtrace right after thread creation, + * where we are sure that we're not inside malloc */ + do_backtrace(); + num_mallocs = num_callocs = 0; + foo1 (); + num_errors = num_mallocs + num_callocs; + if (num_errors > 0) + { + fprintf (stderr, + "FAILURE: detected %d error%s (malloc: %d, calloc: %d)\n", + num_errors, num_errors > 1 ? "s" : "", + num_mallocs, num_callocs); + exit (-1); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-nomalloc.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-nomalloc.c new file mode 100644 index 00000000000000..74d6331286c187 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-nomalloc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gtest-nomalloc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig-rt.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig-rt.c new file mode 100644 index 00000000000000..01fd6dc7d78aab --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig-rt.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gtest-resume-sig-rt.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig.c new file mode 100644 index 00000000000000..0047b524aae7fd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-resume-sig.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gtest-resume-sig.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-trace.c new file mode 100644 index 00000000000000..fb0e9c10bdfc4a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-trace.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gtest-trace.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-varargs.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-varargs.c new file mode 100644 index 00000000000000..17ac600be626bc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-varargs.c @@ -0,0 +1,84 @@ +#define UNW_LOCAL_ONLY +#include +#include "compiler.h" + +#include +#include +#include +#include + +int ok; +int verbose; + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 3) +void a (int, ...) __attribute__((optimize(0))); +void b (void) __attribute__((optimize(0))); +void c (void) __attribute__((optimize(0))); +#endif + +void NOINLINE +b (void) +{ + void *v[20]; + int i, n; + + n = unw_backtrace(v, 20); + + /* Check that the number of addresses given by unw_backtrace() looks + * reasonable. If the compiler inlined everything, then this check will also + * break. */ + if (n >= 7) + ok = 1; + + if (verbose) + for (i = 0; i < n; ++i) + printf ("[%d] %p\n", i, v[i]); +} + +void NOINLINE +c (void) +{ + b (); +} + +void NOINLINE +a (int d, ...) +{ + switch (d) + { + case 5: + a (4, 2,4); + break; + case 4: + a (3, 1,3,5); + break; + case 3: + a (2, 11, 13, 17, 23); + break; + case 2: + a (1); + break; + case 1: + c (); + } +} + +int +main (int argc, char **argv UNUSED) +{ + if (argc > 1) + verbose = 1; + + a (5, 3, 4, 5, 6); + + if (!ok) + { + fprintf (stderr, "FAILURE: expected deeper backtrace.\n"); + return 1; + } + + if (verbose) + printf ("SUCCESS.\n"); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c b/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c new file mode 100644 index 00000000000000..07e916e60a6acb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gx64-test-dwarf-expressions.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Makefile.am b/src/coreclr/src/pal/src/libunwind/tests/Makefile.am new file mode 100644 index 00000000000000..61d1bf875a8c89 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Makefile.am @@ -0,0 +1,251 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +EXTRA_DIST = run-ia64-test-dyn1 run-ptrace-mapper run-ptrace-misc \ + run-check-namespace run-coredump-unwind \ + run-coredump-unwind-mdi check-namespace.sh.in \ + Gtest-nomalloc.c + +MAINTAINERCLEANFILES = Makefile.in + +noinst_PROGRAMS_arch = +noinst_PROGRAMS_cdep = +noinst_PROGRAMS_common = +check_PROGRAMS_arch = +check_PROGRAMS_cdep = +check_PROGRAMS_common = test-proc-info test-static-link \ + test-strerror +check_SCRIPTS_arch = +check_SCRIPTS_cdep = +check_SCRIPTS_common = run-check-namespace + +if REMOTE_ONLY + +perf: + +else + LIBUNWIND_local = $(top_builddir)/src/libunwind.la +if ARCH_IA64 + noinst_PROGRAMS_arch += ia64-test-dyn1 + check_SCRIPTS_arch += run-ia64-test-dyn1 + check_PROGRAMS_arch += Gia64-test-stack Lia64-test-stack \ + Gia64-test-nat Lia64-test-nat \ + Gia64-test-rbs Lia64-test-rbs \ + Gia64-test-readonly Lia64-test-readonly \ + ia64-test-setjmp ia64-test-sig +else #!ARCH_IA64 +if ARCH_PPC64 +if USE_ALTIVEC + noinst_PROGRAMS_arch += ppc64-test-altivec +endif #USE_ALTIVEC +else #!ARCH_PPC64 +if ARCH_X86_64 + check_PROGRAMS_arch += Gx64-test-dwarf-expressions Lx64-test-dwarf-expressions x64-unwind-badjmp-signal-frame +endif #ARCH X86_64 +endif #!ARCH_PPC64 +endif #!ARCH_IA64 + check_PROGRAMS_cdep += Gtest-bt Ltest-bt Gtest-exc Ltest-exc \ + Gtest-init Ltest-init \ + Gtest-concurrent Ltest-concurrent \ + Gtest-resume-sig Ltest-resume-sig \ + Gtest-resume-sig-rt Ltest-resume-sig-rt \ + Gtest-trace Ltest-trace \ + Ltest-init-local-signal \ + Ltest-mem-validate \ + test-async-sig test-flush-cache test-init-remote \ + test-mem test-reg-state Ltest-varargs \ + Ltest-nomalloc Ltest-nocalloc Lrs-race + noinst_PROGRAMS_cdep += forker Gperf-simple Lperf-simple \ + Gperf-trace Lperf-trace + +if BUILD_PTRACE + check_SCRIPTS_cdep += run-ptrace-mapper run-ptrace-misc + check_PROGRAMS_cdep += test-ptrace + noinst_PROGRAMS_cdep += mapper test-ptrace-misc +endif + +if BUILD_SETJMP + check_PROGRAMS_cdep += test-setjmp +endif + +if SUPPORT_CXX_EXCEPTIONS + check_PROGRAMS_cdep += Ltest-cxx-exceptions +endif + +if OS_LINUX +if BUILD_COREDUMP + check_SCRIPTS_cdep += run-coredump-unwind + noinst_PROGRAMS_cdep += crasher test-coredump-unwind + +if HAVE_LZMA + check_SCRIPTS_cdep += run-coredump-unwind-mdi +endif # HAVE_LZMA +endif # BUILD_COREDUMP +endif # OS_LINUX + +perf: perf-startup Gperf-simple Lperf-simple Lperf-trace + @echo "########## Basic performance of generic libunwind:" + @./Gperf-simple + @echo "########## Basic performance of local-only libunwind:" + @./Lperf-simple + @echo "########## Performance of fast unwind:" + @./Lperf-trace + @echo "########## Startup overhead:" + @$(srcdir)/perf-startup @arch@ + +endif + +check_PROGRAMS = $(check_PROGRAMS_common) $(check_PROGRAMS_cdep) \ + $(check_PROGRAMS_arch) +check_SCRIPTS = $(check_SCRIPTS_common) $(check_SCRIPTS_cdep) \ + $(check_SCRIPTS_arch) + + +TESTS = $(check_PROGRAMS) $(check_SCRIPTS) +XFAIL_TESTS = + +if ARCH_IA64 + check_PROGRAMS_cdep += Gtest-dyn1 Ltest-dyn1 +endif + +# Use if arch defines but does not support PTRACE_SINGLESTEP +# ptrace request used in the tests. +XFAIL_TESTS_PTRACE_SINGLESTEP = run-ptrace-mapper run-ptrace-misc + +if ARCH_MIPS +XFAIL_TESTS += $(XFAIL_TESTS_PTRACE_SINGLESTEP) +endif + +if ARCH_ARM +# ARM Linux kernel >=2.6.39 removed PTRACE_SINGLESTEP emulation +XFAIL_TESTS += $(XFAIL_TESTS_PTRACE_SINGLESTEP) +endif + +# This is meant for multilib binaries, -m32. +# ptrace gives EBADREG when testing, +# but generally everything else works. +if NO_PTRACE_TEST + XFAIL_TESTS += run-ptrace-mapper test-ptrace Ltest-init-local-signal +endif + +noinst_PROGRAMS = $(noinst_PROGRAMS_common) $(noinst_PROGRAMS_cdep) \ + $(noinst_PROGRAMS_arch) + +Lia64_test_readonly_SOURCES = Lia64-test-readonly.c ia64-test-readonly-asm.S +Gia64_test_readonly_SOURCES = Gia64-test-readonly.c ia64-test-readonly-asm.S +Lia64_test_stack_SOURCES = Lia64-test-stack.c ia64-test-stack-asm.S \ + ia64-test-stack.h +Gia64_test_stack_SOURCES = Gia64-test-stack.c ia64-test-stack-asm.S \ + ia64-test-stack.h +Lia64_test_rbs_SOURCES = Lia64-test-rbs.c ia64-test-rbs-asm.S ia64-test-rbs.h +Gia64_test_rbs_SOURCES = Gia64-test-rbs.c ia64-test-rbs-asm.S ia64-test-rbs.h +Lia64_test_nat_SOURCES = Lia64-test-nat.c ia64-test-nat-asm.S +Gia64_test_nat_SOURCES = Gia64-test-nat.c ia64-test-nat-asm.S +ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S \ + flush-cache.h +ppc64_test_altivec_SOURCES = ppc64-test-altivec.c ppc64-test-altivec-utils.c + + +Gx64_test_dwarf_expressions_SOURCES = Gx64-test-dwarf-expressions.c \ + x64-test-dwarf-expressions.S +Lx64_test_dwarf_expressions_SOURCES = Lx64-test-dwarf-expressions.c \ + x64-test-dwarf-expressions.S + + +Gtest_init_SOURCES = Gtest-init.cxx +Ltest_init_SOURCES = Ltest-init.cxx +Ltest_cxx_exceptions_SOURCES = Ltest-cxx-exceptions.cxx + +Ltest_init_local_signal_SOURCES = Ltest-init-local-signal.c Ltest-init-local-signal-lib.c + +x64_unwind_badjmp_signal_frame_SOURCES = x64-unwind-badjmp-signal-frame.c +Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S flush-cache.h +Ltest_dyn1_SOURCES = Ltest-dyn1.c flush-cache.S flush-cache.h +test_static_link_SOURCES = test-static-link-loc.c test-static-link-gen.c +test_static_link_LDFLAGS = -static +forker_LDFLAGS = -static +Gtest_bt_SOURCES = Gtest-bt.c ident.c +Ltest_bt_SOURCES = Ltest-bt.c ident.c +test_ptrace_misc_SOURCES = test-ptrace-misc.c ident.c +Ltest_nomalloc_SOURCES = Ltest-nomalloc.c +Ltest_nocalloc_SOURCES = Ltest-nocalloc.c +Gtest_trace_SOURCES = Gtest-trace.c ident.c +Ltest_trace_SOURCES = Ltest-trace.c ident.c +Ltest_mem_validate_SOURCES = Ltest-mem-validate.c + +LIBUNWIND = $(top_builddir)/src/libunwind-$(arch).la +LIBUNWIND_ptrace = $(top_builddir)/src/libunwind-ptrace.la +LIBUNWIND_coredump = $(top_builddir)/src/libunwind-coredump.la + +if USE_ELF32 +LIBUNWIND_ELF = $(top_builddir)/src/libunwind-elf32.la +endif +if USE_ELF64 +LIBUNWIND_ELF = $(top_builddir)/src/libunwind-elf64.la +endif +if USE_ELFXX +LIBUNWIND_ELF = $(top_builddir)/src/libunwind-elfxx.la +endif + +LIBUNWIND_setjmp = $(top_builddir)/src/libunwind-setjmp.la \ + $(LIBUNWIND_ELF) $(LIBUNWIND) + +test_async_sig_LDADD = $(LIBUNWIND_local) -lpthread +test_flush_cache_LDADD = $(LIBUNWIND_local) +test_init_remote_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +test_mem_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +test_reg_state_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +test_ptrace_LDADD = $(LIBUNWIND_ptrace) $(LIBUNWIND) +test_proc_info_LDADD = $(LIBUNWIND) +test_static_link_LDADD = $(LIBUNWIND) +test_strerror_LDADD = $(LIBUNWIND) +Lrs_race_LDADD = $(LIBUNWIND_local) -lpthread +Ltest_varargs_LDADD = $(LIBUNWIND_local) +Ltest_init_local_signal_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) + +Gtest_bt_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Gtest_concurrent_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -lpthread +x64_unwind_badjmp_signal_frame_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Gtest_dyn1_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Gtest_exc_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Gtest_init_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) @BACKTRACELIB@ +Gtest_resume_sig_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Gtest_resume_sig_rt_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Gperf_simple_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Gtest_trace_LDADD=$(LIBUNWIND) $(LIBUNWIND_local) +Gperf_trace_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) + +Ltest_bt_LDADD = $(LIBUNWIND_local) +Ltest_concurrent_LDADD = $(LIBUNWIND_local) -lpthread +Ltest_dyn1_LDADD = $(LIBUNWIND_local) +Ltest_exc_LDADD = $(LIBUNWIND_local) +Ltest_init_LDADD = $(LIBUNWIND_local) +Ltest_nomalloc_LDADD = $(LIBUNWIND_local) @DLLIB@ +Ltest_nocalloc_LDADD = $(LIBUNWIND_local) @DLLIB@ -lpthread +Ltest_resume_sig_LDADD = $(LIBUNWIND_local) +Ltest_resume_sig_rt_LDADD = $(LIBUNWIND_local) +Lperf_simple_LDADD = $(LIBUNWIND_local) +Ltest_trace_LDADD = $(LIBUNWIND_local) +Lperf_trace_LDADD = $(LIBUNWIND_local) +Ltest_mem_validate_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) + +test_setjmp_LDADD = $(LIBUNWIND_setjmp) +ia64_test_setjmp_LDADD = $(LIBUNWIND_setjmp) + +if BUILD_COREDUMP +test_coredump_unwind_LDADD = $(LIBUNWIND_coredump) $(LIBUNWIND) @BACKTRACELIB@ +endif + +Gia64_test_nat_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Gia64_test_stack_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Gia64_test_rbs_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Gia64_test_readonly_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Lia64_test_nat_LDADD = $(LIBUNWIND_local) +Lia64_test_stack_LDADD = $(LIBUNWIND_local) +Lia64_test_rbs_LDADD = $(LIBUNWIND_local) +Lia64_test_readonly_LDADD = $(LIBUNWIND_local) +ia64_test_dyn1_LDADD = $(LIBUNWIND) +ia64_test_sig_LDADD = $(LIBUNWIND) +ppc64_test_altivec_LDADD = $(LIBUNWIND) + +Gx64_test_dwarf_expressions_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Lx64_test_dwarf_expressions_LDADD = $(LIBUNWIND_local) diff --git a/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in b/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in new file mode 100644 index 00000000000000..f43bca263bc35e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in @@ -0,0 +1,387 @@ +#!/bin/sh +verbose=false +if [ "$1" = "-v" ]; then + verbose=true + shift +fi + +build_plat=@build_arch@ +plat=@arch@ +os=@target_os@ +num_errors=0 + +LIBUNWIND=../src/.libs/libunwind.so +LIBUNWIND_GENERIC=../src/.libs/libunwind-${plat}.so + +fetch_symtab () { + filename=$1 + + if [ ! -r $filename ]; then + return + fi + + if $verbose; then + echo "Checking $filename..." + fi + + # + # Unfortunately, "nm --defined" is a GNU-extension. For portability, + # build the list of defined symbols by hand. + # + symtab=`nm -g $filename` + saved_IFS="$IFS" + IFS="" + undef=`nm -g -u $filename` + for line in $undef; do + symtab=`echo "$symtab" | grep -v "^${line}"\$` + done; + IFS="$saved_IFS" +} + +ignore () { + sym=$1 + symtab=`echo "$symtab" | grep -v " ${sym}\$"` +} + +match () { + sym=$1 + if `echo "$symtab" | grep -q " ${sym}\$"`; then + symtab=`echo "$symtab" | grep -v " ${sym}\$"` + else + echo " ERROR: Symbol \"$sym\" missing." + num_errors=`expr $num_errors + 1` + fi +} + +# +# Filter out miscellaneous symbols that get defined by the +# linker for each shared object. +# +filter_misc () { + ignore _DYNAMIC + ignore _GLOBAL_OFFSET_TABLE_ + ignore __bss_start + ignore _edata + ignore _end + ignore _Uelf32_get_proc_name + ignore _Uelf32_valid_object + ignore _Uelf64_get_proc_name + ignore _Uelf64_valid_object + ignore _U.*debug_level + ignore ICRT.INTERNAL # ICC 8.x defines this + + # Ignore symbols generated by the ARM Linux default linker script. + # For details see the binutils sources (src/ld/emulparams/armelf_linux.sh). + if [ ${plat} = "arm" ]; then + ignore __bss_start__ + ignore __bss_end__ + ignore __end__ + ignore _bss_end__ + fi + + if [ ${plat} = "mips" ]; then + ignore _fbss + ignore _fdata + ignore _ftext + ignore _gp + fi + + if [ ${os} == "solaris2.11" ]; then + ignore _PROCEDURE_LINKAGE_TABLE_ + ignore _etext + fi +} + +check_local_unw_abi () { + match _UL${plat}_apply_reg_state + match _UL${plat}_reg_states_iterate + match _UL${plat}_create_addr_space + match _UL${plat}_destroy_addr_space + match _UL${plat}_get_fpreg + match _UL${plat}_get_proc_info + match _UL${plat}_get_proc_info_by_ip + match _UL${plat}_get_proc_name + match _UL${plat}_get_reg + match _UL${plat}_get_save_loc + match _UL${plat}_init_local + match _UL${plat}_init_local2 + match _UL${plat}_init_remote + match _UL${plat}_is_signal_frame + match _UL${plat}_local_addr_space + match _UL${plat}_resume + match _UL${plat}_set_caching_policy + match _UL${plat}_set_cache_size + match _UL${plat}_set_reg + match _UL${plat}_set_fpreg + match _UL${plat}_step + + match _U${plat}_flush_cache + match _U${plat}_get_accessors + match _U${plat}_getcontext + match _U${plat}_regname + match _U${plat}_strerror + + match _U_dyn_cancel + match _U_dyn_info_list_addr + match _U_dyn_register + + match unw_backtrace + @CONFIG_WEAK_BACKTRACE_TRUE@match backtrace + + case ${plat} in + arm) + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_is_fpreg + match _UL${plat}_search_unwind_table + match _UL${plat}_dwarf_search_unwind_table + match _UL${plat}_dwarf_find_unwind_table + ;; + hppa) + match _UL${plat}_dwarf_search_unwind_table + match _UL${plat}_dwarf_find_unwind_table + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_setcontext + ;; + ia64) + match _UL${plat}_search_unwind_table + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + ;; + x86) + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_is_fpreg + match _UL${plat}_dwarf_search_unwind_table + match _UL${plat}_dwarf_find_unwind_table + ;; + x86_64) + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_is_fpreg + match _UL${plat}_dwarf_search_unwind_table + match _UL${plat}_dwarf_find_unwind_table + match _U${plat}_setcontext + ;; + ppc*) + match _U${plat}_get_func_addr + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_is_fpreg + match _UL${plat}_dwarf_search_unwind_table + match _UL${plat}_dwarf_find_unwind_table + ;; + tilegx) + match _U${plat}_is_fpreg + match _UL${plat}_dwarf_search_unwind_table + match _UL${plat}_dwarf_find_unwind_table + match _UL${plat}_local_addr_space_init + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match ${plat}_lock + ;; + s390x) + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_is_fpreg + match _UL${plat}_dwarf_search_unwind_table + match _UL${plat}_dwarf_find_unwind_table + match _U${plat}_setcontext + ;; + + *) + match _U${plat}_is_fpreg + match _UL${plat}_dwarf_search_unwind_table + match _UL${plat}_dwarf_find_unwind_table + ;; + esac + + if [ x@enable_debug_frame@ = xyes ]; then + match _UL${plat}_dwarf_find_debug_frame + fi + +} + +check_generic_unw_abi () { + match _U${plat}_apply_reg_state + match _U${plat}_reg_states_iterate + match _U${plat}_create_addr_space + match _U${plat}_destroy_addr_space + match _U${plat}_flush_cache + match _U${plat}_get_accessors + match _U${plat}_get_fpreg + match _U${plat}_get_proc_info + match _U${plat}_get_proc_info_by_ip + match _U${plat}_get_proc_name + match _U${plat}_get_reg + match _U${plat}_get_save_loc + match _U${plat}_init_local + match _U${plat}_init_local2 + match _U${plat}_init_remote + match _U${plat}_is_signal_frame + match _U${plat}_local_addr_space + match _U${plat}_regname + match _U${plat}_resume + match _U${plat}_set_caching_policy + match _U${plat}_set_cache_size + match _U${plat}_set_fpreg + match _U${plat}_set_reg + match _U${plat}_step + match _U${plat}_strerror + + case ${plat} in + arm) + match _U${plat}_is_fpreg + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_search_unwind_table + match _U${plat}_dwarf_search_unwind_table + match _U${plat}_dwarf_find_unwind_table + ;; + hppa) + match _U${plat}_dwarf_search_unwind_table + match _U${plat}_dwarf_find_unwind_table + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + ;; + ia64) + match _U${plat}_search_unwind_table + match _U${plat}_find_dyn_list + if [ $plat = $build_plat ]; then + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + case $os in + linux*) + match _U${plat}_get_kernel_table + ;; + esac + fi + ;; + x86) + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_is_fpreg + match _U${plat}_dwarf_search_unwind_table + match _U${plat}_dwarf_find_unwind_table + ;; + x86_64) + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_is_fpreg + match _U${plat}_dwarf_search_unwind_table + match _U${plat}_dwarf_find_unwind_table + ;; + ppc*) + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_get_func_addr + match _U${plat}_is_fpreg + match _U${plat}_dwarf_search_unwind_table + match _U${plat}_dwarf_find_unwind_table + ;; + tilegx) + match _U${plat}_dwarf_search_unwind_table + match _U${plat}_dwarf_find_unwind_table + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_is_fpreg + match _U${plat}_local_addr_space_init + match ${plat}_lock + ;; + s390x) + match _U${plat}_is_fpreg + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_dwarf_search_unwind_table + match _U${plat}_dwarf_find_unwind_table + ;; + *) + match _U${plat}_is_fpreg + match _U${plat}_dwarf_search_unwind_table + match _U${plat}_dwarf_find_unwind_table + ;; + esac + + if [ x@enable_debug_frame@ = xyes ]; then + match _U${plat}_dwarf_find_debug_frame + fi +} + +check_cxx_abi () { + match _Unwind_Backtrace + match _Unwind_DeleteException + match _Unwind_FindEnclosingFunction + match _Unwind_ForcedUnwind + match _Unwind_GetBSP + match _Unwind_GetCFA + match _Unwind_GetDataRelBase + match _Unwind_GetGR + match _Unwind_GetIP + match _Unwind_GetIPInfo + match _Unwind_GetLanguageSpecificData + match _Unwind_GetRegionStart + match _Unwind_GetTextRelBase + match _Unwind_RaiseException + match _Unwind_Resume + match _Unwind_Resume_or_Rethrow + match _Unwind_SetGR + match _Unwind_SetIP + match __libunwind_Unwind_Backtrace + match __libunwind_Unwind_DeleteException + match __libunwind_Unwind_FindEnclosingFunction + match __libunwind_Unwind_ForcedUnwind + match __libunwind_Unwind_GetBSP + match __libunwind_Unwind_GetCFA + match __libunwind_Unwind_GetDataRelBase + match __libunwind_Unwind_GetGR + match __libunwind_Unwind_GetIP + match __libunwind_Unwind_GetIPInfo + match __libunwind_Unwind_GetLanguageSpecificData + match __libunwind_Unwind_GetRegionStart + match __libunwind_Unwind_GetTextRelBase + match __libunwind_Unwind_RaiseException + match __libunwind_Unwind_Resume + match __libunwind_Unwind_Resume_or_Rethrow + match __libunwind_Unwind_SetGR + match __libunwind_Unwind_SetIP + case $os in + linux*) + # needed only for Intel 8.0 bug-compatibility + match _ReadSLEB + match _ReadULEB + ;; + esac +} + +check_empty () { + if [ -n "$symtab" ]; then + printf " ERROR: Extraneous symbols:\n$symtab\n" + num_errors=`expr $num_errors + 1` + fi +} + +if [ $plat = $build_plat ]; then + fetch_symtab $LIBUNWIND + filter_misc + check_local_unw_abi + if [ x@enable_cxx_exceptions@ = xyes ]; then + check_cxx_abi + fi + check_empty +fi + +fetch_symtab $LIBUNWIND_GENERIC +filter_misc +check_generic_unw_abi +check_empty + +if [ $num_errors -gt 0 ]; then + echo "FAILURE: Detected $num_errors errors" + exit 1 +fi + +if $verbose; then + echo " SUCCESS: all checks passed" +fi +exit 0 diff --git a/src/coreclr/src/pal/src/libunwind/tests/crasher.c b/src/coreclr/src/pal/src/libunwind/tests/crasher.c new file mode 100644 index 00000000000000..bb99e339c26397 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/crasher.c @@ -0,0 +1,129 @@ +/* This program should crash and produce coredump */ + +#include "compiler.h" + +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#include +#include +#endif + +#if defined(__linux__) +void write_maps(char *fname) +{ + char buf[512], path[128]; + char exec; + uintmax_t addr; + FILE *maps = fopen("/proc/self/maps", "r"); + FILE *out = fopen(fname, "w"); + + if (!maps || !out) + exit(EXIT_FAILURE); + + while (fgets(buf, sizeof(buf), maps)) + { + if (sscanf(buf, "%jx-%*x %*c%*c%c%*c %*x %*s %*d /%126[^\n]", &addr, &exec, path+1) != 3) + continue; + + if (exec != 'x') + continue; + + path[0] = '/'; + fprintf(out, "0x%jx:%s ", addr, path); + } + fprintf(out, "\n"); + + fclose(out); + fclose(maps); +} +#elif defined(__FreeBSD__) +void +write_maps(char *fname) +{ + FILE *out; + char *buf, *bp, *eb; + struct kinfo_vmentry *kv; + int mib[4], error; + size_t len; + + out = fopen(fname, "w"); + if (out == NULL) + exit(EXIT_FAILURE); + + len = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_VMMAP; + mib[3] = getpid(); + error = sysctl(mib, 4, NULL, &len, NULL, 0); + if (error == -1) + exit(EXIT_FAILURE); + len = len * 4 / 3; + buf = malloc(len); + if (buf == NULL) + exit(EXIT_FAILURE); + error = sysctl(mib, 4, buf, &len, NULL, 0); + if (error == -1) + exit(EXIT_FAILURE); + + for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) { + kv = (struct kinfo_vmentry *)(uintptr_t)bp; + if (kv->kve_type == KVME_TYPE_VNODE && + (kv->kve_protection & KVME_PROT_EXEC) != 0) { + fprintf(out, "0x%jx:%s ", kv->kve_start, kv->kve_path); + } + } + + fprintf(out, "\n"); + fclose(out); + free(buf); +} +#else +#error Port me +#endif + +#ifdef __GNUC__ +#ifndef __clang__ +// Gcc >= 8 became too good at inlining aliase c into b when using -O2 or -O3, +// so force -O1 in all cases, otherwise a frame will be missing in the tests. +#pragma GCC optimize "-O1" +#endif +int c(int x) NOINLINE ALIAS(b); +#define compiler_barrier() __asm__ __volatile__ (""); +#else +int c(int x); +#define compiler_barrier() +#endif + +int NOINLINE a(void) +{ + *(volatile int *)32 = 1; + return 1; +} + +int NOINLINE b(int x) +{ + int r; + + compiler_barrier(); + + if (x) + r = a(); + else + r = c(1); + return r + 1; +} + +int +main (int argc, char **argv) +{ + if (argc > 1) + write_maps(argv[1]); + b(0); + return 0; +} + diff --git a/src/coreclr/src/pal/src/libunwind/tests/flush-cache.S b/src/coreclr/src/pal/src/libunwind/tests/flush-cache.S new file mode 100644 index 00000000000000..3ee47269e18264 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/flush-cache.S @@ -0,0 +1,104 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef HAVE__BUILTIN___CLEAR_CACHE + +#if defined(__ia64__) + + .global flush_cache + + .proc flush_cache +flush_cache: + .prologue + alloc r2=ar.pfs,2,0,0,0 + add r8=31,in1 // round up to 32 byte-boundary + ;; + shr.u r8=r8,5 // we flush 32 bytes per iteration + ;; + add r8=-1,r8 + .save ar.lc, r3 + mov r3=ar.lc // save ar.lc + ;; + .body + + mov ar.lc=r8 + ;; +.loop: fc in0 // issuable on M0 only + add in0=32,in0 + br.cloop.sptk.few .loop + ;; + sync.i + ;; + srlz.i + ;; + mov ar.lc=r3 // restore ar.lc + br.ret.sptk.many rp + .endp flush_cache + +#elif defined(__i386__) || defined (__x86_64__) + + .globl flush_cache +flush_cache: + ret + +#elif defined(__hppa__) + +# warning FIX ME!! + + .globl flush_cache +flush_cache: + .proc + .callinfo + bv %r0(%rp) + .procend +#elif defined(__powerpc64__) +# warning IMPLEMENT ME FOR PPC64!! + .globl flush_cache +flush_cache: + lwz 11, 0(1) ; + lwz 0, 4(11) ; + mtlr 0 ; + lwz 31, -4(11) ; + mr 1, 11 ; + blr +#elif defined(__powerpc__) +# warning IMPLEMENT ME FOR PPC32!! + .globl flush_cache +flush_cache: + lwz 11, 0(1) ; + lwz 0, 4(11) ; + mtlr 0 ; + lwz 31, -4(11) ; + mr 1, 11 ; + blr +#elif defined(__arm__) + .text + .globl flush_cache +flush_cache: + bx lr +#elif defined(__tilegx__) + .text + .globl flush_cache +flush_cache: + + andi r0, r0, -64 +1: { + flush r0 ; + addi r0, r0, 64 + } + { + bgtz r1, 1b ; + addi r1, r1, -64 + } + jrp lr +#else +# error Need flush_cache code for this architecture. +#endif + +#if defined ( __linux__) && !defined (__arm__) + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/flush-cache.h b/src/coreclr/src/pal/src/libunwind/tests/flush-cache.h new file mode 100644 index 00000000000000..8227d85b3f42b4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/flush-cache.h @@ -0,0 +1,38 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + +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 FLUSH_CACHE_H +#define FLUSH_CACHE_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE__BUILTIN___CLEAR_CACHE +#define flush_cache(ADDR, LEN) \ + __builtin___clear_cache((ADDR), (ADDR) + (LEN)) +#else +#include +extern void flush_cache (void *addr, size_t len); +#endif + +#endif /* FLUSH_CACHE_H */ diff --git a/src/coreclr/src/pal/src/libunwind/tests/forker.c b/src/coreclr/src/pal/src/libunwind/tests/forker.c new file mode 100644 index 00000000000000..b03f86a7f03805 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/forker.c @@ -0,0 +1,76 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include + +#include +#include +#include + +int +main (int argc, char **argv, char **envp) +{ + char *program, **child_argv; + struct timeval start, stop; + double secs; + int status, i; + long count; + pid_t pid; + + count = atol (argv[1]); + program = argv[2]; + + child_argv = alloca ((argc - 1) * sizeof (char *)); + for (i = 0; i < argc - 2; ++i) + child_argv[i] = argv[2 + i]; + child_argv[i] = NULL; + + gettimeofday (&start, NULL); + for (i = 0; i < count; ++i) + { + pid = fork (); + if (pid == 0) + { + execve (program, child_argv, envp); + _exit (-1); + } + else + { + waitpid (pid, &status, 0); + if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) + { + fprintf (stderr, "%s: child failed\n", argv[0]); + exit (-1); + } + } + } + gettimeofday (&stop, NULL); + + secs = ((stop.tv_sec + 1e-6 * stop.tv_usec) + - (start.tv_sec + 1e-6 * start.tv_usec)); + printf ("%lu nsec/execution\n", + (unsigned long) (1e9 * secs / (double) count)); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-dyn-asm.S b/src/coreclr/src/pal/src/libunwind/tests/ia64-dyn-asm.S new file mode 100644 index 00000000000000..79582e9e1bb9d8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ia64-dyn-asm.S @@ -0,0 +1,102 @@ + .globl func_add1, func_add1_end + .proc func_add1 +func_add1: +{.mib; add r8 = 1, r32 + nop.i 0 + br.ret.sptk.many rp +} +func_add1_end: + .endp func_add1 + + .globl func_add3, func_add3_end + .proc func_add3 +func_add3: +{.mmi; alloc loc0 = ar.pfs, 2, 1, 2, 0 + mov r2 = sp + add sp = -16, sp +} ;; +{.mii; ld8 r8 = [in1], 8 // load the function pointer + mov r3 = rp + mov rp = loc0 // trash rp +} ;; +{.mmi; ld8 r9 = [r8], 8 // load the entry-point + st8 [r2] = r3 + mov out0 = in0 +} ;; +{.mii; ld8 gp = [r8] // load the gp + mov b6 = r9 + mov out1 = in1 +} +{.mib; nop 0 + nop 0 + br.call.sptk rp = b6 +} +{.mmi; add r2 = 16, sp + ;; + ld8 r3 = [r2] // r3 = saved rp + mov ar.pfs = loc0 +} ;; +{.mii; nop 0 + mov rp = r3 + adds sp = 16, sp +} ;; +{.mib; st8 [sp] = in0 // trash rp save location + add r8 = 2, r8 + br.ret.sptk.many rp +} +func_add3_end: + .endp func_add3 + + .globl func_vframe, func_vframe_end + .proc func_vframe +func_vframe: +{.mii; alloc r16 = ar.pfs, 1, 2, 0, 0 // 0 + mov loc0 = rp + mov loc1 = sp +} ;; +{.mmi; sub sp = sp, in0 + st8 [loc1] = r16 + mov r2 = -99 // 0 +} ;; +{.mii; nop 0 + mov rp = r2 + mov ar.pfs = r0 +} +{.mib; mov r16 = r2 + tbit.nz p6, p0 = in0, 4 +(p6) br.cond.sptk.many .exit +} ;; +{.mmi; ld8 r16 = [loc1] + ;; + mov r3 = loc0 // 8 move saved rp to r3 + mov ar.pfs = r16 +} ;; +{.mmi; mov sp = loc1 // 10 + st8 [loc1] = r0 // trash saved pfs + mov loc0 = r2 +} ;; +{.mib; mov r8 = 10 + mov rp = r3 + br.ret.sptk.many rp +} +.exit: +{.mmi; ld8 r16 = [loc1] + ;; + sub sp = 32, sp + mov ar.pfs = r16 +} ;; +{.mmi; mov sp = loc1 + st8 [loc1] = r0 // trash saved pfs + mov rp = loc0 +} +{.mib; nop 0 + mov r8 = 4 + br.ret.sptk.many rp +} +func_vframe_end: + .endp func_vframe + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-dyn1.c b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-dyn1.c new file mode 100644 index 00000000000000..90127dd5b951cc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-dyn1.c @@ -0,0 +1,223 @@ +#include "flush-cache.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +int verbose; + +#ifdef __ia64__ +# define GET_ENTRY(fdesc) (((uintptr_t *) (fdesc))[0]) +# define GET_GP(fdesc) (((uintptr_t *) (fdesc))[0]) +# define EXTRA 16 +#else +# define GET_ENTRY(fdesc) ((uintptr_t ) (fdesc)) +# define GET_GP(fdesc) (0) +# define EXTRA 0 +#endif + +int +make_executable (void *addr, size_t len) +{ + if (mprotect ((void *) (((long) addr) & -getpagesize ()), len, + PROT_READ | PROT_WRITE | PROT_EXEC) < 0) + { + perror ("mprotect"); + return -1; + } + flush_cache (addr, len); + return 0; +} + +void * +create_func (unw_dyn_info_t *di, const char *name, long (*func) (), + void *end, unw_dyn_region_info_t *region) +{ + void *mem, *memend, *addr, *fptr; + unw_word_t gp = 0; + size_t len; + + len = (uintptr_t) end - GET_ENTRY (func) + EXTRA; + mem = malloc (len); + if (verbose) + printf ("%s: cloning %s at %p (%zu bytes)\n", + __FUNCTION__, name, mem, len); + memend = (char *) mem + len; + +#ifdef __ia64__ + addr = (void *) GET_ENTRY (func); + + /* build function descriptor: */ + ((long *) mem)[0] = (long) mem + 16; /* entry point */ + ((long *) mem)[1] = GET_GP (func); /* global-pointer */ + fptr = mem; + mem = (void *) ((long) mem + 16); +#else + fptr = mem; +#endif + + len = (char *) memend - (char *) mem; + memcpy (mem, addr, len); + + if (make_executable (mem, len) < 0) + return NULL; + + if (di) + { + memset (di, 0, sizeof (*di)); + di->start_ip = (unw_word_t) mem; + di->end_ip = (unw_word_t) memend; + di->gp = gp; + di->format = UNW_INFO_FORMAT_DYNAMIC; + di->u.pi.name_ptr = (unw_word_t) name; + di->u.pi.regions = region; + } + return fptr; +} + +int +main (int argc, char **argv) +{ + extern long func_add1 (long); + extern char func_add1_end[]; + extern long func_add3 (long, long (*[])()); + extern char func_add3_end[]; + extern long func_vframe (long); + extern char func_vframe_end[]; + unw_dyn_region_info_t *r_pro, *r_epi, *r, *rtmp; + unw_dyn_info_t di0, di1, di2, di3; + long (*add1) (long); + long (*add3_0) (long); + long (*add3_1) (long, void *[]); + long (*vframe) (long); + void *flist[2]; + long ret; + int i; + + signal (SIGUSR1, SIG_IGN); + signal (SIGUSR2, SIG_IGN); + + if (argc != 1) + verbose = 1; + + add1 = (long (*)(long)) + create_func (&di0, "func_add1", func_add1, func_add1_end, NULL); + + /* Describe the epilogue of func_add3: */ + i = 0; + r_epi = alloca (_U_dyn_region_info_size (5)); + r_epi->op_count = 5; + r_epi->next = NULL; + r_epi->insn_count = -9; + _U_dyn_op_pop_frames (&r_epi->op[i++], + _U_QP_TRUE, /* when=*/ 5, /* num_frames=*/ 1); + _U_dyn_op_stop (&r_epi->op[i++]); + assert ((unsigned) i <= r_epi->op_count); + + /* Describe the prologue of func_add3: */ + i = 0; + r_pro = alloca (_U_dyn_region_info_size (4)); + r_pro->op_count = 4; + r_pro->next = r_epi; + r_pro->insn_count = 8; + _U_dyn_op_save_reg (&r_pro->op[i++], _U_QP_TRUE, /* when=*/ 0, + /* reg=*/ UNW_IA64_AR_PFS, /* dst=*/ UNW_IA64_GR + 34); + _U_dyn_op_add (&r_pro->op[i++], _U_QP_TRUE, /* when=*/ 2, + /* reg= */ UNW_IA64_SP, /* val=*/ -16); + _U_dyn_op_save_reg (&r_pro->op[i++], _U_QP_TRUE, /* when=*/ 4, + /* reg=*/ UNW_IA64_RP, /* dst=*/ UNW_IA64_GR + 3); + _U_dyn_op_spill_sp_rel (&r_pro->op[i++], _U_QP_TRUE, /* when=*/ 7, + /* reg=*/ UNW_IA64_RP, /* off=*/ 16); + assert ((unsigned) i <= r_pro->op_count); + + /* Create regions for func_vframe: */ + i = 0; + r = alloca (_U_dyn_region_info_size (16)); + r->op_count = 16; + r->next = NULL; + r->insn_count = 4; + _U_dyn_op_label_state (&r->op[i++], /* label=*/ 100402); + _U_dyn_op_pop_frames (&r->op[i++], _U_QP_TRUE, /* when=*/ 3, /* frames=*/ 1); + _U_dyn_op_stop (&r->op[i++]); + assert ((unsigned) i <= r->op_count); + + i = 0; + rtmp = r; + r = alloca (_U_dyn_region_info_size (16)); + r->op_count = 16; + r->next = rtmp; + r->insn_count = 16; + _U_dyn_op_save_reg (&r->op[i++], _U_QP_TRUE, /* when=*/ 8, + /* reg=*/ UNW_IA64_RP, /* dst=*/ UNW_IA64_GR + 3); + _U_dyn_op_pop_frames (&r->op[i++], _U_QP_TRUE, /* when=*/ 10, + /* num_frames=*/ 1); + _U_dyn_op_stop (&r->op[i++]); + assert ((unsigned) i <= r->op_count); + + i = 0; + rtmp = r; + r = alloca (_U_dyn_region_info_size (16)); + r->op_count = 16; + r->next = rtmp; + r->insn_count = 5; + _U_dyn_op_save_reg (&r->op[i++], _U_QP_TRUE, /* when=*/ 1, + /* reg=*/ UNW_IA64_RP, /* dst=*/ UNW_IA64_GR + 33); + _U_dyn_op_save_reg (&r->op[i++], _U_QP_TRUE, /* when=*/ 2, + /* reg=*/ UNW_IA64_SP, /* dst=*/ UNW_IA64_GR + 34); + _U_dyn_op_spill_fp_rel (&r->op[i++], _U_QP_TRUE, /* when=*/ 4, + /* reg=*/ UNW_IA64_AR_PFS, /* off=*/ 16); + _U_dyn_op_label_state (&r->op[i++], /* label=*/ 100402); + _U_dyn_op_stop (&r->op[i++]); + assert ((unsigned) i <= r->op_count); + + /* Create two functions which can share the region-list: */ + add3_0 = (long (*) (long)) + create_func (&di1, "func_add3/0", func_add3, func_add3_end, r_pro); + add3_1 = (long (*) (long, void *[])) + create_func (&di2, "func_add3/1", func_add3, func_add3_end, r_pro); + vframe = (long (*) (long)) + create_func (&di3, "func_vframe", func_vframe, func_vframe_end, r); + + _U_dyn_register (&di1); + _U_dyn_register (&di2); + _U_dyn_register (&di3); + _U_dyn_register (&di0); + + flist[0] = add3_0; + flist[1] = add1; + + kill (getpid (), SIGUSR1); /* do something ptmon can latch onto */ + ret = (*add3_1) (13, flist); + if (ret != 18) + { + fprintf (stderr, "FAILURE: (*add3_1)(13) returned %ld\n", ret); + exit (-1); + } + + ret = (*vframe) (48); + if (ret != 4) + { + fprintf (stderr, "FAILURE: (*vframe)(16) returned %ld\n", ret); + exit (-1); + } + ret = (*vframe) (64); + if (ret != 10) + { + fprintf (stderr, "FAILURE: (*vframe)(32) returned %ld\n", ret); + exit (-1); + } + kill (getpid (), SIGUSR2); /* do something ptmon can latch onto */ + + _U_dyn_cancel (&di0); + _U_dyn_cancel (&di1); + _U_dyn_cancel (&di3); + _U_dyn_cancel (&di2); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-nat-asm.S b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-nat-asm.S new file mode 100644 index 00000000000000..eea5ac27836e88 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-nat-asm.S @@ -0,0 +1,508 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + + .text + +#define CALL_NEXT_PTR(gp_save_reg, arg0, arg1) \ + ld8 r2 = [arg0], 8;; /* read the next function pointer */ \ + ld8 r3 = [r2], 8;; /* read the function's entry-point */ \ + ld8 r2 = [r2];; /* read the function's gp */ \ + mov b6 = r3; \ + mov gp_save_reg = gp; \ + mov out0 = arg0; \ + mov out1 = arg1; \ + mov gp = r2; \ + br.call.sptk.many rp = b6;; \ + mov gp = gp_save_reg + +#define CALL_NEXT(gp_save_reg) CALL_NEXT_PTR(gp_save_reg, in0, in1) + +#define LOAD_VAL(reg) \ + ld8 reg = [in1], 8;; \ + tbit.nz p15, p0 = reg, 0;; \ +(p15) ld8.s reg = [r0] + + + .global flushrs + .proc flushrs +flushrs: + flushrs;; + br.ret.sptk.many rp + .endp flushrs + + /* Save r4-r7 into stacked registers, load them up with the + values passed via the pointer in in1 and then call the + function passed via the pointer in in0. */ + + .global save_static_to_stacked + .proc save_static_to_stacked +save_static_to_stacked: + .prologue + .regstk 2, 7, 2, 0 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 2, 7, 2, 0 + .save rp, loc1 + mov loc1 = rp + .spillreg r4, loc2 + mov loc2 = r4 + .spillreg r5, loc3 + mov loc3 = r5 + .spillreg r6, loc4 + mov loc4 = r6 + .spillreg r7, loc5 + mov loc5 = r7 + .body + LOAD_VAL(r4) + LOAD_VAL(r5) + LOAD_VAL(r6) + LOAD_VAL(r7) + CALL_NEXT(loc6) + + mov r4 = loc2 + mov r5 = loc3 + mov r6 = loc4 + mov r7 = loc5 + + mov ar.pfs = loc0 + mov rp = loc1 + br.ret.sptk.many rp + .endp save_static_to_stacked + + /* Save f2 to the memory stack, save r4 to f2, then load + r4 with the value passed via in1 and call the function + passed via in0. */ + + .global save_static_to_fr + .proc save_static_to_fr +save_static_to_fr: + .prologue + .regstk 2, 3, 2, 0 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 2, 3, 2, 0 + .save rp, loc1 + mov loc1 = rp + .fframe 16 + .spillpsp f2, 0 + stf.spill [sp] = f2, -16 + .spillreg r4, f2 + setf.sig f2 = r4 + + .body + + ld8 r4 = [in1], 8;; + tbit.nz p6, p0 = r4, 0;; +(p6) ld8.s r4 = [r0] + + CALL_NEXT(loc2) + + getf.sig r4 = f2 // restore r4 + .restore sp + add sp = 16, sp;; + ldf.fill f2 = [sp] // restore r2 + + mov ar.pfs = loc0 + mov rp = loc1 + br.ret.sptk.many rp + .endp save_static_to_fr + + /* If r4 is not a NaT, save b3 to a stacked register and + then save r4 in b3. The non-NaTness of r4 is saved in + p1. */ + + .global save_static_to_br + .proc save_static_to_br +save_static_to_br: + .prologue + .regstk 2, 6, 2, 0 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 2, 6, 2, 0 + .save rp, loc1 + mov loc1 = rp + + .save pr, loc2 + mov loc2 = pr // save predicates + + .spillreg b3, loc3 + mov loc3 = b3 + + tnat.z p1, p2 = r4;; + .spillreg.p p1, r4, b3 +(p1) mov b3 = r4 + .spillreg.p p2, r4, loc4 +(p2) mov loc4 = r4 + + .body + + LOAD_VAL(r4) + CALL_NEXT(loc5) + + .pred.rel.mutex p1, p2 +(p1) mov r4 = b3 // restore r4 +(p2) mov r4 = loc4 + + mov ar.pfs = loc0 + mov rp = loc1 + mov pr = loc2, -1 + mov b3 = loc3 // restore b3 + br.ret.sptk.many rp + .endp save_static_to_br + + /* Spill r4 into memory and then save r5 in r4. */ + + .global save_static_to_mem + .proc save_static_to_mem +save_static_to_mem: + .prologue + .regstk 2, 4, 2, 0 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 2, 4, 2, 0 + .save rp, loc1 + mov loc1 = rp + .save ar.unat, loc2 + mov loc2 = ar.unat + + .fframe 16 + .spillpsp r4, 0 + st8.spill [sp] = r4, -16 + + .spillreg r5, r4 + mov r4 = r5 + + .body + + LOAD_VAL(r5) + CALL_NEXT(loc3) + + mov r5 = r4 // restore r5 + .restore sp + add sp = 16, sp;; + ld8.fill r4 = [sp] // restore r4 + + mov ar.pfs = loc0 + mov rp = loc1 + mov ar.unat = loc2 // restore ar.unat + br.ret.sptk.many rp + .endp save_static_to_mem + + /* Spill r6 into memory and save primary ar.unat in a register. */ + + .global save_static_to_mem2 + .proc save_static_to_mem2 +save_static_to_mem2: + .prologue + .regstk 2, 5, 2, 0 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 2, 5, 2, 0 + .save rp, loc1 + mov loc1 = rp + .save ar.unat, loc2 + mov loc2 = ar.unat + + .fframe 16 + .spillpsp r6, 0 + st8.spill [sp] = r6, -16;; + .save @priunat, loc3 + mov loc3 = ar.unat + mov ar.unat = 0 // trash ar.unat + + .body + + LOAD_VAL(r6) + CALL_NEXT(loc4) + + mov ar.unat = loc3 // restore primary UNaT + .restore sp + add sp = 16, sp;; + ld8.fill r6 = [sp] // restore r6 + + mov ar.pfs = loc0 + mov rp = loc1 + mov ar.unat = loc2 // restore ar.unat + br.ret.sptk.many rp + .endp save_static_to_mem2 + + /* Spill r6 into memory and save primary ar.unat in memory. */ + + .global save_static_to_mem3 + .proc save_static_to_mem3 +save_static_to_mem3: + .prologue + .regstk 2, 5, 2, 0 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 2, 5, 2, 0 + .save rp, loc1 + mov loc1 = rp + .save ar.unat, loc2 + mov loc2 = ar.unat + + add r2 = 8, sp + .fframe 16 + .spillpsp r6, 0 + st8.spill [sp] = r6, -16;; + mov r3 = ar.unat;; + .savepsp @priunat, -8 + st8 [r2] = r3 + mov ar.unat = 0 // trash ar.unat + + .body + + LOAD_VAL(r6) + CALL_NEXT(loc4) + + add r2 = 24, sp;; + ld8 r3 = [r2];; + mov ar.unat = r3 // restore primary UNaT + .restore sp + add sp = 16, sp;; + ld8.fill r6 = [sp] // restore r6 + + mov ar.pfs = loc0 + mov rp = loc1 + mov ar.unat = loc2 // restore ar.unat + br.ret.sptk.many rp + .endp save_static_to_mem3 + + /* Spill r6 into memory and save primary ar.unat in register, + then in memory. */ + + .global save_static_to_mem4 + .proc save_static_to_mem4 +save_static_to_mem4: + .prologue + .regstk 2, 5, 2, 0 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 2, 5, 2, 0 + .save rp, loc1 + mov loc1 = rp + .save ar.unat, loc2 + mov loc2 = ar.unat + + add r2 = 8, sp + .fframe 16 + .spillpsp r6, 0 + st8.spill [sp] = r6, -16;; + .save @priunat, r3 + mov r3 = ar.unat;; + mov ar.unat = 0 // trash ar.unat + .savepsp @priunat, -8 + st8 [r2] = r3 + mov r3 = r0 // trash register pri UNaT location + .body + + LOAD_VAL(r6) + CALL_NEXT(loc4) + + add r2 = 24, sp;; + ld8 r3 = [r2];; + mov ar.unat = r3 // restore primary UNaT + .restore sp + add sp = 16, sp;; + ld8.fill r6 = [sp] // restore r6 + + mov ar.pfs = loc0 + mov rp = loc1 + mov ar.unat = loc2 // restore ar.unat + br.ret.sptk.many rp + .endp save_static_to_mem4 + + /* Spill r6 into memory and save primary ar.unat in register, + then in memory. */ + + .global save_static_to_mem5 + .proc save_static_to_mem5 +save_static_to_mem5: + .prologue + .regstk 2, 5, 2, 0 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 2, 5, 2, 0 + .save rp, loc1 + mov loc1 = rp + .save ar.unat, loc2 + mov loc2 = ar.unat + + add r2 = 8, sp + .fframe 16 + .spillpsp r6, 0 + st8.spill [sp] = r6, -16;; + mov r3 = ar.unat;; + mov ar.unat = 0 // trash ar.unat + .savepsp @priunat, -8 + st8 [r2] = r3 + .save @priunat, loc3 + mov loc3 = r3 + st8 [r2] = r0 // trash memory pri UNaT location + .body + + LOAD_VAL(r6) + CALL_NEXT(loc4) + + add r2 = 24, sp;; + ld8 r3 = [r2];; + mov ar.unat = loc3 // restore primary UNaT + .restore sp + add sp = 16, sp;; + ld8.fill r6 = [sp] // restore r6 + + mov ar.pfs = loc0 + mov rp = loc1 + mov ar.unat = loc2 // restore ar.unat + br.ret.sptk.many rp + .endp save_static_to_mem5 + + /* Save r4-r7 to various scratch registers, then trigger + a segfault. */ + + .global save_static_to_scratch + .proc save_static_to_scratch +save_static_to_scratch: + .prologue + + .spillreg r4, r16 + mov r16 = r4 // save r4 in r16 + tnat.nz p6, p7 = r5;; + .spillreg.p p6, r5, f31 +(p6) setf.sig f31 = r5 // save r5 in f31 if it's a NaT + .spillreg.p p7, r5, b6 +(p7) mov b6 = r5 // in b6 if it not + .spillreg r6, f32 + setf.sig f32 = r6 // save r6 in f32 (fph partition) + .spillsp r7, 0 + st8.spill [sp] = r7 // save r7 in the scratch stack space + .spillreg f4, f6 + mov f6 = f4;; + .body + + ld8 r2 = [in1] + ;; + mov ar.ec = r2 + + LOAD_VAL(r4) + LOAD_VAL(r5) + LOAD_VAL(r6) + LOAD_VAL(r7) + setf.sig f4 = r4 + + /* Now force a SIGSEGV. Make sure the ld8 is at the beginning of a + bundle, so the signal-handler can skip over it simply by + incrementing the IP. */ + { + .mmi + ld8 r2 = [r0] + nop.m 0 + nop.i 0 ;; + } + + mov f4 = f6 + mov r4 = r16 + .pred.rel.mutex p6, p7 +(p6) getf.sig r5 = f31 +(p7) mov r5 = b6 + getf.sig r6 = f32 + ld8.fill r7 = [sp] + + br.ret.sptk.many rp + .endp save_static_to_scratch + + /* Rotate registers a bit in a vain attempt to sow some confusion. + Care must be taken not to write any rotating general register + after rotation, because we keep the preserved state + there... */ + + .global rotate_regs + .proc rotate_regs +rotate_regs: + .prologue + .regstk 2, 14, 2, 16 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 2, 14, 2, 16 + .save rp, loc1 + mov loc1 = rp + .save pr, loc2 + mov loc2 = pr + .save ar.lc, loc3 + mov loc3 = ar.lc + .spillreg r4, loc4 + mov loc4 = r4 + + ld8 r2 = [in1], 8;; + mov pr = r2, -1 + + ld8 r2 = [in1], 8;; + mov r8 = in0 + mov r9 = in1 + and r2 = 127, r2;; + mov ar.ec = 0 + mov ar.lc = r2;; + + // use p6 to preserve p63 as it gets rotated into p16: +(p16) cmp.eq.unc p6,p0 = r0,r0;; +1: +(p6) cmp.eq.unc p16,p0 = r0,r0 +(p63) cmp.eq.unc p6,p0 = r0,r0 + br.ctop.dptk.few 1b;; + +(p6) cmp.eq.unc p63,p0 = r0,r0 + + CALL_NEXT_PTR(r4, r8, r9) + + clrrrb + + mov ar.pfs = loc0 + mov rp = loc1 + mov pr = loc2, -1 + mov ar.lc = loc3 + mov r4 = loc4 + br.ret.sptk.many rp + + .endp rotate_regs + + .global save_pr + .proc save_pr +save_pr: + .prologue + .regstk 2, 4, 2, 0 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 2, 4, 2, 0 + .save rp, loc1 + mov loc1 = rp + .save pr, loc2 + mov loc2 = pr + + ld8 r2 = [in1], 8;; + mov pr = r2, -1 + + CALL_NEXT(loc3) + + mov ar.pfs = loc0 + mov rp = loc1 + mov pr = loc2, -1 + br.ret.sptk.many rp + + .endp save_pr + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs-asm.S b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs-asm.S new file mode 100644 index 00000000000000..9a6d33fb1de96c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs-asm.S @@ -0,0 +1,275 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "ia64-test-rbs.h" + + .common stackmem, NSTACKS*STACK_SIZE, 16 + + .text + +#define SAVED_SP_OFF 0 +#define SAVED_RP_OFF 8 +#define SAVED_PFS_OFF 16 +#define SAVED_RNAT_OFF 24 +#define SAVED_BSP_OFF 32 +#define SAVED_BSPSTORE_OFF 40 +#define FRAME_SIZE 48 + +#define SPILL(n) \ + /* int rbs_spill_#n(long iteration, int (*next_func[])()) */ \ + .globl rbs_spill_##n; \ + .proc rbs_spill_##n; \ +rbs_spill_##n: \ + .prologue; \ + alloc r18 = ar.pfs, 2, (n)-2, 2, 0;/* read ar.pfs */ \ + /* first, calculate address of new stack: */ \ + addl r2 = @ltoff(stackmem), gp; \ + add r8 = 1, in0; \ + ;; \ + ld8 r2 = [r2]; /* r2 = &stackmem */ \ + shl r3 = in0, STACK_SIZE_SHIFT; \ + shladd r8 = r8, 3, in1; /* r8 = &next_func[iteration+1] */ \ + ;; \ + ld8 r8 = [r8]; /* r8 = next_func[iteration+1] */ \ + add r2 = r2, r3; /* r2 = stackmem[iteration] */ \ + ;; \ + ld8 r9 = [r8], 8;; /* r9 = target's entry-point */ \ + ld8 gp = [r8]; /* r22 = target's gp */ \ + addl r3 = STACK_SIZE-FRAME_SIZE, r2; /* r3 = &stackframe */ \ + ;; \ + mov b6 = r9; \ + st8 [r3] = sp; \ + .vframesp SAVED_SP_OFF+16; \ + adds sp = -16, r3; /* switch the memory stack */ \ + ;; \ + adds r3 = (SAVED_RP_OFF - SAVED_SP_OFF), r3; \ + mov r16 = rp; \ + ;; \ + .savesp rp, SAVED_RP_OFF+16; \ + st8 [r3] = r16, (SAVED_PFS_OFF - SAVED_RP_OFF); \ + ;; \ + .savesp ar.pfs, SAVED_PFS_OFF+16; \ + st8 [r3] = r18, (SAVED_BSP_OFF - SAVED_PFS_OFF); \ + mov r16 = ar.bsp; \ + mov r17 = ar.bspstore; \ + mov r18 = ar.rnat; \ + ;; \ + .savesp ar.bsp, SAVED_BSP_OFF+16; \ + st8 [r3] = r16, (SAVED_BSPSTORE_OFF - SAVED_BSP_OFF); \ + ;; \ + .savesp ar.bspstore, SAVED_BSPSTORE_OFF+16; \ + st8 [r3] = r17, (SAVED_RNAT_OFF - SAVED_BSPSTORE_OFF); \ + mov out1 = in1; \ + ;; \ + .savesp ar.rnat, SAVED_RNAT_OFF+16; \ + st8 [r3] = r18; \ + .body; \ + mov ar.bspstore = r2; /* switch the backing store */ \ + adds out0 = 1, in0; \ + ;; \ + br.call.sptk.many rp = b6; \ +1: /* switch back to stack: */ \ + adds r3 = SAVED_SP_OFF+16, sp; \ + cmp.ge p8, p0 = r8, r0; \ + ;; \ +(p8) add r8 = 1, r8; \ + ld8 r16 = [r3], (SAVED_RP_OFF-SAVED_SP_OFF);; /* saved sp */ \ + ld8 r17 = [r3], (SAVED_PFS_OFF-SAVED_RP_OFF);; /* saved rp */ \ + ld8 r18 = [r3], (SAVED_RNAT_OFF-SAVED_PFS_OFF);;/* saved pfs */ \ + ld8 r19 = [r3], (SAVED_BSP_OFF-SAVED_RNAT_OFF);;/* saved rnat */ \ + ld8 r20 = [r3], (SAVED_BSPSTORE_OFF-SAVED_BSP_OFF);;/* saved bsp */ \ + ld8 r21 = [r3];; /* saved bspstore */ \ + mov rp = r17; \ + mov ar.pfs = r18; \ + shl r3 = in0, STACK_SIZE_SHIFT; \ + addl r2 = @ltoff(stackmem), gp;; \ + ld8 r2 = [r2];; /* r2 = &stackmem */ \ + add r2 = r2, r3; /* r2 = stackmem[iteration] */ \ + mov r3 = ar.bsp;; \ + sub r2 = r3, r2;; /* r2 = dirty_size */ \ + shl r2 = r2, 16;; \ + mov ar.rsc = r2;; \ + alloc r3 = ar.pfs, 0, 0, 0, 0;; \ + loadrs;; \ + mov ar.bspstore = r21;; /* this also restores ar.bsp */ \ + mov ar.rnat = r19; \ + .restore sp; \ + mov sp = r16; \ + br.ret.sptk.many rp; \ + .endp rbs_spill_##n + + SPILL(2); SPILL(3) + SPILL(4); SPILL(5); SPILL(6); SPILL(7) + SPILL(8); SPILL(9); SPILL(10); SPILL(11) + SPILL(12); SPILL(13); SPILL(14); SPILL(15) + SPILL(16); SPILL(17); SPILL(18); SPILL(19) + SPILL(20); SPILL(21); SPILL(22); SPILL(23) + SPILL(24); SPILL(25); SPILL(26); SPILL(27) + SPILL(28); SPILL(29); SPILL(30); SPILL(31) + SPILL(32); SPILL(33); SPILL(34); SPILL(35) + SPILL(36); SPILL(37); SPILL(38); SPILL(39) + SPILL(40); SPILL(41); SPILL(42); SPILL(43) + SPILL(44); SPILL(45); SPILL(46); SPILL(47) + SPILL(48); SPILL(49); SPILL(50); SPILL(51) + SPILL(52); SPILL(53); SPILL(54); SPILL(55) + SPILL(56); SPILL(57); SPILL(58); SPILL(59) + SPILL(60); SPILL(61); SPILL(62); SPILL(63) + SPILL(64); SPILL(65); SPILL(66); SPILL(67) + SPILL(68); SPILL(69); SPILL(70); SPILL(71) + SPILL(72); SPILL(73); SPILL(74); SPILL(75) + SPILL(76); SPILL(77); SPILL(78); SPILL(79) + SPILL(80); SPILL(81); SPILL(82); SPILL(83) + SPILL(84); SPILL(85); SPILL(86); SPILL(87) + SPILL(88); SPILL(89); SPILL(90); SPILL(91) + SPILL(92); SPILL(93); SPILL(94) + +#define LD_LOC(n) \ + ld4 loc##n = [in1], 4;; \ + cmp.eq p8, p9 = r0, loc##n;; \ +(p9) or loc##n = loc##n, r8; \ +(p8) ld4.s loc##n = [r0] + +#define CK_LOC(n) \ + ld4 r16 = [in1], 4;; \ + cmp.eq p8, p9 = r0, r16; \ + or r16 = r16, r9;; \ +(p8) tnat.z p10, p0 = loc##n; \ +(p9) cmp.ne p10, p0 = r16, loc##n; \ + ;; \ +(p10) mov r8 = -n; \ +(p10) br.cond.spnt.many .fail + + /* int loadup(long iteration, int *values, next_func[]) */ + + .global loadup + .proc loadup +loadup: + .prologue + .save ar.pfs, r36 + alloc loc1 = ar.pfs, 3, 90, 3, 0 + .save rp, loc0 + mov loc0 = rp + .body + cmp.eq p6, p7 = 1, in0 + ;; + mov ar.rsc = 0 // put RSE into enforced lazy mode +(p6) mov out1 = in2 +(p7) mov out2 = in2 + +(p6) ld8 r17 = [in2] // get address of function descriptor +(p7) add out0 = -1, in0 +(p7) mov out1 = in1 + + ;; +(p6) ld8 r16 = [r17], 8 // load entry point + shl r8 = in0, 32 // store iteration # in top 32 bits + mov r18 = in1 + ;; +(p6) ld8 r1 = [r17] // load gp +(p6) mov b6 = r16 + +(p6) mov out0 = 0 + ;; + LD_LOC( 2); LD_LOC( 3) + LD_LOC( 4); LD_LOC( 5); LD_LOC( 6); LD_LOC( 7) + LD_LOC( 8); LD_LOC( 9); LD_LOC(10); LD_LOC(11) + LD_LOC(12); LD_LOC(13); LD_LOC(14); LD_LOC(15) + LD_LOC(16); LD_LOC(17); LD_LOC(18); LD_LOC(19) + LD_LOC(20); LD_LOC(21); LD_LOC(22); LD_LOC(23) + LD_LOC(24); LD_LOC(25); LD_LOC(26); LD_LOC(27) + LD_LOC(28); LD_LOC(29); LD_LOC(30); LD_LOC(31) + LD_LOC(32); LD_LOC(33); LD_LOC(34); LD_LOC(35) + LD_LOC(36); LD_LOC(37); LD_LOC(38); LD_LOC(39) + LD_LOC(40); LD_LOC(41); LD_LOC(42); LD_LOC(43) + LD_LOC(44); LD_LOC(45); LD_LOC(46); LD_LOC(47) + LD_LOC(48); LD_LOC(49); LD_LOC(50); LD_LOC(51) + LD_LOC(52); LD_LOC(53); LD_LOC(54); LD_LOC(55) + LD_LOC(56); LD_LOC(57); LD_LOC(58); LD_LOC(59) + LD_LOC(60); LD_LOC(61); LD_LOC(62); LD_LOC(63) + LD_LOC(64); LD_LOC(65); LD_LOC(66); LD_LOC(67) + LD_LOC(68); LD_LOC(69); LD_LOC(70); LD_LOC(71) + LD_LOC(72); LD_LOC(73); LD_LOC(74); LD_LOC(75) + LD_LOC(76); LD_LOC(77); LD_LOC(78); LD_LOC(79) + LD_LOC(80); LD_LOC(81); LD_LOC(82); LD_LOC(83) + LD_LOC(84); LD_LOC(85); LD_LOC(86); LD_LOC(87) + LD_LOC(88); LD_LOC(89) + ;; +{ .mbb + mov in1 = r18 +(p6) br.call.sptk.many rp = b6 +(p7) br.call.sptk.many rp = loadup +} + cmp.lt p8, p9 = r8, r0 + shl r9 = in0, 32 // store iteration # in top 32 bits +(p8) br.cond.spnt.few .fail + ;; + add r8 = 1, r8 + CK_LOC( 2); CK_LOC( 3) + CK_LOC( 4); CK_LOC( 5); CK_LOC( 6); CK_LOC( 7) + CK_LOC( 8); CK_LOC( 9); CK_LOC(10); CK_LOC(11) + CK_LOC(12); CK_LOC(13); CK_LOC(14); CK_LOC(15) + CK_LOC(16); CK_LOC(17); CK_LOC(18); CK_LOC(19) + CK_LOC(20); CK_LOC(21); CK_LOC(22); CK_LOC(23) + CK_LOC(24); CK_LOC(25); CK_LOC(26); CK_LOC(27) + CK_LOC(28); CK_LOC(29); CK_LOC(30); CK_LOC(31) + CK_LOC(32); CK_LOC(33); CK_LOC(34); CK_LOC(35) + CK_LOC(36); CK_LOC(37); CK_LOC(38); CK_LOC(39) + CK_LOC(40); CK_LOC(41); CK_LOC(42); CK_LOC(43) + CK_LOC(44); CK_LOC(45); CK_LOC(46); CK_LOC(47) + CK_LOC(48); CK_LOC(49); CK_LOC(50); CK_LOC(51) + CK_LOC(52); CK_LOC(53); CK_LOC(54); CK_LOC(55) + CK_LOC(56); CK_LOC(57); CK_LOC(58); CK_LOC(59) + CK_LOC(60); CK_LOC(61); CK_LOC(62); CK_LOC(63) + CK_LOC(64); CK_LOC(65); CK_LOC(66); CK_LOC(67) + CK_LOC(68); CK_LOC(69); CK_LOC(70); CK_LOC(71) + CK_LOC(72); CK_LOC(73); CK_LOC(74); CK_LOC(75) + CK_LOC(76); CK_LOC(77); CK_LOC(78); CK_LOC(79) + CK_LOC(80); CK_LOC(81); CK_LOC(82); CK_LOC(83) + CK_LOC(84); CK_LOC(85); CK_LOC(86); CK_LOC(87) + CK_LOC(88); CK_LOC(89) +.fail: + mov rp = loc0 + mov ar.pfs = loc1 + br.ret.sptk.many rp + .endp loadup + + .global resumption_point_label + .proc resumption_point +resumption_point: +resumption_point_label: + .prologue + .save rp, r16 + .save ar.pfs, r0 + .body + mov r8 = r15 + mov b6 = r16 + ;; + br.cond.sptk.many b6 + .endp resumption_point + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs.h b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs.h new file mode 100644 index 00000000000000..3315ad638006ea --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-rbs.h @@ -0,0 +1,3 @@ +#define NSTACKS 128 +#define STACK_SIZE_SHIFT 17 +#define STACK_SIZE (1 << STACK_SIZE_SHIFT) diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-readonly-asm.S b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-readonly-asm.S new file mode 100644 index 00000000000000..acd3ada2c6497c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-readonly-asm.S @@ -0,0 +1,55 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + + .text + + .global test_func + .proc test_func +test_func: + .prologue + .regstk 1, 3, 0, 0 + .save ar.pfs, loc0 + alloc loc0 = ar.pfs, 1, 3, 0, 0 + mov loc1 = rp + .save rp, r0 + .save ar.lc, r0 + .body + mov loc2 = gp + ld8 r2 = [in0], 8;; + ld8 r1 = [in0];; + mov b6 = r2 + br.call.sptk.many rp = b6 + + mov gp = loc2 + mov rp = loc1 + mov ar.pfs = loc0 + br.ret.sptk.many rp + + .endp test_func + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-setjmp.c b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-setjmp.c new file mode 100644 index 00000000000000..50eaa01bc30feb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-setjmp.c @@ -0,0 +1,155 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* Test to verify that we can siglongjmp() into a frame whose register + window is not backed by valid memory. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_IA64INTRIN_H +# include +#endif + +static sigjmp_buf env; +static int return_level; +static uintptr_t return_bsp; +static int verbose; + +uintptr_t +get_bsp (void) +{ +#ifdef __INTEL_COMPILER + return __getReg (_IA64_REG_AR_BSP); +#else + return (uintptr_t) __builtin_ia64_bsp (); +#endif +} + +static void +sighandler (int signal, void *siginfo, void *sigcontext) +{ + ucontext_t *uc = sigcontext; + int local = 0; + + if (verbose) + printf ("got signal, stack at %p, saved bsp=0x%lx\n", + &local, uc->uc_mcontext.sc_ar_bsp); + siglongjmp (env, 1); +} + +/* Direct call of doit () at the end of doit () would get optimized by GCC to + a branch. */ +static void doit (int n); +typedef void (*doit_type) (int); +static volatile doit_type doit_pointer = doit; + +static void +doit (int n) +{ + uintptr_t guard_page_addr, bsp = get_bsp (); + void *ret; + + if (n == 0) + { + size_t page_size = getpagesize (); + + guard_page_addr = (bsp + page_size - 1) & -page_size; + if (verbose) + printf ("guard_page_addr = 0x%lx\n", (unsigned long) guard_page_addr); + ret = mmap ((void *) guard_page_addr, page_size, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (ret != (void *) guard_page_addr) + { + if (ret == MAP_FAILED) + perror ("mmap"); + else + fprintf (stderr, "mmap() returned %p, expected 0x%lx\n", + ret, guard_page_addr); + exit (EXIT_FAILURE); + } + } + + if (sigsetjmp (env, 1)) + { + return_level = n; + return_bsp = bsp; + } + else + (*doit_pointer) (n + 1); +} + +int +main (int argc, char **argv) +{ + struct sigaction sa; + stack_t ss; + + if (argc > 1) + verbose = 1; + + ss.ss_sp = malloc (2 * SIGSTKSZ); + if (ss.ss_sp == NULL) + { + puts ("failed to allocate alternate stack"); + return EXIT_FAILURE; + } + ss.ss_flags = 0; + ss.ss_size = 2 * SIGSTKSZ; + if (sigaltstack (&ss, NULL) < 0) + { + printf ("sigaltstack failed: %s\n", strerror (errno)); + return EXIT_FAILURE; + } + + sa.sa_handler = (void (*) (int)) sighandler; + sigemptyset (&sa.sa_mask); + sa.sa_flags = SA_SIGINFO | SA_ONSTACK; + if (sigaction (SIGSEGV, &sa, NULL) < 0) + { + printf ("sigaction failed: %s\n", strerror (errno)); + exit (1); + } + + doit (0); + + if (verbose) + { + printf ("sigsetjmp returned at level %d bsp=0x%lx\n", + return_level, return_bsp); + puts ("Test succeeded!"); + } + return EXIT_SUCCESS; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-sig.c b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-sig.c new file mode 100644 index 00000000000000..473efe91d758be --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-sig.c @@ -0,0 +1,102 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2001-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 test uses the unwind interface to modify the IP in an ancestor + frame while still returning to the parent frame. */ + +#include +#include +#include + +#include + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +int verbose; + +static void +sighandler (int signal) +{ + unw_cursor_t cursor, cursor2; + unw_word_t ip; + unw_context_t uc; + + if (verbose) + printf ("caught signal %d\n", signal); + + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + panic ("unw_init() failed!\n"); + + /* get cursor for caller of sighandler: */ + if (unw_step (&cursor) < 0) + panic ("unw_step() failed!\n"); + + cursor2 = cursor; + while (!unw_is_signal_frame (&cursor2)) + if (unw_step (&cursor2) < 0) + panic ("failed to find signal frame!\n"); + + if (unw_step (&cursor2) < 0) + panic ("unw_step() failed!\n"); + + if (unw_get_reg (&cursor2, UNW_REG_IP, &ip) < 0) + panic ("failed to get IP!\n"); + + /* skip faulting instruction (doesn't handle MLX template) */ + ++ip; + if ((ip & 0x3) == 0x3) + ip += 13; + + if (unw_set_reg (&cursor2, UNW_REG_IP, ip) < 0) + panic ("failed to set IP!\n"); + + unw_resume (&cursor); /* update context & return to caller of sighandler() */ + + panic ("unexpected return from unw_resume()!\n"); +} + +static void +doit (volatile char *p) +{ + int ch; + + ch = *p; /* trigger SIGSEGV */ + + if (verbose) + printf ("doit: finishing execution!\n"); +} + +int +main (int argc, char **argv) +{ + if (argc > 1) + verbose = 1; + + signal (SIGSEGV, sighandler); + doit (0); + if (verbose) + printf ("SUCCESS\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack-asm.S b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack-asm.S new file mode 100644 index 00000000000000..0aea33a441345f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack-asm.S @@ -0,0 +1,183 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "ia64-test-stack.h" + + .common stackmem, NSTACKS*STACK_SIZE, 16 + + .global do_unwind_tests + + .text + +#define SAVED_SP_OFF 0 +#define SAVED_RP_OFF 8 +#define SAVED_PFS_OFF 16 +#define SAVED_RNAT_OFF 24 +#define SAVED_BSP_OFF 32 +#define SAVED_BSPSTORE_OFF 40 +#define FRAME_SIZE 48 + + .proc stack_it +stack_it: + .prologue + alloc r18 = ar.pfs, 0, 0, 0, 0 // read ar.pfs + // first, calculate address of new stack: + addl r2 = @ltoff(stackmem), gp + shl r3 = r8, STACK_SIZE_SHIFT + ;; + ld8 r2 = [r2] // r2 = &stackmem + ;; + add r2 = r2, r3 // r2 = stackmem[iteration] + ;; + addl r3 = STACK_SIZE-FRAME_SIZE, r2 // r3 = &stackframe + ;; + st8 [r3] = sp + .vframesp SAVED_SP_OFF+16 + adds sp = -16, r3 // switch the memory stack + ;; + adds r3 = (SAVED_RP_OFF - SAVED_SP_OFF), r3 + mov r16 = rp + ;; + .savesp rp, SAVED_RP_OFF+16 + st8 [r3] = r16, (SAVED_PFS_OFF - SAVED_RP_OFF) + ;; + .savesp ar.pfs, SAVED_PFS_OFF+16 + st8 [r3] = r18, (SAVED_BSP_OFF - SAVED_PFS_OFF) + + mov r16 = ar.bsp + mov r17 = ar.bspstore + mov r18 = ar.rnat + ;; + .savesp ar.bsp, SAVED_BSP_OFF+16 + st8 [r3] = r16, (SAVED_BSPSTORE_OFF - SAVED_BSP_OFF) + ;; + .savesp ar.bspstore, SAVED_BSPSTORE_OFF+16 + st8 [r3] = r17, (SAVED_RNAT_OFF - SAVED_BSPSTORE_OFF) + ;; + .savesp ar.rnat, SAVED_RNAT_OFF+16 + st8 [r3] = r18 + ;; + mov ar.bspstore = r2 // switch the backing store + + .body + + // for even iterations, allocate a local variable: + tbit.nz p6, p0 = r8, 0 +(p6) br.cond.sptk.few .skip + ;; + alloc r2 = ar.pfs, 0, 1, 0, 0 + mov loc0 = r8 + ;; +.skip: cmp.ne p6, p7 = 0, r8 + ;; +{ .mbb +(p6) adds r8 = -1, r8 +(p6) br.call.sptk.many rp = stack_it // next iteration +(p7) br.call.sptk.many rp = do_unwind_tests // time for introspection... +} + // switch back to stack: + + adds r3 = SAVED_SP_OFF+16, sp + ;; + ld8 r16 = [r3], (SAVED_RP_OFF-SAVED_SP_OFF);; // saved sp + ld8 r17 = [r3], (SAVED_PFS_OFF-SAVED_RP_OFF);; // saved rp + ld8 r18 = [r3], (SAVED_RNAT_OFF-SAVED_PFS_OFF);; // saved pfs + ld8 r19 = [r3], (SAVED_BSP_OFF-SAVED_RNAT_OFF);; // saved rnat + ld8 r20 = [r3], (SAVED_BSPSTORE_OFF-SAVED_BSP_OFF);; // saved bsp + ld8 r21 = [r3];; // saved bspstore + + mov rp = r17 + mov ar.pfs = r18 + mov ar.bspstore = r21 // this also restores ar.bsp + ;; + mov ar.rnat = r19 + + .restore sp + mov sp = r16 + br.ret.sptk.many rp + .endp stack_it + + +#define SET_LOC(n) add loc##n = n, r8 +#define SET_NAT(n) ld8.s loc##n = [r0] + + .global touch_all + .proc touch_all +touch_all: + .prologue + .save ar.pfs, r34 + alloc loc1 = ar.pfs, 1, 94, 1, 0 + .save rp, loc0 + mov loc0 = rp + .body + + mov ar.rsc = 0 // put RSE into enforced lazy mode + shl r8 = in0, 32 // store iteration # in top 32 bits + add out0 = -1, in0 + cmp.eq p6, p7 = 1, in0 + ;; + SET_LOC( 2); SET_LOC( 3) + SET_LOC( 4); SET_LOC( 5); SET_LOC( 6); SET_LOC( 7) + SET_LOC( 8); SET_LOC( 9); SET_LOC(10); SET_LOC(11) + SET_LOC(12); SET_LOC(13); SET_LOC(14); SET_LOC(15) + SET_LOC(16); SET_LOC(17); SET_LOC(18); SET_LOC(19) + SET_LOC(20); SET_LOC(21); SET_LOC(22); SET_LOC(23) + SET_LOC(24); SET_LOC(25); SET_LOC(26); SET_LOC(27) + SET_LOC(28); SET_LOC(29); SET_LOC(30); SET_LOC(31) + SET_LOC(32); SET_LOC(33); SET_LOC(34); SET_LOC(35) + SET_LOC(36); SET_LOC(37); SET_LOC(38); SET_LOC(39) + SET_LOC(40); SET_LOC(41); SET_LOC(42); SET_LOC(43) + SET_LOC(44); SET_LOC(45); SET_LOC(46); SET_LOC(47) + SET_LOC(48); SET_LOC(49); SET_LOC(50); SET_LOC(51) + SET_LOC(52); SET_LOC(53); SET_LOC(54); SET_LOC(55) + SET_LOC(56); SET_LOC(57); SET_LOC(58); SET_LOC(59) + SET_LOC(60); SET_LOC(61); SET_LOC(62); SET_LOC(63) + SET_LOC(64); SET_LOC(65); SET_LOC(66); SET_LOC(67) + SET_LOC(68); SET_LOC(69); SET_LOC(70); SET_LOC(71) + SET_LOC(72); SET_LOC(73); SET_LOC(74); SET_LOC(75) + SET_LOC(76); SET_LOC(77); SET_LOC(78); SET_LOC(79) + SET_LOC(80); SET_LOC(81); SET_LOC(82); SET_LOC(83) + SET_LOC(84); SET_LOC(85); SET_LOC(86); SET_LOC(87) + SET_LOC(88); SET_LOC(89); SET_LOC(90); SET_LOC(91) + SET_LOC(92); SET_LOC(93) + ;; + SET_NAT(2); SET_NAT(31); SET_NAT(73); SET_NAT(93) + ;; +{ .mbb + mov r8=NSTACKS-1 +(p6) br.call.sptk.many rp = stack_it +(p7) br.call.sptk.many rp = touch_all +} + ;; + + mov rp = loc0 + mov ar.pfs = loc1 + br.ret.sptk.many rp + .endp touch_all + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack.h b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack.h new file mode 100644 index 00000000000000..5665a79d9564ba --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ia64-test-stack.h @@ -0,0 +1,3 @@ +#define NSTACKS 1024 +#define STACK_SIZE_SHIFT 17 +#define STACK_SIZE (1 << STACK_SIZE_SHIFT) diff --git a/src/coreclr/src/pal/src/libunwind/tests/ident.c b/src/coreclr/src/pal/src/libunwind/tests/ident.c new file mode 100644 index 00000000000000..9024e292f5a542 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ident.c @@ -0,0 +1,5 @@ +long +f (long val) +{ + return val; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/mapper.c b/src/coreclr/src/pal/src/libunwind/tests/mapper.c new file mode 100644 index 00000000000000..b47ae780f8ede8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/mapper.c @@ -0,0 +1,78 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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 program creates lots of mappings such that on Linux the + reading of /proc/PID/maps gets very slow. With proper caching, + test-ptrace should still run at acceptable speed once + /proc/PID/maps has been scanned. If the program dies with a + SIGALRM, it means it was running unexpectedly slow. */ + +#include +#include +#include +#include + +#include + +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +#endif +#if !defined(MAP_NORESERVE) +# define MAP_NORESERVE 0 +#endif + +int +main (void) +{ + long n = 0; + + signal (SIGUSR1, SIG_IGN); + signal (SIGUSR2, SIG_IGN); + + printf ("Starting mmap test...\n"); + for (n = 0; n < 30000; ++n) + { + if (mmap (NULL, 1, (n & 1) ? PROT_READ : PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS +#ifdef MAP_NORESERVE + | MAP_NORESERVE +#endif + , + -1, 0) == MAP_FAILED) + { + printf ("Failed after %ld successful maps\n", n - 1); + exit (0); + } + } + + alarm (80); /* die if we don't finish in 80 seconds */ + + printf ("Turning on single-stepping...\n"); + kill (getpid (), SIGUSR1); /* tell test-ptrace to start single-stepping */ + printf ("Va bene?\n"); + kill (getpid (), SIGUSR2); /* tell test-ptrace to stop single-stepping */ + printf ("Turned single-stepping off...\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/perf-startup b/src/coreclr/src/pal/src/libunwind/tests/perf-startup new file mode 100755 index 00000000000000..1c24e9a9bc3b54 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/perf-startup @@ -0,0 +1,19 @@ +#!/bin/sh +platform=$1 +LIBUNWIND=../src/.libs/libunwind.so +LIBUNWIND_PLAT=../src/.libs/libunwind-$platform.so +warmup=$(./forker 2000 /bin/true | cut -f1 -d' ') + +nsec1=$(./forker 2000 /bin/true | cut -f1 -d' ') +printf "\"/bin/true\"\t\t\t\t\t\t: $nsec1 nsec/execution\n" + +nsec2=$(LD_PRELOAD=$LIBUNWIND ./forker 2000 /bin/true | cut -f1 -d' ') +printf "\"LD_PRELOAD=$LIBUNWIND /bin/true\"\t: $nsec2 nsec/execution\n" + +nsec3=$(LD_PRELOAD=$LIBUNWIND_PLAT ./forker 2000 /bin/true | cut -f1 -d' ') +printf "\"LD_PRELOAD=$LIBUNWIND_PLAT /bin/true\"\t: $nsec3 nsec/execution\n" + +echo + +printf "Overhead of preloading $LIBUNWIND\t: $(($nsec2 - $nsec1)) nsec\n" +printf "Overhead of preloading $LIBUNWIND_PLAT\t: $(($nsec3 - $nsec1)) nsec\n" diff --git a/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec-utils.c b/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec-utils.c new file mode 100644 index 00000000000000..bd67ff7d6e0265 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec-utils.c @@ -0,0 +1,32 @@ +#include +#include + +union si_overlay +{ + vector signed int v; + int ints[4]; +}; + +vector signed int +vec_init () +{ + vector signed int v; + static int count = 1; + + ((union si_overlay *) &v)->ints[0] = count++; + ((union si_overlay *) &v)->ints[1] = count++; + ((union si_overlay *) &v)->ints[2] = count++; + ((union si_overlay *) &v)->ints[3] = count++; + return v; +} + +void +vec_print (vector signed int v) +{ + printf ("%08x %08x %08x %08x", + ((union si_overlay *) &v)->ints[0], + ((union si_overlay *) &v)->ints[1], + ((union si_overlay *) &v)->ints[2], + ((union si_overlay *) &v)->ints[3]); +} + diff --git a/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec.c b/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec.c new file mode 100644 index 00000000000000..a3e95eefbbc129 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/ppc64-test-altivec.c @@ -0,0 +1,177 @@ + + +#include +#include +#include +#include +#include +#include + +#include + +#define panic(args...) { fprintf (stderr, args); abort(); } + +extern vector signed int vec_init (); +extern void vec_print (vector signed int v); + +vector signed int vec_stack (int count); + +int +main () +{ + printf ("&vec_stack = %016lx\n", (unsigned long) vec_stack); + vec_stack (3); + return 0; +} + + +vector signed int +vec_stack (int count) +{ + register vector signed int v1; + register vector signed int v2; + register vector signed int v3; + register vector signed int v4; + register vector signed int v5; + register vector signed int v6; + register vector signed int v7; + register vector signed int v8; + register vector signed int v9; + + unw_fpreg_t vr; + + unw_cursor_t cursor; + unw_word_t ip, sp; + unw_context_t uc; + int ret; + int verbose = 1; + + /* if (count == 0) return vec_init(); */ + + if (count == 0) + { + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + { + panic ("unw_init_local failed!\n"); + } + else + { + do + { + if ((ret = unw_get_reg (&cursor, UNW_REG_IP, &ip)) < 0) + { + panic ("FAILURE: unw_get_reg returned %d for UNW_REG_IP\n", + ret); + } + if ((ret = unw_get_reg (&cursor, UNW_REG_SP, &sp)) < 0) + { + panic ("FAILURE: unw_get_reg returned %d for UNW_REG_SP\n", + ret); + } + if ((ret = unw_get_fpreg (&cursor, UNW_PPC64_V30, &vr)) < 0) + { + panic + ("FAILURE: unw_get_vreg returned %d for UNW_PPC64_V30\n", + ret); + } + + + if (verbose) + { + const char *regname = unw_regname (UNW_PPC64_V30); + char proc_name_buffer[256]; + unw_word_t offset; + unsigned int * vec_half1, * vec_half2; + vec_half1 = (unsigned int *)&vr; + vec_half2 = vec_half1 + 1; + printf ("ip = %016lx, sp=%016lx\n", (long) ip, (long) sp); + printf ("vr30 = %08x %08x %08x %08x\n", + (unsigned int) (*vec_half1 >> 16), + (unsigned int) (*vec_half1 & 0xffffffff), + (unsigned int) (*vec_half2 >> 16), + (unsigned int) (*vec_half2 & 0xffffffff)); + ret = + unw_get_proc_name (&cursor, proc_name_buffer, + sizeof (proc_name_buffer), &offset); + if (ret == 0) + { + printf ("proc name = %s, offset = %lx\n", + proc_name_buffer, offset); + } + else + { + panic ("unw_get_proc_name returned %d\n", ret); + } + printf ("unw_regname(UNW_PPC_V30) = %s\n\n", regname); + } + + ret = unw_step (&cursor); + if (ret < 0) + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + panic ("FAILURE: unw_step() returned %d for ip=%lx\n", ret, + (long) ip); + } + } + while (ret > 0); + } + } + + v1 = vec_init (); + v2 = vec_init (); + v3 = vec_init (); + v4 = vec_init (); + v5 = vec_init (); + v6 = vec_init (); + + /* make use of all of the registers in some calculation */ + v7 = + vec_nor (v1, vec_add (v2, vec_sub (v3, vec_and (v4, vec_or (v5, v6))))); + + /* + * "force" the registers to be non-volatile by making a call and also + * using the registers after the call. + */ + v8 = vec_stack (count - 1); + + /* + * Use the result from the previous call, plus all of the non-volatile + * registers in another calculation. + */ + v9 = + vec_nor (v1, + vec_add (v2, + vec_sub (v3, + vec_and (v4, vec_or (v5, vec_xor (v6, v8)))))); + + printf ("v1 - "); + vec_print (v1); + printf ("\n"); + printf ("v2 - "); + vec_print (v2); + printf ("\n"); + printf ("v3 - "); + vec_print (v3); + printf ("\n"); + printf ("v4 - "); + vec_print (v4); + printf ("\n"); + printf ("v5 - "); + vec_print (v5); + printf ("\n"); + printf ("v6 - "); + vec_print (v6); + printf ("\n"); + printf ("v7 - "); + vec_print (v7); + printf ("\n"); + printf ("v8 - "); + vec_print (v8); + printf ("\n"); + printf ("v9 - "); + vec_print (v9); + printf ("\n"); + + return v9; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-check-namespace b/src/coreclr/src/pal/src/libunwind/tests/run-check-namespace new file mode 100755 index 00000000000000..d57c8642a270e7 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/run-check-namespace @@ -0,0 +1,3 @@ +#!/bin/sh +chmod +x ./check-namespace.sh +./check-namespace.sh $* diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind b/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind new file mode 100755 index 00000000000000..8d077425746023 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind @@ -0,0 +1,53 @@ +#!/bin/sh + +# this function is slight modification of the one used in RPM +# found at https://bugzilla.redhat.com/show_bug.cgi?id=834073 +# written by Alexander Larsson +add_minidebug() +{ + debuginfo="$1" ## we don't have separate debuginfo file + binary="$1" + + dynsyms=`mktemp` + funcsyms=`mktemp` + keep_symbols=`mktemp` + mini_debuginfo=`mktemp` + + # Extract the dynamic symbols from the main binary, there is no need to also have these + # in the normal symbol table + nm -D "$binary" --format=posix --defined-only | awk '{ print $1 }' | sort > "$dynsyms" + # Extract all the text (i.e. function) symbols from the debuginfo + nm "$debuginfo" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t") print $1 }' | sort > "$funcsyms" + # Keep all the function symbols not already in the dynamic symbol table + comm -13 "$dynsyms" "$funcsyms" > "$keep_symbols" + # Copy the full debuginfo, keeping only a minumal set of symbols and removing some unnecessary sections + objcopy -S --remove-section .gdb_index --remove-section .comment --keep-symbols="$keep_symbols" "$debuginfo" "$mini_debuginfo" &> /dev/null + #Inject the compressed data into the .gnu_debugdata section of the original binary + xz "$mini_debuginfo" + mini_debuginfo="${mini_debuginfo}.xz" + objcopy --add-section .gnu_debugdata="$mini_debuginfo" "$binary" + rm -f "$dynsyms" "$funcsyms" "$keep_symbols" "$mini_debuginfo" + + strip "$binary" ## throw away the symbol table +} + + +TESTDIR=`pwd` +TEMPDIR=`mktemp --tmpdir -d libunwind-test-XXXXXXXXXX` +trap "rm -r -- $TEMPDIR" EXIT + +cp crasher $TEMPDIR/crasher +if [ "$1" = "-minidebuginfo" ]; then + add_minidebug $TEMPDIR/crasher +fi + +# create core dump +( + cd $TEMPDIR + ulimit -c 10000 + ./crasher backing_files +) 2>/dev/null +COREFILE=$TEMPDIR/core* + +# magic option -testcase enables checking for the specific contents of the stack +./test-coredump-unwind $COREFILE -testcase `cat $TEMPDIR/backing_files` diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind-mdi b/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind-mdi new file mode 100755 index 00000000000000..d0a315b8e32c67 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/run-coredump-unwind-mdi @@ -0,0 +1,8 @@ +#!/bin/sh + +# This test intends to test the unw_get_proc_name function on binaries without +# the symbol table but with so called MiniDebuginfo available. In particular, +# it is tested using the coredump accessors. For more info about MiniDebugInfo +# see e.g. http://fedoraproject.org/wiki/Features/MiniDebugInfo + +${0%/*}/run-coredump-unwind -minidebuginfo diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-ia64-test-dyn1 b/src/coreclr/src/pal/src/libunwind/tests/run-ia64-test-dyn1 new file mode 100755 index 00000000000000..acce944ca15b6e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/run-ia64-test-dyn1 @@ -0,0 +1,2 @@ +#!/bin/sh +./test-ptrace -t ./ia64-test-dyn1 diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-mapper b/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-mapper new file mode 100755 index 00000000000000..dc3010d4b33fe8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-mapper @@ -0,0 +1,2 @@ +#!/bin/sh +./test-ptrace -c -n -t ./mapper $* diff --git a/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-misc b/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-misc new file mode 100755 index 00000000000000..c3a6552f1de935 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/run-ptrace-misc @@ -0,0 +1,2 @@ +#!/bin/sh +./test-ptrace -c -t ./test-ptrace-misc diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-async-sig.c b/src/coreclr/src/pal/src/libunwind/tests/test-async-sig.c new file mode 100644 index 00000000000000..2ce8b4bb711d03 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-async-sig.c @@ -0,0 +1,193 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* Check whether basic unwinding truly is async-signal safe. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "compiler.h" + +#include +#include +#include +#include +#include + +#include + +#define UNW_LOCAL_ONLY +#include + +static const int nerrors_max = 100; + +struct itimerval interval = + { + .it_interval = { .tv_sec = 0, .tv_usec = 0 }, + .it_value = { .tv_sec = 0, .tv_usec = 1000 } + }; + +int verbose; +int nerrors; +int sigcount; + +#ifndef CONFIG_BLOCK_SIGNALS +/* When libunwind is configured with --enable-block-signals=no, the caller + is responsible for preventing recursion via signal handlers. + We use a simple global here. In a multithreaded program, one would use + a thread-local variable. */ +int recurcount; +#endif + +#define panic(args...) \ + { ++nerrors; fprintf (stderr, args); return; } + +static void +do_backtrace (int may_print, int get_proc_name) +{ + char buf[512], name[256]; + unw_cursor_t cursor; + unw_word_t ip, sp, off; + unw_context_t uc; + int ret; + int depth = 0; + +#ifndef CONFIG_BLOCK_SIGNALS + if (recurcount > 0) + return; + recurcount += 1; +#endif + + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + panic ("unw_init_local failed!\n"); + + do + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + unw_get_reg (&cursor, UNW_REG_SP, &sp); + + buf[0] = '\0'; + if (get_proc_name || (may_print && verbose)) + { + ret = unw_get_proc_name (&cursor, name, sizeof (name), &off); + if (ret == 0 && (may_print && verbose)) + { + if (off) + snprintf (buf, sizeof (buf), "<%s+0x%lx>", name, (long) off); + else + { + size_t len = strlen (name); + buf[0] = '<'; + memcpy (buf + 1, name, len); + buf[len + 1] = '>'; + buf[len + 2] = '\0'; + } + } + } + + if (may_print && verbose) + printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); + + ret = unw_step (&cursor); + if (ret < 0) + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + panic ("FAILURE: unw_step() returned %d for ip=%lx\n", + ret, (long) ip); + } + if (depth++ > 100) + { + panic ("FAILURE: unw_step() looping over %d iterations\n", depth); + break; + } + } + while (ret > 0); + +#ifndef CONFIG_BLOCK_SIGNALS + recurcount -= 1; +#endif +} + +void +sighandler (int signal) +{ + if (verbose) + printf ("sighandler(signal=%d, count=%d)\n", signal, sigcount); + + do_backtrace (1, 1); + + ++sigcount; + + if (sigcount == 100) + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); + else if (sigcount == 200) + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); + else if (sigcount == 300 || nerrors > nerrors_max) + { + if (nerrors > nerrors_max) + panic ("Too many errors (%d)\n", nerrors); + if (nerrors) + { + fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); + exit (-1); + } + if (verbose) + printf ("SUCCESS.\n"); + exit (0); + } + setitimer (ITIMER_VIRTUAL, &interval, NULL); +} + +int +main (int argc, char **argv UNUSED) +{ + struct sigaction act; + long i = 0; + + if (argc > 1) + verbose = 1; + + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); + + memset (&act, 0, sizeof (act)); + act.sa_handler = sighandler; + act.sa_flags = SA_SIGINFO; + sigaction (SIGVTALRM, &act, NULL); + + setitimer (ITIMER_VIRTUAL, &interval, NULL); + + while (1) + { + if (0 && verbose) + printf ("%s: starting backtrace\n", __FUNCTION__); + do_backtrace (0, (i++ % 100) == 0); + if (nerrors > nerrors_max) + { + fprintf (stderr, "Too many errors (%d)\n", nerrors); + exit (-1); + } + } + return (0); +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c b/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c new file mode 100644 index 00000000000000..fb06a38effa10f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c @@ -0,0 +1,399 @@ +/* + * Example program for unwinding core dumps. + * + * Compile a-la: + * gcc -Os -Wall \ + * -Wl,--start-group \ + * -lunwind -lunwind-x86 -lunwind-coredump \ + * example-core-unwind.c \ + * -Wl,--end-group \ + * -oexample-core-unwind + * + * Run: + * eu-unstrip -n --core COREDUMP + * figure out which virtual addresses in COREDUMP correspond to which mapped executable files + * (binary and libraries), then supply them like this: + * ./example-core-unwind COREDUMP 0x400000:/bin/crashed_program 0x3458600000:/lib/libc.so.6 [...] + * + * Note: Program eu-unstrip is part of elfutils, virtual addresses of shared + * libraries can be determined by ldd (at least on linux). + */ + +#include "compiler.h" + +#undef _GNU_SOURCE +#define _GNU_SOURCE 1 +#undef __USE_GNU +#define __USE_GNU 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* For SIGSEGV handler code */ +#if HAVE_EXECINFO_H +# include +#else + extern int backtrace (void **, int); +#endif +#include + +#include + + +/* Utility logging functions */ + +enum { + LOGMODE_NONE = 0, + LOGMODE_STDIO = (1 << 0), + LOGMODE_SYSLOG = (1 << 1), + LOGMODE_BOTH = LOGMODE_SYSLOG + LOGMODE_STDIO, +}; +const char *msg_prefix = ""; +const char *msg_eol = "\n"; +int logmode = LOGMODE_STDIO; +int xfunc_error_retval = EXIT_FAILURE; + +void xfunc_die(void) +{ + exit(xfunc_error_retval); +} + +static void verror_msg_helper(const char *s, + va_list p, + const char* strerr, + int flags) +{ + char *msg; + int prefix_len, strerr_len, msgeol_len, used; + + if (!logmode) + return; + + used = vasprintf(&msg, s, p); + if (used < 0) + return; + + /* This is ugly and costs +60 bytes compared to multiple + * fprintf's, but is guaranteed to do a single write. + * This is needed for e.g. when multiple children + * can produce log messages simultaneously. */ + + prefix_len = msg_prefix[0] ? strlen(msg_prefix) + 2 : 0; + strerr_len = strerr ? strlen(strerr) : 0; + msgeol_len = strlen(msg_eol); + /* +3 is for ": " before strerr and for terminating NUL */ + char *msg1 = (char*) realloc(msg, prefix_len + used + strerr_len + msgeol_len + 3); + if (!msg1) + { + free(msg); + return; + } + msg = msg1; + /* TODO: maybe use writev instead of memmoving? Need full_writev? */ + if (prefix_len) + { + char *p; + memmove(msg + prefix_len, msg, used); + used += prefix_len; + p = stpcpy(msg, msg_prefix); + p[0] = ':'; + p[1] = ' '; + } + if (strerr) + { + if (s[0]) + { + msg[used++] = ':'; + msg[used++] = ' '; + } + strcpy(&msg[used], strerr); + used += strerr_len; + } + strcpy(&msg[used], msg_eol); + + if (flags & LOGMODE_STDIO) + { + fflush(stdout); + write(STDERR_FILENO, msg, used + msgeol_len); + } + msg[used] = '\0'; /* remove msg_eol (usually "\n") */ + if (flags & LOGMODE_SYSLOG) + { + syslog(LOG_ERR, "%s", msg + prefix_len); + } + free(msg); +} + +void log_msg(const char *s, ...) +{ + va_list p; + va_start(p, s); + verror_msg_helper(s, p, NULL, logmode); + va_end(p); +} +/* It's a macro, not function, since it collides with log() from math.h */ +#undef log +#define log(...) log_msg(__VA_ARGS__) + +void error_msg(const char *s, ...) +{ + va_list p; + va_start(p, s); + verror_msg_helper(s, p, NULL, logmode); + va_end(p); +} + +void error_msg_and_die(const char *s, ...) +{ + va_list p; + va_start(p, s); + verror_msg_helper(s, p, NULL, logmode); + va_end(p); + xfunc_die(); +} + +void perror_msg(const char *s, ...) +{ + va_list p; + va_start(p, s); + /* Guard against ": Success" */ + verror_msg_helper(s, p, errno ? strerror(errno) : NULL, logmode); + va_end(p); +} + +void perror_msg_and_die(const char *s, ...) +{ + va_list p; + va_start(p, s); + /* Guard against ": Success" */ + verror_msg_helper(s, p, errno ? strerror(errno) : NULL, logmode); + va_end(p); + xfunc_die(); +} + +void die_out_of_memory(void) +{ + error_msg_and_die("Out of memory, exiting"); +} + +/* End of utility logging functions */ + + + +static +void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) +{ + long ip = 0; + ucontext_t *uc UNUSED; + + uc = ucontext; +#if defined(__linux__) +#ifdef UNW_TARGET_X86 + ip = uc->uc_mcontext.gregs[REG_EIP]; +#elif defined(UNW_TARGET_X86_64) + ip = uc->uc_mcontext.gregs[REG_RIP]; +#elif defined(UNW_TARGET_ARM) + ip = uc->uc_mcontext.arm_pc; +#endif +#elif defined(__FreeBSD__) +#ifdef __i386__ + ip = uc->uc_mcontext.mc_eip; +#elif defined(__amd64__) + ip = uc->uc_mcontext.mc_rip; +#else +#error Port me +#endif +#else +#error Port me +#endif + dprintf(2, "signal:%d address:0x%lx ip:0x%lx\n", + sig, + /* this is void*, but using %p would print "(null)" + * even for ptrs which are not exactly 0, but, say, 0x123: + */ + (long)info->si_addr, + ip); + + { + /* glibc extension */ + void *array[50]; + int size; + size = backtrace(array, 50); +#if defined __linux__ && HAVE_EXECINFO_H + backtrace_symbols_fd(array, size, 2); +#endif + } + + _exit(1); +} + +static void install_sigsegv_handler(void) +{ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handle_sigsegv; + sa.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &sa, NULL); + sigaction(SIGILL, &sa, NULL); + sigaction(SIGFPE, &sa, NULL); + sigaction(SIGBUS, &sa, NULL); +} + +int +main(int argc UNUSED, char **argv) +{ + unw_addr_space_t as; + struct UCD_info *ui; + unw_cursor_t c; + int ret; + +#define TEST_FRAMES 4 +#define TEST_NAME_LEN 32 + int testcase = 0; + int test_cur = 0; + long test_start_ips[TEST_FRAMES]; + char test_names[TEST_FRAMES][TEST_NAME_LEN]; + + install_sigsegv_handler(); + + const char *progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + + if (!argv[1]) + error_msg_and_die("Usage: %s COREDUMP [VADDR:BINARY_FILE]...", progname); + + msg_prefix = progname; + + as = unw_create_addr_space(&_UCD_accessors, 0); + if (!as) + error_msg_and_die("unw_create_addr_space() failed"); + + ui = _UCD_create(argv[1]); + if (!ui) + error_msg_and_die("_UCD_create('%s') failed", argv[1]); + ret = unw_init_remote(&c, as, ui); + if (ret < 0) + error_msg_and_die("unw_init_remote() failed: ret=%d\n", ret); + + argv += 2; + + /* Enable checks for the crasher test program? */ + if (*argv && !strcmp(*argv, "-testcase")) + { + testcase = 1; + logmode = LOGMODE_NONE; + argv++; + } + + while (*argv) + { + char *colon; + unsigned long vaddr = strtoul(*argv, &colon, 16); + if (*colon != ':') + error_msg_and_die("Bad format: '%s'", *argv); + if (_UCD_add_backing_file_at_vaddr(ui, vaddr, colon + 1) < 0) + error_msg_and_die("Can't add backing file '%s'", colon + 1); + argv++; + } + + for (;;) + { + unw_word_t ip; + ret = unw_get_reg(&c, UNW_REG_IP, &ip); + if (ret < 0) + error_msg_and_die("unw_get_reg(UNW_REG_IP) failed: ret=%d\n", ret); + + unw_proc_info_t pi; + ret = unw_get_proc_info(&c, &pi); + if (ret < 0) + error_msg_and_die("unw_get_proc_info(ip=0x%lx) failed: ret=%d\n", (long) ip, ret); + + if (!testcase) + printf("\tip=0x%08lx proc=%08lx-%08lx handler=0x%08lx lsda=0x%08lx\n", + (long) ip, + (long) pi.start_ip, (long) pi.end_ip, + (long) pi.handler, (long) pi.lsda); + + if (testcase && test_cur < TEST_FRAMES) + { + unw_word_t off; + + test_start_ips[test_cur] = (long) pi.start_ip; + if (unw_get_proc_name(&c, test_names[test_cur], sizeof(test_names[0]), &off) != 0) + { + test_names[test_cur][0] = '\0'; + } + test_cur++; + } + + log("step"); + ret = unw_step(&c); + log("step done:%d", ret); + if (ret < 0) + error_msg_and_die("FAILURE: unw_step() returned %d", ret); + if (ret == 0) + break; + } + log("stepping ended"); + + /* Check that the second and third frames are equal, but distinct of the + * others */ + if (testcase && + (test_cur != 4 + || test_start_ips[1] != test_start_ips[2] + || test_start_ips[0] == test_start_ips[1] + || test_start_ips[2] == test_start_ips[3] + ) + ) + { + fprintf(stderr, "FAILURE: start IPs incorrect\n"); + return -1; + } + + if (testcase && + ( strcmp(test_names[0], "a") + || strcmp(test_names[1], "b") + || strcmp(test_names[2], "b") + || strcmp(test_names[3], "main") + ) + ) + { + fprintf(stderr, "FAILURE: procedure names are missing/incorrect\n"); + return -1; + } + + _UCD_destroy(ui); + unw_destroy_addr_space(as); + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-flush-cache.c b/src/coreclr/src/pal/src/libunwind/tests/test-flush-cache.c new file mode 100644 index 00000000000000..1611cf48efda69 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-flush-cache.c @@ -0,0 +1,143 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Copyright (c) 2003 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. */ + +#include +#include + +#define UNW_LOCAL_ONLY /* must define this for consistency with backtrace() */ +#include + +int verbose; + +int +f257 (void) +{ + void *buffer[300]; + int i, n; + + if (verbose) + printf ("First backtrace:\n"); + n = unw_backtrace (buffer, 300); + if (verbose) + for (i = 0; i < n; ++i) + printf ("[%d] ip=%p\n", i, buffer[i]); + + unw_set_cache_size (unw_local_addr_space, 1023, 0); + unw_flush_cache (unw_local_addr_space, 0, 0); + + if (verbose) + printf ("\nSecond backtrace:\n"); + n = unw_backtrace (buffer, 300); + if (verbose) + for (i = 0; i < n; ++i) + printf ("[%d] ip=%p\n", i, buffer[i]); + return 0; +} + +#define F(n,m) \ +int \ +f##n (void) \ +{ \ + return f##m (); \ +} + +/* Here, we rely on the fact that the script-cache's hash-table is 256 + entries big. With 257 functions, we're guaranteed to get at least + one hash-collision. */ +F(256,257) F(255,256) F(254,255) F(253,254) +F(252,253) F(251,252) F(250,251) F(249,250) +F(248,249) F(247,248) F(246,247) F(245,246) +F(244,245) F(243,244) F(242,243) F(241,242) +F(240,241) F(239,240) F(238,239) F(237,238) +F(236,237) F(235,236) F(234,235) F(233,234) +F(232,233) F(231,232) F(230,231) F(229,230) +F(228,229) F(227,228) F(226,227) F(225,226) +F(224,225) F(223,224) F(222,223) F(221,222) +F(220,221) F(219,220) F(218,219) F(217,218) +F(216,217) F(215,216) F(214,215) F(213,214) +F(212,213) F(211,212) F(210,211) F(209,210) +F(208,209) F(207,208) F(206,207) F(205,206) +F(204,205) F(203,204) F(202,203) F(201,202) +F(200,201) F(199,200) F(198,199) F(197,198) +F(196,197) F(195,196) F(194,195) F(193,194) +F(192,193) F(191,192) F(190,191) F(189,190) +F(188,189) F(187,188) F(186,187) F(185,186) +F(184,185) F(183,184) F(182,183) F(181,182) +F(180,181) F(179,180) F(178,179) F(177,178) +F(176,177) F(175,176) F(174,175) F(173,174) +F(172,173) F(171,172) F(170,171) F(169,170) +F(168,169) F(167,168) F(166,167) F(165,166) +F(164,165) F(163,164) F(162,163) F(161,162) +F(160,161) F(159,160) F(158,159) F(157,158) +F(156,157) F(155,156) F(154,155) F(153,154) +F(152,153) F(151,152) F(150,151) F(149,150) +F(148,149) F(147,148) F(146,147) F(145,146) +F(144,145) F(143,144) F(142,143) F(141,142) +F(140,141) F(139,140) F(138,139) F(137,138) +F(136,137) F(135,136) F(134,135) F(133,134) +F(132,133) F(131,132) F(130,131) F(129,130) +F(128,129) F(127,128) F(126,127) F(125,126) +F(124,125) F(123,124) F(122,123) F(121,122) +F(120,121) F(119,120) F(118,119) F(117,118) +F(116,117) F(115,116) F(114,115) F(113,114) +F(112,113) F(111,112) F(110,111) F(109,110) +F(108,109) F(107,108) F(106,107) F(105,106) +F(104,105) F(103,104) F(102,103) F(101,102) +F(100,101) F(99,100) F(98,99) F(97,98) +F(96,97) F(95,96) F(94,95) F(93,94) +F(92,93) F(91,92) F(90,91) F(89,90) +F(88,89) F(87,88) F(86,87) F(85,86) +F(84,85) F(83,84) F(82,83) F(81,82) +F(80,81) F(79,80) F(78,79) F(77,78) +F(76,77) F(75,76) F(74,75) F(73,74) +F(72,73) F(71,72) F(70,71) F(69,70) +F(68,69) F(67,68) F(66,67) F(65,66) +F(64,65) F(63,64) F(62,63) F(61,62) +F(60,61) F(59,60) F(58,59) F(57,58) +F(56,57) F(55,56) F(54,55) F(53,54) +F(52,53) F(51,52) F(50,51) F(49,50) +F(48,49) F(47,48) F(46,47) F(45,46) +F(44,45) F(43,44) F(42,43) F(41,42) +F(40,41) F(39,40) F(38,39) F(37,38) +F(36,37) F(35,36) F(34,35) F(33,34) +F(32,33) F(31,32) F(30,31) F(29,30) +F(28,29) F(27,28) F(26,27) F(25,26) +F(24,25) F(23,24) F(22,23) F(21,22) +F(20,21) F(19,20) F(18,19) F(17,18) +F(16,17) F(15,16) F(14,15) F(13,14) +F(12,13) F(11,12) F(10,11) F(9,10) +F(8,9) F(7,8) F(6,7) F(5,6) +F(4,5) F(3,4) F(2,3) F(1,2) + +int +main (int argc, char **argv) +{ + if (argc > 1 && strcmp (argv[1], "-v") == 0) + verbose = 1; + + return f1 (); +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-init-remote.c b/src/coreclr/src/pal/src/libunwind/tests/test-init-remote.c new file mode 100644 index 00000000000000..66f2d6a1e0c2bf --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-init-remote.c @@ -0,0 +1,103 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +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. */ + +/* This test simply verifies that unw_init_remote() can be used in + lieu of unw_init_local(). This was broken for a while on ia64. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "compiler.h" + +#include +#include +#include +#include + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +int verbose; + +static int +do_backtrace (void) +{ + char buf[512], name[256]; + unw_word_t ip, sp, off; + unw_cursor_t cursor; + unw_context_t uc; + int ret; + + unw_getcontext (&uc); + if (unw_init_remote (&cursor, unw_local_addr_space, &uc) < 0) + panic ("unw_init_remote failed!\n"); + + do + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + unw_get_reg (&cursor, UNW_REG_SP, &sp); + buf[0] = '\0'; + if (unw_get_proc_name (&cursor, name, sizeof (name), &off) == 0) + { + if (off) + snprintf (buf, sizeof (buf), "<%s+0x%lx>", name, (long) off); + else + snprintf (buf, sizeof (buf), "<%s>", name); + } + if (verbose) + printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); + + ret = unw_step (&cursor); + if (ret < 0) + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + printf ("FAILURE: unw_step() returned %d for ip=%lx\n", + ret, (long) ip); + return -1; + } + } + while (ret > 0); + + return 0; +} + +static int +foo (void) +{ + return do_backtrace (); +} + +int +main (int argc, char **argv UNUSED) +{ + verbose = (argc > 1); + + if (verbose) + printf ("Normal backtrace:\n"); + return foo (); +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-mem.c b/src/coreclr/src/pal/src/libunwind/tests/test-mem.c new file mode 100644 index 00000000000000..52c977488ac324 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-mem.c @@ -0,0 +1,103 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Copyright (c) 2003 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. */ + +#include "compiler.h" + +#include +#include +#include +#include +#include + +#include + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +int verbose; + +static void +do_backtrace (void) +{ + unw_cursor_t cursor; + unw_word_t ip, sp; + unw_context_t uc; + int ret; + + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + panic ("unw_init_local failed!\n"); + + do + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + unw_get_reg (&cursor, UNW_REG_SP, &sp); + + if (verbose) + printf ("%016lx (sp=%016lx)\n", (long) ip, (long) sp); + + ret = unw_step (&cursor); + if (ret < 0) + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + panic ("FAILURE: unw_step() returned %d for ip=%lx\n", + ret, (long) ip); + } + } + while (ret > 0); +} + +int +consume_some_stack_space (void) +{ + unw_cursor_t cursor; + unw_context_t uc; + char string[1024]; + + memset (&cursor, 0, sizeof (cursor)); + memset (&uc, 0, sizeof (uc)); + return sprintf (string, "hello %p %p\n", &cursor, &uc); +} + +int +main (int argc, char **argv UNUSED) +{ + struct rlimit rlim; + + verbose = argc > 1; + + if (consume_some_stack_space () > 9999) + exit (-1); /* can't happen, but don't let the compiler know... */ + + rlim.rlim_cur = 0; + rlim.rlim_max = RLIM_INFINITY; + setrlimit (RLIMIT_DATA, &rlim); + setrlimit (RLIMIT_AS, &rlim); + + do_backtrace (); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-proc-info.c b/src/coreclr/src/pal/src/libunwind/tests/test-proc-info.c new file mode 100644 index 00000000000000..c4145bc374ec38 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-proc-info.c @@ -0,0 +1,171 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Copyright (c) 2003 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. */ + +/* This test program checks whether proc_info lookup failures are + cached. They must NOT be cached because it could otherwise turn + temporary failures into permanent ones. Furthermore, we allow apps + to return -UNW_ESTOPUNWIND to terminate unwinding (though this + feature is deprecated and dynamic unwind info should be used + instead). */ + +#include +#include + +#include +#include "compiler.h" + +int errors; + +#define panic(args...) \ + { ++errors; fprintf (stderr, args); return -1; } + +static int +find_proc_info (unw_addr_space_t as UNUSED, + unw_word_t ip UNUSED, + unw_proc_info_t *pip UNUSED, + int need_unwind_info UNUSED, + void *arg UNUSED) +{ + return -UNW_ESTOPUNWIND; +} + +static int +access_mem (unw_addr_space_t as UNUSED, + unw_word_t addr UNUSED, + unw_word_t *valp, int write, + void *arg UNUSED) +{ + if (!write) + *valp = 0; + return 0; +} + +static int +access_reg (unw_addr_space_t as UNUSED, + unw_regnum_t regnum UNUSED, + unw_word_t *valp, int write, + void *arg UNUSED) +{ + if (!write) + *valp = 32; + return 0; +} + +static int +access_fpreg (unw_addr_space_t as UNUSED, + unw_regnum_t regnum UNUSED, + unw_fpreg_t *valp, int write, + void *arg UNUSED) +{ + if (!write) + memset (valp, 0, sizeof (*valp)); + return 0; +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as UNUSED, + unw_word_t *dilap UNUSED, + void *arg UNUSED) +{ + return -UNW_ENOINFO; +} + +static void +put_unwind_info (unw_addr_space_t as UNUSED, + unw_proc_info_t *pi UNUSED, + void *arg UNUSED) +{ + ++errors; + fprintf (stderr, "%s() got called!\n", __FUNCTION__); +} + +static int +resume (unw_addr_space_t as UNUSED, + unw_cursor_t *reg UNUSED, + void *arg UNUSED) +{ + panic ("%s() got called!\n", __FUNCTION__); +} + +static int +get_proc_name (unw_addr_space_t as UNUSED, + unw_word_t ip UNUSED, + char *buf UNUSED, + size_t buf_len UNUSED, + unw_word_t *offp UNUSED, + void *arg UNUSED) +{ + panic ("%s() got called!\n", __FUNCTION__); +} + +int +main (int argc, char **argv) +{ + unw_accessors_t acc; + unw_addr_space_t as; + int ret, verbose = 0; + unw_cursor_t c; + + if (argc > 1 && strcmp (argv[1], "-v") == 0) + verbose = 1; + + memset (&acc, 0, sizeof (acc)); + acc.find_proc_info = find_proc_info; + acc.put_unwind_info = put_unwind_info; + acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + acc.access_mem = access_mem; + acc.access_reg = access_reg; + acc.access_fpreg = access_fpreg; + acc.resume = resume; + acc.get_proc_name = get_proc_name; + + as = unw_create_addr_space (&acc, 0); + if (!as) + panic ("unw_create_addr_space() failed\n"); + + unw_set_caching_policy (as, UNW_CACHE_GLOBAL); + + ret = unw_init_remote (&c, as, NULL); + if (ret < 0) + panic ("unw_init_remote() returned %d instead of 0\n", ret); + + ret = unw_step (&c); + if (ret != -UNW_ESTOPUNWIND) + panic ("First call to unw_step() returned %d instead of %d\n", + ret, -UNW_ESTOPUNWIND); + + ret = unw_step (&c); + if (ret != -UNW_ESTOPUNWIND) + panic ("Second call to unw_step() returned %d instead of %d\n", + ret, -UNW_ESTOPUNWIND); + + unw_destroy_addr_space (as); + + if (verbose) + printf ("SUCCESS\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-ptrace-misc.c b/src/coreclr/src/pal/src/libunwind/tests/test-ptrace-misc.c new file mode 100644 index 00000000000000..374059dc44a972 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-ptrace-misc.c @@ -0,0 +1,120 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "compiler.h" + +#include +#include +#include +#include +#include + +#include + +pid_t self; +int global[64]; + +int +func (int arg) +{ + int sum = 0, i, max, arr[1024]; + + if (arg == 0) + { + sum = global[2]; + sum += sum + sum * getppid (); + return sum; + } + else + { + max = arg; + if (max >= 64) + max = 64; + + for (i = 0; i < max; ++i) + arr[i] = func (arg - 1); + + for (i = 0; i < max; ++i) + if (arr[i] > 16) + sum += arr[i]; + else + sum -= arr[i]; + } + return sum; +} + +int +bar (int v) +{ + extern long f (long); + int arr[1] = { v }; + uintptr_t r; + + /* This is a vain attempt to use up lots of registers to force + the frame-chain info to be saved on the memory stack on ia64. + It happens to work with gcc v3.3.4 and gcc v3.4.1 but perhaps + not with any other compiler. */ + r = (uintptr_t) malloc(f (arr[0]) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + (f (v) + f (v)) + )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + ))))))))))))))))))))))))))))))))))))))))))))))))))))))); + if (r < 2) + v = r; + + kill (self, SIGUSR1); /* tell test-ptrace to start single-stepping */ + v = func (v); + kill (self, SIGUSR2); /* tell test-ptrace to stop single-stepping */ + return v; +} + +int +main (int argc, char **argv UNUSED) +{ + int val = argc; + + signal (SIGUSR1, SIG_IGN); + signal (SIGUSR2, SIG_IGN); + + self = getpid (); + + printf ("sum = %d\n", bar (val)); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-ptrace.c b/src/coreclr/src/pal/src/libunwind/tests/test-ptrace.c new file mode 100644 index 00000000000000..e7c7883f38f9eb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-ptrace.c @@ -0,0 +1,370 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#ifdef HAVE_TTRACE + +int +main (void) +{ + printf ("FAILURE: ttrace() not supported yet\n"); + return -1; +} + +#else /* !HAVE_TTRACE */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +extern char **environ; + +static const int nerrors_max = 100; + +int nerrors; +int verbose; +int print_names = 1; + +enum + { + INSTRUCTION, + SYSCALL, + TRIGGER + } +trace_mode = SYSCALL; + +#define panic(args...) \ + do { fprintf (stderr, args); ++nerrors; } while (0) + +static unw_addr_space_t as; +static struct UPT_info *ui; + +static int killed; + +void +do_backtrace (void) +{ + unw_word_t ip, sp, start_ip = 0, off; + int n = 0, ret; + unw_proc_info_t pi; + unw_cursor_t c; + char buf[512]; + size_t len; + + ret = unw_init_remote (&c, as, ui); + if (ret < 0) + panic ("unw_init_remote() failed: ret=%d\n", ret); + + do + { + if ((ret = unw_get_reg (&c, UNW_REG_IP, &ip)) < 0 + || (ret = unw_get_reg (&c, UNW_REG_SP, &sp)) < 0) + panic ("unw_get_reg/unw_get_proc_name() failed: ret=%d\n", ret); + + if (n == 0) + start_ip = ip; + + buf[0] = '\0'; + if (print_names) + unw_get_proc_name (&c, buf, sizeof (buf), &off); + + if (verbose) + { + if (off) + { + len = strlen (buf); + if (len >= sizeof (buf) - 32) + len = sizeof (buf) - 32; + sprintf (buf + len, "+0x%lx", (unsigned long) off); + } + printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp); + } + + if ((ret = unw_get_proc_info (&c, &pi)) < 0) + panic ("unw_get_proc_info(ip=0x%lx) failed: ret=%d\n", (long) ip, ret); + else if (verbose) + printf ("\tproc=%016lx-%016lx\n\thandler=%lx lsda=%lx", + (long) pi.start_ip, (long) pi.end_ip, + (long) pi.handler, (long) pi.lsda); + +#if UNW_TARGET_IA64 + { + unw_word_t bsp; + + if ((ret = unw_get_reg (&c, UNW_IA64_BSP, &bsp)) < 0) + panic ("unw_get_reg() failed: ret=%d\n", ret); + else if (verbose) + printf (" bsp=%lx", bsp); + } +#endif + if (verbose) + printf ("\n"); + + ret = unw_step (&c); + if (ret < 0) + { + unw_get_reg (&c, UNW_REG_IP, &ip); + panic ("FAILURE: unw_step() returned %d for ip=%lx (start ip=%lx)\n", + ret, (long) ip, (long) start_ip); + } + + if (++n > 64) + { + /* guard against bad unwind info in old libraries... */ + panic ("too deeply nested---assuming bogus unwind (start ip=%lx)\n", + (long) start_ip); + break; + } + if (nerrors > nerrors_max) + { + panic ("Too many errors (%d)!\n", nerrors); + break; + } + } + while (ret > 0); + + if (ret < 0) + panic ("unwind failed with ret=%d\n", ret); + + if (verbose) + printf ("================\n\n"); +} + +static pid_t target_pid; +static void target_pid_kill (void) +{ + kill (target_pid, SIGKILL); +} + +int +main (int argc, char **argv) +{ + int status, pid, pending_sig, optind = 1, state = 1; + + as = unw_create_addr_space (&_UPT_accessors, 0); + if (!as) + panic ("unw_create_addr_space() failed"); + + if (argc == 1) + { + static char *args[] = { "self", "/bin/ls", "/usr", NULL }; + + /* automated test case */ + argv = args; + + /* Unless the args array is 'walked' the child + process is unable to access it and dies with a segfault */ + fprintf(stderr, "Automated test (%s,%s,%s,%s)\n", + args[0],args[1],args[2],args[3]); + } + else if (argc > 1) + while (argv[optind][0] == '-') + { + if (strcmp (argv[optind], "-v") == 0) + ++optind, verbose = 1; + else if (strcmp (argv[optind], "-i") == 0) + ++optind, trace_mode = INSTRUCTION; /* backtrace at each insn */ + else if (strcmp (argv[optind], "-s") == 0) + ++optind, trace_mode = SYSCALL; /* backtrace at each syscall */ + else if (strcmp (argv[optind], "-t") == 0) + /* Execute until raise(SIGUSR1), then backtrace at each insn + until raise(SIGUSR2). */ + ++optind, trace_mode = TRIGGER; + else if (strcmp (argv[optind], "-c") == 0) + /* Enable caching of unwind-info. */ + ++optind, unw_set_caching_policy (as, UNW_CACHE_GLOBAL); + else if (strcmp (argv[optind], "-n") == 0) + /* Don't look-up and print symbol names. */ + ++optind, print_names = 0; + else + fprintf(stderr, "unrecognized option: %s\n", argv[optind++]); + if (optind >= argc) + break; + } + + target_pid = fork (); + if (!target_pid) + { + /* child */ + + if (!verbose) + dup2 (open ("/dev/null", O_WRONLY), 1); + +#if HAVE_DECL_PTRACE_TRACEME + ptrace (PTRACE_TRACEME, 0, 0, 0); +#elif HAVE_DECL_PT_TRACE_ME + ptrace (PT_TRACE_ME, 0, 0, 0); +#else +#error Trace me +#endif + + if ((argc > 1) && (optind == argc)) { + fprintf(stderr, "Need to specify a command line for the child\n"); + exit (-1); + } + execve (argv[optind], argv + optind, environ); + _exit (-1); + } + atexit (target_pid_kill); + + ui = _UPT_create (target_pid); + + while (nerrors <= nerrors_max) + { + pid = wait4 (-1, &status, 0, NULL); + if (pid == -1) + { + if (errno == EINTR) + continue; + + panic ("wait4() failed (errno=%d)\n", errno); + } + pending_sig = 0; + if (WIFSIGNALED (status) || WIFEXITED (status) + || (WIFSTOPPED (status) && WSTOPSIG (status) != SIGTRAP)) + { + if (WIFEXITED (status)) + { + if (WEXITSTATUS (status) != 0) + panic ("child's exit status %d\n", WEXITSTATUS (status)); + break; + } + else if (WIFSIGNALED (status)) + { + if (!killed) + panic ("child terminated by signal %d\n", WTERMSIG (status)); + break; + } + else + { + pending_sig = WSTOPSIG (status); + /* Avoid deadlock: */ + if (WSTOPSIG (status) == SIGKILL) + break; + if (trace_mode == TRIGGER) + { + if (WSTOPSIG (status) == SIGUSR1) + state = 0; + else if (WSTOPSIG (status) == SIGUSR2) + state = 1; + } + if (WSTOPSIG (status) != SIGUSR1 && WSTOPSIG (status) != SIGUSR2) + { + static int count = 0; + + if (count++ > 100) + { + panic ("Too many child unexpected signals (now %d)\n", + WSTOPSIG (status)); + killed = 1; + } + } + } + } + + switch (trace_mode) + { + case TRIGGER: + if (state) +#if HAVE_DECL_PTRACE_CONT + ptrace (PTRACE_CONT, target_pid, 0, 0); +#elif HAVE_DECL_PT_CONTINUE + ptrace (PT_CONTINUE, target_pid, (caddr_t)1, 0); +#else +#error Port me +#endif + else + { + do_backtrace (); +#if HAVE_DECL_PTRACE_SINGLESTEP + if (ptrace (PTRACE_SINGLESTEP, target_pid, 0, pending_sig) < 0) + { + panic ("ptrace(PTRACE_SINGLESTEP) failed (errno=%d)\n", errno); + killed = 1; + } +#elif HAVE_DECL_PT_STEP + if (ptrace (PT_STEP, target_pid, (caddr_t)1, pending_sig) < 0) + { + panic ("ptrace(PT_STEP) failed (errno=%d)\n", errno); + killed = 1; + } +#else +#error Singlestep me +#endif + } + break; + + case SYSCALL: + if (!state) + do_backtrace (); + state ^= 1; +#if HAVE_DECL_PTRACE_SYSCALL + ptrace (PTRACE_SYSCALL, target_pid, 0, pending_sig); +#elif HAVE_DECL_PT_SYSCALL + ptrace (PT_SYSCALL, target_pid, (caddr_t)1, pending_sig); +#else +#error Syscall me +#endif + break; + + case INSTRUCTION: + do_backtrace (); +#if HAVE_DECL_PTRACE_SINGLESTEP + ptrace (PTRACE_SINGLESTEP, target_pid, 0, pending_sig); +#elif HAVE_DECL_PT_STEP + ptrace (PT_STEP, target_pid, (caddr_t)1, pending_sig); +#else +#error Singlestep me +#endif + break; + } + if (killed) + kill (target_pid, SIGKILL); + } + + _UPT_destroy (ui); + unw_destroy_addr_space (as); + + if (nerrors) + { + printf ("FAILURE: detected %d errors\n", nerrors); + exit (-1); + } + if (verbose) + printf ("SUCCESS\n"); + + return 0; +} + +#endif /* !HAVE_TTRACE */ diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-reg-state.c b/src/coreclr/src/pal/src/libunwind/tests/test-reg-state.c new file mode 100644 index 00000000000000..ac713ea68ad721 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-reg-state.c @@ -0,0 +1,133 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Copyright (c) 2003 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. */ + +#include "compiler.h" + +#include +#include +#include +#include +#include + +#include +#include + +#define panic(args...) \ + { fprintf (stderr, args); exit (-1); } + +int verbose; + +struct cb_data +{ + unw_word_t ip; + void* reg_state; + size_t len; +}; + +static int +dwarf_reg_states_callback(void *token, + void *rs, + size_t size, + unw_word_t start_ip, unw_word_t end_ip) +{ + struct cb_data *data = token; + if (start_ip <= data->ip && data->ip < end_ip) + { + data->reg_state = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + memcpy(data->reg_state, rs, size); + data->len = size; + } + return 0; +} + +static void +do_backtrace (void) +{ + unw_cursor_t cursor; + unw_word_t ip, sp; + unw_context_t uc; + int ret; + + unw_getcontext (&uc); + if (unw_init_local (&cursor, &uc) < 0) + panic ("unw_init_local failed!\n"); + + do + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + unw_get_reg (&cursor, UNW_REG_SP, &sp); + + if (verbose) + printf ("%016lx (sp=%016lx)\n", (long) ip, (long) sp); + + struct cb_data data = {.ip = ip, .reg_state = NULL}; + ret = unw_reg_states_iterate(&cursor, dwarf_reg_states_callback, &data); + if (ret > 0) + { + ret = unw_apply_reg_state (&cursor, data.reg_state); + munmap(data.reg_state, data.len); + } + if (ret < 0) + { + unw_get_reg (&cursor, UNW_REG_IP, &ip); + panic ("FAILURE: unw_step() returned %d for ip=%lx\n", + ret, (long) ip); + } + } + while (ret > 0); +} + +int +consume_some_stack_space (void) +{ + unw_cursor_t cursor; + unw_context_t uc; + char string[1024]; + + memset (&cursor, 0, sizeof (cursor)); + memset (&uc, 0, sizeof (uc)); + return sprintf (string, "hello %p %p\n", &cursor, &uc); +} + +int +main (int argc, char **argv UNUSED) +{ + struct rlimit rlim; + + verbose = argc > 1; + + if (consume_some_stack_space () > 9999) + exit (-1); /* can't happen, but don't let the compiler know... */ + + rlim.rlim_cur = 0; + rlim.rlim_max = RLIM_INFINITY; + setrlimit (RLIMIT_DATA, &rlim); + + do_backtrace (); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-setjmp.c b/src/coreclr/src/pal/src/libunwind/tests/test-setjmp.c new file mode 100644 index 00000000000000..769b71b2228c6c --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-setjmp.c @@ -0,0 +1,285 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +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. */ + +/* The setjmp()/longjmp(), sigsetjmp()/siglongjmp(). */ + +#include "compiler.h" + +#include +#include +#include +#include +#include +#include + +int nerrors; +int verbose; + +static jmp_buf jbuf; +static sigjmp_buf sigjbuf; +static sigset_t sigset4; + +void +raise_longjmp (jmp_buf jbuf, int i, int n) +{ + while (i < n) + raise_longjmp (jbuf, i + 1, n); + + longjmp (jbuf, n); +} + +void +test_setjmp (void) +{ + volatile int i; + jmp_buf jbuf; + int ret; + + for (i = 0; i < 10; ++i) + { + if ((ret = setjmp (jbuf))) + { + if (verbose) + printf ("%s: secondary setjmp () return, ret=%d\n", + __FUNCTION__, ret); + if (ret != i + 1) + { + fprintf (stderr, "%s: setjmp() returned %d, expected %d\n", + __FUNCTION__, ret, i + 1); + ++nerrors; + } + continue; + } + if (verbose) + printf ("%s.%d: done with setjmp(); calling children\n", + __FUNCTION__, i + 1); + + raise_longjmp (jbuf, 0, i + 1); + + fprintf (stderr, "%s: raise_longjmp() returned unexpectedly\n", + __FUNCTION__); + ++nerrors; + } +} + + +void +raise_siglongjmp (sigjmp_buf jbuf, int i, int n) +{ + while (i < n) + raise_siglongjmp (jbuf, i + 1, n); + + siglongjmp (jbuf, n); +} + +void +test_sigsetjmp (void) +{ + sigjmp_buf jbuf; + volatile int i; + int ret; + + for (i = 0; i < 10; ++i) + { + if ((ret = sigsetjmp (jbuf, 1))) + { + if (verbose) + printf ("%s: secondary sigsetjmp () return, ret=%d\n", + __FUNCTION__, ret); + if (ret != i + 1) + { + fprintf (stderr, "%s: sigsetjmp() returned %d, expected %d\n", + __FUNCTION__, ret, i + 1); + ++nerrors; + } + continue; + } + if (verbose) + printf ("%s.%d: done with sigsetjmp(); calling children\n", + __FUNCTION__, i + 1); + + raise_siglongjmp (jbuf, 0, i + 1); + + fprintf (stderr, "%s: raise_siglongjmp() returned unexpectedly\n", + __FUNCTION__); + ++nerrors; + } +} + +void +sighandler (int signal) +{ + if (verbose) + printf ("%s: got signal %d\n", __FUNCTION__, signal); + + sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset4); + if (verbose) + printf ("%s: back from sigprocmask\n", __FUNCTION__); + + siglongjmp (sigjbuf, 1); + printf ("%s: siglongjmp() returned unexpectedly!\n", __FUNCTION__); +} + +int +main (int argc, char **argv UNUSED) +{ + volatile sigset_t sigset1, sigset2, sigset3; + volatile struct sigaction act; + + if (argc > 1) + verbose = 1; + + sigemptyset ((sigset_t *) &sigset1); + sigaddset ((sigset_t *) &sigset1, SIGUSR1); + sigemptyset ((sigset_t *) &sigset2); + sigaddset ((sigset_t *) &sigset2, SIGUSR2); + + memset ((void *) &act, 0, sizeof (act)); + act.sa_handler = sighandler; + sigaction (SIGTERM, (struct sigaction *) &act, NULL); + + test_setjmp (); + test_sigsetjmp (); + + /* _setjmp() MUST NOT change signal mask: */ + sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL); + if (_setjmp (jbuf)) + { + sigemptyset ((sigset_t *) &sigset3); + sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); + if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset2, + sizeof (sigset_t)) != 0) + { + fprintf (stderr, "FAILURE: _longjmp() manipulated signal mask!\n"); + ++nerrors; + } + else if (verbose) + printf ("OK: _longjmp() seems not to change signal mask\n"); + } + else + { + sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL); + _longjmp (jbuf, 1); + } + + /* sigsetjmp(jbuf, 1) MUST preserve signal mask: */ + sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL); + if (sigsetjmp (sigjbuf, 1)) + { + sigemptyset ((sigset_t *) &sigset3); + sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); + if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset1, + sizeof (sigset_t)) != 0) + { + fprintf (stderr, + "FAILURE: siglongjmp() didn't restore signal mask!\n"); + ++nerrors; + } + else if (verbose) + printf ("OK: siglongjmp() restores signal mask when asked to\n"); + } + else + { + sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL); + siglongjmp (sigjbuf, 1); + } + + /* sigsetjmp(jbuf, 0) MUST NOT preserve signal mask: */ + sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL); + if (sigsetjmp (sigjbuf, 0)) + { + sigemptyset ((sigset_t *) &sigset3); + sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); + if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset2, + sizeof (sigset_t)) != 0) + { + fprintf (stderr, + "FAILURE: siglongjmp() changed signal mask!\n"); + ++nerrors; + } + else if (verbose) + printf ("OK: siglongjmp() leaves signal mask alone when asked to\n"); + } + else + { + sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL); + siglongjmp (sigjbuf, 1); + } + + /* sigsetjmp(jbuf, 1) MUST preserve signal mask: */ + sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL); + if (sigsetjmp (sigjbuf, 1)) + { + sigemptyset ((sigset_t *) &sigset3); + sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); + if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset1, + sizeof (sigset_t)) != 0) + { + fprintf (stderr, + "FAILURE: siglongjmp() didn't restore signal mask!\n"); + ++nerrors; + } + else if (verbose) + printf ("OK: siglongjmp() restores signal mask when asked to\n"); + } + else + { + sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL); + kill (getpid (), SIGTERM); + fprintf (stderr, "FAILURE: unexpected return from kill()\n"); + ++nerrors; + } + + /* sigsetjmp(jbuf, 0) MUST NOT preserve signal mask: */ + sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL); + if (sigsetjmp (sigjbuf, 0)) + { + sigemptyset ((sigset_t *) &sigset3); + sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3); + if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset4, + sizeof (sigset_t)) != 0) + { + fprintf (stderr, + "FAILURE: siglongjmp() changed signal mask!\n"); + ++nerrors; + } + else if (verbose) + printf ("OK: siglongjmp() leaves signal mask alone when asked to\n"); + } + else + { + sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL); + kill (getpid (), SIGTERM); + fprintf (stderr, "FAILURE: unexpected return from kill()\n"); + ++nerrors; + } + + if (nerrors > 0) + { + fprintf (stderr, "FAILURE: detected %d failures\n", nerrors); + exit (-1); + } + if (verbose) + printf ("SUCCESS\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-static-link-gen.c b/src/coreclr/src/pal/src/libunwind/tests/test-static-link-gen.c new file mode 100644 index 00000000000000..d61e7a51c66c06 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-static-link-gen.c @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Copyright (c) 2003 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. */ + +#include + +#include + +extern int verbose; + +static void *funcs[] = + { + (void *) &unw_get_reg, + (void *) &unw_get_fpreg, + (void *) &unw_set_reg, + (void *) &unw_set_fpreg, + (void *) &unw_resume, + (void *) &unw_create_addr_space, + (void *) &unw_destroy_addr_space, + (void *) &unw_get_accessors, + (void *) &unw_flush_cache, + (void *) &unw_set_caching_policy, + (void *) &unw_set_cache_size, + (void *) &unw_regname, + (void *) &unw_get_proc_info, + (void *) &unw_get_save_loc, + (void *) &unw_is_signal_frame, + (void *) &unw_get_proc_name + }; + +int +test_generic (void) +{ + if (verbose) + printf (__FILE__": funcs[0]=%p\n", funcs[0]); + +#ifndef UNW_REMOTE_ONLY + { + unw_context_t uc; + unw_cursor_t c; + + unw_getcontext (&uc); + unw_init_local (&c, &uc); + unw_init_remote (&c, unw_local_addr_space, &uc); + + return unw_step (&c); + } +#else + return 0; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-static-link-loc.c b/src/coreclr/src/pal/src/libunwind/tests/test-static-link-loc.c new file mode 100644 index 00000000000000..1c7aa0378c8df5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-static-link-loc.c @@ -0,0 +1,102 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Copyright (c) 2003 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. */ + +/* The purpose of this program is simply to link in all libunwind-API + functions both in their local-only and generic variants and to make + sure that the final result can be linked statically. */ + +#include + +#define UNW_LOCAL_ONLY +#include +#include "compiler.h" + +extern int test_generic (void); + +int verbose; + +#ifdef UNW_REMOTE_ONLY + +int +test_local (void) +{ + return 0; +} + +#else /* !UNW_REMOTE_ONLY */ + +static void *funcs[] = + { + (void *) &unw_get_reg, + (void *) &unw_get_fpreg, + (void *) &unw_set_reg, + (void *) &unw_set_fpreg, + (void *) &unw_resume, + (void *) &unw_create_addr_space, + (void *) &unw_destroy_addr_space, + (void *) &unw_get_accessors, + (void *) &unw_flush_cache, + (void *) &unw_set_caching_policy, + (void *) &unw_set_cache_size, + (void *) &unw_regname, + (void *) &unw_get_proc_info, + (void *) &unw_get_save_loc, + (void *) &unw_is_signal_frame, + (void *) &unw_get_proc_name, + (void *) &_U_dyn_register, + (void *) &_U_dyn_cancel + }; + +int +test_local (void) +{ + unw_context_t uc; + unw_cursor_t c; + + if (verbose) + printf (__FILE__": funcs[0]=%p\n", funcs[0]); + + unw_getcontext (&uc); + unw_init_local (&c, &uc); + unw_init_remote (&c, unw_local_addr_space, &uc); + return unw_step (&c); +} + +#endif /* !UNW_REMOTE_ONLY */ + +int +main (int argc, char **argv UNUSED) +{ + if (argc > 1) + verbose = 1; + + if (test_local () < 0) + return -1; + if (test_generic () < 0) + return -1; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-strerror.c b/src/coreclr/src/pal/src/libunwind/tests/test-strerror.c new file mode 100644 index 00000000000000..f7ae61ed17bdf8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/test-strerror.c @@ -0,0 +1,18 @@ +#include "compiler.h" +#include +#include + +int +main (int argc, char **argv UNUSED) +{ + int i, verbose = argc > 1; + const char *msg; + + for (i = 0; i < 16; ++i) + { + msg = unw_strerror (-i); + if (verbose) + printf ("%6d -> %s\n", -i, msg); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S b/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S new file mode 100644 index 00000000000000..f275625df10063 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S @@ -0,0 +1,78 @@ +.global DW_CFA_expression_testcase + +.extern recover_register + +.text + +# CFI expressions were added in DWARF v3 to allow compilers to specify memory +# locations or register values using DWARF programs. These programs are simple +# stack-based operations which allow the compiler to encode integer mathematics +# and other complex logic. CFI expressions are therefore more powerful than the +# conventional register + offset schemes. +# +# These tests capture a bug we have fixed in libunwind. CFI expression programs +# always start with the current CFA pushed onto the stack. This file contains a +# pair of routines which test CFI expression parsing. Specifically they test +# DW_CFA_expression logic, which uses DWARF expressions to compute the address +# where a non-volatile register was stored. +# +# Main calls DW_CFA_expression_testcase, which sets up known state in a +# non-volatile (caller-saved) register. We use r12 for this purpose. After this +# DW_CFA_expression_testcase then calls DW_CFA_expression_inner, which clobbers +# r12 after stashing its value on the stack. This routine contains a DWARF3 CFI +# expression to restore the value of r12 on unwind which should allow libunwind +# to recover clobbered state. DW_CFA_expression_inner calls recover_register to +# retrieve the cached register value. This function recovers the register value +# by using libunwind to unwind the stack through DW_CFA_expression_inner and up +# to the call site in DW_CFA_expression_testcase. If our expression is correct, +# libunwind will be able to restore r12 from the stack. +# +# BE CAREFUL WITH rdi, rsi, rax HERE! The arguments to recover_register are +# passed in via rdi, rsi and I just let them flow through unchanged. Similarly +# RAX flows back unchanged. Adding any function calls to the below may clobber +# these registers and cause this test to fail mysteriously. + + +######################################################## +# Test: Restoring a register using a DW_CFA_expression # +# which uses implicit CFA pushed onto stack. # +######################################################## + +.type DW_CFA_expression_testcase STT_FUNC +DW_CFA_expression_testcase: + .cfi_startproc + push %r12 + .cfi_adjust_cfa_offset 8 + # Move our sentinel (known) value into non-volatile (Callee-saved) r12 + mov $111222333, %r12 + .cfi_rel_offset %r12, 0 + call DW_CFA_expression_inner + pop %r12 + .cfi_restore %r12 + .cfi_adjust_cfa_offset -8 + ret + .cfi_endproc +.size DW_CFA_expression_testcase,.-DW_CFA_expression_testcase + +.type DW_CFA_expression_inner STT_FUNC +DW_CFA_expression_inner: + .cfi_startproc + push %r12 + .cfi_adjust_cfa_offset 8 + # !! IMPORTANT BIT !! The test is all about how we parse the following bytes. + # Now we use an expression to describe where our sentinel value is stored: + # DW_CFA_expression(0x10), r12(0x0c), Length(0x02), (preamble) + # DW_OP_lit16(0x40), DW_OP_minus(0x1c) (instructions) + # Parsing starts with the CFA on the stack, then pushes 16, then does a minus + # which is eqivalent to a=pop(), b=pop(), push(b-a), leaving us with a value + # of cfa-16 (cfa points at old rsp, cfa-8 is our rip, so we stored r12 at + # cfa-16). + xor %r12, %r12 # Trash r12 + .cfi_escape 0x10, 0x0c, 0x2, 0x40, 0x1c # DW_CFA_expression for recovery + call recover_register + pop %r12 + .cfi_restore %r12 + .cfi_adjust_cfa_offset -8 + ret + .cfi_endproc +.size DW_CFA_expression_inner,.-DW_CFA_expression_inner diff --git a/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c b/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c new file mode 100644 index 00000000000000..c7b7cf7335a8bd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c @@ -0,0 +1,124 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2019 Brock York + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_PTRACE_H +#include +#endif + +#define UNW_LOCAL_ONLY +#include + +/* + * unwind in the signal handler checking the backtrace is correct + * after a bad jump. + */ +void handle_sigsegv(int signal, siginfo_t *info, void *ucontext) +{ + /* + * 0 = success + * !0 = general failure + * 77 = test skipped + * 99 = complete failure + */ + int test_status = 0; + unw_cursor_t cursor; unw_context_t uc; + unw_word_t ip, sp, offset; + char name[1000]; + int found_signal_frame = 0; + int i = 0; + char *names[] = { + "", + "main", + }; + int names_count = sizeof(names) / sizeof(*names); + + unw_getcontext(&uc); + unw_init_local(&cursor, &uc); + + while (unw_step(&cursor) > 0 && !test_status) + { + if (unw_is_signal_frame(&cursor)) + { + found_signal_frame = 1; + } + if (found_signal_frame) + { + unw_get_reg(&cursor, UNW_REG_IP, &ip); + unw_get_reg(&cursor, UNW_REG_SP, &sp); + memset(name, 0, sizeof(char) * 1000); + unw_get_proc_name(&cursor, name, sizeof(char) * 1000, &offset); + printf("ip = %lx, sp = %lx offset = %lx name = %s\n", (long) ip, (long) sp, (long) offset, name); + if (i < names_count) + { + if (strcmp(names[i], name) != 0) + { + test_status = 1; + printf("frame %s doesn't match expected frame %s\n", name, names[i]); + } + else + { + i += 1; + } + } + } + } + + if (i != names_count) //Make sure we found all the frames! + { + printf("Failed to find all frames i:%d != names_count:%d\n", i, names_count); + test_status = 1; + } + + /*return test_status to test harness*/ + exit(test_status); +} + +void (*invalid_function)() = (void*)1; + +int main(int argc, char *argv[]) +{ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handle_sigsegv; + sa.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &sa, NULL); + + invalid_function(); + + /* + * 99 is the hard error exit status for automake tests: + * https://www.gnu.org/software/automake/manual/html_node/Scripts_002dbased-Testsuites.html#Scripts_002dbased-Testsuites + * If we dont end up in the signal handler something went horribly wrong. + */ + return 99; +} From 5367b646a039bcbd25119449aac8e5ed0698fee3 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 7 May 2020 17:16:51 -0400 Subject: [PATCH 03/12] Update libunwind version in CMake --- src/coreclr/src/pal/src/libunwind/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/pal/src/libunwind/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/CMakeLists.txt index 5c66b90fdb0503..c6ce8da7e9d40d 100644 --- a/src/coreclr/src/pal/src/libunwind/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/CMakeLists.txt @@ -13,8 +13,8 @@ elseif(CLR_CMAKE_HOST_ARCH_I386) endif() set(PKG_MAJOR "1") -set(PKG_MINOR "3") -set(PKG_EXTRA "-rc1") +set(PKG_MINOR "5") +set(PKG_EXTRA "-rc2") configure_file(include/libunwind-common.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind-common.h) configure_file(include/libunwind.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind.h) From ae12f12161c9c6dce1fdfca75a821749aaa18905 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 7 May 2020 18:21:53 -0400 Subject: [PATCH 04/12] Add libunwind-version.txt --- src/coreclr/src/pal/src/libunwind/libunwind-version.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/coreclr/src/pal/src/libunwind/libunwind-version.txt diff --git a/src/coreclr/src/pal/src/libunwind/libunwind-version.txt b/src/coreclr/src/pal/src/libunwind/libunwind-version.txt new file mode 100644 index 00000000000000..e96a102894ad41 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/libunwind-version.txt @@ -0,0 +1,2 @@ +v1.5-rc2 +https://github.com/libunwind/libunwind/releases/tag/v1.5-rc2 From 6bc94d3f94e466c5f67dbc35c8d84aef598bd4ac Mon Sep 17 00:00:00 2001 From: Adeel Date: Thu, 7 May 2020 18:29:39 -0400 Subject: [PATCH 05/12] Add changes for SunOS from @am11 --- src/coreclr/src/pal/src/libunwind/CMakeLists.txt | 1 - .../src/pal/src/libunwind/src/CMakeLists.txt | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/pal/src/libunwind/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/CMakeLists.txt index c6ce8da7e9d40d..fc47c89f640cf2 100644 --- a/src/coreclr/src/pal/src/libunwind/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/CMakeLists.txt @@ -19,4 +19,3 @@ set(PKG_EXTRA "-rc2") configure_file(include/libunwind-common.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind-common.h) configure_file(include/libunwind.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind.h) configure_file(include/tdep/libunwind_i.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/tdep/libunwind_i.h) - diff --git a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt index 891eadd158fa51..c46295594d2c0c 100644 --- a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt @@ -25,6 +25,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") else() add_compile_options(-Wno-unused-value) add_compile_options(-Wno-unused-result) + add_compile_options(-Wno-implicit-function-declaration) + add_compile_options(-Wno-incompatible-pointer-types) endif() if(CLR_CMAKE_HOST_ARCH_ARM) @@ -96,7 +98,6 @@ SET(libunwind_la_SOURCES_generic mi/Gget_fpreg.c mi/Gset_fpreg.c mi/Gset_caching_policy.c mi/Gset_cache_size.c - oop/_OOP_find_proc_info.c ) SET(libunwind_la_SOURCES_os_linux @@ -115,6 +116,14 @@ SET(libunwind_la_SOURCES_os_freebsd_local # Nothing ) +SET(libunwind_la_SOURCES_os_solaris + os-solaris.c +) + +SET(libunwind_la_SOURCES_os_solaris_local +# Nothing +) + if(CLR_CMAKE_HOST_LINUX) SET(libunwind_la_SOURCES_os ${libunwind_la_SOURCES_os_linux}) SET(libunwind_la_SOURCES_os_local ${libunwind_la_SOURCES_os_linux_local}) @@ -137,6 +146,11 @@ elseif(CLR_CMAKE_HOST_FREEBSD) SET(libunwind_la_SOURCES_arm_os arm/Gos-freebsd.c) SET(libunwind_la_SOURCES_arm_os_local arm/Los-freebsd.c) list(APPEND libunwind_coredump_la_SOURCES coredump/_UCD_access_reg_freebsd.c) +elseif(CLR_CMAKE_HOST_SUNOS) + SET(libunwind_la_SOURCES_os ${libunwind_la_SOURCES_os_solaris}) + SET(libunwind_la_SOURCES_os_local ${libunwind_la_SOURCES_os_solaris_local}) + SET(libunwind_la_SOURCES_x86_64_os x86_64/Gos-solaris.c) + SET(libunwind_la_SOURCES_x86_64_os_local x86_64/Los-solaris.c) endif() # List of arch-independent files needed by both local-only and generic From b389eaf98c2af44d41a8605fa1b9f9fe4f29027e Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 7 May 2020 18:32:07 -0400 Subject: [PATCH 06/12] Revert change to oop --- src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt index c46295594d2c0c..853b79d60b8f4f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt @@ -98,6 +98,7 @@ SET(libunwind_la_SOURCES_generic mi/Gget_fpreg.c mi/Gset_fpreg.c mi/Gset_caching_policy.c mi/Gset_cache_size.c + oop/_OOP_find_proc_info.c ) SET(libunwind_la_SOURCES_os_linux From a703c0251763c077eefa12eef735e50f0fbca3f9 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 7 May 2020 18:33:43 -0400 Subject: [PATCH 07/12] Remove obsolete add_definition --- src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt index 853b79d60b8f4f..6014e9d80a574e 100644 --- a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt @@ -14,8 +14,6 @@ add_definitions(-DPACKAGE_STRING="") add_definitions(-DPACKAGE_BUGREPORT="") add_definitions(-D_GNU_SOURCE) -# Ensure that the remote and local unwind code can reside in the same binary without name clashing -add_definitions("-Ddwarf_search_unwind_table_int=UNW_OBJ(dwarf_search_unwind_table_int)") # Disable warning due to incorrect format specifier in debugging printf via the Debug macro add_compile_options(-Wno-format -Wno-format-security) From d871e3a4341074c95e63dc387b631c654cb95ed2 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 8 May 2020 09:14:36 -0400 Subject: [PATCH 08/12] Fix musl build --- src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt index 6014e9d80a574e..e34b63757ca943 100644 --- a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt @@ -51,6 +51,10 @@ elseif(CLR_CMAKE_HOST_ARCH_ARM64) # Disable warning due to labs function called on unsigned argument add_compile_options(-Wno-absolute-value) endif() + // Issue https://github.com/libunwind/libunwind/issues/176 + if (CLR_CMAKE_TARGET_ALPINE_LINUX) + add_definitions("-D__sigset_t=sigset_t") + endif() # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension add_definitions(-Dasm=__asm__) elseif(CLR_CMAKE_HOST_ARCH_I386) From 181d6e01bbdac8e5580cc08d98df46a2f23b0624 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 8 May 2020 16:27:45 -0400 Subject: [PATCH 09/12] Fix comment --- src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt index e34b63757ca943..ce30421dc750dc 100644 --- a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt @@ -51,7 +51,7 @@ elseif(CLR_CMAKE_HOST_ARCH_ARM64) # Disable warning due to labs function called on unsigned argument add_compile_options(-Wno-absolute-value) endif() - // Issue https://github.com/libunwind/libunwind/issues/176 + # Issue https://github.com/libunwind/libunwind/issues/176 if (CLR_CMAKE_TARGET_ALPINE_LINUX) add_definitions("-D__sigset_t=sigset_t") endif() From 3d44d483715ea9782d5bdfa347f3c73ef2038a51 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 8 May 2020 16:30:52 -0400 Subject: [PATCH 10/12] Be consistent and use HOST --- src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt index ce30421dc750dc..386d8ba3260306 100644 --- a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt @@ -52,7 +52,7 @@ elseif(CLR_CMAKE_HOST_ARCH_ARM64) add_compile_options(-Wno-absolute-value) endif() # Issue https://github.com/libunwind/libunwind/issues/176 - if (CLR_CMAKE_TARGET_ALPINE_LINUX) + if (CLR_CMAKE_HOST_ALPINE_LINUX) add_definitions("-D__sigset_t=sigset_t") endif() # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension From d6cf906695eb20660594b82ec2f2141e0216dae4 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 18 May 2020 16:36:32 -0400 Subject: [PATCH 11/12] Fix error in unw_sigcontext Introduced by libunwind/libunwind#71 __reseverved needs to be big enough to store a unw_fpsimd_context_t Which includes 32 128-bit registers, stored as 64 64-bit half registers. Fix off by 2 issue --- src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h index 778b43626b9256..2716afccb815b3 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h @@ -184,7 +184,7 @@ struct unw_sigcontext uint64_t sp; uint64_t pc; uint64_t pstate; - uint8_t __reserved[(34 * 8)] __attribute__((__aligned__(16))); + uint8_t __reserved[(66 * 8)] __attribute__((__aligned__(16))); }; typedef struct From 547210305a609a775bab4eee5fbd2fd575ba7dd4 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 18 May 2020 20:38:17 -0400 Subject: [PATCH 12/12] Arm64 support !UNWIND_CONTEXT_IS_UCONTEXT_T --- src/coreclr/src/pal/src/exception/seh-unwind.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/coreclr/src/pal/src/exception/seh-unwind.cpp b/src/coreclr/src/pal/src/exception/seh-unwind.cpp index 53c86a0045384f..654e385dec40a6 100644 --- a/src/coreclr/src/pal/src/exception/seh-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/seh-unwind.cpp @@ -111,6 +111,22 @@ static void WinContextToUnwindContext(CONTEXT *winContext, unw_context_t *unwCon unwContext->regs[13] = winContext->Sp; unwContext->regs[14] = winContext->Lr; unwContext->regs[15] = winContext->Pc; +#elif defined(HOST_ARM64) + unwContext->uc_mcontext.pc = winContext->Pc; + unwContext->uc_mcontext.sp = winContext->Sp; + unwContext->uc_mcontext.regs[29] = winContext->Fp; + unwContext->uc_mcontext.regs[30] = winContext->Lr; + + unwContext->uc_mcontext.regs[19] = winContext->X19; + unwContext->uc_mcontext.regs[20] = winContext->X20; + unwContext->uc_mcontext.regs[21] = winContext->X21; + unwContext->uc_mcontext.regs[22] = winContext->X22; + unwContext->uc_mcontext.regs[23] = winContext->X23; + unwContext->uc_mcontext.regs[24] = winContext->X24; + unwContext->uc_mcontext.regs[25] = winContext->X25; + unwContext->uc_mcontext.regs[26] = winContext->X26; + unwContext->uc_mcontext.regs[27] = winContext->X27; + unwContext->uc_mcontext.regs[28] = winContext->X28; #endif }